From d3afd5b428dff0254f0b61445db21d457973043c Mon Sep 17 00:00:00 2001 From: Packit Service Date: Feb 24 2021 15:19:25 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/bin/Makefile.in b/bin/Makefile.in index a465e70..a18b222 100644 --- a/bin/Makefile.in +++ b/bin/Makefile.in @@ -11,8 +11,8 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -SUBDIRS = named named-sdb named-pkcs11 rndc dig delv dnssec dnssec-pkcs11 tools nsupdate \ - check confgen @NZD_TOOLS@ @PYTHON_TOOLS@ @PKCS11_TOOLS@ sdb_tools tests +SUBDIRS = named rndc dig delv dnssec tools nsupdate check confgen \ + @NZD_TOOLS@ @PYTHON_TOOLS@ @PKCS11_TOOLS@ tests TARGETS = @BIND9_MAKE_RULES@ diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in index b2baf48..6f55fa6 100644 --- a/bin/check/Makefile.in +++ b/bin/check/Makefile.in @@ -81,14 +81,12 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man8: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - (cd ${DESTDIR}${mandir}/man8; rm -f named-compilezone.8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8) - -install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs install-man8 +install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkconf@EXEEXT@ ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkzone@EXEEXT@ ${DESTDIR}${sbindir} (cd ${DESTDIR}${sbindir}; rm -f named-compilezone@EXEEXT@; ${LINK_PROGRAM} named-checkzone@EXEEXT@ named-compilezone@EXEEXT@) + for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8 || exit 1; done + (cd ${DESTDIR}${mandir}/man8; rm -f named-compilezone.8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8) uninstall:: rm -f ${DESTDIR}${mandir}/man8/named-compilezone.8 diff --git a/bin/check/named-checkconf.docbook b/bin/check/named-checkconf.docbook index 11d57f9..9f5dc2e 100644 --- a/bin/check/named-checkconf.docbook +++ b/bin/check/named-checkconf.docbook @@ -12,7 +12,7 @@ --> - + 2014-01-10 @@ -24,7 +24,7 @@ named-checkconf 8 - BIND9 + BIND9 diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook index 771b33a..7fcae97 100644 --- a/bin/check/named-checkzone.docbook +++ b/bin/check/named-checkzone.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-19 @@ -22,7 +22,7 @@ named-checkzone 8 - BIND9 + BIND9 diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in index b5df60b..57a917f 100644 --- a/bin/confgen/Makefile.in +++ b/bin/confgen/Makefile.in @@ -93,14 +93,13 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man8: rndc-confgen.8 ddns-confgen.8 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - (cd ${DESTDIR}${mandir}/man8; rm -f tsig-keygen.8; ${LINK_PROGRAM} ddns-confgen.8 tsig-keygen.8) - -install:: rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@ installdirs install-man8 +install:: rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} ddns-confgen@EXEEXT@ ${DESTDIR}${sbindir} + ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/ddns-confgen.8 ${DESTDIR}${mandir}/man8 (cd ${DESTDIR}${sbindir}; rm -f tsig-keygen@EXEEXT@; ${LINK_PROGRAM} ddns-confgen@EXEEXT@ tsig-keygen@EXEEXT@) + (cd ${DESTDIR}${mandir}/man8; rm -f tsig-keygen.8; ${LINK_PROGRAM} ddns-confgen.8 tsig-keygen.8) uninstall:: rm -f ${DESTDIR}${mandir}/man8/tsig-keygen.8 diff --git a/bin/confgen/ddns-confgen.docbook b/bin/confgen/ddns-confgen.docbook index 60c25d6..3ce3e55 100644 --- a/bin/confgen/ddns-confgen.docbook +++ b/bin/confgen/ddns-confgen.docbook @@ -10,7 +10,7 @@ --> - + 2014-03-06 @@ -22,7 +22,7 @@ ddns-confgen 8 - BIND9 + BIND9 diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c index 1ac775f..6125448 100644 --- a/bin/confgen/keygen.c +++ b/bin/confgen/keygen.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -74,7 +73,7 @@ alg_fromtext(const char *name) { p = &name[5]; #ifndef PK11_MD5_DISABLE - if (strcasecmp(p, "md5") == 0 && isc_md5_available()) + if (strcasecmp(p, "md5") == 0) return DST_ALG_HMACMD5; #endif if (strcasecmp(p, "sha1") == 0) @@ -133,13 +132,6 @@ generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg, switch (alg) { #ifndef PK11_MD5_DISABLE case DST_ALG_HMACMD5: - if (!isc_md5_available()) { - fatal("unsupported algorithm %d\n", alg); - } else if (keysize < 1 || keysize > 512) { - fatal("keysize %d out of range (must be 1-512)\n", - keysize); - } - break; #endif case DST_ALG_HMACSHA1: case DST_ALG_HMACSHA224: @@ -161,11 +153,6 @@ generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg, DO("create entropy context", isc_entropy_create(mctx, &ectx)); -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(ectx, true); - } -#endif if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { randomfile = NULL; open_keyboard = ISC_ENTROPY_KEYBOARDYES; diff --git a/bin/confgen/rndc-confgen.c b/bin/confgen/rndc-confgen.c index 5b272ee..538e730 100644 --- a/bin/confgen/rndc-confgen.c +++ b/bin/confgen/rndc-confgen.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -62,7 +61,7 @@ const char *progname; bool verbose = false; -const char *keyfile, *keydef, *algdef; +const char *keyfile, *keydef; ISC_PLATFORM_NORETURN_PRE static void usage(int status) ISC_PLATFORM_NORETURN_POST; @@ -70,12 +69,13 @@ usage(int status) ISC_PLATFORM_NORETURN_POST; static void usage(int status) { +#ifndef PK11_MD5_DISABLE fprintf(stderr, "\ Usage:\n\ %s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \ [-s addr] [-t chrootdir] [-u user]\n\ -a: generate just the key clause and write it to keyfile (%s)\n\ - -A alg: algorithm (default %s)\n\ + -A alg: algorithm (default hmac-md5)\n\ -b bits: from 1 through 512, default 256; total length of the secret\n\ -c keyfile: specify an alternate key file (requires -a)\n\ -k keyname: the name as it will be used in named.conf and rndc.conf\n\ @@ -84,7 +84,24 @@ Usage:\n\ -s addr: the address to which rndc should connect\n\ -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\ -u user: set the keyfile owner to \"user\" (requires -a)\n", - progname, keydef, algdef); + progname, keydef); +#else + fprintf(stderr, "\ +Usage:\n\ + %s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \ +[-s addr] [-t chrootdir] [-u user]\n\ + -a: generate just the key clause and write it to keyfile (%s)\n\ + -A alg: algorithm (default hmac-sha256)\n\ + -b bits: from 1 through 512, default 256; total length of the secret\n\ + -c keyfile: specify an alternate key file (requires -a)\n\ + -k keyname: the name as it will be used in named.conf and rndc.conf\n\ + -p port: the port named will listen on and rndc will connect to\n\ + -r randomfile: source of random data (use \"keyboard\" for key timing)\n\ + -s addr: the address to which rndc should connect\n\ + -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\ + -u user: set the keyfile owner to \"user\" (requires -a)\n", + progname, keydef); +#endif exit (status); } @@ -120,12 +137,11 @@ main(int argc, char **argv) { progname = program; keyname = DEFAULT_KEYNAME; - alg = DST_ALG_HMACSHA256; #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) - alg = DST_ALG_HMACMD5; + alg = DST_ALG_HMACMD5; +#else + alg = DST_ALG_HMACSHA256; #endif - algdef = alg_totext(alg); serveraddr = DEFAULT_SERVER; port = DEFAULT_PORT; diff --git a/bin/confgen/rndc-confgen.docbook b/bin/confgen/rndc-confgen.docbook index bf78273..22dd5f5 100644 --- a/bin/confgen/rndc-confgen.docbook +++ b/bin/confgen/rndc-confgen.docbook @@ -10,7 +10,7 @@ --> - + 2013-03-14 @@ -22,7 +22,7 @@ rndc-confgen 8 - BIND9 + BIND9 diff --git a/bin/delv/Makefile.in b/bin/delv/Makefile.in index 8ba5ad0..83230d4 100644 --- a/bin/delv/Makefile.in +++ b/bin/delv/Makefile.in @@ -63,12 +63,10 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 -install-man1: delv.1 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man1 - -install:: delv@EXEEXT@ installdirs install-man1 +install:: delv@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ delv@EXEEXT@ ${DESTDIR}${bindir} + ${INSTALL_DATA} ${srcdir}/delv.1 ${DESTDIR}${mandir}/man1 uninstall:: rm -f ${DESTDIR}${mandir}/man1/delv.1 diff --git a/bin/delv/delv.docbook b/bin/delv/delv.docbook index dbcb960..dbb3a10 100644 --- a/bin/delv/delv.docbook +++ b/bin/delv/delv.docbook @@ -12,7 +12,7 @@ --> - + 2014-04-23 @@ -24,7 +24,7 @@ delv 1 - BIND9 + BIND9 diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in index 3a8f72d..7683d5b 100644 --- a/bin/dig/Makefile.in +++ b/bin/dig/Makefile.in @@ -91,16 +91,16 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 -install-man1: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man1 - -install:: dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ installdirs install-man1 +install:: dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ dig@EXEEXT@ ${DESTDIR}${bindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ host@EXEEXT@ ${DESTDIR}${bindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ nslookup@EXEEXT@ ${DESTDIR}${bindir} + for m in ${MANPAGES}; do \ + ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man1 || exit 1; \ + done uninstall:: for m in ${MANPAGES}; do \ diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 225bbc9..2077fcf 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -1782,10 +1781,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, ptr = ptr2; ptr2 = ptr3; } else { - hmacname = DNS_TSIG_HMACSHA256_NAME; #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) - hmacname = DNS_TSIG_HMACMD5_NAME; + hmacname = DNS_TSIG_HMACMD5_NAME; +#else + hmacname = DNS_TSIG_HMACSHA256_NAME; #endif digestbits = 0; } diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 259010b..e1600da 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -12,7 +12,7 @@ --> - + 2014-02-19 @@ -24,7 +24,7 @@ dig 1 - BIND9 + BIND9 @@ -1330,42 +1330,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr reply from the server. If you'd like to turn off the IDN support for some reason, use parameters +noidnin and - +noidnout or define - the IDN_DISABLE environment variable. - - - - - RETURN CODES - - Dig return codes are: - - - - 0: Everything went well, including things like NXDOMAIN - - - - - 1: Usage error - - - - - 8: Couldn't open batch file - - - - - 9: No reply from server - - - - - 10: Internal error - - - + +noidnout. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index e37c5ec..4043aa3 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -81,7 +81,6 @@ #include #include #include -#include #include #include #include @@ -827,11 +826,6 @@ make_empty_lookup(void) { looknew->badcookie = true; #ifdef WITH_IDN_SUPPORT looknew->idnin = isatty(1)?(getenv("IDN_DISABLE") == NULL):false; - if (looknew->idnin) { - const char *charset = getenv("CHARSET"); - if (charset && !strcmp(charset, "ASCII")) - looknew->idnin = false; - } #else looknew->idnin = false; #endif @@ -1253,10 +1247,9 @@ parse_hmac(const char *hmac) { digestbits = 0; #ifndef PK11_MD5_DISABLE - if (strcasecmp(buf, "hmac-md5") == 0 && isc_md5_available()) { + if (strcasecmp(buf, "hmac-md5") == 0) { hmacname = DNS_TSIG_HMACMD5_NAME; - } else if (strncasecmp(buf, "hmac-md5-", 9) == 0 && - isc_md5_available()) { + } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { hmacname = DNS_TSIG_HMACMD5_NAME; digestbits = parse_bits(&buf[9], "digest-bits [0..128]", 128); } else @@ -1376,13 +1369,7 @@ setup_file_key(void) { switch (dst_key_alg(dstkey)) { #ifndef PK11_MD5_DISABLE case DST_ALG_HMACMD5: - if (isc_md5_available()) { - hmacname = DNS_TSIG_HMACMD5_NAME; - } else { - printf(";; Couldn't create key %s: bad algorithm\n", - keynametext); - goto failure; - } + hmacname = DNS_TSIG_HMACMD5_NAME; break; #endif case DST_ALG_HMACSHA1: @@ -1832,13 +1819,6 @@ clear_query(dig_query_t *query) { if (query->timer != NULL) isc_timer_detach(&query->timer); - - if (query->waiting_senddone) { - debug("send_done not yet called"); - query->pending_free = true; - return; - } - lookup = query->lookup; if (lookup->current_query == query) @@ -1864,7 +1844,10 @@ clear_query(dig_query_t *query) { isc_mempool_put(commctx, query->recvspace); isc_buffer_invalidate(&query->recvbuf); isc_buffer_invalidate(&query->lengthbuf); - isc_mem_free(mctx, query); + if (query->waiting_senddone) + query->pending_free = true; + else + isc_mem_free(mctx, query); } /*% @@ -2920,9 +2903,9 @@ send_done(isc_task_t *_task, isc_event_t *event) { isc_event_free(&event); if (query->pending_free) - clear_query(query); + isc_mem_free(mctx, query); - check_next_lookup(l); + check_if_done(); UNLOCK_LOOKUP; } diff --git a/bin/dig/host.docbook b/bin/dig/host.docbook index 12d05d2..a3e4d7e 100644 --- a/bin/dig/host.docbook +++ b/bin/dig/host.docbook @@ -12,7 +12,7 @@ --> - + 2009-01-20 @@ -24,7 +24,7 @@ host 1 - BIND9 + BIND9 @@ -390,7 +390,7 @@ host appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. - If you'd like to turn off the IDN support for some reason, define + If you'd like to turn off the IDN support for some reason, defines the IDN_DISABLE environment variable. The IDN support is disabled if the variable is set when host runs. diff --git a/bin/dig/nslookup.docbook b/bin/dig/nslookup.docbook index 2cb85e2..b21cf92 100644 --- a/bin/dig/nslookup.docbook +++ b/bin/dig/nslookup.docbook @@ -38,7 +38,7 @@ - SUCH DAMAGE. --> - + 2014-01-24 @@ -50,7 +50,7 @@ nslookup 1 - BIND9 + BIND9 @@ -502,21 +502,6 @@ nslookup -query=hinfo -timeout=10 - IDN SUPPORT - - - If nslookup has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - nslookup appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, define - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - nslookup runs. - - - FILES /etc/resolv.conf diff --git a/bin/dnssec-pkcs11/Makefile.in b/bin/dnssec-pkcs11/Makefile.in deleted file mode 100644 index e59a118..0000000 --- a/bin/dnssec-pkcs11/Makefile.in +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -VERSION=@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = ${DNS_PKCS11_INCLUDES} ${ISC_PKCS11_INCLUDES} - -CDEFINES = -DVERSION=\"${VERSION}\" @PKCS11_ENGINE@ \ - @CRYPTO_PK11@ -DPK11_LIB_LOCATION=\"@PKCS11_PROVIDER@\" -CWARNINGS = - -DNSLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@ -ISCLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ -ISCNOSYMLIBS = ../../lib/isc-pkcs11/libisc-pkcs11-nosymtbl.@A@ - -DNSDEPLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ -ISCDEPLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ - -DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ - -NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@ - -# Alphabetically -TARGETS = dnssec-keygen-pkcs11@EXEEXT@ dnssec-signzone-pkcs11@EXEEXT@ \ - dnssec-keyfromlabel-pkcs11@EXEEXT@ dnssec-dsfromkey-pkcs11@EXEEXT@ \ - dnssec-revoke-pkcs11@EXEEXT@ dnssec-settime-pkcs11@EXEEXT@ \ - dnssec-verify-pkcs11@EXEEXT@ dnssec-importkey-pkcs11@EXEEXT@ - -OBJS = dnssectool.@O@ - -SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \ - dnssec-revoke.c dnssec-settime.c dnssec-signzone.c \ - dnssec-verify.c dnssec-importkey.c dnssectool.c - -MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \ - dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8 \ - dnssec-verify.8 dnssec-importkey.8 - -HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \ - dnssec-keygen.html dnssec-revoke.html \ - dnssec-settime.html dnssec-signzone.html \ - dnssec-verify.html dnssec-importkey.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -dnssec-dsfromkey-pkcs11@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS} - export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \ - ${FINALBUILDCMD} - -dnssec-keyfromlabel-pkcs11@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS} - export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \ - ${FINALBUILDCMD} - -dnssec-keygen-pkcs11@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS} - export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \ - ${FINALBUILDCMD} - -dnssec-signzone.@O@: dnssec-signzone.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ - -c ${srcdir}/dnssec-signzone.c - -dnssec-signzone-pkcs11@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS} - export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \ - ${FINALBUILDCMD} - -dnssec-verify.@O@: dnssec-verify.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ - -c ${srcdir}/dnssec-verify.c - -dnssec-verify-pkcs11@EXEEXT@: dnssec-verify.@O@ ${OBJS} ${DEPLIBS} - export BASEOBJS="dnssec-verify.@O@ ${OBJS}"; \ - ${FINALBUILDCMD} - -dnssec-revoke-pkcs11@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dnssec-revoke.@O@ ${OBJS} ${LIBS} - -dnssec-settime-pkcs11@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dnssec-settime.@O@ ${OBJS} ${LIBS} - -dnssec-importkey-pkcs11@EXEEXT@: dnssec-importkey.@O@ ${OBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dnssec-importkey.@O@ ${OBJS} ${LIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - -install-man8: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install:: ${TARGETS} installdirs - for t in ${TARGETS}; do ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} $$t ${DESTDIR}${sbindir} || exit 1; done - -uninstall:: - for t in ${TARGETS}; do ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/$$t || exit 1; done - -clean distclean:: - rm -f ${TARGETS} - diff --git a/bin/dnssec-pkcs11/dnssec-dsfromkey.8 b/bin/dnssec-pkcs11/dnssec-dsfromkey.8 deleted file mode 100644 index ac78ed4..0000000 --- a/bin/dnssec-pkcs11/dnssec-dsfromkey.8 +++ /dev/null @@ -1,242 +0,0 @@ -.\" Copyright (C) 2008-2012, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-dsfromkey -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2012-05-02 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-DSFROMKEY" "8" "2012\-05\-02" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-dsfromkey \- DNSSEC DS RR generation tool -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-dsfromkey\fR\ 'u -\fBdnssec\-dsfromkey\fR [\fB\-1\fR | \fB\-2\fR | \fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-C\fR | \fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-T\ \fR\fB\fITTL\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] {keyfile} -.HP \w'\fBdnssec\-dsfromkey\fR\ 'u -\fBdnssec\-dsfromkey\fR [\fB\-1\fR | \fB\-2\fR | \fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-C\fR | \fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-T\ \fR\fB\fITTL\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-A\fR] {\fB\-f\ \fR\fB\fIfile\fR\fR} [dnsname] -.HP \w'\fBdnssec\-dsfromkey\fR\ 'u -\fBdnssec\-dsfromkey\fR [\fB\-1\fR | \fB\-2\fR | \fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-C\fR | \fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-T\ \fR\fB\fITTL\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] {\-s} {dnsname} -.HP \w'\fBdnssec\-dsfromkey\fR\ 'u -\fBdnssec\-dsfromkey\fR [\fB\-h\fR | \fB\-V\fR] -.SH "DESCRIPTION" -.PP -The -\fBdnssec\-dsfromkey\fR -command outputs DS (Delegation Signer) resource records (RRs) and other similarly\-constructed RRs: with the -\fB\-l\fR -option it outputs DLV (DNSSEC Lookaside Validation) RRs; or with the -\fB\-C\fR -it outputs CDS (Child DS) RRs\&. -.PP -The input keys can be specified in a number of ways: -.PP -By default, -\fBdnssec\-dsfromkey\fR -reads a key file named like -Knnnn\&.+aaa+iiiii\&.key, as generated by -\fBdnssec\-keygen\fR\&. -.PP -With the -\fB\-f \fR\fB\fIfile\fR\fR -option, -\fBdnssec\-dsfromkey\fR -reads keys from a zone file or partial zone file (which can contain just the DNSKEY records)\&. -.PP -With the -\fB\-s\fR -option, -\fBdnssec\-dsfromkey\fR -reads a -keyset\- -file, as generated by -\fBdnssec\-keygen\fR -\fB\-C\fR\&. -.SH "OPTIONS" -.PP -\-1 -.RS 4 -An abbreviation for -\fB\-a SHA1\fR -.RE -.PP -\-2 -.RS 4 -An abbreviation for -\fB\-a SHA\-256\fR -.RE -.PP -\-a \fIalgorithm\fR -.RS 4 -Specify a digest algorithm to use when converting DNSKEY records to DS records\&. This option can be repeated, so that multiple DS records are created for each DNSKEY record\&. -.sp -The -\fIalgorithm\fR -must be one of SHA\-1, SHA\-256, or SHA\-384\&. These values are case insensitive, and the hyphen may be omitted\&. If no algorithm is specified, the default is to use both SHA\-1 and SHA\-256\&. -.RE -.PP -\-A -.RS 4 -Include ZSKs when generating DS records\&. Without this option, only keys which have the KSK flag set will be converted to DS records and printed\&. Useful only in -\fB\-f\fR -zone file mode\&. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Specifies the DNS class (default is IN)\&. Useful only in -\fB\-s\fR -keyset or -\fB\-f\fR -zone file mode\&. -.RE -.PP -\-C -.RS 4 -Generate CDS records rather than DS records\&. This is mutually exclusive with the -\fB\-l\fR -option for generating DLV records\&. -.RE -.PP -\-f \fIfile\fR -.RS 4 -Zone file mode: -\fBdnssec\-dsfromkey\fR\*(Aqs final -\fIdnsname\fR -argument is the DNS domain name of a zone whose master file can be read from -\fBfile\fR\&. If the zone name is the same as -\fBfile\fR, then it may be omitted\&. -.sp -If -\fIfile\fR -is -"\-", then the zone data is read from the standard input\&. This makes it possible to use the output of the -\fBdig\fR -command as input, as in: -.sp -\fBdig dnskey example\&.com | dnssec\-dsfromkey \-f \- example\&.com\fR -.RE -.PP -\-h -.RS 4 -Prints usage information\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Look for key files or -keyset\- -files in -\fBdirectory\fR\&. -.RE -.PP -\-l \fIdomain\fR -.RS 4 -Generate a DLV set instead of a DS set\&. The specified -\fIdomain\fR -is appended to the name for each record in the set\&. This is mutually exclusive with the -\fB\-C\fR -option for generating CDS records\&. -.RE -.PP -\-s -.RS 4 -Keyset mode: -\fBdnssec\-dsfromkey\fR\*(Aqs final -\fIdnsname\fR -argument is the DNS domain name used to locate a -keyset\- -file\&. -.RE -.PP -\-T \fITTL\fR -.RS 4 -Specifies the TTL of the DS records\&. By default the TTL is omitted\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.SH "EXAMPLE" -.PP -To build the SHA\-256 DS RR from the -\fBKexample\&.com\&.+003+26160\fR -keyfile name, you can issue the following command: -.PP -\fBdnssec\-dsfromkey \-2 Kexample\&.com\&.+003+26160\fR -.PP -The command would print something like: -.PP -\fBexample\&.com\&. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0C5EA0B94\fR -.SH "FILES" -.PP -The keyfile can be designated by the key identification -Knnnn\&.+aaa+iiiii -or the full file name -Knnnn\&.+aaa+iiiii\&.key -as generated by -dnssec\-keygen(8)\&. -.PP -The keyset file name is built from the -\fBdirectory\fR, the string -keyset\- -and the -\fBdnsname\fR\&. -.SH "CAVEAT" -.PP -A keyfile error can give a "file not found" even if the file exists\&. -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 3658 -(DS RRs), -RFC 4431 -(DLV RRs), -RFC 4509 -(SHA\-256 for DS RRs), -RFC 6605 -(SHA\-384 for DS RRs), -RFC 7344 -(CDS and CDNSKEY RRs)\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2008-2012, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-dsfromkey.c b/bin/dnssec-pkcs11/dnssec-dsfromkey.c deleted file mode 100644 index 9cb63a8..0000000 --- a/bin/dnssec-pkcs11/dnssec-dsfromkey.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-dsfromkey"; -int verbose; - -static dns_rdataclass_t rdclass; -static dns_fixedname_t fixed; -static dns_name_t *name = NULL; -static isc_mem_t *mctx = NULL; -static uint32_t ttl; -static bool emitttl = false; - -static isc_result_t -initname(char *setname) { - isc_result_t result; - isc_buffer_t buf; - - name = dns_fixedname_initname(&fixed); - - isc_buffer_init(&buf, setname, strlen(setname)); - isc_buffer_add(&buf, strlen(setname)); - result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); - return (result); -} - -static void -db_load_from_stream(dns_db_t *db, FILE *fp) { - isc_result_t result; - dns_rdatacallbacks_t callbacks; - - dns_rdatacallbacks_init(&callbacks); - result = dns_db_beginload(db, &callbacks); - if (result != ISC_R_SUCCESS) - fatal("dns_db_beginload failed: %s", isc_result_totext(result)); - - result = dns_master_loadstream(fp, name, name, rdclass, 0, - &callbacks, mctx); - if (result != ISC_R_SUCCESS) - fatal("can't load from input: %s", isc_result_totext(result)); - - result = dns_db_endload(db, &callbacks); - if (result != ISC_R_SUCCESS) - fatal("dns_db_endload failed: %s", isc_result_totext(result)); -} - -static isc_result_t -loadset(const char *filename, dns_rdataset_t *rdataset) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - char setname[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, setname, sizeof(setname)); - - result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, - rdclass, 0, NULL, &db); - if (result != ISC_R_SUCCESS) - fatal("can't create database"); - - if (strcmp(filename, "-") == 0) { - db_load_from_stream(db, stdin); - filename = "input"; - } else { - result = dns_db_load(db, filename); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - fatal("can't load %s: %s", filename, - isc_result_totext(result)); - } - - result = dns_db_findnode(db, name, false, &node); - if (result != ISC_R_SUCCESS) - fatal("can't find %s node in %s", setname, filename); - - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, - 0, 0, rdataset, NULL); - - if (result == ISC_R_NOTFOUND) - fatal("no DNSKEY RR for %s in %s", setname, filename); - else if (result != ISC_R_SUCCESS) - fatal("dns_db_findrdataset"); - - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - return (result); -} - -static isc_result_t -loadkeyset(char *dirname, dns_rdataset_t *rdataset) { - isc_result_t result; - char filename[PATH_MAX + 1]; - isc_buffer_t buf; - - dns_rdataset_init(rdataset); - - isc_buffer_init(&buf, filename, sizeof(filename)); - if (dirname != NULL) { - /* allow room for a trailing slash */ - if (strlen(dirname) >= isc_buffer_availablelength(&buf)) - return (ISC_R_NOSPACE); - isc_buffer_putstr(&buf, dirname); - if (dirname[strlen(dirname) - 1] != '/') - isc_buffer_putstr(&buf, "/"); - } - - if (isc_buffer_availablelength(&buf) < 7) - return (ISC_R_NOSPACE); - isc_buffer_putstr(&buf, "keyset-"); - - result = dns_name_tofilenametext(name, false, &buf); - check_result(result, "dns_name_tofilenametext()"); - if (isc_buffer_availablelength(&buf) == 0) - return (ISC_R_NOSPACE); - isc_buffer_putuint8(&buf, 0); - - return (loadset(filename, rdataset)); -} - -static void -loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, - dns_rdata_t *rdata) -{ - isc_result_t result; - dst_key_t *key = NULL; - isc_buffer_t keyb; - isc_region_t r; - - dns_rdata_init(rdata); - - isc_buffer_init(&keyb, key_buf, key_buf_size); - - result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, - mctx, &key); - if (result != ISC_R_SUCCESS) - fatal("can't load %s.key: %s", - filename, isc_result_totext(result)); - - if (verbose > 2) { - char keystr[DST_KEY_FORMATSIZE]; - - dst_key_format(key, keystr, sizeof(keystr)); - fprintf(stderr, "%s: %s\n", program, keystr); - } - - result = dst_key_todns(key, &keyb); - if (result != ISC_R_SUCCESS) - fatal("can't decode key"); - - isc_buffer_usedregion(&keyb, &r); - dns_rdata_fromregion(rdata, dst_key_class(key), - dns_rdatatype_dnskey, &r); - - rdclass = dst_key_class(key); - - name = dns_fixedname_initname(&fixed); - result = dns_name_copy(dst_key_name(key), name, NULL); - if (result != ISC_R_SUCCESS) - fatal("can't copy name"); - - dst_key_free(&key); -} - -static void -logkey(dns_rdata_t *rdata) -{ - isc_result_t result; - dst_key_t *key = NULL; - isc_buffer_t buf; - char keystr[DST_KEY_FORMATSIZE]; - - isc_buffer_init(&buf, rdata->data, rdata->length); - isc_buffer_add(&buf, rdata->length); - result = dst_key_fromdns(name, rdclass, &buf, mctx, &key); - if (result != ISC_R_SUCCESS) - return; - - dst_key_format(key, keystr, sizeof(keystr)); - fprintf(stderr, "%s: %s\n", program, keystr); - - dst_key_free(&key); -} - -static void -emit(dns_dsdigest_t dtype, bool showall, char *lookaside, - bool cds, dns_rdata_t *rdata) -{ - isc_result_t result; - unsigned char buf[DNS_DS_BUFFERSIZE]; - char text_buf[DST_KEY_MAXTEXTSIZE]; - char name_buf[DNS_NAME_MAXWIRE]; - char class_buf[10]; - isc_buffer_t textb, nameb, classb; - isc_region_t r; - dns_rdata_t ds; - dns_rdata_dnskey_t dnskey; - - isc_buffer_init(&textb, text_buf, sizeof(text_buf)); - isc_buffer_init(&nameb, name_buf, sizeof(name_buf)); - isc_buffer_init(&classb, class_buf, sizeof(class_buf)); - - dns_rdata_init(&ds); - - result = dns_rdata_tostruct(rdata, &dnskey, NULL); - if (result != ISC_R_SUCCESS) - fatal("can't convert DNSKEY"); - - if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall) - return; - - result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds); - if (result != ISC_R_SUCCESS) - fatal("can't build record"); - - result = dns_name_totext(name, false, &nameb); - if (result != ISC_R_SUCCESS) - fatal("can't print name"); - - /* Add lookaside origin, if set */ - if (lookaside != NULL) { - if (isc_buffer_availablelength(&nameb) < strlen(lookaside)) - fatal("DLV origin '%s' is too long", lookaside); - isc_buffer_putstr(&nameb, lookaside); - if (lookaside[strlen(lookaside) - 1] != '.') { - if (isc_buffer_availablelength(&nameb) < 1) - fatal("DLV origin '%s' is too long", lookaside); - isc_buffer_putstr(&nameb, "."); - } - } - - result = dns_rdata_tofmttext(&ds, (dns_name_t *) NULL, 0, 0, 0, "", - &textb); - - if (result != ISC_R_SUCCESS) - fatal("can't print rdata"); - - result = dns_rdataclass_totext(rdclass, &classb); - if (result != ISC_R_SUCCESS) - fatal("can't print class"); - - isc_buffer_usedregion(&nameb, &r); - printf("%.*s ", (int)r.length, r.base); - - if (emitttl) - printf("%u ", ttl); - - isc_buffer_usedregion(&classb, &r); - printf("%.*s", (int)r.length, r.base); - - if (lookaside == NULL) { - if (cds) - printf(" CDS "); - else - printf(" DS "); - } else - printf(" DLV "); - - isc_buffer_usedregion(&textb, &r); - printf("%.*s\n", (int)r.length, r.base); -} - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] keyfile\n\n", program); - fprintf(stderr, " %s [options] -f zonefile [zonename]\n\n", program); - fprintf(stderr, " %s [options] -s dnsname\n\n", program); - fprintf(stderr, " %s [-h|-V]\n\n", program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, "Options:\n" -" -1: digest algorithm SHA-1\n" -" -2: digest algorithm SHA-256\n" -" -a algorithm: digest algorithm (SHA-1, SHA-256, SHA-384 or GOST)\n" -" -A: include all keys in DS set, not just KSKs (-f only)\n" -" -c class: rdata class for DS set (default IN) (-f or -s only)\n" -" -C: print CDS records\n" -" -f zonefile: read keys from a zone file\n" -" -h: print help information\n" -" -K directory: where to find key or keyset files\n" -" -l zone: print DLV records in the given lookaside zone\n" -" -s: read keys from keyset- file\n" -" -T: TTL of output records (omitted by default)\n" -" -v level: verbosity\n" -" -V: print version information\n"); - fprintf(stderr, "Output: DS, DLV, or CDS RRs\n"); - - exit (-1); -} - -int -main(int argc, char **argv) { - char *algname = NULL, *classname = NULL; - char *filename = NULL, *dir = NULL, *namestr; - char *lookaside = NULL; - char *endp, *arg1; - int ch; - dns_dsdigest_t dtype = DNS_DSDIGEST_SHA1; - bool cds = false; - bool both = true; - bool usekeyset = false; - bool showall = false; - isc_result_t result; - isc_log_t *log = NULL; - isc_entropy_t *ectx = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata; - - dns_rdata_init(&rdata); - - if (argc == 1) - usage(); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("out of memory"); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - -#define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:hV" - while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) { - switch (ch) { - case '1': - dtype = DNS_DSDIGEST_SHA1; - both = false; - break; - case '2': - dtype = DNS_DSDIGEST_SHA256; - both = false; - break; - case 'A': - showall = true; - break; - case 'a': - algname = isc_commandline_argument; - both = false; - break; - case 'C': - if (lookaside != NULL) - fatal("lookaside and CDS are mutually" - " exclusive"); - cds = true; - break; - case 'c': - classname = isc_commandline_argument; - break; - case 'd': - fprintf(stderr, "%s: the -d option is deprecated; " - "use -K\n", program); - /* fall through */ - case 'K': - dir = isc_commandline_argument; - if (strlen(dir) == 0U) - fatal("directory must be non-empty string"); - break; - case 'f': - filename = isc_commandline_argument; - break; - case 'l': - if (cds) - fatal("lookaside and CDS are mutually" - " exclusive"); - lookaside = isc_commandline_argument; - if (strlen(lookaside) == 0U) - fatal("lookaside must be a non-empty string"); - break; - case 's': - usekeyset = true; - break; - case 'T': - emitttl = true; - ttl = atol(isc_commandline_argument); - break; - case 'v': - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (algname != NULL) { - if (strcasecmp(algname, "SHA1") == 0 || - strcasecmp(algname, "SHA-1") == 0) - dtype = DNS_DSDIGEST_SHA1; - else if (strcasecmp(algname, "SHA256") == 0 || - strcasecmp(algname, "SHA-256") == 0) - dtype = DNS_DSDIGEST_SHA256; -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - else if (strcasecmp(algname, "GOST") == 0) - dtype = DNS_DSDIGEST_GOST; -#endif - else if (strcasecmp(algname, "SHA384") == 0 || - strcasecmp(algname, "SHA-384") == 0) - dtype = DNS_DSDIGEST_SHA384; - else - fatal("unknown algorithm %s", algname); - } - - rdclass = strtoclass(classname); - - if (usekeyset && filename != NULL) - fatal("cannot use both -s and -f"); - - /* When not using -f, -A is implicit */ - if (filename == NULL) - showall = true; - - /* - * Use local variable arg1 so that clang can correctly analyse - * reachable paths rather than 'argc < isc_commandline_index + 1'. - */ - arg1 = argv[isc_commandline_index]; - if (arg1 == NULL && filename == NULL) { - fatal("the key file name was not specified"); - } - if (arg1 != NULL && argv[isc_commandline_index + 1] != NULL) { - fatal("extraneous arguments"); - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - result = dst_lib_init(mctx, ectx, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not initialize hash"); - isc_entropy_stopcallbacksources(ectx); - - setup_logging(mctx, &log); - - dns_rdataset_init(&rdataset); - - if (usekeyset || filename != NULL) { - if (arg1 == NULL) { - /* using file name as the zone name */ - namestr = filename; - } else { - namestr = arg1; - } - - result = initname(namestr); - if (result != ISC_R_SUCCESS) { - fatal("could not initialize name %s", namestr); - } - - if (usekeyset) { - result = loadkeyset(dir, &rdataset); - } else { - INSIST(filename != NULL); - result = loadset(filename, &rdataset); - } - - if (result != ISC_R_SUCCESS) { - fatal("could not load DNSKEY set: %s\n", - isc_result_totext(result)); - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_init(&rdata); - dns_rdataset_current(&rdataset, &rdata); - - if (verbose > 2) { - logkey(&rdata); - } - - if (both) { - emit(DNS_DSDIGEST_SHA1, showall, lookaside, - cds, &rdata); - emit(DNS_DSDIGEST_SHA256, showall, lookaside, - cds, &rdata); - } else { - emit(dtype, showall, lookaside, cds, &rdata); - } - } - } else { - unsigned char key_buf[DST_KEY_MAXSIZE]; - - loadkey(arg1, key_buf, DST_KEY_MAXSIZE, &rdata); - - if (both) { - emit(DNS_DSDIGEST_SHA1, showall, lookaside, cds, - &rdata); - emit(DNS_DSDIGEST_SHA256, showall, lookaside, cds, - &rdata); - } else { - emit(dtype, showall, lookaside, cds, &rdata); - } - } - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - cleanup_logging(&log); - isc_hash_destroy(); - dst_lib_destroy(); - cleanup_entropy(&ectx); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - fflush(stdout); - if (ferror(stdout)) { - fprintf(stderr, "write error\n"); - return (1); - } else - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-dsfromkey.docbook b/bin/dnssec-pkcs11/dnssec-dsfromkey.docbook deleted file mode 100644 index c2d66d7..0000000 --- a/bin/dnssec-pkcs11/dnssec-dsfromkey.docbook +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - 2012-05-02 - - - ISC - Internet Systems Consortium, Inc. - - - - dnssec-dsfromkey - 8 - BIND9 - - - - dnssec-dsfromkey - DNSSEC DS RR generation tool - - - - - 2008 - 2009 - 2010 - 2011 - 2012 - 2014 - 2015 - 2016 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-dsfromkey - - - - - - - - - - - - - keyfile - - - dnssec-dsfromkey - - - - - - - - - - - - - - - dnsname - - - dnssec-dsfromkey - - - - - - - - - - - - - - -s - dnsname - - - dnssec-dsfromkey - - - - - - - - DESCRIPTION - - - The dnssec-dsfromkey command outputs DS (Delegation - Signer) resource records (RRs) and other similarly-constructed RRs: - with the option it outputs DLV (DNSSEC Lookaside - Validation) RRs; or with the it outputs CDS (Child - DS) RRs. - - - - The input keys can be specified in a number of ways: - - - - By default, dnssec-dsfromkey reads a key file - named like Knnnn.+aaa+iiiii.key, as generated - by dnssec-keygen. - - - - With the - option, dnssec-dsfromkey reads keys from a zone file - or partial zone file (which can contain just the DNSKEY records). - - - - With the - option, dnssec-dsfromkey reads - a keyset- file, as generated - by dnssec-keygen . - - - - - OPTIONS - - - - -1 - - - An abbreviation for - - - - - - -2 - - - An abbreviation for - - - - - - -a algorithm - - - Specify a digest algorithm to use when converting DNSKEY - records to DS records. This option can be repeated, so - that multiple DS records are created for each DNSKEY - record. - - - The algorithm must be one of - SHA-1, SHA-256, or SHA-384. These values are case insensitive, - and the hyphen may be omitted. If no algorithm is specified, - the default is to use both SHA-1 and SHA-256. - - - - - - -A - - - Include ZSKs when generating DS records. Without this option, only - keys which have the KSK flag set will be converted to DS records - and printed. Useful only in zone file mode. - - - - - - -c class - - - Specifies the DNS class (default is IN). Useful only - in keyset or - zone file mode. - - - - - - -C - - - Generate CDS records rather than DS records. This is mutually - exclusive with the option for generating DLV - records. - - - - - - -f file - - - Zone file mode: dnssec-dsfromkey's - final dnsname argument is - the DNS domain name of a zone whose master file can be read - from . If the zone name is the same as - , then it may be omitted. - - - If file is "-", then - the zone data is read from the standard input. This makes it - possible to use the output of the dig - command as input, as in: - - - dig dnskey example.com | dnssec-dsfromkey -f - example.com - - - - - - -h - - - Prints usage information. - - - - - - -K directory - - - Look for key files or keyset- files in - . - - - - - - -l domain - - - Generate a DLV set instead of a DS set. The specified - domain is appended to the name for each - record in the set. - This is mutually exclusive with the option - for generating CDS records. - - - - - - -s - - - Keyset mode: dnssec-dsfromkey's - final dnsname argument is the DNS - domain name used to locate a keyset- file. - - - - - - -T TTL - - - Specifies the TTL of the DS records. By default the TTL is omitted. - - - - - - -v level - - - Sets the debugging level. - - - - - - -V - - - Prints version information. - - - - - - - EXAMPLE - - - To build the SHA-256 DS RR from the - Kexample.com.+003+26160 - keyfile name, you can issue the following command: - - dnssec-dsfromkey -2 Kexample.com.+003+26160 - - - The command would print something like: - - example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0C5EA0B94 - - - - - FILES - - - The keyfile can be designated by the key identification - Knnnn.+aaa+iiiii or the full file name - Knnnn.+aaa+iiiii.key as generated by - dnssec-keygen8. - - - The keyset file name is built from the , - the string keyset- and the - . - - - - CAVEAT - - - A keyfile error can give a "file not found" even if the file exists. - - - - SEE ALSO - - - dnssec-keygen8 - , - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 3658 (DS RRs), - RFC 4431 (DLV RRs), - RFC 4509 (SHA-256 for DS RRs), - RFC 6605 (SHA-384 for DS RRs), - RFC 7344 (CDS and CDNSKEY RRs). - - - - diff --git a/bin/dnssec-pkcs11/dnssec-dsfromkey.html b/bin/dnssec-pkcs11/dnssec-dsfromkey.html deleted file mode 100644 index 0f6d5c7..0000000 --- a/bin/dnssec-pkcs11/dnssec-dsfromkey.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - -dnssec-dsfromkey - - -
-
-
-

Name

-

dnssec-dsfromkey — DNSSEC DS RR generation tool

-
-
-

Synopsis

-

dnssec-dsfromkey [ -1 | -2 | -a alg ] [ -C | -l domain ] [-T TTL] [-v level] [-K directory] {keyfile}

-

dnssec-dsfromkey [ -1 | -2 | -a alg ] [ -C | -l domain ] [-T TTL] [-v level] [-c class] [-A] {-f file} [dnsname]

-

dnssec-dsfromkey [ -1 | -2 | -a alg ] [ -C | -l domain ] [-T TTL] [-v level] [-c class] [-K directory] {-s} {dnsname}

-

dnssec-dsfromkey [ -h | -V ]

-
-
-

DESCRIPTION

-

- The dnssec-dsfromkey command outputs DS (Delegation - Signer) resource records (RRs) and other similarly-constructed RRs: - with the -l option it outputs DLV (DNSSEC Lookaside - Validation) RRs; or with the -C it outputs CDS (Child - DS) RRs. -

-

- The input keys can be specified in a number of ways: -

-

- By default, dnssec-dsfromkey reads a key file - named like Knnnn.+aaa+iiiii.key, as generated - by dnssec-keygen. -

-

- With the -f file - option, dnssec-dsfromkey reads keys from a zone file - or partial zone file (which can contain just the DNSKEY records). -

-

- With the -s - option, dnssec-dsfromkey reads - a keyset- file, as generated - by dnssec-keygen -C. -

-
-
-

OPTIONS

-
-
-1
-

- An abbreviation for -a SHA1 -

-
-2
-

- An abbreviation for -a SHA-256 -

-
-a algorithm
-
-

- Specify a digest algorithm to use when converting DNSKEY - records to DS records. This option can be repeated, so - that multiple DS records are created for each DNSKEY - record. -

-

- The algorithm must be one of - SHA-1, SHA-256, or SHA-384. These values are case insensitive, - and the hyphen may be omitted. If no algorithm is specified, - the default is to use both SHA-1 and SHA-256. -

-
-
-A
-

- Include ZSKs when generating DS records. Without this option, only - keys which have the KSK flag set will be converted to DS records - and printed. Useful only in -f zone file mode. -

-
-c class
-

- Specifies the DNS class (default is IN). Useful only - in -s keyset or -f - zone file mode. -

-
-C
-

- Generate CDS records rather than DS records. This is mutually - exclusive with the -l option for generating DLV - records. -

-
-f file
-
-

- Zone file mode: dnssec-dsfromkey's - final dnsname argument is - the DNS domain name of a zone whose master file can be read - from file. If the zone name is the same as - file, then it may be omitted. -

-

- If file is "-", then - the zone data is read from the standard input. This makes it - possible to use the output of the dig - command as input, as in: -

-

- dig dnskey example.com | dnssec-dsfromkey -f - example.com -

-
-
-h
-

- Prints usage information. -

-
-K directory
-

- Look for key files or keyset- files in - directory. -

-
-l domain
-

- Generate a DLV set instead of a DS set. The specified - domain is appended to the name for each - record in the set. - This is mutually exclusive with the -C option - for generating CDS records. -

-
-s
-

- Keyset mode: dnssec-dsfromkey's - final dnsname argument is the DNS - domain name used to locate a keyset- file. -

-
-T TTL
-

- Specifies the TTL of the DS records. By default the TTL is omitted. -

-
-v level
-

- Sets the debugging level. -

-
-V
-

- Prints version information. -

-
-
-
-

EXAMPLE

-

- To build the SHA-256 DS RR from the - Kexample.com.+003+26160 - keyfile name, you can issue the following command: -

-

dnssec-dsfromkey -2 Kexample.com.+003+26160 -

-

- The command would print something like: -

-

example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0C5EA0B94 -

-
-
-

FILES

-

- The keyfile can be designated by the key identification - Knnnn.+aaa+iiiii or the full file name - Knnnn.+aaa+iiiii.key as generated by - dnssec-keygen(8). -

-

- The keyset file name is built from the directory, - the string keyset- and the - dnsname. -

-
-
-

CAVEAT

-

- A keyfile error can give a "file not found" even if the file exists. -

-
-
-

SEE ALSO

-

dnssec-keygen(8), - dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 3658 (DS RRs), - RFC 4431 (DLV RRs), - RFC 4509 (SHA-256 for DS RRs), - RFC 6605 (SHA-384 for DS RRs), - RFC 7344 (CDS and CDNSKEY RRs). -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-importkey.8 b/bin/dnssec-pkcs11/dnssec-importkey.8 deleted file mode 100644 index 14de556..0000000 --- a/bin/dnssec-pkcs11/dnssec-importkey.8 +++ /dev/null @@ -1,138 +0,0 @@ -.\" Copyright (C) 2013-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-importkey -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: August 21, 2015 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-IMPORTKEY" "8" "August 21, 2015" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-importkey \- import DNSKEY records from external systems so they can be managed -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-importkey\fR\ 'u -\fBdnssec\-importkey\fR [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-P\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] {\fBkeyfile\fR} -.HP \w'\fBdnssec\-importkey\fR\ 'u -\fBdnssec\-importkey\fR {\fB\-f\ \fR\fB\fIfilename\fR\fR} [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-P\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fBdnsname\fR] -.SH "DESCRIPTION" -.PP -\fBdnssec\-importkey\fR -reads a public DNSKEY record and generates a pair of \&.key/\&.private files\&. The DNSKEY record may be read from an existing \&.key file, in which case a corresponding \&.private file will be generated, or it may be read from any other file or from the standard input, in which case both \&.key and \&.private files will be generated\&. -.PP -The newly\-created \&.private file does -\fInot\fR -contain private key data, and cannot be used for signing\&. However, having a \&.private file makes it possible to set publication (\fB\-P\fR) and deletion (\fB\-D\fR) times for the key, which means the public key can be added to and removed from the DNSKEY RRset on schedule even if the true private key is stored offline\&. -.SH "OPTIONS" -.PP -\-f \fIfilename\fR -.RS 4 -Zone file mode: instead of a public keyfile name, the argument is the DNS domain name of a zone master file, which can be read from -\fBfile\fR\&. If the domain name is the same as -\fBfile\fR, then it may be omitted\&. -.sp -If -\fBfile\fR -is set to -"\-", then the zone data is read from the standard input\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Sets the directory in which the key files are to reside\&. -.RE -.PP -\-L \fIttl\fR -.RS 4 -Sets the default TTL to use for this key when it is converted into a DNSKEY RR\&. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence\&. Setting the default TTL to -0 -or -none -removes it\&. -.RE -.PP -\-h -.RS 4 -Emit usage message and exit\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.SH "TIMING OPTIONS" -.PP -Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS\&. If the argument begins with a \*(Aq+\*(Aq or \*(Aq\-\*(Aq, it is interpreted as an offset from the present time\&. For convenience, if such an offset is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively\&. Without a suffix, the offset is computed in seconds\&. To explicitly prevent a date from being set, use \*(Aqnone\*(Aq or \*(Aqnever\*(Aq\&. -.PP -\-P \fIdate/offset\fR -.RS 4 -Sets the date on which a key is to be published to the zone\&. After that date, the key will be included in the zone but will not be used to sign it\&. -.RE -.PP -\-P sync \fIdate/offset\fR -.RS 4 -Sets the date on which CDS and CDNSKEY records that match this key are to be published to the zone\&. -.RE -.PP -\-D \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be deleted\&. After that date, the key will no longer be included in the zone\&. (It may remain in the key repository, however\&.) -.RE -.PP -\-D sync \fIdate/offset\fR -.RS 4 -Sets the date on which the CDS and CDNSKEY records that match this key are to be deleted\&. -.RE -.SH "FILES" -.PP -A keyfile can be designed by the key identification -Knnnn\&.+aaa+iiiii -or the full file name -Knnnn\&.+aaa+iiiii\&.key -as generated by -dnssec\-keygen(8)\&. -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 5011\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2013-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-importkey.c b/bin/dnssec-pkcs11/dnssec-importkey.c deleted file mode 100644 index 52863a1..0000000 --- a/bin/dnssec-pkcs11/dnssec-importkey.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-importkey"; -int verbose; - -static dns_rdataclass_t rdclass; -static dns_fixedname_t fixed; -static dns_name_t *name = NULL; -static isc_mem_t *mctx = NULL; -static bool setpub = false, setdel = false; -static bool setttl = false; -static isc_stdtime_t pub = 0, del = 0; -static dns_ttl_t ttl = 0; -static isc_stdtime_t syncadd = 0, syncdel = 0; -static bool setsyncadd = false; -static bool setsyncdel = false; - -static isc_result_t -initname(char *setname) { - isc_result_t result; - isc_buffer_t buf; - - name = dns_fixedname_initname(&fixed); - - isc_buffer_init(&buf, setname, strlen(setname)); - isc_buffer_add(&buf, strlen(setname)); - result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); - return (result); -} - -static void -db_load_from_stream(dns_db_t *db, FILE *fp) { - isc_result_t result; - dns_rdatacallbacks_t callbacks; - - dns_rdatacallbacks_init(&callbacks); - result = dns_db_beginload(db, &callbacks); - if (result != ISC_R_SUCCESS) - fatal("dns_db_beginload failed: %s", isc_result_totext(result)); - - result = dns_master_loadstream(fp, name, name, rdclass, 0, - &callbacks, mctx); - if (result != ISC_R_SUCCESS) - fatal("can't load from input: %s", isc_result_totext(result)); - - result = dns_db_endload(db, &callbacks); - if (result != ISC_R_SUCCESS) - fatal("dns_db_endload failed: %s", isc_result_totext(result)); -} - -static isc_result_t -loadset(const char *filename, dns_rdataset_t *rdataset) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - char setname[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, setname, sizeof(setname)); - - result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, - rdclass, 0, NULL, &db); - if (result != ISC_R_SUCCESS) - fatal("can't create database"); - - if (strcmp(filename, "-") == 0) { - db_load_from_stream(db, stdin); - filename = "input"; - } else { - result = dns_db_load3(db, filename, dns_masterformat_text, - DNS_MASTER_NOTTL); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - fatal("can't load %s: %s", filename, - isc_result_totext(result)); - } - - result = dns_db_findnode(db, name, false, &node); - if (result != ISC_R_SUCCESS) - fatal("can't find %s node in %s", setname, filename); - - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, - 0, 0, rdataset, NULL); - - if (result == ISC_R_NOTFOUND) - fatal("no DNSKEY RR for %s in %s", setname, filename); - else if (result != ISC_R_SUCCESS) - fatal("dns_db_findrdataset"); - - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - return (result); -} - -static void -loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, - dns_rdata_t *rdata) -{ - isc_result_t result; - dst_key_t *key = NULL; - isc_buffer_t keyb; - isc_region_t r; - - dns_rdata_init(rdata); - - isc_buffer_init(&keyb, key_buf, key_buf_size); - - result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, - mctx, &key); - if (result != ISC_R_SUCCESS) - fatal("invalid keyfile name %s: %s", - filename, isc_result_totext(result)); - - if (verbose > 2) { - char keystr[DST_KEY_FORMATSIZE]; - - dst_key_format(key, keystr, sizeof(keystr)); - fprintf(stderr, "%s: %s\n", program, keystr); - } - - result = dst_key_todns(key, &keyb); - if (result != ISC_R_SUCCESS) - fatal("can't decode key"); - - isc_buffer_usedregion(&keyb, &r); - dns_rdata_fromregion(rdata, dst_key_class(key), - dns_rdatatype_dnskey, &r); - - rdclass = dst_key_class(key); - - name = dns_fixedname_initname(&fixed); - result = dns_name_copy(dst_key_name(key), name, NULL); - if (result != ISC_R_SUCCESS) - fatal("can't copy name"); - - dst_key_free(&key); -} - -static void -emit(const char *dir, dns_rdata_t *rdata) { - isc_result_t result; - char keystr[DST_KEY_FORMATSIZE]; - char pubname[1024]; - char priname[1024]; - isc_buffer_t buf; - dst_key_t *key = NULL, *tmp = NULL; - - isc_buffer_init(&buf, rdata->data, rdata->length); - isc_buffer_add(&buf, rdata->length); - result = dst_key_fromdns(name, rdclass, &buf, mctx, &key); - if (result != ISC_R_SUCCESS) { - fatal("dst_key_fromdns: %s", isc_result_totext(result)); - } - - isc_buffer_init(&buf, pubname, sizeof(pubname)); - result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); - if (result != ISC_R_SUCCESS) { - fatal("Failed to build public key filename: %s", - isc_result_totext(result)); - } - isc_buffer_init(&buf, priname, sizeof(priname)); - result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); - if (result != ISC_R_SUCCESS) { - fatal("Failed to build private key filename: %s", - isc_result_totext(result)); - } - - result = dst_key_fromfile(dst_key_name(key), dst_key_id(key), - dst_key_alg(key), - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - dir, mctx, &tmp); - if (result == ISC_R_SUCCESS) { - if (dst_key_isprivate(tmp) && !dst_key_isexternal(tmp)) - fatal("Private key already exists in %s", priname); - dst_key_free(&tmp); - } - - dst_key_setexternal(key, true); - if (setpub) - dst_key_settime(key, DST_TIME_PUBLISH, pub); - if (setdel) - dst_key_settime(key, DST_TIME_DELETE, del); - if (setsyncadd) - dst_key_settime(key, DST_TIME_SYNCPUBLISH, syncadd); - if (setsyncdel) - dst_key_settime(key, DST_TIME_SYNCDELETE, syncdel); - - if (setttl) - dst_key_setttl(key, ttl); - - result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - dir); - if (result != ISC_R_SUCCESS) { - dst_key_format(key, keystr, sizeof(keystr)); - fatal("Failed to write key %s: %s", keystr, - isc_result_totext(result)); - } - printf("%s\n", pubname); - - isc_buffer_clear(&buf); - result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); - if (result != ISC_R_SUCCESS) { - fatal("Failed to build private key filename: %s", - isc_result_totext(result)); - } - printf("%s\n", priname); - dst_key_free(&key); -} - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s options [-K dir] keyfile\n\n", program); - fprintf(stderr, " %s options -f file [keyname]\n\n", program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f file: read key from zone file\n"); - fprintf(stderr, " -K : directory in which to store " - "the key files\n"); - fprintf(stderr, " -L ttl: set default key TTL\n"); - fprintf(stderr, " -v \n"); - fprintf(stderr, " -V: print version information\n"); - fprintf(stderr, " -h: print usage and exit\n"); - fprintf(stderr, "Timing options:\n"); - fprintf(stderr, " -P date/[+-]offset/none: set/unset key " - "publication date\n"); - fprintf(stderr, " -P sync date/[+-]offset/none: set/unset " - "CDS and CDNSKEY publication date\n"); - fprintf(stderr, " -D date/[+-]offset/none: set/unset key " - "deletion date\n"); - fprintf(stderr, " -D sync date/[+-]offset/none: set/unset " - "CDS and CDNSKEY deletion date\n"); - - exit (-1); -} - -int -main(int argc, char **argv) { - char *classname = NULL; - char *filename = NULL, *dir = NULL, *namestr; - char *endp; - int ch; - isc_result_t result; - isc_log_t *log = NULL; - isc_entropy_t *ectx = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata; - isc_stdtime_t now; - - dns_rdata_init(&rdata); - isc_stdtime_get(&now); - - if (argc == 1) - usage(); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("out of memory"); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - -#define CMDLINE_FLAGS "D:f:hK:L:P:v:V" - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'D': - /* -Dsync ? */ - if (isoptarg("sync", argv, usage)) { - if (setsyncdel) - fatal("-D sync specified more than " - "once"); - - syncdel = strtotime(isc_commandline_argument, - now, now, &setsyncdel); - break; - } - /* -Ddnskey ? */ - (void)isoptarg("dnskey", argv, usage); - if (setdel) - fatal("-D specified more than once"); - - del = strtotime(isc_commandline_argument, - now, now, &setdel); - break; - case 'K': - dir = isc_commandline_argument; - if (strlen(dir) == 0U) - fatal("directory must be non-empty string"); - break; - case 'L': - ttl = strtottl(isc_commandline_argument); - setttl = true; - break; - case 'P': - /* -Psync ? */ - if (isoptarg("sync", argv, usage)) { - if (setsyncadd) - fatal("-P sync specified more than " - "once"); - - syncadd = strtotime(isc_commandline_argument, - now, now, &setsyncadd); - break; - } - /* -Pdnskey ? */ - (void)isoptarg("dnskey", argv, usage); - if (setpub) - fatal("-P specified more than once"); - - pub = strtotime(isc_commandline_argument, - now, now, &setpub); - break; - case 'f': - filename = isc_commandline_argument; - break; - case 'v': - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - rdclass = strtoclass(classname); - - if (argc < isc_commandline_index + 1 && filename == NULL) - fatal("the key file name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("extraneous arguments"); - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - result = dst_lib_init(mctx, ectx, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not initialize hash"); - isc_entropy_stopcallbacksources(ectx); - - setup_logging(mctx, &log); - - dns_rdataset_init(&rdataset); - - if (filename != NULL) { - if (argc < isc_commandline_index + 1) { - /* using filename as zone name */ - namestr = filename; - } else - namestr = argv[isc_commandline_index]; - - result = initname(namestr); - if (result != ISC_R_SUCCESS) - fatal("could not initialize name %s", namestr); - - result = loadset(filename, &rdataset); - - if (result != ISC_R_SUCCESS) - fatal("could not load DNSKEY set: %s\n", - isc_result_totext(result)); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - - dns_rdata_init(&rdata); - dns_rdataset_current(&rdataset, &rdata); - emit(dir, &rdata); - } - } else { - unsigned char key_buf[DST_KEY_MAXSIZE]; - - loadkey(argv[isc_commandline_index], key_buf, - DST_KEY_MAXSIZE, &rdata); - - emit(dir, &rdata); - } - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - cleanup_logging(&log); - isc_hash_destroy(); - dst_lib_destroy(); - cleanup_entropy(&ectx); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - fflush(stdout); - if (ferror(stdout)) { - fprintf(stderr, "write error\n"); - return (1); - } else - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-importkey.docbook b/bin/dnssec-pkcs11/dnssec-importkey.docbook deleted file mode 100644 index 176fa77..0000000 --- a/bin/dnssec-pkcs11/dnssec-importkey.docbook +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - 2014-02-20 - - - August 21, 2015 - ISC - Internet Systems Consortium, Inc. - - - - dnssec-importkey - 8 - BIND9 - - - - dnssec-importkey - import DNSKEY records from external systems so they can be managed - - - - - 2013 - 2014 - 2015 - 2016 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-importkey - - - - - - - - - - - - - dnssec-importkey - - - - - - - - - - - - - - - DESCRIPTION - - dnssec-importkey - reads a public DNSKEY record and generates a pair of - .key/.private files. The DNSKEY record may be read from an - existing .key file, in which case a corresponding .private file - will be generated, or it may be read from any other file or - from the standard input, in which case both .key and .private - files will be generated. - - - The newly-created .private file does not - contain private key data, and cannot be used for signing. - However, having a .private file makes it possible to set - publication () and deletion - () times for the key, which means the - public key can be added to and removed from the DNSKEY RRset - on schedule even if the true private key is stored offline. - - - - OPTIONS - - - - - -f filename - - - Zone file mode: instead of a public keyfile name, the argument - is the DNS domain name of a zone master file, which can be read - from . If the domain name is the same as - , then it may be omitted. - - - If is set to "-", then - the zone data is read from the standard input. - - - - - - -K directory - - - Sets the directory in which the key files are to reside. - - - - - - -L ttl - - - Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. Setting the default TTL to - 0 or none removes it. - - - - - - -h - - - Emit usage message and exit. - - - - - - -v level - - - Sets the debugging level. - - - - - - -V - - - Prints version information. - - - - - - - - TIMING OPTIONS - - - Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. - - - - - -P date/offset - - - Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. - - - - - - -P sync date/offset - - - Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. - - - - - - -D date/offset - - - Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) - - - - - - -D sync date/offset - - - Sets the date on which the CDS and CDNSKEY records that match - this key are to be deleted. - - - - - - - - FILES - - - A keyfile can be designed by the key identification - Knnnn.+aaa+iiiii or the full file name - Knnnn.+aaa+iiiii.key as generated by - dnssec-keygen8. - - - - SEE ALSO - - - dnssec-keygen8 - , - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 5011. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-importkey.html b/bin/dnssec-pkcs11/dnssec-importkey.html deleted file mode 100644 index 28a1395..0000000 --- a/bin/dnssec-pkcs11/dnssec-importkey.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - -dnssec-importkey - - -
-
-
-

Name

-

dnssec-importkey — import DNSKEY records from external systems so they can be managed

-
-
-

Synopsis

-

dnssec-importkey [-K directory] [-L ttl] [-P date/offset] [-P sync date/offset] [-D date/offset] [-D sync date/offset] [-h] [-v level] [-V] {keyfile}

-

dnssec-importkey {-f filename} [-K directory] [-L ttl] [-P date/offset] [-P sync date/offset] [-D date/offset] [-D sync date/offset] [-h] [-v level] [-V] [dnsname]

-
-
-

DESCRIPTION

-

dnssec-importkey - reads a public DNSKEY record and generates a pair of - .key/.private files. The DNSKEY record may be read from an - existing .key file, in which case a corresponding .private file - will be generated, or it may be read from any other file or - from the standard input, in which case both .key and .private - files will be generated. -

-

- The newly-created .private file does not - contain private key data, and cannot be used for signing. - However, having a .private file makes it possible to set - publication (-P) and deletion - (-D) times for the key, which means the - public key can be added to and removed from the DNSKEY RRset - on schedule even if the true private key is stored offline. -

-
-
-

OPTIONS

-
-
-f filename
-
-

- Zone file mode: instead of a public keyfile name, the argument - is the DNS domain name of a zone master file, which can be read - from file. If the domain name is the same as - file, then it may be omitted. -

-

- If file is set to "-", then - the zone data is read from the standard input. -

-
-
-K directory
-

- Sets the directory in which the key files are to reside. -

-
-L ttl
-

- Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. Setting the default TTL to - 0 or none removes it. -

-
-h
-

- Emit usage message and exit. -

-
-v level
-

- Sets the debugging level. -

-
-V
-

- Prints version information. -

-
-
-
-

TIMING OPTIONS

-

- Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. -

-
-
-P date/offset
-

- Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. -

-
-P sync date/offset
-

- Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. -

-
-D date/offset
-

- Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) -

-
-D sync date/offset
-

- Sets the date on which the CDS and CDNSKEY records that match - this key are to be deleted. -

-
-
-
-

FILES

-

- A keyfile can be designed by the key identification - Knnnn.+aaa+iiiii or the full file name - Knnnn.+aaa+iiiii.key as generated by - dnssec-keygen(8). -

-
-
-

SEE ALSO

-

dnssec-keygen(8), - dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 5011. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-keyfromlabel.8 b/bin/dnssec-pkcs11/dnssec-keyfromlabel.8 deleted file mode 100644 index 1b2a2f4..0000000 --- a/bin/dnssec-pkcs11/dnssec-keyfromlabel.8 +++ /dev/null @@ -1,305 +0,0 @@ -.\" Copyright (C) 2008-2012, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-keyfromlabel -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: August 27, 2015 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-KEYFROMLABEL" "8" "August 27, 2015" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-keyfromlabel \- DNSSEC key generation tool -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-keyfromlabel\fR\ 'u -\fBdnssec\-keyfromlabel\fR {\-l\ \fIlabel\fR} [\fB\-3\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-P\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-y\fR] {name} -.SH "DESCRIPTION" -.PP -\fBdnssec\-keyfromlabel\fR -generates a key pair of files that referencing a key object stored in a cryptographic hardware service module (HSM)\&. The private key file can be used for DNSSEC signing of zone data as if it were a conventional signing key created by -\fBdnssec\-keygen\fR, but the key material is stored within the HSM, and the actual signing takes place there\&. -.PP -The -\fBname\fR -of the key is specified on the command line\&. This must match the name of the zone for which the key is being generated\&. -.SH "OPTIONS" -.PP -\-a \fIalgorithm\fR -.RS 4 -Selects the cryptographic algorithm\&. The value of -\fBalgorithm\fR -must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448\&. These values are case insensitive\&. -.sp -If no algorithm is specified, then RSASHA1 will be used by default, unless the -\fB\-3\fR -option is specified, in which case NSEC3RSASHA1 will be used instead\&. (If -\fB\-3\fR -is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3\&.) -.sp -Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended\&. -.sp -Note 2: DH automatically sets the \-k flag\&. -.RE -.PP -\-3 -.RS 4 -Use an NSEC3\-capable algorithm to generate a DNSSEC key\&. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -Specifies the cryptographic hardware to use\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-l \fIlabel\fR -.RS 4 -Specifies the label for a key pair in the crypto hardware\&. -.sp -When -BIND -9 is built with OpenSSL\-based PKCS#11 support, the label is an arbitrary string that identifies a particular key\&. -.sp -When -BIND -9 is built with native PKCS#11 support, the label is a PKCS#11 URI string in the format "pkcs11:\fBkeyword\fR=\fIvalue\fR[;\fBkeyword\fR=\fIvalue\fR;\&.\&.\&.]" Keywords include "token", which identifies the HSM; "object", which identifies the key; and "pin\-source", which identifies a file from which the HSM\*(Aqs PIN code can be obtained\&. The label will be stored in the on\-disk "private" file\&. -.sp -If the label contains a -\fBpin\-source\fR -field, tools using the generated key files will be able to use the HSM for signing and other operations without any need for an operator to manually enter a PIN\&. Note: Making the HSM\*(Aqs PIN accessible in this manner may reduce the security advantage of using an HSM; be sure this is what you want to do before making use of this feature\&. -.RE -.PP -\-n \fInametype\fR -.RS 4 -Specifies the owner type of the key\&. The value of -\fBnametype\fR -must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY)\&. These values are case insensitive\&. -.RE -.PP -\-C -.RS 4 -Compatibility mode: generates an old\-style key, without any metadata\&. By default, -\fBdnssec\-keyfromlabel\fR -will include the key\*(Aqs creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc)\&. Keys that include this data may be incompatible with older versions of BIND; the -\fB\-C\fR -option suppresses them\&. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Indicates that the DNS record containing the key should have the specified class\&. If not specified, class IN is used\&. -.RE -.PP -\-f \fIflag\fR -.RS 4 -Set the specified flag in the flag field of the KEY/DNSKEY record\&. The only recognized flags are KSK (Key Signing Key) and REVOKE\&. -.RE -.PP -\-G -.RS 4 -Generate a key, but do not publish it or sign with it\&. This option is incompatible with \-P and \-A\&. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBdnssec\-keyfromlabel\fR\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Sets the directory in which the key files are to be written\&. -.RE -.PP -\-k -.RS 4 -Generate KEY records rather than DNSKEY records\&. -.RE -.PP -\-L \fIttl\fR -.RS 4 -Sets the default TTL to use for this key when it is converted into a DNSKEY RR\&. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence\&. Setting the default TTL to -0 -or -none -removes it\&. -.RE -.PP -\-p \fIprotocol\fR -.RS 4 -Sets the protocol value for the key\&. The protocol is a number between 0 and 255\&. The default is 3 (DNSSEC)\&. Other possible values for this argument are listed in RFC 2535 and its successors\&. -.RE -.PP -\-S \fIkey\fR -.RS 4 -Generate a key as an explicit successor to an existing key\&. The name, algorithm, size, and type of the key will be set to match the predecessor\&. The activation date of the new key will be set to the inactivation date of the existing one\&. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days\&. -.RE -.PP -\-t \fItype\fR -.RS 4 -Indicates the use of the key\&. -\fBtype\fR -must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF\&. The default is AUTHCONF\&. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-y -.RS 4 -Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked\&. (This is only safe to use if you are sure you won\*(Aqt be using RFC 5011 trust anchor maintenance with either of the keys involved\&.) -.RE -.SH "TIMING OPTIONS" -.PP -Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS\&. If the argument begins with a \*(Aq+\*(Aq or \*(Aq\-\*(Aq, it is interpreted as an offset from the present time\&. For convenience, if such an offset is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively\&. Without a suffix, the offset is computed in seconds\&. To explicitly prevent a date from being set, use \*(Aqnone\*(Aq or \*(Aqnever\*(Aq\&. -.PP -\-P \fIdate/offset\fR -.RS 4 -Sets the date on which a key is to be published to the zone\&. After that date, the key will be included in the zone but will not be used to sign it\&. If not set, and if the \-G option has not been used, the default is "now"\&. -.RE -.PP -\-P sync \fIdate/offset\fR -.RS 4 -Sets the date on which the CDS and CDNSKEY records which match this key are to be published to the zone\&. -.RE -.PP -\-A \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be activated\&. After that date, the key will be included in the zone and used to sign it\&. If not set, and if the \-G option has not been used, the default is "now"\&. -.RE -.PP -\-R \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be revoked\&. After that date, the key will be flagged as revoked\&. It will be included in the zone and will be used to sign it\&. -.RE -.PP -\-I \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be retired\&. After that date, the key will still be included in the zone, but it will not be used to sign it\&. -.RE -.PP -\-D \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be deleted\&. After that date, the key will no longer be included in the zone\&. (It may remain in the key repository, however\&.) -.RE -.PP -\-D sync \fIdate/offset\fR -.RS 4 -Sets the date on which the CDS and CDNSKEY records which match this key are to be deleted\&. -.RE -.PP -\-i \fIinterval\fR -.RS 4 -Sets the prepublication interval for a key\&. If set, then the publication and activation dates must be separated by at least this much time\&. If the activation date is specified but the publication date isn\*(Aqt, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn\*(Aqt, then activation will be set to this much time after publication\&. -.sp -If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero\&. -.sp -As with date offsets, if the argument is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the interval is measured in years, months, weeks, days, hours, or minutes, respectively\&. Without a suffix, the interval is measured in seconds\&. -.RE -.SH "GENERATED KEY FILES" -.PP -When -\fBdnssec\-keyfromlabel\fR -completes successfully, it prints a string of the form -Knnnn\&.+aaa+iiiii -to the standard output\&. This is an identification string for the key files it has generated\&. -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -nnnn -is the key name\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -aaa -is the numeric representation of the algorithm\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -iiiii -is the key identifier (or footprint)\&. -.RE -.PP -\fBdnssec\-keyfromlabel\fR -creates two files, with names based on the printed string\&. -Knnnn\&.+aaa+iiiii\&.key -contains the public key, and -Knnnn\&.+aaa+iiiii\&.private -contains the private key\&. -.PP -The -\&.key -file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement)\&. -.PP -The -\&.private -file contains algorithm\-specific fields\&. For obvious security reasons, this file does not have general read permission\&. -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 4034, -The PKCS#11 URI Scheme (draft\-pechanec\-pkcs11uri\-13)\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2008-2012, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-keyfromlabel.c b/bin/dnssec-pkcs11/dnssec-keyfromlabel.c deleted file mode 100644 index 9da7312..0000000 --- a/bin/dnssec-pkcs11/dnssec-keyfromlabel.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -#define MAX_RSA 4096 /* should be long enough... */ - -const char *program = "dnssec-keyfromlabel"; -int verbose; - -#define DEFAULT_ALGORITHM "RSASHA1" -#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1" - -static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |" - " NSEC3DSA | NSEC3RSASHA1 |" - " RSASHA256 | RSASHA512 | ECCGOST |" - " ECDSAP256SHA256 | ECDSAP384SHA384 |" - " ED25519 | ED448"; - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s -l label [options] name\n\n", - program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, "Required options:\n"); - fprintf(stderr, " -l label: label of the key pair\n"); - fprintf(stderr, " name: owner of the key\n"); - fprintf(stderr, "Other options:\n"); - fprintf(stderr, " -a algorithm: %s\n", algs); - fprintf(stderr, " (default: RSASHA1, or " - "NSEC3RSASHA1 if using -3)\n"); - fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); - fprintf(stderr, " -c class (default: IN)\n"); - fprintf(stderr, " -E :\n"); -#if defined(PKCS11CRYPTO) - fprintf(stderr, " path to PKCS#11 provider library " - "(default is %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, " name of an OpenSSL engine to use " - "(default is \"pkcs11\")\n"); -#else - fprintf(stderr, " name of an OpenSSL engine to use\n"); -#endif - fprintf(stderr, " -f keyflag: KSK | REVOKE\n"); - fprintf(stderr, " -K directory: directory in which to place " - "key files\n"); - fprintf(stderr, " -k: generate a TYPE=KEY key\n"); - fprintf(stderr, " -L ttl: default key TTL\n"); - fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n"); - fprintf(stderr, " (DNSKEY generation defaults to ZONE\n"); - fprintf(stderr, " -p protocol: default: 3 [dnssec]\n"); - fprintf(stderr, " -t type: " - "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " - "(default: AUTHCONF)\n"); - fprintf(stderr, " -y: permit keys that might collide\n"); - fprintf(stderr, " -v verbose level\n"); - fprintf(stderr, " -V: print version information\n"); - fprintf(stderr, "Date options:\n"); - fprintf(stderr, " -P date/[+-]offset: set key publication date\n"); - fprintf(stderr, " -P sync date/[+-]offset: set CDS and CDNSKEY " - "publication date\n"); - fprintf(stderr, " -A date/[+-]offset: set key activation date\n"); - fprintf(stderr, " -R date/[+-]offset: set key revocation date\n"); - fprintf(stderr, " -I date/[+-]offset: set key inactivation date\n"); - fprintf(stderr, " -D date/[+-]offset: set key deletion date\n"); - fprintf(stderr, " -D sync date/[+-]offset: set CDS and CDNSKEY " - "deletion date\n"); - fprintf(stderr, " -G: generate key only; do not set -P or -A\n"); - fprintf(stderr, " -C: generate a backward-compatible key, omitting" - " all dates\n"); - fprintf(stderr, " -S : generate a successor to an existing " - "key\n"); - fprintf(stderr, " -i : prepublication interval for " - "successor key " - "(default: 30 days)\n"); - fprintf(stderr, "Output:\n"); - fprintf(stderr, " K++.key, " - "K++.private\n"); - - exit (-1); -} - -int -main(int argc, char **argv) { - char *algname = NULL, *freeit = NULL; - char *nametype = NULL, *type = NULL; - const char *directory = NULL; - const char *predecessor = NULL; - dst_key_t *prevkey = NULL; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - char *classname = NULL; - char *endp; - dst_key_t *key = NULL; - dns_fixedname_t fname; - dns_name_t *name; - uint16_t flags = 0, kskflag = 0, revflag = 0; - dns_secalg_t alg; - bool oldstyle = false; - isc_mem_t *mctx = NULL; - int ch; - int protocol = -1, signatory = 0; - isc_result_t ret; - isc_textregion_t r; - char filename[255]; - isc_buffer_t buf; - isc_log_t *log = NULL; - isc_entropy_t *ectx = NULL; - dns_rdataclass_t rdclass; - int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; - char *label = NULL; - dns_ttl_t ttl = 0; - isc_stdtime_t publish = 0, activate = 0, revoke = 0; - isc_stdtime_t inactive = 0, deltime = 0; - isc_stdtime_t now; - int prepub = -1; - bool setpub = false, setact = false; - bool setrev = false, setinact = false; - bool setdel = false, setttl = false; - bool unsetpub = false, unsetact = false; - bool unsetrev = false, unsetinact = false; - bool unsetdel = false; - bool genonly = false; - bool use_nsec3 = false; - bool avoid_collisions = true; - bool exact; - unsigned char c; - isc_stdtime_t syncadd = 0, syncdel = 0; - bool unsetsyncadd = false, setsyncadd = false; - bool unsetsyncdel = false, setsyncdel = false; - - if (argc == 1) - usage(); - - RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - isc_stdtime_get(&now); - -#define CMDLINE_FLAGS "3A:a:Cc:D:E:Ff:GhI:i:kK:L:l:n:P:p:R:S:t:v:Vy" - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case '3': - use_nsec3 = true; - break; - case 'a': - algname = isc_commandline_argument; - break; - case 'C': - oldstyle = true; - break; - case 'c': - classname = isc_commandline_argument; - break; - case 'E': - engine = isc_commandline_argument; - break; - case 'f': - c = (unsigned char)(isc_commandline_argument[0]); - if (toupper(c) == 'K') - kskflag = DNS_KEYFLAG_KSK; - else if (toupper(c) == 'R') - revflag = DNS_KEYFLAG_REVOKE; - else - fatal("unknown flag '%s'", - isc_commandline_argument); - break; - case 'K': - directory = isc_commandline_argument; - ret = try_dir(directory); - if (ret != ISC_R_SUCCESS) - fatal("cannot open directory %s: %s", - directory, isc_result_totext(ret)); - break; - case 'k': - options |= DST_TYPE_KEY; - break; - case 'L': - ttl = strtottl(isc_commandline_argument); - setttl = true; - break; - case 'l': - label = isc_mem_strdup(mctx, isc_commandline_argument); - break; - case 'n': - nametype = isc_commandline_argument; - break; - case 'p': - protocol = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || protocol < 0 || protocol > 255) - fatal("-p must be followed by a number " - "[0..255]"); - break; - case 't': - type = isc_commandline_argument; - break; - case 'v': - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - case 'y': - avoid_collisions = false; - break; - case 'G': - genonly = true; - break; - case 'P': - /* -Psync ? */ - if (isoptarg("sync", argv, usage)) { - if (unsetsyncadd || setsyncadd) - fatal("-P sync specified more than " - "once"); - - syncadd = strtotime(isc_commandline_argument, - now, now, &setsyncadd); - unsetsyncadd = !setsyncadd; - break; - } - /* -Pdnskey ? */ - (void)isoptarg("dnskey", argv, usage); - if (setpub || unsetpub) - fatal("-P specified more than once"); - - publish = strtotime(isc_commandline_argument, - now, now, &setpub); - unsetpub = !setpub; - break; - case 'A': - if (setact || unsetact) - fatal("-A specified more than once"); - - activate = strtotime(isc_commandline_argument, - now, now, &setact); - unsetact = !setact; - break; - case 'R': - if (setrev || unsetrev) - fatal("-R specified more than once"); - - revoke = strtotime(isc_commandline_argument, - now, now, &setrev); - unsetrev = !setrev; - break; - case 'I': - if (setinact || unsetinact) - fatal("-I specified more than once"); - - inactive = strtotime(isc_commandline_argument, - now, now, &setinact); - unsetinact = !setinact; - break; - case 'D': - /* -Dsync ? */ - if (isoptarg("sync", argv, usage)) { - if (unsetsyncdel || setsyncdel) - fatal("-D sync specified more than " - "once"); - - syncdel = strtotime(isc_commandline_argument, - now, now, &setsyncdel); - unsetsyncdel = !setsyncdel; - break; - } - /* -Ddnskey ? */ - (void)isoptarg("dnskey", argv, usage); - if (setdel || unsetdel) - fatal("-D specified more than once"); - - deltime = strtotime(isc_commandline_argument, - now, now, &setdel); - unsetdel = !setdel; - break; - case 'S': - predecessor = isc_commandline_argument; - break; - case 'i': - prepub = strtottl(isc_commandline_argument); - break; - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - ret = dst_lib_init2(mctx, ectx, engine, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (ret != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(ret)); - - setup_logging(mctx, &log); - - if (predecessor == NULL) { - if (label == NULL) - fatal("the key label was not specified"); - if (argc < isc_commandline_index + 1) - fatal("the key name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("extraneous arguments"); - - name = dns_fixedname_initname(&fname); - isc_buffer_init(&buf, argv[isc_commandline_index], - strlen(argv[isc_commandline_index])); - isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); - ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); - if (ret != ISC_R_SUCCESS) - fatal("invalid key name %s: %s", - argv[isc_commandline_index], - isc_result_totext(ret)); - - if (strchr(label, ':') == NULL) { - char *l; - int len; - - len = strlen(label) + 8; - l = isc_mem_allocate(mctx, len); - if (l == NULL) - fatal("cannot allocate memory"); - snprintf(l, len, "pkcs11:%s", label); - isc_mem_free(mctx, label); - label = l; - } - - if (algname == NULL) { - if (use_nsec3) - algname = strdup(DEFAULT_NSEC3_ALGORITHM); - else - algname = strdup(DEFAULT_ALGORITHM); - if (algname == NULL) - fatal("strdup failed"); - freeit = algname; - if (verbose > 0) - fprintf(stderr, "no algorithm specified; " - "defaulting to %s\n", algname); - } - - if (strcasecmp(algname, "RSA") == 0) { -#ifndef PK11_MD5_DISABLE - fprintf(stderr, "The use of RSA (RSAMD5) is not " - "recommended.\nIf you still wish to " - "use RSA (RSAMD5) please specify " - "\"-a RSAMD5\"\n"); -#else - fprintf(stderr, - "The use of RSA (RSAMD5) was disabled\n"); - if (freeit != NULL) - free(freeit); - return (1); - } else if (strcasecmp(algname, "RSAMD5") == 0) { - fprintf(stderr, "The use of RSAMD5 was disabled\n"); -#endif - if (freeit != NULL) - free(freeit); - return (1); - } else { - r.base = algname; - r.length = strlen(algname); - ret = dns_secalg_fromtext(&alg, &r); - if (ret != ISC_R_SUCCESS) - fatal("unknown algorithm %s", algname); - if (alg == DST_ALG_DH) - options |= DST_TYPE_KEY; - } - - if (use_nsec3 && - alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && - alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 && - alg != DST_ALG_ECCGOST && - alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384 && - alg != DST_ALG_ED25519 && alg != DST_ALG_ED448) { - fatal("%s is incompatible with NSEC3; " - "do not use the -3 option", algname); - } - - if (type != NULL && (options & DST_TYPE_KEY) != 0) { - if (strcasecmp(type, "NOAUTH") == 0) - flags |= DNS_KEYTYPE_NOAUTH; - else if (strcasecmp(type, "NOCONF") == 0) - flags |= DNS_KEYTYPE_NOCONF; - else if (strcasecmp(type, "NOAUTHCONF") == 0) - flags |= (DNS_KEYTYPE_NOAUTH | - DNS_KEYTYPE_NOCONF); - else if (strcasecmp(type, "AUTHCONF") == 0) - /* nothing */; - else - fatal("invalid type %s", type); - } - - if (!oldstyle && prepub > 0) { - if (setpub && setact && (activate - prepub) < publish) - fatal("Activation and publication dates " - "are closer together than the\n\t" - "prepublication interval."); - - if (!setpub && !setact) { - setpub = setact = true; - publish = now; - activate = now + prepub; - } else if (setpub && !setact) { - setact = true; - activate = publish + prepub; - } else if (setact && !setpub) { - setpub = true; - publish = activate - prepub; - } - - if ((activate - prepub) < now) - fatal("Time until activation is shorter " - "than the\n\tprepublication interval."); - } - } else { - char keystr[DST_KEY_FORMATSIZE]; - isc_stdtime_t when; - int major, minor; - - if (prepub == -1) - prepub = (30 * 86400); - - if (algname != NULL) - fatal("-S and -a cannot be used together"); - if (nametype != NULL) - fatal("-S and -n cannot be used together"); - if (type != NULL) - fatal("-S and -t cannot be used together"); - if (setpub || unsetpub) - fatal("-S and -P cannot be used together"); - if (setact || unsetact) - fatal("-S and -A cannot be used together"); - if (use_nsec3) - fatal("-S and -3 cannot be used together"); - if (oldstyle) - fatal("-S and -C cannot be used together"); - if (genonly) - fatal("-S and -G cannot be used together"); - - ret = dst_key_fromnamedfile(predecessor, directory, - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - mctx, &prevkey); - if (ret != ISC_R_SUCCESS) - fatal("Invalid keyfile %s: %s", - predecessor, isc_result_totext(ret)); - if (!dst_key_isprivate(prevkey)) - fatal("%s is not a private key", predecessor); - - name = dst_key_name(prevkey); - alg = dst_key_alg(prevkey); - flags = dst_key_flags(prevkey); - -#ifdef PK11_MD5_DISABLE - if (alg == DST_ALG_RSAMD5) - fatal("Key %s uses disabled RSAMD5", predecessor); -#endif - - dst_key_format(prevkey, keystr, sizeof(keystr)); - dst_key_getprivateformat(prevkey, &major, &minor); - if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) - fatal("Key %s has incompatible format version %d.%d\n\t" - "It is not possible to generate a successor key.", - keystr, major, minor); - - ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when); - if (ret != ISC_R_SUCCESS) - fatal("Key %s has no activation date.\n\t" - "You must use dnssec-settime -A to set one " - "before generating a successor.", keystr); - - ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate); - if (ret != ISC_R_SUCCESS) - fatal("Key %s has no inactivation date.\n\t" - "You must use dnssec-settime -I to set one " - "before generating a successor.", keystr); - - publish = activate - prepub; - if (publish < now) - fatal("Key %s becomes inactive\n\t" - "sooner than the prepublication period " - "for the new key ends.\n\t" - "Either change the inactivation date with " - "dnssec-settime -I,\n\t" - "or use the -i option to set a shorter " - "prepublication interval.", keystr); - - ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when); - if (ret != ISC_R_SUCCESS) - fprintf(stderr, "%s: WARNING: Key %s has no removal " - "date;\n\t it will remain in the zone " - "indefinitely after rollover.\n\t " - "You can use dnssec-settime -D to " - "change this.\n", program, keystr); - - setpub = setact = true; - } - - if (nametype == NULL) { - if ((options & DST_TYPE_KEY) != 0) /* KEY */ - fatal("no nametype specified"); - flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ - } else if (strcasecmp(nametype, "zone") == 0) - flags |= DNS_KEYOWNER_ZONE; - else if ((options & DST_TYPE_KEY) != 0) { /* KEY */ - if (strcasecmp(nametype, "host") == 0 || - strcasecmp(nametype, "entity") == 0) - flags |= DNS_KEYOWNER_ENTITY; - else if (strcasecmp(nametype, "user") == 0) - flags |= DNS_KEYOWNER_USER; - else - fatal("invalid KEY nametype %s", nametype); - } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ - fatal("invalid DNSKEY nametype %s", nametype); - - rdclass = strtoclass(classname); - - if (directory == NULL) - directory = "."; - - if ((options & DST_TYPE_KEY) != 0) /* KEY */ - flags |= signatory; - else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */ - flags |= kskflag; - flags |= revflag; - } - - if (protocol == -1) - protocol = DNS_KEYPROTO_DNSSEC; - else if ((options & DST_TYPE_KEY) == 0 && - protocol != DNS_KEYPROTO_DNSSEC) - fatal("invalid DNSKEY protocol: %d", protocol); - - if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { - if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) - fatal("specified null key with signing authority"); - } - - if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && - alg == DNS_KEYALG_DH) - fatal("a key with algorithm '%s' cannot be a zone key", - algname); - - isc_buffer_init(&buf, filename, sizeof(filename) - 1); - - /* associate the key */ - ret = dst_key_fromlabel(name, alg, flags, protocol, rdclass, -#ifdef PKCS11CRYPTO - "pkcs11", -#else - engine, -#endif - label, NULL, mctx, &key); - isc_entropy_stopcallbacksources(ectx); - - if (ret != ISC_R_SUCCESS) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_SECALG_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - dns_secalg_format(alg, algstr, sizeof(algstr)); - fatal("failed to get key %s/%s: %s", - namestr, algstr, isc_result_totext(ret)); - /* NOTREACHED */ - exit(-1); - } - - /* - * Set key timing metadata (unless using -C) - * - * Publish and activation dates are set to "now" by default, but - * can be overridden. Creation date is always set to "now". - */ - if (!oldstyle) { - dst_key_settime(key, DST_TIME_CREATED, now); - - if (genonly && (setpub || setact)) - fatal("cannot use -G together with -P or -A options"); - - if (setpub) - dst_key_settime(key, DST_TIME_PUBLISH, publish); - else if (setact) - dst_key_settime(key, DST_TIME_PUBLISH, activate); - else if (!genonly && !unsetpub) - dst_key_settime(key, DST_TIME_PUBLISH, now); - - if (setact) - dst_key_settime(key, DST_TIME_ACTIVATE, activate); - else if (!genonly && !unsetact) - dst_key_settime(key, DST_TIME_ACTIVATE, now); - - if (setrev) { - if (kskflag == 0) - fprintf(stderr, "%s: warning: Key is " - "not flagged as a KSK, but -R " - "was used. Revoking a ZSK is " - "legal, but undefined.\n", - program); - dst_key_settime(key, DST_TIME_REVOKE, revoke); - } - - if (setinact) - dst_key_settime(key, DST_TIME_INACTIVE, inactive); - - if (setdel) - dst_key_settime(key, DST_TIME_DELETE, deltime); - if (setsyncadd) - dst_key_settime(key, DST_TIME_SYNCPUBLISH, syncadd); - if (setsyncdel) - dst_key_settime(key, DST_TIME_SYNCDELETE, syncdel); - - } else { - if (setpub || setact || setrev || setinact || - setdel || unsetpub || unsetact || - unsetrev || unsetinact || unsetdel || genonly || - setsyncadd || setsyncdel) - fatal("cannot use -C together with " - "-P, -A, -R, -I, -D, or -G options"); - /* - * Compatibility mode: Private-key-format - * should be set to 1.2. - */ - dst_key_setprivateformat(key, 1, 2); - } - - /* Set default key TTL */ - if (setttl) - dst_key_setttl(key, ttl); - - /* - * Do not overwrite an existing key. Warn LOUDLY if there - * is a risk of ID collision due to this key or another key - * being revoked. - */ - if (key_collision(key, name, directory, mctx, &exact)) { - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, directory, &buf); - if (ret != ISC_R_SUCCESS) - fatal("dst_key_buildfilename returned: %s\n", - isc_result_totext(ret)); - if (exact) - fatal("%s: %s already exists\n", program, filename); - - if (avoid_collisions) - fatal("%s: %s could collide with another key upon " - "revokation\n", program, filename); - - fprintf(stderr, "%s: WARNING: Key %s could collide with " - "another key upon revokation. If you plan " - "to revoke keys, destroy this key and " - "generate a different one.\n", - program, filename); - } - - ret = dst_key_tofile(key, options, directory); - if (ret != ISC_R_SUCCESS) { - char keystr[DST_KEY_FORMATSIZE]; - dst_key_format(key, keystr, sizeof(keystr)); - fatal("failed to write key %s: %s\n", keystr, - isc_result_totext(ret)); - } - - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, NULL, &buf); - if (ret != ISC_R_SUCCESS) - fatal("dst_key_buildfilename returned: %s\n", - isc_result_totext(ret)); - printf("%s\n", filename); - dst_key_free(&key); - if (prevkey != NULL) - dst_key_free(&prevkey); - - cleanup_logging(&log); - cleanup_entropy(&ectx); - dst_lib_destroy(); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_free(mctx, label); - isc_mem_destroy(&mctx); - - if (freeit != NULL) - free(freeit); - - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-keyfromlabel.docbook b/bin/dnssec-pkcs11/dnssec-keyfromlabel.docbook deleted file mode 100644 index 72d89fb..0000000 --- a/bin/dnssec-pkcs11/dnssec-keyfromlabel.docbook +++ /dev/null @@ -1,550 +0,0 @@ - - - - - - 2014-02-27 - - - August 27, 2015 - ISC - Internet Systems Consortium, Inc. - - - - dnssec-keyfromlabel - 8 - BIND9 - - - - dnssec-keyfromlabel - DNSSEC key generation tool - - - - - 2008 - 2009 - 2010 - 2011 - 2012 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-keyfromlabel - -l label - - - - - - - - - - - - - - - - - - - - - - - - - name - - - - DESCRIPTION - - dnssec-keyfromlabel - generates a key pair of files that referencing a key object stored - in a cryptographic hardware service module (HSM). The private key - file can be used for DNSSEC signing of zone data as if it were a - conventional signing key created by dnssec-keygen, - but the key material is stored within the HSM, and the actual signing - takes place there. - - - The of the key is specified on the command - line. This must match the name of the zone for which the key is - being generated. - - - - OPTIONS - - - - - -a algorithm - - - Selects the cryptographic algorithm. The value of - must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. - These values are case insensitive. - - - If no algorithm is specified, then RSASHA1 will be used by - default, unless the option is specified, - in which case NSEC3RSASHA1 will be used instead. (If - is used and an algorithm is specified, - that algorithm will be checked for compatibility with NSEC3.) - - - Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, and DSA is recommended. - - - Note 2: DH automatically sets the -k flag. - - - - - - -3 - - - Use an NSEC3-capable algorithm to generate a DNSSEC key. - If this option is used and no algorithm is explicitly - set on the command line, NSEC3RSASHA1 will be used by - default. - - - - - - -E engine - - - Specifies the cryptographic hardware to use. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -l label - - - Specifies the label for a key pair in the crypto hardware. - - - When BIND 9 is built with OpenSSL-based - PKCS#11 support, the label is an arbitrary string that - identifies a particular key. - - - When BIND 9 is built with native PKCS#11 - support, the label is a PKCS#11 URI string in the format - "pkcs11:=value;=value;..." - Keywords include "token", which identifies the HSM; "object", which - identifies the key; and "pin-source", which identifies a file from - which the HSM's PIN code can be obtained. The label will be - stored in the on-disk "private" file. - - - If the label contains a - field, tools using the generated - key files will be able to use the HSM for signing and other - operations without any need for an operator to manually enter - a PIN. Note: Making the HSM's PIN accessible in this manner - may reduce the security advantage of using an HSM; be sure - this is what you want to do before making use of this feature. - - - - - - -n nametype - - - Specifies the owner type of the key. The value of - must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with - a host (KEY)), - USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). - These values are case insensitive. - - - - - - -C - - - Compatibility mode: generates an old-style key, without - any metadata. By default, dnssec-keyfromlabel - will include the key's creation date in the metadata stored - with the private key, and other dates may be set there as well - (publication date, activation date, etc). Keys that include - this data may be incompatible with older versions of BIND; the - option suppresses them. - - - - - - -c class - - - Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. - - - - - - -f flag - - - Set the specified flag in the flag field of the KEY/DNSKEY record. - The only recognized flags are KSK (Key Signing Key) and REVOKE. - - - - - - -G - - - Generate a key, but do not publish it or sign with it. This - option is incompatible with -P and -A. - - - - - - -h - - - Prints a short summary of the options and arguments to - dnssec-keyfromlabel. - - - - - - -K directory - - - Sets the directory in which the key files are to be written. - - - - - - -k - - - Generate KEY records rather than DNSKEY records. - - - - - - -L ttl - - - Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. Setting the default TTL to - 0 or none removes it. - - - - - - -p protocol - - - Sets the protocol value for the key. The protocol - is a number between 0 and 255. The default is 3 (DNSSEC). - Other possible values for this argument are listed in - RFC 2535 and its successors. - - - - - - -S key - - - Generate a key as an explicit successor to an existing key. - The name, algorithm, size, and type of the key will be set - to match the predecessor. The activation date of the new - key will be set to the inactivation date of the existing - one. The publication date will be set to the activation - date minus the prepublication interval, which defaults to - 30 days. - - - - - - -t type - - - Indicates the use of the key. must be - one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default - is AUTHCONF. AUTH refers to the ability to authenticate - data, and CONF the ability to encrypt data. - - - - - - -v level - - - Sets the debugging level. - - - - - - -V - - - Prints version information. - - - - - - -y - - - Allows DNSSEC key files to be generated even if the key ID - would collide with that of an existing key, in the event of - either key being revoked. (This is only safe to use if you - are sure you won't be using RFC 5011 trust anchor maintenance - with either of the keys involved.) - - - - - - - - TIMING OPTIONS - - - - Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. - - - - - -P date/offset - - - Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. If not set, and if the -G option has - not been used, the default is "now". - - - - - - -P sync date/offset - - - Sets the date on which the CDS and CDNSKEY records which match - this key are to be published to the zone. - - - - - - -A date/offset - - - Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. If not set, and if the -G option has not been used, the - default is "now". - - - - - - -R date/offset - - - Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. - - - - - - -I date/offset - - - Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. - - - - - - -D date/offset - - - Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) - - - - - - -D sync date/offset - - - Sets the date on which the CDS and CDNSKEY records which match - this key are to be deleted. - - - - - - -i interval - - - Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. - - - If the key is being created as an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. - - - As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. - - - - - - - - GENERATED KEY FILES - - - When dnssec-keyfromlabel completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key files it has generated. - - - - nnnn is the key name. - - - - aaa is the numeric representation - of the algorithm. - - - - iiiii is the key identifier (or - footprint). - - - - dnssec-keyfromlabel - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private key. - - - The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). - - - The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. - - - - SEE ALSO - - - dnssec-keygen8 - , - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 4034, - The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13). - - - - diff --git a/bin/dnssec-pkcs11/dnssec-keyfromlabel.html b/bin/dnssec-pkcs11/dnssec-keyfromlabel.html deleted file mode 100644 index a37f183..0000000 --- a/bin/dnssec-pkcs11/dnssec-keyfromlabel.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - -dnssec-keyfromlabel - - -
-
-
-

Name

-

dnssec-keyfromlabel — DNSSEC key generation tool

-
-
-

Synopsis

-

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-D sync date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-i interval] [-k] [-K directory] [-L ttl] [-n nametype] [-P date/offset] [-P sync date/offset] [-p protocol] [-R date/offset] [-S key] [-t type] [-v level] [-V] [-y] {name}

-
-
-

DESCRIPTION

-

dnssec-keyfromlabel - generates a key pair of files that referencing a key object stored - in a cryptographic hardware service module (HSM). The private key - file can be used for DNSSEC signing of zone data as if it were a - conventional signing key created by dnssec-keygen, - but the key material is stored within the HSM, and the actual signing - takes place there. -

-

- The name of the key is specified on the command - line. This must match the name of the zone for which the key is - being generated. -

-
-
-

OPTIONS

-
-
-a algorithm
-
-

- Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. - These values are case insensitive. -

-

- If no algorithm is specified, then RSASHA1 will be used by - default, unless the -3 option is specified, - in which case NSEC3RSASHA1 will be used instead. (If - -3 is used and an algorithm is specified, - that algorithm will be checked for compatibility with NSEC3.) -

-

- Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, and DSA is recommended. -

-

- Note 2: DH automatically sets the -k flag. -

-
-
-3
-

- Use an NSEC3-capable algorithm to generate a DNSSEC key. - If this option is used and no algorithm is explicitly - set on the command line, NSEC3RSASHA1 will be used by - default. -

-
-E engine
-
-

- Specifies the cryptographic hardware to use. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-l label
-
-

- Specifies the label for a key pair in the crypto hardware. -

-

- When BIND 9 is built with OpenSSL-based - PKCS#11 support, the label is an arbitrary string that - identifies a particular key. -

-

- When BIND 9 is built with native PKCS#11 - support, the label is a PKCS#11 URI string in the format - "pkcs11:keyword=value[;keyword=value;...]" - Keywords include "token", which identifies the HSM; "object", which - identifies the key; and "pin-source", which identifies a file from - which the HSM's PIN code can be obtained. The label will be - stored in the on-disk "private" file. -

-

- If the label contains a - pin-source field, tools using the generated - key files will be able to use the HSM for signing and other - operations without any need for an operator to manually enter - a PIN. Note: Making the HSM's PIN accessible in this manner - may reduce the security advantage of using an HSM; be sure - this is what you want to do before making use of this feature. -

-
-
-n nametype
-

- Specifies the owner type of the key. The value of - nametype must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with - a host (KEY)), - USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). - These values are case insensitive. -

-
-C
-

- Compatibility mode: generates an old-style key, without - any metadata. By default, dnssec-keyfromlabel - will include the key's creation date in the metadata stored - with the private key, and other dates may be set there as well - (publication date, activation date, etc). Keys that include - this data may be incompatible with older versions of BIND; the - -C option suppresses them. -

-
-c class
-

- Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. -

-
-f flag
-

- Set the specified flag in the flag field of the KEY/DNSKEY record. - The only recognized flags are KSK (Key Signing Key) and REVOKE. -

-
-G
-

- Generate a key, but do not publish it or sign with it. This - option is incompatible with -P and -A. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-keyfromlabel. -

-
-K directory
-

- Sets the directory in which the key files are to be written. -

-
-k
-

- Generate KEY records rather than DNSKEY records. -

-
-L ttl
-

- Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. Setting the default TTL to - 0 or none removes it. -

-
-p protocol
-

- Sets the protocol value for the key. The protocol - is a number between 0 and 255. The default is 3 (DNSSEC). - Other possible values for this argument are listed in - RFC 2535 and its successors. -

-
-S key
-

- Generate a key as an explicit successor to an existing key. - The name, algorithm, size, and type of the key will be set - to match the predecessor. The activation date of the new - key will be set to the inactivation date of the existing - one. The publication date will be set to the activation - date minus the prepublication interval, which defaults to - 30 days. -

-
-t type
-

- Indicates the use of the key. type must be - one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default - is AUTHCONF. AUTH refers to the ability to authenticate - data, and CONF the ability to encrypt data. -

-
-v level
-

- Sets the debugging level. -

-
-V
-

- Prints version information. -

-
-y
-

- Allows DNSSEC key files to be generated even if the key ID - would collide with that of an existing key, in the event of - either key being revoked. (This is only safe to use if you - are sure you won't be using RFC 5011 trust anchor maintenance - with either of the keys involved.) -

-
-
-
-

TIMING OPTIONS

-

- Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. -

-
-
-P date/offset
-

- Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. If not set, and if the -G option has - not been used, the default is "now". -

-
-P sync date/offset
-

- Sets the date on which the CDS and CDNSKEY records which match - this key are to be published to the zone. -

-
-A date/offset
-

- Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. If not set, and if the -G option has not been used, the - default is "now". -

-
-R date/offset
-

- Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. -

-
-I date/offset
-

- Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. -

-
-D date/offset
-

- Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) -

-
-D sync date/offset
-

- Sets the date on which the CDS and CDNSKEY records which match - this key are to be deleted. -

-
-i interval
-
-

- Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. -

-

- If the key is being created as an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. -

-

- As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. -

-
-
-
-
-

GENERATED KEY FILES

-

- When dnssec-keyfromlabel completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key files it has generated. -

-
    -
  • nnnn is the key name. -

  • -
  • aaa is the numeric representation - of the algorithm. -

  • -
  • iiiii is the key identifier (or - footprint). -

  • -
-

dnssec-keyfromlabel - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private key. -

-

- The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). -

-

- The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. -

-
-
-

SEE ALSO

-

dnssec-keygen(8), - dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 4034, - The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13). -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-keygen.8 b/bin/dnssec-pkcs11/dnssec-keygen.8 deleted file mode 100644 index 3497146..0000000 --- a/bin/dnssec-pkcs11/dnssec-keygen.8 +++ /dev/null @@ -1,362 +0,0 @@ -.\" Copyright (C) 2000-2005, 2007-2012, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-keygen -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: August 21, 2015 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-KEYGEN" "8" "August 21, 2015" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-keygen \- DNSSEC key generation tool -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-keygen\fR\ 'u -\fBdnssec\-keygen\fR [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-P\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-V\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name} -.SH "DESCRIPTION" -.PP -\fBdnssec\-keygen\fR -generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034\&. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930\&. -.PP -The -\fBname\fR -of the key is specified on the command line\&. For DNSSEC keys, this must match the name of the zone for which the key is being generated\&. -.SH "OPTIONS" -.PP -\-3 -.RS 4 -Use an NSEC3\-capable algorithm to generate a DNSSEC key\&. If this option is used with an algorithm that has both NSEC and NSEC3 versions, then the NSEC3 version will be used; for example, -\fBdnssec\-keygen \-3a RSASHA1\fR -specifies the NSEC3RSASHA1 algorithm\&. -.RE -.PP -\-a \fIalgorithm\fR -.RS 4 -Selects the cryptographic algorithm\&. For DNSSEC keys, the value of -\fBalgorithm\fR -must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448\&. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512\&. These values are case insensitive\&. -.sp -If no algorithm is specified, then RSASHA1 will be used by default, unless the -\fB\-3\fR -option is specified, in which case NSEC3RSASHA1 will be used instead\&. (If -\fB\-3\fR -is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3\&.) -.sp -Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended\&. For TSIG, HMAC\-MD5 is mandatory\&. -.sp -Note 2: DH, HMAC\-MD5, and HMAC\-SHA1 through HMAC\-SHA512 automatically set the \-T KEY option\&. -.RE -.PP -\-b \fIkeysize\fR -.RS 4 -Specifies the number of bits in the key\&. The choice of key size depends on the algorithm used\&. RSA keys must be between 512 and 2048 bits\&. Diffie Hellman keys must be between 128 and 4096 bits\&. DSA keys must be between 512 and 1024 bits and an exact multiple of 64\&. HMAC keys must be between 1 and 512 bits\&. Elliptic curve algorithms don\*(Aqt need this parameter\&. -.sp -The key size does not need to be specified if using a default algorithm\&. The default key size is 1024 bits for zone signing keys (ZSKs) and 2048 bits for key signing keys (KSKs, generated with -\fB\-f KSK\fR)\&. However, if an algorithm is explicitly specified with the -\fB\-a\fR, then there is no default key size, and the -\fB\-b\fR -must be used\&. -.RE -.PP -\-C -.RS 4 -Compatibility mode: generates an old\-style key, without any timing metadata\&. By default, -\fBdnssec\-keygen\fR -will include the key\*(Aqs creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc)\&. Keys that include this data may be incompatible with older versions of BIND; the -\fB\-C\fR -option suppresses them\&. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Indicates that the DNS record containing the key should have the specified class\&. If not specified, class IN is used\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -Specifies the cryptographic hardware to use, when applicable\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-f \fIflag\fR -.RS 4 -Set the specified flag in the flag field of the KEY/DNSKEY record\&. The only recognized flags are KSK (Key Signing Key) and REVOKE\&. -.RE -.PP -\-G -.RS 4 -Generate a key, but do not publish it or sign with it\&. This option is incompatible with \-P and \-A\&. -.RE -.PP -\-g \fIgenerator\fR -.RS 4 -If generating a Diffie Hellman key, use this generator\&. Allowed values are 2 and 5\&. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2\&. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBdnssec\-keygen\fR\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Sets the directory in which the key files are to be written\&. -.RE -.PP -\-k -.RS 4 -Deprecated in favor of \-T KEY\&. -.RE -.PP -\-L \fIttl\fR -.RS 4 -Sets the default TTL to use for this key when it is converted into a DNSKEY RR\&. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence\&. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL\&. Setting the default TTL to -0 -or -none -is the same as leaving it unset\&. -.RE -.PP -\-n \fInametype\fR -.RS 4 -Specifies the owner type of the key\&. The value of -\fBnametype\fR -must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY)\&. These values are case insensitive\&. Defaults to ZONE for DNSKEY generation\&. -.RE -.PP -\-p \fIprotocol\fR -.RS 4 -Sets the protocol value for the generated key, for use with -\fB\-T KEY\fR\&. The protocol is a number between 0 and 255\&. The default is 3 (DNSSEC)\&. Other possible values for this argument are listed in RFC 2535 and its successors\&. -.RE -.PP -\-q -.RS 4 -Quiet mode: Suppresses unnecessary output, including progress indication\&. Without this option, when -\fBdnssec\-keygen\fR -is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to -stderr -indicating the progress of the key generation\&. A \*(Aq\&.\*(Aq indicates that a random number has been found which passed an initial sieve test; \*(Aq+\*(Aq means a number has passed a single round of the Miller\-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key\&. -.RE -.PP -\-r \fIrandomdev\fR -.RS 4 -Specifies the source of randomness\&. If the operating system does not provide a -/dev/random -or equivalent device, the default source of randomness is keyboard input\&. -randomdev -specifies the name of a character device or file containing random data to be used instead of the default\&. The special value -keyboard -indicates that keyboard input should be used\&. -.RE -.PP -\-S \fIkey\fR -.RS 4 -Create a new key which is an explicit successor to an existing key\&. The name, algorithm, size, and type of the key will be set to match the existing key\&. The activation date of the new key will be set to the inactivation date of the existing one\&. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days\&. -.RE -.PP -\-s \fIstrength\fR -.RS 4 -Specifies the strength value of the key\&. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC\&. -.RE -.PP -\-T \fIrrtype\fR -.RS 4 -Specifies the resource record type to use for the key\&. -\fBrrtype\fR -must be either DNSKEY or KEY\&. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0)\&. -Using any TSIG algorithm (HMAC\-* or DH) forces this option to KEY\&. -.RE -.PP -\-t \fItype\fR -.RS 4 -Indicates the use of the key, for use with -\fB\-T KEY\fR\&. -\fBtype\fR -must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF\&. The default is AUTHCONF\&. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.SH "TIMING OPTIONS" -.PP -Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS\&. If the argument begins with a \*(Aq+\*(Aq or \*(Aq\-\*(Aq, it is interpreted as an offset from the present time\&. For convenience, if such an offset is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively\&. Without a suffix, the offset is computed in seconds\&. To explicitly prevent a date from being set, use \*(Aqnone\*(Aq or \*(Aqnever\*(Aq\&. -.PP -\-P \fIdate/offset\fR -.RS 4 -Sets the date on which a key is to be published to the zone\&. After that date, the key will be included in the zone but will not be used to sign it\&. If not set, and if the \-G option has not been used, the default is "now"\&. -.RE -.PP -\-P sync \fIdate/offset\fR -.RS 4 -Sets the date on which CDS and CDNSKEY records that match this key are to be published to the zone\&. -.RE -.PP -\-A \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be activated\&. After that date, the key will be included in the zone and used to sign it\&. If not set, and if the \-G option has not been used, the default is "now"\&. If set, if and \-P is not set, then the publication date will be set to the activation date minus the prepublication interval\&. -.RE -.PP -\-R \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be revoked\&. After that date, the key will be flagged as revoked\&. It will be included in the zone and will be used to sign it\&. -.RE -.PP -\-I \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be retired\&. After that date, the key will still be included in the zone, but it will not be used to sign it\&. -.RE -.PP -\-D \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be deleted\&. After that date, the key will no longer be included in the zone\&. (It may remain in the key repository, however\&.) -.RE -.PP -\-D sync \fIdate/offset\fR -.RS 4 -Sets the date on which the CDS and CDNSKEY records that match this key are to be deleted\&. -.RE -.PP -\-i \fIinterval\fR -.RS 4 -Sets the prepublication interval for a key\&. If set, then the publication and activation dates must be separated by at least this much time\&. If the activation date is specified but the publication date isn\*(Aqt, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn\*(Aqt, then activation will be set to this much time after publication\&. -.sp -If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero\&. -.sp -As with date offsets, if the argument is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the interval is measured in years, months, weeks, days, hours, or minutes, respectively\&. Without a suffix, the interval is measured in seconds\&. -.RE -.SH "GENERATED KEYS" -.PP -When -\fBdnssec\-keygen\fR -completes successfully, it prints a string of the form -Knnnn\&.+aaa+iiiii -to the standard output\&. This is an identification string for the key it has generated\&. -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -nnnn -is the key name\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -aaa -is the numeric representation of the algorithm\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -iiiii -is the key identifier (or footprint)\&. -.RE -.PP -\fBdnssec\-keygen\fR -creates two files, with names based on the printed string\&. -Knnnn\&.+aaa+iiiii\&.key -contains the public key, and -Knnnn\&.+aaa+iiiii\&.private -contains the private key\&. -.PP -The -\&.key -file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement)\&. -.PP -The -\&.private -file contains algorithm\-specific fields\&. For obvious security reasons, this file does not have general read permission\&. -.PP -Both -\&.key -and -\&.private -files are generated for symmetric cryptography algorithms such as HMAC\-MD5, even though the public and private key are equivalent\&. -.SH "EXAMPLE" -.PP -To generate a 768\-bit DSA key for the domain -\fBexample\&.com\fR, the following command would be issued: -.PP -\fBdnssec\-keygen \-a DSA \-b 768 \-n ZONE example\&.com\fR -.PP -The command would print a string of the form: -.PP -\fBKexample\&.com\&.+003+26160\fR -.PP -In this example, -\fBdnssec\-keygen\fR -creates the files -Kexample\&.com\&.+003+26160\&.key -and -Kexample\&.com\&.+003+26160\&.private\&. -.PP -To generate a matching key\-signing key, issue the command: -.PP -\fBdnssec\-keygen \-a DSA \-b 768 \-n ZONE \-f KSK example\&.com\fR -.SH "SEE ALSO" -.PP -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 2539, -RFC 2845, -RFC 4034\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000-2005, 2007-2012, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-keygen.c b/bin/dnssec-pkcs11/dnssec-keygen.c deleted file mode 100644 index e2dc70e..0000000 --- a/bin/dnssec-pkcs11/dnssec-keygen.c +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -#define MAX_RSA 4096 /* should be long enough... */ - -const char *program = "dnssec-keygen"; -int verbose; - -#define DEFAULT_ALGORITHM "RSASHA1" -#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1" - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void progress(int p); - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] name\n\n", program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, " name: owner of the key\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -K : write keys into directory\n"); - fprintf(stderr, " -a :\n"); - fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1" - " | NSEC3DSA |\n"); - fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n"); - fprintf(stderr, " ECDSAP256SHA256 | ECDSAP384SHA384 |\n"); - fprintf(stderr, " ED25519 | ED448 | DH |\n"); - fprintf(stderr, " HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | " - "HMAC-SHA256 | \n"); - fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n"); - fprintf(stderr, " (default: RSASHA1, or " - "NSEC3RSASHA1 if using -3)\n"); - fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); - fprintf(stderr, " -b :\n"); - fprintf(stderr, " RSAMD5:\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " RSASHA1:\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA); - fprintf(stderr, " DH:\t\t[128..4096]\n"); - fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); - fprintf(stderr, " NSEC3DSA:\t[512..1024] and divisible " - "by 64\n"); - fprintf(stderr, " ECCGOST:\tignored\n"); - fprintf(stderr, " ECDSAP256SHA256:\tignored\n"); - fprintf(stderr, " ECDSAP384SHA384:\tignored\n"); - fprintf(stderr, " ED25519:\tignored\n"); - fprintf(stderr, " ED448:\tignored\n"); - fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); - fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); - fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); - fprintf(stderr, " HMAC-SHA256:\t[1..256]\n"); - fprintf(stderr, " HMAC-SHA384:\t[1..384]\n"); - fprintf(stderr, " HMAC-SHA512:\t[1..512]\n"); - fprintf(stderr, " (if using the default algorithm, key size\n" - " defaults to 2048 for KSK, or 1024 for all " - "others)\n"); - fprintf(stderr, " -n : ZONE | HOST | ENTITY | " - "USER | OTHER\n"); - fprintf(stderr, " (DNSKEY generation defaults to ZONE)\n"); - fprintf(stderr, " -c : (default: IN)\n"); - fprintf(stderr, " -d (0 => max, default)\n"); - fprintf(stderr, " -E :\n"); -#if defined(PKCS11CRYPTO) - fprintf(stderr, " path to PKCS#11 provider library " - "(default is %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, " name of an OpenSSL engine to use " - "(default is \"pkcs11\")\n"); -#else - fprintf(stderr, " name of an OpenSSL engine to use\n"); -#endif - fprintf(stderr, " -f : KSK | REVOKE\n"); - fprintf(stderr, " -g : use specified generator " - "(DH only)\n"); - fprintf(stderr, " -L : default key TTL\n"); - fprintf(stderr, " -p : (default: 3 [dnssec])\n"); - fprintf(stderr, " -r : a file containing random data\n"); - fprintf(stderr, " -s : strength value this key signs DNS " - "records with (default: 0)\n"); - fprintf(stderr, " -T : DNSKEY | KEY (default: DNSKEY; " - "use KEY for SIG(0))\n"); - fprintf(stderr, " -t : " - "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " - "(default: AUTHCONF)\n"); - fprintf(stderr, " -h: print usage and exit\n"); - fprintf(stderr, " -m :\n"); - fprintf(stderr, " usage | trace | record | size | mctx\n"); - fprintf(stderr, " -v : set verbosity level (0 - 10)\n"); - fprintf(stderr, " -V: print version information\n"); - fprintf(stderr, "Timing options:\n"); - fprintf(stderr, " -P date/[+-]offset/none: set key publication date " - "(default: now)\n"); - fprintf(stderr, " -P sync date/[+-]offset/none: set CDS and CDNSKEY " - "publication date\n"); - fprintf(stderr, " -A date/[+-]offset/none: set key activation date " - "(default: now)\n"); - fprintf(stderr, " -R date/[+-]offset/none: set key " - "revocation date\n"); - fprintf(stderr, " -I date/[+-]offset/none: set key " - "inactivation date\n"); - fprintf(stderr, " -D date/[+-]offset/none: set key deletion date\n"); - fprintf(stderr, " -D sync date/[+-]offset/none: set CDS and CDNSKEY " - "deletion date\n"); - - fprintf(stderr, " -G: generate key only; do not set -P or -A\n"); - fprintf(stderr, " -C: generate a backward-compatible key, omitting " - "all dates\n"); - fprintf(stderr, " -S : generate a successor to an existing " - "key\n"); - fprintf(stderr, " -i : prepublication interval for " - "successor key " - "(default: 30 days)\n"); - fprintf(stderr, "Output:\n"); - fprintf(stderr, " K++.key, " - "K++.private\n"); - - exit (-1); -} - -static bool -dsa_size_ok(int size) { - return (size >= 512 && size <= 1024 && size % 64 == 0); -} - -static void -progress(int p) -{ - char c = '*'; - - switch (p) { - case 0: - c = '.'; - break; - case 1: - c = '+'; - break; - case 2: - c = '*'; - break; - case 3: - c = ' '; - break; - default: - break; - } - (void) putc(c, stderr); - (void) fflush(stderr); -} - -int -main(int argc, char **argv) { - char *algname = NULL, *freeit = NULL; - char *nametype = NULL, *type = NULL; - char *classname = NULL; - char *endp; - dst_key_t *key = NULL; - dns_fixedname_t fname; - dns_name_t *name; - uint16_t flags = 0, kskflag = 0, revflag = 0; - dns_secalg_t alg; - bool conflict = false, null_key = false; - bool oldstyle = false; - isc_mem_t *mctx = NULL; - int ch, generator = 0, param = 0; - int protocol = -1, size = -1, signatory = 0; - isc_result_t ret; - isc_textregion_t r; - char filename[255]; - const char *directory = NULL; - const char *predecessor = NULL; - dst_key_t *prevkey = NULL; - isc_buffer_t buf; - isc_log_t *log = NULL; - isc_entropy_t *ectx = NULL; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - dns_rdataclass_t rdclass; - int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; - int dbits = 0; - dns_ttl_t ttl = 0; - bool use_default = false, use_nsec3 = false; - isc_stdtime_t publish = 0, activate = 0, revokekey = 0; - isc_stdtime_t inactive = 0, deltime = 0; - isc_stdtime_t now; - int prepub = -1; - bool setpub = false, setact = false; - bool setrev = false, setinact = false; - bool setdel = false, setttl = false; - bool unsetpub = false, unsetact = false; - bool unsetrev = false, unsetinact = false; - bool unsetdel = false; - bool genonly = false; - bool quiet = false; - bool show_progress = false; - unsigned char c; - isc_stdtime_t syncadd = 0, syncdel = 0; - bool setsyncadd = false; - bool setsyncdel = false; - - if (argc == 1) - usage(); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - /* - * Process memory debugging argument first. - */ -#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:kL:m:n:P:p:qR:r:S:s:T:t:" \ - "v:V" - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'm': - if (strcasecmp(isc_commandline_argument, "record") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - if (strcasecmp(isc_commandline_argument, "trace") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGTRACE; - if (strcasecmp(isc_commandline_argument, "usage") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; - if (strcasecmp(isc_commandline_argument, "size") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGSIZE; - if (strcasecmp(isc_commandline_argument, "mctx") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGCTX; - break; - default: - break; - } - } - isc_commandline_reset = true; - - RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - - isc_stdtime_get(&now); - - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case '3': - use_nsec3 = true; - break; - case 'a': - algname = isc_commandline_argument; - break; - case 'b': - size = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || size < 0) - fatal("-b requires a non-negative number"); - break; - case 'C': - oldstyle = true; - break; - case 'c': - classname = isc_commandline_argument; - break; - case 'd': - dbits = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || dbits < 0) - fatal("-d requires a non-negative number"); - break; - case 'E': - engine = isc_commandline_argument; - break; - case 'e': - fprintf(stderr, - "phased-out option -e " - "(was 'use (RSA) large exponent')\n"); - break; - case 'f': - c = (unsigned char)(isc_commandline_argument[0]); - if (toupper(c) == 'K') - kskflag = DNS_KEYFLAG_KSK; - else if (toupper(c) == 'R') - revflag = DNS_KEYFLAG_REVOKE; - else - fatal("unknown flag '%s'", - isc_commandline_argument); - break; - case 'g': - generator = strtol(isc_commandline_argument, - &endp, 10); - if (*endp != '\0' || generator <= 0) - fatal("-g requires a positive number"); - break; - case 'K': - directory = isc_commandline_argument; - ret = try_dir(directory); - if (ret != ISC_R_SUCCESS) - fatal("cannot open directory %s: %s", - directory, isc_result_totext(ret)); - break; - case 'k': - fatal("The -k option has been deprecated.\n" - "To generate a key-signing key, use -f KSK.\n" - "To generate a key with TYPE=KEY, use -T KEY.\n"); - break; - case 'L': - ttl = strtottl(isc_commandline_argument); - setttl = true; - break; - case 'n': - nametype = isc_commandline_argument; - break; - case 'm': - break; - case 'p': - protocol = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || protocol < 0 || protocol > 255) - fatal("-p must be followed by a number " - "[0..255]"); - break; - case 'q': - quiet = true; - break; - case 'r': - setup_entropy(mctx, isc_commandline_argument, &ectx); - break; - case 's': - signatory = strtol(isc_commandline_argument, - &endp, 10); - if (*endp != '\0' || signatory < 0 || signatory > 15) - fatal("-s must be followed by a number " - "[0..15]"); - break; - case 'T': - if (strcasecmp(isc_commandline_argument, "KEY") == 0) - options |= DST_TYPE_KEY; - else if (strcasecmp(isc_commandline_argument, - "DNSKEY") == 0) - /* default behavior */ - ; - else - fatal("unknown type '%s'", - isc_commandline_argument); - break; - case 't': - type = isc_commandline_argument; - break; - case 'v': - endp = NULL; - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - case 'z': - /* already the default */ - break; - case 'G': - genonly = true; - break; - case 'P': - /* -Psync ? */ - if (isoptarg("sync", argv, usage)) { - if (setsyncadd) - fatal("-P sync specified more than " - "once"); - - syncadd = strtotime(isc_commandline_argument, - now, now, &setsyncadd); - break; - } - (void)isoptarg("dnskey", argv, usage); - if (setpub || unsetpub) - fatal("-P specified more than once"); - - publish = strtotime(isc_commandline_argument, - now, now, &setpub); - unsetpub = !setpub; - break; - case 'A': - if (setact || unsetact) - fatal("-A specified more than once"); - - activate = strtotime(isc_commandline_argument, - now, now, &setact); - unsetact = !setact; - break; - case 'R': - if (setrev || unsetrev) - fatal("-R specified more than once"); - - revokekey = strtotime(isc_commandline_argument, - now, now, &setrev); - unsetrev = !setrev; - break; - case 'I': - if (setinact || unsetinact) - fatal("-I specified more than once"); - - inactive = strtotime(isc_commandline_argument, - now, now, &setinact); - unsetinact = !setinact; - break; - case 'D': - /* -Dsync ? */ - if (isoptarg("sync", argv, usage)) { - if (setsyncdel) - fatal("-D sync specified more than " - "once"); - - syncdel = strtotime(isc_commandline_argument, - now, now, &setsyncdel); - break; - } - (void)isoptarg("dnskey", argv, usage); - if (setdel || unsetdel) - fatal("-D specified more than once"); - - deltime = strtotime(isc_commandline_argument, - now, now, &setdel); - unsetdel = !setdel; - break; - case 'S': - predecessor = isc_commandline_argument; - break; - case 'i': - prepub = strtottl(isc_commandline_argument); - break; - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (!isatty(0)) - quiet = true; - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - ret = dst_lib_init2(mctx, ectx, engine, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (ret != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(ret)); - - setup_logging(mctx, &log); - - if (predecessor == NULL) { - if (prepub == -1) - prepub = 0; - - if (argc < isc_commandline_index + 1) - fatal("the key name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("extraneous arguments"); - - name = dns_fixedname_initname(&fname); - isc_buffer_init(&buf, argv[isc_commandline_index], - strlen(argv[isc_commandline_index])); - isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); - ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); - if (ret != ISC_R_SUCCESS) - fatal("invalid key name %s: %s", - argv[isc_commandline_index], - isc_result_totext(ret)); - - if (algname == NULL) { - use_default = true; - if (use_nsec3) - algname = strdup(DEFAULT_NSEC3_ALGORITHM); - else - algname = strdup(DEFAULT_ALGORITHM); - if (algname == NULL) - fatal("strdup failed"); - freeit = algname; - if (verbose > 0) - fprintf(stderr, "no algorithm specified; " - "defaulting to %s\n", algname); - } - - if (strcasecmp(algname, "RSA") == 0) { -#ifndef PK11_MD5_DISABLE - fprintf(stderr, "The use of RSA (RSAMD5) is not " - "recommended.\nIf you still wish to " - "use RSA (RSAMD5) please specify " - "\"-a RSAMD5\"\n"); - INSIST(freeit == NULL); - return (1); - } else if (strcasecmp(algname, "HMAC-MD5") == 0) { - if (isc_md5_available()) { - alg = DST_ALG_HMACMD5; - } else { - fprintf(stderr, - "The use of HMAC-MD5 was disabled\n"); - return (1); - } - } else if (strcasecmp(algname, "RSAMD5") == 0 && - !isc_md5_available()) { - fprintf(stderr, "The use of RSAMD5 was disabled\n"); - INSIST(freeit == NULL); - return (1); - } else if (strcasecmp(algname, "HMAC-MD5") == 0) { - alg = DST_ALG_HMACMD5; -#else - fprintf(stderr, - "The use of RSA (RSAMD5) was disabled\n"); - INSIST(freeit == NULL); - return (1); - } else if (strcasecmp(algname, "RSAMD5") == 0) { - fprintf(stderr, "The use of RSAMD5 was disabled\n"); - INSIST(freeit == NULL); - return (1); - } else if (strcasecmp(algname, "HMAC-MD5") == 0) { - fprintf(stderr, - "The use of HMAC-MD5 was disabled\n"); - return (1); -#endif - } else if (strcasecmp(algname, "HMAC-SHA1") == 0) - alg = DST_ALG_HMACSHA1; - else if (strcasecmp(algname, "HMAC-SHA224") == 0) - alg = DST_ALG_HMACSHA224; - else if (strcasecmp(algname, "HMAC-SHA256") == 0) - alg = DST_ALG_HMACSHA256; - else if (strcasecmp(algname, "HMAC-SHA384") == 0) - alg = DST_ALG_HMACSHA384; - else if (strcasecmp(algname, "HMAC-SHA512") == 0) - alg = DST_ALG_HMACSHA512; - else { - r.base = algname; - r.length = strlen(algname); - ret = dns_secalg_fromtext(&alg, &r); - if (ret != ISC_R_SUCCESS) - fatal("unknown algorithm %s", algname); - if (alg == DST_ALG_DH) - options |= DST_TYPE_KEY; - } - -#ifdef PK11_MD5_DISABLE - INSIST((alg != DNS_KEYALG_RSAMD5) && (alg != DST_ALG_HMACMD5)); -#endif - - if (!dst_algorithm_supported(alg)) - fatal("unsupported algorithm: %d", alg); - - if (use_nsec3 && - alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && - alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 && - alg != DST_ALG_ECCGOST && - alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384 && - alg != DST_ALG_ED25519 && alg != DST_ALG_ED448) { - fatal("%s is incompatible with NSEC3; " - "do not use the -3 option", algname); - } - - if (type != NULL && (options & DST_TYPE_KEY) != 0) { - if (strcasecmp(type, "NOAUTH") == 0) - flags |= DNS_KEYTYPE_NOAUTH; - else if (strcasecmp(type, "NOCONF") == 0) - flags |= DNS_KEYTYPE_NOCONF; - else if (strcasecmp(type, "NOAUTHCONF") == 0) { - flags |= (DNS_KEYTYPE_NOAUTH | - DNS_KEYTYPE_NOCONF); - if (size < 0) - size = 0; - } - else if (strcasecmp(type, "AUTHCONF") == 0) - /* nothing */; - else - fatal("invalid type %s", type); - } - - if (size < 0) { - if (use_default) { - if ((kskflag & DNS_KEYFLAG_KSK) != 0) - size = 2048; - else - size = 1024; - if (verbose > 0) - fprintf(stderr, "key size not " - "specified; defaulting" - " to %d\n", size); - } else if (alg != DST_ALG_ECCGOST && - alg != DST_ALG_ECDSA256 && - alg != DST_ALG_ECDSA384 && - alg != DST_ALG_ED25519 && - alg != DST_ALG_ED448) - fatal("key size not specified (-b option)"); - } - - if (!oldstyle && prepub > 0) { - if (setpub && setact && (activate - prepub) < publish) - fatal("Activation and publication dates " - "are closer together than the\n\t" - "prepublication interval."); - - if (!setpub && !setact) { - setpub = setact = true; - publish = now; - activate = now + prepub; - } else if (setpub && !setact) { - setact = true; - activate = publish + prepub; - } else if (setact && !setpub) { - setpub = true; - publish = activate - prepub; - } - - if ((activate - prepub) < now) - fatal("Time until activation is shorter " - "than the\n\tprepublication interval."); - } - } else { - char keystr[DST_KEY_FORMATSIZE]; - isc_stdtime_t when; - int major, minor; - - if (prepub == -1) - prepub = (30 * 86400); - - if (algname != NULL) - fatal("-S and -a cannot be used together"); - if (size >= 0) - fatal("-S and -b cannot be used together"); - if (nametype != NULL) - fatal("-S and -n cannot be used together"); - if (type != NULL) - fatal("-S and -t cannot be used together"); - if (setpub || unsetpub) - fatal("-S and -P cannot be used together"); - if (setact || unsetact) - fatal("-S and -A cannot be used together"); - if (use_nsec3) - fatal("-S and -3 cannot be used together"); - if (oldstyle) - fatal("-S and -C cannot be used together"); - if (genonly) - fatal("-S and -G cannot be used together"); - - ret = dst_key_fromnamedfile(predecessor, directory, - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - mctx, &prevkey); - if (ret != ISC_R_SUCCESS) - fatal("Invalid keyfile %s: %s", - predecessor, isc_result_totext(ret)); - if (!dst_key_isprivate(prevkey)) - fatal("%s is not a private key", predecessor); - - name = dst_key_name(prevkey); - alg = dst_key_alg(prevkey); - size = dst_key_size(prevkey); - flags = dst_key_flags(prevkey); - - dst_key_format(prevkey, keystr, sizeof(keystr)); - dst_key_getprivateformat(prevkey, &major, &minor); - if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) - fatal("Key %s has incompatible format version %d.%d\n\t" - "It is not possible to generate a successor key.", - keystr, major, minor); - - ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when); - if (ret != ISC_R_SUCCESS) - fatal("Key %s has no activation date.\n\t" - "You must use dnssec-settime -A to set one " - "before generating a successor.", keystr); - - ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate); - if (ret != ISC_R_SUCCESS) - fatal("Key %s has no inactivation date.\n\t" - "You must use dnssec-settime -I to set one " - "before generating a successor.", keystr); - - publish = activate - prepub; - if (publish < now) - fatal("Key %s becomes inactive\n\t" - "sooner than the prepublication period " - "for the new key ends.\n\t" - "Either change the inactivation date with " - "dnssec-settime -I,\n\t" - "or use the -i option to set a shorter " - "prepublication interval.", keystr); - - ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when); - if (ret != ISC_R_SUCCESS) - fprintf(stderr, "%s: WARNING: Key %s has no removal " - "date;\n\t it will remain in the zone " - "indefinitely after rollover.\n\t " - "You can use dnssec-settime -D to " - "change this.\n", program, keystr); - - setpub = setact = true; - } - - switch (alg) { - case DNS_KEYALG_RSAMD5: - case DNS_KEYALG_RSASHA1: - case DNS_KEYALG_NSEC3RSASHA1: - case DNS_KEYALG_RSASHA256: - if (size != 0 && (size < 512 || size > MAX_RSA)) - fatal("RSA key size %d out of range", size); - break; - case DNS_KEYALG_RSASHA512: - if (size != 0 && (size < 1024 || size > MAX_RSA)) - fatal("RSA key size %d out of range", size); - break; - case DNS_KEYALG_DH: - if (size != 0 && (size < 128 || size > 4096)) - fatal("DH key size %d out of range", size); - break; - case DNS_KEYALG_DSA: - case DNS_KEYALG_NSEC3DSA: - if (size != 0 && !dsa_size_ok(size)) - fatal("invalid DSS key size: %d", size); - break; - case DST_ALG_ECCGOST: - size = 256; - break; - case DST_ALG_ECDSA256: - size = 256; - break; - case DST_ALG_ECDSA384: - size = 384; - break; - case DST_ALG_ED25519: - size = 256; - break; - case DST_ALG_ED448: - size = 456; - break; - case DST_ALG_HMACMD5: - options |= DST_TYPE_KEY; - if (size < 1 || size > 512) - fatal("HMAC-MD5 key size %d out of range", size); - if (dbits != 0 && (dbits < 80 || dbits > 128)) - fatal("HMAC-MD5 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-MD5 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA1: - options |= DST_TYPE_KEY; - if (size < 1 || size > 160) - fatal("HMAC-SHA1 key size %d out of range", size); - if (dbits != 0 && (dbits < 80 || dbits > 160)) - fatal("HMAC-SHA1 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA1 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA224: - options |= DST_TYPE_KEY; - if (size < 1 || size > 224) - fatal("HMAC-SHA224 key size %d out of range", size); - if (dbits != 0 && (dbits < 112 || dbits > 224)) - fatal("HMAC-SHA224 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA224 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA256: - options |= DST_TYPE_KEY; - if (size < 1 || size > 256) - fatal("HMAC-SHA256 key size %d out of range", size); - if (dbits != 0 && (dbits < 128 || dbits > 256)) - fatal("HMAC-SHA256 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA256 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA384: - options |= DST_TYPE_KEY; - if (size < 1 || size > 384) - fatal("HMAC-384 key size %d out of range", size); - if (dbits != 0 && (dbits < 192 || dbits > 384)) - fatal("HMAC-SHA384 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA384 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA512: - options |= DST_TYPE_KEY; - if (size < 1 || size > 512) - fatal("HMAC-SHA512 key size %d out of range", size); - if (dbits != 0 && (dbits < 256 || dbits > 512)) - fatal("HMAC-SHA512 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA512 digest bits %d not divisible by 8", - dbits); - break; - } - - if (alg != DNS_KEYALG_DH && generator != 0) - fatal("specified DH generator for a non-DH key"); - - if (nametype == NULL) { - if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ - fatal("no nametype specified"); - flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ - } else if (strcasecmp(nametype, "zone") == 0) - flags |= DNS_KEYOWNER_ZONE; - else if ((options & DST_TYPE_KEY) != 0) { /* KEY / HMAC */ - if (strcasecmp(nametype, "host") == 0 || - strcasecmp(nametype, "entity") == 0) - flags |= DNS_KEYOWNER_ENTITY; - else if (strcasecmp(nametype, "user") == 0) - flags |= DNS_KEYOWNER_USER; - else - fatal("invalid KEY nametype %s", nametype); - } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ - fatal("invalid DNSKEY nametype %s", nametype); - - rdclass = strtoclass(classname); - - if (directory == NULL) - directory = "."; - - if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ - flags |= signatory; - else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */ - flags |= kskflag; - flags |= revflag; - } - - if (protocol == -1) - protocol = DNS_KEYPROTO_DNSSEC; - else if ((options & DST_TYPE_KEY) == 0 && - protocol != DNS_KEYPROTO_DNSSEC) - fatal("invalid DNSKEY protocol: %d", protocol); - - if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { - if (size > 0) - fatal("specified null key with non-zero size"); - if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) - fatal("specified null key with signing authority"); - } - - if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && - (alg == DNS_KEYALG_DH || alg == DST_ALG_HMACMD5 || - alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || - alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || - alg == DST_ALG_HMACSHA512)) - fatal("a key with algorithm '%s' cannot be a zone key", - algname); - - switch(alg) { - case DNS_KEYALG_RSAMD5: - case DNS_KEYALG_RSASHA1: - case DNS_KEYALG_NSEC3RSASHA1: - case DNS_KEYALG_RSASHA256: - case DNS_KEYALG_RSASHA512: - show_progress = true; - break; - - case DNS_KEYALG_DH: - param = generator; - break; - - case DNS_KEYALG_DSA: - case DNS_KEYALG_NSEC3DSA: - case DST_ALG_ECCGOST: - case DST_ALG_ECDSA256: - case DST_ALG_ECDSA384: - case DST_ALG_ED25519: - case DST_ALG_ED448: - show_progress = true; - /* fall through */ - - case DST_ALG_HMACMD5: - case DST_ALG_HMACSHA1: - case DST_ALG_HMACSHA224: - case DST_ALG_HMACSHA256: - case DST_ALG_HMACSHA384: - case DST_ALG_HMACSHA512: - param = 0; - break; - } - - if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) - null_key = true; - - isc_buffer_init(&buf, filename, sizeof(filename) - 1); - - do { - conflict = false; - - if (!quiet && show_progress) { - fprintf(stderr, "Generating key pair."); - ret = dst_key_generate2(name, alg, size, param, flags, - protocol, rdclass, mctx, &key, - &progress); - putc('\n', stderr); - fflush(stderr); - } else { - ret = dst_key_generate2(name, alg, size, param, flags, - protocol, rdclass, mctx, &key, - NULL); - } - - isc_entropy_stopcallbacksources(ectx); - - if (ret != ISC_R_SUCCESS) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_SECALG_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - dns_secalg_format(alg, algstr, sizeof(algstr)); - fatal("failed to generate key %s/%s: %s\n", - namestr, algstr, isc_result_totext(ret)); - /* NOTREACHED */ - exit(-1); - } - - dst_key_setbits(key, dbits); - - /* - * Set key timing metadata (unless using -C) - * - * Creation date is always set to "now". - * - * For a new key without an explicit predecessor, publish - * and activation dates are set to "now" by default, but - * can both be overridden. - * - * For a successor key, activation is set to match the - * predecessor's inactivation date. Publish is set to 30 - * days earlier than that (XXX: this should be configurable). - * If either of the resulting dates are in the past, that's - * an error; the inactivation date of the predecessor key - * must be updated before a successor key can be created. - */ - if (!oldstyle) { - dst_key_settime(key, DST_TIME_CREATED, now); - - if (genonly && (setpub || setact)) - fatal("cannot use -G together with " - "-P or -A options"); - - if (setpub) - dst_key_settime(key, DST_TIME_PUBLISH, publish); - else if (setact && !unsetpub) - dst_key_settime(key, DST_TIME_PUBLISH, - activate - prepub); - else if (!genonly && !unsetpub) - dst_key_settime(key, DST_TIME_PUBLISH, now); - - if (setact) - dst_key_settime(key, DST_TIME_ACTIVATE, - activate); - else if (!genonly && !unsetact) - dst_key_settime(key, DST_TIME_ACTIVATE, now); - - if (setrev) { - if (kskflag == 0) - fprintf(stderr, "%s: warning: Key is " - "not flagged as a KSK, but -R " - "was used. Revoking a ZSK is " - "legal, but undefined.\n", - program); - dst_key_settime(key, DST_TIME_REVOKE, revokekey); - } - - if (setinact) - dst_key_settime(key, DST_TIME_INACTIVE, - inactive); - - if (setdel) { - if (setinact && deltime < inactive) - fprintf(stderr, "%s: warning: Key is " - "scheduled to be deleted " - "before it is scheduled to be " - "made inactive.\n", - program); - dst_key_settime(key, DST_TIME_DELETE, deltime); - } - - if (setsyncadd) - dst_key_settime(key, DST_TIME_SYNCPUBLISH, - syncadd); - - if (setsyncdel) - dst_key_settime(key, DST_TIME_SYNCDELETE, - syncdel); - - } else { - if (setpub || setact || setrev || setinact || - setdel || unsetpub || unsetact || - unsetrev || unsetinact || unsetdel || genonly || - setsyncadd || setsyncdel) - fatal("cannot use -C together with " - "-P, -A, -R, -I, -D, or -G options"); - /* - * Compatibility mode: Private-key-format - * should be set to 1.2. - */ - dst_key_setprivateformat(key, 1, 2); - } - - /* Set the default key TTL */ - if (setttl) - dst_key_setttl(key, ttl); - - /* - * Do not overwrite an existing key, or create a key - * if there is a risk of ID collision due to this key - * or another key being revoked. - */ - if (key_collision(key, name, directory, mctx, NULL)) { - conflict = true; - if (null_key) { - dst_key_free(&key); - break; - } - - if (verbose > 0) { - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, - directory, &buf); - if (ret == ISC_R_SUCCESS) - fprintf(stderr, - "%s: %s already exists, or " - "might collide with another " - "key upon revokation. " - "Generating a new key\n", - program, filename); - } - - dst_key_free(&key); - } - } while (conflict == true); - - if (conflict) - fatal("cannot generate a null key due to possible key ID " - "collision"); - - ret = dst_key_tofile(key, options, directory); - if (ret != ISC_R_SUCCESS) { - char keystr[DST_KEY_FORMATSIZE]; - dst_key_format(key, keystr, sizeof(keystr)); - fatal("failed to write key %s: %s\n", keystr, - isc_result_totext(ret)); - } - - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, NULL, &buf); - if (ret != ISC_R_SUCCESS) - fatal("dst_key_buildfilename returned: %s\n", - isc_result_totext(ret)); - printf("%s\n", filename); - dst_key_free(&key); - if (prevkey != NULL) - dst_key_free(&prevkey); - - cleanup_logging(&log); - cleanup_entropy(&ectx); - dst_lib_destroy(); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - if (freeit != NULL) - free(freeit); - - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-keygen.docbook b/bin/dnssec-pkcs11/dnssec-keygen.docbook deleted file mode 100644 index d4e2f29..0000000 --- a/bin/dnssec-pkcs11/dnssec-keygen.docbook +++ /dev/null @@ -1,668 +0,0 @@ - - - - - - 2014-02-06 - - - August 21, 2015 - ISC - Internet Systems Consortium, Inc. - - - - dnssec-keygen - 8 - BIND9 - - - - dnssec-keygen - DNSSEC key generation tool - - - - - 2000 - 2001 - 2002 - 2003 - 2004 - 2005 - 2007 - 2008 - 2009 - 2010 - 2011 - 2012 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-keygen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - name - - - - DESCRIPTION - - dnssec-keygen - generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 - and RFC 4034. It can also generate keys for use with - TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY - (Transaction Key) as defined in RFC 2930. - - - The of the key is specified on the command - line. For DNSSEC keys, this must match the name of the zone for - which the key is being generated. - - - - OPTIONS - - - - - - -3 - - - Use an NSEC3-capable algorithm to generate a DNSSEC key. - If this option is used with an algorithm that has both - NSEC and NSEC3 versions, then the NSEC3 version will be - used; for example, dnssec-keygen -3a RSASHA1 - specifies the NSEC3RSASHA1 algorithm. - - - - - - -a algorithm - - - Selects the cryptographic algorithm. For DNSSEC keys, the value - of must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. - For TSIG/TKEY, the value must - be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, - HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are - case insensitive. - - - If no algorithm is specified, then RSASHA1 will be used by - default, unless the option is specified, - in which case NSEC3RSASHA1 will be used instead. (If - is used and an algorithm is specified, - that algorithm will be checked for compatibility with NSEC3.) - - - Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is - mandatory. - - - Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512 - automatically set the -T KEY option. - - - - - - -b keysize - - - Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSA keys must be - between 512 and 2048 bits. Diffie Hellman keys must be between - 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC keys must be - between 1 and 512 bits. Elliptic curve algorithms don't need - this parameter. - - - The key size does not need to be specified if using a default - algorithm. The default key size is 1024 bits for zone signing - keys (ZSKs) and 2048 bits for key signing keys (KSKs, - generated with ). However, if an - algorithm is explicitly specified with the , - then there is no default key size, and the - must be used. - - - - - - -C - - - Compatibility mode: generates an old-style key, without any - timing metadata. By default, dnssec-keygen - will include the key's creation date in the metadata stored with - the private key, and other dates may be set there as well - (publication date, activation date, etc). Keys that include this - data may be incompatible with older versions of BIND; the - option suppresses them. - - - - - - -c class - - - Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. - - - - - - -E engine - - - Specifies the cryptographic hardware to use, when applicable. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -f flag - - - Set the specified flag in the flag field of the KEY/DNSKEY record. - The only recognized flags are KSK (Key Signing Key) and REVOKE. - - - - - - -G - - - Generate a key, but do not publish it or sign with it. This - option is incompatible with -P and -A. - - - - - - -g generator - - - If generating a Diffie Hellman key, use this generator. - Allowed values are 2 and 5. If no generator - is specified, a known prime from RFC 2539 will be used - if possible; otherwise the default is 2. - - - - - - -h - - - Prints a short summary of the options and arguments to - dnssec-keygen. - - - - - - -K directory - - - Sets the directory in which the key files are to be written. - - - - - - -k - - - Deprecated in favor of -T KEY. - - - - - - -L ttl - - - Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. If this value is not set and there - is no existing DNSKEY RRset, the TTL will default to the - SOA TTL. Setting the default TTL to 0 - or none is the same as leaving it unset. - - - - - - -n nametype - - - Specifies the owner type of the key. The value of - must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated - with a host (KEY)), USER (for a key associated with a - user(KEY)) or OTHER (DNSKEY). These values are case - insensitive. Defaults to ZONE for DNSKEY generation. - - - - - - -p protocol - - - Sets the protocol value for the generated key, for use - with . The protocol is a number between 0 - and 255. The default is 3 (DNSSEC). Other possible values for - this argument are listed in RFC 2535 and its successors. - - - - - - -q - - - Quiet mode: Suppresses unnecessary output, including - progress indication. Without this option, when - dnssec-keygen is run interactively - to generate an RSA or DSA key pair, it will print a string - of symbols to stderr indicating the - progress of the key generation. A '.' indicates that a - random number has been found which passed an initial - sieve test; '+' means a number has passed a single - round of the Miller-Rabin primality test; a space - means that the number has passed all the tests and is - a satisfactory key. - - - - - - -r randomdev - - - Specifies a source of randomness. Normally, when generating - DNSSEC keys, this option has no effect; the random number - generation function provided by the cryptographic library will - be used. - - - If that behavior is disabled at compile time, however, - the specified file will be used as entropy source - for key generation. randomdev is - the name of a character device or file containing random - data to be used. The special value keyboard - indicates that keyboard input should be used. - - - The default is /dev/random if the - operating system provides it or an equivalent device; - if not, the default source of randomness is keyboard input. - - - - - - -S key - - - Create a new key which is an explicit successor to an - existing key. The name, algorithm, size, and type of the - key will be set to match the existing key. The activation - date of the new key will be set to the inactivation date of - the existing one. The publication date will be set to the - activation date minus the prepublication interval, which - defaults to 30 days. - - - - - - -s strength - - - Specifies the strength value of the key. The strength is - a number between 0 and 15, and currently has no defined - purpose in DNSSEC. - - - - - - -T rrtype - - - Specifies the resource record type to use for the key. - must be either DNSKEY or KEY. The - default is DNSKEY when using a DNSSEC algorithm, but it can be - overridden to KEY for use with SIG(0). - - - Using any TSIG algorithm (HMAC-* or DH) forces this option - to KEY. - - - - - - -t type - - - Indicates the use of the key, for use with . must be one of AUTHCONF, - NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH - refers to the ability to authenticate data, and CONF the ability - to encrypt data. - - - - - - -V - - - Prints version information. - - - - - - -v level - - - Sets the debugging level. - - - - - - - - TIMING OPTIONS - - - - Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. - - - - - -P date/offset - - - Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. If not set, and if the -G option has - not been used, the default is "now". - - - - - - -P sync date/offset - - - Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. - - - - - - -A date/offset - - - Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. If not set, and if the -G option has not been used, the - default is "now". If set, if and -P is not set, then - the publication date will be set to the activation date - minus the prepublication interval. - - - - - - -R date/offset - - - Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. - - - - - - -I date/offset - - - Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. - - - - - - -D date/offset - - - Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) - - - - - - -D sync date/offset - - - Sets the date on which the CDS and CDNSKEY records that match this - key are to be deleted. - - - - - - -i interval - - - Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. - - - If the key is being created as an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. - - - As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. - - - - - - - - - GENERATED KEYS - - - When dnssec-keygen completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key it has generated. - - - - nnnn is the key name. - - - - aaa is the numeric representation - of the - algorithm. - - - - iiiii is the key identifier (or - footprint). - - - - dnssec-keygen - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private - key. - - - The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). - - - The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. - - - Both .key and .private - files are generated for symmetric cryptography algorithms such as - HMAC-MD5, even though the public and private key are equivalent. - - - - EXAMPLE - - - To generate a 768-bit DSA key for the domain - example.com, the following command would be - issued: - - dnssec-keygen -a DSA -b 768 -n ZONE example.com - - - The command would print a string of the form: - - Kexample.com.+003+26160 - - - In this example, dnssec-keygen creates - the files Kexample.com.+003+26160.key - and - Kexample.com.+003+26160.private. - - - To generate a matching key-signing key, issue the command: - - - dnssec-keygen -a DSA -b 768 -n ZONE -f KSK example.com - - - - SEE ALSO - - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 2539, - RFC 2845, - RFC 4034. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-keygen.html b/bin/dnssec-pkcs11/dnssec-keygen.html deleted file mode 100644 index ac56ee9..0000000 --- a/bin/dnssec-pkcs11/dnssec-keygen.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - -dnssec-keygen - - -
-
-
-

Name

-

dnssec-keygen — DNSSEC key generation tool

-
-
-

Synopsis

-

dnssec-keygen [-3] [-A date/offset] [-a algorithm] [-b keysize] [-C] [-c class] [-D date/offset] [-D sync date/offset] [-E engine] [-f flag] [-G] [-g generator] [-h] [-I date/offset] [-i interval] [-K directory] [-k] [-L ttl] [-n nametype] [-P date/offset] [-P sync date/offset] [-p protocol] [-q] [-R date/offset] [-r randomdev] [-S key] [-s strength] [-t type] [-V] [-v level] {name}

-
-
-

DESCRIPTION

-

dnssec-keygen - generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 - and RFC 4034. It can also generate keys for use with - TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY - (Transaction Key) as defined in RFC 2930. -

-

- The name of the key is specified on the command - line. For DNSSEC keys, this must match the name of the zone for - which the key is being generated. -

-
-
-

OPTIONS

-
-
-3
-

- Use an NSEC3-capable algorithm to generate a DNSSEC key. - If this option is used with an algorithm that has both - NSEC and NSEC3 versions, then the NSEC3 version will be - used; for example, dnssec-keygen -3a RSASHA1 - specifies the NSEC3RSASHA1 algorithm. -

-
-a algorithm
-
-

- Selects the cryptographic algorithm. For DNSSEC keys, the value - of algorithm must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. - For TSIG/TKEY, the value must - be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, - HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are - case insensitive. -

-

- If no algorithm is specified, then RSASHA1 will be used by - default, unless the -3 option is specified, - in which case NSEC3RSASHA1 will be used instead. (If - -3 is used and an algorithm is specified, - that algorithm will be checked for compatibility with NSEC3.) -

-

- Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is - mandatory. -

-

- Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512 - automatically set the -T KEY option. -

-
-
-b keysize
-
-

- Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSA keys must be - between 512 and 2048 bits. Diffie Hellman keys must be between - 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC keys must be - between 1 and 512 bits. Elliptic curve algorithms don't need - this parameter. -

-

- The key size does not need to be specified if using a default - algorithm. The default key size is 1024 bits for zone signing - keys (ZSKs) and 2048 bits for key signing keys (KSKs, - generated with -f KSK). However, if an - algorithm is explicitly specified with the -a, - then there is no default key size, and the -b - must be used. -

-
-
-C
-

- Compatibility mode: generates an old-style key, without any - timing metadata. By default, dnssec-keygen - will include the key's creation date in the metadata stored with - the private key, and other dates may be set there as well - (publication date, activation date, etc). Keys that include this - data may be incompatible with older versions of BIND; the - -C option suppresses them. -

-
-c class
-

- Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. -

-
-E engine
-
-

- Specifies the cryptographic hardware to use, when applicable. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-f flag
-

- Set the specified flag in the flag field of the KEY/DNSKEY record. - The only recognized flags are KSK (Key Signing Key) and REVOKE. -

-
-G
-

- Generate a key, but do not publish it or sign with it. This - option is incompatible with -P and -A. -

-
-g generator
-

- If generating a Diffie Hellman key, use this generator. - Allowed values are 2 and 5. If no generator - is specified, a known prime from RFC 2539 will be used - if possible; otherwise the default is 2. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-keygen. -

-
-K directory
-

- Sets the directory in which the key files are to be written. -

-
-k
-

- Deprecated in favor of -T KEY. -

-
-L ttl
-

- Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. If this value is not set and there - is no existing DNSKEY RRset, the TTL will default to the - SOA TTL. Setting the default TTL to 0 - or none is the same as leaving it unset. -

-
-n nametype
-

- Specifies the owner type of the key. The value of - nametype must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated - with a host (KEY)), USER (for a key associated with a - user(KEY)) or OTHER (DNSKEY). These values are case - insensitive. Defaults to ZONE for DNSKEY generation. -

-
-p protocol
-

- Sets the protocol value for the generated key, for use - with -T KEY. The protocol is a number between 0 - and 255. The default is 3 (DNSSEC). Other possible values for - this argument are listed in RFC 2535 and its successors. -

-
-q
-

- Quiet mode: Suppresses unnecessary output, including - progress indication. Without this option, when - dnssec-keygen is run interactively - to generate an RSA or DSA key pair, it will print a string - of symbols to stderr indicating the - progress of the key generation. A '.' indicates that a - random number has been found which passed an initial - sieve test; '+' means a number has passed a single - round of the Miller-Rabin primality test; a space - means that the number has passed all the tests and is - a satisfactory key. -

-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-S key
-

- Create a new key which is an explicit successor to an - existing key. The name, algorithm, size, and type of the - key will be set to match the existing key. The activation - date of the new key will be set to the inactivation date of - the existing one. The publication date will be set to the - activation date minus the prepublication interval, which - defaults to 30 days. -

-
-s strength
-

- Specifies the strength value of the key. The strength is - a number between 0 and 15, and currently has no defined - purpose in DNSSEC. -

-
-T rrtype
-
-

- Specifies the resource record type to use for the key. - rrtype must be either DNSKEY or KEY. The - default is DNSKEY when using a DNSSEC algorithm, but it can be - overridden to KEY for use with SIG(0). -

-

-

-

- Using any TSIG algorithm (HMAC-* or DH) forces this option - to KEY. -

-
-
-t type
-

- Indicates the use of the key, for use with -T - KEY. type must be one of AUTHCONF, - NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH - refers to the ability to authenticate data, and CONF the ability - to encrypt data. -

-
-V
-

- Prints version information. -

-
-v level
-

- Sets the debugging level. -

-
-
-
-

TIMING OPTIONS

-

- Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To explicitly prevent a date from being - set, use 'none' or 'never'. -

-
-
-P date/offset
-

- Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. If not set, and if the -G option has - not been used, the default is "now". -

-
-P sync date/offset
-

- Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. -

-
-A date/offset
-

- Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. If not set, and if the -G option has not been used, the - default is "now". If set, if and -P is not set, then - the publication date will be set to the activation date - minus the prepublication interval. -

-
-R date/offset
-

- Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. -

-
-I date/offset
-

- Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. -

-
-D date/offset
-

- Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) -

-
-D sync date/offset
-

- Sets the date on which the CDS and CDNSKEY records that match this - key are to be deleted. -

-
-i interval
-
-

- Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. -

-

- If the key is being created as an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. -

-

- As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. -

-
-
-
-
-

GENERATED KEYS

-

- When dnssec-keygen completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key it has generated. -

-
    -
  • nnnn is the key name. -

  • -
  • aaa is the numeric representation - of the - algorithm. -

  • -
  • iiiii is the key identifier (or - footprint). -

  • -
-

dnssec-keygen - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private - key. -

-

- The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). -

-

- The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. -

-

- Both .key and .private - files are generated for symmetric cryptography algorithms such as - HMAC-MD5, even though the public and private key are equivalent. -

-
-
-

EXAMPLE

-

- To generate a 768-bit DSA key for the domain - example.com, the following command would be - issued: -

-

dnssec-keygen -a DSA -b 768 -n ZONE example.com -

-

- The command would print a string of the form: -

-

Kexample.com.+003+26160 -

-

- In this example, dnssec-keygen creates - the files Kexample.com.+003+26160.key - and - Kexample.com.+003+26160.private. -

-

- To generate a matching key-signing key, issue the command: -

-

- dnssec-keygen -a DSA -b 768 -n ZONE -f KSK example.com -

-
-
-

SEE ALSO

-

dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 2539, - RFC 2845, - RFC 4034. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-revoke.8 b/bin/dnssec-pkcs11/dnssec-revoke.8 deleted file mode 100644 index 60a196f..0000000 --- a/bin/dnssec-pkcs11/dnssec-revoke.8 +++ /dev/null @@ -1,103 +0,0 @@ -.\" Copyright (C) 2009, 2011, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-revoke -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2014-01-15 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-REVOKE" "8" "2014\-01\-15" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-revoke \- set the REVOKED bit on a DNSSEC key -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-revoke\fR\ 'u -\fBdnssec\-revoke\fR [\fB\-hr\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\fR] [\fB\-R\fR] {keyfile} -.SH "DESCRIPTION" -.PP -\fBdnssec\-revoke\fR -reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now\-revoked key\&. -.SH "OPTIONS" -.PP -\-h -.RS 4 -Emit usage message and exit\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Sets the directory in which the key files are to reside\&. -.RE -.PP -\-r -.RS 4 -After writing the new keyset files remove the original keyset files\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -Specifies the cryptographic hardware to use, when applicable\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-f -.RS 4 -Force overwrite: Causes -\fBdnssec\-revoke\fR -to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key\&. -.RE -.PP -\-R -.RS 4 -Print the key tag of the key with the REVOKE bit set but do not revoke the key\&. -.RE -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -BIND 9 Administrator Reference Manual, -RFC 5011\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2009, 2011, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-revoke.c b/bin/dnssec-pkcs11/dnssec-revoke.c deleted file mode 100644 index 74a99b0..0000000 --- a/bin/dnssec-pkcs11/dnssec-revoke.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-revoke"; -int verbose; - -static isc_mem_t *mctx = NULL; - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] keyfile\n\n", program); - fprintf(stderr, "Version: %s\n", VERSION); -#if defined(PKCS11CRYPTO) - fprintf(stderr, " -E engine: specify PKCS#11 provider " - "(default: %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, " -E engine: specify OpenSSL engine " - "(default \"pkcs11\")\n"); -#else - fprintf(stderr, " -E engine: specify OpenSSL engine\n"); -#endif - fprintf(stderr, " -f: force overwrite\n"); - fprintf(stderr, " -h: help\n"); - fprintf(stderr, " -K directory: use directory for key files\n"); - fprintf(stderr, " -r: remove old keyfiles after " - "creating revoked version\n"); - fprintf(stderr, " -v level: set level of verbosity\n"); - fprintf(stderr, " -V: print version information\n"); - fprintf(stderr, "Output:\n"); - fprintf(stderr, " K++.key, " - "K++.private\n"); - - exit (-1); -} - -int -main(int argc, char **argv) { - isc_result_t result; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - char const *filename = NULL; - char *dir = NULL; - char newname[1024], oldname[1024]; - char keystr[DST_KEY_FORMATSIZE]; - char *endp; - int ch; - isc_entropy_t *ectx = NULL; - dst_key_t *key = NULL; - uint32_t flags; - isc_buffer_t buf; - bool force = false; - bool removefile = false; - bool id = false; - - if (argc == 1) - usage(); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("Out of memory"); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - while ((ch = isc_commandline_parse(argc, argv, "E:fK:rRhv:V")) != -1) { - switch (ch) { - case 'E': - engine = isc_commandline_argument; - break; - case 'f': - force = true; - break; - case 'K': - /* - * We don't have to copy it here, but do it to - * simplify cleanup later - */ - dir = isc_mem_strdup(mctx, isc_commandline_argument); - if (dir == NULL) { - fatal("Failed to allocate memory for " - "directory"); - } - break; - case 'r': - removefile = true; - break; - case 'R': - id = true; - break; - case 'v': - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (argc < isc_commandline_index + 1 || - argv[isc_commandline_index] == NULL) - fatal("The key file name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("Extraneous arguments"); - - if (dir != NULL) { - filename = argv[isc_commandline_index]; - } else { - result = isc_file_splitpath(mctx, argv[isc_commandline_index], - &dir, &filename); - if (result != ISC_R_SUCCESS) - fatal("cannot process filename %s: %s", - argv[isc_commandline_index], - isc_result_totext(result)); - if (strcmp(dir, ".") == 0) { - isc_mem_free(mctx, dir); - dir = NULL; - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - result = dst_lib_init2(mctx, ectx, engine, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize dst: %s", - isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize hash"); - isc_entropy_stopcallbacksources(ectx); - - result = dst_key_fromnamedfile(filename, dir, - DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - mctx, &key); - if (result != ISC_R_SUCCESS) - fatal("Invalid keyfile name %s: %s", - filename, isc_result_totext(result)); - - if (id) { - fprintf(stdout, "%u\n", dst_key_rid(key)); - goto cleanup; - } - dst_key_format(key, keystr, sizeof(keystr)); - - if (verbose > 2) - fprintf(stderr, "%s: %s\n", program, keystr); - - if (force) - set_keyversion(key); - else - check_keyversion(key, keystr); - - - flags = dst_key_flags(key); - if ((flags & DNS_KEYFLAG_REVOKE) == 0) { - isc_stdtime_t now; - - if ((flags & DNS_KEYFLAG_KSK) == 0) - fprintf(stderr, "%s: warning: Key is not flagged " - "as a KSK. Revoking a ZSK is " - "legal, but undefined.\n", - program); - - isc_stdtime_get(&now); - dst_key_settime(key, DST_TIME_REVOKE, now); - - dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE); - - isc_buffer_init(&buf, newname, sizeof(newname)); - dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); - - if (access(newname, F_OK) == 0 && !force) { - fatal("Key file %s already exists; " - "use -f to force overwrite", newname); - } - - result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - dir); - if (result != ISC_R_SUCCESS) { - dst_key_format(key, keystr, sizeof(keystr)); - fatal("Failed to write key %s: %s", keystr, - isc_result_totext(result)); - } - - isc_buffer_clear(&buf); - dst_key_buildfilename(key, 0, dir, &buf); - printf("%s\n", newname); - - /* - * Remove old key file, if told to (and if - * it isn't the same as the new file) - */ - if (removefile && dst_key_alg(key) != DST_ALG_RSAMD5) { - isc_buffer_init(&buf, oldname, sizeof(oldname)); - dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE); - dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); - if (strcmp(oldname, newname) == 0) - goto cleanup; - (void)unlink(oldname); - isc_buffer_clear(&buf); - dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); - (void)unlink(oldname); - } - } else { - dst_key_format(key, keystr, sizeof(keystr)); - fatal("Key %s is already revoked", keystr); - } - -cleanup: - dst_key_free(&key); - isc_hash_destroy(); - dst_lib_destroy(); - cleanup_entropy(&ectx); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - if (dir != NULL) - isc_mem_free(mctx, dir); - isc_mem_destroy(&mctx); - - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-revoke.docbook b/bin/dnssec-pkcs11/dnssec-revoke.docbook deleted file mode 100644 index 35d425c..0000000 --- a/bin/dnssec-pkcs11/dnssec-revoke.docbook +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - 2014-01-15 - - - ISC - Internet Systems Consortium, Inc. - - - - dnssec-revoke - 8 - BIND9 - - - - dnssec-revoke - set the REVOKED bit on a DNSSEC key - - - - - 2009 - 2011 - 2014 - 2015 - 2016 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-revoke - - - - - - - - keyfile - - - - DESCRIPTION - - dnssec-revoke - reads a DNSSEC key file, sets the REVOKED bit on the key as defined - in RFC 5011, and creates a new pair of key files containing the - now-revoked key. - - - - OPTIONS - - - - - -h - - - Emit usage message and exit. - - - - - - -K directory - - - Sets the directory in which the key files are to reside. - - - - - - -r - - - After writing the new keyset files remove the original keyset - files. - - - - - - -v level - - - Sets the debugging level. - - - - - - -V - - - Prints version information. - - - - - - -E engine - - - Specifies the cryptographic hardware to use, when applicable. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -f - - - Force overwrite: Causes dnssec-revoke to - write the new key pair even if a file already exists matching - the algorithm and key ID of the revoked key. - - - - - - -R - - - Print the key tag of the key with the REVOKE bit set but do - not revoke the key. - - - - - - - SEE ALSO - - - dnssec-keygen8 - , - BIND 9 Administrator Reference Manual, - RFC 5011. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-revoke.html b/bin/dnssec-pkcs11/dnssec-revoke.html deleted file mode 100644 index 2578146..0000000 --- a/bin/dnssec-pkcs11/dnssec-revoke.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - -dnssec-revoke - - -
-
-
-

Name

-

dnssec-revoke — set the REVOKED bit on a DNSSEC key

-
-
-

Synopsis

-

dnssec-revoke [-hr] [-v level] [-V] [-K directory] [-E engine] [-f] [-R] {keyfile}

-
-
-

DESCRIPTION

-

dnssec-revoke - reads a DNSSEC key file, sets the REVOKED bit on the key as defined - in RFC 5011, and creates a new pair of key files containing the - now-revoked key. -

-
-
-

OPTIONS

-
-
-h
-

- Emit usage message and exit. -

-
-K directory
-

- Sets the directory in which the key files are to reside. -

-
-r
-

- After writing the new keyset files remove the original keyset - files. -

-
-v level
-

- Sets the debugging level. -

-
-V
-

- Prints version information. -

-
-E engine
-
-

- Specifies the cryptographic hardware to use, when applicable. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-f
-

- Force overwrite: Causes dnssec-revoke to - write the new key pair even if a file already exists matching - the algorithm and key ID of the revoked key. -

-
-R
-

- Print the key tag of the key with the REVOKE bit set but do - not revoke the key. -

-
-
-
-

SEE ALSO

-

dnssec-keygen(8), - BIND 9 Administrator Reference Manual, - RFC 5011. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-settime.8 b/bin/dnssec-pkcs11/dnssec-settime.8 deleted file mode 100644 index d37f29e..0000000 --- a/bin/dnssec-pkcs11/dnssec-settime.8 +++ /dev/null @@ -1,204 +0,0 @@ -.\" Copyright (C) 2009-2011, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-settime -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2015-08-21 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-SETTIME" "8" "2015\-08\-21" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-settime \- set the key timing metadata for a DNSSEC key -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-settime\fR\ 'u -\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-P\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ sync\ \fR\fB\fIdate/offset\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-h\fR] [\fB\-V\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile} -.SH "DESCRIPTION" -.PP -\fBdnssec\-settime\fR -reads a DNSSEC private key file and sets the key timing metadata as specified by the -\fB\-P\fR, -\fB\-A\fR, -\fB\-R\fR, -\fB\-I\fR, and -\fB\-D\fR -options\&. The metadata can then be used by -\fBdnssec\-signzone\fR -or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc\&. -.PP -If none of these options is set on the command line, then -\fBdnssec\-settime\fR -simply prints the key timing metadata already stored in the key\&. -.PP -When key metadata fields are changed, both files of a key pair (Knnnn\&.+aaa+iiiii\&.key -and -Knnnn\&.+aaa+iiiii\&.private) are regenerated\&. Metadata fields are stored in the private file\&. A human\-readable description of the metadata is also placed in comments in the key file\&. The private file\*(Aqs permissions are always set to be inaccessible to anyone other than the owner (mode 0600)\&. -.SH "OPTIONS" -.PP -\-f -.RS 4 -Force an update of an old\-format key with no metadata fields\&. Without this option, -\fBdnssec\-settime\fR -will fail when attempting to update a legacy key\&. With this option, the key will be recreated in the new format, but with the original key data retained\&. The key\*(Aqs creation date will be set to the present time\&. If no other values are specified, then the key\*(Aqs publication and activation dates will also be set to the present time\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Sets the directory in which the key files are to reside\&. -.RE -.PP -\-L \fIttl\fR -.RS 4 -Sets the default TTL to use for this key when it is converted into a DNSKEY RR\&. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence\&. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL\&. Setting the default TTL to -0 -or -none -removes it from the key\&. -.RE -.PP -\-h -.RS 4 -Emit usage message and exit\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -Specifies the cryptographic hardware to use, when applicable\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.SH "TIMING OPTIONS" -.PP -Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS\&. If the argument begins with a \*(Aq+\*(Aq or \*(Aq\-\*(Aq, it is interpreted as an offset from the present time\&. For convenience, if such an offset is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively\&. Without a suffix, the offset is computed in seconds\&. To unset a date, use \*(Aqnone\*(Aq or \*(Aqnever\*(Aq\&. -.PP -\-P \fIdate/offset\fR -.RS 4 -Sets the date on which a key is to be published to the zone\&. After that date, the key will be included in the zone but will not be used to sign it\&. -.RE -.PP -\-P sync \fIdate/offset\fR -.RS 4 -Sets the date on which CDS and CDNSKEY records that match this key are to be published to the zone\&. -.RE -.PP -\-A \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be activated\&. After that date, the key will be included in the zone and used to sign it\&. -.RE -.PP -\-R \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be revoked\&. After that date, the key will be flagged as revoked\&. It will be included in the zone and will be used to sign it\&. -.RE -.PP -\-I \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be retired\&. After that date, the key will still be included in the zone, but it will not be used to sign it\&. -.RE -.PP -\-D \fIdate/offset\fR -.RS 4 -Sets the date on which the key is to be deleted\&. After that date, the key will no longer be included in the zone\&. (It may remain in the key repository, however\&.) -.RE -.PP -\-D sync \fIdate/offset\fR -.RS 4 -Sets the date on which the CDS and CDNSKEY records that match this key are to be deleted\&. -.RE -.PP -\-S \fIpredecessor key\fR -.RS 4 -Select a key for which the key being modified will be an explicit successor\&. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified\&. The activation date of the successor key will be set to the inactivation date of the predecessor\&. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days\&. -.RE -.PP -\-i \fIinterval\fR -.RS 4 -Sets the prepublication interval for a key\&. If set, then the publication and activation dates must be separated by at least this much time\&. If the activation date is specified but the publication date isn\*(Aqt, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn\*(Aqt, then activation will be set to this much time after publication\&. -.sp -If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero\&. -.sp -As with date offsets, if the argument is followed by one of the suffixes \*(Aqy\*(Aq, \*(Aqmo\*(Aq, \*(Aqw\*(Aq, \*(Aqd\*(Aq, \*(Aqh\*(Aq, or \*(Aqmi\*(Aq, then the interval is measured in years, months, weeks, days, hours, or minutes, respectively\&. Without a suffix, the interval is measured in seconds\&. -.RE -.SH "PRINTING OPTIONS" -.PP -\fBdnssec\-settime\fR -can also be used to print the timing metadata associated with a key\&. -.PP -\-u -.RS 4 -Print times in UNIX epoch format\&. -.RE -.PP -\-p \fIC/P/Psync/A/R/I/D/Dsync/all\fR -.RS 4 -Print a specific metadata value or set of metadata values\&. The -\fB\-p\fR -option may be followed by one or more of the following letters or strings to indicate which value or values to print: -\fBC\fR -for the creation date, -\fBP\fR -for the publication date, -\fBPsync\fR -for the CDS and CDNSKEY publication date, -\fBA\fR -for the activation date, -\fBR\fR -for the revocation date, -\fBI\fR -for the inactivation date, -\fBD\fR -for the deletion date, and -\fBDsync\fR -for the CDS and CDNSKEY deletion date To print all of the metadata, use -\fB\-p all\fR\&. -.RE -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 5011\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2009-2011, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-settime.c b/bin/dnssec-pkcs11/dnssec-settime.c deleted file mode 100644 index 2c568fc..0000000 --- a/bin/dnssec-pkcs11/dnssec-settime.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-settime"; -int verbose; - -static isc_mem_t *mctx = NULL; - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] keyfile\n\n", program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, "General options:\n"); -#if defined(PKCS11CRYPTO) - fprintf(stderr, " -E engine: specify PKCS#11 provider " - "(default: %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, " -E engine: specify OpenSSL engine " - "(default \"pkcs11\")\n"); -#else - fprintf(stderr, " -E engine: specify OpenSSL engine\n"); -#endif - fprintf(stderr, " -f: force update of old-style " - "keys\n"); - fprintf(stderr, " -K directory: set key file location\n"); - fprintf(stderr, " -L ttl: set default key TTL\n"); - fprintf(stderr, " -v level: set level of verbosity\n"); - fprintf(stderr, " -V: print version information\n"); - fprintf(stderr, " -h: help\n"); - fprintf(stderr, "Timing options:\n"); - fprintf(stderr, " -P date/[+-]offset/none: set/unset key " - "publication date\n"); - fprintf(stderr, " -P sync date/[+-]offset/none: set/unset " - "CDS and CDNSKEY publication date\n"); - fprintf(stderr, " -A date/[+-]offset/none: set/unset key " - "activation date\n"); - fprintf(stderr, " -R date/[+-]offset/none: set/unset key " - "revocation date\n"); - fprintf(stderr, " -I date/[+-]offset/none: set/unset key " - "inactivation date\n"); - fprintf(stderr, " -D date/[+-]offset/none: set/unset key " - "deletion date\n"); - fprintf(stderr, " -D sync date/[+-]offset/none: set/unset " - "CDS and CDNSKEY deletion date\n"); - fprintf(stderr, " -S : generate a successor to an existing " - "key\n"); - fprintf(stderr, " -i : prepublication interval for " - "successor key " - "(default: 30 days)\n"); - fprintf(stderr, "Printing options:\n"); - fprintf(stderr, " -p C/P/Psync/A/R/I/D/Dsync/all: print a " - "particular time value or values\n"); - fprintf(stderr, " -u: print times in unix epoch " - "format\n"); - fprintf(stderr, "Output:\n"); - fprintf(stderr, " K++.key, " - "K++.private\n"); - - exit (-1); -} - -static void -printtime(dst_key_t *key, int type, const char *tag, bool epoch, - FILE *stream) -{ - isc_result_t result; - isc_stdtime_t when; - - if (tag != NULL) - fprintf(stream, "%s: ", tag); - - result = dst_key_gettime(key, type, &when); - if (result == ISC_R_NOTFOUND) { - fprintf(stream, "UNSET\n"); - } else if (epoch) { - fprintf(stream, "%d\n", (int) when); - } else { - time_t now = when; - struct tm t, *tm = localtime_r(&now, &t); - unsigned int flen; - char timebuf[80]; - - if (tm == NULL) { - fprintf(stream, "INVALID\n"); - return; - } - - flen = strftime(timebuf, sizeof(timebuf), - "%a %b %e %H:%M:%S %Y", tm); - INSIST(flen > 0U && flen < sizeof(timebuf)); - fprintf(stream, "%s\n", timebuf); - } -} - -int -main(int argc, char **argv) { - isc_result_t result; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - const char *filename = NULL; - char *directory = NULL; - char newname[1024]; - char keystr[DST_KEY_FORMATSIZE]; - char *endp, *p; - int ch; - isc_entropy_t *ectx = NULL; - const char *predecessor = NULL; - dst_key_t *prevkey = NULL; - dst_key_t *key = NULL; - isc_buffer_t buf; - dns_name_t *name = NULL; - dns_secalg_t alg = 0; - unsigned int size = 0; - uint16_t flags = 0; - int prepub = -1; - dns_ttl_t ttl = 0; - isc_stdtime_t now; - isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0; - isc_stdtime_t prevact = 0, previnact = 0, prevdel = 0; - bool setpub = false, setact = false; - bool setrev = false, setinact = false; - bool setdel = false, setttl = false; - bool unsetpub = false, unsetact = false; - bool unsetrev = false, unsetinact = false; - bool unsetdel = false; - bool printcreate = false, printpub = false; - bool printact = false, printrev = false; - bool printinact = false, printdel = false; - bool force = false; - bool epoch = false; - bool changed = false; - isc_log_t *log = NULL; - isc_stdtime_t syncadd = 0, syncdel = 0; - bool unsetsyncadd = false, setsyncadd = false; - bool unsetsyncdel = false, setsyncdel = false; - bool printsyncadd = false, printsyncdel = false; - - if (argc == 1) - usage(); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("Out of memory"); - - setup_logging(mctx, &log); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - isc_stdtime_get(&now); - -#define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:V" - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'A': - if (setact || unsetact) - fatal("-A specified more than once"); - - changed = true; - act = strtotime(isc_commandline_argument, - now, now, &setact); - unsetact = !setact; - break; - case 'D': - /* -Dsync ? */ - if (isoptarg("sync", argv, usage)) { - if (unsetsyncdel || setsyncdel) - fatal("-D sync specified more than " - "once"); - - changed = true; - syncdel = strtotime(isc_commandline_argument, - now, now, &setsyncdel); - unsetsyncdel = !setsyncdel; - break; - } - /* -Ddnskey ? */ - (void)isoptarg("dnskey", argv, usage); - if (setdel || unsetdel) - fatal("-D specified more than once"); - - changed = true; - del = strtotime(isc_commandline_argument, - now, now, &setdel); - unsetdel = !setdel; - break; - case 'E': - engine = isc_commandline_argument; - break; - case 'f': - force = true; - break; - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - case 'I': - if (setinact || unsetinact) - fatal("-I specified more than once"); - - changed = true; - inact = strtotime(isc_commandline_argument, - now, now, &setinact); - unsetinact = !setinact; - break; - case 'i': - prepub = strtottl(isc_commandline_argument); - break; - case 'K': - /* - * We don't have to copy it here, but do it to - * simplify cleanup later - */ - directory = isc_mem_strdup(mctx, - isc_commandline_argument); - if (directory == NULL) { - fatal("Failed to allocate memory for " - "directory"); - } - break; - case 'L': - ttl = strtottl(isc_commandline_argument); - setttl = true; - break; - case 'P': - /* -Psync ? */ - if (isoptarg("sync", argv, usage)) { - if (unsetsyncadd || setsyncadd) - fatal("-P sync specified more than " - "once"); - - changed = true; - syncadd = strtotime(isc_commandline_argument, - now, now, &setsyncadd); - unsetsyncadd = !setsyncadd; - break; - } - (void)isoptarg("dnskey", argv, usage); - if (setpub || unsetpub) - fatal("-P specified more than once"); - - changed = true; - pub = strtotime(isc_commandline_argument, - now, now, &setpub); - unsetpub = !setpub; - break; - case 'p': - p = isc_commandline_argument; - if (!strcasecmp(p, "all")) { - printcreate = true; - printpub = true; - printact = true; - printrev = true; - printinact = true; - printdel = true; - printsyncadd = true; - printsyncdel = true; - break; - } - - do { - switch (*p++) { - case 'A': - printact = true; - break; - case 'C': - printcreate = true; - break; - case 'D': - if (!strncmp(p, "sync", 4)) { - p += 4; - printsyncdel = true; - break; - } - printdel = true; - break; - case 'I': - printinact = true; - break; - case 'P': - if (!strncmp(p, "sync", 4)) { - p += 4; - printsyncadd = true; - break; - } - printpub = true; - break; - case 'R': - printrev = true; - break; - case ' ': - break; - default: - usage(); - break; - } - } while (*p != '\0'); - break; - case 'R': - if (setrev || unsetrev) - fatal("-R specified more than once"); - - changed = true; - rev = strtotime(isc_commandline_argument, - now, now, &setrev); - unsetrev = !setrev; - break; - case 'S': - predecessor = isc_commandline_argument; - break; - case 'u': - epoch = true; - break; - case 'V': - /* Does not return. */ - version(program); - case 'v': - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (argc < isc_commandline_index + 1 || - argv[isc_commandline_index] == NULL) - fatal("The key file name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("Extraneous arguments"); - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - result = dst_lib_init2(mctx, ectx, engine, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize dst: %s", - isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize hash"); - isc_entropy_stopcallbacksources(ectx); - - if (predecessor != NULL) { - int major, minor; - - if (prepub == -1) - prepub = (30 * 86400); - - if (setpub || unsetpub) - fatal("-S and -P cannot be used together"); - if (setact || unsetact) - fatal("-S and -A cannot be used together"); - - result = dst_key_fromnamedfile(predecessor, directory, - DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE, - mctx, &prevkey); - if (result != ISC_R_SUCCESS) - fatal("Invalid keyfile %s: %s", - filename, isc_result_totext(result)); - if (!dst_key_isprivate(prevkey) && !dst_key_isexternal(prevkey)) - fatal("%s is not a private key", filename); - - name = dst_key_name(prevkey); - alg = dst_key_alg(prevkey); - size = dst_key_size(prevkey); - flags = dst_key_flags(prevkey); - - dst_key_format(prevkey, keystr, sizeof(keystr)); - dst_key_getprivateformat(prevkey, &major, &minor); - if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) - fatal("Predecessor has incompatible format " - "version %d.%d\n\t", major, minor); - - result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &prevact); - if (result != ISC_R_SUCCESS) - fatal("Predecessor has no activation date. " - "You must set one before\n\t" - "generating a successor."); - - result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, - &previnact); - if (result != ISC_R_SUCCESS) - fatal("Predecessor has no inactivation date. " - "You must set one before\n\t" - "generating a successor."); - - pub = previnact - prepub; - act = previnact; - - if ((previnact - prepub) < now && prepub != 0) - fatal("Time until predecessor inactivation is\n\t" - "shorter than the prepublication interval. " - "Either change\n\t" - "predecessor inactivation date, or use the -i " - "option to set\n\t" - "a shorter prepublication interval."); - - result = dst_key_gettime(prevkey, DST_TIME_DELETE, &prevdel); - if (result != ISC_R_SUCCESS) - fprintf(stderr, "%s: warning: Predecessor has no " - "removal date;\n\t" - "it will remain in the zone " - "indefinitely after rollover.\n", - program); - else if (prevdel < previnact) - fprintf(stderr, "%s: warning: Predecessor is " - "scheduled to be deleted\n\t" - "before it is scheduled to be " - "inactive.\n", program); - - changed = setpub = setact = true; - } else { - if (prepub < 0) - prepub = 0; - - if (prepub > 0) { - if (setpub && setact && (act - prepub) < pub) - fatal("Activation and publication dates " - "are closer together than the\n\t" - "prepublication interval."); - - if (setpub && !setact) { - setact = true; - act = pub + prepub; - } else if (setact && !setpub) { - setpub = true; - pub = act - prepub; - } - - if ((act - prepub) < now) - fatal("Time until activation is shorter " - "than the\n\tprepublication interval."); - } - } - - if (directory != NULL) { - filename = argv[isc_commandline_index]; - } else { - result = isc_file_splitpath(mctx, argv[isc_commandline_index], - &directory, &filename); - if (result != ISC_R_SUCCESS) - fatal("cannot process filename %s: %s", - argv[isc_commandline_index], - isc_result_totext(result)); - } - - result = dst_key_fromnamedfile(filename, directory, - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - mctx, &key); - if (result != ISC_R_SUCCESS) - fatal("Invalid keyfile %s: %s", - filename, isc_result_totext(result)); - - if (!dst_key_isprivate(key) && !dst_key_isexternal(key)) - fatal("%s is not a private key", filename); - - dst_key_format(key, keystr, sizeof(keystr)); - - if (predecessor != NULL) { - if (!dns_name_equal(name, dst_key_name(key))) - fatal("Key name mismatch"); - if (alg != dst_key_alg(key)) - fatal("Key algorithm mismatch"); - if (size != dst_key_size(key)) - fatal("Key size mismatch"); - if (flags != dst_key_flags(key)) - fatal("Key flags mismatch"); - } - - prevdel = previnact = 0; - if ((setdel && setinact && del < inact) || - (dst_key_gettime(key, DST_TIME_INACTIVE, - &previnact) == ISC_R_SUCCESS && - setdel && !setinact && !unsetinact && del < previnact) || - (dst_key_gettime(key, DST_TIME_DELETE, - &prevdel) == ISC_R_SUCCESS && - setinact && !setdel && !unsetdel && prevdel < inact) || - (!setdel && !unsetdel && !setinact && !unsetinact && - prevdel != 0 && prevdel < previnact)) - fprintf(stderr, "%s: warning: Key is scheduled to " - "be deleted before it is\n\t" - "scheduled to be inactive.\n", - program); - - if (force) - set_keyversion(key); - else - check_keyversion(key, keystr); - - if (verbose > 2) - fprintf(stderr, "%s: %s\n", program, keystr); - - /* - * Set time values. - */ - if (setpub) - dst_key_settime(key, DST_TIME_PUBLISH, pub); - else if (unsetpub) - dst_key_unsettime(key, DST_TIME_PUBLISH); - - if (setact) - dst_key_settime(key, DST_TIME_ACTIVATE, act); - else if (unsetact) - dst_key_unsettime(key, DST_TIME_ACTIVATE); - - if (setrev) { - if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) - fprintf(stderr, "%s: warning: Key %s is already " - "revoked; changing the revocation date " - "will not affect this.\n", - program, keystr); - if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0) - fprintf(stderr, "%s: warning: Key %s is not flagged as " - "a KSK, but -R was used. Revoking a " - "ZSK is legal, but undefined.\n", - program, keystr); - dst_key_settime(key, DST_TIME_REVOKE, rev); - } else if (unsetrev) { - if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) - fprintf(stderr, "%s: warning: Key %s is already " - "revoked; removing the revocation date " - "will not affect this.\n", - program, keystr); - dst_key_unsettime(key, DST_TIME_REVOKE); - } - - if (setinact) - dst_key_settime(key, DST_TIME_INACTIVE, inact); - else if (unsetinact) - dst_key_unsettime(key, DST_TIME_INACTIVE); - - if (setdel) - dst_key_settime(key, DST_TIME_DELETE, del); - else if (unsetdel) - dst_key_unsettime(key, DST_TIME_DELETE); - - if (setsyncadd) - dst_key_settime(key, DST_TIME_SYNCPUBLISH, syncadd); - else if (unsetsyncadd) - dst_key_unsettime(key, DST_TIME_SYNCPUBLISH); - - if (setsyncdel) - dst_key_settime(key, DST_TIME_SYNCDELETE, syncdel); - else if (unsetsyncdel) - dst_key_unsettime(key, DST_TIME_SYNCDELETE); - - if (setttl) - dst_key_setttl(key, ttl); - - /* - * No metadata changes were made but we're forcing an upgrade - * to the new format anyway: use "-P now -A now" as the default - */ - if (force && !changed) { - dst_key_settime(key, DST_TIME_PUBLISH, now); - dst_key_settime(key, DST_TIME_ACTIVATE, now); - changed = true; - } - - if (!changed && setttl) - changed = true; - - /* - * Print out time values, if -p was used. - */ - if (printcreate) - printtime(key, DST_TIME_CREATED, "Created", epoch, stdout); - - if (printpub) - printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout); - - if (printact) - printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout); - - if (printrev) - printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout); - - if (printinact) - printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout); - - if (printdel) - printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout); - - if (printsyncadd) - printtime(key, DST_TIME_SYNCPUBLISH, "SYNC Publish", - epoch, stdout); - - if (printsyncdel) - printtime(key, DST_TIME_SYNCDELETE, "SYNC Delete", - epoch, stdout); - - if (changed) { - isc_buffer_init(&buf, newname, sizeof(newname)); - result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, - &buf); - if (result != ISC_R_SUCCESS) { - fatal("Failed to build public key filename: %s", - isc_result_totext(result)); - } - - result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - directory); - if (result != ISC_R_SUCCESS) { - dst_key_format(key, keystr, sizeof(keystr)); - fatal("Failed to write key %s: %s", keystr, - isc_result_totext(result)); - } - - printf("%s\n", newname); - - isc_buffer_clear(&buf); - result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, - &buf); - if (result != ISC_R_SUCCESS) { - fatal("Failed to build private key filename: %s", - isc_result_totext(result)); - } - printf("%s\n", newname); - } - - if (prevkey != NULL) - dst_key_free(&prevkey); - dst_key_free(&key); - isc_hash_destroy(); - dst_lib_destroy(); - cleanup_entropy(&ectx); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - cleanup_logging(&log); - isc_mem_free(mctx, directory); - isc_mem_destroy(&mctx); - - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-settime.docbook b/bin/dnssec-pkcs11/dnssec-settime.docbook deleted file mode 100644 index 75f5035..0000000 --- a/bin/dnssec-pkcs11/dnssec-settime.docbook +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - 2015-08-21 - - - ISC - Internet Systems Consortium, Inc. - - - - dnssec-settime - 8 - BIND9 - - - - dnssec-settime - set the key timing metadata for a DNSSEC key - - - - - 2009 - 2010 - 2011 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-settime - - - - - - - - - - - - - - - - - keyfile - - - - DESCRIPTION - - dnssec-settime - reads a DNSSEC private key file and sets the key timing metadata - as specified by the , , - , , and - options. The metadata can then be used by - dnssec-signzone or other signing software to - determine when a key is to be published, whether it should be - used for signing a zone, etc. - - - If none of these options is set on the command line, - then dnssec-settime simply prints the key timing - metadata already stored in the key. - - - When key metadata fields are changed, both files of a key - pair (Knnnn.+aaa+iiiii.key and - Knnnn.+aaa+iiiii.private) are regenerated. - Metadata fields are stored in the private file. A human-readable - description of the metadata is also placed in comments in the key - file. The private file's permissions are always set to be - inaccessible to anyone other than the owner (mode 0600). - - - - OPTIONS - - - - - -f - - - Force an update of an old-format key with no metadata fields. - Without this option, dnssec-settime will - fail when attempting to update a legacy key. With this option, - the key will be recreated in the new format, but with the - original key data retained. The key's creation date will be - set to the present time. If no other values are specified, - then the key's publication and activation dates will also - be set to the present time. - - - - - - -K directory - - - Sets the directory in which the key files are to reside. - - - - - - -L ttl - - - Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. If this value is not set and there - is no existing DNSKEY RRset, the TTL will default to the - SOA TTL. Setting the default TTL to 0 - or none removes it from the key. - - - - - - -h - - - Emit usage message and exit. - - - - - - -V - - - Prints version information. - - - - - - -v level - - - Sets the debugging level. - - - - - - -E engine - - - Specifies the cryptographic hardware to use, when applicable. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - - TIMING OPTIONS - - - Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To unset a date, use 'none' or 'never'. - - - - - -P date/offset - - - Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. - - - - - - -P sync date/offset - - - Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. - - - - - - -A date/offset - - - Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. - - - - - - -R date/offset - - - Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. - - - - - - -I date/offset - - - Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. - - - - - - -D date/offset - - - Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) - - - - - - -D sync date/offset - - - Sets the date on which the CDS and CDNSKEY records that match this - key are to be deleted. - - - - - - -S predecessor key - - - Select a key for which the key being modified will be an - explicit successor. The name, algorithm, size, and type of the - predecessor key must exactly match those of the key being - modified. The activation date of the successor key will be set - to the inactivation date of the predecessor. The publication - date will be set to the activation date minus the prepublication - interval, which defaults to 30 days. - - - - - - -i interval - - - Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. - - - If the key is being set to be an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. - - - As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. - - - - - - - PRINTING OPTIONS - - - dnssec-settime can also be used to print the - timing metadata associated with a key. - - - - - -u - - - Print times in UNIX epoch format. - - - - - - -p C/P/Psync/A/R/I/D/Dsync/all - - - Print a specific metadata value or set of metadata values. - The option may be followed by one or more - of the following letters or strings to indicate which value - or values to print: - for the creation date, - for the publication date, - for the CDS and CDNSKEY publication date, - for the activation date, - for the revocation date, - for the inactivation date, - for the deletion date, and - for the CDS and CDNSKEY deletion date - To print all of the metadata, use . - - - - - - - - SEE ALSO - - - dnssec-keygen8 - , - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 5011. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-settime.html b/bin/dnssec-pkcs11/dnssec-settime.html deleted file mode 100644 index 3d3cf09..0000000 --- a/bin/dnssec-pkcs11/dnssec-settime.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - -dnssec-settime - - -
-
-
-

Name

-

dnssec-settime — set the key timing metadata for a DNSSEC key

-
-
-

Synopsis

-

dnssec-settime [-f] [-K directory] [-L ttl] [-P date/offset] [-P sync date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-D sync date/offset] [-S key] [-i interval] [-h] [-V] [-v level] [-E engine] {keyfile}

-
-
-

DESCRIPTION

-

dnssec-settime - reads a DNSSEC private key file and sets the key timing metadata - as specified by the -P, -A, - -R, -I, and -D - options. The metadata can then be used by - dnssec-signzone or other signing software to - determine when a key is to be published, whether it should be - used for signing a zone, etc. -

-

- If none of these options is set on the command line, - then dnssec-settime simply prints the key timing - metadata already stored in the key. -

-

- When key metadata fields are changed, both files of a key - pair (Knnnn.+aaa+iiiii.key and - Knnnn.+aaa+iiiii.private) are regenerated. - Metadata fields are stored in the private file. A human-readable - description of the metadata is also placed in comments in the key - file. The private file's permissions are always set to be - inaccessible to anyone other than the owner (mode 0600). -

-
-
-

OPTIONS

-
-
-f
-

- Force an update of an old-format key with no metadata fields. - Without this option, dnssec-settime will - fail when attempting to update a legacy key. With this option, - the key will be recreated in the new format, but with the - original key data retained. The key's creation date will be - set to the present time. If no other values are specified, - then the key's publication and activation dates will also - be set to the present time. -

-
-K directory
-

- Sets the directory in which the key files are to reside. -

-
-L ttl
-

- Sets the default TTL to use for this key when it is converted - into a DNSKEY RR. If the key is imported into a zone, - this is the TTL that will be used for it, unless there was - already a DNSKEY RRset in place, in which case the existing TTL - would take precedence. If this value is not set and there - is no existing DNSKEY RRset, the TTL will default to the - SOA TTL. Setting the default TTL to 0 - or none removes it from the key. -

-
-h
-

- Emit usage message and exit. -

-
-V
-

- Prints version information. -

-
-v level
-

- Sets the debugging level. -

-
-E engine
-
-

- Specifies the cryptographic hardware to use, when applicable. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-
-
-

TIMING OPTIONS

-

- Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. - If the argument begins with a '+' or '-', it is interpreted as - an offset from the present time. For convenience, if such an offset - is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', - then the offset is computed in years (defined as 365 24-hour days, - ignoring leap years), months (defined as 30 24-hour days), weeks, - days, hours, or minutes, respectively. Without a suffix, the offset - is computed in seconds. To unset a date, use 'none' or 'never'. -

-
-
-P date/offset
-

- Sets the date on which a key is to be published to the zone. - After that date, the key will be included in the zone but will - not be used to sign it. -

-
-P sync date/offset
-

- Sets the date on which CDS and CDNSKEY records that match this - key are to be published to the zone. -

-
-A date/offset
-

- Sets the date on which the key is to be activated. After that - date, the key will be included in the zone and used to sign - it. -

-
-R date/offset
-

- Sets the date on which the key is to be revoked. After that - date, the key will be flagged as revoked. It will be included - in the zone and will be used to sign it. -

-
-I date/offset
-

- Sets the date on which the key is to be retired. After that - date, the key will still be included in the zone, but it - will not be used to sign it. -

-
-D date/offset
-

- Sets the date on which the key is to be deleted. After that - date, the key will no longer be included in the zone. (It - may remain in the key repository, however.) -

-
-D sync date/offset
-

- Sets the date on which the CDS and CDNSKEY records that match this - key are to be deleted. -

-
-S predecessor key
-

- Select a key for which the key being modified will be an - explicit successor. The name, algorithm, size, and type of the - predecessor key must exactly match those of the key being - modified. The activation date of the successor key will be set - to the inactivation date of the predecessor. The publication - date will be set to the activation date minus the prepublication - interval, which defaults to 30 days. -

-
-i interval
-
-

- Sets the prepublication interval for a key. If set, then - the publication and activation dates must be separated by at least - this much time. If the activation date is specified but the - publication date isn't, then the publication date will default - to this much time before the activation date; conversely, if - the publication date is specified but activation date isn't, - then activation will be set to this much time after publication. -

-

- If the key is being set to be an explicit successor to another - key, then the default prepublication interval is 30 days; - otherwise it is zero. -

-

- As with date offsets, if the argument is followed by one of - the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the - interval is measured in years, months, weeks, days, hours, - or minutes, respectively. Without a suffix, the interval is - measured in seconds. -

-
-
-
-
-

PRINTING OPTIONS

-

- dnssec-settime can also be used to print the - timing metadata associated with a key. -

-
-
-u
-

- Print times in UNIX epoch format. -

-
-p C/P/Psync/A/R/I/D/Dsync/all
-

- Print a specific metadata value or set of metadata values. - The -p option may be followed by one or more - of the following letters or strings to indicate which value - or values to print: - C for the creation date, - P for the publication date, - Psync for the CDS and CDNSKEY publication date, - A for the activation date, - R for the revocation date, - I for the inactivation date, - D for the deletion date, and - Dsync for the CDS and CDNSKEY deletion date - To print all of the metadata, use -p all. -

-
-
-
-

SEE ALSO

-

dnssec-keygen(8), - dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 5011. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-signzone.8 b/bin/dnssec-pkcs11/dnssec-signzone.8 deleted file mode 100644 index 53b0733..0000000 --- a/bin/dnssec-pkcs11/dnssec-signzone.8 +++ /dev/null @@ -1,480 +0,0 @@ -.\" Copyright (C) 2000-2009, 2011-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-signzone -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2014-02-18 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-SIGNZONE" "8" "2014\-02\-18" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-signzone \- DNSSEC zone signing tool -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-signzone\fR\ 'u -\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-M\ \fR\fB\fImaxttl\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-P\fR] [\fB\-p\fR] [\fB\-Q\fR] [\fB\-R\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-X\ \fR\fB\fIextended\ end\-time\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] -.SH "DESCRIPTION" -.PP -\fBdnssec\-signzone\fR -signs a zone\&. It generates NSEC and RRSIG records and produces a signed version of the zone\&. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a -keyset -file for each child zone\&. -.SH "OPTIONS" -.PP -\-a -.RS 4 -Verify all generated signatures\&. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Specifies the DNS class of the zone\&. -.RE -.PP -\-C -.RS 4 -Compatibility mode: Generate a -keyset\-\fIzonename\fR -file in addition to -dsset\-\fIzonename\fR -when signing a zone, for use by older versions of -\fBdnssec\-signzone\fR\&. -.RE -.PP -\-d \fIdirectory\fR -.RS 4 -Look for -dsset\- -or -keyset\- -files in -\fBdirectory\fR\&. -.RE -.PP -\-D -.RS 4 -Output only those record types automatically managed by -\fBdnssec\-signzone\fR, i\&.e\&. RRSIG, NSEC, NSEC3 and NSEC3PARAM records\&. If smart signing (\fB\-S\fR) is used, DNSKEY records are also included\&. The resulting file can be included in the original zone file with -\fB$INCLUDE\fR\&. This option cannot be combined with -\fB\-O raw\fR, -\fB\-O map\fR, or serial number updating\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-g -.RS 4 -Generate DS records for child zones from -dsset\- -or -keyset\- -file\&. Existing DS records will be removed\&. -.RE -.PP -\-K \fIdirectory\fR -.RS 4 -Key repository: Specify a directory to search for DNSSEC keys\&. If not specified, defaults to the current directory\&. -.RE -.PP -\-k \fIkey\fR -.RS 4 -Treat specified key as a key signing key ignoring any key flags\&. This option may be specified multiple times\&. -.RE -.PP -\-l \fIdomain\fR -.RS 4 -Generate a DLV set in addition to the key (DNSKEY) and DS sets\&. The domain is appended to the name of the records\&. -.RE -.PP -\-M \fImaxttl\fR -.RS 4 -Sets the maximum TTL for the signed zone\&. Any TTL higher than -\fImaxttl\fR -in the input zone will be reduced to -\fImaxttl\fR -in the output\&. This provides certainty as to the largest possible TTL in the signed zone, which is useful to know when rolling keys because it is the longest possible time before signatures that have been retrieved by resolvers will expire from resolver caches\&. Zones that are signed with this option should be configured to use a matching -\fBmax\-zone\-ttl\fR -in -named\&.conf\&. (Note: This option is incompatible with -\fB\-D\fR, because it modifies non\-DNSSEC data in the output zone\&.) -.RE -.PP -\-s \fIstart\-time\fR -.RS 4 -Specify the date and time when the generated RRSIG records become valid\&. This can be either an absolute or relative time\&. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000\&. A relative start time is indicated by +N, which is N seconds from the current time\&. If no -\fBstart\-time\fR -is specified, the current time minus 1 hour (to allow for clock skew) is used\&. -.RE -.PP -\-e \fIend\-time\fR -.RS 4 -Specify the date and time when the generated RRSIG records expire\&. As with -\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation\&. A time relative to the start time is indicated with +N, which is N seconds from the start time\&. A time relative to the current time is indicated with now+N\&. If no -\fBend\-time\fR -is specified, 30 days from the start time is used as a default\&. -\fBend\-time\fR -must be later than -\fBstart\-time\fR\&. -.RE -.PP -\-X \fIextended end\-time\fR -.RS 4 -Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire\&. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e\&.g\&., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually\&. -.sp -As with -\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation\&. A time relative to the start time is indicated with +N, which is N seconds from the start time\&. A time relative to the current time is indicated with now+N\&. If no -\fBextended end\-time\fR -is specified, the value of -\fBend\-time\fR -is used as the default\&. (\fBend\-time\fR, in turn, defaults to 30 days from the start time\&.) -\fBextended end\-time\fR -must be later than -\fBstart\-time\fR\&. -.RE -.PP -\-f \fIoutput\-file\fR -.RS 4 -The name of the output file containing the signed zone\&. The default is to append -\&.signed -to the input filename\&. If -\fBoutput\-file\fR -is set to -"\-", then the signed zone is written to the standard output, with a default output format of "full"\&. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBdnssec\-signzone\fR\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-i \fIinterval\fR -.RS 4 -When a previously\-signed zone is passed as input, records may be resigned\&. The -\fBinterval\fR -option specifies the cycle interval as an offset from the current time (in seconds)\&. If a RRSIG record expires after the cycle interval, it is retained\&. Otherwise, it is considered to be expiring soon, and it will be replaced\&. -.sp -The default cycle interval is one quarter of the difference between the signature end and start times\&. So if neither -\fBend\-time\fR -or -\fBstart\-time\fR -are specified, -\fBdnssec\-signzone\fR -generates signatures that are valid for 30 days, with a cycle interval of 7\&.5 days\&. Therefore, if any existing RRSIG records are due to expire in less than 7\&.5 days, they would be replaced\&. -.RE -.PP -\-I \fIinput\-format\fR -.RS 4 -The format of the input zone file\&. Possible formats are -\fB"text"\fR -(default), -\fB"raw"\fR, and -\fB"map"\fR\&. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly\&. The use of this option does not make much sense for non\-dynamic zones\&. -.RE -.PP -\-j \fIjitter\fR -.RS 4 -When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously\&. If the zone is incrementally signed, i\&.e\&. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time\&. The -\fBjitter\fR -option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time\&. -.sp -Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i\&.e\&. if large numbers of RRSIGs don\*(Aqt expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time\&. -.RE -.PP -\-L \fIserial\fR -.RS 4 -When writing a signed zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number\&. (This is expected to be used primarily for testing purposes\&.) -.RE -.PP -\-n \fIncpus\fR -.RS 4 -Specifies the number of threads to use\&. By default, one thread is started for each detected CPU\&. -.RE -.PP -\-N \fIsoa\-serial\-format\fR -.RS 4 -The SOA serial number format of the signed zone\&. Possible formats are -\fB"keep"\fR -(default), -\fB"increment"\fR, -\fB"unixtime"\fR, and -\fB"date"\fR\&. -.PP -\fB"keep"\fR -.RS 4 -Do not modify the SOA serial number\&. -.RE -.PP -\fB"increment"\fR -.RS 4 -Increment the SOA serial number using RFC 1982 arithmetics\&. -.RE -.PP -\fB"unixtime"\fR -.RS 4 -Set the SOA serial number to the number of seconds since epoch\&. -.RE -.PP -\fB"date"\fR -.RS 4 -Set the SOA serial number to today\*(Aqs date in YYYYMMDDNN format\&. -.RE -.RE -.PP -\-o \fIorigin\fR -.RS 4 -The zone origin\&. If not specified, the name of the zone file is assumed to be the origin\&. -.RE -.PP -\-O \fIoutput\-format\fR -.RS 4 -The format of the output file containing the signed zone\&. Possible formats are -\fB"text"\fR -(default), which is the standard textual representation of the zone; -\fB"full"\fR, which is text output in a format suitable for processing by external scripts; and -\fB"map"\fR, -\fB"raw"\fR, and -\fB"raw=N"\fR, which store the zone in binary formats for rapid loading by -\fBnamed\fR\&. -\fB"raw=N"\fR -specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of -\fBnamed\fR; if N is 1, the file can be read by release 9\&.9\&.0 or higher; the default is 1\&. -.RE -.PP -\-p -.RS 4 -Use pseudo\-random data when signing the zone\&. This is faster, but less secure, than using real random data\&. This option may be useful when signing large zones or when the entropy source is limited\&. -.RE -.PP -\-P -.RS 4 -Disable post sign verification tests\&. -.sp -The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm\&. This option skips these tests\&. -.RE -.PP -\-Q -.RS 4 -Remove signatures from keys that are no longer active\&. -.sp -Normally, when a previously\-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained\&. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset\&. The -\fB\-Q\fR -forces -\fBdnssec\-signzone\fR -to remove signatures from keys that are no longer active\&. This enables ZSK rollover using the procedure described in RFC 4641, section 4\&.2\&.1\&.1 ("Pre\-Publish Key Rollover")\&. -.RE -.PP -\-R -.RS 4 -Remove signatures from keys that are no longer published\&. -.sp -This option is similar to -\fB\-Q\fR, except it forces -\fBdnssec\-signzone\fR -to signatures from keys that are no longer published\&. This enables ZSK rollover using the procedure described in RFC 4641, section 4\&.2\&.1\&.2 ("Double Signature Zone Signing Key Rollover")\&. -.RE -.PP -\-r \fIrandomdev\fR -.RS 4 -Specifies the source of randomness\&. If the operating system does not provide a -/dev/random -or equivalent device, the default source of randomness is keyboard input\&. -randomdev -specifies the name of a character device or file containing random data to be used instead of the default\&. The special value -keyboard -indicates that keyboard input should be used\&. -.RE -.PP -\-S -.RS 4 -Smart signing: Instructs -\fBdnssec\-signzone\fR -to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate\&. -.sp -When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules\&. Each successive rule takes priority over the prior ones: -.PP -.RS 4 -If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone\&. -.RE -.PP -.RS 4 -If the key\*(Aqs publication date is set and is in the past, the key is published in the zone\&. -.RE -.PP -.RS 4 -If the key\*(Aqs activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone\&. -.RE -.PP -.RS 4 -If the key\*(Aqs revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone\&. -.RE -.PP -.RS 4 -If either of the key\*(Aqs unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata\&. -.RE -.RE -.PP -\-T \fIttl\fR -.RS 4 -Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository\&. If not specified, the default is the TTL value from the zone\*(Aqs SOA record\&. This option is ignored when signing without -\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case\&. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records\*(Aq TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value\&. In the event of a a conflict between TTL values in imported keys, the shortest one is used\&. -.RE -.PP -\-t -.RS 4 -Print statistics at completion\&. -.RE -.PP -\-u -.RS 4 -Update NSEC/NSEC3 chain when re\-signing a previously signed zone\&. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters\&. Without this option, -\fBdnssec\-signzone\fR -will retain the existing chain when re\-signing\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-x -.RS 4 -Only sign the DNSKEY RRset with key\-signing keys, and omit signatures from zone\-signing keys\&. (This is similar to the -\fBdnssec\-dnskey\-kskonly yes;\fR -zone option in -\fBnamed\fR\&.) -.RE -.PP -\-z -.RS 4 -Ignore KSK flag on key when determining what to sign\&. This causes KSK\-flagged keys to sign all records, not just the DNSKEY RRset\&. (This is similar to the -\fBupdate\-check\-ksk no;\fR -zone option in -\fBnamed\fR\&.) -.RE -.PP -\-3 \fIsalt\fR -.RS 4 -Generate an NSEC3 chain with the given hex encoded salt\&. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain\&. -.RE -.PP -\-H \fIiterations\fR -.RS 4 -When generating an NSEC3 chain, use this many iterations\&. The default is 10\&. -.RE -.PP -\-A -.RS 4 -When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations\&. -.sp -Using this option twice (i\&.e\&., -\fB\-AA\fR) turns the OPTOUT flag off for all records\&. This is useful when using the -\fB\-u\fR -option to modify an NSEC3 chain which previously had OPTOUT set\&. -.RE -.PP -zonefile -.RS 4 -The file containing the zone to be signed\&. -.RE -.PP -key -.RS 4 -Specify which keys should be used to sign the zone\&. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex\&. If these are found and there are matching private keys, in the current directory, then these will be used for signing\&. -.RE -.SH "EXAMPLE" -.PP -The following command signs the -\fBexample\&.com\fR -zone with the DSA key generated by -\fBdnssec\-keygen\fR -(Kexample\&.com\&.+003+17247)\&. Because the -\fB\-S\fR -option is not being used, the zone\*(Aqs keys must be in the master file (db\&.example\&.com)\&. This invocation looks for -dsset -files, in the current directory, so that DS records can be imported from them (\fB\-g\fR)\&. -.sp -.if n \{\ -.RS 4 -.\} -.nf -% dnssec\-signzone \-g \-o example\&.com db\&.example\&.com \e -Kexample\&.com\&.+003+17247 -db\&.example\&.com\&.signed -% -.fi -.if n \{\ -.RE -.\} -.PP -In the above example, -\fBdnssec\-signzone\fR -creates the file -db\&.example\&.com\&.signed\&. This file should be referenced in a zone statement in a -named\&.conf -file\&. -.PP -This example re\-signs a previously signed zone with default parameters\&. The private keys are assumed to be in the current directory\&. -.sp -.if n \{\ -.RS 4 -.\} -.nf -% cp db\&.example\&.com\&.signed db\&.example\&.com -% dnssec\-signzone \-o example\&.com db\&.example\&.com -db\&.example\&.com\&.signed -% -.fi -.if n \{\ -.RE -.\} -.SH "SEE ALSO" -.PP -\fBdnssec-keygen\fR(8), -BIND 9 Administrator Reference Manual, -RFC 4033, -RFC 4641\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000-2009, 2011-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-signzone.c b/bin/dnssec-pkcs11/dnssec-signzone.c deleted file mode 100644 index 7308fc6..0000000 --- a/bin/dnssec-pkcs11/dnssec-signzone.c +++ /dev/null @@ -1,3908 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-signzone"; -int verbose; - -typedef struct hashlist hashlist_t; - -static int nsec_datatype = dns_rdatatype_nsec; - -#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3) -#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) - -#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) - -#define BUFSIZE 2048 -#define MAXDSKEYS 8 - -#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453) -#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0) -#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1) - -#define SOA_SERIAL_KEEP 0 -#define SOA_SERIAL_INCREMENT 1 -#define SOA_SERIAL_UNIXTIME 2 -#define SOA_SERIAL_DATE 3 - -typedef struct signer_event sevent_t; -struct signer_event { - ISC_EVENT_COMMON(sevent_t); - dns_fixedname_t *fname; - dns_dbnode_t *node; -}; - -static dns_dnsseckeylist_t keylist; -static unsigned int keycount = 0; -isc_rwlock_t keylist_lock; -static isc_stdtime_t starttime = 0, endtime = 0, dnskey_endtime = 0, now; -static int cycle = -1; -static int jitter = 0; -static bool tryverify = false; -static bool printstats = false; -static isc_mem_t *mctx = NULL; -static isc_entropy_t *ectx = NULL; -static dns_ttl_t zone_soa_min_ttl; -static dns_ttl_t soa_ttl; -static FILE *outfp = NULL; -static char *tempfile = NULL; -static const dns_master_style_t *masterstyle; -static dns_masterformat_t inputformat = dns_masterformat_text; -static dns_masterformat_t outputformat = dns_masterformat_text; -static uint32_t rawversion = 1, serialnum = 0; -static bool snset = false; -static unsigned int nsigned = 0, nretained = 0, ndropped = 0; -static unsigned int nverified = 0, nverifyfailed = 0; -static const char *directory = NULL, *dsdir = NULL; -static isc_mutex_t namelock, statslock; -static isc_taskmgr_t *taskmgr = NULL; -static dns_db_t *gdb; /* The database */ -static dns_dbversion_t *gversion; /* The database version */ -static dns_dbiterator_t *gdbiter; /* The database iterator */ -static dns_rdataclass_t gclass; /* The class */ -static dns_name_t *gorigin; /* The database origin */ -static int nsec3flags = 0; -static dns_iterations_t nsec3iter = 10U; -static unsigned char saltbuf[255]; -static unsigned char *gsalt = saltbuf; -static size_t salt_length = 0; -static isc_task_t *master = NULL; -static unsigned int ntasks = 0; -static bool shuttingdown = false, finished = false; -static bool nokeys = false; -static bool removefile = false; -static bool generateds = false; -static bool ignore_kskflag = false; -static bool keyset_kskonly = false; -static dns_name_t *dlv = NULL; -static dns_fixedname_t dlv_fixed; -static dns_master_style_t *dsstyle = NULL; -static unsigned int serialformat = SOA_SERIAL_KEEP; -static unsigned int hash_length = 0; -static bool unknownalg = false; -static bool disable_zone_check = false; -static bool update_chain = false; -static bool set_keyttl = false; -static dns_ttl_t keyttl; -static bool smartsign = false; -static bool remove_orphansigs = false; -static bool remove_inactkeysigs = false; -static bool output_dnssec_only = false; -static bool output_stdout = false; -bool set_maxttl = false; -static dns_ttl_t maxttl = 0; - -#define INCSTAT(counter) \ - if (printstats) { \ - LOCK(&statslock); \ - counter++; \ - UNLOCK(&statslock); \ - } - -static void -sign(isc_task_t *task, isc_event_t *event); - -/*% - * Store a copy of 'name' in 'fzonecut' and return a pointer to that copy. - */ -static dns_name_t * -savezonecut(dns_fixedname_t *fzonecut, dns_name_t *name) { - dns_name_t *result; - - result = dns_fixedname_initname(fzonecut); - dns_name_copy(name, result, NULL); - - return (result); -} - -static void -dumpnode(dns_name_t *name, dns_dbnode_t *node) { - dns_rdataset_t rds; - dns_rdatasetiter_t *iter = NULL; - isc_buffer_t *buffer = NULL; - isc_region_t r; - isc_result_t result; - unsigned bufsize = 4096; - - if (outputformat != dns_masterformat_text) - return; - - if (!output_dnssec_only) { - result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, - name, masterstyle, outfp); - check_result(result, "dns_master_dumpnodetostream"); - return; - } - - result = dns_db_allrdatasets(gdb, node, gversion, 0, &iter); - check_result(result, "dns_db_allrdatasets"); - - dns_rdataset_init(&rds); - - result = isc_buffer_allocate(mctx, &buffer, bufsize); - check_result(result, "isc_buffer_allocate"); - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) { - - dns_rdatasetiter_current(iter, &rds); - - if (rds.type != dns_rdatatype_rrsig && - rds.type != dns_rdatatype_nsec && - rds.type != dns_rdatatype_nsec3 && - rds.type != dns_rdatatype_nsec3param && - (!smartsign || rds.type != dns_rdatatype_dnskey)) { - dns_rdataset_disassociate(&rds); - continue; - } - - for (;;) { - result = dns_master_rdatasettotext(name, &rds, - masterstyle, buffer); - if (result != ISC_R_NOSPACE) - break; - - bufsize <<= 1; - isc_buffer_free(&buffer); - result = isc_buffer_allocate(mctx, &buffer, bufsize); - check_result(result, "isc_buffer_allocate"); - } - check_result(result, "dns_master_rdatasettotext"); - - isc_buffer_usedregion(buffer, &r); - result = isc_stdio_write(r.base, 1, r.length, outfp, NULL); - check_result(result, "isc_stdio_write"); - isc_buffer_clear(buffer); - - dns_rdataset_disassociate(&rds); - } - - isc_buffer_free(&buffer); - dns_rdatasetiter_destroy(&iter); -} - -/*% - * Sign the given RRset with given key, and add the signature record to the - * given tuple. - */ -static void -signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key, - dns_ttl_t ttl, dns_diff_t *add, const char *logmsg) -{ - isc_result_t result; - isc_stdtime_t jendtime, expiry; - char keystr[DST_KEY_FORMATSIZE]; - dns_rdata_t trdata = DNS_RDATA_INIT; - unsigned char array[BUFSIZE]; - isc_buffer_t b; - dns_difftuple_t *tuple; - - dst_key_format(key, keystr, sizeof(keystr)); - vbprintf(1, "\t%s %s\n", logmsg, keystr); - - if (rdataset->type == dns_rdatatype_dnskey) - expiry = dnskey_endtime; - else - expiry = endtime; - - jendtime = (jitter != 0) ? isc_random_jitter(expiry, jitter) : expiry; - isc_buffer_init(&b, array, sizeof(array)); - result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, - mctx, &b, &trdata); - isc_entropy_stopcallbacksources(ectx); - if (result != ISC_R_SUCCESS) { - fatal("dnskey '%s' failed to sign data: %s", - keystr, isc_result_totext(result)); - } - INCSTAT(nsigned); - - if (tryverify) { - result = dns_dnssec_verify(name, rdataset, key, - true, mctx, &trdata); - if (result == ISC_R_SUCCESS) { - vbprintf(3, "\tsignature verified\n"); - INCSTAT(nverified); - } else { - vbprintf(3, "\tsignature failed to verify\n"); - INCSTAT(nverifyfailed); - } - } - - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, - name, ttl, &trdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); -} - -static inline bool -issigningkey(dns_dnsseckey_t *key) { - return (key->force_sign || key->hint_sign); -} - -static inline bool -ispublishedkey(dns_dnsseckey_t *key) { - return ((key->force_publish || key->hint_publish) && - !key->hint_remove); -} - -static inline bool -iszonekey(dns_dnsseckey_t *key) { - return (dns_name_equal(dst_key_name(key->key), gorigin) && - dst_key_iszonekey(key->key)); -} - -static inline bool -isksk(dns_dnsseckey_t *key) { - return (key->ksk); -} - -static inline bool -iszsk(dns_dnsseckey_t *key) { - return (ignore_kskflag || !key->ksk); -} - -/*% - * Find the key that generated an RRSIG, if it is in the key list. If - * so, return a pointer to it, otherwise return NULL. - * - * No locking is performed here, this must be done by the caller. - */ -static dns_dnsseckey_t * -keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) { - dns_dnsseckey_t *key; - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - if (rrsig->keyid == dst_key_id(key->key) && - rrsig->algorithm == dst_key_alg(key->key) && - dns_name_equal(&rrsig->signer, dst_key_name(key->key))) - return (key); - } - return (NULL); -} - -/*% - * Finds the key that generated a RRSIG, if possible. First look at the keys - * that we've loaded already, and then see if there's a key on disk. - */ -static dns_dnsseckey_t * -keythatsigned(dns_rdata_rrsig_t *rrsig) { - isc_result_t result; - dst_key_t *pubkey = NULL, *privkey = NULL; - dns_dnsseckey_t *key = NULL; - - isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read); - key = keythatsigned_unlocked(rrsig); - isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read); - if (key != NULL) - return (key); - - /* - * We did not find the key in our list. Get a write lock now, since - * we may be modifying the bits. We could do the tryupgrade() dance, - * but instead just get a write lock and check once again to see if - * it is on our list. It's possible someone else may have added it - * after all. - */ - isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write); - key = keythatsigned_unlocked(rrsig); - if (key != NULL) { - isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); - return (key); - } - - result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, - rrsig->algorithm, DST_TYPE_PUBLIC, - directory, mctx, &pubkey); - if (result != ISC_R_SUCCESS) { - isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); - return (NULL); - } - - result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, - rrsig->algorithm, - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - directory, mctx, &privkey); - if (result == ISC_R_SUCCESS) { - dst_key_free(&pubkey); - result = dns_dnsseckey_create(mctx, &privkey, &key); - } else - result = dns_dnsseckey_create(mctx, &pubkey, &key); - - if (result == ISC_R_SUCCESS) { - key->force_publish = false; - key->force_sign = false; - key->index = keycount++; - ISC_LIST_APPEND(keylist, key, link); - } - - isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); - return (key); -} - -/*% - * Check to see if we expect to find a key at this name. If we see a RRSIG - * and can't find the signing key that we expect to find, we drop the rrsig. - * I'm not sure if this is completely correct, but it seems to work. - */ -static bool -expecttofindkey(dns_name_t *name) { - unsigned int options = DNS_DBFIND_NOWILD; - dns_fixedname_t fname; - isc_result_t result; - char namestr[DNS_NAME_FORMATSIZE]; - - dns_fixedname_init(&fname); - result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options, - 0, NULL, dns_fixedname_name(&fname), NULL, NULL); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_NXDOMAIN: - case DNS_R_NXRRSET: - return (true); - case DNS_R_DELEGATION: - case DNS_R_CNAME: - case DNS_R_DNAME: - return (false); - } - dns_name_format(name, namestr, sizeof(namestr)); - fatal("failure looking for '%s DNSKEY' in database: %s", - namestr, isc_result_totext(result)); - /* NOTREACHED */ - return (false); /* removes a warning */ -} - -static inline bool -setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - dns_rdata_t *rrsig) -{ - isc_result_t result; - result = dns_dnssec_verify(name, set, key, false, mctx, rrsig); - if (result == ISC_R_SUCCESS) { - INCSTAT(nverified); - return (true); - } else { - INCSTAT(nverifyfailed); - return (false); - } -} - -/*% - * Signs a set. Goes through contortions to decide if each RRSIG should - * be dropped or retained, and then determines if any new SIGs need to - * be generated. - */ -static void -signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, - dns_rdataset_t *set) -{ - dns_rdataset_t sigset; - dns_rdata_t sigrdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t rrsig; - dns_dnsseckey_t *key; - isc_result_t result; - bool nosigs = false; - bool *wassignedby, *nowsignedby; - int arraysize; - dns_difftuple_t *tuple; - dns_ttl_t ttl; - int i; - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[TYPE_FORMATSIZE]; - char sigstr[SIG_FORMATSIZE]; - - dns_name_format(name, namestr, sizeof(namestr)); - type_format(set->type, typestr, sizeof(typestr)); - - ttl = ISC_MIN(set->ttl, endtime - starttime); - - dns_rdataset_init(&sigset); - result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig, - set->type, 0, &sigset, NULL); - if (result == ISC_R_NOTFOUND) { - vbprintf(2, "no existing signatures for %s/%s\n", - namestr, typestr); - result = ISC_R_SUCCESS; - nosigs = true; - } - if (result != ISC_R_SUCCESS) - fatal("failed while looking for '%s RRSIG %s': %s", - namestr, typestr, isc_result_totext(result)); - - vbprintf(1, "%s/%s:\n", namestr, typestr); - - arraysize = keycount; - if (!nosigs) - arraysize += dns_rdataset_count(&sigset); - wassignedby = isc_mem_get(mctx, arraysize * sizeof(bool)); - nowsignedby = isc_mem_get(mctx, arraysize * sizeof(bool)); - if (wassignedby == NULL || nowsignedby == NULL) - fatal("out of memory"); - - for (i = 0; i < arraysize; i++) - wassignedby[i] = nowsignedby[i] = false; - - if (nosigs) - result = ISC_R_NOMORE; - else - result = dns_rdataset_first(&sigset); - - while (result == ISC_R_SUCCESS) { - bool expired, future; - bool keep = false, resign = false; - - dns_rdataset_current(&sigset, &sigrdata); - - result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL); - check_result(result, "dns_rdata_tostruct"); - - future = isc_serial_lt(now, rrsig.timesigned); - - key = keythatsigned(&rrsig); - sig_format(&rrsig, sigstr, sizeof(sigstr)); - if (key != NULL && issigningkey(key)) - expired = isc_serial_gt(now + cycle, rrsig.timeexpire); - else - expired = isc_serial_gt(now, rrsig.timeexpire); - - if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) { - /* rrsig is dropped and not replaced */ - vbprintf(2, "\trrsig by %s dropped - " - "invalid validity period\n", - sigstr); - } else if (key == NULL && !future && - expecttofindkey(&rrsig.signer)) { - /* rrsig is dropped and not replaced */ - vbprintf(2, "\trrsig by %s dropped - " - "private dnskey not found\n", - sigstr); - } else if (key == NULL || future) { - keep = (!expired && !remove_orphansigs); - vbprintf(2, "\trrsig by %s %s - dnskey not found\n", - keep ? "retained" : "dropped", sigstr); - } else if (!dns_dnssec_keyactive(key->key, now) && - remove_inactkeysigs) { - keep = false; - vbprintf(2, "\trrsig by %s dropped - key inactive\n", - sigstr); - } else if (issigningkey(key)) { - wassignedby[key->index] = true; - - if (!expired && rrsig.originalttl == set->ttl && - setverifies(name, set, key->key, &sigrdata)) { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = true; - } else { - vbprintf(2, "\trrsig by %s dropped - %s\n", - sigstr, expired ? "expired" : - rrsig.originalttl != set->ttl ? - "ttl change" : "failed to verify"); - resign = true; - } - } else if (!ispublishedkey(key) && remove_orphansigs) { - vbprintf(2, "\trrsig by %s dropped - dnskey removed\n", - sigstr); - } else if (iszonekey(key)) { - wassignedby[key->index] = true; - - if (!expired && rrsig.originalttl == set->ttl && - setverifies(name, set, key->key, &sigrdata)) { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = true; - } else { - vbprintf(2, "\trrsig by %s dropped - %s\n", - sigstr, expired ? "expired" : - rrsig.originalttl != set->ttl ? - "ttl change" : "failed to verify"); - } - } else if (!expired) { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = true; - } else { - vbprintf(2, "\trrsig by %s expired\n", sigstr); - } - - if (keep) { - if (key != NULL) - nowsignedby[key->index] = true; - INCSTAT(nretained); - if (sigset.ttl != ttl) { - vbprintf(2, "\tfixing ttl %s\n", sigstr); - tuple = NULL; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_DELRESIGN, - name, sigset.ttl, - &sigrdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - name, ttl, - &sigrdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); - } - } else { - tuple = NULL; - vbprintf(2, "removing signature by %s\n", sigstr); - result = dns_difftuple_create(mctx, - DNS_DIFFOP_DELRESIGN, - name, sigset.ttl, - &sigrdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - INCSTAT(ndropped); - } - - if (resign) { - INSIST(!keep); - - signwithkey(name, set, key->key, ttl, add, - "resigning with dnskey"); - nowsignedby[key->index] = true; - } - - dns_rdata_reset(&sigrdata); - dns_rdata_freestruct(&rrsig); - result = dns_rdataset_next(&sigset); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - check_result(result, "dns_rdataset_first/next"); - if (dns_rdataset_isassociated(&sigset)) - dns_rdataset_disassociate(&sigset); - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - if (nowsignedby[key->index]) - continue; - - if (!issigningkey(key)) - continue; - - if (set->type == dns_rdatatype_dnskey && - dns_name_equal(name, gorigin)) { - bool have_ksk; - dns_dnsseckey_t *tmpkey; - - have_ksk = isksk(key); - for (tmpkey = ISC_LIST_HEAD(keylist); - tmpkey != NULL; - tmpkey = ISC_LIST_NEXT(tmpkey, link)) { - if (dst_key_alg(key->key) != - dst_key_alg(tmpkey->key)) - continue; - if (REVOKE(tmpkey->key)) - continue; - if (isksk(tmpkey)) - have_ksk = true; - } - if (isksk(key) || !have_ksk || - (iszsk(key) && !keyset_kskonly)) - signwithkey(name, set, key->key, ttl, add, - "signing with dnskey"); - } else if (set->type == dns_rdatatype_cds || - set->type == dns_rdatatype_cdnskey || - iszsk(key)) { - signwithkey(name, set, key->key, ttl, add, - "signing with dnskey"); - } - } - - isc_mem_put(mctx, wassignedby, arraysize * sizeof(bool)); - isc_mem_put(mctx, nowsignedby, arraysize * sizeof(bool)); -} - -struct hashlist { - unsigned char *hashbuf; - size_t entries; - size_t size; - size_t length; -}; - -static void -hashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) { - - l->entries = 0; - l->length = length + 1; - - if (nodes != 0) { - l->size = nodes; - l->hashbuf = malloc(l->size * l->length); - if (l->hashbuf == NULL) - l->size = 0; - } else { - l->size = 0; - l->hashbuf = NULL; - } -} - -static void -hashlist_free(hashlist_t *l) { - if (l->hashbuf) { - free(l->hashbuf); - l->hashbuf = NULL; - l->entries = 0; - l->length = 0; - l->size = 0; - } -} - -static void -hashlist_add(hashlist_t *l, const unsigned char *hash, size_t len) -{ - - REQUIRE(len <= l->length); - - if (l->entries == l->size) { - l->size = l->size * 2 + 100; - l->hashbuf = realloc(l->hashbuf, l->size * l->length); - if (l->hashbuf == NULL) - fatal("unable to grow hashlist: out of memory"); - } - memset(l->hashbuf + l->entries * l->length, 0, l->length); - memmove(l->hashbuf + l->entries * l->length, hash, len); - l->entries++; -} - -static void -hashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name, - unsigned int hashalg, unsigned int iterations, - const unsigned char *salt, size_t salt_len, - bool speculative) -{ - char nametext[DNS_NAME_FORMATSIZE]; - unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1]; - unsigned int len; - size_t i; - - len = isc_iterated_hash(hash, hashalg, iterations, - salt, (int)salt_len, - name->ndata, name->length); - if (verbose) { - dns_name_format(name, nametext, sizeof nametext); - for (i = 0 ; i < len; i++) - fprintf(stderr, "%02x", hash[i]); - fprintf(stderr, " %s\n", nametext); - } - hash[len++] = speculative ? 1 : 0; - hashlist_add(l, hash, len); -} - -static int -hashlist_comp(const void *a, const void *b) { - return (isc_safe_memcompare(a, b, hash_length + 1)); -} - -static void -hashlist_sort(hashlist_t *l) { - INSIST(l->hashbuf != NULL || l->length == 0); - if (l->length > 0) { - qsort(l->hashbuf, l->entries, l->length, hashlist_comp); - } -} - -static bool -hashlist_hasdup(hashlist_t *l) { - unsigned char *current; - unsigned char *next = l->hashbuf; - size_t entries = l->entries; - - /* - * Skip initial speculative wild card hashes. - */ - while (entries > 0U && next[l->length-1] != 0U) { - next += l->length; - entries--; - } - - current = next; - while (entries-- > 1U) { - next += l->length; - if (next[l->length-1] != 0) - continue; - if (isc_safe_memequal(current, next, l->length - 1)) - return (true); - current = next; - } - return (false); -} - -static const unsigned char * -hashlist_findnext(const hashlist_t *l, - const unsigned char hash[NSEC3_MAX_HASH_LENGTH]) -{ - size_t entries = l->entries; - const unsigned char *next = bsearch(hash, l->hashbuf, l->entries, - l->length, hashlist_comp); - INSIST(next != NULL); - - do { - if (next < l->hashbuf + (l->entries - 1) * l->length) - next += l->length; - else - next = l->hashbuf; - if (next[l->length - 1] == 0) - break; - } while (entries-- > 1U); - INSIST(entries != 0U); - return (next); -} - -static bool -hashlist_exists(const hashlist_t *l, - const unsigned char hash[NSEC3_MAX_HASH_LENGTH]) -{ - if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp)) - return (true); - else - return (false); -} - -static void -addnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name, - unsigned int hashalg, unsigned int iterations, - const unsigned char *salt, size_t salt_len) -{ - dns_fixedname_t fixed; - dns_name_t *wild; - dns_dbnode_t *node = NULL; - isc_result_t result; - char namestr[DNS_NAME_FORMATSIZE]; - - wild = dns_fixedname_initname(&fixed); - - result = dns_name_concatenate(dns_wildcardname, name, wild, NULL); - if (result == ISC_R_NOSPACE) - return; - check_result(result,"addnowildcardhash: dns_name_concatenate()"); - - result = dns_db_findnode(gdb, wild, false, &node); - if (result == ISC_R_SUCCESS) { - dns_db_detachnode(gdb, &node); - return; - } - - if (verbose) { - dns_name_format(wild, namestr, sizeof(namestr)); - fprintf(stderr, "adding no-wildcardhash for %s\n", namestr); - } - - hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_len, - true); -} - -static void -opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass, - dns_db_t **dbp) -{ - char filename[PATH_MAX]; - isc_buffer_t b; - isc_result_t result; - - isc_buffer_init(&b, filename, sizeof(filename)); - if (dsdir != NULL) { - /* allow room for a trailing slash */ - if (strlen(dsdir) >= isc_buffer_availablelength(&b)) - fatal("path '%s' is too long", dsdir); - isc_buffer_putstr(&b, dsdir); - if (dsdir[strlen(dsdir) - 1] != '/') - isc_buffer_putstr(&b, "/"); - } - if (strlen(prefix) > isc_buffer_availablelength(&b)) - fatal("path '%s' is too long", dsdir); - isc_buffer_putstr(&b, prefix); - result = dns_name_tofilenametext(name, false, &b); - check_result(result, "dns_name_tofilenametext()"); - if (isc_buffer_availablelength(&b) == 0) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - fatal("name '%s' is too long", namestr); - } - isc_buffer_putuint8(&b, 0); - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - rdclass, 0, NULL, dbp); - check_result(result, "dns_db_create()"); - - result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - dns_db_detach(dbp); -} - -/*% - * Load the DS set for a child zone, if a dsset-* file can be found. - * If not, try to find a keyset-* file from an earlier version of - * dnssec-signzone, and build DS records from that. - */ -static isc_result_t -loadds(dns_name_t *name, uint32_t ttl, dns_rdataset_t *dsset) { - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_dbnode_t *node = NULL; - isc_result_t result; - dns_rdataset_t keyset; - dns_rdata_t key, ds; - unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - dns_diff_t diff; - dns_difftuple_t *tuple = NULL; - - opendb("dsset-", name, gclass, &db); - if (db != NULL) { - result = dns_db_findnode(db, name, false, &node); - if (result == ISC_R_SUCCESS) { - dns_rdataset_init(dsset); - result = dns_db_findrdataset(db, node, NULL, - dns_rdatatype_ds, 0, 0, - dsset, NULL); - dns_db_detachnode(db, &node); - if (result == ISC_R_SUCCESS) { - vbprintf(2, "found DS records\n"); - dsset->ttl = ttl; - dns_db_detach(&db); - return (result); - } - } - dns_db_detach(&db); - } - - /* No DS records found; try again, looking for DNSKEY records */ - opendb("keyset-", name, gclass, &db); - if (db == NULL) { - return (ISC_R_NOTFOUND); - } - - result = dns_db_findnode(db, name, false, &node); - if (result != ISC_R_SUCCESS) { - dns_db_detach(&db); - return (result); - } - - dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, - &keyset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (result); - } - vbprintf(2, "found DNSKEY records\n"); - - result = dns_db_newversion(db, &ver); - check_result(result, "dns_db_newversion"); - dns_diff_init(mctx, &diff); - - for (result = dns_rdataset_first(&keyset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keyset)) - { - dns_rdata_init(&key); - dns_rdata_init(&ds); - dns_rdataset_current(&keyset, &key); - result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, - ttl, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); - result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, - ttl, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - } - - result = dns_diff_apply(&diff, db, ver); - check_result(result, "dns_diff_apply"); - dns_diff_clear(&diff); - - dns_db_closeversion(db, &ver, true); - - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0, - dsset, NULL); - check_result(result, "dns_db_findrdataset"); - - dns_rdataset_disassociate(&keyset); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (result); -} - -static bool -secure(dns_name_t *name, dns_dbnode_t *node) { - dns_rdataset_t dsset; - isc_result_t result; - - if (dns_name_equal(name, gorigin)) - return (false); - - dns_rdataset_init(&dsset); - result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds, - 0, 0, &dsset, NULL); - if (dns_rdataset_isassociated(&dsset)) - dns_rdataset_disassociate(&dsset); - - return (result == ISC_R_SUCCESS); -} - -/*% - * Signs all records at a name. - */ -static void -signname(dns_dbnode_t *node, dns_name_t *name) { - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatasetiter_t *rdsiter; - bool isdelegation = false; - dns_diff_t del, add; - char namestr[DNS_NAME_FORMATSIZE]; - - dns_rdataset_init(&rdataset); - dns_name_format(name, namestr, sizeof(namestr)); - - /* - * Determine if this is a delegation point. - */ - if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) - isdelegation = true; - - /* - * Now iterate through the rdatasets. - */ - dns_diff_init(mctx, &del); - dns_diff_init(mctx, &add); - rdsiter = NULL; - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - - /* If this is a RRSIG set, skip it. */ - if (rdataset.type == dns_rdatatype_rrsig) - goto skip; - - /* - * If this name is a delegation point, skip all records - * except NSEC and DS sets. Otherwise check that there - * isn't a DS record. - */ - if (isdelegation) { - if (rdataset.type != nsec_datatype && - rdataset.type != dns_rdatatype_ds) - goto skip; - } else if (rdataset.type == dns_rdatatype_ds) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namebuf, sizeof(namebuf)); - fatal("'%s': found DS RRset without NS RRset\n", - namebuf); - } - - signset(&del, &add, node, name, &rdataset); - - skip: - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration for name '%s' failed: %s", - namestr, isc_result_totext(result)); - - dns_rdatasetiter_destroy(&rdsiter); - - result = dns_diff_applysilently(&del, gdb, gversion); - if (result != ISC_R_SUCCESS) - fatal("failed to delete SIGs at node '%s': %s", - namestr, isc_result_totext(result)); - - result = dns_diff_applysilently(&add, gdb, gversion); - if (result != ISC_R_SUCCESS) - fatal("failed to add SIGs at node '%s': %s", - namestr, isc_result_totext(result)); - - dns_diff_clear(&del); - dns_diff_clear(&add); -} - -/* - * See if the node contains any non RRSIG/NSEC records and report to - * caller. Clean out extraneous RRSIG records for node. - */ -static inline bool -active_node(dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdatasetiter_t *rdsiter2 = NULL; - bool active = false; - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatatype_t type; - dns_rdatatype_t covers; - bool found; - - dns_rdataset_init(&rdataset); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_nsec && - rdataset.type != dns_rdatatype_nsec3 && - rdataset.type != dns_rdatatype_rrsig) - active = true; - dns_rdataset_disassociate(&rdataset); - if (!active) - result = dns_rdatasetiter_next(rdsiter); - else - result = ISC_R_NOMORE; - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - - if (!active && nsec_datatype == dns_rdatatype_nsec) { - /*% - * The node is empty of everything but NSEC / RRSIG records. - */ - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - result = dns_db_deleterdataset(gdb, node, gversion, - rdataset.type, - rdataset.covers); - check_result(result, "dns_db_deleterdataset()"); - dns_rdataset_disassociate(&rdataset); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - } else { - /* - * Delete RRSIGs for types that no longer exist. - */ - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - /* - * Delete the NSEC chain if we are signing with - * NSEC3. - */ - if (nsec_datatype == dns_rdatatype_nsec3 && - (type == dns_rdatatype_nsec || - covers == dns_rdatatype_nsec)) { - result = dns_db_deleterdataset(gdb, node, - gversion, type, - covers); - check_result(result, - "dns_db_deleterdataset(nsec/rrsig)"); - continue; - } - if (type != dns_rdatatype_rrsig) - continue; - found = false; - for (result = dns_rdatasetiter_first(rdsiter2); - !found && result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter2)) { - dns_rdatasetiter_current(rdsiter2, &rdataset); - if (rdataset.type == covers) - found = true; - dns_rdataset_disassociate(&rdataset); - } - if (!found) { - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - result = dns_db_deleterdataset(gdb, node, - gversion, type, - covers); - check_result(result, - "dns_db_deleterdataset(rrsig)"); - } else if (result != ISC_R_NOMORE && - result != ISC_R_SUCCESS) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter2); - } - dns_rdatasetiter_destroy(&rdsiter); - - return (active); -} - -/*% - * Extracts the minimum TTL from the SOA record, and the SOA record's TTL. - */ -static void -get_soa_ttls(void) { - dns_rdataset_t soaset; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - - name = dns_fixedname_initname(&fname); - dns_rdataset_init(&soaset); - result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa, - 0, 0, NULL, name, &soaset, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed to find an SOA at the zone apex: %s", - isc_result_totext(result)); - - result = dns_rdataset_first(&soaset); - check_result(result, "dns_rdataset_first"); - dns_rdataset_current(&soaset, &rdata); - zone_soa_min_ttl = dns_soa_getminimum(&rdata); - soa_ttl = soaset.ttl; - if (set_maxttl) { - zone_soa_min_ttl = ISC_MIN(zone_soa_min_ttl, maxttl); - soa_ttl = ISC_MIN(soa_ttl, maxttl); - } - dns_rdataset_disassociate(&soaset); -} - -/*% - * Increment (or set if nonzero) the SOA serial - */ -static isc_result_t -setsoaserial(uint32_t serial, dns_updatemethod_t method) { - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - uint32_t old_serial, new_serial; - - result = dns_db_getoriginnode(gdb, &node); - if (result != ISC_R_SUCCESS) - return result; - - dns_rdataset_init(&rdataset); - - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_soa, 0, - 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rdataset_first(&rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_rdataset_current(&rdataset, &rdata); - - old_serial = dns_soa_getserial(&rdata); - - if (method == dns_updatemethod_date || - method == dns_updatemethod_unixtime) { - new_serial = dns_update_soaserial(old_serial, method); - } else if (serial != 0 || method == dns_updatemethod_none) { - /* Set SOA serial to the value provided. */ - new_serial = serial; - } else { - /* Increment SOA serial using RFC 1982 arithmetics */ - new_serial = (old_serial + 1) & 0xFFFFFFFF; - if (new_serial == 0) - new_serial = 1; - } - - /* If the new serial is not likely to cause a zone transfer - * (a/ixfr) from servers having the old serial, warn the user. - * - * RFC1982 section 7 defines the maximum increment to be - * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single - * comparison. (5 - 6 == (2^32)-1, not negative-one) - */ - if (new_serial == old_serial || - (new_serial - old_serial) > 0x7fffffffU) - fprintf(stderr, "%s: warning: Serial number not advanced, " - "zone may not transfer\n", program); - - dns_soa_setserial(new_serial, &rdata); - - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_soa, 0); - check_result(result, "dns_db_deleterdataset"); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_db_addrdataset(gdb, node, gversion, - 0, &rdataset, 0, NULL); - check_result(result, "dns_db_addrdataset"); - if (result != ISC_R_SUCCESS) - goto cleanup; - -cleanup: - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(gdb, &node); - dns_rdata_reset(&rdata); - - return (result); -} - -/*% - * Delete any RRSIG records at a node. - */ -static void -cleannode(dns_db_t *db, dns_dbversion_t *dbversion, dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdataset_t set; - isc_result_t result, dresult; - - if (outputformat != dns_masterformat_text || !disable_zone_check) - return; - - dns_rdataset_init(&set); - result = dns_db_allrdatasets(db, node, dbversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - bool destroy = false; - dns_rdatatype_t covers = 0; - dns_rdatasetiter_current(rdsiter, &set); - if (set.type == dns_rdatatype_rrsig) { - covers = set.covers; - destroy = true; - } - dns_rdataset_disassociate(&set); - result = dns_rdatasetiter_next(rdsiter); - if (destroy) { - dresult = dns_db_deleterdataset(db, node, dbversion, - dns_rdatatype_rrsig, - covers); - check_result(dresult, "dns_db_deleterdataset"); - } - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter); -} - -/*% - * Set up the iterator and global state before starting the tasks. - */ -static void -presign(void) { - isc_result_t result; - - gdbiter = NULL; - result = dns_db_createiterator(gdb, 0, &gdbiter); - check_result(result, "dns_db_createiterator()"); -} - -/*% - * Clean up the iterator and global state after the tasks complete. - */ -static void -postsign(void) { - dns_dbiterator_destroy(&gdbiter); -} - -/*% - * Sign the apex of the zone. - * Note the origin may not be the first node if there are out of zone - * records. - */ -static void -signapex(void) { - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - - name = dns_fixedname_initname(&fixed); - result = dns_dbiterator_seek(gdbiter, gorigin); - check_result(result, "dns_dbiterator_seek()"); - result = dns_dbiterator_current(gdbiter, &node, name); - check_dns_dbiterator_current(result); - signname(node, name); - dumpnode(name, node); - cleannode(gdb, gversion, node); - dns_db_detachnode(gdb, &node); - result = dns_dbiterator_first(gdbiter); - if (result == ISC_R_NOMORE) - finished = true; - else if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); -} - -/*% - * Assigns a node to a worker thread. This is protected by the master task's - * lock. - */ -static void -assignwork(isc_task_t *task, isc_task_t *worker) { - dns_fixedname_t *fname; - dns_name_t *name; - dns_dbnode_t *node; - sevent_t *sevent; - dns_rdataset_t nsec; - bool found; - isc_result_t result; - static dns_name_t *zonecut = NULL; /* Protected by namelock. */ - static dns_fixedname_t fzonecut; /* Protected by namelock. */ - static unsigned int ended = 0; /* Protected by namelock. */ - - if (shuttingdown) - return; - - LOCK(&namelock); - if (finished) { - ended++; - if (ended == ntasks) { - isc_task_detach(&task); - isc_app_shutdown(); - } - goto unlock; - } - - fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); - if (fname == NULL) - fatal("out of memory"); - name = dns_fixedname_initname(fname); - node = NULL; - found = false; - while (!found) { - result = dns_dbiterator_current(gdbiter, &node, name); - check_dns_dbiterator_current(result); - /* - * The origin was handled by signapex(). - */ - if (dns_name_equal(name, gorigin)) { - dns_db_detachnode(gdb, &node); - goto next; - } - /* - * Sort the zone data from the glue and out-of-zone data. - * For NSEC zones nodes with zone data have NSEC records. - * For NSEC3 zones the NSEC3 nodes are zone data but - * outside of the zone name space. For the rest we need - * to track the bottom of zone cuts. - * Nodes which don't need to be signed are dumped here. - */ - dns_rdataset_init(&nsec); - result = dns_db_findrdataset(gdb, node, gversion, - nsec_datatype, 0, 0, - &nsec, NULL); - if (dns_rdataset_isassociated(&nsec)) - dns_rdataset_disassociate(&nsec); - if (result == ISC_R_SUCCESS) { - found = true; - } else if (nsec_datatype == dns_rdatatype_nsec3) { - if (dns_name_issubdomain(name, gorigin) && - (zonecut == NULL || - !dns_name_issubdomain(name, zonecut))) { - if (is_delegation(gdb, gversion, gorigin, - name, node, NULL)) - { - zonecut = savezonecut(&fzonecut, name); - if (!OPTOUT(nsec3flags) || - secure(name, node)) - found = true; - } else if (has_dname(gdb, gversion, node)) { - zonecut = savezonecut(&fzonecut, name); - found = true; - } else { - found = true; - } - } - } - - if (!found) { - dumpnode(name, node); - dns_db_detachnode(gdb, &node); - } - - next: - result = dns_dbiterator_next(gdbiter); - if (result == ISC_R_NOMORE) { - finished = true; - break; - } else if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); - } - if (!found) { - ended++; - if (ended == ntasks) { - isc_task_detach(&task); - isc_app_shutdown(); - } - isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); - goto unlock; - } - sevent = (sevent_t *) - isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, - sign, NULL, sizeof(sevent_t)); - if (sevent == NULL) - fatal("failed to allocate event\n"); - - sevent->node = node; - sevent->fname = fname; - isc_task_send(worker, ISC_EVENT_PTR(&sevent)); - unlock: - UNLOCK(&namelock); -} - -/*% - * Start a worker task - */ -static void -startworker(isc_task_t *task, isc_event_t *event) { - isc_task_t *worker; - - worker = (isc_task_t *)event->ev_arg; - assignwork(task, worker); - isc_event_free(&event); -} - -/*% - * Write a node to the output file, and restart the worker task. - */ -static void -writenode(isc_task_t *task, isc_event_t *event) { - isc_task_t *worker; - sevent_t *sevent = (sevent_t *)event; - - worker = (isc_task_t *)event->ev_sender; - dumpnode(dns_fixedname_name(sevent->fname), sevent->node); - cleannode(gdb, gversion, sevent->node); - dns_db_detachnode(gdb, &sevent->node); - isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); - assignwork(task, worker); - isc_event_free(&event); -} - -/*% - * Sign a database node. - */ -static void -sign(isc_task_t *task, isc_event_t *event) { - dns_fixedname_t *fname; - dns_dbnode_t *node; - sevent_t *sevent, *wevent; - - sevent = (sevent_t *)event; - node = sevent->node; - fname = sevent->fname; - isc_event_free(&event); - - signname(node, dns_fixedname_name(fname)); - wevent = (sevent_t *) - isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, - writenode, NULL, sizeof(sevent_t)); - if (wevent == NULL) - fatal("failed to allocate event\n"); - wevent->node = node; - wevent->fname = fname; - isc_task_send(master, ISC_EVENT_PTR(&wevent)); -} - -/*% - * Update / remove the DS RRset. Preserve RRSIG(DS) if possible. - */ -static void -add_ds(dns_name_t *name, dns_dbnode_t *node, uint32_t nsttl) { - dns_rdataset_t dsset; - dns_rdataset_t sigdsset; - isc_result_t result; - - dns_rdataset_init(&dsset); - dns_rdataset_init(&sigdsset); - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_ds, - 0, 0, &dsset, &sigdsset); - if (result == ISC_R_SUCCESS) { - dns_rdataset_disassociate(&dsset); - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_ds, 0); - check_result(result, "dns_db_deleterdataset"); - } - - result = loadds(name, nsttl, &dsset); - if (result == ISC_R_SUCCESS) { - result = dns_db_addrdataset(gdb, node, gversion, 0, - &dsset, 0, NULL); - check_result(result, "dns_db_addrdataset"); - dns_rdataset_disassociate(&dsset); - if (dns_rdataset_isassociated(&sigdsset)) - dns_rdataset_disassociate(&sigdsset); - } else if (dns_rdataset_isassociated(&sigdsset)) { - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_rrsig, - dns_rdatatype_ds); - check_result(result, "dns_db_deleterdataset"); - dns_rdataset_disassociate(&sigdsset); - } -} - -/* - * Remove records of the given type and their signatures. - */ -static void -remove_records(dns_dbnode_t *node, dns_rdatatype_t which, - bool checknsec) -{ - isc_result_t result; - dns_rdatatype_t type, covers; - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - - /* - * Delete any records of the given type at the apex. - */ - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - if (type == which || covers == which) { - if (which == dns_rdatatype_nsec && - checknsec && !update_chain) - fatal("Zone contains NSEC records. Use -u " - "to update to NSEC3."); - if (which == dns_rdatatype_nsec3param && - checknsec && !update_chain) - fatal("Zone contains NSEC3 chains. Use -u " - "to update to NSEC."); - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, "dns_db_deleterdataset()"); - continue; - } - } - dns_rdatasetiter_destroy(&rdsiter); -} - -/* - * Remove signatures covering the given type. If type == 0, - * then remove all signatures, unless this is a delegation, in - * which case remove all signatures except for DS or nsec_datatype - */ -static void -remove_sigs(dns_dbnode_t *node, bool delegation, - dns_rdatatype_t which) -{ - isc_result_t result; - dns_rdatatype_t type, covers; - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - - if (type != dns_rdatatype_rrsig) - continue; - - if (which == 0 && delegation && - (dns_rdatatype_atparent(covers) || - (nsec_datatype == dns_rdatatype_nsec && - covers == nsec_datatype))) - continue; - - if (which != 0 && covers != which) - continue; - - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, "dns_db_deleterdataset()"); - } - dns_rdatasetiter_destroy(&rdsiter); -} - -/*% - * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records. - */ -static void -nsecify(void) { - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL, *nextnode = NULL; - dns_fixedname_t fname, fnextname, fzonecut; - dns_name_t *name, *nextname, *zonecut; - dns_rdataset_t rdataset; - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdatatype_t type, covers; - bool done = false; - isc_result_t result; - uint32_t nsttl = 0; - - dns_rdataset_init(&rdataset); - name = dns_fixedname_initname(&fname); - nextname = dns_fixedname_initname(&fnextname); - zonecut = NULL; - - /* - * Remove any NSEC3 chains. - */ - result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); - check_result(result, "dns_db_createiterator()"); - for (result = dns_dbiterator_first(dbiter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiter)) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, - "dns_db_deleterdataset(nsec3param/rrsig)"); - } - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(gdb, &node); - } - dns_dbiterator_destroy(&dbiter); - - result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - /* - * Skip out-of-zone records. - */ - if (!dns_name_issubdomain(name, gorigin)) { - result = dns_dbiterator_next(dbiter); - if (result == ISC_R_NOMORE) - done = true; - else - check_result(result, "dns_dbiterator_next()"); - dns_db_detachnode(gdb, &node); - continue; - } - - if (dns_name_equal(name, gorigin)) { - remove_records(node, dns_rdatatype_nsec3param, - true); - /* Clean old rrsigs at apex. */ - (void)active_node(node); - } - - if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) { - zonecut = savezonecut(&fzonecut, name); - remove_sigs(node, true, 0); - if (generateds) - add_ds(name, node, nsttl); - } else if (has_dname(gdb, gversion, node)) { - zonecut = savezonecut(&fzonecut, name); - } - - result = dns_dbiterator_next(dbiter); - nextnode = NULL; - while (result == ISC_R_SUCCESS) { - bool active = false; - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - check_dns_dbiterator_current(result); - active = active_node(nextnode); - if (!active) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (!dns_name_issubdomain(nextname, gorigin) || - (zonecut != NULL && - dns_name_issubdomain(nextname, zonecut))) - { - remove_sigs(nextnode, false, 0); - remove_records(nextnode, dns_rdatatype_nsec, - false); - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - dns_db_detachnode(gdb, &nextnode); - break; - } - if (result == ISC_R_NOMORE) { - dns_name_clone(gorigin, nextname); - done = true; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - dns_dbiterator_pause(dbiter); - result = dns_nsec_build(gdb, gversion, node, nextname, - zone_soa_min_ttl); - check_result(result, "dns_nsec_build()"); - dns_db_detachnode(gdb, &node); - } - - dns_dbiterator_destroy(&dbiter); -} - -static void -addnsec3param(const unsigned char *salt, size_t salt_len, - dns_iterations_t iterations) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - unsigned char nsec3parambuf[5 + 255]; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t b; - isc_result_t result; - - dns_rdataset_init(&rdataset); - - nsec3param.common.rdclass = gclass; - nsec3param.common.rdtype = dns_rdatatype_nsec3param; - ISC_LINK_INIT(&nsec3param.common, link); - nsec3param.mctx = NULL; - nsec3param.flags = 0; - nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1; - nsec3param.iterations = iterations; - nsec3param.salt_length = (unsigned char)salt_len; - DE_CONST(salt, nsec3param.salt); - - isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf)); - result = dns_rdata_fromstruct(&rdata, gclass, - dns_rdatatype_nsec3param, - &nsec3param, &b); - check_result(result, "dns_rdata_fromstruct()"); - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = rdata.rdclass; - rdatalist.type = rdata.type; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - result = dns_rdatalist_tordataset(&rdatalist, &rdataset); - check_result(result, "dns_rdatalist_tordataset()"); - - result = dns_db_findnode(gdb, gorigin, true, &node); - check_result(result, "dns_db_findnode(gorigin)"); - - /* - * Delete any current NSEC3PARAM records. - */ - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_nsec3param, 0); - if (result == DNS_R_UNCHANGED) - result = ISC_R_SUCCESS; - check_result(result, "dddnsec3param: dns_db_deleterdataset()"); - - result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset, - DNS_DBADD_MERGE, NULL); - if (result == DNS_R_UNCHANGED) - result = ISC_R_SUCCESS; - check_result(result, "addnsec3param: dns_db_addrdataset()"); - dns_db_detachnode(gdb, &node); -} - -static void -addnsec3(dns_name_t *name, dns_dbnode_t *node, - const unsigned char *salt, size_t salt_len, - unsigned int iterations, hashlist_t *hashlist, - dns_ttl_t ttl) -{ - unsigned char hash[NSEC3_MAX_HASH_LENGTH]; - const unsigned char *nexthash; - unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE]; - dns_fixedname_t hashname; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_dbnode_t *nsec3node = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - size_t hash_len; - - dns_name_format(name, namebuf, sizeof(namebuf)); - - dns_fixedname_init(&hashname); - dns_rdataset_init(&rdataset); - - dns_name_downcase(name, name, NULL); - result = dns_nsec3_hashname(&hashname, hash, &hash_len, - name, gorigin, dns_hash_sha1, iterations, - salt, salt_len); - check_result(result, "addnsec3: dns_nsec3_hashname()"); - nexthash = hashlist_findnext(hashlist, hash); - result = dns_nsec3_buildrdata(gdb, gversion, node, - unknownalg ? - DNS_NSEC3_UNKNOWNALG : dns_hash_sha1, - nsec3flags, iterations, - salt, salt_len, - nexthash, ISC_SHA1_DIGESTLENGTH, - nsec3buffer, &rdata); - check_result(result, "addnsec3: dns_nsec3_buildrdata()"); - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = rdata.rdclass; - rdatalist.type = rdata.type; - rdatalist.ttl = ttl; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - result = dns_rdatalist_tordataset(&rdatalist, &rdataset); - check_result(result, "dns_rdatalist_tordataset()"); - result = dns_db_findnsec3node(gdb, dns_fixedname_name(&hashname), - true, &nsec3node); - check_result(result, "addnsec3: dns_db_findnode()"); - result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset, - 0, NULL); - if (result == DNS_R_UNCHANGED) - result = ISC_R_SUCCESS; - check_result(result, "addnsec3: dns_db_addrdataset()"); - dns_db_detachnode(gdb, &nsec3node); -} - -/*% - * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list. - * - * Extract the hash from the first label of 'name' then see if it - * is in hashlist. If 'name' is not in the hashlist then delete the - * any NSEC3 records which have the same parameters as the chain we - * are building. - * - * XXXMPA Should we also check that it of the form <hash>.<origin>? - */ -static void -nsec3clean(dns_name_t *name, dns_dbnode_t *node, - unsigned int hashalg, unsigned int iterations, - const unsigned char *salt, size_t salt_len, hashlist_t *hashlist) -{ - dns_label_t label; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata, delrdata; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset, delrdataset; - bool delete_rrsigs = false; - isc_buffer_t target; - isc_result_t result; - unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1]; - bool exists; - - /* - * Get the first label. - */ - dns_name_getlabel(name, 0, &label); - - /* - * We want just the label contents. - */ - isc_region_consume(&label, 1); - - /* - * Decode base32hex string. - */ - isc_buffer_init(&target, hash, sizeof(hash) - 1); - result = isc_base32hex_decoderegion(&label, &target); - if (result != ISC_R_SUCCESS) - return; - - hash[isc_buffer_usedlength(&target)] = 0; - - exists = hashlist_exists(hashlist, hash); - - /* - * Verify that the NSEC3 parameters match the current ones - * otherwise we are dealing with a different NSEC3 chain. - */ - dns_rdataset_init(&rdataset); - dns_rdataset_init(&delrdataset); - - result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - return; - - /* - * Delete any NSEC3 records which are not part of the current - * NSEC3 chain. - */ - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_init(&rdata); - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - check_result(result, "dns_rdata_tostruct"); - if (exists && nsec3.hash == hashalg && - nsec3.iterations == iterations && - nsec3.salt_length == salt_len && - isc_safe_memequal(nsec3.salt, salt, salt_len)) - continue; - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = rdata.rdclass; - rdatalist.type = rdata.type; - if (set_maxttl) - rdatalist.ttl = ISC_MIN(rdataset.ttl, maxttl); - dns_rdata_init(&delrdata); - dns_rdata_clone(&rdata, &delrdata); - ISC_LIST_APPEND(rdatalist.rdata, &delrdata, link); - result = dns_rdatalist_tordataset(&rdatalist, &delrdataset); - check_result(result, "dns_rdatalist_tordataset()"); - result = dns_db_subtractrdataset(gdb, node, gversion, - &delrdataset, 0, NULL); - dns_rdataset_disassociate(&delrdataset); - if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET) - check_result(result, "dns_db_subtractrdataset(NSEC3)"); - delete_rrsigs = true; - } - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_NOMORE) - check_result(result, "dns_rdataset_first/next"); - - if (!delete_rrsigs) - return; - /* - * Delete the NSEC3 RRSIGs - */ - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_rrsig, - dns_rdatatype_nsec3); - if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) - check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))"); -} - -static void -rrset_cleanup(dns_name_t *name, dns_rdataset_t *rdataset, - dns_diff_t *add, dns_diff_t *del) -{ - isc_result_t result; - unsigned int count1 = 0; - dns_rdataset_t tmprdataset; - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[TYPE_FORMATSIZE]; - - dns_name_format(name, namestr, sizeof(namestr)); - type_format(rdataset->type, typestr, sizeof(typestr)); - - dns_rdataset_init(&tmprdataset); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata1 = DNS_RDATA_INIT; - unsigned int count2 = 0; - - count1++; - dns_rdataset_current(rdataset, &rdata1); - dns_rdataset_clone(rdataset, &tmprdataset); - for (result = dns_rdataset_first(&tmprdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&tmprdataset)) { - dns_rdata_t rdata2 = DNS_RDATA_INIT; - dns_difftuple_t *tuple = NULL; - count2++; - dns_rdataset_current(&tmprdataset, &rdata2); - if (count1 < count2 && - dns_rdata_casecompare(&rdata1, &rdata2) == 0) - { - vbprintf(2, "removing duplicate at %s/%s\n", - namestr, typestr); - result = dns_difftuple_create(mctx, - DNS_DIFFOP_DELRESIGN, - name, rdataset->ttl, - &rdata2, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - } else if (set_maxttl && rdataset->ttl > maxttl) { - vbprintf(2, "reducing ttl of %s/%s " - "from %d to %d\n", - namestr, typestr, - rdataset->ttl, maxttl); - result = dns_difftuple_create(mctx, - DNS_DIFFOP_DELRESIGN, - name, rdataset->ttl, - &rdata2, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - tuple = NULL; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - name, maxttl, - &rdata2, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); - } - } - dns_rdataset_disassociate(&tmprdataset); - } -} - -static void -cleanup_zone(void) { - isc_result_t result; - dns_dbiterator_t *dbiter = NULL; - dns_rdatasetiter_t *rdsiter = NULL; - dns_diff_t add, del; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_fixedname_t fname; - dns_name_t *name; - - dns_diff_init(mctx, &add); - dns_diff_init(mctx, &del); - name = dns_fixedname_initname(&fname); - dns_rdataset_init(&rdataset); - - result = dns_db_createiterator(gdb, 0, &dbiter); - check_result(result, "dns_db_createiterator()"); - - for (result = dns_dbiterator_first(dbiter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiter)) { - - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - rrset_cleanup(name, &rdataset, &add, &del); - dns_rdataset_disassociate(&rdataset); - } - if (result != ISC_R_NOMORE) - fatal("rdatasets iteration failed."); - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(gdb, &node); - } - if (result != ISC_R_NOMORE) - fatal("zone iteration failed."); - - result = dns_diff_applysilently(&del, gdb, gversion); - check_result(result, "dns_diff_applysilently"); - - result = dns_diff_applysilently(&add, gdb, gversion); - check_result(result, "dns_diff_applysilently"); - - dns_diff_clear(&del); - dns_diff_clear(&add); - dns_dbiterator_destroy(&dbiter); -} - -/* - * Generate NSEC3 records for the zone. - */ -static void -nsec3ify(unsigned int hashalg, dns_iterations_t iterations, - const unsigned char *salt, size_t salt_len, hashlist_t *hashlist) -{ - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL, *nextnode = NULL; - dns_fixedname_t fname, fnextname, fzonecut; - dns_name_t *name, *nextname, *zonecut; - dns_rdataset_t rdataset; - int order; - bool active; - bool done = false; - isc_result_t result; - uint32_t nsttl = 0; - unsigned int count, nlabels; - - dns_rdataset_init(&rdataset); - name = dns_fixedname_initname(&fname); - nextname = dns_fixedname_initname(&fnextname); - zonecut = NULL; - - /* - * Walk the zone generating the hash names. - */ - result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - /* - * Skip out-of-zone records. - */ - if (!dns_name_issubdomain(name, gorigin)) { - result = dns_dbiterator_next(dbiter); - if (result == ISC_R_NOMORE) - done = true; - else - check_result(result, "dns_dbiterator_next()"); - dns_db_detachnode(gdb, &node); - continue; - } - - if (dns_name_equal(name, gorigin)) { - remove_records(node, dns_rdatatype_nsec, true); - /* Clean old rrsigs at apex. */ - (void)active_node(node); - } - - if (has_dname(gdb, gversion, node)) { - zonecut = savezonecut(&fzonecut, name); - } - - result = dns_dbiterator_next(dbiter); - nextnode = NULL; - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - check_dns_dbiterator_current(result); - active = active_node(nextnode); - if (!active) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (!dns_name_issubdomain(nextname, gorigin) || - (zonecut != NULL && - dns_name_issubdomain(nextname, zonecut))) { - remove_sigs(nextnode, false, 0); - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (is_delegation(gdb, gversion, gorigin, - nextname, nextnode, &nsttl)) - { - zonecut = savezonecut(&fzonecut, nextname); - remove_sigs(nextnode, true, 0); - if (generateds) - add_ds(nextname, nextnode, nsttl); - if (OPTOUT(nsec3flags) && - !secure(nextname, nextnode)) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - } else if (has_dname(gdb, gversion, nextnode)) { - zonecut = savezonecut(&fzonecut, nextname); - } - dns_db_detachnode(gdb, &nextnode); - break; - } - if (result == ISC_R_NOMORE) { - dns_name_copy(gorigin, nextname, NULL); - done = true; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - dns_name_downcase(name, name, NULL); - hashlist_add_dns_name(hashlist, name, hashalg, iterations, - salt, salt_len, false); - dns_db_detachnode(gdb, &node); - /* - * Add hashes for empty nodes. Use closest encloser logic. - * The closest encloser either has data or is a empty - * node for another span so we don't add - * it here. Empty labels on nextname are within the span. - */ - dns_name_downcase(nextname, nextname, NULL); - dns_name_fullcompare(name, nextname, &order, &nlabels); - addnowildcardhash(hashlist, name, hashalg, iterations, - salt, salt_len); - count = dns_name_countlabels(nextname); - while (count > nlabels + 1) { - count--; - dns_name_split(nextname, count, NULL, nextname); - hashlist_add_dns_name(hashlist, nextname, hashalg, - iterations, salt, salt_len, - false); - addnowildcardhash(hashlist, nextname, hashalg, - iterations, salt, salt_len); - } - } - dns_dbiterator_destroy(&dbiter); - - /* - * We have all the hashes now so we can sort them. - */ - hashlist_sort(hashlist); - - /* - * Check for duplicate hashes. If found the salt needs to - * be changed. - */ - if (hashlist_hasdup(hashlist)) - fatal("Duplicate hash detected. Pick a different salt."); - - /* - * Generate the nsec3 records. - */ - zonecut = NULL; - done = false; - - addnsec3param(salt, salt_len, iterations); - - /* - * Clean out NSEC3 records which don't match this chain. - */ - result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); - check_result(result, "dns_db_createiterator()"); - - for (result = dns_dbiterator_first(dbiter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiter)) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - nsec3clean(name, node, hashalg, iterations, salt, salt_len, - hashlist); - dns_db_detachnode(gdb, &node); - } - dns_dbiterator_destroy(&dbiter); - - /* - * Generate / complete the new chain. - */ - result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - /* - * Skip out-of-zone records. - */ - if (!dns_name_issubdomain(name, gorigin)) { - result = dns_dbiterator_next(dbiter); - if (result == ISC_R_NOMORE) - done = true; - else - check_result(result, "dns_dbiterator_next()"); - dns_db_detachnode(gdb, &node); - continue; - } - - if (has_dname(gdb, gversion, node)) { - zonecut = savezonecut(&fzonecut, name); - } - - result = dns_dbiterator_next(dbiter); - nextnode = NULL; - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - check_dns_dbiterator_current(result); - active = active_node(nextnode); - if (!active) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (!dns_name_issubdomain(nextname, gorigin) || - (zonecut != NULL && - dns_name_issubdomain(nextname, zonecut))) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (is_delegation(gdb, gversion, gorigin, - nextname, nextnode, NULL)) - { - zonecut = savezonecut(&fzonecut, nextname); - if (OPTOUT(nsec3flags) && - !secure(nextname, nextnode)) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - } else if (has_dname(gdb, gversion, nextnode)) { - zonecut = savezonecut(&fzonecut, nextname); - } - dns_db_detachnode(gdb, &nextnode); - break; - } - if (result == ISC_R_NOMORE) { - dns_name_copy(gorigin, nextname, NULL); - done = true; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - /* - * We need to pause here to release the lock on the database. - */ - dns_dbiterator_pause(dbiter); - addnsec3(name, node, salt, salt_len, iterations, - hashlist, zone_soa_min_ttl); - dns_db_detachnode(gdb, &node); - /* - * Add NSEC3's for empty nodes. Use closest encloser logic. - */ - dns_name_fullcompare(name, nextname, &order, &nlabels); - count = dns_name_countlabels(nextname); - while (count > nlabels + 1) { - count--; - dns_name_split(nextname, count, NULL, nextname); - addnsec3(nextname, NULL, salt, salt_len, - iterations, hashlist, zone_soa_min_ttl); - } - } - dns_dbiterator_destroy(&dbiter); -} - -/*% - * Load the zone file from disk - */ -static void -loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { - isc_buffer_t b; - int len; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - len = strlen(origin); - isc_buffer_init(&b, origin, len); - isc_buffer_add(&b, len); - - name = dns_fixedname_initname(&fname); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed converting name '%s' to dns format: %s", - origin, isc_result_totext(result)); - - result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, - rdclass, 0, NULL, db); - check_result(result, "dns_db_create()"); - - result = dns_db_load2(*db, file, inputformat); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - fatal("failed loading zone from '%s': %s", - file, isc_result_totext(result)); -} - -/*% - * Finds all public zone keys in the zone, and attempts to load the - * private keys from disk. - */ -static void -loadzonekeys(bool preserve_keys, bool load_public) { - dns_dbnode_t *node; - dns_dbversion_t *currentversion = NULL; - isc_result_t result; - dns_rdataset_t rdataset, keysigs, soasigs; - - node = NULL; - result = dns_db_findnode(gdb, gorigin, false, &node); - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone's origin: %s", - isc_result_totext(result)); - - dns_db_currentversion(gdb, ¤tversion); - - dns_rdataset_init(&rdataset); - dns_rdataset_init(&soasigs); - dns_rdataset_init(&keysigs); - - /* Make note of the keys which signed the SOA, if any */ - result = dns_db_findrdataset(gdb, node, currentversion, - dns_rdatatype_soa, 0, 0, - &rdataset, &soasigs); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* Preserve the TTL of the DNSKEY RRset, if any */ - dns_rdataset_disassociate(&rdataset); - result = dns_db_findrdataset(gdb, node, currentversion, - dns_rdatatype_dnskey, 0, 0, - &rdataset, &keysigs); - - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (set_keyttl && keyttl != rdataset.ttl) { - fprintf(stderr, "User-specified TTL %u conflicts " - "with existing DNSKEY RRset TTL.\n", - keyttl); - fprintf(stderr, "Imported keys will use the RRSet " - "TTL %u instead.\n", - rdataset.ttl); - } - keyttl = rdataset.ttl; - - /* Load keys corresponding to the existing DNSKEY RRset. */ - result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx, - &rdataset, &keysigs, &soasigs, - preserve_keys, load_public, - &keylist); - if (result != ISC_R_SUCCESS) - fatal("failed to load the zone keys: %s", - isc_result_totext(result)); - - cleanup: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (dns_rdataset_isassociated(&keysigs)) - dns_rdataset_disassociate(&keysigs); - if (dns_rdataset_isassociated(&soasigs)) - dns_rdataset_disassociate(&soasigs); - dns_db_detachnode(gdb, &node); - dns_db_closeversion(gdb, ¤tversion, false); -} - -static void -loadexplicitkeys(char *keyfiles[], int n, bool setksk) { - isc_result_t result; - int i; - - for (i = 0; i < n; i++) { - dns_dnsseckey_t *key = NULL; - dst_key_t *newkey = NULL; - - result = dst_key_fromnamedfile(keyfiles[i], directory, - DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE, - mctx, &newkey); - if (result != ISC_R_SUCCESS) - fatal("cannot load dnskey %s: %s", keyfiles[i], - isc_result_totext(result)); - - if (!dns_name_equal(gorigin, dst_key_name(newkey))) - fatal("key %s not at origin\n", keyfiles[i]); - - if (!dst_key_isprivate(newkey)) - fatal("cannot sign zone with non-private dnskey %s", - keyfiles[i]); - - /* Skip any duplicates */ - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - if (dst_key_id(key->key) == dst_key_id(newkey) && - dst_key_alg(key->key) == dst_key_alg(newkey)) - break; - } - - if (key == NULL) { - /* We haven't seen this key before */ - dns_dnsseckey_create(mctx, &newkey, &key); - ISC_LIST_APPEND(keylist, key, link); - key->source = dns_keysource_user; - } else { - dst_key_free(&key->key); - key->key = newkey; - } - - key->force_publish = true; - key->force_sign = true; - - if (setksk) - key->ksk = true; - } -} - -static void -report(const char *format, ...) { - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - putc('\n', stderr); -} - -static void -build_final_keylist(void) { - isc_result_t result; - dns_dbversion_t *ver = NULL; - dns_diff_t diff; - dns_dnsseckeylist_t matchkeys; - char name[DNS_NAME_FORMATSIZE]; - - /* - * Find keys that match this zone in the key repository. - */ - ISC_LIST_INIT(matchkeys); - result = dns_dnssec_findmatchingkeys(gorigin, directory, - mctx, &matchkeys); - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - check_result(result, "dns_dnssec_findmatchingkeys"); - - result = dns_db_newversion(gdb, &ver); - check_result(result, "dns_db_newversion"); - - dns_diff_init(mctx, &diff); - - /* - * Update keylist with information from from the key repository. - */ - dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl, - &diff, ignore_kskflag, mctx, report); - - dns_name_format(gorigin, name, sizeof(name)); - - result = dns_diff_applysilently(&diff, gdb, ver); - if (result != ISC_R_SUCCESS) - fatal("failed to update DNSKEY RRset at node '%s': %s", - name, isc_result_totext(result)); - - dns_db_closeversion(gdb, &ver, true); - - dns_diff_clear(&diff); -} - -static void -warnifallksk(dns_db_t *db) { - dns_dbversion_t *currentversion = NULL; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_rdata_dnskey_t dnskey; - bool have_non_ksk = false; - - dns_db_currentversion(db, ¤tversion); - - result = dns_db_findnode(db, gorigin, false, &node); - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone's origin: %s", - isc_result_totext(result)); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, currentversion, - dns_rdatatype_dnskey, 0, 0, &rdataset, - NULL); - if (result != ISC_R_SUCCESS) - fatal("failed to find keys at the zone apex: %s", - isc_result_totext(result)); - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dnskey, NULL); - check_result(result, "dns_rdata_tostruct"); - if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { - have_non_ksk = true; - result = ISC_R_NOMORE; - } else - result = dns_rdataset_next(&rdataset); - dns_rdata_freestruct(&dnskey); - } - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - dns_db_closeversion(db, ¤tversion, false); - if (!have_non_ksk && !ignore_kskflag) { - if (disable_zone_check) - fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; " - "supply a ZSK or use '-z'.\n", - program); - else - fatal("No non-KSK DNSKEY found; " - "supply a ZSK or use '-z'."); - } -} - -static void -set_nsec3params(bool update, bool set_salt, - bool set_optout, bool set_iter) -{ - isc_result_t result; - dns_dbversion_t *ver = NULL; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3_t nsec3; - dns_fixedname_t fname; - dns_name_t *hashname; - unsigned char orig_salt[255]; - size_t orig_saltlen; - dns_hash_t orig_hash; - uint16_t orig_iter; - - dns_db_currentversion(gdb, &ver); - dns_rdataset_init(&rdataset); - - orig_saltlen = sizeof(orig_salt); - result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL, - &orig_iter, orig_salt, - &orig_saltlen); - if (result != ISC_R_SUCCESS) - goto cleanup; - - nsec_datatype = dns_rdatatype_nsec3; - - if (!update && set_salt) { - if (salt_length != orig_saltlen || - !isc_safe_memequal(saltbuf, orig_salt, salt_length)) - fatal("An NSEC3 chain exists with a different salt. " - "Use -u to update it."); - } else if (!set_salt) { - salt_length = orig_saltlen; - memmove(saltbuf, orig_salt, orig_saltlen); - gsalt = saltbuf; - } - - if (!update && set_iter) { - if (nsec3iter != orig_iter) - fatal("An NSEC3 chain exists with different " - "iterations. Use -u to update it."); - } else if (!set_iter) - nsec3iter = orig_iter; - - /* - * Find an NSEC3 record to get the current OPTOUT value. - * (This assumes all NSEC3 records agree.) - */ - - hashname = dns_fixedname_initname(&fname); - result = dns_nsec3_hashname(&fname, NULL, NULL, - gorigin, gorigin, dns_hash_sha1, - orig_iter, orig_salt, orig_saltlen); - check_result(result, "dns_nsec3_hashname"); - - result = dns_db_findnsec3node(gdb, hashname, false, &node); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - check_result(result, "dns_rdata_tostruct"); - - if (!update && set_optout) { - if (nsec3flags != nsec3.flags) - fatal("An NSEC3 chain exists with%s OPTOUT. " - "Use -u -%s to %s it.", - OPTOUT(nsec3.flags) ? "" : "out", - OPTOUT(nsec3.flags) ? "AA" : "A", - OPTOUT(nsec3.flags) ? "clear" : "set"); - } else if (!set_optout) - nsec3flags = nsec3.flags; - - dns_rdata_freestruct(&nsec3); - - cleanup: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(gdb, &node); - dns_db_closeversion(gdb, &ver, false); -} - -static void -writeset(const char *prefix, dns_rdatatype_t type) { - char *filename; - char namestr[DNS_NAME_FORMATSIZE]; - dns_db_t *db = NULL; - dns_dbversion_t *dbversion = NULL; - dns_diff_t diff; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixed; - dns_name_t *name; - dns_rdata_t rdata, ds; - bool have_ksk = false; - bool have_non_ksk = false; - isc_buffer_t b; - isc_buffer_t namebuf; - isc_region_t r; - isc_result_t result; - dns_dnsseckey_t *key, *tmpkey; - unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - unsigned char keybuf[DST_KEY_MAXSIZE]; - unsigned int filenamelen; - const dns_master_style_t *style = - (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle; - - isc_buffer_init(&namebuf, namestr, sizeof(namestr)); - result = dns_name_tofilenametext(gorigin, false, &namebuf); - check_result(result, "dns_name_tofilenametext"); - isc_buffer_putuint8(&namebuf, 0); - filenamelen = strlen(prefix) + strlen(namestr) + 1; - if (dsdir != NULL) - filenamelen += strlen(dsdir) + 1; - filename = isc_mem_get(mctx, filenamelen); - if (filename == NULL) - fatal("out of memory"); - if (dsdir != NULL) - snprintf(filename, filenamelen, "%s/", dsdir); - else - filename[0] = 0; - strlcat(filename, prefix, filenamelen); - strlcat(filename, namestr, filenamelen); - - dns_diff_init(mctx, &diff); - - if (type == dns_rdatatype_dlv) { - dns_name_t tname; - unsigned int labels; - - dns_name_init(&tname, NULL); - name = dns_fixedname_initname(&fixed); - labels = dns_name_countlabels(gorigin); - dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname); - result = dns_name_concatenate(&tname, dlv, name, NULL); - check_result(result, "dns_name_concatenate"); - } else - name = gorigin; - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - if (REVOKE(key->key)) - continue; - if (isksk(key)) { - have_ksk = true; - have_non_ksk = false; - } else { - have_ksk = false; - have_non_ksk = true; - } - for (tmpkey = ISC_LIST_HEAD(keylist); - tmpkey != NULL; - tmpkey = ISC_LIST_NEXT(tmpkey, link)) { - if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key)) - continue; - if (REVOKE(tmpkey->key)) - continue; - if (isksk(tmpkey)) - have_ksk = true; - else - have_non_ksk = true; - } - if (have_ksk && have_non_ksk && !isksk(key)) - continue; - dns_rdata_init(&rdata); - dns_rdata_init(&ds); - isc_buffer_init(&b, keybuf, sizeof(keybuf)); - result = dst_key_todns(key->key, &b); - check_result(result, "dst_key_todns"); - isc_buffer_usedregion(&b, &r); - dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); - if (type != dns_rdatatype_dnskey) { - result = dns_ds_buildrdata(gorigin, &rdata, - DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - if (type == dns_rdatatype_dlv) - ds.type = dns_rdatatype_dlv; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - name, 0, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); - result = dns_ds_buildrdata(gorigin, &rdata, - DNS_DSDIGEST_SHA256, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - if (type == dns_rdatatype_dlv) - ds.type = dns_rdatatype_dlv; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - name, 0, &ds, &tuple); - - } else - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - gorigin, zone_soa_min_ttl, - &rdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - } - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - gclass, 0, NULL, &db); - check_result(result, "dns_db_create"); - - result = dns_db_newversion(db, &dbversion); - check_result(result, "dns_db_newversion"); - - result = dns_diff_apply(&diff, db, dbversion); - check_result(result, "dns_diff_apply"); - dns_diff_clear(&diff); - - result = dns_master_dump(mctx, db, dbversion, style, filename); - check_result(result, "dns_master_dump"); - - isc_mem_put(mctx, filename, filenamelen); - - dns_db_closeversion(db, &dbversion, false); - dns_db_detach(&db); -} - -static void -print_time(FILE *fp) { - time_t currenttime = time(NULL); - struct tm t, *tm = localtime_r(¤ttime, &t); - unsigned int flen; - char timebuf[80]; - - if (tm == NULL || outputformat != dns_masterformat_text) { - return; - } - - flen = strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S %Y", tm); - INSIST(flen > 0U && flen < sizeof(timebuf)); - fprintf(fp, "; File written on %s\n", timebuf); -} - -static void -print_version(FILE *fp) { - if (outputformat != dns_masterformat_text) - return; - - fprintf(fp, "; dnssec_signzone version " VERSION "\n"); -} - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); - - fprintf(stderr, "\n"); - - fprintf(stderr, "Version: %s\n", VERSION); - - fprintf(stderr, "Options: (default value in parenthesis) \n"); - fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n" - "\t\tfor the zone and determines how they are to " - "be used\n"); - fprintf(stderr, "\t-K directory:\n"); - fprintf(stderr, "\t\tdirectory to find key files (.)\n"); - fprintf(stderr, "\t-d directory:\n"); - fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n"); - fprintf(stderr, "\t-g:\t"); - fprintf(stderr, "update DS records based on child zones' " - "dsset-* files\n"); - fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n"); - fprintf(stderr, "\t\tRRSIG start time " - "- absolute|offset (now - 1 hour)\n"); - fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); - fprintf(stderr, "\t\tRRSIG end time " - "- absolute|from start|from now " - "(now + 30 days)\n"); - fprintf(stderr, "\t-X [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); - fprintf(stderr, "\t\tDNSKEY RRSIG end " - "- absolute|from start|from now " - "(matches -e)\n"); - fprintf(stderr, "\t-i interval:\n"); - fprintf(stderr, "\t\tcycle interval - resign " - "if < interval from end ( (end-start)/4 )\n"); - fprintf(stderr, "\t-j jitter:\n"); - fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n"); - fprintf(stderr, "\t-v debuglevel (0)\n"); - fprintf(stderr, "\t-V:\tprint version information\n"); - fprintf(stderr, "\t-o origin:\n"); - fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); - fprintf(stderr, "\t-f outfile:\n"); - fprintf(stderr, "\t\tfile the signed zone is written in " - "(zonefile + .signed)\n"); - fprintf(stderr, "\t-I format:\n"); - fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); - fprintf(stderr, "\t-O format:\n"); - fprintf(stderr, "\t\tfile format of signed zone file (text)\n"); - fprintf(stderr, "\t-N format:\n"); - fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n"); - fprintf(stderr, "\t-D:\n"); - fprintf(stderr, "\t\toutput only DNSSEC-related records\n"); - fprintf(stderr, "\t-r randomdev:\n"); - fprintf(stderr, "\t\ta file containing random data\n"); - fprintf(stderr, "\t-a:\t"); - fprintf(stderr, "verify generated signatures\n"); - fprintf(stderr, "\t-c class (IN)\n"); - fprintf(stderr, "\t-E engine:\n"); -#if defined(PKCS11CRYPTO) - fprintf(stderr, "\t\tpath to PKCS#11 provider library " - "(default is %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, "\t\tname of an OpenSSL engine to use " - "(default is \"pkcs11\")\n"); -#else - fprintf(stderr, "\t\tname of an OpenSSL engine to use\n"); -#endif - fprintf(stderr, "\t-p:\t"); - fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); - fprintf(stderr, "\t-P:\t"); - fprintf(stderr, "disable post-sign verification\n"); - fprintf(stderr, "\t-Q:\t"); - fprintf(stderr, "remove signatures from keys that are no " - "longer active\n"); - fprintf(stderr, "\t-R:\t"); - fprintf(stderr, "remove signatures from keys that no longer exist\n"); - fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n"); - fprintf(stderr, "\t-t:\t"); - fprintf(stderr, "print statistics\n"); - fprintf(stderr, "\t-u:\t"); - fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n"); - fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n"); - fprintf(stderr, "\t-z:\tsign all records with KSKs\n"); - fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n" - "\t\twith older versions of dnssec-signzone -g\n"); - fprintf(stderr, "\t-n ncpus (number of cpus present)\n"); - fprintf(stderr, "\t-k key_signing_key\n"); - fprintf(stderr, "\t-l lookasidezone\n"); - fprintf(stderr, "\t-3 NSEC3 salt\n"); - fprintf(stderr, "\t-H NSEC3 iterations (10)\n"); - fprintf(stderr, "\t-A NSEC3 optout\n"); - - fprintf(stderr, "\n"); - - fprintf(stderr, "Signing Keys: "); - fprintf(stderr, "(default: all zone keys that have private keys)\n"); - fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); - - exit(0); -} - -static void -removetempfile(void) { - if (removefile) - isc_file_remove(tempfile); -} - -static void -print_stats(isc_time_t *timer_start, isc_time_t *timer_finish, - isc_time_t *sign_start, isc_time_t *sign_finish) -{ - uint64_t time_us; /* Time in microseconds */ - uint64_t time_ms; /* Time in milliseconds */ - uint64_t sig_ms; /* Signatures per millisecond */ - FILE *out = output_stdout ? stderr : stdout; - - fprintf(out, "Signatures generated: %10u\n", nsigned); - fprintf(out, "Signatures retained: %10u\n", nretained); - fprintf(out, "Signatures dropped: %10u\n", ndropped); - fprintf(out, "Signatures successfully verified: %10u\n", nverified); - fprintf(out, "Signatures unsuccessfully " - "verified: %10u\n", nverifyfailed); - - time_us = isc_time_microdiff(sign_finish, sign_start); - time_ms = time_us / 1000; - fprintf(out, "Signing time in seconds: %7u.%03u\n", - (unsigned int) (time_ms / 1000), - (unsigned int) (time_ms % 1000)); - if (time_us > 0) { - sig_ms = ((uint64_t)nsigned * 1000000000) / time_us; - fprintf(out, "Signatures per second: %7u.%03u\n", - (unsigned int) sig_ms / 1000, - (unsigned int) sig_ms % 1000); - } - - time_us = isc_time_microdiff(timer_finish, timer_start); - time_ms = time_us / 1000; - fprintf(out, "Runtime in seconds: %7u.%03u\n", - (unsigned int) (time_ms / 1000), - (unsigned int) (time_ms % 1000)); -} - -int -main(int argc, char *argv[]) { - int i, ch; - char *startstr = NULL, *endstr = NULL, *classname = NULL; - char *dnskey_endstr = NULL; - char *origin = NULL, *file = NULL, *output = NULL; - char *inputformatstr = NULL, *outputformatstr = NULL; - char *serialformatstr = NULL; - char *dskeyfile[MAXDSKEYS]; - int ndskeys = 0; - char *endp; - isc_time_t timer_start, timer_finish; - isc_time_t sign_start, sign_finish; - dns_dnsseckey_t *key; - isc_result_t result; - isc_log_t *log = NULL; - bool pseudorandom = false; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - unsigned int eflags; - bool free_output = false; - int tempfilelen = 0; - dns_rdataclass_t rdclass; - isc_task_t **tasks = NULL; - isc_buffer_t b; - int len; - hashlist_t hashlist; - bool make_keyset = false; - bool set_salt = false; - bool set_optout = false; - bool set_iter = false; - bool nonsecify = false; - - /* Unused letters: Bb G J q Yy (and F is reserved). */ -#define CMDLINE_FLAGS \ - "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:M:n:N:o:O:PpQRr:s:ST:tuUv:VX:xzZ:" - - /* - * Process memory debugging argument first. - */ - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'm': - if (strcasecmp(isc_commandline_argument, "record") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - if (strcasecmp(isc_commandline_argument, "trace") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGTRACE; - if (strcasecmp(isc_commandline_argument, "usage") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; - if (strcasecmp(isc_commandline_argument, "size") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGSIZE; - if (strcasecmp(isc_commandline_argument, "mctx") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGCTX; - break; - default: - break; - } - } - isc_commandline_reset = true; - -#ifdef _WIN32 - InitSockets(); -#endif - - masterstyle = &dns_master_style_explicitttl; - - check_result(isc_app_start(), "isc_app_start"); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("out of memory"); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case '3': - set_salt = true; - nsec_datatype = dns_rdatatype_nsec3; - if (strcmp(isc_commandline_argument, "-") != 0) { - isc_buffer_t target; - char *sarg; - - sarg = isc_commandline_argument; - isc_buffer_init(&target, saltbuf, - sizeof(saltbuf)); - result = isc_hex_decodestring(sarg, &target); - check_result(result, - "isc_hex_decodestring(salt)"); - salt_length = isc_buffer_usedlength(&target); - } - break; - - case 'A': - set_optout = true; - if (OPTOUT(nsec3flags)) - nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT; - else - nsec3flags |= DNS_NSEC3FLAG_OPTOUT; - break; - - case 'a': - tryverify = true; - break; - - case 'C': - make_keyset = true; - break; - - case 'c': - classname = isc_commandline_argument; - break; - - case 'd': - dsdir = isc_commandline_argument; - if (strlen(dsdir) == 0U) - fatal("DS directory must be non-empty string"); - result = try_dir(dsdir); - if (result != ISC_R_SUCCESS) - fatal("cannot open directory %s: %s", - dsdir, isc_result_totext(result)); - break; - - case 'D': - output_dnssec_only = true; - break; - - case 'E': - engine = isc_commandline_argument; - break; - - case 'e': - endstr = isc_commandline_argument; - break; - - case 'f': - output = isc_commandline_argument; - if (strcmp(output, "-") == 0) - output_stdout = true; - break; - - case 'g': - generateds = true; - break; - - case 'H': - set_iter = true; - nsec3iter = strtoul(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("iterations must be numeric"); - if (nsec3iter > 0xffffU) - fatal("iterations too big"); - break; - - case 'I': - inputformatstr = isc_commandline_argument; - break; - - case 'i': - endp = NULL; - cycle = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || cycle < 0) - fatal("cycle period must be numeric and " - "positive"); - break; - - case 'j': - endp = NULL; - jitter = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || jitter < 0) - fatal("jitter must be numeric and positive"); - break; - - case 'K': - directory = isc_commandline_argument; - break; - - case 'k': - if (ndskeys == MAXDSKEYS) - fatal("too many key-signing keys specified"); - dskeyfile[ndskeys++] = isc_commandline_argument; - break; - - case 'L': - snset = true; - endp = NULL; - serialnum = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') { - fprintf(stderr, "source serial number " - "must be numeric"); - exit(1); - } - break; - - case 'l': - len = strlen(isc_commandline_argument); - isc_buffer_init(&b, isc_commandline_argument, len); - isc_buffer_add(&b, len); - - dlv = dns_fixedname_initname(&dlv_fixed); - result = dns_name_fromtext(dlv, &b, dns_rootname, 0, - NULL); - check_result(result, "dns_name_fromtext(dlv)"); - break; - - case 'M': - endp = NULL; - set_maxttl = true; - maxttl = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') { - fprintf(stderr, "maximum TTL " - "must be numeric"); - exit(1); - } - break; - - case 'm': - break; - - case 'N': - serialformatstr = isc_commandline_argument; - break; - - case 'n': - endp = NULL; - ntasks = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || ntasks > INT32_MAX) - fatal("number of cpus must be numeric"); - break; - - case 'O': - outputformatstr = isc_commandline_argument; - break; - - case 'o': - origin = isc_commandline_argument; - break; - - case 'P': - disable_zone_check = true; - break; - - case 'p': - pseudorandom = true; - break; - - case 'Q': - remove_inactkeysigs = true; - break; - - case 'R': - remove_orphansigs = true; - break; - - case 'r': - setup_entropy(mctx, isc_commandline_argument, &ectx); - break; - - case 'S': - smartsign = true; - break; - - case 's': - startstr = isc_commandline_argument; - break; - - case 'T': - endp = NULL; - set_keyttl = true; - keyttl = strtottl(isc_commandline_argument); - break; - - case 't': - printstats = true; - break; - - case 'U': /* Undocumented for testing only. */ - unknownalg = true; - break; - - case 'u': - update_chain = true; - break; - - case 'v': - endp = NULL; - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("verbose level must be numeric"); - break; - - case 'X': - dnskey_endstr = isc_commandline_argument; - break; - - case 'x': - keyset_kskonly = true; - break; - - case 'z': - ignore_kskflag = true; - break; - - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - case 'Z': /* Undocumented test options */ - if (!strcmp(isc_commandline_argument, "nonsecify")) - nonsecify = true; - break; - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - eflags = ISC_ENTROPY_BLOCKING; - if (!pseudorandom) - eflags |= ISC_ENTROPY_GOODONLY; - - result = dst_lib_init2(mctx, ectx, engine, eflags); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(result)); - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not create hash context"); - - isc_stdtime_get(&now); - - if (startstr != NULL) { - starttime = strtotime(startstr, now, now, NULL); - } else - starttime = now - 3600; /* Allow for some clock skew. */ - - if (endstr != NULL) - endtime = strtotime(endstr, now, starttime, NULL); - else - endtime = starttime + (30 * 24 * 60 * 60); - - if (dnskey_endstr != NULL) { - dnskey_endtime = strtotime(dnskey_endstr, now, starttime, - NULL); - if (endstr != NULL && dnskey_endtime == endtime) - fprintf(stderr, "WARNING: -e and -X were both set, " - "but have identical values.\n"); - } else - dnskey_endtime = endtime; - - if (cycle == -1) - cycle = (endtime - starttime) / 4; - - if (ntasks == 0) - ntasks = isc_os_ncpus() * 2; - vbprintf(4, "using %d cpus\n", ntasks); - - rdclass = strtoclass(classname); - - if (directory == NULL) - directory = "."; - - setup_logging(mctx, &log); - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc < 1) - usage(); - - file = argv[0]; - - argc -= 1; - argv += 1; - - if (origin == NULL) - origin = file; - - if (output == NULL) { - size_t size; - free_output = true; - size = strlen(file) + strlen(".signed") + 1; - output = isc_mem_allocate(mctx, size); - if (output == NULL) - fatal("out of memory"); - snprintf(output, size, "%s.signed", file); - } - - if (inputformatstr != NULL) { - if (strcasecmp(inputformatstr, "text") == 0) - inputformat = dns_masterformat_text; - else if (strcasecmp(inputformatstr, "map") == 0) - inputformat = dns_masterformat_map; - else if (strcasecmp(inputformatstr, "raw") == 0) - inputformat = dns_masterformat_raw; - else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { - inputformat = dns_masterformat_raw; - fprintf(stderr, - "WARNING: input format version ignored\n"); - } else - fatal("unknown file format: %s", inputformatstr); - - } - - if (outputformatstr != NULL) { - if (strcasecmp(outputformatstr, "text") == 0) { - outputformat = dns_masterformat_text; - } else if (strcasecmp(outputformatstr, "full") == 0) { - outputformat = dns_masterformat_text; - masterstyle = &dns_master_style_full; - } else if (strcasecmp(outputformatstr, "map") == 0) { - outputformat = dns_masterformat_map; - } else if (strcasecmp(outputformatstr, "raw") == 0) { - outputformat = dns_masterformat_raw; - } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { - char *end; - outputformat = dns_masterformat_raw; - - outputformat = dns_masterformat_raw; - rawversion = strtol(outputformatstr + 4, &end, 10); - if (end == outputformatstr + 4 || *end != '\0' || - rawversion > 1U) { - fprintf(stderr, - "unknown raw format version\n"); - exit(1); - } - } else - fatal("unknown file format: %s", outputformatstr); - } - - if (serialformatstr != NULL) { - if (strcasecmp(serialformatstr, "keep") == 0) - serialformat = SOA_SERIAL_KEEP; - else if (strcasecmp(serialformatstr, "increment") == 0 || - strcasecmp(serialformatstr, "incr") == 0) - serialformat = SOA_SERIAL_INCREMENT; - else if (strcasecmp(serialformatstr, "unixtime") == 0) - serialformat = SOA_SERIAL_UNIXTIME; - else if (strcasecmp(serialformatstr, "date") == 0) - serialformat = SOA_SERIAL_DATE; - else - fatal("unknown soa serial format: %s", - serialformatstr); - } - - if (output_dnssec_only && outputformat != dns_masterformat_text) - fatal("option -D can only be used with \"-O text\""); - - if (output_dnssec_only && serialformat != SOA_SERIAL_KEEP) - fatal("option -D can only be used with \"-N keep\""); - - if (output_dnssec_only && set_maxttl) - fatal("option -D cannot be used with -M"); - - result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, - 0, 24, 0, 0, 0, 8, mctx); - check_result(result, "dns_master_stylecreate"); - - gdb = NULL; - TIME_NOW(&timer_start); - loadzone(file, origin, rdclass, &gdb); - gorigin = dns_db_origin(gdb); - gclass = dns_db_class(gdb); - get_soa_ttls(); - - if (set_maxttl && set_keyttl && keyttl > maxttl) { - fprintf(stderr, "%s: warning: Specified key TTL %u " - "exceeds maximum zone TTL; reducing to %u\n", - program, keyttl, maxttl); - keyttl = maxttl; - } - - if (!set_keyttl) - keyttl = soa_ttl; - - /* - * Check for any existing NSEC3 parameters in the zone, - * and use them as defaults if -u was not specified. - */ - if (update_chain && !set_optout && !set_iter && !set_salt) - nsec_datatype = dns_rdatatype_nsec; - else - set_nsec3params(update_chain, set_salt, set_optout, set_iter); - - /* - * We need to do this early on, as we start messing with the list - * of keys rather early. - */ - ISC_LIST_INIT(keylist); - result = isc_rwlock_init(&keylist_lock, 0, 0); - if (result != ISC_R_SUCCESS) - fatal("could not initialize keylist_lock: %s", - isc_result_totext(result)); - - /* - * Fill keylist with: - * 1) Keys listed in the DNSKEY set that have - * private keys associated, *if* no keys were - * set on the command line. - * 2) ZSKs set on the command line - * 3) KSKs set on the command line - * 4) Any keys remaining in the DNSKEY set which - * do not have private keys associated and were - * not specified on the command line. - */ - if (argc == 0 || smartsign) - loadzonekeys(!smartsign, false); - loadexplicitkeys(argv, argc, false); - loadexplicitkeys(dskeyfile, ndskeys, true); - loadzonekeys(!smartsign, true); - - /* - * If we're doing smart signing, look in the key repository for - * key files with metadata, and merge them with the keylist - * we have now. - */ - if (smartsign) - build_final_keylist(); - - /* Now enumerate the key list */ - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - key->index = keycount++; - } - - if (keycount == 0) { - if (disable_zone_check) - fprintf(stderr, "%s: warning: No keys specified " - "or found\n", program); - else - fatal("No signing keys specified or found."); - nokeys = true; - } - - warnifallksk(gdb); - - if (IS_NSEC3) { - unsigned int max; - bool answer; - - hash_length = dns_nsec3_hashlength(dns_hash_sha1); - hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2, - hash_length); - result = dns_nsec_nseconly(gdb, gversion, &answer); - if (result == ISC_R_NOTFOUND) - fprintf(stderr, "%s: warning: NSEC3 generation " - "requested with no DNSKEY; ignoring\n", - program); - else if (result != ISC_R_SUCCESS) - check_result(result, "dns_nsec_nseconly"); - else if (answer) - fatal("NSEC3 generation requested with " - "NSEC-only DNSKEY"); - - result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max); - check_result(result, "dns_nsec3_maxiterations()"); - if (nsec3iter > max) - fatal("NSEC3 iterations too big for weakest DNSKEY " - "strength. Maximum iterations allowed %u.", max); - } else { - hashlist_init(&hashlist, 0, 0); /* silence clang */ - } - - gversion = NULL; - result = dns_db_newversion(gdb, &gversion); - check_result(result, "dns_db_newversion()"); - - switch (serialformat) { - case SOA_SERIAL_INCREMENT: - setsoaserial(0, dns_updatemethod_increment); - break; - case SOA_SERIAL_UNIXTIME: - setsoaserial(now, dns_updatemethod_unixtime); - break; - case SOA_SERIAL_DATE: - setsoaserial(now, dns_updatemethod_date); - break; - case SOA_SERIAL_KEEP: - default: - /* do nothing */ - break; - } - - /* Remove duplicates and cap TTLs at maxttl */ - cleanup_zone(); - - if (!nonsecify) { - if (IS_NSEC3) - nsec3ify(dns_hash_sha1, nsec3iter, gsalt, salt_length, - &hashlist); - else - nsecify(); - } - - if (!nokeys) { - writeset("dsset-", dns_rdatatype_ds); - if (make_keyset) - writeset("keyset-", dns_rdatatype_dnskey); - if (dlv != NULL) { - writeset("dlvset-", dns_rdatatype_dlv); - } - } - - if (output_stdout) { - outfp = stdout; - if (outputformatstr == NULL) - masterstyle = &dns_master_style_full; - } else { - tempfilelen = strlen(output) + 20; - tempfile = isc_mem_get(mctx, tempfilelen); - if (tempfile == NULL) - fatal("out of memory"); - - result = isc_file_mktemplate(output, tempfile, tempfilelen); - check_result(result, "isc_file_mktemplate"); - - if (outputformat == dns_masterformat_text) - result = isc_file_openunique(tempfile, &outfp); - else - result = isc_file_bopenunique(tempfile, &outfp); - if (result != ISC_R_SUCCESS) - fatal("failed to open temporary output file: %s", - isc_result_totext(result)); - removefile = true; - setfatalcallback(&removetempfile); - } - - print_time(outfp); - print_version(outfp); - - result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr); - if (result != ISC_R_SUCCESS) - fatal("failed to create task manager: %s", - isc_result_totext(result)); - - master = NULL; - result = isc_task_create(taskmgr, 0, &master); - if (result != ISC_R_SUCCESS) - fatal("failed to create task: %s", isc_result_totext(result)); - - tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); - if (tasks == NULL) - fatal("out of memory"); - for (i = 0; i < (int)ntasks; i++) { - tasks[i] = NULL; - result = isc_task_create(taskmgr, 0, &tasks[i]); - if (result != ISC_R_SUCCESS) - fatal("failed to create task: %s", - isc_result_totext(result)); - } - - RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS); - if (printstats) - RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS); - - presign(); - TIME_NOW(&sign_start); - signapex(); - if (!finished) { - /* - * There is more work to do. Spread it out over multiple - * processors if possible. - */ - for (i = 0; i < (int)ntasks; i++) { - result = isc_app_onrun(mctx, master, startworker, - tasks[i]); - if (result != ISC_R_SUCCESS) - fatal("failed to start task: %s", - isc_result_totext(result)); - } - (void)isc_app_run(); - if (!finished) - fatal("process aborted by user"); - } else - isc_task_detach(&master); - shuttingdown = true; - for (i = 0; i < (int)ntasks; i++) - isc_task_detach(&tasks[i]); - isc_taskmgr_destroy(&taskmgr); - isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); - postsign(); - TIME_NOW(&sign_finish); - - if (!disable_zone_check) - verifyzone(gdb, gversion, gorigin, mctx, - ignore_kskflag, keyset_kskonly); - - if (outputformat != dns_masterformat_text) { - dns_masterrawheader_t header; - dns_master_initrawheader(&header); - if (rawversion == 0U) - header.flags = DNS_MASTERRAW_COMPAT; - else if (snset) { - header.flags = DNS_MASTERRAW_SOURCESERIALSET; - header.sourceserial = serialnum; - } - result = dns_master_dumptostream3(mctx, gdb, gversion, - masterstyle, outputformat, - &header, outfp); - check_result(result, "dns_master_dumptostream3"); - } - - DESTROYLOCK(&namelock); - if (printstats) - DESTROYLOCK(&statslock); - - if (!output_stdout) { - result = isc_stdio_close(outfp); - check_result(result, "isc_stdio_close"); - removefile = false; - - result = isc_file_rename(tempfile, output); - if (result != ISC_R_SUCCESS) - fatal("failed to rename temp file to %s: %s", - output, isc_result_totext(result)); - - printf("%s\n", output); - } - - dns_db_closeversion(gdb, &gversion, false); - dns_db_detach(&gdb); - - hashlist_free(&hashlist); - - while (!ISC_LIST_EMPTY(keylist)) { - key = ISC_LIST_HEAD(keylist); - ISC_LIST_UNLINK(keylist, key, link); - dns_dnsseckey_destroy(mctx, &key); - } - - if (tempfilelen != 0) - isc_mem_put(mctx, tempfile, tempfilelen); - - if (free_output) - isc_mem_free(mctx, output); - - dns_master_styledestroy(&dsstyle, mctx); - - cleanup_logging(&log); - isc_hash_destroy(); - dst_lib_destroy(); - cleanup_entropy(&ectx); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - (void) isc_app_finish(); - - if (printstats) { - TIME_NOW(&timer_finish); - print_stats(&timer_start, &timer_finish, - &sign_start, &sign_finish); - } - -#ifdef _WIN32 - DestroySockets(); -#endif - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-signzone.docbook b/bin/dnssec-pkcs11/dnssec-signzone.docbook deleted file mode 100644 index f352e26..0000000 --- a/bin/dnssec-pkcs11/dnssec-signzone.docbook +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - 2014-02-18 - - - ISC - Internet Systems Consortium, Inc. - - - - dnssec-signzone - 8 - BIND9 - - - - dnssec-signzone - DNSSEC zone signing tool - - - - - 2000 - 2001 - 2002 - 2003 - 2004 - 2005 - 2006 - 2007 - 2008 - 2009 - 2011 - 2012 - 2013 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-signzone - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - zonefile - key - - - - DESCRIPTION - - dnssec-signzone - signs a zone. It generates - NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. - - - - OPTIONS - - - - - -a - - - Verify all generated signatures. - - - - - - -c class - - - Specifies the DNS class of the zone. - - - - - - -C - - - Compatibility mode: Generate a - keyset-zonename - file in addition to - dsset-zonename - when signing a zone, for use by older versions of - dnssec-signzone. - - - - - - -d directory - - - Look for dsset- or - keyset- files in . - - - - - - -D - - - Output only those record types automatically managed by - dnssec-signzone, i.e. RRSIG, NSEC, - NSEC3 and NSEC3PARAM records. If smart signing - () is used, DNSKEY records are also - included. The resulting file can be included in the original - zone file with $INCLUDE. This option - cannot be combined with , - , or serial number updating. - - - - - - -E engine - - - When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -g - - - Generate DS records for child zones from - dsset- or keyset- - file. Existing DS records will be removed. - - - - - - -K directory - - - Key repository: Specify a directory to search for DNSSEC keys. - If not specified, defaults to the current directory. - - - - - - -k key - - - Treat specified key as a key signing key ignoring any - key flags. This option may be specified multiple times. - - - - - - -l domain - - - Generate a DLV set in addition to the key (DNSKEY) and DS sets. - The domain is appended to the name of the records. - - - - - - -M maxttl - - - Sets the maximum TTL for the signed zone. - Any TTL higher than maxttl in the - input zone will be reduced to maxttl - in the output. This provides certainty as to the largest - possible TTL in the signed zone, which is useful to know when - rolling keys because it is the longest possible time before - signatures that have been retrieved by resolvers will expire - from resolver caches. Zones that are signed with this - option should be configured to use a matching - in named.conf. - (Note: This option is incompatible with , - because it modifies non-DNSSEC data in the output zone.) - - - - - - -s start-time - - - Specify the date and time when the generated RRSIG records - become valid. This can be either an absolute or relative - time. An absolute start time is indicated by a number - in YYYYMMDDHHMMSS notation; 20000530144500 denotes - 14:45:00 UTC on May 30th, 2000. A relative start time is - indicated by +N, which is N seconds from the current time. - If no is specified, the current - time minus 1 hour (to allow for clock skew) is used. - - - - - - -e end-time - - - Specify the date and time when the generated RRSIG records - expire. As with , an absolute - time is indicated in YYYYMMDDHHMMSS notation. A time relative - to the start time is indicated with +N, which is N seconds from - the start time. A time relative to the current time is - indicated with now+N. If no is - specified, 30 days from the start time is used as a default. - must be later than - . - - - - - - -X extended end-time - - - Specify the date and time when the generated RRSIG records - for the DNSKEY RRset will expire. This is to be used in cases - when the DNSKEY signatures need to persist longer than - signatures on other records; e.g., when the private component - of the KSK is kept offline and the KSK signature is to be - refreshed manually. - - - As with , an absolute - time is indicated in YYYYMMDDHHMMSS notation. A time relative - to the start time is indicated with +N, which is N seconds from - the start time. A time relative to the current time is - indicated with now+N. If no is - specified, the value of is used as - the default. (, in turn, defaults to - 30 days from the start time.) - must be later than . - - - - - - -f output-file - - - The name of the output file containing the signed zone. The - default is to append .signed to - the input filename. If is - set to "-", then the signed zone is - written to the standard output, with a default output - format of "full". - - - - - - -h - - - Prints a short summary of the options and arguments to - dnssec-signzone. - - - - - - -V - - - Prints version information. - - - - - - -i interval - - - When a previously-signed zone is passed as input, records - may be resigned. The option - specifies the cycle interval as an offset from the current - time (in seconds). If a RRSIG record expires after the - cycle interval, it is retained. Otherwise, it is considered - to be expiring soon, and it will be replaced. - - - The default cycle interval is one quarter of the difference - between the signature end and start times. So if neither - or - are specified, dnssec-signzone - generates - signatures that are valid for 30 days, with a cycle - interval of 7.5 days. Therefore, if any existing RRSIG records - are due to expire in less than 7.5 days, they would be - replaced. - - - - - - -I input-format - - - The format of the input zone file. - Possible formats are "text" (default), - "raw", and "map". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be signed directly. - The use of this option does not make much sense for - non-dynamic zones. - - - - - - -j jitter - - - When signing a zone with a fixed signature lifetime, all - RRSIG records issued at the time of signing expires - simultaneously. If the zone is incrementally signed, i.e. - a previously-signed zone is passed as input to the signer, - all expired signatures have to be regenerated at about the - same time. The option specifies a - jitter window that will be used to randomize the signature - expire time, thus spreading incremental signature - regeneration over time. - - - Signature lifetime jitter also to some extent benefits - validators and servers by spreading out cache expiration, - i.e. if large numbers of RRSIGs don't expire at the same time - from all caches there will be less congestion than if all - validators need to refetch at mostly the same time. - - - - - - -L serial - - - When writing a signed zone to "raw" or "map" format, set the - "source serial" value in the header to the specified serial - number. (This is expected to be used primarily for testing - purposes.) - - - - - - -n ncpus - - - Specifies the number of threads to use. By default, one - thread is started for each detected CPU. - - - - - - -N soa-serial-format - - - The SOA serial number format of the signed zone. - Possible formats are "keep" (default), - "increment", "unixtime", - and "date". - - - - - "keep" - - Do not modify the SOA serial number. - - - - - "increment" - - Increment the SOA serial number using RFC 1982 - arithmetics. - - - - - "unixtime" - - Set the SOA serial number to the number of seconds - since epoch. - - - - - "date" - - Set the SOA serial number to today's date in - YYYYMMDDNN format. - - - - - - - - - -o origin - - - The zone origin. If not specified, the name of the zone file - is assumed to be the origin. - - - - - - -O output-format - - - The format of the output file containing the signed zone. - Possible formats are "text" (default), - which is the standard textual representation of the zone; - "full", which is text output in a - format suitable for processing by external scripts; - and "map", "raw", - and "raw=N", which store the zone in - binary formats for rapid loading by named. - "raw=N" specifies the format version of - the raw zone file: if N is 0, the raw file can be read by - any version of named; if N is 1, the file - can be read by release 9.9.0 or higher; the default is 1. - - - - - - -p - - - Use pseudo-random data when signing the zone. This is faster, - but less secure, than using real random data. This option - may be useful when signing large zones or when the entropy - source is limited. - - - - - - -P - - - Disable post sign verification tests. - - - The post sign verification test ensures that for each algorithm - in use there is at least one non revoked self signed KSK key, - that all revoked KSK keys are self signed, and that all records - in the zone are signed by the algorithm. - This option skips these tests. - - - - - - -Q - - - Remove signatures from keys that are no longer active. - - - Normally, when a previously-signed zone is passed as input - to the signer, and a DNSKEY record has been removed and - replaced with a new one, signatures from the old key - that are still within their validity period are retained. - This allows the zone to continue to validate with cached - copies of the old DNSKEY RRset. The - forces dnssec-signzone to remove - signatures from keys that are no longer active. This - enables ZSK rollover using the procedure described in - RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover"). - - - - - -R - - - Remove signatures from keys that are no longer published. - - - This option is similar to , except it - forces dnssec-signzone to signatures from - keys that are no longer published. This enables ZSK rollover - using the procedure described in RFC 4641, section 4.2.1.2 - ("Double Signature Zone Signing Key Rollover"). - - - - - -r randomdev - - - Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. - - - - - - -S - - - Smart signing: Instructs dnssec-signzone to - search the key repository for keys that match the zone being - signed, and to include them in the zone if appropriate. - - - When a key is found, its timing metadata is examined to - determine how it should be used, according to the following - rules. Each successive rule takes priority over the prior - ones: - - - - - - If no timing metadata has been set for the key, the key is - published in the zone and used to sign the zone. - - - - - - - - If the key's publication date is set and is in the past, the - key is published in the zone. - - - - - - - - If the key's activation date is set and in the past, the - key is published (regardless of publication date) and - used to sign the zone. - - - - - - - - If the key's revocation date is set and in the past, and the - key is published, then the key is revoked, and the revoked key - is used to sign the zone. - - - - - - - - If either of the key's unpublication or deletion dates are set - and in the past, the key is NOT published or used to sign the - zone, regardless of any other metadata. - - - - - - - - - -T ttl - - - Specifies a TTL to be used for new DNSKEY records imported - into the zone from the key repository. If not - specified, the default is the TTL value from the zone's SOA - record. This option is ignored when signing without - , since DNSKEY records are not imported - from the key repository in that case. It is also ignored if - there are any pre-existing DNSKEY records at the zone apex, - in which case new records' TTL values will be set to match - them, or if any of the imported DNSKEY records had a default - TTL value. In the event of a a conflict between TTL values in - imported keys, the shortest one is used. - - - - - - -t - - - Print statistics at completion. - - - - - - -u - - - Update NSEC/NSEC3 chain when re-signing a previously signed - zone. With this option, a zone signed with NSEC can be - switched to NSEC3, or a zone signed with NSEC3 can - be switch to NSEC or to NSEC3 with different parameters. - Without this option, dnssec-signzone will - retain the existing chain when re-signing. - - - - - - -v level - - - Sets the debugging level. - - - - - - -x - - - Only sign the DNSKEY RRset with key-signing keys, and omit - signatures from zone-signing keys. (This is similar to the - dnssec-dnskey-kskonly yes; zone option in - named.) - - - - - - -z - - - Ignore KSK flag on key when determining what to sign. This - causes KSK-flagged keys to sign all records, not just the - DNSKEY RRset. (This is similar to the - update-check-ksk no; zone option in - named.) - - - - - - -3 salt - - - Generate an NSEC3 chain with the given hex encoded salt. - A dash (salt) can - be used to indicate that no salt is to be used when generating the NSEC3 chain. - - - - - - -H iterations - - - When generating an NSEC3 chain, use this many iterations. The - default is 10. - - - - - - -A - - - When generating an NSEC3 chain set the OPTOUT flag on all - NSEC3 records and do not generate NSEC3 records for insecure - delegations. - - - Using this option twice (i.e., ) - turns the OPTOUT flag off for all records. This is useful - when using the option to modify an NSEC3 - chain which previously had OPTOUT set. - - - - - - zonefile - - - The file containing the zone to be signed. - - - - - - key - - - Specify which keys should be used to sign the zone. If - no keys are specified, then the zone will be examined - for DNSKEY records at the zone apex. If these are found and - there are matching private keys, in the current directory, - then these will be used for signing. - - - - - - - - EXAMPLE - - - The following command signs the example.com - zone with the DSA key generated by dnssec-keygen - (Kexample.com.+003+17247). Because the -S option - is not being used, the zone's keys must be in the master file - (db.example.com). This invocation looks - for dsset files, in the current directory, - so that DS records can be imported from them (-g). - -% dnssec-signzone -g -o example.com db.example.com \ -Kexample.com.+003+17247 -db.example.com.signed -% - - In the above example, dnssec-signzone creates - the file db.example.com.signed. This - file should be referenced in a zone statement in a - named.conf file. - - - This example re-signs a previously signed zone with default parameters. - The private keys are assumed to be in the current directory. - -% cp db.example.com.signed db.example.com -% dnssec-signzone -o example.com db.example.com -db.example.com.signed -% - - - SEE ALSO - - - dnssec-keygen8 - , - BIND 9 Administrator Reference Manual, - RFC 4033, RFC 4641. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-signzone.html b/bin/dnssec-pkcs11/dnssec-signzone.html deleted file mode 100644 index 8b6ed1c..0000000 --- a/bin/dnssec-pkcs11/dnssec-signzone.html +++ /dev/null @@ -1,525 +0,0 @@ - - - - - -dnssec-signzone - - -
-
-
-

Name

-

dnssec-signzone — DNSSEC zone signing tool

-
-
-

Synopsis

-

dnssec-signzone [-a] [-c class] [-d directory] [-D] [-E engine] [-e end-time] [-f output-file] [-g] [-h] [-i interval] [-I input-format] [-j jitter] [-K directory] [-k key] [-L serial] [-l domain] [-M maxttl] [-N soa-serial-format] [-o origin] [-O output-format] [-P] [-p] [-Q] [-R] [-r randomdev] [-S] [-s start-time] [-T ttl] [-t] [-u] [-v level] [-V] [-X extended end-time] [-x] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

-
-
-

DESCRIPTION

-

dnssec-signzone - signs a zone. It generates - NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. -

-
-
-

OPTIONS

-
-
-a
-

- Verify all generated signatures. -

-
-c class
-

- Specifies the DNS class of the zone. -

-
-C
-

- Compatibility mode: Generate a - keyset-zonename - file in addition to - dsset-zonename - when signing a zone, for use by older versions of - dnssec-signzone. -

-
-d directory
-

- Look for dsset- or - keyset- files in directory. -

-
-D
-

- Output only those record types automatically managed by - dnssec-signzone, i.e. RRSIG, NSEC, - NSEC3 and NSEC3PARAM records. If smart signing - (-S) is used, DNSKEY records are also - included. The resulting file can be included in the original - zone file with $INCLUDE. This option - cannot be combined with -O raw, - -O map, or serial number updating. -

-
-E engine
-
-

- When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-g
-

- Generate DS records for child zones from - dsset- or keyset- - file. Existing DS records will be removed. -

-
-K directory
-

- Key repository: Specify a directory to search for DNSSEC keys. - If not specified, defaults to the current directory. -

-
-k key
-

- Treat specified key as a key signing key ignoring any - key flags. This option may be specified multiple times. -

-
-l domain
-

- Generate a DLV set in addition to the key (DNSKEY) and DS sets. - The domain is appended to the name of the records. -

-
-M maxttl
-

- Sets the maximum TTL for the signed zone. - Any TTL higher than maxttl in the - input zone will be reduced to maxttl - in the output. This provides certainty as to the largest - possible TTL in the signed zone, which is useful to know when - rolling keys because it is the longest possible time before - signatures that have been retrieved by resolvers will expire - from resolver caches. Zones that are signed with this - option should be configured to use a matching - max-zone-ttl in named.conf. - (Note: This option is incompatible with -D, - because it modifies non-DNSSEC data in the output zone.) -

-
-s start-time
-

- Specify the date and time when the generated RRSIG records - become valid. This can be either an absolute or relative - time. An absolute start time is indicated by a number - in YYYYMMDDHHMMSS notation; 20000530144500 denotes - 14:45:00 UTC on May 30th, 2000. A relative start time is - indicated by +N, which is N seconds from the current time. - If no start-time is specified, the current - time minus 1 hour (to allow for clock skew) is used. -

-
-e end-time
-

- Specify the date and time when the generated RRSIG records - expire. As with start-time, an absolute - time is indicated in YYYYMMDDHHMMSS notation. A time relative - to the start time is indicated with +N, which is N seconds from - the start time. A time relative to the current time is - indicated with now+N. If no end-time is - specified, 30 days from the start time is used as a default. - end-time must be later than - start-time. -

-
-X extended end-time
-
-

- Specify the date and time when the generated RRSIG records - for the DNSKEY RRset will expire. This is to be used in cases - when the DNSKEY signatures need to persist longer than - signatures on other records; e.g., when the private component - of the KSK is kept offline and the KSK signature is to be - refreshed manually. -

-

- As with start-time, an absolute - time is indicated in YYYYMMDDHHMMSS notation. A time relative - to the start time is indicated with +N, which is N seconds from - the start time. A time relative to the current time is - indicated with now+N. If no extended end-time is - specified, the value of end-time is used as - the default. (end-time, in turn, defaults to - 30 days from the start time.) extended end-time - must be later than start-time. -

-
-
-f output-file
-

- The name of the output file containing the signed zone. The - default is to append .signed to - the input filename. If output-file is - set to "-", then the signed zone is - written to the standard output, with a default output - format of "full". -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-signzone. -

-
-V
-

- Prints version information. -

-
-i interval
-
-

- When a previously-signed zone is passed as input, records - may be resigned. The interval option - specifies the cycle interval as an offset from the current - time (in seconds). If a RRSIG record expires after the - cycle interval, it is retained. Otherwise, it is considered - to be expiring soon, and it will be replaced. -

-

- The default cycle interval is one quarter of the difference - between the signature end and start times. So if neither - end-time or start-time - are specified, dnssec-signzone - generates - signatures that are valid for 30 days, with a cycle - interval of 7.5 days. Therefore, if any existing RRSIG records - are due to expire in less than 7.5 days, they would be - replaced. -

-
-
-I input-format
-

- The format of the input zone file. - Possible formats are "text" (default), - "raw", and "map". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be signed directly. - The use of this option does not make much sense for - non-dynamic zones. -

-
-j jitter
-
-

- When signing a zone with a fixed signature lifetime, all - RRSIG records issued at the time of signing expires - simultaneously. If the zone is incrementally signed, i.e. - a previously-signed zone is passed as input to the signer, - all expired signatures have to be regenerated at about the - same time. The jitter option specifies a - jitter window that will be used to randomize the signature - expire time, thus spreading incremental signature - regeneration over time. -

-

- Signature lifetime jitter also to some extent benefits - validators and servers by spreading out cache expiration, - i.e. if large numbers of RRSIGs don't expire at the same time - from all caches there will be less congestion than if all - validators need to refetch at mostly the same time. -

-
-
-L serial
-

- When writing a signed zone to "raw" or "map" format, set the - "source serial" value in the header to the specified serial - number. (This is expected to be used primarily for testing - purposes.) -

-
-n ncpus
-

- Specifies the number of threads to use. By default, one - thread is started for each detected CPU. -

-
-N soa-serial-format
-
-

- The SOA serial number format of the signed zone. - Possible formats are "keep" (default), - "increment", "unixtime", - and "date". -

-
-
"keep"
-

Do not modify the SOA serial number.

-
"increment"
-

Increment the SOA serial number using RFC 1982 - arithmetics.

-
"unixtime"
-

Set the SOA serial number to the number of seconds - since epoch.

-
"date"
-

Set the SOA serial number to today's date in - YYYYMMDDNN format.

-
-
-
-o origin
-

- The zone origin. If not specified, the name of the zone file - is assumed to be the origin. -

-
-O output-format
-

- The format of the output file containing the signed zone. - Possible formats are "text" (default), - which is the standard textual representation of the zone; - "full", which is text output in a - format suitable for processing by external scripts; - and "map", "raw", - and "raw=N", which store the zone in - binary formats for rapid loading by named. - "raw=N" specifies the format version of - the raw zone file: if N is 0, the raw file can be read by - any version of named; if N is 1, the file - can be read by release 9.9.0 or higher; the default is 1. -

-
-p
-

- Use pseudo-random data when signing the zone. This is faster, - but less secure, than using real random data. This option - may be useful when signing large zones or when the entropy - source is limited. -

-
-P
-
-

- Disable post sign verification tests. -

-

- The post sign verification test ensures that for each algorithm - in use there is at least one non revoked self signed KSK key, - that all revoked KSK keys are self signed, and that all records - in the zone are signed by the algorithm. - This option skips these tests. -

-
-
-Q
-
-

- Remove signatures from keys that are no longer active. -

-

- Normally, when a previously-signed zone is passed as input - to the signer, and a DNSKEY record has been removed and - replaced with a new one, signatures from the old key - that are still within their validity period are retained. - This allows the zone to continue to validate with cached - copies of the old DNSKEY RRset. The -Q - forces dnssec-signzone to remove - signatures from keys that are no longer active. This - enables ZSK rollover using the procedure described in - RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover"). -

-
-
-R
-
-

- Remove signatures from keys that are no longer published. -

-

- This option is similar to -Q, except it - forces dnssec-signzone to signatures from - keys that are no longer published. This enables ZSK rollover - using the procedure described in RFC 4641, section 4.2.1.2 - ("Double Signature Zone Signing Key Rollover"). -

-
-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-S
-
-

- Smart signing: Instructs dnssec-signzone to - search the key repository for keys that match the zone being - signed, and to include them in the zone if appropriate. -

-

- When a key is found, its timing metadata is examined to - determine how it should be used, according to the following - rules. Each successive rule takes priority over the prior - ones: -

-
-
-

- If no timing metadata has been set for the key, the key is - published in the zone and used to sign the zone. -

-
-

- If the key's publication date is set and is in the past, the - key is published in the zone. -

-
-

- If the key's activation date is set and in the past, the - key is published (regardless of publication date) and - used to sign the zone. -

-
-

- If the key's revocation date is set and in the past, and the - key is published, then the key is revoked, and the revoked key - is used to sign the zone. -

-
-

- If either of the key's unpublication or deletion dates are set - and in the past, the key is NOT published or used to sign the - zone, regardless of any other metadata. -

-
-
-
-T ttl
-

- Specifies a TTL to be used for new DNSKEY records imported - into the zone from the key repository. If not - specified, the default is the TTL value from the zone's SOA - record. This option is ignored when signing without - -S, since DNSKEY records are not imported - from the key repository in that case. It is also ignored if - there are any pre-existing DNSKEY records at the zone apex, - in which case new records' TTL values will be set to match - them, or if any of the imported DNSKEY records had a default - TTL value. In the event of a a conflict between TTL values in - imported keys, the shortest one is used. -

-
-t
-

- Print statistics at completion. -

-
-u
-

- Update NSEC/NSEC3 chain when re-signing a previously signed - zone. With this option, a zone signed with NSEC can be - switched to NSEC3, or a zone signed with NSEC3 can - be switch to NSEC or to NSEC3 with different parameters. - Without this option, dnssec-signzone will - retain the existing chain when re-signing. -

-
-v level
-

- Sets the debugging level. -

-
-x
-

- Only sign the DNSKEY RRset with key-signing keys, and omit - signatures from zone-signing keys. (This is similar to the - dnssec-dnskey-kskonly yes; zone option in - named.) -

-
-z
-

- Ignore KSK flag on key when determining what to sign. This - causes KSK-flagged keys to sign all records, not just the - DNSKEY RRset. (This is similar to the - update-check-ksk no; zone option in - named.) -

-
-3 salt
-

- Generate an NSEC3 chain with the given hex encoded salt. - A dash (salt) can - be used to indicate that no salt is to be used when generating the NSEC3 chain. -

-
-H iterations
-

- When generating an NSEC3 chain, use this many iterations. The - default is 10. -

-
-A
-
-

- When generating an NSEC3 chain set the OPTOUT flag on all - NSEC3 records and do not generate NSEC3 records for insecure - delegations. -

-

- Using this option twice (i.e., -AA) - turns the OPTOUT flag off for all records. This is useful - when using the -u option to modify an NSEC3 - chain which previously had OPTOUT set. -

-
-
zonefile
-

- The file containing the zone to be signed. -

-
key
-

- Specify which keys should be used to sign the zone. If - no keys are specified, then the zone will be examined - for DNSKEY records at the zone apex. If these are found and - there are matching private keys, in the current directory, - then these will be used for signing. -

-
-
-
-

EXAMPLE

-

- The following command signs the example.com - zone with the DSA key generated by dnssec-keygen - (Kexample.com.+003+17247). Because the -S option - is not being used, the zone's keys must be in the master file - (db.example.com). This invocation looks - for dsset files, in the current directory, - so that DS records can be imported from them (-g). -

-
% dnssec-signzone -g -o example.com db.example.com \
-Kexample.com.+003+17247
-db.example.com.signed
-%
-

- In the above example, dnssec-signzone creates - the file db.example.com.signed. This - file should be referenced in a zone statement in a - named.conf file. -

-

- This example re-signs a previously signed zone with default parameters. - The private keys are assumed to be in the current directory. -

-
% cp db.example.com.signed db.example.com
-% dnssec-signzone -o example.com db.example.com
-db.example.com.signed
-%
-
-
-

SEE ALSO

-

dnssec-keygen(8), - BIND 9 Administrator Reference Manual, - RFC 4033, RFC 4641. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssec-verify.8 b/bin/dnssec-pkcs11/dnssec-verify.8 deleted file mode 100644 index 5fef4e6..0000000 --- a/bin/dnssec-pkcs11/dnssec-verify.8 +++ /dev/null @@ -1,117 +0,0 @@ -.\" Copyright (C) 2012, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: dnssec-verify -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2014-01-15 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "DNSSEC\-VERIFY" "8" "2014\-01\-15" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -dnssec-verify \- DNSSEC zone verification tool -.SH "SYNOPSIS" -.HP \w'\fBdnssec\-verify\fR\ 'u -\fBdnssec\-verify\fR [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-x\fR] [\fB\-z\fR] {zonefile} -.SH "DESCRIPTION" -.PP -\fBdnssec\-verify\fR -verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete\&. -.SH "OPTIONS" -.PP -\-c \fIclass\fR -.RS 4 -Specifies the DNS class of the zone\&. -.RE -.PP -\-E \fIengine\fR -.RS 4 -Specifies the cryptographic hardware to use, when applicable\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-I \fIinput\-format\fR -.RS 4 -The format of the input zone file\&. Possible formats are -\fB"text"\fR -(default) and -\fB"raw"\fR\&. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be verified independently\&. The use of this option does not make much sense for non\-dynamic zones\&. -.RE -.PP -\-o \fIorigin\fR -.RS 4 -The zone origin\&. If not specified, the name of the zone file is assumed to be the origin\&. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level\&. -.RE -.PP -\-V -.RS 4 -Prints version information\&. -.RE -.PP -\-x -.RS 4 -Only verify that the DNSKEY RRset is signed with key\-signing keys\&. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys\&. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone\-signing keys\&. This corresponds to the -\fB\-x\fR -option in -\fBdnssec\-signzone\fR\&. -.RE -.PP -\-z -.RS 4 -Ignore the KSK flag on the keys when determining whether the zone if correctly signed\&. Without this flag it is assumed that there will be a non\-revoked, self\-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set\&. -.sp -With this flag set, we only require that for each algorithm, there will be at least one non\-revoked, self\-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non\-revoked key for the same algorithm that includes the self\-signed key; the same key may be used for both purposes\&. This corresponds to the -\fB\-z\fR -option in -\fBdnssec\-signzone\fR\&. -.RE -.PP -zonefile -.RS 4 -The file containing the zone to be signed\&. -.RE -.SH "SEE ALSO" -.PP -\fBdnssec-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 4033\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2012, 2014-2016, 2018-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/dnssec-pkcs11/dnssec-verify.c b/bin/dnssec-pkcs11/dnssec-verify.c deleted file mode 100644 index 07c7294..0000000 --- a/bin/dnssec-pkcs11/dnssec-verify.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef PKCS11CRYPTO -#include -#endif - -#include "dnssectool.h" - -const char *program = "dnssec-verify"; -int verbose; - -static isc_stdtime_t now; -static isc_mem_t *mctx = NULL; -static isc_entropy_t *ectx = NULL; -static dns_masterformat_t inputformat = dns_masterformat_text; -static dns_db_t *gdb; /* The database */ -static dns_dbversion_t *gversion; /* The database version */ -static dns_rdataclass_t gclass; /* The class */ -static dns_name_t *gorigin; /* The database origin */ -static bool ignore_kskflag = false; -static bool keyset_kskonly = false; - -/*% - * Load the zone file from disk - */ -static void -loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { - isc_buffer_t b; - int len; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - len = strlen(origin); - isc_buffer_init(&b, origin, len); - isc_buffer_add(&b, len); - - name = dns_fixedname_initname(&fname); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed converting name '%s' to dns format: %s", - origin, isc_result_totext(result)); - - result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, - rdclass, 0, NULL, db); - check_result(result, "dns_db_create()"); - - result = dns_db_load2(*db, file, inputformat); - switch (result) { - case DNS_R_SEENINCLUDE: - case ISC_R_SUCCESS: - break; - case DNS_R_NOTZONETOP: - /* - * Comparing pointers (vs. using strcmp()) is intentional: we - * want to check whether -o was supplied on the command line, - * not whether origin and file contain the same string. - */ - if (origin == file) { - fatal("failed loading zone '%s' from file '%s': " - "use -o to specify a different zone origin", - origin, file); - } - /* FALLTHROUGH */ - default: - fatal("failed loading zone from '%s': %s", - file, isc_result_totext(result)); - } -} - -ISC_PLATFORM_NORETURN_PRE static void -usage(void) ISC_PLATFORM_NORETURN_POST; - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); - - fprintf(stderr, "\n"); - - fprintf(stderr, "Version: %s\n", VERSION); - - fprintf(stderr, "Options: (default value in parenthesis) \n"); - fprintf(stderr, "\t-v debuglevel (0)\n"); - fprintf(stderr, "\t-V:\tprint version information\n"); - fprintf(stderr, "\t-o origin:\n"); - fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); - fprintf(stderr, "\t-I format:\n"); - fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); - fprintf(stderr, "\t-c class (IN)\n"); - fprintf(stderr, "\t-E engine:\n"); -#if defined(PKCS11CRYPTO) - fprintf(stderr, "\t\tpath to PKCS#11 provider library " - "(default is %s)\n", PK11_LIB_LOCATION); -#elif defined(USE_PKCS11) - fprintf(stderr, "\t\tname of an OpenSSL engine to use " - "(default is \"pkcs11\")\n"); -#else - fprintf(stderr, "\t\tname of an OpenSSL engine to use\n"); -#endif - fprintf(stderr, "\t-x:\tDNSKEY record signed with KSKs only, " - "not ZSKs\n"); - fprintf(stderr, "\t-z:\tAll records signed with KSKs\n"); - exit(0); -} - -int -main(int argc, char *argv[]) { - char *origin = NULL, *file = NULL; - char *inputformatstr = NULL; - isc_result_t result; - isc_log_t *log = NULL; -#ifdef USE_PKCS11 - const char *engine = PKCS11_ENGINE; -#else - const char *engine = NULL; -#endif - char *classname = NULL; - dns_rdataclass_t rdclass; - char *endp; - int ch; - -#define CMDLINE_FLAGS \ - "hm:o:I:c:E:v:Vxz" - - /* - * Process memory debugging argument first. - */ - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'm': - if (strcasecmp(isc_commandline_argument, "record") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - if (strcasecmp(isc_commandline_argument, "trace") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGTRACE; - if (strcasecmp(isc_commandline_argument, "usage") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; - if (strcasecmp(isc_commandline_argument, "size") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGSIZE; - if (strcasecmp(isc_commandline_argument, "mctx") == 0) - isc_mem_debugging |= ISC_MEM_DEBUGCTX; - break; - default: - break; - } - } - isc_commandline_reset = true; - check_result(isc_app_start(), "isc_app_start"); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("out of memory"); - -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - dns_result_register(); - - isc_commandline_errprint = false; - - while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { - switch (ch) { - case 'c': - classname = isc_commandline_argument; - break; - - case 'E': - engine = isc_commandline_argument; - break; - - case 'I': - inputformatstr = isc_commandline_argument; - break; - - case 'm': - break; - - case 'o': - origin = isc_commandline_argument; - break; - - case 'v': - endp = NULL; - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("verbose level must be numeric"); - break; - - case 'x': - keyset_kskonly = true; - break; - - case 'z': - ignore_kskflag = true; - break; - - case '?': - if (isc_commandline_option != '?') - fprintf(stderr, "%s: invalid argument -%c\n", - program, isc_commandline_option); - /* FALLTHROUGH */ - - case 'h': - /* Does not return. */ - usage(); - - case 'V': - /* Does not return. */ - version(program); - - default: - fprintf(stderr, "%s: unhandled option -%c\n", - program, isc_commandline_option); - exit(1); - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - - result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(result)); - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not create hash context"); - - isc_stdtime_get(&now); - - rdclass = strtoclass(classname); - - setup_logging(mctx, &log); - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc < 1) - usage(); - - file = argv[0]; - - argc -= 1; - argv += 1; - - POST(argc); - POST(argv); - - if (origin == NULL) - origin = file; - - if (inputformatstr != NULL) { - if (strcasecmp(inputformatstr, "text") == 0) - inputformat = dns_masterformat_text; - else if (strcasecmp(inputformatstr, "raw") == 0) - inputformat = dns_masterformat_raw; - else - fatal("unknown file format: %s\n", inputformatstr); - } - - gdb = NULL; - fprintf(stderr, "Loading zone '%s' from file '%s'\n", origin, file); - loadzone(file, origin, rdclass, &gdb); - gorigin = dns_db_origin(gdb); - gclass = dns_db_class(gdb); - - gversion = NULL; - result = dns_db_newversion(gdb, &gversion); - check_result(result, "dns_db_newversion()"); - - verifyzone(gdb, gversion, gorigin, mctx, - ignore_kskflag, keyset_kskonly); - - dns_db_closeversion(gdb, &gversion, false); - dns_db_detach(&gdb); - - cleanup_logging(&log); - dst_lib_destroy(); - isc_hash_destroy(); - cleanup_entropy(&ectx); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - (void) isc_app_finish(); - - return (0); -} diff --git a/bin/dnssec-pkcs11/dnssec-verify.docbook b/bin/dnssec-pkcs11/dnssec-verify.docbook deleted file mode 100644 index 6b41233..0000000 --- a/bin/dnssec-pkcs11/dnssec-verify.docbook +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - 2014-01-15 - - - ISC - Internet Systems Consortium, Inc. - - - - dnssec-verify - 8 - BIND9 - - - - dnssec-verify - DNSSEC zone verification tool - - - - - 2012 - 2014 - 2015 - 2016 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - dnssec-verify - - - - - - - - - zonefile - - - - DESCRIPTION - - dnssec-verify - verifies that a zone is fully signed for each algorithm found - in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 - chains are complete. - - - - OPTIONS - - - - - -c class - - - Specifies the DNS class of the zone. - - - - - - -E engine - - - Specifies the cryptographic hardware to use, when applicable. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -I input-format - - - The format of the input zone file. - Possible formats are "text" (default) - and "raw". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be verified independently. - The use of this option does not make much sense for - non-dynamic zones. - - - - - - -o origin - - - The zone origin. If not specified, the name of the zone file - is assumed to be the origin. - - - - - - -v level - - - Sets the debugging level. - - - - - - -V - - - Prints version information. - - - - - - -x - - - Only verify that the DNSKEY RRset is signed with key-signing - keys. Without this flag, it is assumed that the DNSKEY RRset - will be signed by all active keys. When this flag is set, - it will not be an error if the DNSKEY RRset is not signed - by zone-signing keys. This corresponds to the - option in dnssec-signzone. - - - - - - -z - - - Ignore the KSK flag on the keys when determining whether - the zone if correctly signed. Without this flag it is - assumed that there will be a non-revoked, self-signed - DNSKEY with the KSK flag set for each algorithm and - that RRsets other than DNSKEY RRset will be signed with - a different DNSKEY without the KSK flag set. - - - With this flag set, we only require that for each algorithm, - there will be at least one non-revoked, self-signed DNSKEY, - regardless of the KSK flag state, and that other RRsets - will be signed by a non-revoked key for the same algorithm - that includes the self-signed key; the same key may be used - for both purposes. This corresponds to the - option in dnssec-signzone. - - - - - - zonefile - - - The file containing the zone to be signed. - - - - - - - - SEE ALSO - - - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 4033. - - - - diff --git a/bin/dnssec-pkcs11/dnssec-verify.html b/bin/dnssec-pkcs11/dnssec-verify.html deleted file mode 100644 index 78d4121..0000000 --- a/bin/dnssec-pkcs11/dnssec-verify.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - -dnssec-verify - - -
-
-
-

Name

-

dnssec-verify — DNSSEC zone verification tool

-
-
-

Synopsis

-

dnssec-verify [-c class] [-E engine] [-I input-format] [-o origin] [-v level] [-V] [-x] [-z] {zonefile}

-
-
-

DESCRIPTION

-

dnssec-verify - verifies that a zone is fully signed for each algorithm found - in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 - chains are complete. -

-
-
-

OPTIONS

-
-
-c class
-

- Specifies the DNS class of the zone. -

-
-E engine
-
-

- Specifies the cryptographic hardware to use, when applicable. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-I input-format
-

- The format of the input zone file. - Possible formats are "text" (default) - and "raw". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be verified independently. - The use of this option does not make much sense for - non-dynamic zones. -

-
-o origin
-

- The zone origin. If not specified, the name of the zone file - is assumed to be the origin. -

-
-v level
-

- Sets the debugging level. -

-
-V
-

- Prints version information. -

-
-x
-

- Only verify that the DNSKEY RRset is signed with key-signing - keys. Without this flag, it is assumed that the DNSKEY RRset - will be signed by all active keys. When this flag is set, - it will not be an error if the DNSKEY RRset is not signed - by zone-signing keys. This corresponds to the -x - option in dnssec-signzone. -

-
-z
-
-

- Ignore the KSK flag on the keys when determining whether - the zone if correctly signed. Without this flag it is - assumed that there will be a non-revoked, self-signed - DNSKEY with the KSK flag set for each algorithm and - that RRsets other than DNSKEY RRset will be signed with - a different DNSKEY without the KSK flag set. -

-

- With this flag set, we only require that for each algorithm, - there will be at least one non-revoked, self-signed DNSKEY, - regardless of the KSK flag state, and that other RRsets - will be signed by a non-revoked key for the same algorithm - that includes the self-signed key; the same key may be used - for both purposes. This corresponds to the -z - option in dnssec-signzone. -

-
-
zonefile
-

- The file containing the zone to be signed. -

-
-
-
-

SEE ALSO

-

- dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 4033. -

-
-
- diff --git a/bin/dnssec-pkcs11/dnssectool.c b/bin/dnssec-pkcs11/dnssectool.c deleted file mode 100644 index 6fcd411..0000000 --- a/bin/dnssec-pkcs11/dnssectool.c +++ /dev/null @@ -1,1965 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -/*% - * DNSSEC Support Routines. - */ - -#include - -#include -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dnssectool.h" - -static isc_heap_t *expected_chains, *found_chains; - -struct nsec3_chain_fixed { - uint8_t hash; - uint8_t salt_length; - uint8_t next_length; - uint16_t iterations; - /* unsigned char salt[0]; */ - /* unsigned char owner[0]; */ - /* unsigned char next[0]; */ -}; - -extern int verbose; -extern const char *program; - -typedef struct entropysource entropysource_t; - -struct entropysource { - isc_entropysource_t *source; - isc_mem_t *mctx; - ISC_LINK(entropysource_t) link; -}; - -static ISC_LIST(entropysource_t) sources; -static fatalcallback_t *fatalcallback = NULL; - -void -fatal(const char *format, ...) { - va_list args; - - fprintf(stderr, "%s: fatal: ", program); - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - if (fatalcallback != NULL) - (*fatalcallback)(); - exit(1); -} - -void -setfatalcallback(fatalcallback_t *callback) { - fatalcallback = callback; -} - -void -check_result(isc_result_t result, const char *message) { - if (result != ISC_R_SUCCESS) - fatal("%s: %s", message, isc_result_totext(result)); -} - -void -vbprintf(int level, const char *fmt, ...) { - va_list ap; - if (level > verbose) - return; - va_start(ap, fmt); - fprintf(stderr, "%s: ", program); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -void -version(const char *name) { - fprintf(stderr, "%s %s\n", name, VERSION); - exit(0); -} - -void -type_format(const dns_rdatatype_t type, char *cp, unsigned int size) { - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - isc_buffer_init(&b, cp, size - 1); - result = dns_rdatatype_totext(type, &b); - check_result(result, "dns_rdatatype_totext()"); - isc_buffer_usedregion(&b, &r); - r.base[r.length] = 0; -} - -void -sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_NAME_FORMATSIZE]; - - dns_name_format(&sig->signer, namestr, sizeof(namestr)); - dns_secalg_format(sig->algorithm, algstr, sizeof(algstr)); - snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid); -} - -void -setup_logging(isc_mem_t *mctx, isc_log_t **logp) { - isc_result_t result; - isc_logdestination_t destination; - isc_logconfig_t *logconfig = NULL; - isc_log_t *log = NULL; - int level; - - if (verbose < 0) - verbose = 0; - switch (verbose) { - case 0: - /* - * We want to see warnings about things like out-of-zone - * data in the master file even when not verbose. - */ - level = ISC_LOG_WARNING; - break; - case 1: - level = ISC_LOG_INFO; - break; - default: - level = ISC_LOG_DEBUG(verbose - 2 + 1); - break; - } - - RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); - isc_log_setcontext(log); - dns_log_init(log); - dns_log_setcontext(log); - - RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS); - - /* - * Set up a channel similar to default_stderr except: - * - the logging level is passed in - * - the program name and logging level are printed - * - no time stamp is printed - */ - destination.file.stream = stderr; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - level, - &destination, - ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL); - check_result(result, "isc_log_createchannel()"); - - RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", - NULL, NULL) == ISC_R_SUCCESS); - - *logp = log; -} - -void -cleanup_logging(isc_log_t **logp) { - isc_log_t *log; - - REQUIRE(logp != NULL); - - log = *logp; - *logp = NULL; - - if (log == NULL) - return; - - isc_log_destroy(&log); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); -} - -void -setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { - isc_result_t result; - isc_entropysource_t *source = NULL; - entropysource_t *elt; - int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; - - REQUIRE(ectx != NULL); - - if (*ectx == NULL) { - result = isc_entropy_create(mctx, ectx); - if (result != ISC_R_SUCCESS) - fatal("could not create entropy object: %s", - isc_result_totext(result)); - ISC_LIST_INIT(sources); - } - -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(*ectx, true); - } -#endif - if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { - usekeyboard = ISC_ENTROPY_KEYBOARDYES; - randomfile = NULL; - } - - result = isc_entropy_usebestsource(*ectx, &source, randomfile, - usekeyboard); - - if (result != ISC_R_SUCCESS) - fatal("could not initialize entropy source: %s", - isc_result_totext(result)); - - if (source != NULL) { - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - fatal("out of memory"); - elt->source = source; - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - ISC_LIST_APPEND(sources, elt, link); - } -} - -void -cleanup_entropy(isc_entropy_t **ectx) { - entropysource_t *source; - while (!ISC_LIST_EMPTY(sources)) { - source = ISC_LIST_HEAD(sources); - ISC_LIST_UNLINK(sources, source, link); - isc_entropy_destroysource(&source->source); - isc_mem_put(source->mctx, source, sizeof(*source)); - } - isc_entropy_detach(ectx); -} - -static isc_stdtime_t -time_units(isc_stdtime_t offset, char *suffix, const char *str) { - switch (suffix[0]) { - case 'Y': case 'y': - return (offset * (365 * 24 * 3600)); - case 'M': case 'm': - switch (suffix[1]) { - case 'O': case 'o': - return (offset * (30 * 24 * 3600)); - case 'I': case 'i': - return (offset * 60); - case '\0': - fatal("'%s' ambiguous: use 'mi' for minutes " - "or 'mo' for months", str); - default: - fatal("time value %s is invalid", str); - } - /* NOTREACHED */ - break; - case 'W': case 'w': - return (offset * (7 * 24 * 3600)); - case 'D': case 'd': - return (offset * (24 * 3600)); - case 'H': case 'h': - return (offset * 3600); - case 'S': case 's': case '\0': - return (offset); - default: - fatal("time value %s is invalid", str); - } - /* NOTREACHED */ - return(0); /* silence compiler warning */ -} - -static inline bool -isnone(const char *str) { - return ((strcasecmp(str, "none") == 0) || - (strcasecmp(str, "never") == 0)); -} - -dns_ttl_t -strtottl(const char *str) { - const char *orig = str; - dns_ttl_t ttl; - char *endp; - - if (isnone(str)) - return ((dns_ttl_t) 0); - - ttl = strtol(str, &endp, 0); - if (ttl == 0 && endp == str) - fatal("TTL must be numeric"); - ttl = time_units(ttl, endp, orig); - return (ttl); -} - -isc_stdtime_t -strtotime(const char *str, int64_t now, int64_t base, - bool *setp) -{ - int64_t val, offset; - isc_result_t result; - const char *orig = str; - char *endp; - size_t n; - - if (isnone(str)) { - if (setp != NULL) - *setp = false; - return ((isc_stdtime_t) 0); - } - - if (setp != NULL) - *setp = true; - - if ((str[0] == '0' || str[0] == '-') && str[1] == '\0') - return ((isc_stdtime_t) 0); - - /* - * We accept times in the following formats: - * now([+-]offset) - * YYYYMMDD([+-]offset) - * YYYYMMDDhhmmss([+-]offset) - * [+-]offset - */ - n = strspn(str, "0123456789"); - if ((n == 8u || n == 14u) && - (str[n] == '\0' || str[n] == '-' || str[n] == '+')) - { - char timestr[15]; - - strlcpy(timestr, str, sizeof(timestr)); - timestr[n] = 0; - if (n == 8u) - strlcat(timestr, "000000", sizeof(timestr)); - result = dns_time64_fromtext(timestr, &val); - if (result != ISC_R_SUCCESS) - fatal("time value %s is invalid: %s", orig, - isc_result_totext(result)); - base = val; - str += n; - } else if (strncmp(str, "now", 3) == 0) { - base = now; - str += 3; - } - - if (str[0] == '\0') - return ((isc_stdtime_t) base); - else if (str[0] == '+') { - offset = strtol(str + 1, &endp, 0); - offset = time_units((isc_stdtime_t) offset, endp, orig); - val = base + offset; - } else if (str[0] == '-') { - offset = strtol(str + 1, &endp, 0); - offset = time_units((isc_stdtime_t) offset, endp, orig); - val = base - offset; - } else - fatal("time value %s is invalid", orig); - - return ((isc_stdtime_t) val); -} - -dns_rdataclass_t -strtoclass(const char *str) { - isc_textregion_t r; - dns_rdataclass_t rdclass; - isc_result_t ret; - - if (str == NULL) - return dns_rdataclass_in; - DE_CONST(str, r.base); - r.length = strlen(str); - ret = dns_rdataclass_fromtext(&rdclass, &r); - if (ret != ISC_R_SUCCESS) - fatal("unknown class %s", str); - return (rdclass); -} - -isc_result_t -try_dir(const char *dirname) { - isc_result_t result; - isc_dir_t d; - - isc_dir_init(&d); - result = isc_dir_open(&d, dirname); - if (result == ISC_R_SUCCESS) { - isc_dir_close(&d); - } - return (result); -} - -/* - * Check private key version compatibility. - */ -void -check_keyversion(dst_key_t *key, char *keystr) { - int major, minor; - dst_key_getprivateformat(key, &major, &minor); - INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */ - - if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) - fatal("Key %s has incompatible format version %d.%d, " - "use -f to force upgrade to new version.", - keystr, major, minor); - if (minor > DST_MINOR_VERSION) - fatal("Key %s has incompatible format version %d.%d, " - "use -f to force downgrade to current version.", - keystr, major, minor); -} - -void -set_keyversion(dst_key_t *key) { - int major, minor; - dst_key_getprivateformat(key, &major, &minor); - INSIST(major <= DST_MAJOR_VERSION); - - if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION) - dst_key_setprivateformat(key, DST_MAJOR_VERSION, - DST_MINOR_VERSION); - - /* - * If the key is from a version older than 1.3, set - * set the creation date - */ - if (major < 1 || (major == 1 && minor <= 2)) { - isc_stdtime_t now; - isc_stdtime_get(&now); - dst_key_settime(key, DST_TIME_CREATED, now); - } -} - -bool -key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir, - isc_mem_t *mctx, bool *exact) -{ - isc_result_t result; - bool conflict = false; - dns_dnsseckeylist_t matchkeys; - dns_dnsseckey_t *key = NULL; - uint16_t id, oldid; - uint32_t rid, roldid; - dns_secalg_t alg; - char filename[NAME_MAX]; - isc_buffer_t fileb; - - if (exact != NULL) - *exact = false; - - id = dst_key_id(dstkey); - rid = dst_key_rid(dstkey); - alg = dst_key_alg(dstkey); - - /* - * For HMAC and Diffie Hellman just check if there is a - * direct collision as they can't be revoked. Additionally - * dns_dnssec_findmatchingkeys only handles DNSKEY which is - * not used for HMAC. - */ - switch (alg) { - case DST_ALG_HMACMD5: - case DST_ALG_HMACSHA1: - case DST_ALG_HMACSHA224: - case DST_ALG_HMACSHA256: - case DST_ALG_HMACSHA384: - case DST_ALG_HMACSHA512: - case DST_ALG_DH: - isc_buffer_init(&fileb, filename, sizeof(filename)); - result = dst_key_buildfilename(dstkey, DST_TYPE_PRIVATE, - dir, &fileb); - if (result != ISC_R_SUCCESS) - return (true); - return (isc_file_exists(filename)); - } - - ISC_LIST_INIT(matchkeys); - result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys); - if (result == ISC_R_NOTFOUND) - return (false); - - while (!ISC_LIST_EMPTY(matchkeys) && !conflict) { - key = ISC_LIST_HEAD(matchkeys); - if (dst_key_alg(key->key) != alg) - goto next; - - oldid = dst_key_id(key->key); - roldid = dst_key_rid(key->key); - - if (oldid == rid || roldid == id || id == oldid) { - conflict = true; - if (id != oldid) { - if (verbose > 1) - fprintf(stderr, "Key ID %d could " - "collide with %d\n", - id, oldid); - } else { - if (exact != NULL) - *exact = true; - if (verbose > 1) - fprintf(stderr, "Key ID %d exists\n", - id); - } - } - - next: - ISC_LIST_UNLINK(matchkeys, key, link); - dns_dnsseckey_destroy(mctx, &key); - } - - /* Finish freeing the list */ - while (!ISC_LIST_EMPTY(matchkeys)) { - key = ISC_LIST_HEAD(matchkeys); - ISC_LIST_UNLINK(matchkeys, key, link); - dns_dnsseckey_destroy(mctx, &key); - } - - return (conflict); -} - -bool -is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - dns_name_t *name, dns_dbnode_t *node, uint32_t *ttlp) -{ - dns_rdataset_t nsset; - isc_result_t result; - - if (dns_name_equal(name, origin)) - return (false); - - dns_rdataset_init(&nsset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_ns, - 0, 0, &nsset, NULL); - if (dns_rdataset_isassociated(&nsset)) { - if (ttlp != NULL) - *ttlp = nsset.ttl; - dns_rdataset_disassociate(&nsset); - } - - return (result == ISC_R_SUCCESS); -} - -bool -has_dname(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) { - dns_rdataset_t dnameset; - isc_result_t result; - - dns_rdataset_init(&dnameset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dname, 0, 0, - &dnameset, NULL); - if (dns_rdataset_isassociated(&dnameset)) { - dns_rdataset_disassociate(&dnameset); - } - - return (result == ISC_R_SUCCESS); -} - -static bool -goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name, - dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset, isc_mem_t *mctx) -{ - dns_rdata_dnskey_t key; - dns_rdata_rrsig_t sig; - dst_key_t *dstkey = NULL; - isc_result_t result; - - result = dns_rdata_tostruct(sigrdata, &sig, NULL); - check_result(result, "dns_rdata_tostruct()"); - - for (result = dns_rdataset_first(keyrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(keyrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(keyrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &key, NULL); - check_result(result, "dns_rdata_tostruct()"); - result = dns_dnssec_keyfromrdata(origin, &rdata, mctx, - &dstkey); - if (result != ISC_R_SUCCESS) - return (false); - if (sig.algorithm != key.algorithm || - sig.keyid != dst_key_id(dstkey) || - !dns_name_equal(&sig.signer, origin)) { - dst_key_free(&dstkey); - continue; - } - result = dns_dnssec_verify(name, rdataset, dstkey, false, - mctx, sigrdata); - dst_key_free(&dstkey); - if (result == ISC_R_SUCCESS) - return(true); - } - return (false); -} - -static bool -nsec_bitmap_equal(dns_rdata_nsec_t *nsec, dns_rdata_t *rdata) { - isc_result_t result; - dns_rdata_nsec_t tmpnsec; - - result = dns_rdata_tostruct(rdata, &tmpnsec, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (nsec->len != tmpnsec.len || - memcmp(nsec->typebits, tmpnsec.typebits, nsec->len) != 0) { - return (false); - } - return (true); -} - -static isc_result_t -verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_dbnode_t *node, dns_name_t *nextname) -{ - unsigned char buffer[DNS_NSEC_BUFFERSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char nextbuf[DNS_NAME_FORMATSIZE]; - char found[DNS_NAME_FORMATSIZE]; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_t tmprdata = DNS_RDATA_INIT; - dns_rdata_nsec_t nsec; - isc_result_t result; - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Missing NSEC record for %s\n", namebuf); - goto failure; - } - - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first()"); - - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - check_result(result, "dns_rdata_tostruct()"); - /* Check bit next name is consistent */ - if (!dns_name_equal(&nsec.next, nextname)) { - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_name_format(nextname, nextbuf, sizeof(nextbuf)); - dns_name_format(&nsec.next, found, sizeof(found)); - fprintf(stderr, "Bad NSEC record for %s, next name " - "mismatch (expected:%s, found:%s)\n", namebuf, - nextbuf, found); - goto failure; - } - /* Check bit map is consistent */ - result = dns_nsec_buildrdata(db, ver, node, nextname, buffer, - &tmprdata); - check_result(result, "dns_nsec_buildrdata()"); - if (!nsec_bitmap_equal(&nsec, &tmprdata)) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Bad NSEC record for %s, bit map " - "mismatch\n", namebuf); - goto failure; - } - result = dns_rdataset_next(&rdataset); - if (result != ISC_R_NOMORE) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Multiple NSEC records for %s\n", namebuf); - goto failure; - - } - dns_rdataset_disassociate(&rdataset); - return (ISC_R_SUCCESS); - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (ISC_R_FAILURE); -} - -static void -check_no_rrsig(dns_db_t *db, dns_dbversion_t *ver, dns_rdataset_t *rdataset, - dns_name_t *name, dns_dbnode_t *node) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[80]; - dns_rdataset_t sigrdataset; - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - - dns_rdataset_init(&sigrdataset); - result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &sigrdataset); - if (sigrdataset.type == dns_rdatatype_rrsig && - sigrdataset.covers == rdataset->type) - break; - dns_rdataset_disassociate(&sigrdataset); - } - if (result == ISC_R_SUCCESS) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - fprintf(stderr, "Warning: Found unexpected signatures for " - "%s/%s\n", namebuf, typebuf); - } - if (dns_rdataset_isassociated(&sigrdataset)) - dns_rdataset_disassociate(&sigrdataset); - dns_rdatasetiter_destroy(&rdsiter); -} - -static bool -chain_compare(void *arg1, void *arg2) { - struct nsec3_chain_fixed *e1 = arg1, *e2 = arg2; - size_t len; - - /* - * Do each element in turn to get a stable sort. - */ - if (e1->hash < e2->hash) - return (true); - if (e1->hash > e2->hash) - return (false); - if (e1->iterations < e2->iterations) - return (true); - if (e1->iterations > e2->iterations) - return (false); - if (e1->salt_length < e2->salt_length) - return (true); - if (e1->salt_length > e2->salt_length) - return (false); - if (e1->next_length < e2->next_length) - return (true); - if (e1->next_length > e2->next_length) - return (false); - len = e1->salt_length + 2 * e1->next_length; - if (memcmp(e1 + 1, e2 + 1, len) < 0) - return (true); - return (false); -} - -static bool -chain_equal(struct nsec3_chain_fixed *e1, struct nsec3_chain_fixed *e2) { - size_t len; - - if (e1->hash != e2->hash) - return (false); - if (e1->iterations != e2->iterations) - return (false); - if (e1->salt_length != e2->salt_length) - return (false); - if (e1->next_length != e2->next_length) - return (false); - len = e1->salt_length + 2 * e1->next_length; - if (memcmp(e1 + 1, e2 + 1, len) != 0) - return (false); - return (true); -} - -static isc_result_t -record_nsec3(const unsigned char *rawhash, const dns_rdata_nsec3_t *nsec3, - isc_mem_t *mctx, isc_heap_t *chains) -{ - struct nsec3_chain_fixed *element; - size_t len; - unsigned char *cp; - isc_result_t result; - - len = sizeof(*element) + nsec3->next_length * 2 + nsec3->salt_length; - - element = isc_mem_get(mctx, len); - if (element == NULL) - return (ISC_R_NOMEMORY); - memset(element, 0, len); - element->hash = nsec3->hash; - element->salt_length = nsec3->salt_length; - element->next_length = nsec3->next_length; - element->iterations = nsec3->iterations; - cp = (unsigned char *)(element + 1); - memmove(cp, nsec3->salt, nsec3->salt_length); - cp += nsec3->salt_length; - memmove(cp, rawhash, nsec3->next_length); - cp += nsec3->next_length; - memmove(cp, nsec3->next, nsec3->next_length); - result = isc_heap_insert(chains, element); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_heap_insert failed: %s\n", - isc_result_totext(result)); - isc_mem_put(mctx, element, len); - } - return (result); -} - -static isc_result_t -match_nsec3(dns_name_t *name, isc_mem_t *mctx, - dns_rdata_nsec3param_t *nsec3param, dns_rdataset_t *rdataset, - unsigned char types[8192], unsigned int maxtype, - unsigned char *rawhash, size_t rhsize) -{ - unsigned char cbm[8244]; - char namebuf[DNS_NAME_FORMATSIZE]; - dns_rdata_nsec3_t nsec3; - isc_result_t result; - unsigned int len; - - /* - * Find matching NSEC3 record. - */ - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - check_result(result, "dns_rdata_tostruct()"); - if (nsec3.hash == nsec3param->hash && - nsec3.next_length == rhsize && - nsec3.iterations == nsec3param->iterations && - nsec3.salt_length == nsec3param->salt_length && - memcmp(nsec3.salt, nsec3param->salt, - nsec3param->salt_length) == 0) - break; - } - if (result != ISC_R_SUCCESS) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Missing NSEC3 record for %s\n", namebuf); - return (result); - } - - /* - * Check the type list. - */ - len = dns_nsec_compressbitmap(cbm, types, maxtype); - if (nsec3.len != len || memcmp(cbm, nsec3.typebits, len) != 0) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Bad NSEC3 record for %s, bit map " - "mismatch\n", namebuf); - return (ISC_R_FAILURE); - } - - /* - * Record chain. - */ - result = record_nsec3(rawhash, &nsec3, mctx, expected_chains); - check_result(result, "record_nsec3()"); - - /* - * Make sure there is only one NSEC3 record with this set of - * parameters. - */ - for (result = dns_rdataset_next(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - check_result(result, "dns_rdata_tostruct()"); - if (nsec3.hash == nsec3param->hash && - nsec3.iterations == nsec3param->iterations && - nsec3.salt_length == nsec3param->salt_length && - memcmp(nsec3.salt, nsec3param->salt, - nsec3.salt_length) == 0) { - dns_name_format(name, namebuf, sizeof(namebuf)); - fprintf(stderr, "Multiple NSEC3 records with the " - "same parameter set for %s", namebuf); - result = DNS_R_DUPLICATE; - break; - } - } - if (result != ISC_R_NOMORE) - return (result); - - result = ISC_R_SUCCESS; - return (result); -} - -static bool -innsec3params(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *nsec3paramset) { - dns_rdata_nsec3param_t nsec3param; - isc_result_t result; - - for (result = dns_rdataset_first(nsec3paramset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(nsec3paramset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(nsec3paramset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); - check_result(result, "dns_rdata_tostruct()"); - if (nsec3param.flags == 0 && - nsec3param.hash == nsec3->hash && - nsec3param.iterations == nsec3->iterations && - nsec3param.salt_length == nsec3->salt_length && - memcmp(nsec3param.salt, nsec3->salt, - nsec3->salt_length) == 0) - return (true); - } - return (false); -} - -static isc_result_t -record_found(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, - dns_name_t *name, dns_dbnode_t *node, - dns_rdataset_t *nsec3paramset) -{ - unsigned char owner[NSEC3_MAX_HASH_LENGTH]; - dns_rdata_nsec3_t nsec3; - dns_rdataset_t rdataset; - dns_label_t hashlabel; - isc_buffer_t b; - isc_result_t result; - - if (nsec3paramset == NULL || !dns_rdataset_isassociated(nsec3paramset)) - return (ISC_R_SUCCESS); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - dns_name_getlabel(name, 0, &hashlabel); - isc_region_consume(&hashlabel, 1); - isc_buffer_init(&b, owner, sizeof(owner)); - result = isc_base32hex_decoderegion(&hashlabel, &b); - if (result != ISC_R_SUCCESS) - goto cleanup; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - check_result(result, "dns_rdata_tostruct()"); - if (nsec3.next_length != isc_buffer_usedlength(&b)) - continue; - /* - * We only care about NSEC3 records that match a NSEC3PARAM - * record. - */ - if (!innsec3params(&nsec3, nsec3paramset)) - continue; - - /* - * Record chain. - */ - result = record_nsec3(owner, &nsec3, mctx, found_chains); - check_result(result, "record_nsec3()"); - } - - cleanup: - dns_rdataset_disassociate(&rdataset); - return (ISC_R_SUCCESS); -} - -static bool -isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - dns_rdata_t *nsec3rdata) -{ - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3_t nsec3; - dns_rdata_nsec3param_t nsec3param; - dns_fixedname_t fixed; - dns_name_t *hashname; - isc_result_t result; - dns_dbnode_t *node = NULL; - unsigned char rawhash[NSEC3_MAX_HASH_LENGTH]; - size_t rhsize = sizeof(rawhash); - bool ret; - - result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL); - check_result(result, "dns_rdata_tostruct()"); - - dns_fixedname_init(&fixed); - result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, origin, origin, - nsec3param.hash, nsec3param.iterations, - nsec3param.salt, nsec3param.salt_length); - check_result(result, "dns_nsec3_hashname()"); - - dns_rdataset_init(&rdataset); - hashname = dns_fixedname_name(&fixed); - result = dns_db_findnsec3node(db, hashname, false, &node); - if (result == ISC_R_SUCCESS) - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - return (false); - - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first()"); - - dns_rdataset_current(&rdataset, &rdata); - - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - if (result != ISC_R_SUCCESS) - ret = false; - else - ret = (nsec3.flags & DNS_NSEC3FLAG_OPTOUT); - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (ret); -} - -static isc_result_t -verifynsec3(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - isc_mem_t *mctx, dns_name_t *name, dns_rdata_t *rdata, - bool delegation, bool empty, - unsigned char types[8192], unsigned int maxtype) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char hashbuf[DNS_NAME_FORMATSIZE]; - dns_rdataset_t rdataset; - dns_rdata_nsec3param_t nsec3param; - dns_fixedname_t fixed; - dns_name_t *hashname; - isc_result_t result; - dns_dbnode_t *node = NULL; - unsigned char rawhash[NSEC3_MAX_HASH_LENGTH]; - size_t rhsize = sizeof(rawhash); - bool optout; - - result = dns_rdata_tostruct(rdata, &nsec3param, NULL); - check_result(result, "dns_rdata_tostruct()"); - - if (nsec3param.flags != 0) - return (ISC_R_SUCCESS); - - if (!dns_nsec3_supportedhash(nsec3param.hash)) - return (ISC_R_SUCCESS); - - optout = isoptout(db, ver, origin, rdata); - - dns_fixedname_init(&fixed); - result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, name, origin, - nsec3param.hash, nsec3param.iterations, - nsec3param.salt, nsec3param.salt_length); - check_result(result, "dns_nsec3_hashname()"); - - /* - * We don't use dns_db_find() here as it works with the chosen - * nsec3 chain and we may also be called with uncommitted data - * from dnssec-signzone so the secure status of the zone may not - * be up to date. - */ - dns_rdataset_init(&rdataset); - hashname = dns_fixedname_name(&fixed); - result = dns_db_findnsec3node(db, hashname, false, &node); - if (result == ISC_R_SUCCESS) - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS && - (!delegation || (empty && !optout) || - (!empty && dns_nsec_isset(types, dns_rdatatype_ds)))) - { - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_name_format(hashname, hashbuf, sizeof(hashbuf)); - fprintf(stderr, "Missing NSEC3 record for %s (%s)\n", - namebuf, hashbuf); - } else if (result == ISC_R_NOTFOUND && - delegation && (!empty || optout)) - { - result = ISC_R_SUCCESS; - } else if (result == ISC_R_SUCCESS) { - result = match_nsec3(name, mctx, &nsec3param, &rdataset, - types, maxtype, rawhash, rhsize); - } - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (result); -} - -static isc_result_t -verifynsec3s(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *nsec3paramset, - bool delegation, bool empty, - unsigned char types[8192], unsigned int maxtype) -{ - isc_result_t result; - - for (result = dns_rdataset_first(nsec3paramset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(nsec3paramset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(nsec3paramset, &rdata); - result = verifynsec3(db, ver, origin, mctx, name, &rdata, - delegation, empty, types, maxtype); - if (result != ISC_R_SUCCESS) - break; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - return (result); -} - -static void -verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - isc_mem_t *mctx, dns_rdataset_t *rdataset, dns_name_t *name, - dns_dbnode_t *node, dns_rdataset_t *keyrdataset, - unsigned char *act_algorithms, unsigned char *bad_algorithms) -{ - unsigned char set_algorithms[256]; - char namebuf[DNS_NAME_FORMATSIZE]; - char algbuf[80]; - char typebuf[80]; - dns_rdataset_t sigrdataset; - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - int i; - - dns_rdataset_init(&sigrdataset); - result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &sigrdataset); - if (sigrdataset.type == dns_rdatatype_rrsig && - sigrdataset.covers == rdataset->type) - break; - dns_rdataset_disassociate(&sigrdataset); - } - if (result != ISC_R_SUCCESS) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - fprintf(stderr, "No signatures for %s/%s\n", namebuf, typebuf); - for (i = 0; i < 256; i++) - if (act_algorithms[i] != 0) - bad_algorithms[i] = 1; - dns_rdatasetiter_destroy(&rdsiter); - return; - } - - memset(set_algorithms, 0, sizeof(set_algorithms)); - for (result = dns_rdataset_first(&sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&sigrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t sig; - - dns_rdataset_current(&sigrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &sig, NULL); - check_result(result, "dns_rdata_tostruct()"); - if (rdataset->ttl != sig.originalttl) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - fprintf(stderr, "TTL mismatch for %s %s keytag %u\n", - namebuf, typebuf, sig.keyid); - continue; - } - if ((set_algorithms[sig.algorithm] != 0) || - (act_algorithms[sig.algorithm] == 0)) - continue; - if (goodsig(origin, &rdata, name, keyrdataset, rdataset, mctx)) - set_algorithms[sig.algorithm] = 1; - } - dns_rdatasetiter_destroy(&rdsiter); - if (memcmp(set_algorithms, act_algorithms, sizeof(set_algorithms))) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - for (i = 0; i < 256; i++) - if ((act_algorithms[i] != 0) && - (set_algorithms[i] == 0)) { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "No correct %s signature for " - "%s %s\n", algbuf, namebuf, typebuf); - bad_algorithms[i] = 1; - } - } - dns_rdataset_disassociate(&sigrdataset); -} - -static isc_result_t -verifynode(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - isc_mem_t *mctx, dns_name_t *name, dns_dbnode_t *node, - bool delegation, dns_rdataset_t *keyrdataset, - unsigned char *act_algorithms, unsigned char *bad_algorithms, - dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset, - dns_name_t *nextname) -{ - unsigned char types[8192]; - unsigned int maxtype = 0; - dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result, tresult; - - memset(types, 0, sizeof(types)); - result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - dns_rdataset_init(&rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - /* - * If we are not at a delegation then everything should be - * signed. If we are at a delegation then only the DS set - * is signed. The NS set is not signed at a delegation but - * its existence is recorded in the bit map. Anything else - * other than NSEC and DS is not signed at a delegation. - */ - if (rdataset.type != dns_rdatatype_rrsig && - rdataset.type != dns_rdatatype_dnskey && - (!delegation || rdataset.type == dns_rdatatype_ds || - rdataset.type == dns_rdatatype_nsec)) { - verifyset(db, ver, origin, mctx, &rdataset, - name, node, keyrdataset, - act_algorithms, bad_algorithms); - dns_nsec_setbit(types, rdataset.type, 1); - if (rdataset.type > maxtype) - maxtype = rdataset.type; - } else if (rdataset.type != dns_rdatatype_rrsig && - rdataset.type != dns_rdatatype_dnskey) { - if (rdataset.type == dns_rdatatype_ns) - dns_nsec_setbit(types, rdataset.type, 1); - check_no_rrsig(db, ver, &rdataset, name, node); - } else - dns_nsec_setbit(types, rdataset.type, 1); - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter); - - result = ISC_R_SUCCESS; - - if (nsecset != NULL && dns_rdataset_isassociated(nsecset)) - result = verifynsec(db, ver, name, node, nextname); - - if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) { - tresult = verifynsec3s(db, ver, origin, mctx, name, - nsec3paramset, delegation, false, - types, maxtype); - if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) - result = tresult; - } - return (result); -} - -static bool -is_empty(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - - result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - dns_rdatasetiter_destroy(&rdsiter); - if (result == ISC_R_NOMORE) - return (true); - return (false); -} - -static void -check_no_nsec(dns_name_t *name, dns_dbnode_t *node, dns_db_t *db, - dns_dbversion_t *ver) -{ - dns_rdataset_t rdataset; - isc_result_t result; - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, - 0, 0, &rdataset, NULL); - if (result != ISC_R_NOTFOUND) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namebuf, sizeof(namebuf)); - fatal("unexpected NSEC RRset at %s\n", namebuf); - } - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); -} - -static bool -newchain(const struct nsec3_chain_fixed *first, - const struct nsec3_chain_fixed *e) -{ - if (first->hash != e->hash || - first->iterations != e->iterations || - first->salt_length != e->salt_length || - first->next_length != e->next_length || - memcmp(first + 1, e + 1, first->salt_length) != 0) - return (true); - return (false); -} - -static void -free_element(isc_mem_t *mctx, struct nsec3_chain_fixed *e) { - size_t len; - - len = sizeof(*e) + e->salt_length + 2 * e->next_length; - isc_mem_put(mctx, e, len); -} - -static bool -_checknext(const struct nsec3_chain_fixed *first, - const struct nsec3_chain_fixed *e) -{ - char buf[512]; - const unsigned char *d1 = (const unsigned char *)(first + 1); - const unsigned char *d2 = (const unsigned char *)(e + 1); - isc_buffer_t b; - isc_region_t sr; - - d1 += first->salt_length + first->next_length; - d2 += e->salt_length; - - if (memcmp(d1, d2, first->next_length) == 0) - return (true); - - DE_CONST(d1 - first->next_length, sr.base); - sr.length = first->next_length; - isc_buffer_init(&b, buf, sizeof(buf)); - isc_base32hex_totext(&sr, 1, "", &b); - fprintf(stderr, "Break in NSEC3 chain at: %.*s\n", - (int) isc_buffer_usedlength(&b), buf); - - DE_CONST(d1, sr.base); - sr.length = first->next_length; - isc_buffer_init(&b, buf, sizeof(buf)); - isc_base32hex_totext(&sr, 1, "", &b); - fprintf(stderr, "Expected: %.*s\n", (int) isc_buffer_usedlength(&b), - buf); - - DE_CONST(d2, sr.base); - sr.length = first->next_length; - isc_buffer_init(&b, buf, sizeof(buf)); - isc_base32hex_totext(&sr, 1, "", &b); - fprintf(stderr, "Found: %.*s\n", (int) isc_buffer_usedlength(&b), buf); - - return (false); -} - -static inline bool -checknext(isc_mem_t *mctx, - const struct nsec3_chain_fixed *first, - struct nsec3_chain_fixed *prev, - const struct nsec3_chain_fixed *cur) -{ - bool result = _checknext(prev, cur); - - if (prev != first) { - free_element(mctx, prev); - } - - return (result); -} - -static inline bool -checklast(isc_mem_t *mctx, - struct nsec3_chain_fixed *first, - struct nsec3_chain_fixed *prev) -{ - bool result = _checknext(prev, first); - if (prev != first) { - free_element(mctx, prev); - } - free_element(mctx, first); - - return (result); -} - -#define EXPECTEDANDFOUND "Expected and found NSEC3 chains not equal\n" - -static isc_result_t -verify_nsec3_chains(isc_mem_t *mctx) { - isc_result_t result = ISC_R_SUCCESS; - struct nsec3_chain_fixed *e, *f = NULL; - struct nsec3_chain_fixed *first = NULL, *prev = NULL; - - while ((e = isc_heap_element(expected_chains, 1)) != NULL) { - isc_heap_delete(expected_chains, 1); - if (f == NULL) - f = isc_heap_element(found_chains, 1); - if (f != NULL) { - isc_heap_delete(found_chains, 1); - - /* - * Check that they match. - */ - if (chain_equal(e, f)) { - free_element(mctx, f); - f = NULL; - } else { - if (result == ISC_R_SUCCESS) - fprintf(stderr, EXPECTEDANDFOUND); - result = ISC_R_FAILURE; - /* - * Attempt to resync found_chain. - */ - while (f != NULL && !chain_compare(e, f)) { - free_element(mctx, f); - f = isc_heap_element(found_chains, 1); - if (f != NULL) - isc_heap_delete(found_chains, 1); - if (f != NULL && chain_equal(e, f)) { - free_element(mctx, f); - f = NULL; - break; - } - } - } - } else if (result == ISC_R_SUCCESS) { - fprintf(stderr, EXPECTEDANDFOUND); - result = ISC_R_FAILURE; - } - - if (first == NULL) { - prev = first = e; - } else if (newchain(first, e)) { - if (!checklast(mctx, first, prev)) { - result = ISC_R_FAILURE; - } - - prev = first = e; - } else { - if (!checknext(mctx, first, prev, e)) { - result = ISC_R_FAILURE; - } - - prev = e; - } - } - if (prev != NULL) { - if (!checklast(mctx, first, prev)) - result = ISC_R_FAILURE; - } - do { - if (f != NULL) { - if (result == ISC_R_SUCCESS) { - fprintf(stderr, EXPECTEDANDFOUND); - result = ISC_R_FAILURE; - } - free_element(mctx, f); - } - f = isc_heap_element(found_chains, 1); - if (f != NULL) - isc_heap_delete(found_chains, 1); - } while (f != NULL); - - return (result); -} - -static isc_result_t -verifyemptynodes(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - isc_mem_t *mctx, dns_name_t *name, dns_name_t *prevname, - bool isdelegation, dns_rdataset_t *nsec3paramset) -{ - dns_namereln_t reln; - int order; - unsigned int labels, nlabels, i; - dns_name_t suffix; - isc_result_t result = ISC_R_SUCCESS, tresult; - - reln = dns_name_fullcompare(prevname, name, &order, &labels); - if (order >= 0) - return (result); - - nlabels = dns_name_countlabels(name); - - if (reln == dns_namereln_commonancestor || - reln == dns_namereln_contains) { - dns_name_init(&suffix, NULL); - for (i = labels + 1; i < nlabels; i++) { - dns_name_getlabelsequence(name, nlabels - i, i, - &suffix); - if (nsec3paramset != NULL && - dns_rdataset_isassociated(nsec3paramset)) { - tresult = verifynsec3s(db, ver, origin, mctx, - &suffix, nsec3paramset, - isdelegation, true, - NULL, 0); - if (result == ISC_R_SUCCESS && - tresult != ISC_R_SUCCESS) - result = tresult; - } - } - } - return (result); -} - -/*% - * Verify that certain things are sane: - * - * The apex has a DNSKEY record with at least one KSK, and at least - * one ZSK if the -x flag was not used. - * - * The DNSKEY record was signed with at least one of the KSKs in this - * set. - * - * The rest of the zone was signed with at least one of the ZSKs - * present in the DNSKEY RRSET. - */ -void -verifyzone(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *origin, isc_mem_t *mctx, - bool ignore_kskflag, bool keyset_kskonly) -{ - char algbuf[80]; - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL, *nextnode = NULL; - dns_fixedname_t fname, fnextname, fprevname, fzonecut; - dns_name_t *name, *nextname, *prevname, *zonecut; - dns_rdata_dnskey_t dnskey; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t keyset, soaset; - dns_rdataset_t keysigs, soasigs; - dns_rdataset_t nsecset, nsecsigs; - dns_rdataset_t nsec3paramset, nsec3paramsigs; - int i; - bool done = false; - bool first = true; - bool goodksk = false; - bool goodzsk = false; - isc_result_t result, vresult = ISC_R_UNSET; - unsigned char revoked_ksk[256]; - unsigned char revoked_zsk[256]; - unsigned char standby_ksk[256]; - unsigned char standby_zsk[256]; - unsigned char ksk_algorithms[256]; - unsigned char zsk_algorithms[256]; - unsigned char bad_algorithms[256]; - unsigned char act_algorithms[256]; - - result = isc_heap_create(mctx, chain_compare, NULL, 1024, - &expected_chains); - check_result(result, "isc_heap_create()"); - result = isc_heap_create(mctx, chain_compare, NULL, 1024, - &found_chains); - check_result(result, "isc_heap_create()"); - - result = dns_db_findnode(db, origin, false, &node); - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone's origin: %s", - isc_result_totext(result)); - - dns_rdataset_init(&keyset); - dns_rdataset_init(&keysigs); - dns_rdataset_init(&soaset); - dns_rdataset_init(&soasigs); - dns_rdataset_init(&nsecset); - dns_rdataset_init(&nsecsigs); - dns_rdataset_init(&nsec3paramset); - dns_rdataset_init(&nsec3paramsigs); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, - 0, 0, &keyset, &keysigs); - if (result != ISC_R_SUCCESS) - fatal("Zone contains no DNSSEC keys\n"); - - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, - 0, 0, &soaset, &soasigs); - if (result != ISC_R_SUCCESS) - fatal("Zone contains no SOA record\n"); - - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, - 0, 0, &nsecset, &nsecsigs); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - fatal("NSEC lookup failed\n"); - - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, - 0, 0, &nsec3paramset, &nsec3paramsigs); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - fatal("NSEC3PARAM lookup failed\n"); - - if (!dns_rdataset_isassociated(&keysigs)) - fatal("DNSKEY is not signed (keys offline or inactive?)\n"); - - if (!dns_rdataset_isassociated(&soasigs)) - fatal("SOA is not signed (keys offline or inactive?)\n"); - - if (dns_rdataset_isassociated(&nsecset) && - !dns_rdataset_isassociated(&nsecsigs)) - fatal("NSEC is not signed (keys offline or inactive?)\n"); - - if (dns_rdataset_isassociated(&nsec3paramset) && - !dns_rdataset_isassociated(&nsec3paramsigs)) - fatal("NSEC3PARAM is not signed (keys offline or inactive?)\n"); - - if (!dns_rdataset_isassociated(&nsecset) && - !dns_rdataset_isassociated(&nsec3paramset)) - fatal("No valid NSEC/NSEC3 chain for testing\n"); - - dns_db_detachnode(db, &node); - - memset(revoked_ksk, 0, sizeof(revoked_ksk)); - memset(revoked_zsk, 0, sizeof(revoked_zsk)); - memset(standby_ksk, 0, sizeof(standby_ksk)); - memset(standby_zsk, 0, sizeof(standby_zsk)); - memset(ksk_algorithms, 0, sizeof(ksk_algorithms)); - memset(zsk_algorithms, 0, sizeof(zsk_algorithms)); - memset(bad_algorithms, 0, sizeof(bad_algorithms)); - memset(act_algorithms, 0, sizeof(act_algorithms)); - - /* - * Check that the DNSKEY RR has at least one self signing KSK - * and one ZSK per algorithm in it (or, if -x was used, one - * self-signing KSK). - */ - for (result = dns_rdataset_first(&keyset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keyset)) { - dns_rdataset_current(&keyset, &rdata); - result = dns_rdata_tostruct(&rdata, &dnskey, NULL); - check_result(result, "dns_rdata_tostruct"); - - if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0) - ; - else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { - if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && - !dns_dnssec_selfsigns(&rdata, origin, &keyset, - &keysigs, false, - mctx)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char buffer[1024]; - isc_buffer_t buf; - - dns_name_format(origin, namebuf, - sizeof(namebuf)); - isc_buffer_init(&buf, buffer, sizeof(buffer)); - result = dns_rdata_totext(&rdata, NULL, &buf); - check_result(result, "dns_rdata_totext"); - fatal("revoked KSK is not self signed:\n" - "%s DNSKEY %.*s", namebuf, - (int)isc_buffer_usedlength(&buf), buffer); - } - if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && - revoked_ksk[dnskey.algorithm] != 255) - revoked_ksk[dnskey.algorithm]++; - else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && - revoked_zsk[dnskey.algorithm] != 255) - revoked_zsk[dnskey.algorithm]++; - } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) { - if (dns_dnssec_selfsigns(&rdata, origin, &keyset, - &keysigs, false, mctx)) { - if (ksk_algorithms[dnskey.algorithm] != 255) - ksk_algorithms[dnskey.algorithm]++; - goodksk = true; - } else { - if (standby_ksk[dnskey.algorithm] != 255) - standby_ksk[dnskey.algorithm]++; - } - } else if (dns_dnssec_selfsigns(&rdata, origin, &keyset, - &keysigs, false, mctx)) { - if (zsk_algorithms[dnskey.algorithm] != 255) - zsk_algorithms[dnskey.algorithm]++; - goodzsk = true; - } else if (dns_dnssec_signs(&rdata, origin, &soaset, - &soasigs, false, mctx)) { - if (zsk_algorithms[dnskey.algorithm] != 255) - zsk_algorithms[dnskey.algorithm]++; - } else { - if (standby_zsk[dnskey.algorithm] != 255) - standby_zsk[dnskey.algorithm]++; - } - dns_rdata_freestruct(&dnskey); - dns_rdata_reset(&rdata); - } - dns_rdataset_disassociate(&keysigs); - dns_rdataset_disassociate(&soaset); - dns_rdataset_disassociate(&soasigs); - if (dns_rdataset_isassociated(&nsecsigs)) - dns_rdataset_disassociate(&nsecsigs); - if (dns_rdataset_isassociated(&nsec3paramsigs)) - dns_rdataset_disassociate(&nsec3paramsigs); - - if (ignore_kskflag ) { - if (!goodksk && !goodzsk) - fatal("No self-signed DNSKEY found."); - } else if (!goodksk) - fatal("No self-signed KSK DNSKEY found. Supply an active\n" - "key with the KSK flag set, or use '-P'."); - - fprintf(stderr, "Verifying the zone using the following algorithms:"); - for (i = 0; i < 256; i++) { - if (ignore_kskflag) - act_algorithms[i] = (ksk_algorithms[i] != 0 || - zsk_algorithms[i] != 0) ? 1 : 0; - else - act_algorithms[i] = ksk_algorithms[i] != 0 ? 1 : 0; - if (act_algorithms[i] != 0) { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, " %s", algbuf); - } - } - fprintf(stderr, ".\n"); - - if (!ignore_kskflag && !keyset_kskonly) { - for (i = 0; i < 256; i++) { - /* - * The counts should both be zero or both be non-zero. - * Mark the algorithm as bad if this is not met. - */ - if ((ksk_algorithms[i] != 0) == - (zsk_algorithms[i] != 0)) - continue; - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "Missing %s for algorithm %s\n", - (ksk_algorithms[i] != 0) - ? "ZSK" - : "self-signed KSK", - algbuf); - bad_algorithms[i] = 1; - } - } - - /* - * Check that all the other records were signed by keys that are - * present in the DNSKEY RRSET. - */ - - name = dns_fixedname_initname(&fname); - nextname = dns_fixedname_initname(&fnextname); - dns_fixedname_init(&fprevname); - prevname = NULL; - dns_fixedname_init(&fzonecut); - zonecut = NULL; - - result = dns_db_createiterator(db, DNS_DB_NONSEC3, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - bool isdelegation = false; - - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - if (!dns_name_issubdomain(name, origin)) { - check_no_nsec(name, node, db, ver); - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(dbiter); - if (result == ISC_R_NOMORE) - done = true; - else - check_result(result, "dns_dbiterator_next()"); - continue; - } - if (is_delegation(db, ver, origin, name, node, NULL)) { - zonecut = dns_fixedname_name(&fzonecut); - dns_name_copy(name, zonecut, NULL); - isdelegation = true; - } else if (has_dname(db, ver, node)) { - zonecut = dns_fixedname_name(&fzonecut); - dns_name_copy(name, zonecut, NULL); - } - nextnode = NULL; - result = dns_dbiterator_next(dbiter); - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - check_dns_dbiterator_current(result); - if (!dns_name_issubdomain(nextname, origin) || - (zonecut != NULL && - dns_name_issubdomain(nextname, zonecut))) - { - check_no_nsec(nextname, nextnode, db, ver); - dns_db_detachnode(db, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - if (is_empty(db, ver, nextnode)) { - dns_db_detachnode(db, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - dns_db_detachnode(db, &nextnode); - break; - } - if (result == ISC_R_NOMORE) { - done = true; - nextname = origin; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - result = verifynode(db, ver, origin, mctx, name, node, - isdelegation, &keyset, act_algorithms, - bad_algorithms, &nsecset, &nsec3paramset, - nextname); - if (vresult == ISC_R_UNSET) - vresult = ISC_R_SUCCESS; - if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) - vresult = result; - if (prevname != NULL) { - result = verifyemptynodes(db, ver, origin, mctx, name, - prevname, isdelegation, - &nsec3paramset); - } else - prevname = dns_fixedname_name(&fprevname); - dns_name_copy(name, prevname, NULL); - if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) - vresult = result; - dns_db_detachnode(db, &node); - } - - dns_dbiterator_destroy(&dbiter); - - result = dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbiter); - check_result(result, "dns_db_createiterator()"); - - for (result = dns_dbiterator_first(dbiter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiter) ) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - result = verifynode(db, ver, origin, mctx, name, node, - false, &keyset, act_algorithms, - bad_algorithms, NULL, NULL, NULL); - check_result(result, "verifynode"); - record_found(db, ver, mctx, name, node, &nsec3paramset); - dns_db_detachnode(db, &node); - } - dns_dbiterator_destroy(&dbiter); - - dns_rdataset_disassociate(&keyset); - if (dns_rdataset_isassociated(&nsecset)) - dns_rdataset_disassociate(&nsecset); - if (dns_rdataset_isassociated(&nsec3paramset)) - dns_rdataset_disassociate(&nsec3paramset); - - result = verify_nsec3_chains(mctx); - if (vresult == ISC_R_UNSET) - vresult = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS && vresult == ISC_R_SUCCESS) - vresult = result; - isc_heap_destroy(&expected_chains); - isc_heap_destroy(&found_chains); - - /* - * If we made it this far, we have what we consider a properly signed - * zone. Set the good flag. - */ - for (i = 0; i < 256; i++) { - if (bad_algorithms[i] != 0) { - if (first) - fprintf(stderr, "The zone is not fully signed " - "for the following algorithms:"); - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, " %s", algbuf); - first = false; - } - } - if (!first) { - fprintf(stderr, ".\n"); - fatal("DNSSEC completeness test failed."); - } - - if (vresult != ISC_R_SUCCESS) - fatal("DNSSEC completeness test failed (%s).", - dns_result_totext(vresult)); - - if (goodksk || ignore_kskflag) { - /* - * Print the success summary. - */ - fprintf(stderr, "Zone fully signed:\n"); - for (i = 0; i < 256; i++) { - if ((ksk_algorithms[i] != 0) || - (standby_ksk[i] != 0) || - (revoked_ksk[i] != 0) || - (zsk_algorithms[i] != 0) || - (standby_zsk[i] != 0) || - (revoked_zsk[i] != 0)) { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "Algorithm: %s: KSKs: " - "%u active, %u stand-by, %u revoked\n", - algbuf, ksk_algorithms[i], - standby_ksk[i], revoked_ksk[i]); - fprintf(stderr, "%*sZSKs: " - "%u active, %u %s, %u revoked\n", - (int) strlen(algbuf) + 13, "", - zsk_algorithms[i], - standby_zsk[i], - keyset_kskonly ? "present" : "stand-by", - revoked_zsk[i]); - } - } - } -} - -bool -isoptarg(const char *arg, char **argv, void(*usage)(void)) { - if (!strcasecmp(isc_commandline_argument, arg)) { - if (argv[isc_commandline_index] == NULL) { - fprintf(stderr, "%s: missing argument -%c %s\n", - program, isc_commandline_option, - isc_commandline_argument); - usage(); - } - isc_commandline_argument = argv[isc_commandline_index]; - /* skip to next argument */ - isc_commandline_index++; - return (true); - } - return (false); -} - -#ifdef _WIN32 -void -InitSockets(void) { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup( wVersionRequested, &wsaData ); - if (err != 0) { - fprintf(stderr, "WSAStartup() failed: %d\n", err); - exit(1); - } -} - -void -DestroySockets(void) { - WSACleanup(); -} -#endif diff --git a/bin/dnssec-pkcs11/dnssectool.h b/bin/dnssec-pkcs11/dnssectool.h deleted file mode 100644 index 6cbda2a..0000000 --- a/bin/dnssec-pkcs11/dnssectool.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNSSECTOOL_H -#define DNSSECTOOL_H 1 - -#include -#include - -#include -#include -#include -#include -#include - -#define check_dns_dbiterator_current(result) \ - check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \ - "dns_dbiterator_current()") - - -typedef void (fatalcallback_t)(void); - -ISC_PLATFORM_NORETURN_PRE void -fatal(const char *format, ...) -ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; - -void -setfatalcallback(fatalcallback_t *callback); - -void -check_result(isc_result_t result, const char *message); - -void -vbprintf(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); - -ISC_PLATFORM_NORETURN_PRE void -version(const char *program) ISC_PLATFORM_NORETURN_POST; - -void -type_format(const dns_rdatatype_t type, char *cp, unsigned int size); -#define TYPE_FORMATSIZE 20 - -void -sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size); -#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + sizeof("65535")) - -void -setup_logging(isc_mem_t *mctx, isc_log_t **logp); - -void -cleanup_logging(isc_log_t **logp); - -void -setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx); - -void -cleanup_entropy(isc_entropy_t **ectx); - -dns_ttl_t strtottl(const char *str); - -isc_stdtime_t -strtotime(const char *str, int64_t now, int64_t base, - bool *setp); - -dns_rdataclass_t -strtoclass(const char *str); - -isc_result_t -try_dir(const char *dirname); - -void -check_keyversion(dst_key_t *key, char *keystr); - -void -set_keyversion(dst_key_t *key); - -bool -key_collision(dst_key_t *key, dns_name_t *name, const char *dir, - isc_mem_t *mctx, bool *exact); - -bool -is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, - dns_name_t *name, dns_dbnode_t *node, uint32_t *ttlp); - -/*% - * Return true if version 'ver' of database 'db' contains a DNAME RRset at - * 'node'; return false otherwise. - */ -bool -has_dname(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node); - -void -verifyzone(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *origin, isc_mem_t *mctx, - bool ignore_kskflag, bool keyset_kskonly); - -bool -isoptarg(const char *arg, char **argv, void (*usage)(void)); - -#ifdef _WIN32 -void InitSockets(void); -void DestroySockets(void); -#endif - -#endif /* DNSSEC_DNSSECTOOL_H */ diff --git a/bin/dnssec-pkcs11/win32/dnssectool.dsp.in b/bin/dnssec-pkcs11/win32/dnssectool.dsp.in deleted file mode 100644 index 66cc4e1..0000000 --- a/bin/dnssec-pkcs11/win32/dnssectool.dsp.in +++ /dev/null @@ -1,113 +0,0 @@ -# Microsoft Developer Studio Project File - Name="dnssectool" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Static-Link Library" 0x0104 - -CFG=dnssectool - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dnssectool.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dnssectool.mak" CFG="dnssectool - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dnssectool - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Static-Link Library") -!MESSAGE "dnssectool - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Static-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dnssectool - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" @COPTY@ /FD /c /Fddnssectool -# SUBTRACT CPP /X -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 -# ADD LINK32 /out:"Release/dnssectool.lib" - -!ELSEIF "$(CFG)" == "dnssectool - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /FR @COPTY@ /FD /GZ /c /Fddnssectool -# SUBTRACT CPP /X -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 -# ADD LINK32 /debug out:"Debug/dnssectool.lib" - -!ENDIF - -# Begin Target - -# Name "dnssectool - @PLATFORM@ Release" -# Name "dnssectool - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# Begin Group "Main Dns Lib" - -# PROP Default_Filter "c" -# Begin Source File - -SOURCE=..\dnssectool.c -# End Source File -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/dnssectool.dsw b/bin/dnssec-pkcs11/win32/dnssectool.dsw deleted file mode 100644 index 09562fd..0000000 --- a/bin/dnssec-pkcs11/win32/dnssectool.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "dnssectool"=".\dnssectool.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.filters.in deleted file mode 100644 index 1743f84..0000000 --- a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.filters.in +++ /dev/null @@ -1,27 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.in b/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.in deleted file mode 100644 index 85e0fa1..0000000 --- a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.in +++ /dev/null @@ -1,116 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - - - - - - - {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} - Win32Proj - dnssectool - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - StaticLibrary - true - MultiByte - @PLATFORM_TOOLSET@ - - - StaticLibrary - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - .\$(Configuration)\ - - - .\$(Configuration)\ - None - - - .\$(Configuration)\ - - - .\$(Configuration)\ - None - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_LIB;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Windows - true - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_LIB;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Windows - true - true - true - false - - - - - - diff --git a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.user b/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/dnssectool.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.dsp.in b/bin/dnssec-pkcs11/win32/dsfromkey.dsp.in deleted file mode 100644 index 6967304..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="dsfromkey" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=dsfromkey - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dsfromkey.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dsfromkey.mak" CFG="dsfromkey - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dsfromkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "dsfromkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-dsfromkey.exe" - -!ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-dsfromkey.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "dsfromkey - @PLATFORM@ Release" -# Name "dsfromkey - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-dsfromkey.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.dsw b/bin/dnssec-pkcs11/win32/dsfromkey.dsw deleted file mode 100644 index 06461aa..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "dsfromkey"=".\dsfromkey.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.mak.in b/bin/dnssec-pkcs11/win32/dsfromkey.mak.in deleted file mode 100644 index f5d6ec6..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on dsfromkey.dsp -!IF "$(CFG)" == "" -CFG=dsfromkey - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to dsfromkey - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "dsfromkey - @PLATFORM@ Release" && "$(CFG)" != "dsfromkey - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dsfromkey.mak" CFG="dsfromkey - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dsfromkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "dsfromkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-dsfromkey.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-dsfromkey.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-dsfromkey.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\dsfromkey.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\dsfromkey.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-dsfromkey.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-dsfromkey.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-dsfromkey.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-dsfromkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-dsfromkey.exe" "$(OUTDIR)\dsfromkey.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-dsfromkey.obj" - -@erase "$(INTDIR)\dnssec-dsfromkey.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-dsfromkey.pdb" - -@erase "$(OUTDIR)\dsfromkey.bsc" - -@erase "..\..\..\Build\Debug\dnssec-dsfromkey.exe" - -@erase "..\..\..\Build\Debug\dnssec-dsfromkey.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\dsfromkey.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-dsfromkey.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\dsfromkey.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-dsfromkey.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-dsfromkey.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-dsfromkey.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-dsfromkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("dsfromkey.dep") -!INCLUDE "dsfromkey.dep" -!ELSE -!MESSAGE Warning: cannot find "dsfromkey.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" || "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" -SOURCE="..\dnssec-dsfromkey.c" - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-dsfromkey.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-dsfromkey.obj" "$(INTDIR)\dnssec-dsfromkey.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.filters.in deleted file mode 100644 index 7d0a58e..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.in b/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.in deleted file mode 100644 index 80fd831..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.in +++ /dev/null @@ -1,145 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {6E6297F4-69D7-4533-85E1-BD17C30017C8} - Win32Proj - dsfromkey - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - -@IF PYTHON - - cd ..\..\python -copy /Y dnssec-checkds.py ..\..\Build\$(Configuration)\dnssec-checkds.py -copy /Y dnssec-coverage.py ..\..\Build\$(Configuration)\dnssec-coverage.py -copy /Y dnssec-keymgr.py ..\..\Build\$(Configuration)\dnssec-keymgr.py -cd isc -@PYTHON@ policy.py parse \dev\nul > nul -set PYTHONPATH=. -@PYTHON@ -m parsetab - - -@END PYTHON - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - -@IF PYTHON - - cd ..\..\python -copy /Y dnssec-checkds.py ..\..\Build\$(Configuration)\dnssec-checkds.py -copy /Y dnssec-coverage.py ..\..\Build\$(Configuration)\dnssec-coverage.py -copy /Y dnssec-keymgr.py ..\..\Build\$(Configuration)\dnssec-keymgr.py -cd isc -@PYTHON@ policy.py parse \dev\nul > nul -set PYTHONPATH=. -@PYTHON@ -m parsetab - - -@END PYTHON - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.user b/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/dsfromkey.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/importkey.dsp.in b/bin/dnssec-pkcs11/win32/importkey.dsp.in deleted file mode 100644 index cb6ba98..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="importkey" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=importkey - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "importkey.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "importkey.mak" CFG="importkey - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "importkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "importkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-importkey.exe" - -!ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-importkey.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "importkey - @PLATFORM@ Release" -# Name "importkey - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-importkey.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/importkey.dsw b/bin/dnssec-pkcs11/win32/importkey.dsw deleted file mode 100644 index 28f2ee6..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "importkey"=".\importkey.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/importkey.mak.in b/bin/dnssec-pkcs11/win32/importkey.mak.in deleted file mode 100644 index 53d42af..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on importkey.dsp -!IF "$(CFG)" == "" -CFG=importkey - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to importkey - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "importkey - @PLATFORM@ Release" && "$(CFG)" != "importkey - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "importkey.mak" CFG="importkey - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "importkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "importkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-importkey.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-importkey.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-importkey.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\importkey.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\importkey.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-importkey.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-importkey.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-importkey.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-importkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-importkey.exe" "$(OUTDIR)\importkey.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-importkey.obj" - -@erase "$(INTDIR)\dnssec-importkey.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-importkey.pdb" - -@erase "$(OUTDIR)\importkey.bsc" - -@erase "..\..\..\Build\Debug\dnssec-importkey.exe" - -@erase "..\..\..\Build\Debug\dnssec-importkey.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\importkey.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-importkey.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\importkey.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-importkey.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-importkey.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-importkey.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-importkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("importkey.dep") -!INCLUDE "importkey.dep" -!ELSE -!MESSAGE Warning: cannot find "importkey.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" || "$(CFG)" == "importkey - @PLATFORM@ Debug" -SOURCE="..\dnssec-importkey.c" - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-importkey.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-importkey.obj" "$(INTDIR)\dnssec-importkey.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "importkey - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/importkey.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/importkey.vcxproj.filters.in deleted file mode 100644 index 0bced36..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - diff --git a/bin/dnssec-pkcs11/win32/importkey.vcxproj.in b/bin/dnssec-pkcs11/win32/importkey.vcxproj.in deleted file mode 100644 index 5f8fbe9..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {AB6690A0-055E-458f-BAC5-BF38BCC5834F} - Win32Proj - importkey - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/importkey.vcxproj.user b/bin/dnssec-pkcs11/win32/importkey.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/importkey.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.dsp.in b/bin/dnssec-pkcs11/win32/keyfromlabel.dsp.in deleted file mode 100644 index 1739e9f..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="keyfromlabel" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=keyfromlabel - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "keyfromlabel.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "keyfromlabel.mak" CFG="keyfromlabel - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "keyfromlabel - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "keyfromlabel - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-keyfromlabel.exe" - -!ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keyfromlabel.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "keyfromlabel - @PLATFORM@ Release" -# Name "keyfromlabel - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-keyfromlabel.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.dsw b/bin/dnssec-pkcs11/win32/keyfromlabel.dsw deleted file mode 100644 index 499e9a5..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "keyfromlabel"=".\keyfromlabel.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.mak.in b/bin/dnssec-pkcs11/win32/keyfromlabel.mak.in deleted file mode 100644 index 2a58a96..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on keyfromlabel.dsp -!IF "$(CFG)" == "" -CFG=keyfromlabel - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to keyfromlabel - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "keyfromlabel - @PLATFORM@ Release" && "$(CFG)" != "keyfromlabel - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "keyfromlabel.mak" CFG="keyfromlabel - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "keyfromlabel - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "keyfromlabel - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-keyfromlabel.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-keyfromlabel.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-keyfromlabel.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\keyfromlabel.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\keyfromlabel.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-keyfromlabel.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-keyfromlabel.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-keyfromlabel.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-keyfromlabel.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-keyfromlabel.exe" "$(OUTDIR)\keyfromlabel.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-keyfromlabel.obj" - -@erase "$(INTDIR)\dnssec-keyfromlabel.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-keyfromlabel.pdb" - -@erase "$(OUTDIR)\keyfromlabel.bsc" - -@erase "..\..\..\Build\Debug\dnssec-keyfromlabel.exe" - -@erase "..\..\..\Build\Debug\dnssec-keyfromlabel.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\keyfromlabel.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-keyfromlabel.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\keyfromlabel.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-keyfromlabel.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keyfromlabel.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-keyfromlabel.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-keyfromlabel.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("keyfromlabel.dep") -!INCLUDE "keyfromlabel.dep" -!ELSE -!MESSAGE Warning: cannot find "keyfromlabel.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" || "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" -SOURCE="..\dnssec-keyfromlabel.c" - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-keyfromlabel.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-keyfromlabel.obj" "$(INTDIR)\dnssec-keyfromlabel.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.filters.in deleted file mode 100644 index bb54f81..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.in b/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.in deleted file mode 100644 index 9a26eb7..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {17455DC6-5FBB-47C3-8F44-7DB574A188D3} - Win32Proj - keyfromlabel - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.user b/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/keyfromlabel.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/keygen.dsp.in b/bin/dnssec-pkcs11/win32/keygen.dsp.in deleted file mode 100644 index 6b135bf..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="keygen" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=keygen - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "keygen.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "keygen.mak" CFG="keygen - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "keygen - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "keygen - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-keygen.exe" - -!ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keygen.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "keygen - @PLATFORM@ Release" -# Name "keygen - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-keygen.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/keygen.dsw b/bin/dnssec-pkcs11/win32/keygen.dsw deleted file mode 100644 index bdd633e..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "keygen"=".\keygen.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/keygen.mak.in b/bin/dnssec-pkcs11/win32/keygen.mak.in deleted file mode 100644 index b29d11d..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on keygen.dsp -!IF "$(CFG)" == "" -CFG=keygen - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to keygen - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "keygen - @PLATFORM@ Release" && "$(CFG)" != "keygen - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "keygen.mak" CFG="keygen - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "keygen - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "keygen - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-keygen.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-keygen.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-keygen.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\keygen.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\keygen.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-keygen.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-keygen.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-keygen.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-keygen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-keygen.exe" "$(OUTDIR)\keygen.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-keygen.obj" - -@erase "$(INTDIR)\dnssec-keygen.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-keygen.pdb" - -@erase "$(OUTDIR)\keygen.bsc" - -@erase "..\..\..\Build\Debug\dnssec-keygen.exe" - -@erase "..\..\..\Build\Debug\dnssec-keygen.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\keygen.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-keygen.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\keygen.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-keygen.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keygen.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-keygen.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-keygen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("keygen.dep") -!INCLUDE "keygen.dep" -!ELSE -!MESSAGE Warning: cannot find "keygen.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" || "$(CFG)" == "keygen - @PLATFORM@ Debug" -SOURCE="..\dnssec-keygen.c" - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-keygen.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-keygen.obj" "$(INTDIR)\dnssec-keygen.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "keygen - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/keygen.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/keygen.vcxproj.filters.in deleted file mode 100644 index 5d1fa4c..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/keygen.vcxproj.in b/bin/dnssec-pkcs11/win32/keygen.vcxproj.in deleted file mode 100644 index e748e29..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {0BF11E21-168C-4CAA-B784-429D126BBAE5} - Win32Proj - keygen - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/keygen.vcxproj.user b/bin/dnssec-pkcs11/win32/keygen.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/keygen.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/revoke.dsp.in b/bin/dnssec-pkcs11/win32/revoke.dsp.in deleted file mode 100644 index 521028d..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="revoke" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=revoke - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "revoke.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "revoke.mak" CFG="revoke - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "revoke - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "revoke - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-revoke.exe" - -!ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-revoke.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "revoke - @PLATFORM@ Release" -# Name "revoke - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-revoke.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/revoke.dsw b/bin/dnssec-pkcs11/win32/revoke.dsw deleted file mode 100644 index f588e21..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "revoke"=".\revoke.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/revoke.mak.in b/bin/dnssec-pkcs11/win32/revoke.mak.in deleted file mode 100644 index 03632ef..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on revoke.dsp -!IF "$(CFG)" == "" -CFG=revoke - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to revoke - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "revoke - @PLATFORM@ Release" && "$(CFG)" != "revoke - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "revoke.mak" CFG="revoke - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "revoke - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "revoke - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-revoke.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-revoke.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-revoke.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\revoke.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\revoke.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-revoke.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-revoke.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-revoke.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-revoke.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-revoke.exe" "$(OUTDIR)\revoke.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-revoke.obj" - -@erase "$(INTDIR)\dnssec-revoke.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-revoke.pdb" - -@erase "$(OUTDIR)\revoke.bsc" - -@erase "..\..\..\Build\Debug\dnssec-revoke.exe" - -@erase "..\..\..\Build\Debug\dnssec-revoke.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\revoke.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-revoke.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\revoke.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-revoke.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-revoke.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-revoke.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-revoke.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("revoke.dep") -!INCLUDE "revoke.dep" -!ELSE -!MESSAGE Warning: cannot find "revoke.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" || "$(CFG)" == "revoke - @PLATFORM@ Debug" -SOURCE="..\dnssec-revoke.c" - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-revoke.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-revoke.obj" "$(INTDIR)\dnssec-revoke.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "revoke - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/revoke.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/revoke.vcxproj.filters.in deleted file mode 100644 index 46e7310..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/revoke.vcxproj.in b/bin/dnssec-pkcs11/win32/revoke.vcxproj.in deleted file mode 100644 index 350f234..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {D171F185-D3C2-4463-9CF3-ED1D0B1D6832} - Win32Proj - revoke - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/revoke.vcxproj.user b/bin/dnssec-pkcs11/win32/revoke.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/revoke.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/settime.dsp.in b/bin/dnssec-pkcs11/win32/settime.dsp.in deleted file mode 100644 index d71a3a9..0000000 --- a/bin/dnssec-pkcs11/win32/settime.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="settime" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=settime - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "settime.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "settime.mak" CFG="settime - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "settime - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "settime - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-settime.exe" - -!ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-settime.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "settime - @PLATFORM@ Release" -# Name "settime - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-settime.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/settime.dsw b/bin/dnssec-pkcs11/win32/settime.dsw deleted file mode 100644 index fc4dca8..0000000 --- a/bin/dnssec-pkcs11/win32/settime.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "settime"=".\settime.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/settime.mak.in b/bin/dnssec-pkcs11/win32/settime.mak.in deleted file mode 100644 index 1de3a84..0000000 --- a/bin/dnssec-pkcs11/win32/settime.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on settime.dsp -!IF "$(CFG)" == "" -CFG=settime - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to settime - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "settime - @PLATFORM@ Release" && "$(CFG)" != "settime - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "settime.mak" CFG="settime - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "settime - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "settime - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-settime.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-settime.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-settime.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\settime.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\settime.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-settime.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-settime.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-settime.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-settime.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-settime.exe" "$(OUTDIR)\settime.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-settime.obj" - -@erase "$(INTDIR)\dnssec-settime.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-settime.pdb" - -@erase "$(OUTDIR)\settime.bsc" - -@erase "..\..\..\Build\Debug\dnssec-settime.exe" - -@erase "..\..\..\Build\Debug\dnssec-settime.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\settime.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-settime.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\settime.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-settime.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-settime.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-settime.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-settime.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("settime.dep") -!INCLUDE "settime.dep" -!ELSE -!MESSAGE Warning: cannot find "settime.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" || "$(CFG)" == "settime - @PLATFORM@ Debug" -SOURCE="..\dnssec-settime.c" - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-settime.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-settime.obj" "$(INTDIR)\dnssec-settime.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "settime - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/settime.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/settime.vcxproj.filters.in deleted file mode 100644 index 62b0e82..0000000 --- a/bin/dnssec-pkcs11/win32/settime.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/settime.vcxproj.in b/bin/dnssec-pkcs11/win32/settime.vcxproj.in deleted file mode 100644 index c523130..0000000 --- a/bin/dnssec-pkcs11/win32/settime.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {03FB7588-C5A7-4572-968F-14F1206BC69C} - Win32Proj - settime - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/settime.vcxproj.user b/bin/dnssec-pkcs11/win32/settime.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/settime.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/signzone.dsp.in b/bin/dnssec-pkcs11/win32/signzone.dsp.in deleted file mode 100644 index ee45ec9..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="signzone" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=signzone - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "signzone.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "signzone.mak" CFG="signzone - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "signzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "signzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-signzone.exe" - -!ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-signzone.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "signzone - @PLATFORM@ Release" -# Name "signzone - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-signzone.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/signzone.dsw b/bin/dnssec-pkcs11/win32/signzone.dsw deleted file mode 100644 index 67f5647..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "signzone"=".\signzone.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/signzone.mak.in b/bin/dnssec-pkcs11/win32/signzone.mak.in deleted file mode 100644 index a106465..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on signzone.dsp -!IF "$(CFG)" == "" -CFG=signzone - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to signzone - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "signzone - @PLATFORM@ Release" && "$(CFG)" != "signzone - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "signzone.mak" CFG="signzone - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "signzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "signzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-signzone.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-signzone.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-signzone.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\signzone.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\signzone.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-signzone.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-signzone.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-signzone.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-signzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-signzone.exe" "$(OUTDIR)\signzone.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-signzone.obj" - -@erase "$(INTDIR)\dnssec-signzone.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-signzone.pdb" - -@erase "$(OUTDIR)\signzone.bsc" - -@erase "..\..\..\Build\Debug\dnssec-signzone.exe" - -@erase "..\..\..\Build\Debug\dnssec-signzone.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\signzone.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-signzone.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\signzone.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-signzone.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-signzone.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-signzone.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-signzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("signzone.dep") -!INCLUDE "signzone.dep" -!ELSE -!MESSAGE Warning: cannot find "signzone.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" || "$(CFG)" == "signzone - @PLATFORM@ Debug" -SOURCE="..\dnssec-signzone.c" - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-signzone.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-signzone.obj" "$(INTDIR)\dnssec-signzone.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "signzone - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/signzone.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/signzone.vcxproj.filters.in deleted file mode 100644 index 682ae55..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/signzone.vcxproj.in b/bin/dnssec-pkcs11/win32/signzone.vcxproj.in deleted file mode 100644 index a3d8251..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {205ED8A9-2E4C-41CC-9385-F3613402AA90} - Win32Proj - signzone - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/signzone.vcxproj.user b/bin/dnssec-pkcs11/win32/signzone.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/signzone.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/verify.dsp.in b/bin/dnssec-pkcs11/win32/verify.dsp.in deleted file mode 100644 index 3c76ecd..0000000 --- a/bin/dnssec-pkcs11/win32/verify.dsp.in +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="verify" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=verify - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "verify.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "verify.mak" CFG="verify - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "verify - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "verify - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-verify.exe" - -!ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-verify.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "verify - @PLATFORM@ Release" -# Name "verify - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE="..\dnssec-verify.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/dnssec-pkcs11/win32/verify.dsw b/bin/dnssec-pkcs11/win32/verify.dsw deleted file mode 100644 index 4553264..0000000 --- a/bin/dnssec-pkcs11/win32/verify.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "verify"=".\verify.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/dnssec-pkcs11/win32/verify.mak.in b/bin/dnssec-pkcs11/win32/verify.mak.in deleted file mode 100644 index a858a8b..0000000 --- a/bin/dnssec-pkcs11/win32/verify.mak.in +++ /dev/null @@ -1,324 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on verify.dsp -!IF "$(CFG)" == "" -CFG=verify - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to verify - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "verify - @PLATFORM@ Release" && "$(CFG)" != "verify - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "verify.mak" CFG="verify - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "verify - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "verify - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "..\..\..\Build\Release\dnssec-verify.exe" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-verify.obj" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "..\..\..\Build\Release\dnssec-verify.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\verify.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\verify.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-verify.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-verify.exe" -LINK32_OBJS= \ - "$(INTDIR)\dnssec-verify.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Release\dnssec-verify.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "..\..\..\Build\Debug\dnssec-verify.exe" "$(OUTDIR)\verify.bsc" - - -CLEAN : - -@erase "$(INTDIR)\dnssec-verify.obj" - -@erase "$(INTDIR)\dnssec-verify.sbr" - -@erase "$(INTDIR)\dnssectool.obj" - -@erase "$(INTDIR)\dnssectool.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\dnssec-verify.pdb" - -@erase "$(OUTDIR)\verify.bsc" - -@erase "..\..\..\Build\Debug\dnssec-verify.exe" - -@erase "..\..\..\Build\Debug\dnssec-verify.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" @CRYPTO@ /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\verify.bsc" -BSC32_SBRS= \ - "$(INTDIR)\dnssec-verify.sbr" \ - "$(INTDIR)\dnssectool.sbr" - -"$(OUTDIR)\verify.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-verify.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-verify.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\dnssec-verify.obj" \ - "$(INTDIR)\dnssectool.obj" - -"..\..\..\Build\Debug\dnssec-verify.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("verify.dep") -!INCLUDE "verify.dep" -!ELSE -!MESSAGE Warning: cannot find "verify.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" || "$(CFG)" == "verify - @PLATFORM@ Debug" -SOURCE="..\dnssec-verify.c" - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" - - -"$(INTDIR)\dnssec-verify.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssec-verify.obj" "$(INTDIR)\dnssec-verify.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\dnssectool.c - -!IF "$(CFG)" == "verify - @PLATFORM@ Release" - - -"$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" - - -"$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/dnssec-pkcs11/win32/verify.vcxproj.filters.in b/bin/dnssec-pkcs11/win32/verify.vcxproj.filters.in deleted file mode 100644 index 3b194bd..0000000 --- a/bin/dnssec-pkcs11/win32/verify.vcxproj.filters.in +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - \ No newline at end of file diff --git a/bin/dnssec-pkcs11/win32/verify.vcxproj.in b/bin/dnssec-pkcs11/win32/verify.vcxproj.in deleted file mode 100644 index bed629c..0000000 --- a/bin/dnssec-pkcs11/win32/verify.vcxproj.in +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {FD653434-F1A8-44A9-85B2-A7468491DA6D} - Win32Proj - verify - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - dnssec-$(ProjectName) - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(ProjectName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) - $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) - - - - - - - - - diff --git a/bin/dnssec-pkcs11/win32/verify.vcxproj.user b/bin/dnssec-pkcs11/win32/verify.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/dnssec-pkcs11/win32/verify.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/dnssec/Makefile.in b/bin/dnssec/Makefile.in index 851a008..81b3f9a 100644 --- a/bin/dnssec/Makefile.in +++ b/bin/dnssec/Makefile.in @@ -17,7 +17,7 @@ VERSION=@BIND9_VERSION@ CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} @DST_OPENSSL_INC@ -CDEFINES = -DVERSION=\"${VERSION}\" \ +CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@ @PKCS11_ENGINE@ \ @CRYPTO@ -DPK11_LIB_LOCATION=\"@PKCS11_PROVIDER@\" CWARNINGS = @@ -108,11 +108,9 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man8: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install:: ${TARGETS} installdirs install-man8 +install:: ${TARGETS} installdirs for t in ${TARGETS}; do ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} $$t ${DESTDIR}${sbindir} || exit 1; done + for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8 || exit 1; done uninstall:: for m in ${MANPAGES}; do rm -f ${DESTDIR}${mandir}/man8/$$m || exit 1; done diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c index 9cb63a8..4420f2d 100644 --- a/bin/dnssec/dnssec-dsfromkey.c +++ b/bin/dnssec/dnssec-dsfromkey.c @@ -498,14 +498,14 @@ main(int argc, char **argv) { if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("could not initialize hash"); result = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not initialize hash"); isc_entropy_stopcallbacksources(ectx); setup_logging(mctx, &log); @@ -574,8 +574,8 @@ main(int argc, char **argv) { if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); cleanup_logging(&log); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) diff --git a/bin/dnssec/dnssec-dsfromkey.docbook b/bin/dnssec/dnssec-dsfromkey.docbook index c2d66d7..25aefdf 100644 --- a/bin/dnssec/dnssec-dsfromkey.docbook +++ b/bin/dnssec/dnssec-dsfromkey.docbook @@ -10,7 +10,7 @@ --> - + 2012-05-02 @@ -22,7 +22,7 @@ dnssec-dsfromkey 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-importkey.c b/bin/dnssec/dnssec-importkey.c index 52863a1..dc9a293 100644 --- a/bin/dnssec/dnssec-importkey.c +++ b/bin/dnssec/dnssec-importkey.c @@ -404,14 +404,14 @@ main(int argc, char **argv) { if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("could not initialize hash"); result = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not initialize hash"); isc_entropy_stopcallbacksources(ectx); setup_logging(mctx, &log); @@ -455,8 +455,8 @@ main(int argc, char **argv) { if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); cleanup_logging(&log); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) diff --git a/bin/dnssec/dnssec-importkey.docbook b/bin/dnssec/dnssec-importkey.docbook index 176fa77..a362487 100644 --- a/bin/dnssec/dnssec-importkey.docbook +++ b/bin/dnssec/dnssec-importkey.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-20 @@ -23,7 +23,7 @@ dnssec-importkey 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook index 72d89fb..38c48b8 100644 --- a/bin/dnssec/dnssec-keyfromlabel.docbook +++ b/bin/dnssec/dnssec-keyfromlabel.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-27 @@ -23,7 +23,7 @@ dnssec-keyfromlabel 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index e2dc70e..9d9ae93 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -564,19 +563,6 @@ main(int argc, char **argv) { INSIST(freeit == NULL); return (1); } else if (strcasecmp(algname, "HMAC-MD5") == 0) { - if (isc_md5_available()) { - alg = DST_ALG_HMACMD5; - } else { - fprintf(stderr, - "The use of HMAC-MD5 was disabled\n"); - return (1); - } - } else if (strcasecmp(algname, "RSAMD5") == 0 && - !isc_md5_available()) { - fprintf(stderr, "The use of RSAMD5 was disabled\n"); - INSIST(freeit == NULL); - return (1); - } else if (strcasecmp(algname, "HMAC-MD5") == 0) { alg = DST_ALG_HMACMD5; #else fprintf(stderr, diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook index d4e2f29..733c829 100644 --- a/bin/dnssec/dnssec-keygen.docbook +++ b/bin/dnssec/dnssec-keygen.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-06 @@ -23,7 +23,7 @@ dnssec-keygen 8 - BIND9 + BIND9 @@ -349,23 +349,15 @@ -r randomdev - Specifies a source of randomness. Normally, when generating - DNSSEC keys, this option has no effect; the random number - generation function provided by the cryptographic library will - be used. - - - If that behavior is disabled at compile time, however, - the specified file will be used as entropy source - for key generation. randomdev is + Specifies the source of randomness. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies the name of a character device or file containing random - data to be used. The special value keyboard - indicates that keyboard input should be used. - - - The default is /dev/random if the - operating system provides it or an equivalent device; - if not, the default source of randomness is keyboard input. + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. diff --git a/bin/dnssec/dnssec-revoke.c b/bin/dnssec/dnssec-revoke.c index 74a99b0..0121a34 100644 --- a/bin/dnssec/dnssec-revoke.c +++ b/bin/dnssec/dnssec-revoke.c @@ -184,14 +184,14 @@ main(int argc, char **argv) { if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize hash"); isc_entropy_stopcallbacksources(ectx); result = dst_key_fromnamedfile(filename, dir, @@ -273,8 +273,8 @@ main(int argc, char **argv) { cleanup: dst_key_free(&key); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); diff --git a/bin/dnssec/dnssec-revoke.docbook b/bin/dnssec/dnssec-revoke.docbook index 35d425c..213e551 100644 --- a/bin/dnssec/dnssec-revoke.docbook +++ b/bin/dnssec/dnssec-revoke.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-15 @@ -22,7 +22,7 @@ dnssec-revoke 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c index 2c568fc..f017895 100644 --- a/bin/dnssec/dnssec-settime.c +++ b/bin/dnssec/dnssec-settime.c @@ -391,14 +391,14 @@ main(int argc, char **argv) { if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("Could not initialize hash"); isc_entropy_stopcallbacksources(ectx); if (predecessor != NULL) { @@ -683,8 +683,8 @@ main(int argc, char **argv) { if (prevkey != NULL) dst_key_free(&prevkey); dst_key_free(&key); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); diff --git a/bin/dnssec/dnssec-settime.docbook b/bin/dnssec/dnssec-settime.docbook index 75f5035..a216041 100644 --- a/bin/dnssec/dnssec-settime.docbook +++ b/bin/dnssec/dnssec-settime.docbook @@ -10,7 +10,7 @@ --> - + 2015-08-21 @@ -22,7 +22,7 @@ dnssec-settime 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 7308fc6..dde1b2f 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -3465,15 +3465,14 @@ main(int argc, char *argv[]) { if (!pseudorandom) eflags |= ISC_ENTROPY_GOODONLY; - result = dst_lib_init2(mctx, ectx, engine, eflags); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst: %s", - isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not create hash context"); + result = dst_lib_init2(mctx, ectx, engine, eflags); + if (result != ISC_R_SUCCESS) + fatal("could not initialize dst: %s", + isc_result_totext(result)); isc_stdtime_get(&now); if (startstr != NULL) { @@ -3885,8 +3884,8 @@ main(int argc, char *argv[]) { dns_master_styledestroy(&dsstyle, mctx); cleanup_logging(&log); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook index f352e26..e0b2aa0 100644 --- a/bin/dnssec/dnssec-signzone.docbook +++ b/bin/dnssec/dnssec-signzone.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-18 @@ -22,7 +22,7 @@ dnssec-signzone 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssec-verify.c b/bin/dnssec/dnssec-verify.c index 07c7294..087cd5d 100644 --- a/bin/dnssec/dnssec-verify.c +++ b/bin/dnssec/dnssec-verify.c @@ -281,15 +281,15 @@ main(int argc, char *argv[]) { if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("could not create hash context"); + result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not create hash context"); - isc_stdtime_get(&now); rdclass = strtoclass(classname); diff --git a/bin/dnssec/dnssec-verify.docbook b/bin/dnssec/dnssec-verify.docbook index 6b41233..a9edf25 100644 --- a/bin/dnssec/dnssec-verify.docbook +++ b/bin/dnssec/dnssec-verify.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-15 @@ -22,7 +22,7 @@ dnssec-verify 8 - BIND9 + BIND9 diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 6fcd411..7f045e8 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -236,16 +235,10 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { if (*ectx == NULL) { result = isc_entropy_create(mctx, ectx); if (result != ISC_R_SUCCESS) - fatal("could not create entropy object: %s", - isc_result_totext(result)); + fatal("could not create entropy object"); ISC_LIST_INIT(sources); } -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(*ectx, true); - } -#endif if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { usekeyboard = ISC_ENTROPY_KEYBOARDYES; randomfile = NULL; diff --git a/bin/named-pkcs11/Makefile.in b/bin/named-pkcs11/Makefile.in deleted file mode 100644 index 52a6375..0000000 --- a/bin/named-pkcs11/Makefile.in +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -# Attempt to disable parallel processing. -.NOTPARALLEL: -.NO_PARALLEL: - -VERSION=@BIND9_VERSION@ - -@BIND9_PRODUCT@ - -@BIND9_DESCRIPTION@ - -@BIND9_SRCID@ - -@BIND9_CONFIGARGS@ - -@BIND9_MAKE_INCLUDES@ - -# -# Add database drivers here. -# -DBDRIVER_OBJS = -DBDRIVER_SRCS = -DBDRIVER_INCLUDES = -DBDRIVER_LIBS = - -DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers - -DLZDRIVER_OBJS = @DLZ_DRIVER_OBJS@ -DLZDRIVER_SRCS = @DLZ_DRIVER_SRCS@ -DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@ -DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ - ${LWRES_INCLUDES} ${DNS_PKCS11_INCLUDES} ${BIND9_INCLUDES} \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_PKCS11_INCLUDES} \ - ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} ${MAXMINDDB_CFLAGS} \ - @DST_OPENSSL_INC@ - -CDEFINES = @USE_PKCS11@ @PKCS11_ENGINE@ @CRYPTO_PK11@ @USE_GSSAPI@ - -CWARNINGS = - -DNSLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ -ISCNOSYMLIBS = ../../lib/isc-pkcs11/libisc-pkcs11-nosymtbl.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ - ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ - @LIBS@ - -NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ - @LIBS@ - -SUBDIRS = unix - -TARGETS = named-pkcs11@EXEEXT@ - -GEOIPLINKOBJS = geoip.@O@ -GEOIP2LINKOBJS = geoip.@O@ - -OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ fuzz.@O@ \ - @GEOIPLINKOBJS@ @GEOIP2LINKOBJS@ \ - interfacemgr.@O@ listenlist.@O@ log.@O@ logconf.@O@ \ - main.@O@ notify.@O@ \ - query.@O@ server.@O@ sortlist.@O@ statschannel.@O@ \ - tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ - zoneconf.@O@ \ - lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ - lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ - -UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ - -SYMOBJS = symtbl.@O@ - -GEOIPLINKSRCS = geoip.c -GEOIP2LINKSRCS = geoip.c - -SRCS = builtin.c client.c config.c control.c \ - controlconf.c fuzz.c \ - @GEOIPLINKSRCS@ @GEOIP2LINKSRCS@ \ - interfacemgr.c \ listenlist.c log.c logconf.c \ - main.c notify.c \ - query.c server.c sortlist.c statschannel.c \ - tkeyconf.c tsigconf.c update.c xfrout.c \ - zoneconf.c \ - lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ - lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c - -MANPAGES = named.8 lwresd.8 named.conf.5 - -HTMLPAGES = named.html lwresd.html named.conf.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -EXT_CFLAGS = -fpie - -@BIND9_MAKE_RULES@ - -LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack - -main.@O@: main.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DPRODUCT=\"${PRODUCT}\" \ - -DDESCRIPTION=\"${DESCRIPTION}\" \ - -DSRCID=\"${SRCID}\" \ - -DCONFIGARGS="\"${CONFIGARGS}\"" \ - -DBUILDER="\"make\"" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c - -config.@O@: config.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DSRCID=\"${SRCID}\" \ - -DDYNDB_LIBDIR=\"@libdir@/bind\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" \ - -DMAXMINDDB_PREFIX=\"@MAXMINDDB_PREFIX@\" \ - -c ${srcdir}/config.c - -server.@O@: server.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DPRODUCT=\"${PRODUCT}\" \ - -DVERSION=\"${VERSION}\" -c ${srcdir}/server.c - -named-pkcs11@EXEEXT@: ${OBJS} ${DEPLIBS} - export MAKE_SYMTABLE="yes"; \ - export BASEOBJS="${OBJS} ${UOBJS}"; \ - ${FINALBUILDCMD} - -lwresd@EXEEXT@: named-pkcs11@EXEEXT@ - rm -f lwresd@EXEEXT@ - @LN@ named-pkcs11@EXEEXT@ lwresd@EXEEXT@ - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean maintainer-clean:: - rm -f ${TARGETS} ${OBJS} - -maintainer-clean:: - -bind9.xsl.h: bind9.xsl ${srcdir}/convertxsl.pl - ${PERL} ${srcdir}/convertxsl.pl < ${srcdir}/bind9.xsl > bind9.xsl.h - -depend: bind9.xsl.h -statschannel.@O@: bind9.xsl.h - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install-man5: named.conf.5 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man5 - -install-man8: named.8 lwresd.8 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install-man: install-man5 install-man8 - -install:: named-pkcs11@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-pkcs11@EXEEXT@ ${DESTDIR}${sbindir} - -uninstall:: - ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/named-pkcs11@EXEEXT@ - -@DLZ_DRIVER_RULES@ - -named-symtbl.@O@: named-symtbl.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c named-symtbl.c diff --git a/bin/named-pkcs11/bind9.xsl b/bin/named-pkcs11/bind9.xsl deleted file mode 100644 index 9a1c6ff..0000000 --- a/bin/named-pkcs11/bind9.xsl +++ /dev/null @@ -1,1096 +0,0 @@ - - - - - - - - - - - - - - - - - ISC BIND 9 Statistics - - -
-

ISC Bind 9 Configuration and Statistics

-
-

Alternate statistics views: All, - Status, - Server, - Zones, - Network, - Tasks, - Memory and - Traffic Size

-
-

Server Status

- - - - - - - - - - - - - - - - - -
Boot time: - -
Last reconfigured: - -
Current time: - -
Server version: - -
-
- - -

Incoming Requests by DNS Opcode

- -
- [cannot display chart] -
-
- - - - - - even - odd - - - - - - - - - - - -
- - - -
Total: - -
-
-
- - - -

Incoming Queries by Query Type

-
- [cannot display chart] -
-
- - - - - - even - odd - - - - - - - - - - - -
- - - -
Total: - -
-
-
- -

Outgoing Queries per view

- -

View

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
- -

Server Statistics

- - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Zone Maintenance Statistics

- - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
- -

Resolver Statistics (Common)

- - - - - - even - odd - - - - - - - -
- - - -
-
- - -

Resolver Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

ADB Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Cache Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Cache DB RRsets for View

- - - - - even - odd - - - - - - - -
- - - -
-
-
-
- -

Traffic Size Statistics

-
- -

UDP Requests Received

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

UDP Responses Sent

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

TCP Requests Received

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

TCP Responses Sent

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

Socket I/O Statistics

- - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Zones for View

- - - - - - - even - odd - - - - - - - - - -
NameClassTypeSerial
-
-
- -

Received QTYPES per view/zone

- -

View

- - - - - -

Zone

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
-
- -

Response Codes per view/zone

- -

View

- - - - - -

Zone

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
-
- -

Network Status

- - - - - - - - - - - - - - - even - odd - - - - - - - - - - - - -
IDNameTypeReferencesLocalAddressPeerAddressState
- - - - - - - - - - - - - - - -
-
-
- -

Task Manager Configuration

- - - - - - - - - - - - - - - - - - - - - -
Thread-Model - -
Worker Threads - -
Default Quantum - -
Tasks Running - -
Tasks Ready - -
-
-
- -

Tasks

- - - - - - - - - - - - - - even - odd - - - - - - - - - - - -
IDNameReferencesStateQuantumEvents
- - - - - - - - - - - -
-
-
- -

Memory Usage Summary

- - - - - even - odd - - - - - - - -
- - - -
-
-
- -

Memory Contexts

- - - - - - - - - - - - - - - - - - even - odd - - - - - - - - - - - - - - - -
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
- - - - - - - - - - - - - - - - - - - -
-
-
- - - -
-
diff --git a/bin/named-pkcs11/bind9.xsl.h b/bin/named-pkcs11/bind9.xsl.h deleted file mode 100644 index 9ce8cd7..0000000 --- a/bin/named-pkcs11/bind9.xsl.h +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Generated by convertxsl.pl 1.14 2008/07/17 23:43:26 jinmei Exp - * From unknown - */ -static char xslmsg[] = - "\n" - "\n" - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " ISC BIND 9 Statistics\n" - " \n" - " \n" - "
\n" - "

ISC Bind 9 Configuration and Statistics

\n" - "
\n" - "

Alternate statistics views: All,\n" - " Status,\n" - " Server,\n" - " Zones,\n" - " Network,\n" - " Tasks,\n" - " Memory and\n" - " Traffic Size

\n" - "
\n" - "

Server Status

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
Boot time:\n" - " \n" - "
Last reconfigured:\n" - " \n" - "
Current time:\n" - " \n" - "
Server version:\n" - " \n" - "
\n" - "
\n" - " \n" - " \n" - "

Incoming Requests by DNS Opcode

\n" - " \n" - "
\n" - " [cannot display chart]\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
Total:\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - "

Incoming Queries by Query Type

\n" - "
\n" - " [cannot display chart]\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
Total:\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Outgoing Queries per view

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Server Statistics

\n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Zone Maintenance Statistics

\n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - " \n" - "

Resolver Statistics (Common)

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - " \n" - " \n" - "

Resolver Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

ADB Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Cache Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Cache DB RRsets for View

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Traffic Size Statistics

\n" - "
\n" - " \n" - "

UDP Requests Received

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

UDP Responses Sent

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

TCP Requests Received

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

TCP Responses Sent

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Socket I/O Statistics

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Zones for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
NameClassTypeSerial
\n" - "
\n" - "
\n" - " \n" - "

Received QTYPES per view/zone

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "

Zone

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Response Codes per view/zone

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "

Zone

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Network Status

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameTypeReferencesLocalAddressPeerAddressState
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Task Manager Configuration

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
Thread-Model\n" - " \n" - "
Worker Threads\n" - " \n" - "
Default Quantum\n" - " \n" - "
Tasks Running\n" - " \n" - "
Tasks Ready\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Tasks

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameReferencesStateQuantumEvents
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Memory Usage Summary

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Memory Contexts

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "

Internet Systems Consortium Inc.
http://www.isc.org

\n" - " \n" - " \n" - "
\n" - "
\n"; diff --git a/bin/named-pkcs11/builtin.c b/bin/named-pkcs11/builtin.c deleted file mode 100644 index 25a4df1..0000000 --- a/bin/named-pkcs11/builtin.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file - * \brief - * The built-in "version", "hostname", "id", "authors" and "empty" databases. - */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -typedef struct builtin builtin_t; - -static isc_result_t do_version_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_dns64_lookup(dns_sdblookup_t *lookup); - -/* - * We can't use function pointers as the db_data directly - * because ANSI C does not guarantee that function pointers - * can safely be cast to void pointers and back. - */ - -struct builtin { - isc_result_t (*do_lookup)(dns_sdblookup_t *lookup); - char *server; - char *contact; -}; - -static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; -static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; -static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL }; -static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; -static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; -static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL }; - -static dns_sdbimplementation_t *builtin_impl; -static dns_sdbimplementation_t *dns64_impl; - -/* - * Pre computed HEX * 16 or 1 table. - */ -static const unsigned char hex16[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*00*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*20*/ - 0, 16, 32, 48, 64, 80, 96,112,128,144, 1, 1, 1, 1, 1, 1, /*30*/ - 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*50*/ - 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*60*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/ - 1, 1, 1, 1, 1, 1, 1, 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, /*90*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*A0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*B0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*C0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*D0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*E0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /*F0*/ -}; - -const unsigned char decimal[] = "0123456789"; - -static size_t -dns64_rdata(unsigned char *v, size_t start, unsigned char *rdata) { - size_t i, j = 0; - - for (i = 0; i < 4U; i++) { - unsigned char c = v[start++]; - if (start == 7U) - start++; - if (c > 99) { - rdata[j++] = 3; - rdata[j++] = decimal[c/100]; c = c % 100; - rdata[j++] = decimal[c/10]; c = c % 10; - rdata[j++] = decimal[c]; - } else if (c > 9) { - rdata[j++] = 2; - rdata[j++] = decimal[c/10]; c = c % 10; - rdata[j++] = decimal[c]; - } else { - rdata[j++] = 1; - rdata[j++] = decimal[c]; - } - } - memmove(&rdata[j], "\07in-addr\04arpa", 14); - return (j + 14); -} - -static isc_result_t -dns64_cname(const dns_name_t *zone, const dns_name_t *name, - dns_sdblookup_t *lookup) -{ - size_t zlen, nlen, j, len; - unsigned char v[16], n; - unsigned int i; - unsigned char rdata[sizeof("123.123.123.123.in-addr.arpa.")]; - unsigned char *ndata; - - /* - * The combined length of the zone and name is 74. - * - * The minimum zone length is 10 ((3)ip6(4)arpa(0)). - * - * The length of name should always be even as we are expecting - * a series of nibbles. - */ - zlen = zone->length; - nlen = name->length; - if ((zlen + nlen) > 74U || zlen < 10U || (nlen % 2) != 0U) - return (ISC_R_NOTFOUND); - - /* - * We assume the zone name is well formed. - */ - - /* - * XXXMPA We could check the dns64 suffix here if we need to. - */ - /* - * Check that name is a series of nibbles. - * Compute the byte values that correspond to the nibbles as we go. - * - * Shift the final result 4 bits, by setting 'i' to 1, if we if we - * have a odd number of nibbles so that "must be zero" tests below - * are byte aligned and we correctly return ISC_R_NOTFOUND or - * ISC_R_SUCCESS. We will not generate a CNAME in this case. - */ - ndata = name->ndata; - i = (nlen % 4) == 2U ? 1 : 0; - j = nlen; - memset(v, 0, sizeof(v)); - while (j != 0U) { - INSIST((i/2) < sizeof(v)); - if (ndata[0] != 1) - return (ISC_R_NOTFOUND); - n = hex16[ndata[1]&0xff]; - if (n == 1) - return (ISC_R_NOTFOUND); - v[i/2] = n | (v[i/2]>>4); - j -= 2; - ndata += 2; - i++; - } - - /* - * If we get here then we know name only consisted of nibbles. - * Now we need to determine if the name exists or not and whether - * it corresponds to a empty node in the zone or there should be - * a CNAME. - */ -#define ZLEN(x) (10 + (x)/2) - switch (zlen) { - case ZLEN(32): /* prefix len 32 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 16U && v[(nlen-1)/4 - 4] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 8, rdata); - break; - case ZLEN(40): /* prefix len 40 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 12U && v[(nlen-1)/4 - 3] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 6, rdata); - break; - case ZLEN(48): /* prefix len 48 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 8U && v[(nlen-1)/4 - 2] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 5, rdata); - break; - case ZLEN(56): /* prefix len 56 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 4U && v[(nlen-1)/4 - 1] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 4, rdata); - break; - case ZLEN(64): /* prefix len 64 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (v[(nlen-1)/4] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 3, rdata); - break; - case ZLEN(96): /* prefix len 96 */ - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 0, rdata); - break; - default: - /* - * This should never be reached unless someone adds a - * zone declaration with this internal type to named.conf. - */ - return (ISC_R_NOTFOUND); - } - return (dns_sdb_putrdata(lookup, dns_rdatatype_cname, 600, - rdata, (unsigned int)len)); -} - -static isc_result_t -builtin_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - UNUSED(methods); - UNUSED(clientinfo); - - if (strcmp(name, "@") == 0) - return (b->do_lookup(lookup)); - else - return (ISC_R_NOTFOUND); -} - -static isc_result_t -dns64_lookup(const dns_name_t *zone, const dns_name_t *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(methods); - UNUSED(clientinfo); - - if (name->labels == 0 && name->length == 0) - return (b->do_lookup(lookup)); - else - return (dns64_cname(zone, name, lookup)); -} - -static isc_result_t -put_txt(dns_sdblookup_t *lookup, const char *text) { - unsigned char buf[256]; - unsigned int len = strlen(text); - if (len > 255) - len = 255; /* Silently truncate */ - buf[0] = len; - memmove(&buf[1], text, len); - return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1)); -} - -static isc_result_t -do_version_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->version_set) { - if (ns_g_server->version == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->version)); - } else { - return (put_txt(lookup, ns_g_version)); - } -} - -static isc_result_t -do_hostname_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->hostname_set) { - if (ns_g_server->hostname == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->hostname)); - } else { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } -} - -static isc_result_t -do_authors_lookup(dns_sdblookup_t *lookup) { - isc_result_t result; - const char **p; - static const char *authors[] = { - "Mark Andrews", - "Curtis Blackburn", - "James Brister", - "Ben Cottrell", - "John H. DuBois III", - "Francis Dupont", - "Michael Graff", - "Andreas Gustafsson", - "Bob Halley", - "Evan Hunt", - "JINMEI Tatuya", - "Witold Krecicki", - "David Lawrence", - "Scott Mann", - "Danny Mayer", - "Damien Neil", - "Matt Nelson", - "Jeremy C. Reed", - "Michael Sawyer", - "Brian Wellington", - NULL - }; - - /* - * If a version string is specified, disable the authors.bind zone. - */ - if (ns_g_server->version_set) - return (ISC_R_SUCCESS); - - for (p = authors; *p != NULL; p++) { - result = put_txt(lookup, *p); - if (result != ISC_R_SUCCESS) - return (result); - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_id_lookup(dns_sdblookup_t *lookup) { - - if (ns_g_server->server_usehostname) { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } - - if (ns_g_server->server_id == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->server_id)); -} - -static isc_result_t -do_dns64_lookup(dns_sdblookup_t *lookup) { - UNUSED(lookup); - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_empty_lookup(dns_sdblookup_t *lookup) { - - UNUSED(lookup); - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { - isc_result_t result; - const char *contact = "hostmaster"; - const char *server = "@"; - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - UNUSED(dbdata); - - if (b == &empty_builtin) { - server = "."; - contact = "."; - } else { - if (b->server != NULL) - server = b->server; - if (b->contact != NULL) - contact = b->contact; - } - - result = dns_sdb_putsoa(lookup, server, contact, 0); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - result = dns_sdb_putrr(lookup, "ns", 0, server); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - REQUIRE(argc >= 1); - - UNUSED(zone); - UNUSED(driverdata); - - if (strcmp(argv[0], "empty") == 0 || strcmp(argv[0], "dns64") == 0) { - if (argc != 3) - return (DNS_R_SYNTAX); - } else if (argc != 1) - return (DNS_R_SYNTAX); - - if (strcmp(argv[0], "version") == 0) - *dbdata = &version_builtin; - else if (strcmp(argv[0], "hostname") == 0) - *dbdata = &hostname_builtin; - else if (strcmp(argv[0], "authors") == 0) - *dbdata = &authors_builtin; - else if (strcmp(argv[0], "id") == 0) - *dbdata = &id_builtin; - else if (strcmp(argv[0], "empty") == 0 || - strcmp(argv[0], "dns64") == 0) { - builtin_t *empty; - char *server; - char *contact; - /* - * We don't want built-in zones to fail. Fallback to - * the static configuration if memory allocation fails. - */ - empty = isc_mem_get(ns_g_mctx, sizeof(*empty)); - server = isc_mem_strdup(ns_g_mctx, argv[1]); - contact = isc_mem_strdup(ns_g_mctx, argv[2]); - if (empty == NULL || server == NULL || contact == NULL) { - if (strcmp(argv[0], "empty") == 0) - *dbdata = &empty_builtin; - else - *dbdata = &dns64_builtin; - if (server != NULL) - isc_mem_free(ns_g_mctx, server); - if (contact != NULL) - isc_mem_free(ns_g_mctx, contact); - if (empty != NULL) - isc_mem_put(ns_g_mctx, empty, sizeof (*empty)); - } else { - if (strcmp(argv[0], "empty") == 0) - memmove(empty, &empty_builtin, - sizeof (empty_builtin)); - else - memmove(empty, &dns64_builtin, - sizeof (empty_builtin)); - empty->server = server; - empty->contact = contact; - *dbdata = empty; - } - } else - return (ISC_R_NOTIMPLEMENTED); - return (ISC_R_SUCCESS); -} - -static void -builtin_destroy(const char *zone, void *driverdata, void **dbdata) { - builtin_t *b = (builtin_t *) *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - /* - * Don't free the static versions. - */ - if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || - *dbdata == &authors_builtin || *dbdata == &id_builtin || - *dbdata == &empty_builtin || *dbdata == &dns64_builtin) - return; - - isc_mem_free(ns_g_mctx, b->server); - isc_mem_free(ns_g_mctx, b->contact); - isc_mem_put(ns_g_mctx, b, sizeof (*b)); -} - -static dns_sdbmethods_t builtin_methods = { - builtin_lookup, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - builtin_destroy, - NULL -}; - -static dns_sdbmethods_t dns64_methods = { - NULL, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - builtin_destroy, - dns64_lookup, -}; - -isc_result_t -ns_builtin_init(void) { - RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA, - ns_g_mctx, &builtin_impl) - == ISC_R_SUCCESS); - RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_DNS64, - ns_g_mctx, &dns64_impl) - == ISC_R_SUCCESS); - return (ISC_R_SUCCESS); -} - -void -ns_builtin_deinit(void) { - dns_sdb_unregister(&builtin_impl); - dns_sdb_unregister(&dns64_impl); -} diff --git a/bin/named-pkcs11/client.c b/bin/named-pkcs11/client.c deleted file mode 100644 index 4d140e8..0000000 --- a/bin/named-pkcs11/client.c +++ /dev/null @@ -1,4333 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/*** - *** Client - ***/ - -/*! \file - * Client Routines - * - * Important note! - * - * All client state changes, other than that from idle to listening, occur - * as a result of events. This guarantees serialization and avoids the - * need for locking. - * - * If a routine is ever created that allows someone other than the client's - * task to change the client, then the client will have to be locked. - */ - -#define NS_CLIENT_TRACE -#ifdef NS_CLIENT_TRACE -#define CTRACE(m) ns_client_log(client, \ - NS_LOGCATEGORY_CLIENT, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "%s", (m)) -#define MTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "clientmgr @%p: %s", manager, (m)) -#else -#define CTRACE(m) ((void)(m)) -#define MTRACE(m) ((void)(m)) -#endif - -#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -#define TCP_BUFFER_SIZE (65535 + 2) -#define SEND_BUFFER_SIZE 4096 -#define RECV_BUFFER_SIZE 4096 - -#define TCP_CLIENTS_PER_CONN 23 -/*%< - * Number of simultaneous ns_clients_t (queries in flight) for one - * TCP connection. The number was arbitrarily picked and might be - * changed in the future. - */ - -#ifdef ISC_PLATFORM_USETHREADS - -#define NMCTXS 100 -/*%< - * Number of 'mctx pools' for clients. (Should this be configurable?) - * When enabling threads, we use a pool of memory contexts shared by - * client objects, since concurrent access to a shared context would cause - * heavy contentions. The above constant is expected to be enough for - * completely avoiding contentions among threads for an authoritative-only - * server. - */ -#else -#define NMCTXS 0 -/*%< - * If named with built without thread, simply share manager's context. Using - * a separate context in this case would simply waste memory. - */ -#endif - -#define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */ -#define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */ - -#define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0) -#define WANTEXPIRE(x) (((x)->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0) - -/*% nameserver client manager structure */ -struct ns_clientmgr { - /* Unlocked. */ - unsigned int magic; - - /* The queue object has its own locks */ - client_queue_t inactive; /*%< To be recycled */ - - isc_mem_t * mctx; - isc_taskmgr_t * taskmgr; - isc_timermgr_t * timermgr; - - /* Lock covers manager state. */ - isc_mutex_t lock; - bool exiting; - - /* Lock covers the clients list */ - isc_mutex_t listlock; - client_list_t clients; /*%< All active clients */ - - /* Lock covers the recursing list */ - isc_mutex_t reclock; - client_list_t recursing; /*%< Recursing clients */ - -#if NMCTXS > 0 - /*%< mctx pool for clients. */ - unsigned int nextmctx; - isc_mem_t * mctxpool[NMCTXS]; -#endif -}; - -#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) - -/*! - * Client object states. Ordering is significant: higher-numbered - * states are generally "more active", meaning that the client can - * have more dynamically allocated data, outstanding events, etc. - * In the list below, any such properties listed for state N - * also apply to any state > N. - * - * To force the client into a less active state, set client->newstate - * to that state and call exit_check(). This will cause any - * activities defined for higher-numbered states to be aborted. - */ - -#define NS_CLIENTSTATE_FREED 0 -/*%< - * The client object no longer exists. - */ - -#define NS_CLIENTSTATE_INACTIVE 1 -/*%< - * The client object exists and has a task and timer. - * Its "query" struct and sendbuf are initialized. - * It is on the client manager's list of inactive clients. - * It has a message and OPT, both in the reset state. - */ - -#define NS_CLIENTSTATE_READY 2 -/*%< - * The client object is either a TCP or a UDP one, and - * it is associated with a network interface. It is on the - * client manager's list of active clients. - * - * If it is a TCP client object, it has a TCP listener socket - * and an outstanding TCP listen request. - * - * If it is a UDP client object, it has a UDP listener socket - * and an outstanding UDP receive request. - */ - -#define NS_CLIENTSTATE_READING 3 -/*%< - * The client object is a TCP client object that has received - * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an - * outstanding TCP read request. This state is not used for - * UDP client objects. - */ - -#define NS_CLIENTSTATE_WORKING 4 -/*%< - * The client object has received a request and is working - * on it. It has a view, and it may have any of a non-reset OPT, - * recursion quota, and an outstanding write request. - */ - -#define NS_CLIENTSTATE_RECURSING 5 -/*%< - * The client object is recursing. It will be on the 'recursing' - * list. - */ - -#define NS_CLIENTSTATE_MAX 9 -/*%< - * Sentinel value used to indicate "no state". When client->newstate - * has this value, we are not attempting to exit the current state. - * Must be greater than any valid state. - */ - -/* - * Enable ns_client_dropport() by default. - */ -#ifndef NS_CLIENT_DROPPORT -#define NS_CLIENT_DROPPORT 1 -#endif - -#ifdef NS_CLIENT_NCRSTDATOMIC -_Atomic(unsigned int) ns_client_requests; -#else -unsigned int ns_client_requests; -#endif - -static void client_read(ns_client_t *client); -static void client_accept(ns_client_t *client); -static void client_udprecv(ns_client_t *client); -static void clientmgr_destroy(ns_clientmgr_t *manager); -static bool exit_check(ns_client_t *client); -static void ns_client_endrequest(ns_client_t *client); -static void client_start(isc_task_t *task, isc_event_t *event); -static void client_request(isc_task_t *task, isc_event_t *event); -static void ns_client_dumpmessage(ns_client_t *client, const char *reason); -static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, - dns_dispatch_t *disp, bool tcp); -static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, - isc_socket_t *sock, ns_client_t *oldclient); -static inline bool -allowed(isc_netaddr_t *addr, const dns_name_t *signer, - isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, - uint8_t *ecs_scope, dns_acl_t *acl); -static void compute_cookie(ns_client_t *client, uint32_t when, - uint32_t nonce, const unsigned char *secret, - isc_buffer_t *buf); - -void -ns_client_recursing(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING); - - LOCK(&client->manager->reclock); - client->newstate = client->state = NS_CLIENTSTATE_RECURSING; - ISC_LIST_APPEND(client->manager->recursing, client, rlink); - UNLOCK(&client->manager->reclock); -} - -void -ns_client_killoldestquery(ns_client_t *client) { - ns_client_t *oldest; - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->reclock); - oldest = ISC_LIST_HEAD(client->manager->recursing); - if (oldest != NULL) { - ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink); - UNLOCK(&client->manager->reclock); - ns_query_cancel(oldest); - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_reclimitdropped); - } else { - UNLOCK(&client->manager->reclock); - } -} - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds) { - isc_result_t result; - isc_interval_t interval; - - isc_interval_set(&interval, seconds, 0); - result = isc_timer_reset(client->timer, isc_timertype_once, NULL, - &interval, false); - client->timerset = true; - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "setting timeout: %s", - isc_result_totext(result)); - /* Continue anyway. */ - } -} - -/*% - * Allocate a reference-counted object that will maintain a single pointer to - * the (also reference-counted) TCP client quota, shared between all the - * clients processing queries on a single TCP connection, so that all - * clients sharing the one socket will together consume only one slot in - * the 'tcp-clients' quota. - */ -static isc_result_t -tcpconn_init(ns_client_t *client, bool force) { - isc_result_t result; - isc_quota_t *quota = NULL; - ns_tcpconn_t *tconn = NULL; - - REQUIRE(client->tcpconn == NULL); - - /* - * Try to attach to the quota first, so we won't pointlessly - * allocate memory for a tcpconn object if we can't get one. - */ - if (force) { - result = isc_quota_force(&ns_g_server->tcpquota, "a); - } else { - result = isc_quota_attach(&ns_g_server->tcpquota, "a); - } - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * A global memory context is used for the allocation as different - * client structures may have different memory contexts assigned and a - * reference counter allocated here might need to be freed by a - * different client. The performance impact caused by memory context - * contention here is expected to be negligible, given that this code - * is only executed for TCP connections. - */ - tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn)); - if (tconn == NULL) { - isc_quota_detach("a); - return (ISC_R_NOMEMORY); - } - - isc_refcount_init(&tconn->clients, 1); /* Current client */ - tconn->tcpquota = quota; - quota = NULL; - tconn->pipelined = false; - - client->tcpconn = tconn; - - return (ISC_R_SUCCESS); -} - -/*% - * Increase the count of client structures sharing the TCP connection - * that 'source' is associated with; add a pointer to the same tcpconn - * to 'target', thus associating it with the same TCP connection. - */ -static void -tcpconn_attach(ns_client_t *source, ns_client_t *target) { - int old_clients; - - REQUIRE(source->tcpconn != NULL); - REQUIRE(target->tcpconn == NULL); - REQUIRE(source->tcpconn->pipelined); - - isc_refcount_increment(&source->tcpconn->clients, &old_clients); - INSIST(old_clients > 1); - target->tcpconn = source->tcpconn; -} - -/*% - * Decrease the count of client structures sharing the TCP connection that - * 'client' is associated with. If this is the last client using this TCP - * connection, we detach from the TCP quota and free the tcpconn - * object. Either way, client->tcpconn is set to NULL. - */ -static void -tcpconn_detach(ns_client_t *client) { - ns_tcpconn_t *tconn = NULL; - int old_clients; - - REQUIRE(client->tcpconn != NULL); - - tconn = client->tcpconn; - client->tcpconn = NULL; - - isc_refcount_decrement(&tconn->clients, &old_clients); - if (old_clients == 0) { - isc_quota_detach(&tconn->tcpquota); - isc_mem_free(ns_g_mctx, tconn); - } -} - -/*% - * Mark a client as active and increment the interface's 'ntcpactive' - * counter, as a signal that there is at least one client servicing - * TCP queries for the interface. If we reach the TCP client quota at - * some point, this will be used to determine whether a quota overrun - * should be permitted. - * - * Marking the client active with the 'tcpactive' flag ensures proper - * accounting, by preventing us from incrementing or decrementing - * 'ntcpactive' more than once per client. - */ -static void -mark_tcp_active(ns_client_t *client, bool active) { - if (active && !client->tcpactive) { - isc_refcount_increment0(&client->interface->ntcpactive, NULL); - client->tcpactive = active; - } else if (!active && client->tcpactive) { - isc_refcount_decrement(&client->interface->ntcpactive, NULL); - client->tcpactive = active; - } -} - -/*% - * Check for a deactivation or shutdown request and take appropriate - * action. Returns true if either is in progress; in this case - * the caller must no longer use the client object as it may have been - * freed. - */ -static bool -exit_check(ns_client_t *client) { - bool destroy_manager = false; - ns_clientmgr_t *manager = NULL; - - REQUIRE(NS_CLIENT_VALID(client)); - manager = client->manager; - - if (client->state <= client->newstate) - return (false); /* Business as usual. */ - - INSIST(client->newstate < NS_CLIENTSTATE_RECURSING); - - /* - * We need to detach from the view early when shutting down - * the server to break the following vicious circle: - * - * - The resolver will not shut down until the view refcount is zero - * - The view refcount does not go to zero until all clients detach - * - The client does not detach from the view until references is zero - * - references does not go to zero until the resolver has shut down - * - * Keep the view attached until any outstanding updates complete. - */ - if (client->nupdates == 0 && - client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) - dns_view_detach(&client->view); - - if (client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING) - { - INSIST(client->newstate <= NS_CLIENTSTATE_READING); - /* - * Let the update processing complete. - */ - if (client->nupdates > 0) - return (true); - - /* - * We are trying to abort request processing. - */ - if (client->nsends > 0) { - isc_socket_t *sock; - if (TCP_CLIENT(client)) - sock = client->tcpsocket; - else - sock = client->udpsocket; - isc_socket_cancel(sock, client->task, - ISC_SOCKCANCEL_SEND); - } - - if (! (client->nsends == 0 && client->nrecvs == 0 && - client->references == 0)) - { - /* - * Still waiting for I/O cancel completion. - * or lingering references. - */ - return (true); - } - - /* - * I/O cancel is complete. Burn down all state - * related to the current request. Ensure that - * the client is no longer on the recursing list. - * - * We need to check whether the client is still linked, - * because it may already have been removed from the - * recursing list by ns_client_killoldestquery() - */ - if (client->state == NS_CLIENTSTATE_RECURSING) { - LOCK(&manager->reclock); - if (ISC_LINK_LINKED(client, rlink)) - ISC_LIST_UNLINK(manager->recursing, - client, rlink); - UNLOCK(&manager->reclock); - } - ns_client_endrequest(client); - - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - if (NS_CLIENTSTATE_READING == client->newstate) { - INSIST(client->tcpconn != NULL); - if (!client->tcpconn->pipelined) { - client_read(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (true); /* We're done. */ - } else if (client->mortal) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - } else - return (false); - } - } - - if (client->state == NS_CLIENTSTATE_READING) { - /* - * We are trying to abort the current TCP connection, - * if any. - */ - INSIST(client->recursionquota == NULL); - INSIST(client->newstate <= NS_CLIENTSTATE_READY); - - if (client->nreads > 0) { - dns_tcpmsg_cancelread(&client->tcpmsg); - /* Still waiting for read cancel completion? */ - if (client->nreads > 0) { - return (true); - } - } - - if (client->tcpmsg_valid) { - dns_tcpmsg_invalidate(&client->tcpmsg); - client->tcpmsg_valid = false; - } - - /* - * Soon the client will be ready to accept a new TCP - * connection or UDP request, but we may have enough - * clients doing that already. Check whether this client - * needs to remain active and allow it go inactive if - * not. - * - * UDP clients always go inactive at this point, but a TCP - * client may need to stay active and return to READY - * state if no other clients are available to listen - * for TCP requests on this interface. - * - * Regardless, if we're going to FREED state, that means - * the system is shutting down and we don't need to - * retain clients. - */ - if (client->mortal && TCP_CLIENT(client) && - client->newstate != NS_CLIENTSTATE_FREED && - !ns_g_clienttest && - isc_refcount_current(&client->interface->ntcpaccepting) == 0) - { - /* Nobody else is accepting */ - client->mortal = false; - client->newstate = NS_CLIENTSTATE_READY; - } - - /* - * Detach from TCP connection and TCP client quota, - * if appropriate. If this is the last reference to - * the TCP connection in our pipeline group, the - * TCP quota slot will be released. - */ - if (client->tcpconn) { - tcpconn_detach(client); - } - - if (client->tcpsocket != NULL) { - CTRACE("closetcp"); - isc_socket_detach(&client->tcpsocket); - mark_tcp_active(client, false); - } - - if (client->timerset) { - (void)isc_timer_reset(client->timer, - isc_timertype_inactive, - NULL, NULL, true); - client->timerset = false; - } - - client->peeraddr_valid = false; - - client->state = NS_CLIENTSTATE_READY; - - /* - * We don't need the client; send it to the inactive - * queue for recycling. - */ - if (client->mortal) { - if (client->newstate > NS_CLIENTSTATE_INACTIVE) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - } - } - - if (NS_CLIENTSTATE_READY == client->newstate) { - if (TCP_CLIENT(client)) { - client_accept(client); - } else { - client_udprecv(client); - } - client->newstate = NS_CLIENTSTATE_MAX; - return (true); - } - } - - if (client->state == NS_CLIENTSTATE_READY) { - INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); - - /* - * We are trying to enter the inactive state. - */ - if (client->naccepts > 0) { - isc_socket_cancel(client->tcplistener, client->task, - ISC_SOCKCANCEL_ACCEPT); - /* Still waiting for accept cancel completion? */ - if (client->naccepts > 0) { - return (true); - } - } - - /* Accept cancel is complete. */ - if (client->nrecvs > 0) { - isc_socket_cancel(client->udpsocket, client->task, - ISC_SOCKCANCEL_RECV); - /* Still waiting for recv cancel completion? */ - if (client->nrecvs > 0) { - return (true); - } - } - - /* Still waiting for control event to be delivered */ - if (client->nctls > 0) { - return (true); - } - - INSIST(client->naccepts == 0); - INSIST(client->recursionquota == NULL); - if (client->tcplistener != NULL) { - isc_socket_detach(&client->tcplistener); - mark_tcp_active(client, false); - } - if (client->udpsocket != NULL) { - isc_socket_detach(&client->udpsocket); - } - - /* Deactivate the client. */ - if (client->interface != NULL) { - ns_interface_detach(&client->interface); - } - - if (client->dispatch != NULL) { - dns_dispatch_detach(&client->dispatch); - } - - client->attributes = 0; - client->mortal = false; - - if (client->keytag != NULL) { - isc_mem_put(client->mctx, client->keytag, - client->keytag_len); - client->keytag_len = 0; - } - - /* - * Put the client on the inactive list. If we are aiming for - * the "freed" state, it will be removed from the inactive - * list shortly, and we need to keep the manager locked until - * that has been done, lest the manager decide to reactivate - * the dying client in between. - */ - client->state = NS_CLIENTSTATE_INACTIVE; - INSIST(client->recursionquota == NULL); - - if (client->state == client->newstate) { - client->newstate = NS_CLIENTSTATE_MAX; - if (!ns_g_clienttest && manager != NULL && - !manager->exiting) - { - ISC_QUEUE_PUSH(manager->inactive, client, - ilink); - } - if (client->needshutdown) { - isc_task_shutdown(client->task); - } - return (true); - } - } - - if (client->state == NS_CLIENTSTATE_INACTIVE) { - INSIST(client->newstate == NS_CLIENTSTATE_FREED); - /* - * We are trying to free the client. - * - * When "shuttingdown" is true, either the task has received - * its shutdown event or no shutdown event has ever been - * set up. Thus, we have no outstanding shutdown - * event at this point. - */ - REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); - - INSIST(client->recursionquota == NULL); - INSIST(!ISC_QLINK_LINKED(client, ilink)); - - if (manager != NULL) { - LOCK(&manager->listlock); - ISC_LIST_UNLINK(manager->clients, client, link); - LOCK(&manager->lock); - if (manager->exiting && - ISC_LIST_EMPTY(manager->clients)) - destroy_manager = true; - UNLOCK(&manager->lock); - UNLOCK(&manager->listlock); - } - - ns_query_free(client); - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - isc_event_free((isc_event_t **)&client->sendevent); - isc_event_free((isc_event_t **)&client->recvevent); - isc_timer_detach(&client->timer); - if (client->delaytimer != NULL) - isc_timer_detach(&client->delaytimer); - - if (client->tcpbuf != NULL) - isc_mem_put(client->mctx, client->tcpbuf, - TCP_BUFFER_SIZE); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, - &client->opt); - } - if (client->keytag != NULL) { - isc_mem_put(client->mctx, client->keytag, - client->keytag_len); - client->keytag_len = 0; - } - - dns_message_detach(&client->message); - - /* - * Detaching the task must be done after unlinking from - * the manager's lists because the manager accesses - * client->task. - */ - if (client->task != NULL) - isc_task_detach(&client->task); - - CTRACE("free"); - client->magic = 0; - - /* - * Check that there are no other external references to - * the memory context. - */ - if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) { - isc_mem_stats(client->mctx, stderr); - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Destroy the fetchlock mutex that was created in - * ns_query_init(). - */ - DESTROYLOCK(&client->query.fetchlock); - - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - } - - if (destroy_manager && manager != NULL) - clientmgr_destroy(manager); - - return (true); -} - -/*% - * The client's task has received the client's control event - * as part of the startup process. - */ -static void -client_start(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *) event->ev_arg; - - INSIST(task == client->task); - - UNUSED(task); - - INSIST(client->nctls == 1); - client->nctls--; - - if (exit_check(client)) - return; - - if (TCP_CLIENT(client)) { - if (client->tcpconn != NULL) { - client_read(client); - } else { - client_accept(client); - } - } else { - client_udprecv(client); - } -} - -/*% - * The client's task has received a shutdown event. - */ -static void -client_shutdown(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - UNUSED(task); - - CTRACE("shutdown"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - ISC_QUEUE_UNLINKIFLINKED(client->manager->inactive, client, ilink); - - client->newstate = NS_CLIENTSTATE_FREED; - client->needshutdown = false; - (void)exit_check(client); -} - -static void -ns_client_endrequest(ns_client_t *client) { - INSIST(client->naccepts == 0); - INSIST(client->nreads == 0); - INSIST(client->nsends == 0); - INSIST(client->nrecvs == 0); - INSIST(client->nupdates == 0); - INSIST(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING); - - CTRACE("endrequest"); - - if (client->next != NULL) { - (client->next)(client); - client->next = NULL; - } - - if (client->view != NULL) { -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_resolver) { - dns_cache_clean(client->view->cache, INT_MAX); - dns_adb_flush(client->view->adb); - } -#endif - dns_view_detach(&client->view); - } - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - - client->signer = NULL; - client->udpsize = 512; - client->extflags = 0; - client->ednsversion = -1; - dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); - - if (client->recursionquota != NULL) { - isc_quota_detach(&client->recursionquota); - isc_stats_decrement(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - - /* - * Clear all client attributes that are specific to - * the request; that's all except the TCP flag. - */ - client->attributes &= NS_CLIENTATTR_TCP; -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_client || - ns_g_fuzz_type == ns_fuzz_tcpclient || - ns_g_fuzz_type == ns_fuzz_resolver) { - named_fuzz_notify(); - } -#endif /* ENABLE_AFL */ - -} - -void -ns_client_next(ns_client_t *client, isc_result_t result) { - int newstate; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING || - client->state == NS_CLIENTSTATE_READING); - - CTRACE("next"); - - if (result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request failed: %s", isc_result_totext(result)); - - /* - * An error processing a TCP request may have left - * the connection out of sync. To be safe, we always - * sever the connection when result != ISC_R_SUCCESS. - */ - if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) - newstate = NS_CLIENTSTATE_READING; - else - newstate = NS_CLIENTSTATE_READY; - - if (client->newstate > newstate) - client->newstate = newstate; - (void)exit_check(client); -} - - -static void -client_senddone(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - - REQUIRE(sevent != NULL); - REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); - client = sevent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(sevent == client->sendevent); - - UNUSED(task); - - CTRACE("senddone"); - - if (sevent->result != ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "error sending response: %s", - isc_result_totext(sevent->result)); - - INSIST(client->nsends > 0); - client->nsends--; - - if (client->tcpbuf != NULL) { - INSIST(TCP_CLIENT(client)); - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - ns_client_next(client, ISC_R_SUCCESS); -} - -/*% - * We only want to fail with ISC_R_NOSPACE when called from - * ns_client_sendraw() and not when called from ns_client_send(), - * tcpbuffer is NULL when called from ns_client_sendraw() and - * length != 0. tcpbuffer != NULL when called from ns_client_send() - * and length == 0. - */ - -static isc_result_t -client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, - isc_buffer_t *tcpbuffer, uint32_t length, - unsigned char *sendbuf, unsigned char **datap) -{ - unsigned char *data; - uint32_t bufsize; - isc_result_t result; - - INSIST(datap != NULL); - INSIST((tcpbuffer == NULL && length != 0) || - (tcpbuffer != NULL && length == 0)); - - if (TCP_CLIENT(client)) { - INSIST(client->tcpbuf == NULL); - if (length + 2 > TCP_BUFFER_SIZE) { - result = ISC_R_NOSPACE; - goto done; - } - client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); - if (client->tcpbuf == NULL) { - result = ISC_R_NOMEMORY; - goto done; - } - data = client->tcpbuf; - if (tcpbuffer != NULL) { - isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); - isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); - } else { - isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); - INSIST(length <= 0xffff); - isc_buffer_putuint16(buffer, (uint16_t)length); - } - } else { - data = sendbuf; - if ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) == 0) { - if (client->view != NULL) - bufsize = client->view->nocookieudp; - else - bufsize = 512; - } else - bufsize = client->udpsize; - if (bufsize > client->udpsize) - bufsize = client->udpsize; - if (bufsize > SEND_BUFFER_SIZE) - bufsize = SEND_BUFFER_SIZE; - if (length > bufsize) { - result = ISC_R_NOSPACE; - goto done; - } - isc_buffer_init(buffer, data, bufsize); - } - *datap = data; - result = ISC_R_SUCCESS; - - done: - return (result); -} - -static isc_result_t -client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { - struct in6_pktinfo *pktinfo; - isc_result_t result; - isc_region_t r; - isc_sockaddr_t *address; - isc_socket_t *sock; - isc_netaddr_t netaddr; - int match; - unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; - - if (TCP_CLIENT(client)) { - sock = client->tcpsocket; - address = NULL; - } else { - sock = client->udpsocket; - address = &client->peeraddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - return (DNS_R_BLACKHOLED); - sockflags |= ISC_SOCKFLAG_NORETRY; - } - - if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && - (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - - if (client->dispatch != NULL) { - isc_dscp_t dscp = dns_dispatch_getdscp(client->dispatch); - if (dscp != -1) { - client->dscp = dscp; - } - } - - if (client->dscp == -1) { - client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; - client->sendevent->dscp = 0; - } else { - client->sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; - client->sendevent->dscp = client->dscp; - } - - isc_buffer_usedregion(buffer, &r); - - /* - * If this is a UDP client and the IPv6 packet can't be - * encapsulated without generating a PTB on a 1500 octet - * MTU link force fragmentation at 1280 if it is a IPv6 - * response. - */ - client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_USEMINMTU; - if (!TCP_CLIENT(client) && r.length > 1432) - client->sendevent->attributes |= ISC_SOCKEVENTATTR_USEMINMTU; - - CTRACE("sendto"); - - result = isc_socket_sendto2(sock, &r, client->task, - address, pktinfo, - client->sendevent, sockflags); - if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { - client->nsends++; - if (result == ISC_R_SUCCESS) - client_senddone(client->task, - (isc_event_t *)client->sendevent); - result = ISC_R_SUCCESS; - } - return (result); -} - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *message) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_region_t r; - isc_region_t *mr; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("sendraw"); - - mr = dns_message_getrawmessage(message); - if (mr == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto done; - } - - result = client_allocsendbuf(client, &buffer, NULL, mr->length, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - /* - * Copy message to buffer and fixup id. - */ - isc_buffer_availableregion(&buffer, &r); - result = isc_buffer_copyregion(&buffer, mr); - if (result != ISC_R_SUCCESS) - goto done; - r.base[0] = (client->message->id >> 8) & 0xff; - r.base[1] = client->message->id & 0xff; - - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - ns_client_next(client, result); -} - -static void -client_send(ns_client_t *client) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_buffer_t tcpbuffer; - isc_region_t r; - dns_compress_t cctx; - bool cleanup_cctx = false; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - unsigned int render_opts; - unsigned int preferred_glue; - bool opt_included = false; - size_t respsize; -#ifdef HAVE_DNSTAP - unsigned char zone[DNS_NAME_MAXWIRE]; - dns_dtmsgtype_t dtmsgtype; - isc_region_t zr; -#endif /* HAVE_DNSTAP */ - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("send"); - - if (client->message->opcode == dns_opcode_query && - (client->attributes & NS_CLIENTATTR_RA) != 0) - client->message->flags |= DNS_MESSAGEFLAG_RA; - - if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) - render_opts = 0; - else - render_opts = DNS_MESSAGERENDER_OMITDNSSEC; - - preferred_glue = 0; - if (client->view != NULL) { - if (client->view->preferred_glue == dns_rdatatype_a) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else if (client->view->preferred_glue == dns_rdatatype_aaaa) - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - if (preferred_glue == 0) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * filter-aaaa-on-v4 yes or break-dnssec option to suppress - * AAAA records. - * - * We already know that request came via IPv4, - * that we have both AAAA and A records, - * and that we either have no signatures that the client wants - * or we are supposed to break DNSSEC. - * - * Override preferred glue if necessary. - */ - if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) { - render_opts |= DNS_MESSAGERENDER_FILTER_AAAA; - if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - } -#endif - - /* - * Create an OPT for our reply. - */ - if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { - result = ns_client_addopt(client, client->message, - &client->opt); - if (result != ISC_R_SUCCESS) - goto done; - } - - /* - * XXXRTH The following doesn't deal with TCP buffer resizing. - */ - result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - result = dns_compress_init(&cctx, -1, client->mctx); - if (result != ISC_R_SUCCESS) - goto done; - if (client->peeraddr_valid && client->view != NULL) { - isc_netaddr_t netaddr; - dns_name_t *name = NULL; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (client->message->tsigkey != NULL) - name = &client->message->tsigkey->name; - - if (client->view->nocasecompress == NULL || - !allowed(&netaddr, name, NULL, 0, NULL, - client->view->nocasecompress)) - { - dns_compress_setsensitive(&cctx, true); - } - - if (client->view->msgcompression == false) { - dns_compress_disable(&cctx); - } - } - cleanup_cctx = true; - - result = dns_message_renderbegin(client->message, &cctx, &buffer); - if (result != ISC_R_SUCCESS) - goto done; - - if (client->opt != NULL) { - result = dns_message_setopt(client->message, client->opt); - opt_included = true; - client->opt = NULL; - if (result != ISC_R_SUCCESS) - goto done; - } - result = dns_message_rendersection(client->message, - DNS_SECTION_QUESTION, 0); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - /* - * Stop after the question if TC was set for rate limiting. - */ - if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) - goto renderend; - result = dns_message_rendersection(client->message, - DNS_SECTION_ANSWER, - DNS_MESSAGERENDER_PARTIAL | - render_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_AUTHORITY, - DNS_MESSAGERENDER_PARTIAL | - render_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ADDITIONAL, - preferred_glue | render_opts); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - goto done; - renderend: - result = dns_message_renderend(client->message); - - if (result != ISC_R_SUCCESS) - goto done; - -#ifdef HAVE_DNSTAP - memset(&zr, 0, sizeof(zr)); - if (((client->message->flags & DNS_MESSAGEFLAG_AA) != 0) && - (client->query.authzone != NULL)) - { - isc_buffer_t b; - dns_name_t *zo = - dns_zone_getorigin(client->query.authzone); - - isc_buffer_init(&b, zone, sizeof(zone)); - dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE); - result = dns_name_towire(zo, &cctx, &b); - if (result == ISC_R_SUCCESS) - isc_buffer_usedregion(&b, &zr); - } - - if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) - dtmsgtype = DNS_DTTYPE_CR; - else - dtmsgtype = DNS_DTTYPE_AR; -#endif /* HAVE_DNSTAP */ - - if (cleanup_cctx) { - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - } - - if (TCP_CLIENT(client)) { - isc_buffer_usedregion(&buffer, &r); - isc_buffer_putuint16(&tcpbuffer, (uint16_t) r.length); - isc_buffer_add(&tcpbuffer, r.length); -#ifdef HAVE_DNSTAP - if (client->view != NULL) { - dns_dt_send(client->view, dtmsgtype, - &client->peeraddr, &client->destsockaddr, - true, &zr, &client->requesttime, NULL, - &buffer); - } -#endif /* HAVE_DNSTAP */ - - /* don't count the 2-octet length header */ - respsize = isc_buffer_usedlength(&tcpbuffer) - 2; - result = client_sendpkg(client, &tcpbuffer); - - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->tcpoutstats4, - ISC_MIN((int)respsize / 16, 256)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->tcpoutstats6, - ISC_MIN((int)respsize / 16, 256)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else { - respsize = isc_buffer_usedlength(&buffer); - result = client_sendpkg(client, &buffer); -#ifdef HAVE_DNSTAP - if (client->view != NULL) { - dns_dt_send(client->view, dtmsgtype, - &client->peeraddr, - &client->destsockaddr, - false, &zr, - &client->requesttime, NULL, &buffer); - } -#endif /* HAVE_DNSTAP */ - - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->udpoutstats4, - ISC_MIN((int)respsize / 16, 256)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->udpoutstats6, - ISC_MIN((int)respsize / 16, 256)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - - /* update statistics (XXXJT: is it okay to access message->xxxkey?) */ - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response); - - dns_rcodestats_increment(ns_g_server->rcodestats, - client->message->rcode); - if (opt_included) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_edns0out); - } - if (client->message->tsigkey != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_tsigout); - } - if (client->message->sig0key != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_sig0out); - } - if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_truncatedresp); - - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - - ns_client_next(client, result); -} - -/* - * Completes the sending of a delayed client response. - */ -static void -client_delay(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->delaytimer != NULL); - - UNUSED(task); - - CTRACE("client_delay"); - - isc_event_free(&event); - isc_timer_detach(&client->delaytimer); - - client_send(client); - ns_client_detach(&client); -} - -void -ns_client_send(ns_client_t *client) { - - /* - * Delay the response by ns_g_delay ms. - */ - if (ns_g_delay != 0) { - ns_client_t *dummy = NULL; - isc_result_t result; - isc_interval_t interval; - - /* - * Replace ourselves if we have not already been replaced. - */ - if (!client->mortal) { - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - goto nodelay; - } - - ns_client_attach(client, &dummy); - if (ns_g_delay >= 1000) - isc_interval_set(&interval, ns_g_delay / 1000, - (ns_g_delay % 1000) * 1000000); - else - isc_interval_set(&interval, 0, ns_g_delay * 1000000); - result = isc_timer_create(client->manager->timermgr, - isc_timertype_once, NULL, &interval, - client->task, client_delay, - client, &client->delaytimer); - if (result == ISC_R_SUCCESS) - return; - - ns_client_detach(&dummy); - } - - nodelay: - client_send(client); -} - -#if NS_CLIENT_DROPPORT -#define DROPPORT_NO 0 -#define DROPPORT_REQUEST 1 -#define DROPPORT_RESPONSE 2 -/*% - * ns_client_dropport determines if certain requests / responses - * should be dropped based on the port number. - * - * Returns: - * \li 0: Don't drop. - * \li 1: Drop request. - * \li 2: Drop (error) response. - */ -static int -ns_client_dropport(in_port_t port) { - switch (port) { - case 7: /* echo */ - case 13: /* daytime */ - case 19: /* chargen */ - case 37: /* time */ - return (DROPPORT_REQUEST); - case 464: /* kpasswd */ - return (DROPPORT_RESPONSE); - } - return (DROPPORT_NO); -} -#endif - -void -ns_client_error(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("error"); - - message = client->message; - rcode = dns_result_torcode(result); - -#if NS_CLIENT_DROPPORT - /* - * Don't send FORMERR to ports on the drop port list. - */ - if (rcode == dns_rcode_formerr && - ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != - DROPPORT_NO) { - char buf[64]; - isc_buffer_t b; - - isc_buffer_init(&b, buf, sizeof(buf) - 1); - if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) - isc_buffer_putstr(&b, "UNKNOWN RCODE"); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped error (%.*s) response: suspicious port", - (int)isc_buffer_usedlength(&b), buf); - ns_client_next(client, ISC_R_SUCCESS); - return; - } -#endif - - /* - * Try to rate limit error responses. - */ - if (client->view != NULL && client->view->rrl != NULL) { - bool wouldlog; - char log_buf[DNS_RRL_LOG_BUF_LEN]; - dns_rrl_result_t rrl_result; - int loglevel; - - INSIST(rcode != dns_rcode_noerror && - rcode != dns_rcode_nxdomain); - if (ns_g_server->log_queries) - loglevel = DNS_RRL_LOG_DROP; - else - loglevel = ISC_LOG_DEBUG(1); - wouldlog = isc_log_wouldlog(ns_g_lctx, loglevel); - rrl_result = dns_rrl(client->view, &client->peeraddr, - TCP_CLIENT(client), - dns_rdataclass_in, dns_rdatatype_none, - NULL, result, client->now, - wouldlog, log_buf, sizeof(log_buf)); - if (rrl_result != DNS_RRL_RESULT_OK) { - /* - * Log dropped errors in the query category - * so that they are not lost in silence. - * Starts of rate-limited bursts are logged in - * NS_LOGCATEGORY_RRL. - */ - if (wouldlog) { - ns_client_log(client, - NS_LOGCATEGORY_QUERY_ERRORS, - NS_LOGMODULE_CLIENT, - loglevel, - "%s", log_buf); - } - /* - * Some error responses cannot be 'slipped', - * so don't try to slip any error responses. - */ - if (!client->view->rrl->log_only) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_ratedropped); - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_dropped); - ns_client_next(client, DNS_R_DROP); - return; - } - } - } - - /* - * Message may be an in-progress reply that we had trouble - * with, in which case QR will be set. We need to clear QR before - * calling dns_message_reply() to avoid triggering an assertion. - */ - message->flags &= ~DNS_MESSAGEFLAG_QR; - /* - * AA and AD shouldn't be set. - */ - message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); - result = dns_message_reply(message, true); - if (result != ISC_R_SUCCESS) { - /* - * It could be that we've got a query with a good header, - * but a bad question section, so we try again with - * want_question_section set to false. - */ - result = dns_message_reply(message, false); - if (result != ISC_R_SUCCESS) { - ns_client_next(client, result); - return; - } - } - message->rcode = rcode; - - if (rcode == dns_rcode_formerr) { - /* - * FORMERR loop avoidance: If we sent a FORMERR message - * with the same ID to the same client less than two - * seconds ago, assume that we are in an infinite error - * packet dialog with a server for some protocol whose - * error responses look enough like DNS queries to - * elicit a FORMERR response. Drop a packet to break - * the loop. - */ - if (isc_sockaddr_equal(&client->peeraddr, - &client->formerrcache.addr) && - message->id == client->formerrcache.id && - (isc_time_seconds(&client->requesttime) - - client->formerrcache.time) < 2) - { - /* Drop packet. */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "possible error packet loop, " - "FORMERR dropped"); - ns_client_next(client, result); - return; - } - client->formerrcache.addr = client->peeraddr; - client->formerrcache.time = - isc_time_seconds(&client->requesttime); - client->formerrcache.id = message->id; - } else if (rcode == dns_rcode_servfail && client->query.qname != NULL && - client->view != NULL && client->view->fail_ttl != 0 && - ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0)) - { - /* - * SERVFAIL caching: store qname/qtype of failed queries - */ - isc_time_t expire; - isc_interval_t i; - uint32_t flags = 0; - - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) - flags = NS_FAILCACHE_CD; - - isc_interval_set(&i, client->view->fail_ttl, 0); - result = isc_time_nowplusinterval(&expire, &i); - if (result == ISC_R_SUCCESS) - dns_badcache_add(client->view->failcache, - client->query.qname, - client->query.qtype, - true, flags, &expire); - } - ns_client_send(client); -} - -isc_result_t -ns_client_addopt(ns_client_t *client, dns_message_t *message, - dns_rdataset_t **opt) -{ - unsigned char ecs[ECS_SIZE]; - char nsid[BUFSIZ], *nsidp; - unsigned char cookie[COOKIE_SIZE]; - isc_result_t result; - dns_view_t *view; - dns_resolver_t *resolver; - uint16_t udpsize; - dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; - int count = 0; - unsigned int flags; - unsigned char expire[4]; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(opt != NULL && *opt == NULL); - REQUIRE(message != NULL); - - view = client->view; - resolver = (view != NULL) ? view->resolver : NULL; - if (resolver != NULL) - udpsize = dns_resolver_getudpsize(resolver); - else - udpsize = ns_g_udpsize; - - flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE; - - /* Set EDNS options if applicable */ - if (WANTNSID(client) && - (ns_g_server->server_id != NULL || - ns_g_server->server_usehostname)) { - if (ns_g_server->server_usehostname) { - result = ns_os_gethostname(nsid, sizeof(nsid)); - if (result != ISC_R_SUCCESS) { - goto no_nsid; - } - nsidp = nsid; - } else - nsidp = ns_g_server->server_id; - - INSIST(count < DNS_EDNSOPTIONS); - ednsopts[count].code = DNS_OPT_NSID; - ednsopts[count].length = (uint16_t)strlen(nsidp); - ednsopts[count].value = (unsigned char *)nsidp; - count++; - } - no_nsid: - if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) { - isc_buffer_t buf; - isc_stdtime_t now; - uint32_t nonce; - - isc_buffer_init(&buf, cookie, sizeof(cookie)); - isc_stdtime_get(&now); - nonce = ((isc_rng_random(ns_g_server->rngctx) << 16) | - isc_rng_random(ns_g_server->rngctx)); - - compute_cookie(client, now, nonce, ns_g_server->secret, &buf); - - INSIST(count < DNS_EDNSOPTIONS); - ednsopts[count].code = DNS_OPT_COOKIE; - ednsopts[count].length = COOKIE_SIZE; - ednsopts[count].value = cookie; - count++; - } - if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) { - isc_buffer_t buf; - - INSIST(count < DNS_EDNSOPTIONS); - - isc_buffer_init(&buf, expire, sizeof(expire)); - isc_buffer_putuint32(&buf, client->expire); - ednsopts[count].code = DNS_OPT_EXPIRE; - ednsopts[count].length = 4; - ednsopts[count].value = expire; - count++; - } - if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) && - (client->ecs_addr.family == AF_INET || - client->ecs_addr.family == AF_INET6 || - client->ecs_addr.family == AF_UNSPEC)) - { - isc_buffer_t buf; - uint8_t addr[16]; - uint32_t plen, addrl; - uint16_t family = 0; - - /* Add CLIENT-SUBNET option. */ - - plen = client->ecs_addrlen; - - /* Round up prefix len to a multiple of 8 */ - addrl = (plen + 7) / 8; - - switch (client->ecs_addr.family) { - case AF_UNSPEC: - INSIST(plen == 0); - family = 0; - break; - case AF_INET: - INSIST(plen <= 32); - family = 1; - memmove(addr, &client->ecs_addr.type, addrl); - break; - case AF_INET6: - INSIST(plen <= 128); - family = 2; - memmove(addr, &client->ecs_addr.type, addrl); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_buffer_init(&buf, ecs, sizeof(ecs)); - /* family */ - isc_buffer_putuint16(&buf, family); - /* source prefix-length */ - isc_buffer_putuint8(&buf, client->ecs_addrlen); - /* scope prefix-length */ - isc_buffer_putuint8(&buf, client->ecs_scope); - - /* address */ - if (addrl > 0) { - /* Mask off last address byte */ - if ((plen % 8) != 0) - addr[addrl - 1] &= - ~0U << (8 - (plen % 8)); - isc_buffer_putmem(&buf, addr, - (unsigned) addrl); - } - - ednsopts[count].code = DNS_OPT_CLIENT_SUBNET; - ednsopts[count].length = addrl + 4; - ednsopts[count].value = ecs; - count++; - } - - result = dns_message_buildopt(message, opt, 0, udpsize, flags, - ednsopts, count); - return (result); -} - -static inline bool -allowed(isc_netaddr_t *addr, const dns_name_t *signer, - isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, - uint8_t *ecs_scope, dns_acl_t *acl) -{ - int match; - isc_result_t result; - - if (acl == NULL) - return (true); - result = dns_acl_match2(addr, signer, ecs_addr, ecs_addrlen, ecs_scope, - acl, &ns_g_server->aclenv, &match, NULL); - if (result == ISC_R_SUCCESS && match > 0) - return (true); - return (false); -} - -/* - * Callback to see if a non-recursive query coming from 'srcaddr' to - * 'destaddr', with optional key 'mykey' for class 'rdclass' would be - * delivered to 'myview'. - * - * We run this unlocked as both the view list and the interface list - * are updated when the appropriate task has exclusivity. - */ -bool -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr, - dns_rdataclass_t rdclass, void *arg) -{ - dns_view_t *view; - dns_tsigkey_t *key = NULL; - isc_netaddr_t netsrc; - isc_netaddr_t netdst; - - UNUSED(arg); - - /* - * ns_g_server->interfacemgr is task exclusive locked. - */ - if (ns_g_server->interfacemgr == NULL) - return (true); - - if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) - return (false); - - isc_netaddr_fromsockaddr(&netsrc, srcaddr); - isc_netaddr_fromsockaddr(&netdst, dstaddr); - - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - const dns_name_t *tsig = NULL; - - if (view->matchrecursiveonly) - continue; - - if (rdclass != view->rdclass) - continue; - - if (mykey != NULL) { - bool match; - isc_result_t result; - - result = dns_view_gettsig(view, &mykey->name, &key); - if (result != ISC_R_SUCCESS) - continue; - match = dst_key_compare(mykey->key, key->key); - dns_tsigkey_detach(&key); - if (!match) - continue; - tsig = dns_tsigkey_identity(mykey); - } - - if (allowed(&netsrc, tsig, NULL, 0, NULL, - view->matchclients) && - allowed(&netdst, tsig, NULL, 0, NULL, - view->matchdestinations)) - break; - } - return (view == myview); -} - -static void -compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce, - const unsigned char *secret, isc_buffer_t *buf) -{ - switch (ns_g_server->cookiealg) { - case ns_cookiealg_siphash24: { - unsigned char digest[ISC_SIPHASH24_TAG_LENGTH] = { 0 }; - unsigned char input[16 + 16] = { 0 }; - size_t inputlen = 0; - isc_netaddr_t netaddr; - unsigned char *cp; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1); - isc_buffer_putuint24(buf, 0); /* Reserved */ - isc_buffer_putuint32(buf, when); - - memmove(input, cp, 16); - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - memmove(input + 16, cp, 4); - inputlen = 20; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - memmove(input + 16, cp, 16); - inputlen = 32; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_siphash24(secret, input, inputlen, digest); - isc_buffer_putmem(buf, digest, 8); - break; - } -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) - case ns_cookiealg_aes: { - unsigned char digest[ISC_AES_BLOCK_LENGTH]; - unsigned char input[4 + 4 + 16]; - isc_netaddr_t netaddr; - unsigned char *cp; - unsigned int i; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - memmove(input, cp, 16); - isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) { - input[i] = digest[i] ^ digest[i + 8]; - } - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - memmove(input + 8, cp, 4); - memset(input + 12, 0, 4); - isc_aes128_crypt(secret, input, digest); - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - memmove(input + 8, cp, 16); - isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) { - input[i + 8] = digest[i] ^ digest[i + 8]; - } - isc_aes128_crypt(ns_g_server->secret, input + 8, - digest); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - for (i = 0; i < 8; i++) { - digest[i] ^= digest[i + 8]; - } - isc_buffer_putmem(buf, digest, 8); - break; - } -#endif - - case ns_cookiealg_sha1: { - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - isc_netaddr_t netaddr; - unsigned char *cp; - isc_hmacsha1_t hmacsha1; - unsigned int length; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - - isc_hmacsha1_init(&hmacsha1, secret, ISC_SHA1_DIGESTLENGTH); - isc_hmacsha1_update(&hmacsha1, cp, 16); - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - length = 4; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - length = 16; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_hmacsha1_update(&hmacsha1, cp, length); - isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest)); - isc_buffer_putmem(buf, digest, 8); - isc_hmacsha1_invalidate(&hmacsha1); - break; - } - - case ns_cookiealg_sha256: { - unsigned char digest[ISC_SHA256_DIGESTLENGTH]; - isc_netaddr_t netaddr; - unsigned char *cp; - isc_hmacsha256_t hmacsha256; - unsigned int length; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - - isc_hmacsha256_init(&hmacsha256, secret, - ISC_SHA256_DIGESTLENGTH); - isc_hmacsha256_update(&hmacsha256, cp, 16); - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - length = 4; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - length = 16; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_hmacsha256_update(&hmacsha256, cp, length); - isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest)); - isc_buffer_putmem(buf, digest, 8); - isc_hmacsha256_invalidate(&hmacsha256); - break; - } - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void -process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - ns_altsecret_t *altsecret; - unsigned char dbuf[COOKIE_SIZE]; - unsigned char *old; - isc_stdtime_t now; - uint32_t when; - uint32_t nonce; - isc_buffer_t db; - - /* - * If we have already seen a cookie option skip this cookie option. - */ - if ((!ns_g_server->answercookie) || - (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) - { - isc_buffer_forward(buf, (unsigned int)optlen); - return; - } - - client->attributes |= NS_CLIENTATTR_WANTCOOKIE; - - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_cookiein); - - if (optlen != COOKIE_SIZE) { - /* - * Not our token. - */ - INSIST(optlen >= 8U); - memmove(client->cookie, isc_buffer_current(buf), 8); - isc_buffer_forward(buf, (unsigned int)optlen); - - if (optlen == 8U) - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookienew); - else - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiebadsize); - return; - } - - /* - * Process all of the incoming buffer. - */ - old = isc_buffer_current(buf); - memmove(client->cookie, old, 8); - isc_buffer_forward(buf, 8); - nonce = isc_buffer_getuint32(buf); - when = isc_buffer_getuint32(buf); - isc_buffer_forward(buf, 8); - - /* - * Allow for a 5 minute clock skew between servers sharing a secret. - * Only accept COOKIE if we have talked to the client in the last hour. - */ - isc_stdtime_get(&now); - if (isc_serial_gt(when, (now + 300)) || /* In the future. */ - isc_serial_lt(when, (now - 3600))) { /* In the past. */ - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiebadtime); - return; - } - - isc_buffer_init(&db, dbuf, sizeof(dbuf)); - compute_cookie(client, when, nonce, ns_g_server->secret, &db); - - if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiematch); - client->attributes |= NS_CLIENTATTR_HAVECOOKIE; - return; - } - - for (altsecret = ISC_LIST_HEAD(ns_g_server->altsecrets); - altsecret != NULL; - altsecret = ISC_LIST_NEXT(altsecret, link)) - { - isc_buffer_init(&db, dbuf, sizeof(dbuf)); - compute_cookie(client, when, nonce, altsecret->secret, &db); - if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiematch); - client->attributes |= NS_CLIENTATTR_HAVECOOKIE; - return; - } - } - - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookienomatch); -} - -static isc_result_t -process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - uint16_t family; - uint8_t addrlen, addrbytes, scope, *paddr; - isc_netaddr_t caddr; - - /* - * If we have already seen a ECS option skip this ECS option. - */ - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); - } - - /* - * XXXMUKS: Is there any need to repeat these checks here - * (except query's scope length) when they are done in the OPT - * RDATA fromwire code? - */ - - if (optlen < 4U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option too short"); - return (DNS_R_FORMERR); - } - - family = isc_buffer_getuint16(buf); - addrlen = isc_buffer_getuint8(buf); - scope = isc_buffer_getuint8(buf); - optlen -= 4; - - if (scope != 0U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid scope"); - return (DNS_R_OPTERR); - } - - memset(&caddr, 0, sizeof(caddr)); - switch (family) { - case 0: - /* - * XXXMUKS: In queries, if FAMILY is set to 0, SOURCE - * PREFIX-LENGTH must be 0 and ADDRESS should not be - * present as the address and prefix lengths don't make - * sense because the family is unknown. - */ - if (addrlen != 0U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for FAMILY=0", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_UNSPEC; - break; - case 1: - if (addrlen > 32U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for IPv4", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_INET; - break; - case 2: - if (addrlen > 128U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for IPv6", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_INET6; - break; - default: - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid family"); - return (DNS_R_OPTERR); - } - - addrbytes = (addrlen + 7) / 8; - if (isc_buffer_remaininglength(buf) < addrbytes) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: address too short"); - return (DNS_R_OPTERR); - } - - paddr = (uint8_t *) &caddr.type; - if (addrbytes != 0U) { - memmove(paddr, isc_buffer_current(buf), addrbytes); - isc_buffer_forward(buf, addrbytes); - optlen -= addrbytes; - - if ((addrlen % 8) != 0) { - uint8_t bits = ~0U << (8 - (addrlen % 8)); - bits &= paddr[addrbytes - 1]; - if (bits != paddr[addrbytes - 1]) - return (DNS_R_OPTERR); - } - } - - memmove(&client->ecs_addr, &caddr, sizeof(caddr)); - client->ecs_addrlen = addrlen; - client->ecs_scope = 0; - client->attributes |= NS_CLIENTATTR_HAVEECS; - - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); -} - -static isc_result_t -process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - - if (optlen == 0 || (optlen % 2) != 0) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (DNS_R_OPTERR); - } - - /* Silently drop additional keytag options. */ - if (client->keytag != NULL) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); - } - - client->keytag = isc_mem_get(client->mctx, optlen); - if (client->keytag != NULL) { - client->keytag_len = (uint16_t)optlen; - memmove(client->keytag, isc_buffer_current(buf), optlen); - } - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); -} - -static isc_result_t -process_opt(ns_client_t *client, dns_rdataset_t *opt) { - dns_rdata_t rdata; - isc_buffer_t optbuf; - isc_result_t result; - uint16_t optcode; - uint16_t optlen; - - /* - * Set the client's UDP buffer size. - */ - client->udpsize = opt->rdclass; - - /* - * If the requested UDP buffer size is less than 512, - * ignore it and use 512. - */ - if (client->udpsize < 512) - client->udpsize = 512; - - /* - * Get the flags out of the OPT record. - */ - client->extflags = (uint16_t)(opt->ttl & 0xFFFF); - - /* - * Do we understand this version of EDNS? - * - * XXXRTH need library support for this! - */ - client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; - if (client->ednsversion > DNS_EDNS_VERSION) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_badednsver); - result = ns_client_addopt(client, client->message, - &client->opt); - if (result == ISC_R_SUCCESS) - result = DNS_R_BADVERS; - ns_client_error(client, result); - goto cleanup; - } - - /* Check for NSID request */ - result = dns_rdataset_first(opt); - if (result == ISC_R_SUCCESS) { - dns_rdata_init(&rdata); - dns_rdataset_current(opt, &rdata); - isc_buffer_init(&optbuf, rdata.data, rdata.length); - isc_buffer_add(&optbuf, rdata.length); - while (isc_buffer_remaininglength(&optbuf) >= 4) { - optcode = isc_buffer_getuint16(&optbuf); - optlen = isc_buffer_getuint16(&optbuf); - switch (optcode) { - case DNS_OPT_NSID: - if (!WANTNSID(client)) - isc_stats_increment( - ns_g_server->nsstats, - dns_nsstatscounter_nsidopt); - client->attributes |= NS_CLIENTATTR_WANTNSID; - isc_buffer_forward(&optbuf, optlen); - break; - case DNS_OPT_COOKIE: - process_cookie(client, &optbuf, optlen); - break; - case DNS_OPT_EXPIRE: - if (!WANTEXPIRE(client)) - isc_stats_increment( - ns_g_server->nsstats, - dns_nsstatscounter_expireopt); - client->attributes |= NS_CLIENTATTR_WANTEXPIRE; - isc_buffer_forward(&optbuf, optlen); - break; - case DNS_OPT_CLIENT_SUBNET: - result = process_ecs(client, &optbuf, optlen); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - goto cleanup; - } - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_ecsopt); - break; - case DNS_OPT_KEY_TAG: - result = process_keytag(client, &optbuf, - optlen); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - return (result); - } - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_keytagopt); - break; - default: - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_otheropt); - isc_buffer_forward(&optbuf, optlen); - break; - } - } - } - - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_edns0in); - client->attributes |= NS_CLIENTATTR_WANTOPT; - - cleanup: - return (result); -} - -/* - * Handle an incoming request event from the socket (UDP case) - * or tcpmsg (TCP case). - */ -static void -client_request(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent; - isc_result_t result; - isc_result_t sigresult = ISC_R_SUCCESS; - isc_buffer_t *buffer; - isc_buffer_t tbuffer; - dns_view_t *view; - dns_rdataset_t *opt; - dns_name_t *signame; - bool ra; /* Recursion available. */ - isc_netaddr_t netaddr; - int match; - dns_messageid_t id; - unsigned int flags; - bool notimp; - size_t reqsize; -#ifdef HAVE_DNSTAP - dns_dtmsgtype_t dtmsgtype; -#endif - - REQUIRE(event != NULL); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - INSIST(client->recursionquota == NULL); - - INSIST(client->state == (TCP_CLIENT(client) ? - NS_CLIENTSTATE_READING : - NS_CLIENTSTATE_READY)); - - ncr_inc(ns_client_requests); - - if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { - INSIST(!TCP_CLIENT(client)); - sevent = (isc_socketevent_t *)event; - REQUIRE(sevent == client->recvevent); - isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); - isc_buffer_add(&tbuffer, sevent->n); - buffer = &tbuffer; - result = sevent->result; - if (result == ISC_R_SUCCESS) { - client->peeraddr = sevent->address; - client->peeraddr_valid = true; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(90), - "received DSCP %d", sevent->dscp); - if (client->dscp == -1) - client->dscp = sevent->dscp; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->attributes |= NS_CLIENTATTR_PKTINFO; - client->pktinfo = sevent->pktinfo; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) - client->attributes |= NS_CLIENTATTR_MULTICAST; - client->nrecvs--; - } else { - INSIST(TCP_CLIENT(client)); - INSIST(client->tcpconn != NULL); - REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); - REQUIRE(event->ev_sender == &client->tcpmsg); - buffer = &client->tcpmsg.buffer; - result = client->tcpmsg.result; - INSIST(client->nreads == 1); - /* - * client->peeraddr was set when the connection was accepted. - */ - client->nreads--; - } - - reqsize = isc_buffer_usedlength(buffer); - /* don't count the length header */ - if (TCP_CLIENT(client)) - reqsize -= 2; - - if (exit_check(client)) - goto cleanup; - client->state = client->newstate = NS_CLIENTSTATE_WORKING; - - isc_task_getcurrenttimex(task, &client->requesttime); - client->tnow = client->requesttime; - client->now = isc_time_seconds(&client->tnow); - - if (result != ISC_R_SUCCESS) { - if (TCP_CLIENT(client)) { - ns_client_next(client, result); - } else { - if (result != ISC_R_CANCELED) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "UDP client handler shutting " - "down due to fatal receive " - "error: %s", - isc_result_totext(result)); - isc_task_shutdown(client->task); - } - goto cleanup; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - -#if NS_CLIENT_DROPPORT - if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == - DROPPORT_REQUEST) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped request: suspicious port"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } -#endif - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s request", - TCP_CLIENT(client) ? "TCP" : "UDP"); - - /* - * Check the blackhole ACL for UDP only, since TCP is done in - * client_newconn. - */ - if (!TCP_CLIENT(client)) { - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed UDP datagram"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Silently drop multicast requests for the present. - * XXXMPA revisit this as mDNS spec was published. - */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "dropping multicast request"); - ns_client_next(client, DNS_R_REFUSED); - goto cleanup; - } - - result = dns_message_peekheader(buffer, &id, &flags); - if (result != ISC_R_SUCCESS) { - /* - * There isn't enough header to determine whether - * this was a request or a response. Drop it. - */ - ns_client_next(client, result); - goto cleanup; - } - - /* - * The client object handles requests, not responses. - * If this is a UDP response, forward it to the dispatcher. - * If it's a TCP response, discard it here. - */ - if ((flags & DNS_MESSAGEFLAG_QR) != 0) { - if (TCP_CLIENT(client)) { - CTRACE("unexpected response"); - ns_client_next(client, DNS_R_FORMERR); - goto cleanup; - } else { - dns_dispatch_importrecv(client->dispatch, event); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Update some statistics counters. Don't count responses. - */ - if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requestv4); - } else { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requestv6); - } - if (TCP_CLIENT(client)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requesttcp); - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->tcpinstats4, - ISC_MIN((int)reqsize / 16, 18)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->tcpinstats6, - ISC_MIN((int)reqsize / 16, 18)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else { - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->udpinstats4, - ISC_MIN((int)reqsize / 16, 18)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->udpinstats6, - ISC_MIN((int)reqsize / 16, 18)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - - /* - * It's a request. Parse it. - */ - result = dns_message_parse(client->message, buffer, 0); - if (result != ISC_R_SUCCESS) { - /* - * Parsing the request failed. Send a response - * (typically FORMERR or SERVFAIL). - */ - if (result == DNS_R_OPTERR) { - (void)ns_client_addopt(client, client->message, - &client->opt); - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message parsing failed: %s", - isc_result_totext(result)); - if (result == ISC_R_NOSPACE || result == DNS_R_BADTSIG) { - result = DNS_R_FORMERR; - } - ns_client_error(client, result); - goto cleanup; - } - - /* - * Pipeline TCP query processing. - */ - if (TCP_CLIENT(client)) { - if (client->message->opcode != dns_opcode_query) { - client->tcpconn->pipelined = false; - } - - /* - * Limit the maximum number of simultaneous pipelined - * queries on TCP connection to TCP_CLIENTS_PER_CONN. - */ - if ((isc_refcount_current(&client->tcpconn->clients) - > TCP_CLIENTS_PER_CONN)) - { - client->tcpconn->pipelined = false; - } - - if (client->tcpconn->pipelined) { - /* - * We're pipelining. Replace the client; the - * replacement can read the TCP socket looking - * for new messages and this one can process the - * current message asynchronously. - * - * There will now be at least three clients using this - * TCP socket - one accepting new connections, - * one reading an existing connection to get new - * messages, and one answering the message already - * received. - */ - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - client->tcpconn->pipelined = false; - } - } - } - - dns_opcodestats_increment(ns_g_server->opcodestats, - client->message->opcode); - switch (client->message->opcode) { - case dns_opcode_query: - case dns_opcode_update: - case dns_opcode_notify: - notimp = false; - break; - case dns_opcode_iquery: - default: - notimp = true; - break; - } - - client->message->rcode = dns_rcode_noerror; - - /* RFC1123 section 6.1.3.2 */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) - client->message->flags &= ~DNS_MESSAGEFLAG_RD; - - /* - * Deal with EDNS. - */ - if (ns_g_noedns) - opt = NULL; - else - opt = dns_message_getopt(client->message); - - client->ecs_addrlen = 0; - client->ecs_scope = 0; - - if (opt != NULL) { - /* - * Are returning FORMERR to all EDNS queries? - * Simulate a STD13 compliant server. - */ - if (ns_g_ednsformerr) { - ns_client_error(client, DNS_R_FORMERR); - return; - } - - /* - * Are returning NOTIMP to all EDNS queries? - */ - if (ns_g_ednsnotimp) { - ns_client_error(client, DNS_R_NOTIMP); - return; - } - - /* - * Are returning REFUSED to all EDNS queries? - */ - if (ns_g_ednsrefused) { - ns_client_error(client, DNS_R_REFUSED); - return; - } - - /* - * Are we dropping all EDNS queries? - */ - if (ns_g_dropedns) { - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - - result = process_opt(client, opt); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (client->message->rdclass == 0) { - if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 && - client->message->opcode == dns_opcode_query && - client->message->counts[DNS_SECTION_QUESTION] == 0U) - { - result = dns_message_reply(client->message, true); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - return; - } - if (notimp) - client->message->rcode = dns_rcode_notimp; - ns_client_send(client); - return; - } - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message class could not be determined"); - ns_client_dumpmessage(client, - "message class could not be determined"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); - goto cleanup; - } - - /* - * Determine the destination address. If the receiving interface is - * bound to a specific address, we simply use it regardless of the - * address family. All IPv4 queries should fall into this case. - * Otherwise, if this is a TCP query, get the address from the - * receiving socket (this needs a system call and can be heavy). - * For IPv6 UDP queries, we get this from the pktinfo structure (if - * supported). - * If all the attempts fail (this can happen due to memory shortage, - * etc), we regard this as an error for safety. - */ - if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) - isc_netaddr_fromsockaddr(&client->destaddr, - &client->interface->addr); - else { - isc_sockaddr_t sockaddr; - result = ISC_R_FAILURE; - - if (TCP_CLIENT(client)) - result = isc_socket_getsockname(client->tcpsocket, - &sockaddr); - if (result == ISC_R_SUCCESS) - isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr); - if (result != ISC_R_SUCCESS && - client->interface->addr.type.sa.sa_family == AF_INET6 && - (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { - /* - * XXXJT technically, we should convert the receiving - * interface ID to a proper scope zone ID. However, - * due to the fact there is no standard API for this, - * we only handle link-local addresses and use the - * interface index as link ID. Despite the assumption, - * it should cover most typical cases. - */ - isc_netaddr_fromin6(&client->destaddr, - &client->pktinfo.ipi6_addr); - if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) - isc_netaddr_setzone(&client->destaddr, - client->pktinfo.ipi6_ifindex); - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "failed to get request's " - "destination: %s", - isc_result_totext(result)); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - isc_sockaddr_fromnetaddr(&client->destsockaddr, &client->destaddr, 0); - - /* - * Find a view that matches the client's source address. - */ - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (client->message->rdclass == view->rdclass || - client->message->rdclass == dns_rdataclass_any) - { - const dns_name_t *tsig = NULL; - isc_netaddr_t *addr = NULL; - uint8_t *scope = NULL; - - sigresult = dns_message_rechecksig(client->message, - view); - if (sigresult == ISC_R_SUCCESS) { - dns_tsigkey_t *tsigkey; - - tsigkey = client->message->tsigkey; - tsig = dns_tsigkey_identity(tsigkey); - } - - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - addr = &client->ecs_addr; - scope = &client->ecs_scope; - } - - if (allowed(&netaddr, tsig, addr, client->ecs_addrlen, - scope, view->matchclients) && - allowed(&client->destaddr, tsig, NULL, - 0, NULL, view->matchdestinations) && - !(view->matchrecursiveonly && - (client->message->flags & DNS_MESSAGEFLAG_RD) == 0)) - { - dns_view_attach(view, &client->view); - break; - } - } - } - - if (view == NULL) { - char classname[DNS_RDATACLASS_FORMATSIZE]; - - /* - * Do a dummy TSIG verification attempt so that the - * response will have a TSIG if the query did, as - * required by RFC2845. - */ - isc_buffer_t b; - isc_region_t *r; - - dns_message_resetsig(client->message); - - r = dns_message_getrawmessage(client->message); - isc_buffer_init(&b, r->base, r->length); - isc_buffer_add(&b, r->length); - (void)dns_tsig_verify(&b, client->message, NULL, NULL); - - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "no matching view in class '%s'", classname); - ns_client_dumpmessage(client, "no matching view in class"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); - goto cleanup; - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), - "using view '%s'", view->name); - - /* - * Check for a signature. We log bad signatures regardless of - * whether they ultimately cause the request to be rejected or - * not. We do not log the lack of a signature unless we are - * debugging. - */ - client->signer = NULL; - dns_name_init(&client->signername, NULL); - result = dns_message_signer(client->message, &client->signername); - if (result != ISC_R_NOTFOUND) { - signame = NULL; - if (dns_message_gettsig(client->message, &signame) != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_tsigin); - } else { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_sig0in); - } - - } - if (result == ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(&client->signername, namebuf, sizeof(namebuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request has valid signature: %s", namebuf); - client->signer = &client->signername; - } else if (result == ISC_R_NOTFOUND) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is not signed"); - } else if (result == DNS_R_NOIDENTITY) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is signed by a nonauthoritative key"); - } else { - char tsigrcode[64]; - isc_buffer_t b; - dns_rcode_t status; - isc_result_t tresult; - - /* There is a signature, but it is bad. */ - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_invalidsig); - signame = NULL; - if (dns_message_gettsig(client->message, &signame) != NULL) { - char namebuf[DNS_NAME_FORMATSIZE]; - char cnamebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(signame, namebuf, sizeof(namebuf)); - status = client->message->tsigstatus; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - if (client->message->tsigkey->generated) { - dns_name_format(client->message->tsigkey->creator, - cnamebuf, sizeof(cnamebuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s (%s): %s (%s)", namebuf, - cnamebuf, - isc_result_totext(result), - tsigrcode); - } else { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s: %s (%s)", namebuf, - isc_result_totext(result), - tsigrcode); - } - } else { - status = client->message->sig0status; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: %s (%s)", - isc_result_totext(result), tsigrcode); - } - /* - * Accept update messages signed by unknown keys so that - * update forwarding works transparently through slaves - * that don't have all the same keys as the master. - */ - if (!(client->message->tsigstatus == dns_tsigerror_badkey && - client->message->opcode == dns_opcode_update)) { - ns_client_error(client, sigresult); - goto cleanup; - } - } - - /* - * Decide whether recursive service is available to this client. - * We do this here rather than in the query code so that we can - * set the RA bit correctly on all kinds of responses, not just - * responses to ordinary queries. Note if you can't query the - * cache there is no point in setting RA. - */ - ra = false; - if (client->view->resolver != NULL && - client->view->recursion == true && - ns_client_checkaclsilent(client, NULL, - client->view->recursionacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, NULL, - client->view->cacheacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, &client->destaddr, - client->view->recursiononacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, &client->destaddr, - client->view->cacheonacl, - true) == ISC_R_SUCCESS) - ra = true; - - if (ra == true) { - client->attributes |= NS_CLIENTATTR_RA; - } - - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, - ISC_LOG_DEBUG(3), ra ? "recursion available" : - "recursion not available"); - - /* - * Adjust maximum UDP response size for this client. - */ - if (client->udpsize > 512) { - dns_peer_t *peer = NULL; - uint16_t udpsize = view->maxudp; - (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer); - if (peer != NULL) - dns_peer_getmaxudp(peer, &udpsize); - if (client->udpsize > udpsize) - client->udpsize = udpsize; - } - - /* - * Dispatch the request. - */ - switch (client->message->opcode) { - case dns_opcode_query: - CTRACE("query"); -#ifdef HAVE_DNSTAP - if (ra && (client->message->flags & DNS_MESSAGEFLAG_RD) != 0) { - dtmsgtype = DNS_DTTYPE_CQ; - } else { - dtmsgtype = DNS_DTTYPE_AQ; - } - - dns_dt_send(view, dtmsgtype, &client->peeraddr, - &client->destsockaddr, TCP_CLIENT(client), NULL, - &client->requesttime, NULL, buffer); -#endif /* HAVE_DNSTAP */ - - ns_query_start(client); - break; - case dns_opcode_update: - CTRACE("update"); - ns_client_settimeout(client, 60); - ns_update_start(client, sigresult); - break; - case dns_opcode_notify: - CTRACE("notify"); - ns_client_settimeout(client, 60); - ns_notify_start(client); - break; - case dns_opcode_iquery: - CTRACE("iquery"); - ns_client_error(client, DNS_R_NOTIMP); - break; - default: - CTRACE("unknown opcode"); - ns_client_error(client, DNS_R_NOTIMP); - } - - cleanup: - return; -} - -static void -client_timeout(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->timer != NULL); - - UNUSED(task); - - CTRACE("timeout"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - if (client->newstate > NS_CLIENTSTATE_READY) - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); -} - -static isc_result_t -get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { - isc_mem_t *clientmctx; - isc_result_t result; -#if NMCTXS > 0 - unsigned int nextmctx; -#endif - - MTRACE("clientmctx"); - - /* - * Caller must be holding the manager lock. - */ - if (ns_g_clienttest) { - result = isc_mem_create(0, 0, mctxp); - if (result == ISC_R_SUCCESS) - isc_mem_setname(*mctxp, "client", NULL); - return (result); - } -#if NMCTXS > 0 - nextmctx = manager->nextmctx++; - if (manager->nextmctx == NMCTXS) - manager->nextmctx = 0; - - INSIST(nextmctx < NMCTXS); - - clientmctx = manager->mctxpool[nextmctx]; - if (clientmctx == NULL) { - result = isc_mem_create(0, 0, &clientmctx); - if (result != ISC_R_SUCCESS) - return (result); - isc_mem_setname(clientmctx, "client", NULL); - - manager->mctxpool[nextmctx] = clientmctx; - } -#else - clientmctx = manager->mctx; -#endif - - isc_mem_attach(clientmctx, mctxp); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - ns_client_t *client; - isc_result_t result; - isc_mem_t *mctx = NULL; - - /* - * Caller must be holding the manager lock. - * - * Note: creating a client does not add the client to the - * manager's client list or set the client's manager pointer. - * The caller is responsible for that. - */ - - REQUIRE(clientp != NULL && *clientp == NULL); - - result = get_clientmctx(manager, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - - client = isc_mem_get(mctx, sizeof(*client)); - if (client == NULL) { - isc_mem_detach(&mctx); - return (ISC_R_NOMEMORY); - } - client->mctx = mctx; - - client->task = NULL; - result = isc_task_create(manager->taskmgr, 0, &client->task); - if (result != ISC_R_SUCCESS) - goto cleanup_client; - isc_task_setname(client->task, "client", client); - - client->timer = NULL; - result = isc_timer_create(manager->timermgr, isc_timertype_inactive, - NULL, NULL, client->task, client_timeout, - client, &client->timer); - if (result != ISC_R_SUCCESS) - goto cleanup_task; - client->timerset = false; - - client->delaytimer = NULL; - - client->message = NULL; - result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, - &client->message); - if (result != ISC_R_SUCCESS) - goto cleanup_timer; - - /* XXXRTH Hardwired constants */ - - client->sendevent = isc_socket_socketevent(client->mctx, client, - ISC_SOCKEVENT_SENDDONE, - client_senddone, client); - if (client->sendevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_message; - } - - client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE); - if (client->recvbuf == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_sendevent; - } - - client->recvevent = isc_socket_socketevent(client->mctx, client, - ISC_SOCKEVENT_RECVDONE, - client_request, client); - if (client->recvevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_recvbuf; - } - - client->magic = NS_CLIENT_MAGIC; - client->manager = NULL; - client->state = NS_CLIENTSTATE_INACTIVE; - client->newstate = NS_CLIENTSTATE_MAX; - client->naccepts = 0; - client->nreads = 0; - client->nsends = 0; - client->nrecvs = 0; - client->nupdates = 0; - client->nctls = 0; - client->references = 0; - client->attributes = 0; - client->view = NULL; - client->dispatch = NULL; - client->udpsocket = NULL; - client->tcplistener = NULL; - client->tcpsocket = NULL; - client->tcpmsg_valid = false; - client->tcpbuf = NULL; - client->opt = NULL; - client->udpsize = 512; - client->dscp = -1; - client->extflags = 0; - client->ednsversion = -1; - client->next = NULL; - client->shutdown = NULL; - client->shutdown_arg = NULL; - client->signer = NULL; - dns_name_init(&client->signername, NULL); - client->mortal = false; - client->tcpconn = NULL; - client->recursionquota = NULL; - client->interface = NULL; - client->peeraddr_valid = false; - client->ecs_addrlen = 0; - client->ecs_scope = 0; -#ifdef ALLOW_FILTER_AAAA - client->filter_aaaa = dns_aaaa_ok; -#endif - client->needshutdown = ns_g_clienttest; - client->tcpactive = false; - - ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, - NS_EVENT_CLIENTCONTROL, client_start, client, client, - NULL, NULL); - /* - * Initialize FORMERR cache to sentinel value that will not match - * any actual FORMERR response. - */ - isc_sockaddr_any(&client->formerrcache.addr); - client->formerrcache.time = 0; - client->formerrcache.id = 0; - ISC_LINK_INIT(client, link); - ISC_LINK_INIT(client, rlink); - ISC_QLINK_INIT(client, ilink); - client->keytag = NULL; - client->keytag_len = 0; - - /* - * We call the init routines for the various kinds of client here, - * after we have created an otherwise valid client, because some - * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). - */ - result = ns_query_init(client); - if (result != ISC_R_SUCCESS) - goto cleanup_recvevent; - - result = isc_task_onshutdown(client->task, client_shutdown, client); - if (result != ISC_R_SUCCESS) - goto cleanup_query; - - CTRACE("create"); - - *clientp = client; - - return (ISC_R_SUCCESS); - - cleanup_query: - ns_query_free(client); - - cleanup_recvevent: - isc_event_free((isc_event_t **)&client->recvevent); - - cleanup_recvbuf: - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - - cleanup_sendevent: - isc_event_free((isc_event_t **)&client->sendevent); - - client->magic = 0; - - cleanup_message: - dns_message_detach(&client->message); - - cleanup_timer: - isc_timer_detach(&client->timer); - - cleanup_task: - isc_task_detach(&client->task); - - cleanup_client: - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - - return (result); -} - -static void -client_read(ns_client_t *client) { - isc_result_t result; - - CTRACE("read"); - - result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, - client_request, client); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * Set a timeout to limit the amount of time we will wait - * for a request on this TCP connection. - */ - ns_client_settimeout(client, 30); - - client->state = client->newstate = NS_CLIENTSTATE_READING; - INSIST(client->nreads == 0); - INSIST(client->recursionquota == NULL); - client->nreads++; - - return; - fail: - ns_client_next(client, result); -} - -static void -client_newconn(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_client_t *client = event->ev_arg; - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->task == task); - - UNUSED(task); - - INSIST(client->state == NS_CLIENTSTATE_READY); - - /* - * The accept() was successful and we're now establishing a new - * connection. We need to make note of it in the client and - * interface objects so client objects can do the right thing - * when going inactive in exit_check() (see comments in - * client_accept() for details). - */ - INSIST(client->naccepts == 1); - client->naccepts--; - - isc_refcount_decrement(&client->interface->ntcpaccepting, NULL); - - /* - * We must take ownership of the new socket before the exit - * check to make sure it gets destroyed if we decide to exit. - */ - if (nevent->result == ISC_R_SUCCESS) { - client->tcpsocket = nevent->newsocket; - isc_socket_setname(client->tcpsocket, "client-tcp", NULL); - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - (void)isc_socket_getpeername(client->tcpsocket, - &client->peeraddr); - client->peeraddr_valid = true; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "new TCP connection"); - } else { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - * - * Going idle is probably the right thing if the - * I/O was canceled. - */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "accept failed: %s", - isc_result_totext(nevent->result)); - tcpconn_detach(client); - } - - if (exit_check(client)) - goto freeevent; - - if (nevent->result == ISC_R_SUCCESS) { - int match; - isc_netaddr_t netaddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed connection attempt"); - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); - goto freeevent; - } - - INSIST(client->tcpmsg_valid == false); - dns_tcpmsg_init(client->mctx, client->tcpsocket, - &client->tcpmsg); - client->tcpmsg_valid = true; - - /* - * Let a new client take our place immediately, before - * we wait for a request packet. If we don't, - * telnetting to port 53 (once per CPU) will - * deny service to legitimate TCP clients. - */ - result = ns_client_replace(client); - if (result == ISC_R_SUCCESS && - (ns_g_server->keepresporder == NULL || - !allowed(&netaddr, NULL, NULL, 0, NULL, - ns_g_server->keepresporder))) - { - client->tcpconn->pipelined = true; - } - - client_read(client); - } - - freeevent: - isc_event_free(&event); -} - -static void -client_accept(ns_client_t *client) { - isc_result_t result; - - CTRACE("accept"); - /* - * Set up a new TCP connection. This means try to attach to the - * TCP client quota (tcp-clients), but fail if we're over quota. - */ - result = tcpconn_init(client, false); - if (result != ISC_R_SUCCESS) { - bool exit; - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "TCP client quota reached: %s", - isc_result_totext(result)); - - /* - * We have exceeded the system-wide TCP client quota. But, - * we can't just block this accept in all cases, because if - * we did, a heavy TCP load on other interfaces might cause - * this interface to be starved, with no clients able to - * accept new connections. - * - * So, we check here to see if any other clients are - * already servicing TCP queries on this interface (whether - * accepting, reading, or processing). If we find that at - * least one client other than this one is active, then - * it's okay *not* to call accept - we can let this - * client go inactive and another will take over when it's - * done. - * - * If there aren't enough active clients on the interface, - * then we can be a little bit flexible about the quota. - * We'll allow *one* extra client through to ensure we're - * listening on every interface; we do this by setting the - * 'force' option to tcpconn_init(). - * - * (Note: In practice this means that the real TCP client - * quota is tcp-clients plus the number of listening - * interfaces plus 1.) - */ - exit = (isc_refcount_current(&client->interface->ntcpactive) > - (client->tcpactive ? 1U : 0U)); - if (exit) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - (void)exit_check(client); - return; - } - - result = tcpconn_init(client, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - /* TCP high-water stats update. */ - unsigned int curr_tcpquota = isc_quota_getused(&ns_g_server->tcpquota); - isc_stats_update_if_greater(ns_g_server->nsstats, - dns_nsstatscounter_tcphighwater, - curr_tcpquota); - - /* - * If this client was set up using get_client() or get_worker(), - * then TCP is already marked active. However, if it was restarted - * from exit_check(), it might not be, so we take care of it now. - */ - mark_tcp_active(client, true); - - result = isc_socket_accept(client->tcplistener, client->task, - client_newconn, client); - if (result != ISC_R_SUCCESS) { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - */ - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - - tcpconn_detach(client); - mark_tcp_active(client, false); - return; - } - - /* - * The client's 'naccepts' counter indicates that this client has - * called accept() and is waiting for a new connection. It should - * never exceed 1. - */ - INSIST(client->naccepts == 0); - client->naccepts++; - - /* - * The interface's 'ntcpaccepting' counter is incremented when - * any client calls accept(), and decremented in client_newconn() - * once the connection is established. - * - * When the client object is shutting down after handling a TCP - * request (see exit_check()), if this value is at least one, that - * means another client has called accept() and is waiting to - * establish the next connection. That means the client may be - * be free to become inactive; otherwise it may need to start - * listening for connections itself to prevent the interface - * going dead. - */ - isc_refcount_increment0(&client->interface->ntcpaccepting, NULL); -} - -static void -client_udprecv(ns_client_t *client) { - isc_result_t result; - isc_region_t r; - - CTRACE("udprecv"); - - r.base = client->recvbuf; - r.length = RECV_BUFFER_SIZE; - result = isc_socket_recv2(client->udpsocket, &r, 1, - client->task, client->recvevent, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_recv2() failed: %s", - isc_result_totext(result)); - /* - * This cannot happen in the current implementation, since - * isc_socket_recv2() cannot fail if flags == 0. - * - * If this does fail, we just go idle. - */ - return; - } - INSIST(client->nrecvs == 0); - client->nrecvs++; -} - -void -ns_client_attach(ns_client_t *source, ns_client_t **targetp) { - REQUIRE(NS_CLIENT_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - source->references++; - ns_client_log(source, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_attach: ref = %d", source->references); - *targetp = source; -} - -void -ns_client_detach(ns_client_t **clientp) { - ns_client_t *client = *clientp; - - client->references--; - INSIST(client->references >= 0); - *clientp = NULL; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_detach: ref = %d", client->references); - (void)exit_check(client); -} - -bool -ns_client_shuttingdown(ns_client_t *client) { - return (client->newstate == NS_CLIENTSTATE_FREED); -} - -isc_result_t -ns_client_replace(ns_client_t *client) { - isc_result_t result; - bool tcp; - - CTRACE("replace"); - - REQUIRE(client != NULL); - REQUIRE(client->manager != NULL); - - tcp = TCP_CLIENT(client); - if (tcp && client->tcpconn != NULL && client->tcpconn->pipelined) { - result = get_worker(client->manager, client->interface, - client->tcpsocket, client); - } else { - result = get_client(client->manager, client->interface, - client->dispatch, tcp); - - } - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * The responsibility for listening for new requests is hereby - * transferred to the new client. Therefore, the old client - * should refrain from listening for any more requests. - */ - client->mortal = true; - - return (ISC_R_SUCCESS); -} - -/*** - *** Client Manager - ***/ - -static void -clientmgr_destroy(ns_clientmgr_t *manager) { -#if NMCTXS > 0 - int i; -#endif - - REQUIRE(ISC_LIST_EMPTY(manager->clients)); - - MTRACE("clientmgr_destroy"); - -#if NMCTXS > 0 - for (i = 0; i < NMCTXS; i++) { - if (manager->mctxpool[i] != NULL) - isc_mem_detach(&manager->mctxpool[i]); - } -#endif - - ISC_QUEUE_DESTROY(manager->inactive); - DESTROYLOCK(&manager->lock); - DESTROYLOCK(&manager->listlock); - DESTROYLOCK(&manager->reclock); - manager->magic = 0; - isc_mem_put(manager->mctx, manager, sizeof(*manager)); -} - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) -{ - ns_clientmgr_t *manager; - isc_result_t result; -#if NMCTXS > 0 - int i; -#endif - - manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&manager->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_manager; - - result = isc_mutex_init(&manager->listlock); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - result = isc_mutex_init(&manager->reclock); - if (result != ISC_R_SUCCESS) - goto cleanup_listlock; - - manager->mctx = mctx; - manager->taskmgr = taskmgr; - manager->timermgr = timermgr; - manager->exiting = false; - ISC_LIST_INIT(manager->clients); - ISC_LIST_INIT(manager->recursing); - ISC_QUEUE_INIT(manager->inactive, ilink); -#if NMCTXS > 0 - manager->nextmctx = 0; - for (i = 0; i < NMCTXS; i++) - manager->mctxpool[i] = NULL; /* will be created on-demand */ -#endif - manager->magic = MANAGER_MAGIC; - - MTRACE("create"); - - *managerp = manager; - - return (ISC_R_SUCCESS); - - cleanup_listlock: - (void) isc_mutex_destroy(&manager->listlock); - - cleanup_lock: - (void) isc_mutex_destroy(&manager->lock); - - cleanup_manager: - isc_mem_put(manager->mctx, manager, sizeof(*manager)); - - return (result); -} - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp) { - isc_result_t result; - ns_clientmgr_t *manager; - ns_client_t *client; - bool need_destroy = false, unlock = false; - - REQUIRE(managerp != NULL); - manager = *managerp; - REQUIRE(VALID_MANAGER(manager)); - - MTRACE("destroy"); - - /* - * Check for success because we may already be task-exclusive - * at this point. Only if we succeed at obtaining an exclusive - * lock now will we need to relinquish it later. - */ - result = isc_task_beginexclusive(ns_g_server->task); - if (result == ISC_R_SUCCESS) - unlock = true; - - manager->exiting = true; - - for (client = ISC_LIST_HEAD(manager->clients); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - if (ISC_LIST_EMPTY(manager->clients)) - need_destroy = true; - - if (unlock) - isc_task_endexclusive(ns_g_server->task); - - if (need_destroy) - clientmgr_destroy(manager); - - *managerp = NULL; -} - -/* - * ISC_QUEUE_POP is deliberately not tsan safe to avoid aquiring - * the taillock every time ISC_QUEUE_POP is called. - * Isolate ISC_QUEUE_POP from tsan analysis. - */ -ISC_NO_SANITIZE_THREAD static ns_client_t * -queue_pop(ns_clientmgr_t *manager) -{ - ns_client_t *client = NULL; - - if (!ns_g_clienttest) { - ISC_QUEUE_POP(manager->inactive, ilink, client); - } - return (client); -} - -static isc_result_t -get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, - dns_dispatch_t *disp, bool tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - isc_event_t *ev; - ns_client_t *client; - MTRACE("get client"); - - REQUIRE(manager != NULL); - - if (manager->exiting) - return (ISC_R_SHUTTINGDOWN); - - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = NULL; - if (!ns_g_clienttest) { - client = queue_pop(manager); - } - - if (client != NULL) - MTRACE("recycle"); - else { - MTRACE("create new"); - - LOCK(&manager->lock); - result = client_create(manager, &client); - UNLOCK(&manager->lock); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&manager->listlock); - ISC_LIST_APPEND(manager->clients, client, link); - UNLOCK(&manager->listlock); - } - - client->manager = manager; - ns_interface_attach(ifp, &client->interface); - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - client->dscp = ifp->dscp; - - if (tcp) { - mark_tcp_active(client, true); - - client->attributes |= NS_CLIENTATTR_TCP; - isc_socket_attach(ifp->tcpsocket, - &client->tcplistener); - - } else { - isc_socket_t *sock; - - dns_dispatch_attach(disp, &client->dispatch); - sock = dns_dispatch_getsocket(client->dispatch); - isc_socket_attach(sock, &client->udpsocket); - } - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - - return (result); -} - -static isc_result_t -get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, - ns_client_t *oldclient) -{ - isc_result_t result = ISC_R_SUCCESS; - isc_event_t *ev; - ns_client_t *client; - MTRACE("get worker"); - - REQUIRE(manager != NULL); - REQUIRE(oldclient != NULL); - - if (manager->exiting) - return (ISC_R_SHUTTINGDOWN); - - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = NULL; - if (!ns_g_clienttest) { - client = queue_pop(manager); - } - - if (client != NULL) - MTRACE("recycle"); - else { - MTRACE("create new"); - - LOCK(&manager->lock); - result = client_create(manager, &client); - UNLOCK(&manager->lock); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&manager->listlock); - ISC_LIST_APPEND(manager->clients, client, link); - UNLOCK(&manager->listlock); - } - - client->manager = manager; - ns_interface_attach(ifp, &client->interface); - client->newstate = client->state = NS_CLIENTSTATE_WORKING; - INSIST(client->recursionquota == NULL); - - client->dscp = ifp->dscp; - - client->attributes |= NS_CLIENTATTR_TCP; - client->mortal = true; - - tcpconn_attach(oldclient, client); - mark_tcp_active(client, true); - - isc_socket_attach(ifp->tcpsocket, &client->tcplistener); - isc_socket_attach(sock, &client->tcpsocket); - isc_socket_setname(client->tcpsocket, "worker-tcp", NULL); - (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr); - client->peeraddr_valid = true; - - INSIST(client->tcpmsg_valid == false); - dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg); - client->tcpmsg_valid = true; - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - - return (result); -} - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, bool tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - unsigned int disp; - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(n > 0); - - MTRACE("createclients"); - - for (disp = 0; disp < n; disp++) { - result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); - if (result != ISC_R_SUCCESS) - break; - } - - return (result); -} - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client) { - return (&client->peeraddr); -} - -isc_sockaddr_t * -ns_client_getdestaddr(ns_client_t *client) { - return (&client->destsockaddr); -} - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, - dns_acl_t *acl, bool default_allow) -{ - isc_result_t result; - isc_netaddr_t tmpnetaddr; - isc_netaddr_t *ecs_addr = NULL; - uint8_t ecs_addrlen = 0; - int match; - - if (acl == NULL) { - if (default_allow) - goto allow; - else - goto deny; - } - - if (netaddr == NULL) { - isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr); - netaddr = &tmpnetaddr; - } - - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - ecs_addr = &client->ecs_addr; - ecs_addrlen = client->ecs_addrlen; - } - - result = dns_acl_match2(netaddr, client->signer, - ecs_addr, ecs_addrlen, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS) - goto deny; /* Internal error, already logged. */ - - if (match > 0) - goto allow; - goto deny; /* Negative match or no match. */ - - allow: - return (ISC_R_SUCCESS); - - deny: - return (DNS_R_REFUSED); -} - -isc_result_t -ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr, - const char *opname, dns_acl_t *acl, - bool default_allow, int log_level) -{ - isc_result_t result; - isc_netaddr_t netaddr; - - if (sockaddr != NULL) - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL, - acl, default_allow); - - if (result == ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s approved", opname); - else - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - log_level, "%s denied", opname); - return (result); -} - -static void -ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { - if (client->peeraddr_valid) - isc_sockaddr_format(&client->peeraddr, peerbuf, - (unsigned int)len); - else - snprintf(peerbuf, len, "@%p", client); -} - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) -{ - char msgbuf[4096]; - char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *viewname = ""; - const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = ""; - const char *signer = "", *qname = ""; - dns_name_t *q = NULL; - - REQUIRE(client != NULL); - - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - - if (client->signer != NULL) { - dns_name_format(client->signer, signerbuf, sizeof(signerbuf)); - sep1 = "/key "; - signer = signerbuf; - } - - q = client->query.origqname != NULL - ? client->query.origqname : client->query.qname; - if (q != NULL) { - dns_name_format(q, qnamebuf, sizeof(qnamebuf)); - sep2 = " ("; - sep3 = ")"; - qname = qnamebuf; - } - - if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - sep4 = ": view "; - viewname = client->view->name; - } - - if (client->peeraddr_valid) { - isc_sockaddr_format(&client->peeraddr, - peerbuf, sizeof(peerbuf)); - } else { - snprintf(peerbuf, sizeof(peerbuf), "(no-peer)"); - } - - isc_log_write(ns_g_lctx, category, module, level, - "client @%p %s%s%s%s%s%s%s%s: %s", - client, peerbuf, sep1, signer, sep2, qname, sep3, - sep4, viewname, msgbuf); -} - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, ...) -{ - va_list ap; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - va_start(ap, fmt); - ns_client_logv(client, category, module, level, fmt, ap); - va_end(ap); -} - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, - classbuf); -} - -static void -ns_client_dumpmessage(ns_client_t *client, const char *reason) { - isc_buffer_t buffer; - char *buf = NULL; - int len = 1024; - isc_result_t result; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1))) - return; - - /* - * Note that these are multiline debug messages. We want a newline - * to appear in the log after each message. - */ - - do { - buf = isc_mem_get(client->mctx, len); - if (buf == NULL) - break; - isc_buffer_init(&buffer, buf, len); - result = dns_message_totext(client->message, - &dns_master_style_debug, - 0, &buffer); - if (result == ISC_R_NOSPACE) { - isc_mem_put(client->mctx, buf, len); - len += 1024; - } else if (result == ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "%s\n%.*s", reason, - (int)isc_buffer_usedlength(&buffer), - buf); - } while (result == ISC_R_NOSPACE); - - if (buf != NULL) - isc_mem_put(client->mctx, buf, len); -} - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { - ns_client_t *client; - char namebuf[DNS_NAME_FORMATSIZE]; - char original[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - const char *name; - const char *sep; - const char *origfor; - dns_rdataset_t *rdataset; - - REQUIRE(VALID_MANAGER(manager)); - - LOCK(&manager->reclock); - client = ISC_LIST_HEAD(manager->recursing); - while (client != NULL) { - INSIST(client->state == NS_CLIENTSTATE_RECURSING); - - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && - strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } else { - name = ""; - sep = ""; - } - - LOCK(&client->query.fetchlock); - INSIST(client->query.qname != NULL); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - if (client->query.qname != client->query.origqname && - client->query.origqname != NULL) { - origfor = " for "; - dns_name_format(client->query.origqname, original, - sizeof(original)); - } else { - origfor = ""; - original[0] = '\0'; - } - rdataset = ISC_LIST_HEAD(client->query.qname->list); - if (rdataset == NULL && client->query.origqname != NULL) - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - if (rdataset != NULL) { - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - } else { - strlcpy(typebuf, "-", sizeof(typebuf)); - strlcpy(classbuf, "-", sizeof(classbuf)); - } - UNLOCK(&client->query.fetchlock); - fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s " - "requesttime %u\n", peerbuf, sep, name, - client->message->id, namebuf, typebuf, classbuf, - origfor, original, - isc_time_seconds(&client->requesttime)); - client = ISC_LIST_NEXT(client, rlink); - } - UNLOCK(&manager->reclock); -} - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { - LOCK(&client->query.fetchlock); - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = name; - client->query.attributes &= ~NS_QUERYATTR_REDIRECT; - UNLOCK(&client->query.fetchlock); -} - -isc_result_t -ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) { - ns_client_t *client = (ns_client_t *) ci->data; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(addrp != NULL); - - *addrp = &client->peeraddr; - return (ISC_R_SUCCESS); -} diff --git a/bin/named-pkcs11/config.c b/bin/named-pkcs11/config.c deleted file mode 100644 index d2cd3bc..0000000 --- a/bin/named-pkcs11/config.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -/*% default configuration */ -static char defaultconf[] = "\ -options {\n\ - answer-cookie true;\n\ - automatic-interface-scan yes;\n\ - bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\ -# blackhole {none;};\n" -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) -" cookie-algorithm aes;\n" -#else -" cookie-algorithm sha256;\n" -#endif -#ifndef WIN32 -" coresize default;\n\ - datasize default;\n" -#endif -"\ -# deallocate-on-exit ;\n\ -# directory \n\ - dump-file \"named_dump.db\";\n\ - edns-udp-size 1232;\n\ -# fake-iquery ;\n" -#ifndef WIN32 -" files unlimited;\n" -#endif -#if defined(HAVE_GEOIP2) && !defined(WIN32) -" geoip-directory \"" MAXMINDDB_PREFIX "/share/GeoIP\";\n" -#elif defined(HAVE_GEOIP2) -" geoip-directory \".\";\n" -#endif -"\ -# has-old-clients ;\n\ - heartbeat-interval 60;\n\ -# host-statistics ;\n\ - interface-interval 60;\n\ -# keep-response-order {none;};\n\ - listen-on {any;};\n\ - listen-on-v6 {any;};\n\ -# lock-file \"" NS_LOCALSTATEDIR "/run/named/named.lock\";\n\ - match-mapped-addresses no;\n\ - max-rsa-exponent-size 0; /* no limit */\n\ - max-udp-size 1232;\n\ - memstatistics-file \"named.memstats\";\n\ -# multiple-cnames ;\n\ -# named-xfer ;\n\ - nocookie-udp-size 4096;\n\ - notify-rate 20;\n\ - nta-lifetime 3600;\n\ - nta-recheck 300;\n\ -# pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\ - port 53;\n\ - prefetch 2 9;\n" -#if defined(ISC_PLATFORM_CRYPTORANDOM) -" random-device none;\n" -#elif defined(PATH_RANDOMDEV) -" random-device \"" PATH_RANDOMDEV "\";\n" -#endif -" recursing-file \"named.recursing\";\n\ - recursive-clients 1000;\n\ - request-nsid false;\n\ - reserved-sockets 512;\n\ - resolver-query-timeout 10;\n\ - rrset-order { order random; };\n\ - secroots-file \"named.secroots\";\n\ - send-cookie true;\n\ -# serial-queries ;\n\ - serial-query-rate 20;\n\ - server-id none;\n\ - session-keyalg hmac-sha256;\n\ -# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\ - session-keyname local-ddns;\n" -#ifndef WIN32 -" stacksize default;\n" -#endif -" startup-notify-rate 20;\n\ - statistics-file \"named.stats\";\n\ -# statistics-interval ;\n\ - tcp-clients 150;\n\ - tcp-listen-queue 10;\n\ -# tkey-dhkey \n\ -# tkey-domain \n\ -# tkey-gssapi-credential \n\ - transfer-message-size 20480;\n\ - transfers-in 10;\n\ - transfers-out 10;\n\ - transfers-per-ns 2;\n\ -# treat-cr-as-space ;\n\ - trust-anchor-telemetry yes;\n\ -# use-id-pool ;\n\ -# use-ixfr ;\n\ -\n\ - /* view */\n\ - acache-cleaning-interval 60;\n\ - acache-enable no;\n\ - additional-from-auth true;\n\ - additional-from-cache true;\n\ - allow-new-zones no;\n\ - allow-notify {none;};\n\ - allow-query-cache { localnets; localhost; };\n\ - allow-query-cache-on { any; };\n\ - allow-recursion { localnets; localhost; };\n\ - allow-recursion-on { any; };\n\ - allow-update-forwarding {none;};\n\ -# allow-v6-synthesis ;\n\ - auth-nxdomain false;\n\ - check-dup-records warn;\n\ - check-mx warn;\n\ - check-names master fail;\n\ - check-names response ignore;\n\ - check-names slave warn;\n\ - check-spf warn;\n\ - cleaning-interval 0; /* now meaningless */\n\ - clients-per-query 10;\n\ - dnssec-accept-expired no;\n\ - dnssec-enable yes;\n\ - dnssec-validation yes; \n" -#ifdef HAVE_DNSTAP -" dnstap-identity hostname;\n" -#endif -"\ -# fetch-glue ;\n\ - fetch-quota-params 100 0.1 0.3 0.7;\n\ - fetches-per-server 0;\n\ - fetches-per-zone 0;\n" -#ifdef ALLOW_FILTER_AAAA -" filter-aaaa-on-v4 no;\n\ - filter-aaaa-on-v6 no;\n\ - filter-aaaa { any; };\n" -#endif -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -" geoip-use-ecs yes;\n" -#endif -" lame-ttl 600;\n" -#ifdef HAVE_LMDB -" lmdb-mapsize 32M;\n" -#endif -" max-cache-size 90%;\n\ - max-acache-size 16M;\n\ - max-cache-ttl 604800; /* 1 week */\n\ - max-clients-per-query 100;\n\ - max-ncache-ttl 10800; /* 3 hours */\n\ - max-recursion-depth 7;\n\ - max-recursion-queries 100;\n\ - max-stale-ttl 604800; /* 1 week */\n\ - message-compression yes;\n\ -# min-roots ;\n\ - minimal-any false;\n\ - minimal-responses false;\n\ - notify-source *;\n\ - notify-source-v6 *;\n\ - nsec3-test-zone no;\n\ - provide-ixfr true;\n\ - query-source address *;\n\ - query-source-v6 address *;\n\ - recursion true;\n\ - request-expire true;\n\ - request-ixfr true;\n\ - require-server-cookie no;\n\ - resolver-nonbackoff-tries 3;\n\ - resolver-retry-interval 800; /* in milliseconds */\n\ -# rfc2308-type1 ;\n\ - root-key-sentinel yes;\n\ - servfail-ttl 1;\n\ -# sortlist \n\ - stale-answer-enable false;\n\ - stale-answer-ttl 1; /* 1 second */\n\ -# topology \n\ - transfer-format many-answers;\n\ - v6-bias 50;\n\ - zero-no-soa-ttl-cache no;\n\ -\n\ - /* zone */\n\ - allow-query {any;};\n\ - allow-query-on {any;};\n\ - allow-transfer {any;};\n\ -# also-notify \n\ - alt-transfer-source *;\n\ - alt-transfer-source-v6 *;\n\ - check-integrity yes;\n\ - check-mx-cname warn;\n\ - check-sibling yes;\n\ - check-srv-cname warn;\n\ - check-wildcard yes;\n\ - dialup no;\n\ - dnssec-dnskey-kskonly no;\n\ - dnssec-loadkeys-interval 60;\n\ - dnssec-secure-to-insecure no;\n\ - dnssec-update-mode maintain;\n\ -# forward \n\ -# forwarders \n\ - inline-signing no;\n\ - ixfr-from-differences false;\n\ -# maintain-ixfr-base ;\n\ -# max-ixfr-log-size \n\ - max-journal-size unlimited;\n\ - max-records 0;\n\ - max-refresh-time 2419200; /* 4 weeks */\n\ - max-retry-time 1209600; /* 2 weeks */\n\ - max-transfer-idle-in 60;\n\ - max-transfer-idle-out 60;\n\ - max-transfer-time-in 120;\n\ - max-transfer-time-out 120;\n\ - min-refresh-time 300;\n\ - min-retry-time 500;\n\ - multi-master no;\n\ - notify yes;\n\ - notify-delay 5;\n\ - notify-to-soa no;\n\ - serial-update-method increment;\n\ - sig-signing-nodes 100;\n\ - sig-signing-signatures 10;\n\ - sig-signing-type 65534;\n\ - sig-validity-interval 30; /* days */\n\ - transfer-source *;\n\ - transfer-source-v6 *;\n\ - try-tcp-refresh yes; /* BIND 8 compat */\n\ - update-check-ksk yes;\n\ - zero-no-soa-ttl yes;\n\ - zone-statistics terse;\n\ -};\n\ -" - -"#\n\ -# Zones in the \"_bind\" view are NOT counted in the count of zones.\n\ -#\n\ -view \"_bind\" chaos {\n\ - recursion no;\n\ - notify no;\n\ - allow-new-zones no;\n\ -\n\ - # Prevent use of this zone in DNS amplified reflection DoS attacks\n\ - rate-limit {\n\ - responses-per-second 3;\n\ - slip 0;\n\ - min-table-size 10;\n\ - };\n\ -\n\ - zone \"version.bind\" chaos {\n\ - type master;\n\ - database \"_builtin version\";\n\ - };\n\ -\n\ - zone \"hostname.bind\" chaos {\n\ - type master;\n\ - database \"_builtin hostname\";\n\ - };\n\ -\n\ - zone \"authors.bind\" chaos {\n\ - type master;\n\ - database \"_builtin authors\";\n\ - };\n\ -\n\ - zone \"id.server\" chaos {\n\ - type master;\n\ - database \"_builtin id\";\n\ - };\n\ -};\n\ -" -"#\n\ -# Default trusted key(s), used if \n\ -# \"dnssec-validation auto;\" is set and\n\ -# sysconfdir/bind.keys doesn't exist).\n\ -#\n\ -# BEGIN MANAGED KEYS\n" - -/* Imported from bind.keys.h: */ -MANAGED_KEYS - -"# END MANAGED KEYS\n\ -"; - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { - isc_buffer_t b; - - isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); - isc_buffer_add(&b, sizeof(defaultconf) - 1); - return (cfg_parse_buffer4(parser, &b, __FILE__, 0, - &cfg_type_namedconf, - CFG_PCTX_NODEPRECATED, conf)); -} - -isc_result_t -ns_config_get(cfg_obj_t const * const *maps, const char *name, - const cfg_obj_t **obj) -{ - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - } -} - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char *which, - const cfg_obj_t **obj) -{ - const cfg_listelt_t *element; - const cfg_obj_t *checknames; - const cfg_obj_t *type; - const cfg_obj_t *value; - int i; - - REQUIRE(maps != NULL); - REQUIRE(which != NULL); - REQUIRE(obj != NULL && *obj == NULL); - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - checknames = NULL; - if (cfg_map_get(maps[i], "check-names", - &checknames) == ISC_R_SUCCESS) { - /* - * Zone map entry is not a list. - */ - if (checknames != NULL && !cfg_obj_islist(checknames)) { - *obj = checknames; - return (ISC_R_SUCCESS); - } - for (element = cfg_list_first(checknames); - element != NULL; - element = cfg_list_next(element)) { - value = cfg_listelt_value(element); - type = cfg_tuple_get(value, "type"); - if (strcasecmp(cfg_obj_asstring(type), - which) == 0) { - *obj = cfg_tuple_get(value, "mode"); - return (ISC_R_SUCCESS); - } - } - - } - } -} - -int -ns_config_listcount(const cfg_obj_t *list) { - const cfg_listelt_t *e; - int i = 0; - - for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e)) - i++; - - return (i); -} - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(classobj)) { - *classp = defclass; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(classobj), r.base); - r.length = strlen(r.base); - result = dns_rdataclass_fromtext(classp, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown class '%s'", r.base); - return (result); -} - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(typeobj)) { - *typep = deftype; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(typeobj), r.base); - r.length = strlen(r.base); - result = dns_rdatatype_fromtext(typep, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown type '%s'", r.base); - return (result); -} - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj) { - dns_zonetype_t ztype = dns_zone_none; - const char *str; - - str = cfg_obj_asstring(zonetypeobj); - if (strcasecmp(str, "master") == 0) { - ztype = dns_zone_master; - } else if (strcasecmp(str, "slave") == 0) { - ztype = dns_zone_slave; - } else if (strcasecmp(str, "stub") == 0) { - ztype = dns_zone_stub; - } else if (strcasecmp(str, "static-stub") == 0) { - ztype = dns_zone_staticstub; - } else if (strcasecmp(str, "redirect") == 0) { - ztype = dns_zone_redirect; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - return (ztype); -} - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, - uint32_t *countp) -{ - int count, i = 0; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj, *dscpobj; - const cfg_listelt_t *element; - isc_sockaddr_t *addrs; - in_port_t port; - isc_dscp_t dscp = -1, *dscps = NULL; - isc_result_t result; - - INSIST(addrsp != NULL && *addrsp == NULL); - INSIST(dscpsp == NULL || *dscpsp == NULL); - INSIST(countp != NULL); - - addrlist = cfg_tuple_get(list, "addresses"); - count = ns_config_listcount(addrlist); - - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } else if (defport != 0) - port = defport; - else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - - if (dscpsp != NULL) { - dscpobj = cfg_tuple_get(list, "dscp"); - if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t)); - if (dscps == NULL) - return (ISC_R_NOMEMORY); - } - - addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); - if (addrs == NULL) { - if (dscps != NULL) - isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t)); - return (ISC_R_NOMEMORY); - } - - for (element = cfg_list_first(addrlist); - element != NULL; - element = cfg_list_next(element), i++) - { - const cfg_obj_t *addr; - INSIST(i < count); - addr = cfg_listelt_value(element); - addrs[i] = *cfg_obj_assockaddr(addr); - if (dscpsp != NULL) { - isc_dscp_t innerdscp; - innerdscp = cfg_obj_getdscp(addr); - if (innerdscp == -1) - innerdscp = dscp; - dscps[i] = innerdscp; - } - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - } - INSIST(i == count); - - *addrsp = addrs; - *countp = count; - - if (dscpsp != NULL) - *dscpsp = dscps; - - return (ISC_R_SUCCESS); -} - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_dscp_t **dscpsp, uint32_t count) -{ - INSIST(addrsp != NULL && *addrsp != NULL); - INSIST(dscpsp == NULL || *dscpsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - *addrsp = NULL; - - if (dscpsp != NULL) { - isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t)); - *dscpsp = NULL; - } -} - -static isc_result_t -get_masters_def(const cfg_obj_t *cctx, const char *name, - const cfg_obj_t **ret) -{ - isc_result_t result; - const cfg_obj_t *masters = NULL; - const cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "masters", &masters); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(masters); - elt != NULL; - elt = cfg_list_next(elt)) { - const cfg_obj_t *list; - const char *listname; - - list = cfg_listelt_value(elt); - listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); - - if (strcasecmp(listname, name) == 0) { - *ret = list; - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, dns_ipkeylist_t *ipkl) -{ - uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0; - uint32_t listcount = 0, l = 0, j; - uint32_t stackcount = 0, pushed = 0; - isc_result_t result; - const cfg_listelt_t *element; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj; - const cfg_obj_t *dscpobj; - in_port_t port; - isc_dscp_t dscp = -1; - dns_fixedname_t fname; - isc_sockaddr_t *addrs = NULL; - isc_dscp_t *dscps = NULL; - dns_name_t **keys = NULL; - struct { const char *name; } *lists = NULL; - struct { - const cfg_listelt_t *element; - in_port_t port; - isc_dscp_t dscp; - } *stack = NULL; - - REQUIRE(ipkl != NULL); - REQUIRE(ipkl->count == 0); - REQUIRE(ipkl->addrs == NULL); - REQUIRE(ipkl->keys == NULL); - REQUIRE(ipkl->dscps == NULL); - REQUIRE(ipkl->labels == NULL); - REQUIRE(ipkl->allocated == 0); - - /* - * Get system defaults. - */ - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_config_getdscp(config, &dscp); - if (result != ISC_R_SUCCESS) - goto cleanup; - - newlist: - addrlist = cfg_tuple_get(list, "addresses"); - portobj = cfg_tuple_get(list, "port"); - dscpobj = cfg_tuple_get(list, "dscp"); - - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - result = ISC_R_RANGE; - goto cleanup; - } - port = (in_port_t) val; - } - - if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - result = ISC_R_RANGE; - goto cleanup; - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - result = ISC_R_NOMEMORY; - - element = cfg_list_first(addrlist); - resume: - for ( ; - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *addr; - const cfg_obj_t *key; - const char *keystr; - isc_buffer_t b; - - addr = cfg_tuple_get(cfg_listelt_value(element), - "masterselement"); - key = cfg_tuple_get(cfg_listelt_value(element), "key"); - - if (!cfg_obj_issockaddr(addr)) { - const char *listname = cfg_obj_asstring(addr); - isc_result_t tresult; - - /* Grow lists? */ - if (listcount == l) { - void * tmp; - uint32_t newlen = listcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*lists); - oldsize = listcount * sizeof(*lists); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (listcount != 0) { - memmove(tmp, lists, oldsize); - isc_mem_put(mctx, lists, oldsize); - } - lists = tmp; - listcount = newlen; - } - /* Seen? */ - for (j = 0; j < l; j++) - if (strcasecmp(lists[j].name, listname) == 0) - break; - if (j < l) - continue; - tresult = get_masters_def(config, listname, &list); - if (tresult == ISC_R_NOTFOUND) { - cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, - "masters \"%s\" not found", listname); - - result = tresult; - goto cleanup; - } - if (tresult != ISC_R_SUCCESS) - goto cleanup; - lists[l++].name = listname; - /* Grow stack? */ - if (stackcount == pushed) { - void * tmp; - uint32_t newlen = stackcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*stack); - oldsize = stackcount * sizeof(*stack); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (stackcount != 0) { - memmove(tmp, stack, oldsize); - isc_mem_put(mctx, stack, oldsize); - } - stack = tmp; - stackcount = newlen; - } - /* - * We want to resume processing this list on the - * next element. - */ - stack[pushed].element = cfg_list_next(element); - stack[pushed].port = port; - stack[pushed].dscp = dscp; - pushed++; - goto newlist; - } - - if (i == addrcount) { - void * tmp; - uint32_t newlen = addrcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (addrcount != 0) { - memmove(tmp, addrs, oldsize); - isc_mem_put(mctx, addrs, oldsize); - } - addrs = tmp; - addrcount = newlen; - - newsize = newlen * sizeof(isc_dscp_t); - oldsize = dscpcount * sizeof(isc_dscp_t); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (dscpcount != 0) { - memmove(tmp, dscps, oldsize); - isc_mem_put(mctx, dscps, oldsize); - } - dscps = tmp; - dscpcount = newlen; - - newsize = newlen * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (keycount != 0) { - memmove(tmp, keys, oldsize); - isc_mem_put(mctx, keys, oldsize); - } - keys = tmp; - keycount = newlen; - } - - addrs[i] = *cfg_obj_assockaddr(addr); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - dscps[i] = cfg_obj_getdscp(addr); - if (dscps[i] == -1) - dscps[i] = dscp; - keys[i] = NULL; - i++; /* Increment here so that cleanup on error works. */ - if (!cfg_obj_isstring(key)) - continue; - keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t)); - if (keys[i - 1] == NULL) - goto cleanup; - dns_name_init(keys[i - 1], NULL); - - keystr = cfg_obj_asstring(key); - isc_buffer_constinit(&b, keystr, strlen(keystr)); - isc_buffer_add(&b, strlen(keystr)); - dns_fixedname_init(&fname); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_name_dup(dns_fixedname_name(&fname), mctx, - keys[i - 1]); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - if (pushed != 0) { - pushed--; - element = stack[pushed].element; - port = stack[pushed].port; - dscp = stack[pushed].dscp; - goto resume; - } - if (i < addrcount) { - void * tmp; - size_t newsize, oldsize; - - newsize = i * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, addrs, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, addrs, oldsize); - addrs = tmp; - addrcount = i; - - newsize = i * sizeof(isc_dscp_t); - oldsize = dscpcount * sizeof(isc_dscp_t); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, dscps, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, dscps, oldsize); - dscps = tmp; - dscpcount = i; - - newsize = i * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, keys, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, keys, oldsize); - keys = tmp; - keycount = i; - } - - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - - INSIST(dscpcount == addrcount); - INSIST(keycount == addrcount); - INSIST(keycount == dscpcount); - - ipkl->addrs = addrs; - ipkl->dscps = dscps; - ipkl->keys = keys; - ipkl->count = addrcount; - ipkl->allocated = addrcount; - - return (ISC_R_SUCCESS); - - cleanup: - if (addrs != NULL) - isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); - if (dscps != NULL) - isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t)); - if (keys != NULL) { - for (j = 0; j < i; j++) { - if (keys[j] == NULL) - continue; - if (dns_name_dynamic(keys[j])) - dns_name_free(keys[j], mctx); - isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); - } - isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); - } - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - return (result); -} - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp) { - const cfg_obj_t *maps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *portobj = NULL; - isc_result_t result; - int i; - - (void)cfg_map_get(config, "options", &options); - i = 0; - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "port", &portobj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_asuint32(portobj) >= UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - *portp = (in_port_t)cfg_obj_asuint32(portobj); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) { - const cfg_obj_t *options = NULL; - const cfg_obj_t *dscpobj = NULL; - isc_result_t result; - - (void)cfg_map_get(config, "options", &options); - if (options == NULL) - return (ISC_R_SUCCESS); - - result = cfg_map_get(options, "dscp", &dscpobj); - if (result != ISC_R_SUCCESS || dscpobj == NULL) { - *dscpp = -1; - return (ISC_R_SUCCESS); - } - if (cfg_obj_asuint32(dscpobj) >= 64) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp '%u' out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - *dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - return (ISC_R_SUCCESS); -} - -struct keyalgorithms { - const char *str; - enum { hmacnone, hmacmd5, hmacsha1, hmacsha224, - hmacsha256, hmacsha384, hmacsha512 } hmac; - unsigned int type; - uint16_t size; -} algorithms[] = { -#ifndef PK11_MD5_DISABLE - { "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 }, - { "hmac-md5.sig-alg.reg.int", hmacmd5, DST_ALG_HMACMD5, 0 }, - { "hmac-md5.sig-alg.reg.int.", hmacmd5, DST_ALG_HMACMD5, 0 }, -#endif - { "hmac-sha1", hmacsha1, DST_ALG_HMACSHA1, 160 }, - { "hmac-sha224", hmacsha224, DST_ALG_HMACSHA224, 224 }, - { "hmac-sha256", hmacsha256, DST_ALG_HMACSHA256, 256 }, - { "hmac-sha384", hmacsha384, DST_ALG_HMACSHA384, 384 }, - { "hmac-sha512", hmacsha512, DST_ALG_HMACSHA512, 512 }, - { NULL, hmacnone, DST_ALG_UNKNOWN, 0 } -}; - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - uint16_t *digestbits) -{ - return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits)); -} - -static inline int -algorithms_start() { -#ifndef PK11_MD5_DISABLE - if (!isc_md5_available()) { - int i = 0; - while (algorithms[i].str != NULL && - algorithms[i].hmac == hmacmd5) { - i++; - } - return i; - } -#endif - return 0; -} - -isc_result_t -ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, - unsigned int *typep, uint16_t *digestbits) -{ - int i; - size_t len = 0; - uint16_t bits; - isc_result_t result; - - for (i = algorithms_start(); algorithms[i].str != NULL; i++) { - len = strlen(algorithms[i].str); - if (strncasecmp(algorithms[i].str, str, len) == 0 && - (str[len] == '\0' || - (algorithms[i].size != 0 && str[len] == '-'))) - break; - } - if (algorithms[i].str == NULL) - return (ISC_R_NOTFOUND); - if (str[len] == '-') { - result = isc_parse_uint16(&bits, str + len + 1, 10); - if (result != ISC_R_SUCCESS) - return (result); - if (bits > algorithms[i].size) - return (ISC_R_RANGE); - } else if (algorithms[i].size == 0) - bits = 128; - else - bits = algorithms[i].size; - - if (name != NULL) { - switch (algorithms[i].hmac) { -#ifndef PK11_MD5_DISABLE - case hmacmd5: - if (isc_md5_available()) { - *name = dns_tsig_hmacmd5_name; break; - } else { - return (ISC_R_NOTFOUND); - } -#endif - case hmacsha1: *name = dns_tsig_hmacsha1_name; break; - case hmacsha224: *name = dns_tsig_hmacsha224_name; break; - case hmacsha256: *name = dns_tsig_hmacsha256_name; break; - case hmacsha384: *name = dns_tsig_hmacsha384_name; break; - case hmacsha512: *name = dns_tsig_hmacsha512_name; break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (typep != NULL) - *typep = algorithms[i].type; - if (digestbits != NULL) - *digestbits = bits; - return (ISC_R_SUCCESS); -} diff --git a/bin/named-pkcs11/control.c b/bin/named-pkcs11/control.c deleted file mode 100644 index 0756c73..0000000 --- a/bin/named-pkcs11/control.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static isc_result_t -getcommand(isc_lex_t *lex, char **cmdp) { - isc_result_t result; - isc_token_t token; - - REQUIRE(cmdp != NULL && *cmdp == NULL); - - result = isc_lex_gettoken(lex, ISC_LEXOPT_EOF, &token); - if (result != ISC_R_SUCCESS) - return (result); - - isc_lex_ungettoken(lex, &token); - - if (token.type != isc_tokentype_string) - return (ISC_R_FAILURE); - - *cmdp = token.value.as_textregion.base; - - return (ISC_R_SUCCESS); -} - -static inline bool -command_compare(const char *str, const char *command) { - return (strcasecmp(str, command) == 0); -} - -/*% - * This function is called to process the incoming command - * when a control channel message is received. - */ -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, bool readonly, - isc_buffer_t **text) -{ - isccc_sexpr_t *data; - char *cmdline = NULL; - char *command = NULL; - isc_result_t result; - int log_level; - isc_buffer_t src; - isc_lex_t *lex = NULL; -#ifdef HAVE_LIBSCF - ns_smf_want_disable = 0; -#endif - - data = isccc_alist_lookup(message, "_data"); - if (!isccc_alist_alistp(data)) { - /* - * No data section. - */ - return (ISC_R_FAILURE); - } - - result = isccc_cc_lookupstring(data, "type", &cmdline); - if (result != ISC_R_SUCCESS) { - /* - * We have no idea what this is. - */ - return (result); - } - - result = isc_lex_create(ns_g_mctx, strlen(cmdline), &lex); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_init(&src, cmdline, strlen(cmdline)); - isc_buffer_add(&src, strlen(cmdline)); - result = isc_lex_openbuffer(lex, &src); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = getcommand(lex, &command); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Compare the 'command' parameter against all known control commands. - */ - if ((command_compare(command, NS_COMMAND_NULL) && - strlen(cmdline) == 4) || - command_compare(command, NS_COMMAND_STATUS)) - { - log_level = ISC_LOG_DEBUG(1); - } else { - log_level = ISC_LOG_INFO; - } - - /* - * If this listener should have read-only access, reject - * restricted commands here. rndc nta is handled specially - * below. - */ - if (readonly && - !command_compare(command, NS_COMMAND_NTA) && - !command_compare(command, NS_COMMAND_NULL) && - !command_compare(command, NS_COMMAND_STATUS) && - !command_compare(command, NS_COMMAND_SHOWZONE) && - !command_compare(command, NS_COMMAND_TESTGEN) && - !command_compare(command, NS_COMMAND_ZONESTATUS)) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, log_level, - "rejecting restricted control channel " - "command '%s'", cmdline); - result = ISC_R_FAILURE; - goto cleanup; - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, log_level, - "received control channel command '%s'", - cmdline); - - /* - * After the lengthy "halt" and "stop", the commands are - * handled in alphabetical order of the NS_COMMAND_ macros. - */ - if (command_compare(command, NS_COMMAND_HALT)) { -#ifdef HAVE_LIBSCF - /* - * If we are managed by smf(5), AND in chroot, then - * we cannot connect to the smf repository, so just - * return with an appropriate message back to rndc. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - goto cleanup; - } - /* - * If we are managed by smf(5) but not in chroot, - * try to disable ourselves the smf way. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; - /* - * If ns_smf_got_instance = 0, ns_smf_chroot - * is not relevant and we fall through to - * isc_app_shutdown below. - */ -#endif - /* Do not flush master files */ - ns_server_flushonshutdown(ns_g_server, false); - ns_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_STOP)) { - /* - * "stop" is the same as "halt" except it does - * flush master files. - */ -#ifdef HAVE_LIBSCF - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - goto cleanup; - } - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; -#endif - ns_server_flushonshutdown(ns_g_server, true); - ns_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_ADDZONE) || - command_compare(command, NS_COMMAND_MODZONE)) { - result = ns_server_changezone(ns_g_server, cmdline, text); - } else if (command_compare(command, NS_COMMAND_DELZONE)) { - result = ns_server_delzone(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_DNSTAP) || - command_compare(command, NS_COMMAND_DNSTAPREOPEN)) { - result = ns_server_dnstap(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_DUMPDB)) { - ns_server_dumpdb(ns_g_server, lex, text); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) { - result = ns_server_dumpstats(ns_g_server); - } else if (command_compare(command, NS_COMMAND_FLUSH)) { - result = ns_server_flushcache(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { - result = ns_server_flushnode(ns_g_server, lex, false); - } else if (command_compare(command, NS_COMMAND_FLUSHTREE)) { - result = ns_server_flushnode(ns_g_server, lex, true); - } else if (command_compare(command, NS_COMMAND_FREEZE)) { - result = ns_server_freeze(ns_g_server, true, lex, - text); - } else if (command_compare(command, NS_COMMAND_LOADKEYS) || - command_compare(command, NS_COMMAND_SIGN)) { - result = ns_server_rekey(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_MKEYS)) { - result = ns_server_mkeys(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_NOTIFY)) { - result = ns_server_notifycommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_NOTRACE)) { - ns_g_debuglevel = 0; - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_NTA)) { - result = ns_server_nta(ns_g_server, lex, readonly, text); - } else if (command_compare(command, NS_COMMAND_NULL)) { - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_QUERYLOG)) { - result = ns_server_togglequerylog(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_RECONFIG)) { - result = ns_server_reconfigcommand(ns_g_server); - } else if (command_compare(command, NS_COMMAND_RECURSING)) { - result = ns_server_dumprecursing(ns_g_server); - } else if (command_compare(command, NS_COMMAND_REFRESH)) { - result = ns_server_refreshcommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_RELOAD)) { - result = ns_server_reloadcommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_RETRANSFER)) { - result = ns_server_retransfercommand(ns_g_server, - lex, text); - } else if (command_compare(command, NS_COMMAND_SCAN)) { - result = ISC_R_SUCCESS; - ns_server_scan_interfaces(ns_g_server); - } else if (command_compare(command, NS_COMMAND_SECROOTS)) { - result = ns_server_dumpsecroots(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SIGNING)) { - result = ns_server_signing(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SHOWZONE)) { - result = ns_server_showzone(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_STATUS)) { - result = ns_server_status(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_SYNC)) { - result = ns_server_sync(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_THAW) || - command_compare(command, NS_COMMAND_UNFREEZE)) { - result = ns_server_freeze(ns_g_server, false, lex, - text); - } else if (command_compare(command, NS_COMMAND_TESTGEN)) { - result = ns_server_testgen(lex, text); - } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) { - result = ISC_R_SUCCESS; - isc_timermgr_poke(ns_g_timermgr); - } else if (command_compare(command, NS_COMMAND_TRACE)) { - result = ns_server_setdebuglevel(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) { - result = ns_server_tsigdelete(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_TSIGLIST)) { - result = ns_server_tsiglist(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_VALIDATION)) { - result = ns_server_validation(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_ZONESTATUS)) { - result = ns_server_zonestatus(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SERVESTALE)) { - result = ns_server_servestale(ns_g_server, lex, text); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "unknown control channel command '%s'", - command); - result = DNS_R_UNKNOWNCOMMAND; - } - - cleanup: - if (lex != NULL) - isc_lex_destroy(&lex); - - return (result); -} diff --git a/bin/named-pkcs11/controlconf.c b/bin/named-pkcs11/controlconf.c deleted file mode 100644 index 42128dc..0000000 --- a/bin/named-pkcs11/controlconf.c +++ /dev/null @@ -1,1556 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -/* - * Note: Listeners and connections are not locked. All event handlers are - * executed by the server task, and all callers of exported routines must - * be running under the server task. - */ - -typedef struct controlkey controlkey_t; -typedef ISC_LIST(controlkey_t) controlkeylist_t; - -typedef struct controlconnection controlconnection_t; -typedef ISC_LIST(controlconnection_t) controlconnectionlist_t; - -typedef struct controllistener controllistener_t; -typedef ISC_LIST(controllistener_t) controllistenerlist_t; - -struct controlkey { - char * keyname; - uint32_t algorithm; - isc_region_t secret; - ISC_LINK(controlkey_t) link; -}; - -struct controlconnection { - isc_socket_t * sock; - isccc_ccmsg_t ccmsg; - bool ccmsg_valid; - bool sending; - isc_timer_t * timer; - isc_buffer_t * buffer; - controllistener_t * listener; - uint32_t nonce; - ISC_LINK(controlconnection_t) link; -}; - -struct controllistener { - ns_controls_t * controls; - isc_mem_t * mctx; - isc_task_t * task; - isc_sockaddr_t address; - isc_socket_t * sock; - dns_acl_t * acl; - bool listening; - bool exiting; - controlkeylist_t keys; - controlconnectionlist_t connections; - isc_sockettype_t type; - uint32_t perm; - uint32_t owner; - uint32_t group; - bool readonly; - ISC_LINK(controllistener_t) link; -}; - -struct ns_controls { - ns_server_t *server; - controllistenerlist_t listeners; - bool shuttingdown; - isc_mutex_t symtab_lock; - isccc_symtab_t *symtab; -}; - -static void control_newconn(isc_task_t *task, isc_event_t *event); -static void control_recvmessage(isc_task_t *task, isc_event_t *event); - -#define CLOCKSKEW 300 - -static void -free_controlkey(controlkey_t *key, isc_mem_t *mctx) { - if (key->keyname != NULL) - isc_mem_free(mctx, key->keyname); - if (key->secret.base != NULL) - isc_mem_put(mctx, key->secret.base, key->secret.length); - isc_mem_put(mctx, key, sizeof(*key)); -} - -static void -free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) { - while (!ISC_LIST_EMPTY(*keylist)) { - controlkey_t *key = ISC_LIST_HEAD(*keylist); - ISC_LIST_UNLINK(*keylist, key, link); - free_controlkey(key, mctx); - } -} - -static void -free_listener(controllistener_t *listener) { - INSIST(listener->exiting); - INSIST(!listener->listening); - INSIST(ISC_LIST_EMPTY(listener->connections)); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - free_controlkeylist(&listener->keys, listener->mctx); - - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - - isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); -} - -static void -maybe_free_listener(controllistener_t *listener) { - if (listener->exiting && - !listener->listening && - ISC_LIST_EMPTY(listener->connections)) - free_listener(listener); -} - -static void -maybe_free_connection(controlconnection_t *conn) { - controllistener_t *listener = conn->listener; - - if (conn->buffer != NULL) - isc_buffer_free(&conn->buffer); - - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - - if (conn->ccmsg_valid) { - isccc_ccmsg_cancelread(&conn->ccmsg); - return; - } - - if (conn->sending) { - isc_socket_cancel(conn->sock, listener->task, - ISC_SOCKCANCEL_SEND); - return; - } - - ISC_LIST_UNLINK(listener->connections, conn, link); -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_rndc) { - named_fuzz_notify(); - } -#endif - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -} - -static void -shutdown_listener(controllistener_t *listener) { - controlconnection_t *conn; - controlconnection_t *next; - - if (!listener->exiting) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_UNLINK(listener->controls->listeners, listener, link); - - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "stopping command channel on %s", socktext); - if (listener->type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, true); - listener->exiting = true; - } - - for (conn = ISC_LIST_HEAD(listener->connections); - conn != NULL; - conn = next) - { - next = ISC_LIST_NEXT(conn, link); - maybe_free_connection(conn); - } - - if (listener->listening) - isc_socket_cancel(listener->sock, listener->task, - ISC_SOCKCANCEL_ACCEPT); - - maybe_free_listener(listener); -} - -static bool -address_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) { - isc_netaddr_t netaddr; - isc_result_t result; - int match; - - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = dns_acl_match(&netaddr, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS || match <= 0) - return (false); - else - return (true); -} - -static isc_result_t -control_accept(controllistener_t *listener) { - isc_result_t result; - result = isc_socket_accept(listener->sock, - listener->task, - control_newconn, listener); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - else - listener->listening = true; - return (result); -} - -static isc_result_t -control_listen(controllistener_t *listener) { - isc_result_t result; - - result = isc_socket_listen(listener->sock, 0); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_listen() failed: %s", - isc_result_totext(result)); - return (result); -} - -static void -control_next(controllistener_t *listener) { - (void)control_accept(listener); -} - -static void -control_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - controlconnection_t *conn = event->ev_arg; - controllistener_t *listener = conn->listener; - isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender; - isc_result_t result; - - REQUIRE(conn->sending); - - UNUSED(task); - - conn->sending = false; - - if (sevent->result != ISC_R_SUCCESS && - sevent->result != ISC_R_CANCELED) - { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "error sending command response to %s: %s", - socktext, isc_result_totext(sevent->result)); - } - isc_event_free(&event); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) { - isc_socket_detach(&conn->sock); - maybe_free_connection(conn); - maybe_free_listener(listener); - } -} - -static inline void -log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(ccmsg->sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_ERROR, - "invalid command from %s: %s", - socktext, isc_result_totext(result)); -} - -static void -control_recvmessage(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = NULL; - controllistener_t *listener = NULL; - ns_server_t *server = NULL; - controlkey_t *key = NULL; - isccc_sexpr_t *request = NULL; - isccc_sexpr_t *response = NULL; - uint32_t algorithm; - isccc_region_t secret; - isc_stdtime_t now; - isc_buffer_t b; - isc_region_t r; - isc_buffer_t *text; - isc_result_t result; - isc_result_t eresult; - isccc_sexpr_t *_ctrl = NULL; - isccc_time_t sent; - isccc_time_t exp; - uint32_t nonce; - isccc_sexpr_t *data = NULL; - - REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); - - conn = event->ev_arg; - listener = conn->listener; - server = listener->controls->server; - algorithm = DST_ALG_UNKNOWN; - secret.rstart = NULL; - text = NULL; - - /* Is the server shutting down? */ - if (listener->controls->shuttingdown) - goto cleanup; - - if (conn->ccmsg.result != ISC_R_SUCCESS) { - if (conn->ccmsg.result != ISC_R_CANCELED && - conn->ccmsg.result != ISC_R_EOF) - log_invalid(&conn->ccmsg, conn->ccmsg.result); - goto cleanup; - } - - request = NULL; - - for (key = ISC_LIST_HEAD(listener->keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - isccc_region_t ccregion; - - ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); - ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); - secret.rstart = isc_mem_get(listener->mctx, key->secret.length); - if (secret.rstart == NULL) - goto cleanup; - memmove(secret.rstart, key->secret.base, key->secret.length); - secret.rend = secret.rstart + key->secret.length; - algorithm = key->algorithm; - result = isccc_cc_fromwire(&ccregion, &request, - algorithm, &secret); - if (result == ISC_R_SUCCESS) - break; - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - if (result != ISCCC_R_BADAUTH) { - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - } - - if (key == NULL) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* We shouldn't be getting a reply. */ - if (isccc_cc_isreply(request)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - isc_stdtime_get(&now); - - /* - * Limit exposure to replay attacks. - */ - _ctrl = isccc_alist_lookup(request, "_ctrl"); - if (!isccc_alist_alistp(_ctrl)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { - if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { - log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); - goto cleanup_request; - } - } else { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - /* - * Expire messages that are too old. - */ - if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && - now > exp) { - log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); - goto cleanup_request; - } - - /* - * Duplicate suppression (required for UDP). - */ - LOCK(&listener->controls->symtab_lock); - isccc_cc_cleansymtab(listener->controls->symtab, now); - result = isccc_cc_checkdup(listener->controls->symtab, request, now); - UNLOCK(&listener->controls->symtab_lock); - if (result != ISC_R_SUCCESS) { - if (result == ISC_R_EXISTS) - result = ISCCC_R_DUPLICATE; - log_invalid(&conn->ccmsg, result); - goto cleanup_request; - } - - if (conn->nonce != 0 && - (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || - conn->nonce != nonce)) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup_request; - } - - result = isc_buffer_allocate(listener->mctx, &text, 2 * 2048); - if (result != ISC_R_SUCCESS) - goto cleanup_request; - - /* - * Establish nonce. - */ - if (conn->nonce == 0) { - while (conn->nonce == 0) { - uint16_t r1 = isc_rng_random(server->rngctx); - uint16_t r2 = isc_rng_random(server->rngctx); - conn->nonce = (r1 << 16) | r2; - } - eresult = ISC_R_SUCCESS; - } else - eresult = ns_control_docommand(request, listener->readonly, &text); - - result = isccc_cc_createresponse(request, now, now + 60, &response); - if (result != ISC_R_SUCCESS) - goto cleanup_request; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - if (isccc_cc_defineuint32(data, "result", eresult) == NULL) - goto cleanup_response; - } - - if (eresult != ISC_R_SUCCESS) { - if (data != NULL) { - const char *estr = isc_result_totext(eresult); - if (isccc_cc_definestring(data, "err", estr) == NULL) - goto cleanup_response; - } - } - - if (isc_buffer_usedlength(text) > 0) { - if (data != NULL) { - char *str = (char *)isc_buffer_base(text); - if (isccc_cc_definestring(data, "text", str) == NULL) - goto cleanup_response; - } - } - - _ctrl = isccc_alist_lookup(response, "_ctrl"); - if (_ctrl == NULL || - isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) - goto cleanup_response; - - if (conn->buffer == NULL) { - result = isc_buffer_allocate(listener->mctx, - &conn->buffer, 2 * 2048); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - } - - isc_buffer_clear(conn->buffer); - /* Skip the length field (4 bytes) */ - isc_buffer_add(conn->buffer, 4); - - result = isccc_cc_towire(response, &conn->buffer, algorithm, &secret); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - - isc_buffer_init(&b, conn->buffer->base, 4); - isc_buffer_putuint32(&b, conn->buffer->used - 4); - - r.base = conn->buffer->base; - r.length = conn->buffer->used; - - result = isc_socket_send(conn->sock, &r, task, control_senddone, conn); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - conn->sending = true; - - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - isccc_sexpr_free(&request); - isccc_sexpr_free(&response); - isc_buffer_free(&text); - return; - - cleanup_response: - isccc_sexpr_free(&response); - - cleanup_request: - isccc_sexpr_free(&request); - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - if (text != NULL) - isc_buffer_free(&text); - - cleanup: - isc_socket_detach(&conn->sock); - isccc_ccmsg_invalidate(&conn->ccmsg); - conn->ccmsg_valid = false; - maybe_free_connection(conn); - maybe_free_listener(listener); -} - -static void -control_timeout(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = event->ev_arg; - - UNUSED(task); - - isc_timer_detach(&conn->timer); - maybe_free_connection(conn); - - isc_event_free(&event); -} - -static isc_result_t -newconnection(controllistener_t *listener, isc_socket_t *sock) { - controlconnection_t *conn; - isc_interval_t interval; - isc_result_t result; - - conn = isc_mem_get(listener->mctx, sizeof(*conn)); - if (conn == NULL) - return (ISC_R_NOMEMORY); - - conn->sock = sock; - isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg); - - /* Set a 32 KiB upper limit on incoming message. */ - isccc_ccmsg_setmaxsize(&conn->ccmsg, 32768); - - conn->ccmsg_valid = true; - conn->sending = false; - conn->buffer = NULL; - conn->timer = NULL; - isc_interval_set(&interval, 60, 0); - result = isc_timer_create(ns_g_timermgr, isc_timertype_once, - NULL, &interval, listener->task, - control_timeout, conn, &conn->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - conn->listener = listener; - conn->nonce = 0; - ISC_LINK_INIT(conn, link); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_APPEND(listener->connections, conn, link); - return (ISC_R_SUCCESS); - - cleanup: - if (conn->buffer != NULL) - isc_buffer_free(&conn->buffer); - isccc_ccmsg_invalidate(&conn->ccmsg); - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_rndc) { - named_fuzz_notify(); - } -#endif - return (result); -} - -static void -control_newconn(isc_task_t *task, isc_event_t *event) { - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - controllistener_t *listener = event->ev_arg; - isc_socket_t *sock; - isc_sockaddr_t peeraddr; - isc_result_t result; - - UNUSED(task); - - listener->listening = false; - - if (nevent->result != ISC_R_SUCCESS) { - if (nevent->result == ISC_R_CANCELED) { - shutdown_listener(listener); - goto cleanup; - } - goto restart; - } - - sock = nevent->newsocket; - isc_socket_setname(sock, "control", NULL); - (void)isc_socket_getpeername(sock, &peeraddr); - if (listener->type == isc_sockettype_tcp && - !address_ok(&peeraddr, listener->acl)) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "rejected command channel message from %s", - socktext); - isc_socket_detach(&sock); - goto restart; - } - - result = newconnection(listener, sock); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "dropped command channel from %s: %s", - socktext, isc_result_totext(result)); - isc_socket_detach(&sock); - goto restart; - } - - restart: - control_next(listener); - cleanup: - isc_event_free(&event); -} - -static void -controls_shutdown(ns_controls_t *controls) { - controllistener_t *listener; - controllistener_t *next; - - for (listener = ISC_LIST_HEAD(controls->listeners); - listener != NULL; - listener = next) - { - /* - * This is asynchronous. As listeners shut down, they will - * call their callbacks. - */ - next = ISC_LIST_NEXT(listener, link); - shutdown_listener(listener); - } -} - -void -ns_controls_shutdown(ns_controls_t *controls) { - controls_shutdown(controls); - controls->shuttingdown = true; -} - -static isc_result_t -cfgkeylist_find(const cfg_obj_t *keylist, const char *keyname, - const cfg_obj_t **objp) -{ - const cfg_listelt_t *element; - const char *str; - const cfg_obj_t *obj; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_map_getname(obj)); - if (strcasecmp(str, keyname) == 0) - break; - } - if (element == NULL) - return (ISC_R_NOTFOUND); - obj = cfg_listelt_value(element); - *objp = obj; - return (ISC_R_SUCCESS); -} - -static isc_result_t -controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx, - controlkeylist_t *keyids) -{ - const cfg_listelt_t *element; - char *newstr = NULL; - const char *str; - const cfg_obj_t *obj; - controlkey_t *key; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - newstr = isc_mem_strdup(mctx, str); - if (newstr == NULL) - goto cleanup; - key = isc_mem_get(mctx, sizeof(*key)); - if (key == NULL) - goto cleanup; - key->keyname = newstr; - key->algorithm = DST_ALG_UNKNOWN; - key->secret.base = NULL; - key->secret.length = 0; - ISC_LINK_INIT(key, link); - ISC_LIST_APPEND(*keyids, key, link); - newstr = NULL; - } - return (ISC_R_SUCCESS); - - cleanup: - if (newstr != NULL) - isc_mem_free(mctx, newstr); - free_controlkeylist(keyids, mctx); - return (ISC_R_NOMEMORY); -} - -static void -register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist, - controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) -{ - controlkey_t *keyid, *next; - const cfg_obj_t *keydef; - char secret[1024]; - isc_buffer_t b; - isc_result_t result; - - /* - * Find the keys corresponding to the keyids used by this listener. - */ - for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) { - next = ISC_LIST_NEXT(keyid, link); - - result = cfgkeylist_find(keylist, keyid->keyname, &keydef); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't find key '%s' for use with " - "command channel %s", - keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - } else { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - unsigned int algtype; - - (void)cfg_map_get(keydef, "algorithm", &algobj); - (void)cfg_map_get(keydef, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm2(algstr, NULL, - &algtype, NULL) != ISC_R_SUCCESS) - { - cfg_obj_log(control, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel %s", - algstr, keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->algorithm = algtype; - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on " - "command channel %s: %s", - keyid->keyname, socktext, - isc_result_totext(result)); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - break; - } - memmove(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - } - } -} - -#define CHECK(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static isc_result_t -get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { - isc_result_t result; - cfg_parser_t *pctx = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *key = NULL; - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - controlkey_t *keyid = NULL; - char secret[1024]; - unsigned int algtype; - isc_buffer_t b; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_INFO, - "configuring command channel from '%s'", - ns_g_keyfile); - if (! isc_file_exists(ns_g_keyfile)) - return (ISC_R_FILENOTFOUND); - - CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); - CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); - CHECK(cfg_map_get(config, "key", &key)); - - keyid = isc_mem_get(mctx, sizeof(*keyid)); - if (keyid == NULL) - CHECK(ISC_R_NOMEMORY); - keyid->keyname = isc_mem_strdup(mctx, - cfg_obj_asstring(cfg_map_getname(key))); - keyid->secret.base = NULL; - keyid->secret.length = 0; - keyid->algorithm = DST_ALG_UNKNOWN; - ISC_LINK_INIT(keyid, link); - if (keyid->keyname == NULL) - CHECK(ISC_R_NOMEMORY); - - CHECK(bind9_check_key(key, ns_g_lctx)); - - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm2(algstr, NULL, - &algtype, NULL) != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel", - algstr, keyid->keyname); - goto cleanup; - } - - keyid->algorithm = algtype; - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on command channel: %s", - keyid->keyname, isc_result_totext(result)); - goto cleanup; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - CHECK(ISC_R_NOMEMORY); - } - memmove(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - ISC_LIST_APPEND(*keyids, keyid, link); - keyid = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (keyid != NULL) - free_controlkey(keyid, mctx); - if (config != NULL) - cfg_obj_destroy(pctx, &config); - if (pctx != NULL) - cfg_parser_destroy(&pctx); - return (result); -} - -/* - * Ensures that both '*global_keylistp' and '*control_keylistp' are - * valid or both are NULL. - */ -static void -get_key_info(const cfg_obj_t *config, const cfg_obj_t *control, - const cfg_obj_t **global_keylistp, - const cfg_obj_t **control_keylistp) -{ - isc_result_t result; - const cfg_obj_t *control_keylist = NULL; - const cfg_obj_t *global_keylist = NULL; - - REQUIRE(global_keylistp != NULL && *global_keylistp == NULL); - REQUIRE(control_keylistp != NULL && *control_keylistp == NULL); - - control_keylist = cfg_tuple_get(control, "keys"); - - if (!cfg_obj_isvoid(control_keylist) && - cfg_list_first(control_keylist) != NULL) { - result = cfg_map_get(config, "key", &global_keylist); - - if (result == ISC_R_SUCCESS) { - *global_keylistp = global_keylist; - *control_keylistp = control_keylist; - } - } -} - -static void -update_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - controlkeylist_t keys; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(cp->listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * There is already a listener for this sockaddr. - * Update the access list and key information. - * - * First try to deal with the key situation. There are a few - * possibilities: - * (a) It had an explicit keylist and still has an explicit keylist. - * (b) It had an automagic key and now has an explicit keylist. - * (c) It had an explicit keylist and now needs an automagic key. - * (d) It has an automagic key and still needs the automagic key. - * - * (c) and (d) are the annoying ones. The caller needs to know - * that it should use the automagic configuration for key information - * in place of the named.conf configuration. - * - * XXXDCL There is one other hazard that has not been dealt with, - * the problem that if a key change is being caused by a control - * channel reload, then the response will be with the new key - * and not able to be decrypted by the client. - */ - if (control != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - INSIST(global_keylist != NULL); - - ISC_LIST_INIT(keys); - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, &keys); - if (result == ISC_R_SUCCESS) { - free_controlkeylist(&listener->keys, listener->mctx); - listener->keys = keys; - register_keys(control, global_keylist, &listener->keys, - listener->mctx, socktext); - } - } else { - free_controlkeylist(&listener->keys, listener->mctx); - result = get_rndckey(listener->mctx, &listener->keys); - } - - if (result != ISC_R_SUCCESS && global_keylist != NULL) { - /* - * This message might be a little misleading since the - * "new keys" might in fact be identical to the old ones, - * but tracking whether they are identical just for the - * sake of avoiding this message would be too much trouble. - */ - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - /* - * Now, keep the old access list unless a new one can be made. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else { - result = dns_acl_any(listener->mctx, &new_acl); - } - - if (control != NULL) { - const cfg_obj_t *readonly; - - readonly = cfg_tuple_get(control, "read-only"); - if (!cfg_obj_isvoid(readonly)) - listener->readonly = cfg_obj_asboolean(readonly); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - /* XXXDCL say the old acl is still used? */ - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - uint32_t perm, owner, group; - perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); - owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); - group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); - result = ISC_R_SUCCESS; - if (listener->perm != perm || listener->owner != owner || - listener->group != group) - result = isc_socket_permunix(&listener->address, perm, - owner, group); - if (result == ISC_R_SUCCESS) { - listener->perm = perm; - listener->owner = owner; - listener->group = group; - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't update ownership/permission for " - "command channel %s", socktext); - } - - *listenerp = listener; -} - -static void -add_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - isc_mem_t *mctx = cp->server->mctx; - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - listener = isc_mem_get(mctx, sizeof(*listener)); - if (listener == NULL) - result = ISC_R_NOMEMORY; - - if (result == ISC_R_SUCCESS) { - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - listener->controls = cp; - listener->task = cp->server->task; - listener->address = *addr; - listener->sock = NULL; - listener->listening = false; - listener->exiting = false; - listener->acl = NULL; - listener->type = type; - listener->perm = 0; - listener->owner = 0; - listener->group = 0; - listener->readonly = false; - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->keys); - ISC_LIST_INIT(listener->connections); - - /* - * Make the acl. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, mctx, 0, - &new_acl); - } else { - result = dns_acl_any(mctx, &new_acl); - } - } - - if ((result == ISC_R_SUCCESS) && (control != NULL)) { - const cfg_obj_t *readonly; - - readonly = cfg_tuple_get(control, "read-only"); - if (!cfg_obj_isvoid(readonly)) - listener->readonly = cfg_obj_asboolean(readonly); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - if (config != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, - &listener->keys); - if (result == ISC_R_SUCCESS) - register_keys(control, global_keylist, - &listener->keys, - listener->mctx, socktext); - } else - result = get_rndckey(mctx, &listener->keys); - - if (result != ISC_R_SUCCESS && control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - if (result == ISC_R_SUCCESS) { - int pf = isc_sockaddr_pf(&listener->address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || -#ifdef ISC_PLATFORM_HAVESYSUNH - (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) || -#endif - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - result = ISC_R_FAMILYNOSUPPORT; - } - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, false); - - if (result == ISC_R_SUCCESS) - result = isc_socket_create(ns_g_socketmgr, - isc_sockaddr_pf(&listener->address), - type, &listener->sock); - if (result == ISC_R_SUCCESS) - isc_socket_setname(listener->sock, "control", NULL); - -#ifndef ISC_ALLOW_MAPPED - if (result == ISC_R_SUCCESS) - isc_socket_ipv6only(listener->sock, true); -#endif - - if (result == ISC_R_SUCCESS) - result = isc_socket_bind(listener->sock, &listener->address, - ISC_SOCKET_REUSEADDRESS); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, - "perm")); - listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, - "owner")); - listener->group = cfg_obj_asuint32(cfg_tuple_get(control, - "group")); - result = isc_socket_permunix(&listener->address, listener->perm, - listener->owner, listener->group); - } - if (result == ISC_R_SUCCESS) - result = control_listen(listener); - - if (result == ISC_R_SUCCESS) - result = control_accept(listener); - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "command channel listening on %s", socktext); - *listenerp = listener; - - } else { - if (listener != NULL) { - listener->exiting = true; - free_listener(listener); - } - - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - - *listenerp = NULL; - } - - /* XXXDCL return error results? fail hard? */ -} - -isc_result_t -ns_controls_configure(ns_controls_t *cp, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx) -{ - controllistener_t *listener; - controllistenerlist_t new_listeners; - const cfg_obj_t *controlslist = NULL; - const cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'controls' statements. - */ - (void)cfg_map_get(config, "controls", &controlslist); - - /* - * Run through the new control channel list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (controlslist != NULL) { - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *inetcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "inet", &inetcontrols); - if (inetcontrols == NULL) - continue; - - for (element2 = cfg_list_first(inetcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *obj; - isc_sockaddr_t addr; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - obj = cfg_tuple_get(control, "address"); - addr = *cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, - NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel %s", - socktext); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *unixcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "unix", &unixcontrols); - if (unixcontrols == NULL) - continue; - - for (element2 = cfg_list_first(unixcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *path; - isc_sockaddr_t addr; - isc_result_t result; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - path = cfg_tuple_get(control, "path"); - result = isc_sockaddr_frompath(&addr, - cfg_obj_asstring(path)); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "control channel '%s': %s", - cfg_obj_asstring(path), - isc_result_totext(result)); - continue; - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel '%s'", - cfg_obj_asstring(path)); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - } else { - int i; - - for (i = 0; i < 2; i++) { - isc_sockaddr_t addr; - - if (i == 0) { - struct in_addr localhost; - - if (isc_net_probeipv4() != ISC_R_SUCCESS) - continue; - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&addr, &localhost, 0); - } else { - if (isc_net_probeipv6() != ISC_R_SUCCESS) - continue; - isc_sockaddr_fromin6(&addr, - &in6addr_loopback, 0); - } - isc_sockaddr_setport(&addr, NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - - update_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - - /* - * ns_control_shutdown() will stop whatever is on the global - * listeners list, which currently only has whatever sockaddrs - * were in the previous configuration (if any) that do not - * remain in the current configuration. - */ - controls_shutdown(cp); - - /* - * Put all of the valid listeners on the listeners list. - * Anything already on listeners in the process of shutting - * down will be taken care of by listen_done(). - */ - ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { - isc_mem_t *mctx = server->mctx; - isc_result_t result; - ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); - - if (controls == NULL) { - return (ISC_R_NOMEMORY); - } - - *controls = (ns_controls_t){ - .server = server, - }; - - ISC_LIST_INIT(controls->listeners); - - result = isc_mutex_init(&controls->symtab_lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - - LOCK(&controls->symtab_lock); - result = isccc_cc_createsymtab(&controls->symtab); - UNLOCK(&controls->symtab_lock); - - if (result != ISC_R_SUCCESS) { - isc_mutex_destroy(&controls->symtab_lock); - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - *ctrlsp = controls; - return (ISC_R_SUCCESS); -} - -void -ns_controls_destroy(ns_controls_t **ctrlsp) { - ns_controls_t *controls = *ctrlsp; - - REQUIRE(ISC_LIST_EMPTY(controls->listeners)); - - LOCK(&controls->symtab_lock); - isccc_symtab_destroy(&controls->symtab); - UNLOCK(&controls->symtab_lock); - isc_mutex_destroy(&controls->symtab_lock); - isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); - *ctrlsp = NULL; -} diff --git a/bin/named-pkcs11/convertxsl.pl b/bin/named-pkcs11/convertxsl.pl deleted file mode 100755 index 092bc01..0000000 --- a/bin/named-pkcs11/convertxsl.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -use strict; -use warnings; - -my $rev = '$Id: convertxsl.pl,v 1.14 2008/07/17 23:43:26 jinmei Exp $'; -$rev =~ s/\$//g; -$rev =~ s/,v//g; -$rev =~ s/Id: //; - -my $xsl = "unknown"; -my $lines = ''; - -while (<>) { - chomp; - # pickout the id for comment. - $xsl = $_ if (//); - # convert Id string to a form not recognisable by cvs. - $_ =~ s///; - s/[\ \t]+/ /g; - s/\>\ \\.*//; -$xsl =~ s/,v//; - -print "/*\n * Generated by $rev \n * From $xsl\n */\n"; -print 'static char xslmsg[] =',"\n"; -print $lines; - -print ';', "\n"; diff --git a/bin/named-pkcs11/fuzz.c b/bin/named-pkcs11/fuzz.c deleted file mode 100644 index 0d6165f..0000000 --- a/bin/named-pkcs11/fuzz.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include "config.h" - -#include -#include - -#include - -#ifdef ENABLE_AFL -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifndef __AFL_LOOP -#error To use American Fuzzy Lop you have to set CC to afl-clang-fast!!! -#endif - -/* - * We are using pthreads directly because we might be using it with unthreaded - * version of BIND, where all thread functions are mocks. Since AFL for now only - * works on Linux it's not a problem. - */ -static pthread_cond_t cond; -static pthread_mutex_t mutex; -static bool ready; - - -static void * -fuzz_main_client(void *arg) { - char *host; - char *port; - struct sockaddr_in servaddr; - int sockfd; - int loop; - void *buf; - - UNUSED(arg); - - /* - * Parse named -A argument in the "address:port" syntax. Due to - * the syntax used, this only supports IPv4 addresses. - */ - - host = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(host != NULL); - port = strchr(host, ':'); - RUNTIME_CHECK(port != NULL); - *port = 0; - ++port; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, host, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(port)); - - free(host); - - /* Wait for named to start. */ - while (!ns_g_run_done) { - usleep(10000); - } - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(sockfd != -1); - - buf = malloc(65536); - RUNTIME_CHECK(buf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - - length = read(0, buf, 65536); - if (length <= 0) { - usleep(1000000); - continue; - } - - if (length > 4096) { - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, - false); - isc_app_shutdown(); - return (NULL); - } - raise(SIGSTOP); - continue; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - - sent = sendto(sockfd, buf, length, 0, - (struct sockaddr *) &servaddr, sizeof(servaddr)); - RUNTIME_CHECK(sent == length); - - /* unclog */ - recvfrom(sockfd, buf, 65536, MSG_DONTWAIT, NULL, NULL); - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == ISC_R_SUCCESS); - } - - free(buf); - close(sockfd); - - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - return (NULL); -} - -static void * -fuzz_main_resolver(void *arg) { - char *shost, *sport, *rhost, *rport; - /* Query for A? aaaaaaaaaa.example. */ - char respacket[] = - "\0\0\1 \0\1\0\0\0\0\0\0\naaaaaaaaaa\7example\0\0\1\0\1"; - struct sockaddr_in servaddr, recaddr, recvaddr; - int sockfd; - int listenfd; - int loop; - char *buf, *rbuf; - - UNUSED(arg); - - /* - * Parse named -A argument in the "laddress:sport:raddress:rport" - * syntax. Due to the syntax used, this only supports IPv4 addresses. - */ - - shost = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(shost != NULL); - sport = strchr(shost, ':'); - RUNTIME_CHECK(sport != NULL); - *sport = 0; - sport++; - rhost = strchr(sport, ':'); - RUNTIME_CHECK(rhost != NULL); - *rhost = 0; - rhost++; - rport = strchr(rhost, ':'); - RUNTIME_CHECK(rport != NULL); - *rport = 0; - rport++; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, shost, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(sport)); - - memset(&recaddr, 0, sizeof (recaddr)); - recaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, rhost, &recaddr.sin_addr) == 1); - recaddr.sin_port = htons(atoi(rport)); - - free(shost); - - /* Wait for named to start */ - while (!ns_g_run_done) { - usleep(10000); - } - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(sockfd != -1); - - listenfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(listenfd != -1); - RUNTIME_CHECK(bind(listenfd, (struct sockaddr *)&recaddr, - sizeof(struct sockaddr_in)) == 0); - - buf = malloc(65536); - rbuf = malloc(65536); - RUNTIME_CHECK(buf != NULL); - RUNTIME_CHECK(rbuf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - memset(buf, 0, 16); - length = read(0, buf, 65536); - if (length <= 0) { - usleep(1000000); - continue; - } - - if (length > 4096) { - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, - false); - isc_app_shutdown(); - return (NULL); - } - raise(SIGSTOP); - continue; - } - - if (length < 16) { - length = 16; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - /* Randomize query ID. */ - int id = random(); - respacket[0] = id >> 8; - respacket[1] = id & 0xff; - - /* flush */ - socklen_t socklen = sizeof(recvaddr); - sent = recvfrom(listenfd, rbuf, 65536, MSG_DONTWAIT, - (struct sockaddr *) &recvaddr, &socklen); - - sent = sendto(sockfd, respacket, sizeof(respacket), 0, - (struct sockaddr *) &servaddr, sizeof(servaddr)); - RUNTIME_CHECK(sent == sizeof(respacket)); - - socklen = sizeof(recvaddr); - sent = recvfrom(listenfd, rbuf, 65536, 0, - (struct sockaddr *) &recvaddr, &socklen); - RUNTIME_CHECK(sent > 0); - - /* Copy QID and set QR so that response is always processed. */ - buf[0] = rbuf[0]; - buf[1] = rbuf[1]; - buf[2] |= 0x80; - - sent = sendto(listenfd, buf, length, 0, - (struct sockaddr *) &recvaddr, sizeof(recvaddr)); - RUNTIME_CHECK(sent == length); - - /* We might get additional questions here (e.g. for CNAME). */ - for (;;) { - fd_set fds; - struct timeval tv; - int rv; - int max; - - FD_ZERO(&fds); - FD_SET(listenfd, &fds); - FD_SET(sockfd, &fds); - tv.tv_sec = 10; - tv.tv_usec = 0; - max = (listenfd > sockfd ? listenfd : sockfd)+1; - - rv = select(max, &fds, NULL, NULL, &tv); - RUNTIME_CHECK(rv > 0); - - if (FD_ISSET(sockfd, &fds)) { - /* It's the reply, we're done. */ - recvfrom(sockfd, buf, 65536, 0, NULL, NULL); - break; - } - - /* - * We've got additional question (eg. cname chain) - * We are bouncing it - setting QR flag and NOERROR - * rcode and sending it back. - */ - - length = recvfrom(listenfd, buf, 65536, 0, - (struct sockaddr *) &recvaddr, &socklen); - buf[2] |= 0x80; - buf[3] &= 0xF0; - sent = sendto(listenfd, buf, length, 0, - (struct sockaddr *) &recvaddr, - sizeof(recvaddr)); - RUNTIME_CHECK(sent == length); - } - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == 0); - } - - free(buf); - free(rbuf); - close(sockfd); - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - /* - * It's here just for the signature, that's how AFL detects if it's - * a 'persistent mode' binary. - */ - __AFL_LOOP(0); - - return (NULL); -} - -static void * -fuzz_main_tcp(void *arg) { - char *host; - char *port; - struct sockaddr_in servaddr; - int sockfd; - char *buf; - int loop; - - UNUSED(arg); - - /* - * Parse named -A argument in the "address:port" syntax. Due to - * the syntax used, this only supports IPv4 addresses. - */ - - host = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(host != NULL); - port = strchr(host, ':'); - RUNTIME_CHECK(port != NULL); - *port = 0; - ++port; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, host, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(port)); - - free(host); - - /* Wait for named to start */ - while (!ns_g_run_done) { - usleep(10000); - } - - buf = malloc(65539); - RUNTIME_CHECK(buf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - - if (ns_g_fuzz_type == ns_fuzz_tcpclient) { - /* - * To fuzz TCP client we have to put length at - * the start of packet. - */ - length = read(0, buf+2, 65535); - buf[0] = length >> 8; - buf[1] = length & 0xff; - length += 2; - } else { - length = read(0, buf, 65535); - } - if (length <= 0) { - usleep(1000000); - continue; - } - if (ns_g_fuzz_type == ns_fuzz_http) { - /* - * This guarantees that the request will be processed. - */ - buf[length++]='\r'; - buf[length++]='\n'; - buf[length++]='\r'; - buf[length++]='\n'; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - int yes = 1; - int r; - sockfd = socket(AF_INET, SOCK_STREAM, 0); - - RUNTIME_CHECK(sockfd != -1); - RUNTIME_CHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - &yes, sizeof(int)) == 0); - - do { - r = connect(sockfd, (struct sockaddr*)&servaddr, - sizeof(servaddr)); - } while (r != 0); - - sent = write(sockfd, buf, length); - RUNTIME_CHECK(sent == length); - close(sockfd); - - /* unclog */ - recvfrom(sockfd, buf, 65537, MSG_DONTWAIT, NULL, NULL); - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == ISC_R_SUCCESS); - } - - free(buf); - close(sockfd); - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - return (NULL); -} - -#endif /* ENABLE_AFL */ - -void -named_fuzz_notify(void) { -#ifdef ENABLE_AFL - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - return; - } - - raise(SIGSTOP); - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == 0); - - ready = true; - - RUNTIME_CHECK(pthread_cond_signal(&cond) == 0); - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == 0); -#endif /* ENABLE_AFL */ -} - -void -named_fuzz_setup(void) { -#ifdef ENABLE_AFL - if (getenv("__AFL_PERSISTENT") || getenv("AFL_CMIN")) { - pthread_t thread; - void *(fn) = NULL; - - switch (ns_g_fuzz_type) { - case ns_fuzz_client: - fn = fuzz_main_client; - break; - - case ns_fuzz_http: - case ns_fuzz_tcpclient: - case ns_fuzz_rndc: - fn = fuzz_main_tcp; - break; - case ns_fuzz_resolver: - fn = fuzz_main_resolver; - break; - default: - RUNTIME_CHECK(fn != NULL); - } - - RUNTIME_CHECK(pthread_mutex_init(&mutex, NULL) == 0); - RUNTIME_CHECK(pthread_cond_init(&cond, NULL) == 0); - RUNTIME_CHECK(pthread_create(&thread, NULL, fn, NULL) == 0); - } -#endif /* ENABLE_AFL */ -} diff --git a/bin/named-pkcs11/geoip.c b/bin/named-pkcs11/geoip.c deleted file mode 100644 index 02db0de..0000000 --- a/bin/named-pkcs11/geoip.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#if defined(HAVE_GEOIP2) -#include -#elif defined(HAVE_GEOIP) -#include -#include -#endif - -#include -#include -#include - -#include - -#include -#include - -static dns_geoip_databases_t geoip_table; - -#if defined(HAVE_GEOIP) -static void -init_geoip_db(void **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, - GeoIPOptions method, const char *name) -{ - char *info; - GeoIP *db; - - REQUIRE(dbp != NULL); - - db = (GeoIP *)*dbp; - - if (db != NULL) { - GeoIP_delete(db); - db = *dbp = NULL; - } - - if (! GeoIP_db_avail(edition)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "GeoIP %s (type %d) DB not available", name, edition); - goto fail; - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "initializing GeoIP %s (type %d) DB", name, edition); - - db = GeoIP_open_type(edition, method); - if (db == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to initialize GeoIP %s (type %d) DB%s", - name, edition, fallback == 0 - ? "geoip matches using this database will fail" : ""); - goto fail; - } - - info = GeoIP_database_info(db); - if (info != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s", info); - free(info); - } - - *dbp = db; - return; - - fail: - if (fallback != 0) { - init_geoip_db(dbp, fallback, 0, method, name); - } - -} -#elif defined(HAVE_GEOIP2) -static MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain; - -static MMDB_s * -open_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) { - char pathbuf[PATH_MAX]; - unsigned int n; - int ret; - - n = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile); - if (n >= sizeof(pathbuf)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "GeoIP2 database '%s/%s': path too long", - dir, dbfile); - return (NULL); - } - - ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb); - if (ret == MMDB_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "opened GeoIP2 database '%s'", pathbuf); - return (mmdb); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "unable to open GeoIP2 database '%s' (status %d)", - pathbuf, ret); - - return (NULL); -} -#endif /* HAVE_GEOIP2 */ - - -void -ns_geoip_init(void) { -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - if (ns_g_geoip == NULL) { - ns_g_geoip = &geoip_table; - } -#if defined(HAVE_GEOIP) - GeoIP_cleanup(); -#endif -#else - return; -#endif -} - -void -ns_geoip_load(char *dir) { -#if defined(HAVE_GEOIP2) - REQUIRE(dir != NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "looking for GeoIP2 databases in '%s'", dir); - - ns_g_geoip->country = open_geoip2(dir, "GeoIP2-Country.mmdb", - &geoip_country); - if (ns_g_geoip->country == NULL) { - ns_g_geoip->country = open_geoip2(dir, - "GeoLite2-Country.mmdb", - &geoip_country); - } - - ns_g_geoip->city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city); - if (ns_g_geoip->city == NULL) { - ns_g_geoip->city = open_geoip2(dir, "GeoLite2-City.mmdb", - &geoip_city); - } - - ns_g_geoip->as = open_geoip2(dir, "GeoIP2-ASN.mmdb", &geoip_as); - if (ns_g_geoip->as == NULL) { - ns_g_geoip->as = open_geoip2(dir, "GeoLite2-ASN.mmdb", - &geoip_as); - } - - ns_g_geoip->isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp); - ns_g_geoip->domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", - &geoip_domain); -#elif defined(HAVE_GEOIP) - GeoIPOptions method; - -#ifdef _WIN32 - method = GEOIP_STANDARD; -#else - method = GEOIP_MMAP_CACHE; -#endif - - ns_geoip_init(); - if (dir != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using \"%s\" as GeoIP directory", dir); - GeoIP_setup_custom_directory(dir); - } - - init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION, 0, - method, "Country (IPv4)"); -#ifdef HAVE_GEOIP_V6 - init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6, 0, - method, "Country (IPv6)"); -#endif - - init_geoip_db(&ns_g_geoip->city_v4, GEOIP_CITY_EDITION_REV1, - GEOIP_CITY_EDITION_REV0, method, "City (IPv4)"); -#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6) - init_geoip_db(&ns_g_geoip->city_v6, GEOIP_CITY_EDITION_REV1_V6, - GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)"); -#endif - - init_geoip_db(&ns_g_geoip->region, GEOIP_REGION_EDITION_REV1, - GEOIP_REGION_EDITION_REV0, method, "Region"); - - init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION, 0, - method, "ISP"); - init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION, 0, - method, "Org"); - init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION, 0, - method, "AS"); - init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION, 0, - method, "Domain"); - init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION, 0, - method, "NetSpeed"); -#else - UNUSED(dir); - - return; -#endif -} - -void -ns_geoip_shutdown(void) { -#ifdef HAVE_GEOIP2 - if (ns_g_geoip->country != NULL) { - MMDB_close(ns_g_geoip->country); - ns_g_geoip->country = NULL; - } - if (ns_g_geoip->city != NULL) { - MMDB_close(ns_g_geoip->city); - ns_g_geoip->city = NULL; - } - if (ns_g_geoip->as != NULL) { - MMDB_close(ns_g_geoip->as); - ns_g_geoip->as = NULL; - } - if (ns_g_geoip->isp != NULL) { - MMDB_close(ns_g_geoip->isp); - ns_g_geoip->isp = NULL; - } - if (ns_g_geoip->domain != NULL) { - MMDB_close(ns_g_geoip->domain); - ns_g_geoip->domain = NULL; - } -#endif /* HAVE_GEOIP2 */ -} diff --git a/bin/named-pkcs11/include/dlz/dlz_dlopen_driver.h b/bin/named-pkcs11/include/dlz/dlz_dlopen_driver.h deleted file mode 100644 index 8dcc4b4..0000000 --- a/bin/named-pkcs11/include/dlz/dlz_dlopen_driver.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DLZ_DLOPEN_DRIVER_H -#define DLZ_DLOPEN_DRIVER_H - -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx); - -void -dlz_dlopen_clear(void); -#endif diff --git a/bin/named-pkcs11/include/named/builtin.h b/bin/named-pkcs11/include/named/builtin.h deleted file mode 100644 index 240132f..0000000 --- a/bin/named-pkcs11/include/named/builtin.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_BUILTIN_H -#define NAMED_BUILTIN_H 1 - -/*! \file */ - -#include - -isc_result_t ns_builtin_init(void); - -void ns_builtin_deinit(void); - -#endif /* NAMED_BUILTIN_H */ diff --git a/bin/named-pkcs11/include/named/client.h b/bin/named-pkcs11/include/named/client.h deleted file mode 100644 index 09839bc..0000000 --- a/bin/named-pkcs11/include/named/client.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_CLIENT_H -#define NAMED_CLIENT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * This module defines two objects, ns_client_t and ns_clientmgr_t. - * - * An ns_client_t object handles incoming DNS requests from clients - * on a given network interface. - * - * Each ns_client_t object can handle only one TCP connection or UDP - * request at a time. Therefore, several ns_client_t objects are - * typically created to serve each network interface, e.g., one - * for handling TCP requests and a few (one per CPU) for handling - * UDP requests. - * - * Incoming requests are classified as queries, zone transfer - * requests, update requests, notify requests, etc, and handed off - * to the appropriate request handler. When the request has been - * fully handled (which can be much later), the ns_client_t must be - * notified of this by calling one of the following functions - * exactly once in the context of its task: - * \code - * ns_client_send() (sending a non-error response) - * ns_client_sendraw() (sending a raw response) - * ns_client_error() (sending an error response) - * ns_client_next() (sending no response) - *\endcode - * This will release any resources used by the request and - * and allow the ns_client_t to listen for the next request. - * - * A ns_clientmgr_t manages a number of ns_client_t objects. - * New ns_client_t objects are created by calling - * ns_clientmgr_createclients(). They are destroyed by - * destroying their manager. - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*** - *** Types - ***/ - -/*% reference-counted TCP connection object */ -typedef struct ns_tcpconn { - isc_refcount_t clients; /* Number of clients using - * this connection. Conn can - * be freed if goes to 0 - */ - isc_quota_t *tcpquota; - bool pipelined; -} ns_tcpconn_t; - -/*% nameserver client structure */ -struct ns_client { - unsigned int magic; - isc_mem_t * mctx; - ns_clientmgr_t * manager; - int state; - int newstate; - int naccepts; - int nreads; - int nsends; - int nrecvs; - int nupdates; - int nctls; - int references; - bool tcpactive; - bool needshutdown; /* - * Used by clienttest to get - * the client to go from - * inactive to free state - * by shutting down the - * client's task. - */ - unsigned int attributes; - isc_task_t * task; - dns_view_t * view; - dns_dispatch_t * dispatch; - isc_socket_t * udpsocket; - isc_socket_t * tcplistener; - isc_socket_t * tcpsocket; - unsigned char * tcpbuf; - dns_tcpmsg_t tcpmsg; - bool tcpmsg_valid; - isc_timer_t * timer; - isc_timer_t * delaytimer; - bool timerset; - dns_message_t * message; - isc_socketevent_t * sendevent; - isc_socketevent_t * recvevent; - unsigned char * recvbuf; - dns_rdataset_t * opt; - uint16_t udpsize; - uint16_t extflags; - int16_t ednsversion; /* -1 noedns */ - void (*next)(ns_client_t *); - void (*shutdown)(void *arg, isc_result_t result); - void *shutdown_arg; - ns_query_t query; - isc_time_t requesttime; - isc_stdtime_t now; - isc_time_t tnow; - dns_name_t signername; /*%< [T]SIG key name */ - dns_name_t *signer; /*%< NULL if not valid sig */ - bool mortal; /*%< Die after handling request */ - ns_tcpconn_t *tcpconn; - isc_quota_t *recursionquota; - ns_interface_t *interface; - - isc_sockaddr_t peeraddr; - bool peeraddr_valid; - isc_netaddr_t destaddr; - isc_sockaddr_t destsockaddr; - - isc_netaddr_t ecs_addr; /*%< EDNS client subnet */ - uint8_t ecs_addrlen; - uint8_t ecs_scope; - - struct in6_pktinfo pktinfo; - isc_dscp_t dscp; - isc_event_t ctlevent; -#ifdef ALLOW_FILTER_AAAA - dns_aaaa_t filter_aaaa; -#endif - /*% - * Information about recent FORMERR response(s), for - * FORMERR loop avoidance. This is separate for each - * client object rather than global only to avoid - * the need for locking. - */ - struct { - isc_sockaddr_t addr; - isc_stdtime_t time; - dns_messageid_t id; - } formerrcache; - - ISC_LINK(ns_client_t) link; - ISC_LINK(ns_client_t) rlink; - ISC_QLINK(ns_client_t) ilink; - unsigned char cookie[8]; - uint32_t expire; - unsigned char *keytag; - uint16_t keytag_len; -}; - -typedef ISC_QUEUE(ns_client_t) client_queue_t; -typedef ISC_LIST(ns_client_t) client_list_t; - -#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') -#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) - -#define NS_CLIENTATTR_TCP 0x0001 -#define NS_CLIENTATTR_RA 0x0002 /*%< Client gets recursive service */ -#define NS_CLIENTATTR_PKTINFO 0x0004 /*%< pktinfo is valid */ -#define NS_CLIENTATTR_MULTICAST 0x0008 /*%< recv'd from multicast */ -#define NS_CLIENTATTR_WANTDNSSEC 0x0010 /*%< include dnssec records */ -#define NS_CLIENTATTR_WANTNSID 0x0020 /*%< include nameserver ID */ -#ifdef ALLOW_FILTER_AAAA -#define NS_CLIENTATTR_FILTER_AAAA 0x0040 /*%< suppress AAAAs */ -#define NS_CLIENTATTR_FILTER_AAAA_RC 0x0080 /*%< recursing for A against AAAA */ -#endif -#define NS_CLIENTATTR_WANTAD 0x0100 /*%< want AD in response if possible */ -#define NS_CLIENTATTR_WANTCOOKIE 0x0200 /*%< return a COOKIE */ -#define NS_CLIENTATTR_HAVECOOKIE 0x0400 /*%< has a valid COOKIE */ -#define NS_CLIENTATTR_WANTEXPIRE 0x0800 /*%< return seconds to expire */ -#define NS_CLIENTATTR_HAVEEXPIRE 0x1000 /*%< return seconds to expire */ -#define NS_CLIENTATTR_WANTOPT 0x2000 /*%< add opt to reply */ -#define NS_CLIENTATTR_HAVEECS 0x4000 /*%< received an ECS option */ - -#define NS_CLIENTATTR_NOSETFC 0x8000 /*%< don't set servfail cache */ - -/* - * Flag to use with the SERVFAIL cache to indicate - * that a query had the CD bit set. - */ -#define NS_FAILCACHE_CD 0x01 - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#define ncr_inc(x) atomic_fetch_add(&(x), (1)) -#define ncr_load(x) atomic_load(&(x)) -#define NS_CLIENT_NCRSTDATOMIC 1 -extern _Atomic(unsigned int) ns_client_requests; -#elif defined(ISC_PLATFORM_HAVEXADD) -#define ncr_inc(x) isc_atomic_xadd((int *)&(x), 1); -#define ncr_load(x) isc_atomic_xadd((int *)&(x), 0); -extern unsigned int ns_client_requests; -#else -#define ncr_inc(x) ((x)++) -#define ncr_load(x) (x) -extern unsigned int ns_client_requests; -#endif - -/*** - *** Functions - ***/ - -/*% - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_send(ns_client_t *client); -/*% - * Finish processing the current client request and - * send client->message as a response. - * \brief - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *msg); -/*% - * Finish processing the current client request and - * send msg as a response using client->message->id for the id. - */ - -void -ns_client_error(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request and return - * an error response to the client. The error response - * will have an RCODE determined by 'result'. - */ - -void -ns_client_next(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request, - * return no response to the client. - */ - -bool -ns_client_shuttingdown(ns_client_t *client); -/*% - * Return true iff the client is currently shutting down. - */ - -void -ns_client_attach(ns_client_t *source, ns_client_t **target); -/*% - * Attach '*targetp' to 'source'. - */ - -void -ns_client_detach(ns_client_t **clientp); -/*% - * Detach '*clientp' from its client. - */ - -isc_result_t -ns_client_replace(ns_client_t *client); -/*% - * Try to replace the current client with a new one, so that the - * current one can go off and do some lengthy work without - * leaving the dispatch/socket without service. - */ - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds); -/*% - * Set a timer in the client to go off in the specified amount of time. - */ - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); -/*% - * Create a client manager. - */ - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp); -/*% - * Destroy a client manager and all ns_client_t objects - * managed by it. - */ - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, bool tcp); -/*% - * Create up to 'n' clients listening on interface 'ifp'. - * If 'tcp' is true, the clients will listen for TCP connections, - * otherwise for UDP requests. - */ - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client); -/*% - * Get the socket address of the client whose request is - * currently being processed. - */ - -isc_sockaddr_t * -ns_client_getdestaddr(ns_client_t *client); -/*%< - * Get the destination address (server) for the request that is - * currently being processed. - */ - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, - dns_acl_t *acl, bool default_allow); - -/*% - * Convenience function for client request ACL checking. - * - * Check the current client request against 'acl'. If 'acl' - * is NULL, allow the request iff 'default_allow' is true. - * If netaddr is NULL, check the ACL against client->peeraddr; - * otherwise check it against netaddr. - * - * Notes: - *\li This is appropriate for checking allow-update, - * allow-query, allow-transfer, etc. It is not appropriate - * for checking the blackhole list because we treat positive - * matches as "allow" and negative matches as "deny"; in - * the case of the blackhole list this would be backwards. - * - * Requires: - *\li 'client' points to a valid client. - *\li 'netaddr' points to a valid address, or is NULL. - *\li 'acl' points to a valid ACL, or is NULL. - * - * Returns: - *\li ISC_R_SUCCESS if the request should be allowed - * \li DNS_R_REFUSED if the request should be denied - *\li No other return values are possible. - */ - -isc_result_t -ns_client_checkacl(ns_client_t *client, - isc_sockaddr_t *sockaddr, - const char *opname, dns_acl_t *acl, - bool default_allow, - int log_level); -/*% - * Like ns_client_checkaclsilent, except the outcome of the check is - * logged at log level 'log_level' if denied, and at debug 3 if approved. - * Log messages will refer to the request as an 'opname' request. - * - * Requires: - *\li 'client' points to a valid client. - *\li 'sockaddr' points to a valid address, or is NULL. - *\li 'acl' points to a valid ACL, or is NULL. - *\li 'opname' points to a null-terminated string. - */ - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len); - -#define NS_CLIENT_ACLMSGSIZE(x) \ - (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ - DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) - -void -ns_client_recursing(ns_client_t *client); -/*% - * Add client to end of th recursing list. - */ - -void -ns_client_killoldestquery(ns_client_t *client); -/*% - * Kill the oldest recursive query (recursing list head). - */ - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); -/*% - * Dump the outstanding recursive queries to 'f'. - */ - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); -/*% - * Replace the qname. - */ - -bool -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - dns_rdataclass_t rdclass, void *arg); -/*% - * Isself callback. - */ - -isc_result_t -ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); - -isc_result_t -ns_client_addopt(ns_client_t *client, dns_message_t *message, - dns_rdataset_t **opt); - -#endif /* NAMED_CLIENT_H */ diff --git a/bin/named-pkcs11/include/named/config.h b/bin/named-pkcs11/include/named/config.h deleted file mode 100644 index 656336b..0000000 --- a/bin/named-pkcs11/include/named/config.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NAMED_CONFIG_H -#define NAMED_CONFIG_H 1 - -/*! \file */ - -#include - -#include - -#include -#include - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); - -isc_result_t -ns_config_get(cfg_obj_t const * const *maps, const char *name, - const cfg_obj_t **obj); - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char *name, - const cfg_obj_t **obj); - -int -ns_config_listcount(const cfg_obj_t *list); - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp); - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep); - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj); - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, - uint32_t *countp); - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_dscp_t **dscpsp, uint32_t count); - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, dns_ipkeylist_t *ipkl); - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp); - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - uint16_t *digestbits); -isc_result_t -ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, - unsigned int *typep, uint16_t *digestbits); - -isc_result_t -ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp); - -#endif /* NAMED_CONFIG_H */ diff --git a/bin/named-pkcs11/include/named/control.h b/bin/named-pkcs11/include/named/control.h deleted file mode 100644 index 37403f1..0000000 --- a/bin/named-pkcs11/include/named/control.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_CONTROL_H -#define NAMED_CONTROL_H 1 - -/*! \file - * \brief - * The name server command channel. - */ - -#include -#include - -#include - -#include - -#define NS_CONTROL_PORT 953 - -#define NS_COMMAND_STOP "stop" -#define NS_COMMAND_HALT "halt" -#define NS_COMMAND_RELOAD "reload" -#define NS_COMMAND_RECONFIG "reconfig" -#define NS_COMMAND_REFRESH "refresh" -#define NS_COMMAND_RETRANSFER "retransfer" -#define NS_COMMAND_DUMPSTATS "stats" -#define NS_COMMAND_QUERYLOG "querylog" -#define NS_COMMAND_DUMPDB "dumpdb" -#define NS_COMMAND_SECROOTS "secroots" -#define NS_COMMAND_TRACE "trace" -#define NS_COMMAND_NOTRACE "notrace" -#define NS_COMMAND_FLUSH "flush" -#define NS_COMMAND_FLUSHNAME "flushname" -#define NS_COMMAND_FLUSHTREE "flushtree" -#define NS_COMMAND_STATUS "status" -#define NS_COMMAND_TSIGLIST "tsig-list" -#define NS_COMMAND_TSIGDELETE "tsig-delete" -#define NS_COMMAND_FREEZE "freeze" -#define NS_COMMAND_UNFREEZE "unfreeze" -#define NS_COMMAND_THAW "thaw" -#define NS_COMMAND_TIMERPOKE "timerpoke" -#define NS_COMMAND_RECURSING "recursing" -#define NS_COMMAND_NULL "null" -#define NS_COMMAND_NOTIFY "notify" -#define NS_COMMAND_VALIDATION "validation" -#define NS_COMMAND_SCAN "scan" -#define NS_COMMAND_SIGN "sign" -#define NS_COMMAND_LOADKEYS "loadkeys" -#define NS_COMMAND_ADDZONE "addzone" -#define NS_COMMAND_MODZONE "modzone" -#define NS_COMMAND_DELZONE "delzone" -#define NS_COMMAND_SHOWZONE "showzone" -#define NS_COMMAND_SYNC "sync" -#define NS_COMMAND_SIGNING "signing" -#define NS_COMMAND_ZONESTATUS "zonestatus" -#define NS_COMMAND_NTA "nta" -#define NS_COMMAND_TESTGEN "testgen" -#define NS_COMMAND_MKEYS "managed-keys" -#define NS_COMMAND_DNSTAPREOPEN "dnstap-reopen" -#define NS_COMMAND_DNSTAP "dnstap" -#define NS_COMMAND_SERVESTALE "serve-stale" - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); -/*%< - * Create an initial, empty set of command channels for 'server'. - */ - -void -ns_controls_destroy(ns_controls_t **ctrlsp); -/*%< - * Destroy a set of command channels. - * - * Requires: - * Shutdown of the channels has completed. - */ - -isc_result_t -ns_controls_configure(ns_controls_t *controls, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx); -/*%< - * Configure zero or more command channels into 'controls' - * as defined in the configuration parse tree 'config'. - * The channels will evaluate ACLs in the context of - * 'aclconfctx'. - */ - -void -ns_controls_shutdown(ns_controls_t *controls); -/*%< - * Initiate shutdown of all the command channels in 'controls'. - */ - -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, bool readonly, - isc_buffer_t **text); - -#endif /* NAMED_CONTROL_H */ diff --git a/bin/named-pkcs11/include/named/fuzz.h b/bin/named-pkcs11/include/named/fuzz.h deleted file mode 100644 index c05f112..0000000 --- a/bin/named-pkcs11/include/named/fuzz.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_FUZZ_H -#define NAMED_FUZZ_H - -void -named_fuzz_notify(void); - -void -named_fuzz_setup(void); - -typedef enum { - ns_fuzz_none, - ns_fuzz_client, - ns_fuzz_tcpclient, - ns_fuzz_resolver, - ns_fuzz_http, - ns_fuzz_rndc -} ns_fuzz_t; - -#endif /* NAMED_FUZZ_H */ diff --git a/bin/named-pkcs11/include/named/geoip.h b/bin/named-pkcs11/include/named/geoip.h deleted file mode 100644 index c293f1a..0000000 --- a/bin/named-pkcs11/include/named/geoip.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef _GEOIP_H -#define _GEOIP_H - -extern dns_geoip_databases_t *ns_g_geoip; - -void -ns_geoip_init(void); - -void -ns_geoip_load(char *dir); - -void -ns_geoip_shutdown(void); -#endif diff --git a/bin/named-pkcs11/include/named/globals.h b/bin/named-pkcs11/include/named/globals.h deleted file mode 100644 index 0d96a79..0000000 --- a/bin/named-pkcs11/include/named/globals.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_GLOBALS_H -#define NAMED_GLOBALS_H 1 - -/*! \file */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -#ifndef NS_RUN_PID_DIR -#define NS_RUN_PID_DIR 1 -#endif - -EXTERN isc_mem_t * ns_g_mctx INIT(NULL); -EXTERN unsigned int ns_g_cpus INIT(0); -EXTERN unsigned int ns_g_udpdisp INIT(0); -EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL); -EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL); -EXTERN isc_entropy_t * ns_g_entropy INIT(NULL); -EXTERN isc_entropy_t * ns_g_fallbackentropy INIT(NULL); -EXTERN unsigned int ns_g_cpus_detected INIT(1); - -#ifdef ENABLE_AFL -EXTERN bool ns_g_run_done INIT(false); -#endif -/* - * XXXRTH We're going to want multiple timer managers eventually. One - * for really short timers, another for client timers, and one - * for zone timers. - */ -EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL); -EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL); -EXTERN cfg_parser_t * ns_g_parser INIT(NULL); -EXTERN cfg_parser_t * ns_g_addparser INIT(NULL); -EXTERN const char * ns_g_version INIT(VERSION); -EXTERN const char * ns_g_product INIT(PRODUCT); -EXTERN const char * ns_g_description INIT(DESCRIPTION); -EXTERN const char * ns_g_srcid INIT(SRCID); -EXTERN const char * ns_g_configargs INIT(CONFIGARGS); -EXTERN const char * ns_g_builder INIT(BUILDER); -EXTERN in_port_t ns_g_port INIT(0); -EXTERN isc_dscp_t ns_g_dscp INIT(-1); -EXTERN in_port_t lwresd_g_listenport INIT(0); - -EXTERN ns_server_t * ns_g_server INIT(NULL); - -EXTERN bool ns_g_lwresdonly INIT(false); - -/* - * Logging. - */ -EXTERN isc_log_t * ns_g_lctx INIT(NULL); -EXTERN isc_logcategory_t * ns_g_categories INIT(NULL); -EXTERN isc_logmodule_t * ns_g_modules INIT(NULL); -EXTERN unsigned int ns_g_debuglevel INIT(0); - -/* - * Current configuration information. - */ -EXTERN cfg_obj_t * ns_g_config INIT(NULL); -EXTERN const cfg_obj_t * ns_g_defaults INIT(NULL); -EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR - "/named.conf"); -EXTERN cfg_obj_t * ns_g_bindkeys INIT(NULL); -EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR - "/rndc.key"); - -EXTERN dns_tsigkey_t * ns_g_sessionkey INIT(NULL); -EXTERN dns_name_t ns_g_sessionkeyname; - -EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR - "/lwresd.conf"); -EXTERN const char * lwresd_g_resolvconffile INIT("/etc" - "/resolv.conf"); -EXTERN bool ns_g_conffileset INIT(false); -EXTERN bool lwresd_g_useresolvconf INIT(false); -EXTERN uint16_t ns_g_udpsize INIT(4096); -EXTERN cfg_aclconfctx_t * ns_g_aclconfctx INIT(NULL); - -/* - * Initial resource limits. - */ -EXTERN isc_resourcevalue_t ns_g_initstacksize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initdatasize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initcoresize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initopenfiles INIT(0); - -/* - * Misc. - */ -EXTERN bool ns_g_coreok INIT(true); -EXTERN const char * ns_g_chrootdir INIT(NULL); -EXTERN bool ns_g_foreground INIT(false); -EXTERN bool ns_g_logstderr INIT(false); -EXTERN bool ns_g_nosyslog INIT(false); -EXTERN const char * ns_g_logfile INIT(NULL); - -EXTERN const char * ns_g_defaultsessionkeyfile - INIT(NS_LOCALSTATEDIR "/run/named/" - "session.key"); -EXTERN const char * ns_g_defaultlockfile INIT(NS_LOCALSTATEDIR - "/run/named/" - "named.lock"); -EXTERN bool ns_g_forcelock INIT(false); - -#if NS_RUN_PID_DIR -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named/" - "named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd/" - "lwresd.pid"); -#else -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd.pid"); -#endif - -EXTERN const char * ns_g_username INIT(NULL); - -#if defined(USE_PKCS11) -EXTERN const char * ns_g_engine INIT(PKCS11_ENGINE); -#else -EXTERN const char * ns_g_engine INIT(NULL); -#endif - -EXTERN int ns_g_listen INIT(3); -EXTERN isc_time_t ns_g_boottime; -EXTERN isc_time_t ns_g_configtime; -EXTERN bool ns_g_memstatistics INIT(false); -EXTERN bool ns_g_clienttest INIT(false); -EXTERN bool ns_g_dropedns INIT(false); -EXTERN bool ns_g_ednsformerr INIT(false); -EXTERN bool ns_g_ednsnotimp INIT(false); -EXTERN bool ns_g_ednsrefused INIT(false); -EXTERN bool ns_g_noedns INIT(false); -EXTERN bool ns_g_nosoa INIT(false); -EXTERN bool ns_g_noaa INIT(false); -EXTERN bool ns_g_keepstderr INIT(false); -EXTERN unsigned int ns_g_delay INIT(0); -EXTERN bool ns_g_nonearest INIT(false); -EXTERN bool ns_g_notcp INIT(false); -EXTERN bool ns_g_disable6 INIT(false); -EXTERN bool ns_g_disable4 INIT(false); -EXTERN unsigned int ns_g_tat_interval INIT(24*3600); -EXTERN bool ns_g_fixedlocal INIT(false); -EXTERN bool ns_g_sigvalinsecs INIT(false); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL); -#endif - -EXTERN const char * ns_g_fuzz_named_addr INIT(NULL); -EXTERN ns_fuzz_t ns_g_fuzz_type INIT(ns_fuzz_none); - -EXTERN dns_acl_t * ns_g_mapped INIT(NULL); - -#undef EXTERN -#undef INIT - -#endif /* NAMED_GLOBALS_H */ diff --git a/bin/named-pkcs11/include/named/interfacemgr.h b/bin/named-pkcs11/include/named/interfacemgr.h deleted file mode 100644 index 2170693..0000000 --- a/bin/named-pkcs11/include/named/interfacemgr.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_INTERFACEMGR_H -#define NAMED_INTERFACEMGR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The interface manager monitors the operating system's list - * of network interfaces, creating and destroying listeners - * as needed. - * - * Reliability: - *\li No impact expected. - * - * Resources: - * - * Security: - * \li The server will only be able to bind to the DNS port on - * newly discovered interfaces if it is running as root. - * - * Standards: - *\li The API for scanning varies greatly among operating systems. - * This module attempts to hide the differences. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -/*** - *** Types - ***/ - -#define IFACE_MAGIC ISC_MAGIC('I',':','-',')') -#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) - -#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ -#define MAX_UDP_DISPATCH 128 /*%< Maximum number of UDP dispatchers - to start per interface */ -/*% The nameserver interface structure */ -struct ns_interface { - unsigned int magic; /*%< Magic number. */ - ns_interfacemgr_t * mgr; /*%< Interface manager. */ - isc_mutex_t lock; - int references; /*%< Locked */ - unsigned int generation; /*%< Generation number. */ - isc_sockaddr_t addr; /*%< Address and port. */ - unsigned int flags; /*%< Interface characteristics */ - char name[32]; /*%< Null terminated. */ - dns_dispatch_t * udpdispatch[MAX_UDP_DISPATCH]; - /*%< UDP dispatchers. */ - isc_socket_t * tcpsocket; /*%< TCP socket. */ - isc_dscp_t dscp; /*%< "listen-on" DSCP value */ - isc_refcount_t ntcpaccepting; /*%< Number of clients - ready to accept new - TCP connections on this - interface */ - isc_refcount_t ntcpactive; /*%< Number of clients - servicing TCP queries - (whether accepting or - connected) */ - int nudpdispatch; /*%< Number of UDP dispatches */ - ns_clientmgr_t * clientmgr; /*%< Client manager. */ - ISC_LINK(ns_interface_t) link; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - isc_task_t *task, ns_interfacemgr_t **mgrp); -/*% - * Create a new interface manager. - * - * Initially, the new manager will not listen on any interfaces. - * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() - * to set nonempty listen-on lists. - */ - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp); - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); - -bool -ns_interfacemgr_islistening(ns_interfacemgr_t *mgr); -/*% - * Return if the manager is listening on any interface. It can be called - * after a scan or adjust. - */ - -isc_result_t -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose); -/*% - * Scan the operatings system's list of network interfaces - * and create listeners when new interfaces are discovered. - * Shut down the sockets for interfaces that go away. - * - * This should be called once on server startup and then - * periodically according to the 'interface-interval' option - * in named.conf. - */ - -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose); -/*% - * Similar to ns_interfacemgr_scan(), but this function also tries to see the - * need for an explicit listen-on when a list element in 'list' is going to - * override an already-listening a wildcard interface. - * - * This function does not update localhost and localnets ACLs. - * - * This should be called once on server startup, after configuring views and - * zones. - */ - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv4 "listen-on" list of 'mgr' to 'value'. - * The previous IPv4 listen-on list is freed. - */ - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv6 "listen-on" list of 'mgr' to 'value'. - * The previous IPv6 listen-on list is freed. - */ - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target); - -void -ns_interface_detach(ns_interface_t **targetp); - -void -ns_interface_shutdown(ns_interface_t *ifp); -/*% - * Stop listening for queries on interface 'ifp'. - * May safely be called multiple times. - */ - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); - -bool -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr); - -#endif /* NAMED_INTERFACEMGR_H */ diff --git a/bin/named-pkcs11/include/named/listenlist.h b/bin/named-pkcs11/include/named/listenlist.h deleted file mode 100644 index 04525c0..0000000 --- a/bin/named-pkcs11/include/named/listenlist.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LISTENLIST_H -#define NAMED_LISTENLIST_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * "Listen lists", as in the "listen-on" configuration statement. - */ - -/*** - *** Imports - ***/ - - -#include -#include - -#include - -/*** - *** Types - ***/ - -typedef struct ns_listenelt ns_listenelt_t; -typedef struct ns_listenlist ns_listenlist_t; - -struct ns_listenelt { - isc_mem_t * mctx; - in_port_t port; - isc_dscp_t dscp; /* -1 = not set, 0..63 */ - dns_acl_t * acl; - ISC_LINK(ns_listenelt_t) link; -}; - -struct ns_listenlist { - isc_mem_t * mctx; - int refcount; - ISC_LIST(ns_listenelt_t) elts; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - dns_acl_t *acl, ns_listenelt_t **target); -/*% - * Create a listen-on list element. - */ - -void -ns_listenelt_destroy(ns_listenelt_t *elt); -/*% - * Destroy a listen-on list element. - */ - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); -/*% - * Create a new, empty listen-on list. - */ - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); -/*% - * Attach '*target' to '*source'. - */ - -void -ns_listenlist_detach(ns_listenlist_t **listp); -/*% - * Detach 'listp'. - */ - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - bool enabled, ns_listenlist_t **target); -/*% - * Create a listen-on list with default contents, matching - * all addresses with port 'port' (if 'enabled' is true), - * or no addresses (if 'enabled' is false). - */ - -#endif /* NAMED_LISTENLIST_H */ diff --git a/bin/named-pkcs11/include/named/log.h b/bin/named-pkcs11/include/named/log.h deleted file mode 100644 index 0d1d985..0000000 --- a/bin/named-pkcs11/include/named/log.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LOG_H -#define NAMED_LOG_H 1 - -/*! \file */ - -#include -#include - -#include - -#include /* Required for ns_g_(categories|modules). */ - -/* Unused slot 0. */ -#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1]) -#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2]) -#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3]) -#define NS_LOGCATEGORY_QUERIES (&ns_g_categories[4]) -#define NS_LOGCATEGORY_UNMATCHED (&ns_g_categories[5]) -#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) -#define NS_LOGCATEGORY_QUERY_ERRORS (&ns_g_categories[7]) -#define NS_LOGCATEGORY_TAT (&ns_g_categories[8]) -#define NS_LOGCATEGORY_SERVE_STALE (&ns_g_categories[9]) - -/* - * Backwards compatibility. - */ -#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL - -#define NS_LOGMODULE_MAIN (&ns_g_modules[0]) -#define NS_LOGMODULE_CLIENT (&ns_g_modules[1]) -#define NS_LOGMODULE_SERVER (&ns_g_modules[2]) -#define NS_LOGMODULE_QUERY (&ns_g_modules[3]) -#define NS_LOGMODULE_INTERFACEMGR (&ns_g_modules[4]) -#define NS_LOGMODULE_UPDATE (&ns_g_modules[5]) -#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6]) -#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7]) -#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8]) -#define NS_LOGMODULE_CONTROL (&ns_g_modules[9]) -#define NS_LOGMODULE_LWRESD (&ns_g_modules[10]) - -isc_result_t -ns_log_init(bool safe); -/*% - * Initialize the logging system and set up an initial default - * logging default configuration that will be used until the - * config file has been read. - * - * If 'safe' is true, use a default configuration that refrains - * from opening files. This is to avoid creating log files - * as root. - */ - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg); -/*% - * Set up logging channels according to the named defaults, which - * may differ from the logging library defaults. Currently, - * this just means setting up default_debug. - */ - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg); -/*% - * Like ns_log_setdefaultchannels(), but omits any logging to files. - */ - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category default" to go to the right places. - */ - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category unmatched" to go to the right places. - */ - -void -ns_log_shutdown(void); - -#endif /* NAMED_LOG_H */ diff --git a/bin/named-pkcs11/include/named/logconf.h b/bin/named-pkcs11/include/named/logconf.h deleted file mode 100644 index 8438b67..0000000 --- a/bin/named-pkcs11/include/named/logconf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NAMED_LOGCONF_H -#define NAMED_LOGCONF_H 1 - -/*! \file */ - -#include - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt); -/*%< - * Set up the logging configuration in '*logconf' according to - * the named.conf data in 'logstmt'. - */ - -#endif /* NAMED_LOGCONF_H */ diff --git a/bin/named-pkcs11/include/named/lwaddr.h b/bin/named-pkcs11/include/named/lwaddr.h deleted file mode 100644 index 3e5eed2..0000000 --- a/bin/named-pkcs11/include/named/lwaddr.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include - -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la); - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port); - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na); - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa); diff --git a/bin/named-pkcs11/include/named/lwdclient.h b/bin/named-pkcs11/include/named/lwdclient.h deleted file mode 100644 index 389abc7..0000000 --- a/bin/named-pkcs11/include/named/lwdclient.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWDCLIENT_H -#define NAMED_LWDCLIENT_H 1 - -/*! \file */ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) - -#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) - -/*% Lightweight Resolver Daemon Client */ -struct ns_lwdclient { - isc_sockaddr_t address; /*%< where to reply */ - struct in6_pktinfo pktinfo; - bool pktinfo_valid; - ns_lwdclientmgr_t *clientmgr; /*%< our parent */ - ISC_LINK(ns_lwdclient_t) link; - unsigned int state; - void *arg; /*%< packet processing state */ - - /* - * Received data info. - */ - unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */ - uint32_t recvlength; /*%< length recv'd */ - lwres_lwpacket_t pkt; - - /*% - * Send data state. If sendbuf != buffer (that is, the send buffer - * isn't our receive buffer) it will be freed to the lwres_context_t. - */ - unsigned char *sendbuf; - uint32_t sendlength; - isc_buffer_t recv_buffer; - - /*% - * gabn (get address by name) state info. - */ - dns_adbfind_t *find; - dns_adbfind_t *v4find; - dns_adbfind_t *v6find; - unsigned int find_wanted; /*%< Addresses we want */ - dns_fixedname_t query_name; - dns_fixedname_t target_name; - ns_lwsearchctx_t searchctx; - lwres_gabnresponse_t gabn; - - /*% - * gnba (get name by address) state info. - */ - lwres_gnbaresponse_t gnba; - dns_byaddr_t *byaddr; - unsigned int options; - isc_netaddr_t na; - - /*% - * grbn (get rrset by name) state info. - * - * Note: this also uses target_name and searchctx. - */ - lwres_grbnresponse_t grbn; - dns_lookup_t *lookup; - dns_rdatatype_t rdtype; - - /*% - * Alias and address info. This is copied up to the gabn/gnba - * structures eventually. - * - * XXXMLG We can keep all of this in a client since we only service - * three packet types right now. If we started handling more, - * we'd need to use "arg" above and allocate/destroy things. - */ - char *aliases[LWRES_MAX_ALIASES]; - uint16_t aliaslen[LWRES_MAX_ALIASES]; - lwres_addr_t addrs[LWRES_MAX_ADDRS]; -}; - -/*% - * Client states. - * - * _IDLE The client is not doing anything at all. - * - * _RECV The client is waiting for data after issuing a socket recv(). - * - * _RECVDONE Data has been received, and is being processed. - * - * _FINDWAIT An adb (or other) request was made that cannot be satisfied - * immediately. An event will wake the client up. - * - * _SEND All data for a response has completed, and a reply was - * sent via a socket send() call. - * - * Badly formatted state table: - * - * IDLE -> RECV when client has a recv() queued. - * - * RECV -> RECVDONE when recvdone event received. - * - * RECVDONE -> SEND if the data for a reply is at hand. - * RECVDONE -> FINDWAIT if more searching is needed, and events will - * eventually wake us up again. - * - * FINDWAIT -> SEND when enough data was received to reply. - * - * SEND -> IDLE when a senddone event was received. - * - * At any time -> IDLE on error. Sometimes this will be -> SEND - * instead, if enough data is on hand to reply with a meaningful - * error. - * - * Packets which are badly formatted may or may not get error returns. - */ -#define NS_LWDCLIENT_STATEIDLE 1 -#define NS_LWDCLIENT_STATERECV 2 -#define NS_LWDCLIENT_STATERECVDONE 3 -#define NS_LWDCLIENT_STATEFINDWAIT 4 -#define NS_LWDCLIENT_STATESEND 5 -#define NS_LWDCLIENT_STATESENDDONE 6 - -#define NS_LWDCLIENT_ISIDLE(c) \ - ((c)->state == NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_ISRECV(c) \ - ((c)->state == NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_ISRECVDONE(c) \ - ((c)->state == NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_ISFINDWAIT(c) \ - ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_ISSEND(c) \ - ((c)->state == NS_LWDCLIENT_STATESEND) - -/*% - * Overall magic test that means we're not idle. - */ -#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) - -#define NS_LWDCLIENT_SETIDLE(c) \ - ((c)->state = NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_SETRECV(c) \ - ((c)->state = NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_SETRECVDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_SETFINDWAIT(c) \ - ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_SETSEND(c) \ - ((c)->state = NS_LWDCLIENT_STATESEND) -#define NS_LWDCLIENT_SETSENDDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATESENDDONE) - -/*% lightweight daemon client manager */ -struct ns_lwdclientmgr { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_socket_t *sock; /*%< socket to use */ - dns_view_t *view; - lwres_context_t *lwctx; /*%< lightweight proto context */ - isc_task_t *task; /*%< owning task */ - unsigned int flags; - isc_mutex_t lock; - ISC_LINK(ns_lwdclientmgr_t) link; - ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */ - ISC_LIST(ns_lwdclient_t) running; /*%< running clients */ -}; - -#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 -#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); - -void -ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); - -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *); - -void -ns_lwdclient_stateidle(ns_lwdclient_t *); - -void -ns_lwdclient_recv(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_send(isc_task_t *, isc_event_t *); - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); - -/* - * Processing functions of various types. - */ -void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); - -void ns_lwdclient_errorpktsend(ns_lwdclient_t *, uint32_t); - -void ns_lwdclient_log(int level, const char *format, ...) - ISC_FORMAT_PRINTF(2, 3); - -#endif /* NAMED_LWDCLIENT_H */ diff --git a/bin/named-pkcs11/include/named/lwresd.h b/bin/named-pkcs11/include/named/lwresd.h deleted file mode 100644 index fff9f11..0000000 --- a/bin/named-pkcs11/include/named/lwresd.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWRESD_H -#define NAMED_LWRESD_H 1 - -/*! \file */ - -#include -#include - -#include - -#include - -struct ns_lwresd { - unsigned int magic; - - isc_mutex_t lock; - dns_view_t *view; - ns_lwsearchlist_t *search; - unsigned int ndots; - unsigned int ntasks; - unsigned int nclients; - isc_mem_t *mctx; - bool shutting_down; - unsigned int refs; -}; - -struct ns_lwreslistener { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - isc_sockaddr_t address; - ns_lwresd_t *manager; - isc_socket_t *sock; - unsigned int refs; - ISC_LIST(ns_lwdclientmgr_t) cmgrs; - ISC_LINK(ns_lwreslistener_t) link; -}; - -/*% - * Configure lwresd. - */ -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config); - -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp); - -/*% - * Trigger shutdown. - */ -void -ns_lwresd_shutdown(void); - -/* - * Manager functions - */ -/*% create manager */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp); - -/*% attach to manager */ -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); - -/*% detach from manager */ -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp); - -/* - * Listener functions - */ -/*% attach to listener */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp); - -/*% detach from lister */ -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); - -/*% link client manager */ -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - -/*% unlink client manager */ -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - - - - -/* - * INTERNAL FUNCTIONS. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size); - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size); - -#endif /* NAMED_LWRESD_H */ diff --git a/bin/named-pkcs11/include/named/lwsearch.h b/bin/named-pkcs11/include/named/lwsearch.h deleted file mode 100644 index a256f33..0000000 --- a/bin/named-pkcs11/include/named/lwsearch.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWSEARCH_H -#define NAMED_LWSEARCH_H 1 - -#include -#include -#include - -#include - -#include - -/*! \file - * \brief - * Lightweight resolver search list types and routines. - * - * An ns_lwsearchlist_t holds a list of search path elements. - * - * An ns_lwsearchctx stores the state of search list during a lookup - * operation. - */ - -/*% An ns_lwsearchlist_t holds a list of search path elements. */ -struct ns_lwsearchlist { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - unsigned int refs; - dns_namelist_t names; -}; -/*% An ns_lwsearchctx stores the state of search list during a lookup operation. */ -struct ns_lwsearchctx { - dns_name_t *relname; - dns_name_t *searchname; - unsigned int ndots; - ns_lwsearchlist_t *list; - bool doneexact; - bool exactfirst; -}; - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp); -/*%< - * Create an empty search list object. - */ - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target); -/*%< - * Attach to a search list object. - */ - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp); -/*%< - * Detach from a search list object. - */ - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name); -/*%< - * Append an element to a search list. This creates a copy of the name. - */ - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots); -/*%< - * Creates a search list context structure. - */ - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the first element, which - * is usually the exact name. - */ - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the next element. - */ - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname); -/*%< - * Obtains the current name to be looked up. This involves either - * concatenating the name with a search path element, making an - * exact name absolute, or doing nothing. - */ - -#endif /* NAMED_LWSEARCH_H */ diff --git a/bin/named-pkcs11/include/named/main.h b/bin/named-pkcs11/include/named/main.h deleted file mode 100644 index 5e5738f..0000000 --- a/bin/named-pkcs11/include/named/main.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_MAIN_H -#define NAMED_MAIN_H 1 - -/*! \file */ - -#ifdef ISC_MAIN_HOOK -#define main(argc, argv) bindmain(argc, argv) -#endif - -/* - * Commandline arguments for named; also referenced in win32/ntservice.c - */ -#define NS_MAIN_ARGS "46A:c:C:d:D:E:fFgi:lL:M:m:n:N:p:P:sS:t:T:U:u:vVx:X:" - -ISC_PLATFORM_NORETURN_PRE void -ns_main_earlyfatal(const char *format, ...) -ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; - -void -ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_setmemstats(const char *); - -#endif /* NAMED_MAIN_H */ diff --git a/bin/named-pkcs11/include/named/notify.h b/bin/named-pkcs11/include/named/notify.h deleted file mode 100644 index 52895e5..0000000 --- a/bin/named-pkcs11/include/named/notify.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_NOTIFY_H -#define NAMED_NOTIFY_H 1 - -#include -#include - -/*** - *** Module Info - ***/ - -/*! \file - * \brief - * RFC1996 - * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) - */ - -/*** - *** Functions. - ***/ - -void -ns_notify_start(ns_client_t *client); - -/*%< - * Examines the incoming message to determine appropriate zone. - * Returns FORMERR if there is not exactly one question. - * Returns REFUSED if we do not serve the listed zone. - * Pass the message to the zone module for processing - * and returns the return status. - * - * Requires - *\li client to be valid. - */ - -#endif /* NAMED_NOTIFY_H */ - diff --git a/bin/named-pkcs11/include/named/ns_smf_globals.h b/bin/named-pkcs11/include/named/ns_smf_globals.h deleted file mode 100644 index d2b695c..0000000 --- a/bin/named-pkcs11/include/named/ns_smf_globals.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_SMF_GLOBALS_H -#define NS_SMF_GLOBALS_H 1 - -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN unsigned int ns_smf_got_instance INIT(0); -EXTERN unsigned int ns_smf_chroot INIT(0); -EXTERN unsigned int ns_smf_want_disable INIT(0); - -isc_result_t ns_smf_add_message(isc_buffer_t **text); -isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx); - -#undef EXTERN -#undef INIT - -#endif /* NS_SMF_GLOBALS_H */ diff --git a/bin/named-pkcs11/include/named/query.h b/bin/named-pkcs11/include/named/query.h deleted file mode 100644 index 53c052b..0000000 --- a/bin/named-pkcs11/include/named/query.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_QUERY_H -#define NAMED_QUERY_H 1 - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include - -#include - -/*% nameserver database version structure */ -typedef struct ns_dbversion { - dns_db_t *db; - dns_dbversion_t *version; - bool acl_checked; - bool queryok; - ISC_LINK(struct ns_dbversion) link; -} ns_dbversion_t; - -/*% - * nameserver recursion parameters, to uniquely identify a recursion - * query; this is used to detect a recursion loop - */ -typedef struct ns_query_recparam { - dns_rdatatype_t qtype; - dns_name_t * qname; - dns_fixedname_t fqname; - dns_name_t * qdomain; - dns_fixedname_t fqdomain; -} ns_query_recparam_t; - -/*% nameserver query structure */ -struct ns_query { - unsigned int attributes; - unsigned int restarts; - bool timerset; - dns_name_t * qname; - dns_name_t * origqname; - dns_rdatatype_t qtype; - unsigned int dboptions; - unsigned int fetchoptions; - dns_db_t * gluedb; - dns_db_t * authdb; - dns_zone_t * authzone; - bool authdbset; - bool isreferral; - isc_mutex_t fetchlock; - dns_fetch_t * fetch; - dns_fetch_t * prefetch; - dns_rpz_st_t * rpz_st; - isc_bufferlist_t namebufs; - ISC_LIST(ns_dbversion_t) activeversions; - ISC_LIST(ns_dbversion_t) freeversions; - dns_rdataset_t * dns64_aaaa; - dns_rdataset_t * dns64_sigaaaa; - bool * dns64_aaaaok; - unsigned int dns64_aaaaoklen; - unsigned int dns64_options; - unsigned int dns64_ttl; - - struct { - dns_db_t * db; - dns_zone_t * zone; - dns_dbnode_t * node; - dns_rdatatype_t qtype; - dns_name_t * fname; - dns_fixedname_t fixed; - isc_result_t result; - dns_rdataset_t * rdataset; - dns_rdataset_t * sigrdataset; - bool authoritative; - bool is_zone; - } redirect; - - ns_query_recparam_t recparam; - dns_keytag_t root_key_sentinel_keyid; - bool root_key_sentinel_is_ta; - bool root_key_sentinel_not_ta; -}; - -#define NS_QUERYATTR_RECURSIONOK 0x0001 -#define NS_QUERYATTR_CACHEOK 0x0002 -#define NS_QUERYATTR_PARTIALANSWER 0x0004 -#define NS_QUERYATTR_NAMEBUFUSED 0x0008 -#define NS_QUERYATTR_RECURSING 0x0010 -#define NS_QUERYATTR_CACHEGLUEOK 0x0020 -#define NS_QUERYATTR_QUERYOKVALID 0x0040 -#define NS_QUERYATTR_QUERYOK 0x0080 -#define NS_QUERYATTR_WANTRECURSION 0x0100 -#define NS_QUERYATTR_SECURE 0x0200 -#define NS_QUERYATTR_NOAUTHORITY 0x0400 -#define NS_QUERYATTR_NOADDITIONAL 0x0800 -#define NS_QUERYATTR_CACHEACLOKVALID 0x1000 -#define NS_QUERYATTR_CACHEACLOK 0x2000 -#define NS_QUERYATTR_DNS64 0x4000 -#define NS_QUERYATTR_DNS64EXCLUDE 0x8000 -#define NS_QUERYATTR_RRL_CHECKED 0x10000 -#define NS_QUERYATTR_REDIRECT 0x20000 - -isc_result_t -ns_query_init(ns_client_t *client); - -void -ns_query_free(ns_client_t *client); - -void -ns_query_start(ns_client_t *client); - -void -ns_query_cancel(ns_client_t *client); - -#endif /* NAMED_QUERY_H */ diff --git a/bin/named-pkcs11/include/named/seccomp.h b/bin/named-pkcs11/include/named/seccomp.h deleted file mode 100644 index 970ce28..0000000 --- a/bin/named-pkcs11/include/named/seccomp.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SECCOMP_H -#define NAMED_SECCOMP_H 1 - -/*! \file */ - -#ifdef HAVE_LIBSECCOMP -#include -#include -#include -#include -#include - -/*% - * For each architecture, the scmp_syscalls and - * scmp_syscall_names arrays MUST be kept in sync. - */ -#ifdef __x86_64__ -int scmp_syscalls[] = { - SCMP_SYS(access), - SCMP_SYS(open), - SCMP_SYS(openat), - SCMP_SYS(lseek), - SCMP_SYS(clock_gettime), - SCMP_SYS(time), - SCMP_SYS(read), - SCMP_SYS(write), - SCMP_SYS(close), - SCMP_SYS(brk), - SCMP_SYS(poll), - SCMP_SYS(select), - SCMP_SYS(madvise), - SCMP_SYS(mmap), - SCMP_SYS(munmap), - SCMP_SYS(exit_group), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(rt_sigaction), - SCMP_SYS(fsync), - SCMP_SYS(rt_sigreturn), - SCMP_SYS(setsid), - SCMP_SYS(chdir), - SCMP_SYS(futex), - SCMP_SYS(stat), - SCMP_SYS(rt_sigsuspend), - SCMP_SYS(fstat), - SCMP_SYS(epoll_ctl), - SCMP_SYS(gettimeofday), - SCMP_SYS(getpid), -#ifdef HAVE_GETRANDOM - SCMP_SYS(getrandom), -#endif - SCMP_SYS(rename), - SCMP_SYS(unlink), - SCMP_SYS(socket), - SCMP_SYS(sendto), -#ifndef ISC_PLATFORM_USETHREADS - SCMP_SYS(bind), - SCMP_SYS(accept), - SCMP_SYS(connect), - SCMP_SYS(listen), - SCMP_SYS(fcntl), - SCMP_SYS(sendmsg), - SCMP_SYS(recvmsg), - SCMP_SYS(uname), - SCMP_SYS(setrlimit), - SCMP_SYS(getrlimit), - SCMP_SYS(setsockopt), - SCMP_SYS(getsockopt), - SCMP_SYS(getsockname), - SCMP_SYS(lstat), - SCMP_SYS(getgid), - SCMP_SYS(getegid), - SCMP_SYS(getuid), - SCMP_SYS(geteuid), - SCMP_SYS(setresgid), - SCMP_SYS(setresuid), - SCMP_SYS(setgid), - SCMP_SYS(setuid), - SCMP_SYS(prctl), - SCMP_SYS(epoll_wait), - SCMP_SYS(getdents), - SCMP_SYS(utimes), - SCMP_SYS(dup), -#endif -}; -const char *scmp_syscall_names[] = { - "access", - "open", - "openat", - "lseek", - "clock_gettime", - "time", - "read", - "write", - "close", - "brk", - "poll", - "select", - "madvise", - "mmap", - "munmap", - "exit_group", - "rt_sigprocmask", - "rt_sigaction", - "fsync", - "rt_sigreturn", - "setsid", - "chdir", - "futex", - "stat", - "rt_sigsuspend", - "fstat", - "epoll_ctl", - "gettimeofday", - "getpid", -#ifdef HAVE_GETRANDOM - "getrandom", -#endif - "rename", - "unlink", - "socket", - "sendto", -#ifndef ISC_PLATFORM_USETHREADS - "bind", - "accept", - "connect", - "listen", - "fcntl", - "sendmsg", - "recvmsg", - "uname", - "setrlimit", - "getrlimit", - "setsockopt", - "getsockopt", - "getsockname", - "lstat", - "getgid", - "getegid", - "getuid", - "geteuid", - "setresgid", - "setresuid", - "setgid", - "setuid", - "prctl", - "epoll_wait", - "getdents", - "utimes", - "dup", -#endif -}; -#endif /* __x86_64__ */ -#ifdef __i386__ -int scmp_syscalls[] = { - SCMP_SYS(access), - SCMP_SYS(open), - SCMP_SYS(clock_gettime), - SCMP_SYS(time), - SCMP_SYS(read), - SCMP_SYS(write), - SCMP_SYS(close), - SCMP_SYS(brk), - SCMP_SYS(poll), - SCMP_SYS(_newselect), - SCMP_SYS(select), - SCMP_SYS(madvise), - SCMP_SYS(mmap2), - SCMP_SYS(mmap), - SCMP_SYS(munmap), - SCMP_SYS(exit_group), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(sigprocmask), - SCMP_SYS(rt_sigaction), - SCMP_SYS(socketcall), - SCMP_SYS(fsync), - SCMP_SYS(sigreturn), - SCMP_SYS(setsid), - SCMP_SYS(chdir), - SCMP_SYS(futex), - SCMP_SYS(stat64), - SCMP_SYS(rt_sigsuspend), - SCMP_SYS(fstat64), - SCMP_SYS(epoll_ctl), - SCMP_SYS(gettimeofday), - SCMP_SYS(getpid), -#ifdef HAVE_GETRANDOM - SCMP_SYS(getrandom), -#endif - SCMP_SYS(unlink), -#ifndef ISC_PLATFORM_USETHREADS - SCMP_SYS(fcntl64), -#endif -}; -const char *scmp_syscall_names[] = { - "access", - "open", - "clock_gettime", - "time", - "read", - "write", - "close", - "brk", - "poll", - "_newselect", - "select", - "madvise", - "mmap2", - "mmap", - "munmap", - "exit_group", - "rt_sigprocmask", - "sigprocmask", - "rt_sigaction", - "socketcall", - "fsync", - "sigreturn", - "setsid", - "chdir", - "futex", - "stat64", - "rt_sigsuspend", - "fstat64", - "epoll_ctl", - "gettimeofday", - "getpid", -#ifdef HAVE_GETRANDOM - "getrandom", -#endif - "unlink", -#ifndef ISC_PLATFORM_USETHREADS - "fcntl64", -#endif -}; -#endif /* __i386__ */ -#endif /* HAVE_LIBSECCOMP */ - -#endif /* NAMED_SECCOMP_H */ diff --git a/bin/named-pkcs11/include/named/server.h b/bin/named-pkcs11/include/named/server.h deleted file mode 100644 index 08a02dc..0000000 --- a/bin/named-pkcs11/include/named/server.h +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SERVER_H -#define NAMED_SERVER_H 1 - -/*! \file */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) -#define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) -#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) -#define NS_EVENT_DELZONE (NS_EVENTCLASS + 2) -#define NS_EVENT_TATSEND (NS_EVENTCLASS + 3) - -/*% - * Name server state. Better here than in lots of separate global variables. - */ -struct ns_server { - unsigned int magic; - isc_mem_t * mctx; - - isc_task_t * task; - - /* Configurable data. */ - isc_quota_t xfroutquota; - isc_quota_t tcpquota; - isc_quota_t recursionquota; - - dns_acl_t *blackholeacl; - dns_acl_t *keepresporder; - char * statsfile; /*%< Statistics file name */ - char * dumpfile; /*%< Dump file name */ - char * secrootsfile; /*%< Secroots file name */ - char * bindkeysfile; /*%< bind.keys file name */ - char * recfile; /*%< Recursive file name */ - bool version_set; /*%< User has set version */ - char * version; /*%< User-specified version */ - bool hostname_set; /*%< User has set hostname */ - char * hostname; /*%< User-specified hostname */ - /*% Use hostname for server id */ - bool server_usehostname; - char * server_id; /*%< User-specified server id */ - - /*% - * Current ACL environment. This defines the - * current values of the localhost and localnets - * ACLs. - */ - dns_aclenv_t aclenv; - - /* Server data structures. */ - dns_loadmgr_t * loadmgr; - dns_zonemgr_t * zonemgr; - dns_viewlist_t viewlist; - ns_interfacemgr_t * interfacemgr; - dns_db_t * in_roothints; - dns_tkeyctx_t * tkeyctx; - - isc_timer_t * interface_timer; - isc_timer_t * heartbeat_timer; - isc_timer_t * pps_timer; - isc_timer_t * tat_timer; - - uint32_t interface_interval; - uint32_t heartbeat_interval; - - isc_mutex_t reload_event_lock; - isc_event_t * reload_event; - - bool flushonshutdown; - bool log_queries; /*%< For BIND 8 compatibility */ - - ns_cachelist_t cachelist; /*%< Possibly shared caches */ - isc_stats_t * nsstats; /*%< Server stats */ - dns_stats_t * rcvquerystats; /*% Incoming query stats */ - dns_stats_t * opcodestats; /*%< Incoming message stats */ - isc_stats_t * zonestats; /*% Zone management stats */ - isc_stats_t * resolverstats; /*% Resolver stats */ - isc_stats_t * sockstats; /*%< Socket stats */ - isc_stats_t * udpinstats4; /*%< Traffic size: UDPv4 in */ - isc_stats_t * udpoutstats4; /*%< Traffic size: UDPv4 out */ - isc_stats_t * udpinstats6; /*%< Traffic size: UDPv6 in */ - isc_stats_t * udpoutstats6; /*%< Traffic size: UDPv6 out */ - isc_stats_t * tcpinstats4; /*%< Traffic size: TCPv4 in */ - isc_stats_t * tcpoutstats4; /*%< Traffic size: TCPv4 out */ - isc_stats_t * tcpinstats6; /*%< Traffic size: TCPv6 in */ - isc_stats_t * tcpoutstats6; /*%< Traffic size: TCPv6 out */ - dns_stats_t * rcodestats; /*%< Sent Response code stats */ - - ns_controls_t * controls; /*%< Control channels */ - unsigned int dispatchgen; - ns_dispatchlist_t dispatches; - - dns_acache_t *acache; - - ns_statschannellist_t statschannels; - - dns_tsigkey_t *sessionkey; - char *session_keyfile; - dns_name_t *session_keyname; - unsigned int session_keyalg; - uint16_t session_keybits; - bool interface_auto; - unsigned char secret[32]; /*%< Server Cookie Secret */ - ns_altsecretlist_t altsecrets; - ns_cookiealg_t cookiealg; - bool answercookie; - - dns_dtenv_t *dtenv; /*%< Dnstap environment */ - - char * lockfile; - - uint16_t transfer_tcp_message_size; - isc_rng_t * rngctx; -}; - -struct ns_altsecret { - ISC_LINK(ns_altsecret_t) link; - unsigned char secret[32]; -}; - -#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') -#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC) - -/*% - * Server statistics counters. Used as isc_statscounter_t values. - */ -enum { - dns_nsstatscounter_requestv4 = 0, - dns_nsstatscounter_requestv6 = 1, - dns_nsstatscounter_edns0in = 2, - dns_nsstatscounter_badednsver = 3, - dns_nsstatscounter_tsigin = 4, - dns_nsstatscounter_sig0in = 5, - dns_nsstatscounter_invalidsig = 6, - dns_nsstatscounter_requesttcp = 7, - - dns_nsstatscounter_authrej = 8, - dns_nsstatscounter_recurserej = 9, - dns_nsstatscounter_xfrrej = 10, - dns_nsstatscounter_updaterej = 11, - - dns_nsstatscounter_response = 12, - dns_nsstatscounter_truncatedresp = 13, - dns_nsstatscounter_edns0out = 14, - dns_nsstatscounter_tsigout = 15, - dns_nsstatscounter_sig0out = 16, - - dns_nsstatscounter_success = 17, - dns_nsstatscounter_authans = 18, - dns_nsstatscounter_nonauthans = 19, - dns_nsstatscounter_referral = 20, - dns_nsstatscounter_nxrrset = 21, - dns_nsstatscounter_servfail = 22, - dns_nsstatscounter_formerr = 23, - dns_nsstatscounter_nxdomain = 24, - dns_nsstatscounter_recursion = 25, - dns_nsstatscounter_duplicate = 26, - dns_nsstatscounter_dropped = 27, - dns_nsstatscounter_failure = 28, - - dns_nsstatscounter_xfrdone = 29, - - dns_nsstatscounter_updatereqfwd = 30, - dns_nsstatscounter_updaterespfwd = 31, - dns_nsstatscounter_updatefwdfail = 32, - dns_nsstatscounter_updatedone = 33, - dns_nsstatscounter_updatefail = 34, - dns_nsstatscounter_updatebadprereq = 35, - - dns_nsstatscounter_recursclients = 36, - - dns_nsstatscounter_dns64 = 37, - - dns_nsstatscounter_ratedropped = 38, - dns_nsstatscounter_rateslipped = 39, - - dns_nsstatscounter_rpz_rewrites = 40, - - dns_nsstatscounter_udp = 41, - dns_nsstatscounter_tcp = 42, - - dns_nsstatscounter_nsidopt = 43, - dns_nsstatscounter_expireopt = 44, - dns_nsstatscounter_otheropt = 45, - dns_nsstatscounter_ecsopt = 46, - - dns_nsstatscounter_nxdomainredirect = 47, - dns_nsstatscounter_nxdomainredirect_rlookup = 48, - - dns_nsstatscounter_cookiein = 49, - dns_nsstatscounter_cookiebadsize = 50, - dns_nsstatscounter_cookiebadtime = 51, - dns_nsstatscounter_cookienomatch = 52, - dns_nsstatscounter_cookiematch = 53, - dns_nsstatscounter_cookienew = 54, - dns_nsstatscounter_badcookie = 55, - - dns_nsstatscounter_keytagopt = 56, - - dns_nsstatscounter_tcphighwater = 57, - - dns_nsstatscounter_reclimitdropped = 58, - - dns_nsstatscounter_trystale = 59, - dns_nsstatscounter_usedstale = 60, - - dns_nsstatscounter_max = 61 -}; - -/*% - * Traffic size statistics counters. Used as isc_statscounter_t values. - */ -enum { - dns_sizecounter_in_0 = 0, - dns_sizecounter_in_16 = 1, - dns_sizecounter_in_32 = 2, - dns_sizecounter_in_48 = 3, - dns_sizecounter_in_64 = 4, - dns_sizecounter_in_80 = 5, - dns_sizecounter_in_96 = 6, - dns_sizecounter_in_112 = 7, - dns_sizecounter_in_128 = 8, - dns_sizecounter_in_144 = 9, - dns_sizecounter_in_160 = 10, - dns_sizecounter_in_176 = 11, - dns_sizecounter_in_192 = 12, - dns_sizecounter_in_208 = 13, - dns_sizecounter_in_224 = 14, - dns_sizecounter_in_240 = 15, - dns_sizecounter_in_256 = 16, - dns_sizecounter_in_272 = 17, - dns_sizecounter_in_288 = 18, - - dns_sizecounter_in_max = 19, -}; - -enum { - dns_sizecounter_out_0 = 0, - dns_sizecounter_out_16 = 1, - dns_sizecounter_out_32 = 2, - dns_sizecounter_out_48 = 3, - dns_sizecounter_out_64 = 4, - dns_sizecounter_out_80 = 5, - dns_sizecounter_out_96 = 6, - dns_sizecounter_out_112 = 7, - dns_sizecounter_out_128 = 8, - dns_sizecounter_out_144 = 9, - dns_sizecounter_out_160 = 10, - dns_sizecounter_out_176 = 11, - dns_sizecounter_out_192 = 12, - dns_sizecounter_out_208 = 13, - dns_sizecounter_out_224 = 14, - dns_sizecounter_out_240 = 15, - dns_sizecounter_out_256 = 16, - dns_sizecounter_out_272 = 17, - dns_sizecounter_out_288 = 18, - dns_sizecounter_out_304 = 19, - dns_sizecounter_out_320 = 20, - dns_sizecounter_out_336 = 21, - dns_sizecounter_out_352 = 22, - dns_sizecounter_out_368 = 23, - dns_sizecounter_out_384 = 24, - dns_sizecounter_out_400 = 25, - dns_sizecounter_out_416 = 26, - dns_sizecounter_out_432 = 27, - dns_sizecounter_out_448 = 28, - dns_sizecounter_out_464 = 29, - dns_sizecounter_out_480 = 30, - dns_sizecounter_out_496 = 31, - dns_sizecounter_out_512 = 32, - dns_sizecounter_out_528 = 33, - dns_sizecounter_out_544 = 34, - dns_sizecounter_out_560 = 35, - dns_sizecounter_out_576 = 36, - dns_sizecounter_out_592 = 37, - dns_sizecounter_out_608 = 38, - dns_sizecounter_out_624 = 39, - dns_sizecounter_out_640 = 40, - dns_sizecounter_out_656 = 41, - dns_sizecounter_out_672 = 42, - dns_sizecounter_out_688 = 43, - dns_sizecounter_out_704 = 44, - dns_sizecounter_out_720 = 45, - dns_sizecounter_out_736 = 46, - dns_sizecounter_out_752 = 47, - dns_sizecounter_out_768 = 48, - dns_sizecounter_out_784 = 49, - dns_sizecounter_out_800 = 50, - dns_sizecounter_out_816 = 51, - dns_sizecounter_out_832 = 52, - dns_sizecounter_out_848 = 53, - dns_sizecounter_out_864 = 54, - dns_sizecounter_out_880 = 55, - dns_sizecounter_out_896 = 56, - dns_sizecounter_out_912 = 57, - dns_sizecounter_out_928 = 58, - dns_sizecounter_out_944 = 59, - dns_sizecounter_out_960 = 60, - dns_sizecounter_out_976 = 61, - dns_sizecounter_out_992 = 62, - dns_sizecounter_out_1008 = 63, - dns_sizecounter_out_1024 = 64, - dns_sizecounter_out_1040 = 65, - dns_sizecounter_out_1056 = 66, - dns_sizecounter_out_1072 = 67, - dns_sizecounter_out_1088 = 68, - dns_sizecounter_out_1104 = 69, - dns_sizecounter_out_1120 = 70, - dns_sizecounter_out_1136 = 71, - dns_sizecounter_out_1152 = 72, - dns_sizecounter_out_1168 = 73, - dns_sizecounter_out_1184 = 74, - dns_sizecounter_out_1200 = 75, - dns_sizecounter_out_1216 = 76, - dns_sizecounter_out_1232 = 77, - dns_sizecounter_out_1248 = 78, - dns_sizecounter_out_1264 = 79, - dns_sizecounter_out_1280 = 80, - dns_sizecounter_out_1296 = 81, - dns_sizecounter_out_1312 = 82, - dns_sizecounter_out_1328 = 83, - dns_sizecounter_out_1344 = 84, - dns_sizecounter_out_1360 = 85, - dns_sizecounter_out_1376 = 86, - dns_sizecounter_out_1392 = 87, - dns_sizecounter_out_1408 = 88, - dns_sizecounter_out_1424 = 89, - dns_sizecounter_out_1440 = 90, - dns_sizecounter_out_1456 = 91, - dns_sizecounter_out_1472 = 92, - dns_sizecounter_out_1488 = 93, - dns_sizecounter_out_1504 = 94, - dns_sizecounter_out_1520 = 95, - dns_sizecounter_out_1536 = 96, - dns_sizecounter_out_1552 = 97, - dns_sizecounter_out_1568 = 98, - dns_sizecounter_out_1584 = 99, - dns_sizecounter_out_1600 = 100, - dns_sizecounter_out_1616 = 101, - dns_sizecounter_out_1632 = 102, - dns_sizecounter_out_1648 = 103, - dns_sizecounter_out_1664 = 104, - dns_sizecounter_out_1680 = 105, - dns_sizecounter_out_1696 = 106, - dns_sizecounter_out_1712 = 107, - dns_sizecounter_out_1728 = 108, - dns_sizecounter_out_1744 = 109, - dns_sizecounter_out_1760 = 110, - dns_sizecounter_out_1776 = 111, - dns_sizecounter_out_1792 = 112, - dns_sizecounter_out_1808 = 113, - dns_sizecounter_out_1824 = 114, - dns_sizecounter_out_1840 = 115, - dns_sizecounter_out_1856 = 116, - dns_sizecounter_out_1872 = 117, - dns_sizecounter_out_1888 = 118, - dns_sizecounter_out_1904 = 119, - dns_sizecounter_out_1920 = 120, - dns_sizecounter_out_1936 = 121, - dns_sizecounter_out_1952 = 122, - dns_sizecounter_out_1968 = 123, - dns_sizecounter_out_1984 = 124, - dns_sizecounter_out_2000 = 125, - dns_sizecounter_out_2016 = 126, - dns_sizecounter_out_2032 = 127, - dns_sizecounter_out_2048 = 128, - dns_sizecounter_out_2064 = 129, - dns_sizecounter_out_2080 = 130, - dns_sizecounter_out_2096 = 131, - dns_sizecounter_out_2112 = 132, - dns_sizecounter_out_2128 = 133, - dns_sizecounter_out_2144 = 134, - dns_sizecounter_out_2160 = 135, - dns_sizecounter_out_2176 = 136, - dns_sizecounter_out_2192 = 137, - dns_sizecounter_out_2208 = 138, - dns_sizecounter_out_2224 = 139, - dns_sizecounter_out_2240 = 140, - dns_sizecounter_out_2256 = 141, - dns_sizecounter_out_2272 = 142, - dns_sizecounter_out_2288 = 143, - dns_sizecounter_out_2304 = 144, - dns_sizecounter_out_2320 = 145, - dns_sizecounter_out_2336 = 146, - dns_sizecounter_out_2352 = 147, - dns_sizecounter_out_2368 = 148, - dns_sizecounter_out_2384 = 149, - dns_sizecounter_out_2400 = 150, - dns_sizecounter_out_2416 = 151, - dns_sizecounter_out_2432 = 152, - dns_sizecounter_out_2448 = 153, - dns_sizecounter_out_2464 = 154, - dns_sizecounter_out_2480 = 155, - dns_sizecounter_out_2496 = 156, - dns_sizecounter_out_2512 = 157, - dns_sizecounter_out_2528 = 158, - dns_sizecounter_out_2544 = 159, - dns_sizecounter_out_2560 = 160, - dns_sizecounter_out_2576 = 161, - dns_sizecounter_out_2592 = 162, - dns_sizecounter_out_2608 = 163, - dns_sizecounter_out_2624 = 164, - dns_sizecounter_out_2640 = 165, - dns_sizecounter_out_2656 = 166, - dns_sizecounter_out_2672 = 167, - dns_sizecounter_out_2688 = 168, - dns_sizecounter_out_2704 = 169, - dns_sizecounter_out_2720 = 170, - dns_sizecounter_out_2736 = 171, - dns_sizecounter_out_2752 = 172, - dns_sizecounter_out_2768 = 173, - dns_sizecounter_out_2784 = 174, - dns_sizecounter_out_2800 = 175, - dns_sizecounter_out_2816 = 176, - dns_sizecounter_out_2832 = 177, - dns_sizecounter_out_2848 = 178, - dns_sizecounter_out_2864 = 179, - dns_sizecounter_out_2880 = 180, - dns_sizecounter_out_2896 = 181, - dns_sizecounter_out_2912 = 182, - dns_sizecounter_out_2928 = 183, - dns_sizecounter_out_2944 = 184, - dns_sizecounter_out_2960 = 185, - dns_sizecounter_out_2976 = 186, - dns_sizecounter_out_2992 = 187, - dns_sizecounter_out_3008 = 188, - dns_sizecounter_out_3024 = 189, - dns_sizecounter_out_3040 = 190, - dns_sizecounter_out_3056 = 191, - dns_sizecounter_out_3072 = 192, - dns_sizecounter_out_3088 = 193, - dns_sizecounter_out_3104 = 194, - dns_sizecounter_out_3120 = 195, - dns_sizecounter_out_3136 = 196, - dns_sizecounter_out_3152 = 197, - dns_sizecounter_out_3168 = 198, - dns_sizecounter_out_3184 = 199, - dns_sizecounter_out_3200 = 200, - dns_sizecounter_out_3216 = 201, - dns_sizecounter_out_3232 = 202, - dns_sizecounter_out_3248 = 203, - dns_sizecounter_out_3264 = 204, - dns_sizecounter_out_3280 = 205, - dns_sizecounter_out_3296 = 206, - dns_sizecounter_out_3312 = 207, - dns_sizecounter_out_3328 = 208, - dns_sizecounter_out_3344 = 209, - dns_sizecounter_out_3360 = 210, - dns_sizecounter_out_3376 = 211, - dns_sizecounter_out_3392 = 212, - dns_sizecounter_out_3408 = 213, - dns_sizecounter_out_3424 = 214, - dns_sizecounter_out_3440 = 215, - dns_sizecounter_out_3456 = 216, - dns_sizecounter_out_3472 = 217, - dns_sizecounter_out_3488 = 218, - dns_sizecounter_out_3504 = 219, - dns_sizecounter_out_3520 = 220, - dns_sizecounter_out_3536 = 221, - dns_sizecounter_out_3552 = 222, - dns_sizecounter_out_3568 = 223, - dns_sizecounter_out_3584 = 224, - dns_sizecounter_out_3600 = 225, - dns_sizecounter_out_3616 = 226, - dns_sizecounter_out_3632 = 227, - dns_sizecounter_out_3648 = 228, - dns_sizecounter_out_3664 = 229, - dns_sizecounter_out_3680 = 230, - dns_sizecounter_out_3696 = 231, - dns_sizecounter_out_3712 = 232, - dns_sizecounter_out_3728 = 233, - dns_sizecounter_out_3744 = 234, - dns_sizecounter_out_3760 = 235, - dns_sizecounter_out_3776 = 236, - dns_sizecounter_out_3792 = 237, - dns_sizecounter_out_3808 = 238, - dns_sizecounter_out_3824 = 239, - dns_sizecounter_out_3840 = 240, - dns_sizecounter_out_3856 = 241, - dns_sizecounter_out_3872 = 242, - dns_sizecounter_out_3888 = 243, - dns_sizecounter_out_3904 = 244, - dns_sizecounter_out_3920 = 245, - dns_sizecounter_out_3936 = 246, - dns_sizecounter_out_3952 = 247, - dns_sizecounter_out_3968 = 248, - dns_sizecounter_out_3984 = 249, - dns_sizecounter_out_4000 = 250, - dns_sizecounter_out_4016 = 251, - dns_sizecounter_out_4032 = 252, - dns_sizecounter_out_4048 = 253, - dns_sizecounter_out_4064 = 254, - dns_sizecounter_out_4080 = 255, - dns_sizecounter_out_4096 = 256, - - dns_sizecounter_out_max = 257 -}; - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); -/*%< - * Create a server object with default settings. - * This function either succeeds or causes the program to exit - * with a fatal error. - */ - -void -ns_server_destroy(ns_server_t **serverp); -/*%< - * Destroy a server object, freeing its memory. - */ - -void -ns_server_reloadwanted(ns_server_t *server); -/*%< - * Inform a server that a reload is wanted. This function - * may be called asynchronously, from outside the server's task. - * If a reload is already scheduled or in progress, the call - * is ignored. - */ - -void -ns_server_scan_interfaces(ns_server_t *server); -/*%< - * Trigger a interface scan. - * Must only be called when running under server->task. - */ - -void -ns_server_flushonshutdown(ns_server_t *server, bool flush); -/*%< - * Inform the server that the zones should be flushed to disk on shutdown. - */ - -isc_result_t -ns_server_reloadcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "reload" command from the command channel. - */ - -isc_result_t -ns_server_reconfigcommand(ns_server_t *server); -/*%< - * Act on a "reconfig" command from the command channel. - */ - -isc_result_t -ns_server_notifycommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "notify" command from the command channel. - */ - -isc_result_t -ns_server_refreshcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "refresh" command from the command channel. - */ - -isc_result_t -ns_server_retransfercommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "retransfer" command from the command channel. - */ - -isc_result_t -ns_server_togglequerylog(ns_server_t *server, isc_lex_t *lex); -/*%< - * Enable/disable logging of queries. (Takes "yes" or "no" argument, - * but can also be used as a toggle for backward comptibility.) - */ - -/*% - * Save the current NTAs for all views to files. - */ -isc_result_t -ns_server_saventa(ns_server_t *server); - -/*% - * Load NTAs for all views from files. - */ -isc_result_t -ns_server_loadnta(ns_server_t *server); - -/*% - * Dump the current statistics to the statistics file. - */ -isc_result_t -ns_server_dumpstats(ns_server_t *server); - -/*% - * Dump the current cache to the dump file. - */ -isc_result_t -ns_server_dumpdb(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump the current security roots to the secroots file. - */ -isc_result_t -ns_server_dumpsecroots(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); - -/*% - * Change or increment the server debug level. - */ -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, isc_lex_t *lex); - -/*% - * Flush the server's cache(s) - */ -isc_result_t -ns_server_flushcache(ns_server_t *server, isc_lex_t *lex); - -/*% - * Flush a particular name from the server's cache. If 'tree' is false, - * also flush the name from the ADB and badcache. If 'tree' is true, also - * flush all the names under the specified name. - */ -isc_result_t -ns_server_flushnode(ns_server_t *server, isc_lex_t *lex, - bool tree); - -/*% - * Report the server's status. - */ -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t **text); - -/*% - * Report a list of dynamic and static tsig keys, per view. - */ -isc_result_t -ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text); - -/*% - * Delete a specific key (with optional view). - */ -isc_result_t -ns_server_tsigdelete(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); - -/*% - * Enable or disable updates for a zone. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, bool freeze, - isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump zone updates to disk, optionally removing the journal file - */ -isc_result_t -ns_server_sync(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Update a zone's DNSKEY set from the key repository. If - * the command that triggered the call to this function was "sign", - * then force a full signing of the zone. If it was "loadkeys", - * then don't sign the zone; any needed changes to signatures can - * take place incrementally. - */ -isc_result_t -ns_server_rekey(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump the current recursive queries. - */ -isc_result_t -ns_server_dumprecursing(ns_server_t *server); - -/*% - * Maintain a list of dispatches that require reserved ports. - */ -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr); - -/*% - * Enable or disable dnssec validation. - */ -isc_result_t -ns_server_validation(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Add a zone to a running process, or modify an existing zone - */ -isc_result_t -ns_server_changezone(ns_server_t *server, char *command, isc_buffer_t **text); - -/*% - * Deletes a zone from a running process - */ -isc_result_t -ns_server_delzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Show current configuration for a given zone - */ -isc_result_t -ns_server_showzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Lists the status of the signing records for a given zone. - */ -isc_result_t -ns_server_signing(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Lists status information for a given zone (e.g., name, type, files, - * load time, expiry, etc). - */ -isc_result_t -ns_server_zonestatus(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Adds/updates a Negative Trust Anchor (NTA) for a specified name and - * duration, in a particular view if specified, or in all views. - */ -isc_result_t -ns_server_nta(ns_server_t *server, isc_lex_t *lex, bool readonly, - isc_buffer_t **text); - -/*% - * Generates a test sequence that is only for use in system tests. The - * argument is the size of required output in bytes. - */ -isc_result_t -ns_server_testgen(isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Force fefresh or print status for managed keys zones. - */ -isc_result_t -ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Close and reopen DNSTAP output file. - */ -isc_result_t -ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - - -/*% - * Control whether stale answers are served or not when configured in - * named.conf. - */ -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -#endif /* NAMED_SERVER_H */ diff --git a/bin/named-pkcs11/include/named/sortlist.h b/bin/named-pkcs11/include/named/sortlist.h deleted file mode 100644 index 0c4e17d..0000000 --- a/bin/named-pkcs11/include/named/sortlist.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SORTLIST_H -#define NAMED_SORTLIST_H 1 - -/*! \file */ - -#include - -#include - -/*% - * Type for callback functions that rank addresses. - */ -typedef int -(*dns_addressorderfunc_t)(const isc_netaddr_t *address, const void *arg); - -/*% - * Return value type for setup_sortlist. - */ -typedef enum { - NS_SORTLISTTYPE_NONE, - NS_SORTLISTTYPE_1ELEMENT, - NS_SORTLISTTYPE_2ELEMENT -} ns_sortlisttype_t; - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * - * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and - * make '*argp' point to the matching subelement. - * - * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and - * make '*argp' point to ACL that forms the second element. - * - * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' - * to NULL. - */ - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', the matching element - * of a 1-element top-level sortlist statement. - */ - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', a topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * If a sortlist statement applies, return in '*orderp' a pointer to a function - * for ranking network addresses based on that sortlist statement, and in - * '*argp' an argument to pass to said function. If no sortlist statement - * applies, set '*orderp' and '*argp' to NULL. - */ - -#endif /* NAMED_SORTLIST_H */ diff --git a/bin/named-pkcs11/include/named/statschannel.h b/bin/named-pkcs11/include/named/statschannel.h deleted file mode 100644 index c107c29..0000000 --- a/bin/named-pkcs11/include/named/statschannel.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_STATSCHANNEL_H -#define NAMED_STATSCHANNEL_H 1 - -/*! \file - * \brief - * The statistics channels built-in the name server. - */ - -#include - -#include - -#include - -#define NS_STATSCHANNEL_HTTPPORT 80 - -isc_result_t -ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx); -/*%< - * [Re]configure the statistics channels. - * - * If it is no longer there but was previously configured, destroy - * it here. - * - * If the IP address or port has changed, destroy the old server - * and create a new one. - */ - - -void -ns_statschannels_shutdown(ns_server_t *server); -/*%< - * Initiate shutdown of all the statistics channel listeners. - */ - -isc_result_t -ns_stats_dump(ns_server_t *server, FILE *fp); -/*%< - * Dump statistics counters managed by the server to the file fp. - */ - -#endif /* NAMED_STATSCHANNEL_H */ diff --git a/bin/named-pkcs11/include/named/tkeyconf.h b/bin/named-pkcs11/include/named/tkeyconf.h deleted file mode 100644 index 7c2d8a8..0000000 --- a/bin/named-pkcs11/include/named/tkeyconf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_TKEYCONF_H -#define NS_TKEYCONF_H 1 - -/*! \file */ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); -/*%< - * Create a TKEY context and configure it, including the default DH key - * and default domain, according to 'options'. - * - * Requires: - *\li 'cfg' is a valid configuration options object. - *\li 'mctx' is not NULL - *\li 'ectx' is not NULL - *\li 'tctx' is not NULL - *\li '*tctx' is NULL - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TKEYCONF_H */ diff --git a/bin/named-pkcs11/include/named/tsigconf.h b/bin/named-pkcs11/include/named/tsigconf.h deleted file mode 100644 index 87ddc5e..0000000 --- a/bin/named-pkcs11/include/named/tsigconf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_TSIGCONF_H -#define NS_TSIGCONF_H 1 - -/*! \file */ - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/*%< - * Create a TSIG key ring and configure it according to the 'key' - * statements in the global and view configuration objects. - * - * Requires: - * \li 'config' is not NULL. - * \li 'vconfig' is not NULL. - * \li 'mctx' is not NULL - * \li 'ringp' is not NULL, and '*ringp' is NULL - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TSIGCONF_H */ diff --git a/bin/named-pkcs11/include/named/types.h b/bin/named-pkcs11/include/named/types.h deleted file mode 100644 index 8a045e0..0000000 --- a/bin/named-pkcs11/include/named/types.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_TYPES_H -#define NAMED_TYPES_H 1 - -/*! \file */ - -#include - -typedef struct ns_cache ns_cache_t; -typedef ISC_LIST(ns_cache_t) ns_cachelist_t; -typedef struct ns_client ns_client_t; -typedef struct ns_clientmgr ns_clientmgr_t; -typedef struct ns_query ns_query_t; -typedef struct ns_server ns_server_t; -typedef struct ns_xmld ns_xmld_t; -typedef struct ns_xmldmgr ns_xmldmgr_t; -typedef struct ns_interface ns_interface_t; -typedef struct ns_interfacemgr ns_interfacemgr_t; -typedef struct ns_lwresd ns_lwresd_t; -typedef struct ns_lwreslistener ns_lwreslistener_t; -typedef struct ns_lwdclient ns_lwdclient_t; -typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; -typedef struct ns_lwsearchlist ns_lwsearchlist_t; -typedef struct ns_lwsearchctx ns_lwsearchctx_t; -typedef struct ns_controls ns_controls_t; -typedef struct ns_dispatch ns_dispatch_t; -typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; -typedef struct ns_statschannel ns_statschannel_t; -typedef ISC_LIST(ns_statschannel_t) ns_statschannellist_t; -typedef struct ns_altsecret ns_altsecret_t; -typedef ISC_LIST(ns_altsecret_t) ns_altsecretlist_t; - -typedef enum { - ns_cookiealg_aes, - ns_cookiealg_sha1, - ns_cookiealg_sha256, - ns_cookiealg_siphash24 -} ns_cookiealg_t; - -#define NS_COOKIE_VERSION_1 1 - -#endif /* NAMED_TYPES_H */ diff --git a/bin/named-pkcs11/include/named/update.h b/bin/named-pkcs11/include/named/update.h deleted file mode 100644 index 484ad95..0000000 --- a/bin/named-pkcs11/include/named/update.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_UPDATE_H -#define NAMED_UPDATE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * RFC2136 Dynamic Update - */ - -/*** - *** Imports - ***/ - -#include -#include - -/*** - *** Types. - ***/ - -/*** - *** Functions - ***/ - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult); - -#endif /* NAMED_UPDATE_H */ diff --git a/bin/named-pkcs11/include/named/xfrout.h b/bin/named-pkcs11/include/named/xfrout.h deleted file mode 100644 index a0fc886..0000000 --- a/bin/named-pkcs11/include/named/xfrout.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_XFROUT_H -#define NAMED_XFROUT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * Outgoing zone transfers (AXFR + IXFR). - */ - -/*** - *** Functions - ***/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); - -#endif /* NAMED_XFROUT_H */ diff --git a/bin/named-pkcs11/include/named/zoneconf.h b/bin/named-pkcs11/include/named/zoneconf.h deleted file mode 100644 index a5d367b..0000000 --- a/bin/named-pkcs11/include/named/zoneconf.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_ZONECONF_H -#define NS_ZONECONF_H 1 - -/*! \file */ - -#include -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone, dns_zone_t *raw); -/*%< - * Configure or reconfigure a zone according to the named.conf - * data in 'cctx' and 'czone'. - * - * The zone origin is not configured, it is assumed to have been set - * at zone creation time. - * - * Require: - * \li 'lctx' to be initialized or NULL. - * \li 'cctx' to be initialized or NULL. - * \li 'ac' to point to an initialized ns_aclconfctx_t. - * \li 'czone' to be initialized. - * \li 'zone' to be initialized. - */ - -bool -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig); -/*%< - * If 'zone' can be safely reconfigured according to the configuration - * data in 'zconfig', return true. If the configuration data is so - * different from the current zone state that the zone needs to be destroyed - * and recreated, return false. - */ - -isc_result_t -ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, - dns_rdataclass_t rdclass, dns_name_t *name); -/*%> - * configure a DLZ zone, setting up the database methods and calling - * postload to load the origin values - * - * Require: - * \li 'dlzdatabase' to be a valid dlz database - * \li 'zone' to be initialized. - * \li 'rdclass' to be a valid rdataclass - * \li 'name' to be a valid zone origin name - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_ZONECONF_H */ diff --git a/bin/named-pkcs11/interfacemgr.c b/bin/named-pkcs11/interfacemgr.c deleted file mode 100644 index e12fad9..0000000 --- a/bin/named-pkcs11/interfacemgr.c +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_NET_ROUTE_H -#include -#if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR) -#define USE_ROUTE_SOCKET 1 -#define ROUTE_SOCKET_PROTOCOL PF_ROUTE -#define MSGHDR rt_msghdr -#define MSGTYPE rtm_type -#endif -#endif - -#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) -#include -#include -#if defined(RTM_NEWADDR) && defined(RTM_DELADDR) -#define USE_ROUTE_SOCKET 1 -#define ROUTE_SOCKET_PROTOCOL PF_NETLINK -#define MSGHDR nlmsghdr -#define MSGTYPE nlmsg_type -#endif -#endif - -#ifdef TUNE_LARGE -#define UDPBUFFERS 32768 -#else -#define UDPBUFFERS 1000 -#endif /* TUNE_LARGE */ - -#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') -#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) - -#define IFMGR_COMMON_LOGARGS \ - ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR - -/*% nameserver interface manager structure */ -struct ns_interfacemgr { - unsigned int magic; /*%< Magic number. */ - int references; - isc_mutex_t lock; - isc_mem_t * mctx; /*%< Memory context. */ - isc_taskmgr_t * taskmgr; /*%< Task manager. */ - isc_socketmgr_t * socketmgr; /*%< Socket manager. */ - dns_dispatchmgr_t * dispatchmgr; - unsigned int generation; /*%< Current generation no. */ - ns_listenlist_t * listenon4; - ns_listenlist_t * listenon6; - dns_aclenv_t aclenv; /*%< Localhost/localnets ACLs */ - ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces. */ - ISC_LIST(isc_sockaddr_t) listenon; -#ifdef USE_ROUTE_SOCKET - isc_task_t * task; - isc_socket_t * route; - unsigned char buf[2048]; -#endif -}; - -static void -purge_old_interfaces(ns_interfacemgr_t *mgr); - -static void -clearlistenon(ns_interfacemgr_t *mgr); - -#ifdef USE_ROUTE_SOCKET -static void -route_event(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = NULL; - ns_interfacemgr_t *mgr = NULL; - isc_region_t r; - isc_result_t result; - struct MSGHDR *rtm; - bool done = true; - - UNUSED(task); - - REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); - mgr = event->ev_arg; - sevent = (isc_socketevent_t *)event; - - if (sevent->result != ISC_R_SUCCESS) { - if (sevent->result != ISC_R_CANCELED) - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "automatic interface scanning " - "terminated: %s", - isc_result_totext(sevent->result)); - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; - } - - rtm = (struct MSGHDR *)mgr->buf; -#ifdef RTM_VERSION - if (rtm->rtm_version != RTM_VERSION) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "automatic interface rescanning disabled: " - "rtm->rtm_version mismatch (%u != %u) " - "recompile required", rtm->rtm_version, - RTM_VERSION); - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; - } -#endif - - switch (rtm->MSGTYPE) { - case RTM_NEWADDR: - case RTM_DELADDR: - if (mgr->route != NULL && ns_g_server->interface_auto) - ns_server_scan_interfaces(ns_g_server); - break; - default: - break; - } - - LOCK(&mgr->lock); - if (mgr->route != NULL) { - /* - * Look for next route event. - */ - r.base = mgr->buf; - r.length = sizeof(mgr->buf); - result = isc_socket_recv(mgr->route, &r, 1, mgr->task, - route_event, mgr); - if (result == ISC_R_SUCCESS) - done = false; - } - UNLOCK(&mgr->lock); - - if (done) - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; -} -#endif - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - isc_task_t *task, ns_interfacemgr_t **mgrp) -{ - isc_result_t result; - ns_interfacemgr_t *mgr; - -#ifndef USE_ROUTE_SOCKET - UNUSED(task); -#endif - - REQUIRE(mctx != NULL); - REQUIRE(mgrp != NULL); - REQUIRE(*mgrp == NULL); - - mgr = isc_mem_get(mctx, sizeof(*mgr)); - if (mgr == NULL) - return (ISC_R_NOMEMORY); - - mgr->mctx = NULL; - isc_mem_attach(mctx, &mgr->mctx); - - result = isc_mutex_init(&mgr->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - - mgr->taskmgr = taskmgr; - mgr->socketmgr = socketmgr; - mgr->dispatchmgr = dispatchmgr; - mgr->generation = 1; - mgr->listenon4 = NULL; - mgr->listenon6 = NULL; - - ISC_LIST_INIT(mgr->interfaces); - ISC_LIST_INIT(mgr->listenon); - - /* - * The listen-on lists are initially empty. - */ - result = ns_listenlist_create(mctx, &mgr->listenon4); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); - - result = dns_aclenv_init(mctx, &mgr->aclenv); - if (result != ISC_R_SUCCESS) - goto cleanup_listenon; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - mgr->aclenv.geoip = ns_g_geoip; -#endif - -#ifdef USE_ROUTE_SOCKET - mgr->route = NULL; - result = isc_socket_create(mgr->socketmgr, ROUTE_SOCKET_PROTOCOL, - isc_sockettype_raw, &mgr->route); - switch (result) { - case ISC_R_NOPERM: - case ISC_R_SUCCESS: - case ISC_R_NOTIMPLEMENTED: - case ISC_R_FAMILYNOSUPPORT: - break; - default: - goto cleanup_aclenv; - } - - mgr->task = NULL; - if (mgr->route != NULL) - isc_task_attach(task, &mgr->task); - mgr->references = (mgr->route != NULL) ? 2 : 1; -#else - mgr->references = 1; -#endif - mgr->magic = IFMGR_MAGIC; - *mgrp = mgr; - -#ifdef USE_ROUTE_SOCKET - if (mgr->route != NULL) { - isc_region_t r = { mgr->buf, sizeof(mgr->buf) }; - - result = isc_socket_recv(mgr->route, &r, 1, mgr->task, - route_event, mgr); - if (result != ISC_R_SUCCESS) { - isc_task_detach(&mgr->task); - isc_socket_detach(&mgr->route); - ns_interfacemgr_detach(&mgr); - } - } -#endif - return (ISC_R_SUCCESS); - -#ifdef USE_ROUTE_SOCKET - cleanup_aclenv: - dns_aclenv_destroy(&mgr->aclenv); -#endif - cleanup_listenon: - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - cleanup_mem: - isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); - return (result); -} - -static void -ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - -#ifdef USE_ROUTE_SOCKET - if (mgr->route != NULL) - isc_socket_detach(&mgr->route); - if (mgr->task != NULL) - isc_task_detach(&mgr->task); -#endif - dns_aclenv_destroy(&mgr->aclenv); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - clearlistenon(mgr); - DESTROYLOCK(&mgr->lock); - mgr->magic = 0; - isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); -} - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { - return (&mgr->aclenv); -} - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { - REQUIRE(NS_INTERFACEMGR_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp) { - isc_result_t need_destroy = false; - ns_interfacemgr_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACEMGR_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = true; - UNLOCK(&target->lock); - if (need_destroy) - ns_interfacemgr_destroy(target); - *targetp = NULL; -} - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - /*% - * Shut down and detach all interfaces. - * By incrementing the generation count, we make purge_old_interfaces() - * consider all interfaces "old". - */ - mgr->generation++; -#ifdef USE_ROUTE_SOCKET - LOCK(&mgr->lock); - if (mgr->route != NULL) { - isc_socket_cancel(mgr->route, mgr->task, ISC_SOCKCANCEL_RECV); - isc_socket_detach(&mgr->route); - isc_task_detach(&mgr->task); - } - UNLOCK(&mgr->lock); -#endif - purge_old_interfaces(mgr); -} - - -static isc_result_t -ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret) -{ - ns_interface_t *ifp; - isc_result_t result; - int disp; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); - if (ifp == NULL) - return (ISC_R_NOMEMORY); - - ifp->mgr = NULL; - ifp->generation = mgr->generation; - ifp->addr = *addr; - ifp->flags = 0; - strlcpy(ifp->name, name, sizeof(ifp->name)); - ifp->clientmgr = NULL; - - result = isc_mutex_init(&ifp->lock); - if (result != ISC_R_SUCCESS) - goto lock_create_failure; - - result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, - ns_g_timermgr, - &ifp->clientmgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "ns_clientmgr_create() failed: %s", - isc_result_totext(result)); - goto clientmgr_create_failure; - } - - for (disp = 0; disp < MAX_UDP_DISPATCH; disp++) - ifp->udpdispatch[disp] = NULL; - - ifp->tcpsocket = NULL; - - /* - * Create a single TCP client object. It will replace itself - * with a new one as soon as it gets a connection, so the actual - * connections will be handled in parallel even though there is - * only one client initially. - */ - isc_refcount_init(&ifp->ntcpaccepting, 0); - isc_refcount_init(&ifp->ntcpactive, 0); - - ifp->nudpdispatch = 0; - - ifp->dscp = -1; - - ISC_LINK_INIT(ifp, link); - - ns_interfacemgr_attach(mgr, &ifp->mgr); - ISC_LIST_APPEND(mgr->interfaces, ifp, link); - - ifp->references = 1; - ifp->magic = IFACE_MAGIC; - *ifpret = ifp; - - return (ISC_R_SUCCESS); - - clientmgr_create_failure: - DESTROYLOCK(&ifp->lock); - - lock_create_failure: - ifp->magic = 0; - isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); - - return (ISC_R_UNEXPECTED); -} - -static isc_result_t -ns_interface_listenudp(ns_interface_t *ifp) { - isc_result_t result; - unsigned int attrs; - unsigned int attrmask; - int disp, i; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - if (isc_sockaddr_pf(&ifp->addr) == AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_NOLISTEN; - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - - ifp->nudpdispatch = ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH); - for (disp = 0; disp < ifp->nudpdispatch; disp++) { - result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr, - ns_g_socketmgr, - ns_g_taskmgr, &ifp->addr, - 4096, UDPBUFFERS, - 32768, 8219, 8237, - attrs, attrmask, - &ifp->udpdispatch[disp], - disp == 0 - ? NULL - : ifp->udpdispatch[0]); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "could not listen on UDP socket: %s", - isc_result_totext(result)); - goto udp_dispatch_failure; - } - - } - - result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch, - ifp, false); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "UDP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto addtodispatch_failure; - } - - return (ISC_R_SUCCESS); - - addtodispatch_failure: - for (i = disp - 1; i >= 0; i--) { - dns_dispatch_changeattributes(ifp->udpdispatch[i], 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&(ifp->udpdispatch[i])); - } - ifp->nudpdispatch = 0; - - udp_dispatch_failure: - return (result); -} - -static isc_result_t -ns_interface_accepttcp(ns_interface_t *ifp) { - isc_result_t result; - - /* - * Open a TCP socket. - */ - result = isc_socket_create(ifp->mgr->socketmgr, - isc_sockaddr_pf(&ifp->addr), - isc_sockettype_tcp, - &ifp->tcpsocket); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "creating TCP socket: %s", - isc_result_totext(result)); - goto tcp_socket_failure; - } - isc_socket_setname(ifp->tcpsocket, "dispatcher", NULL); -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(ifp->tcpsocket, true); -#endif - result = isc_socket_bind(ifp->tcpsocket, &ifp->addr, - ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "binding TCP socket: %s", - isc_result_totext(result)); - goto tcp_bind_failure; - } - - if (ifp->dscp != -1) - isc_socket_dscp(ifp->tcpsocket, ifp->dscp); - - result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "listening on TCP socket: %s", - isc_result_totext(result)); - goto tcp_listen_failure; - } - - /* - * If/when there a multiple filters listen to the - * result. - */ - (void)isc_socket_filter(ifp->tcpsocket, "dataready"); - - result = ns_clientmgr_createclients(ifp->clientmgr, 1, ifp, true); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "TCP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto accepttcp_failure; - } - return (ISC_R_SUCCESS); - - accepttcp_failure: - tcp_listen_failure: - tcp_bind_failure: - isc_socket_detach(&ifp->tcpsocket); - tcp_socket_failure: - return (result); -} - -static isc_result_t -ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret, - bool accept_tcp, isc_dscp_t dscp, - bool *addr_in_use) -{ - isc_result_t result; - ns_interface_t *ifp = NULL; - REQUIRE(ifpret != NULL && *ifpret == NULL); - REQUIRE(addr_in_use == NULL || *addr_in_use == false); - - result = ns_interface_create(mgr, addr, name, &ifp); - if (result != ISC_R_SUCCESS) - return (result); - - ifp->dscp = dscp; - - result = ns_interface_listenudp(ifp); - if (result != ISC_R_SUCCESS) { - if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) - *addr_in_use = true; - goto cleanup_interface; - } - - if (!ns_g_notcp && accept_tcp == true) { - result = ns_interface_accepttcp(ifp); - if (result != ISC_R_SUCCESS) { - if ((result == ISC_R_ADDRINUSE) && - (addr_in_use != NULL)) - *addr_in_use = true; - - /* - * XXXRTH We don't currently have a way to easily stop - * dispatch service, so we currently return - * ISC_R_SUCCESS (the UDP stuff will work even if TCP - * creation failed). This will be fixed later. - */ - result = ISC_R_SUCCESS; - } - } - *ifpret = ifp; - return (result); - - cleanup_interface: - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - ns_interface_detach(&ifp); - return (result); -} - -void -ns_interface_shutdown(ns_interface_t *ifp) { - if (ifp->clientmgr != NULL) - ns_clientmgr_destroy(&ifp->clientmgr); -} - -static void -ns_interface_destroy(ns_interface_t *ifp) { - isc_mem_t *mctx; - int disp; - - REQUIRE(NS_INTERFACE_VALID(ifp)); - - mctx = ifp->mgr->mctx; - - ns_interface_shutdown(ifp); - - for (disp = 0; disp < ifp->nudpdispatch; disp++) - if (ifp->udpdispatch[disp] != NULL) { - dns_dispatch_changeattributes(ifp->udpdispatch[disp], 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&(ifp->udpdispatch[disp])); - } - - if (ifp->tcpsocket != NULL) - isc_socket_detach(&ifp->tcpsocket); - - DESTROYLOCK(&ifp->lock); - - ns_interfacemgr_detach(&ifp->mgr); - - isc_refcount_destroy(&ifp->ntcpactive); - isc_refcount_destroy(&ifp->ntcpaccepting); - - ifp->magic = 0; - isc_mem_put(mctx, ifp, sizeof(*ifp)); -} - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target) { - REQUIRE(NS_INTERFACE_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interface_detach(ns_interface_t **targetp) { - isc_result_t need_destroy = false; - ns_interface_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACE_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = true; - UNLOCK(&target->lock); - if (need_destroy) - ns_interface_destroy(target); - *targetp = NULL; -} - -/*% - * Search the interface list for an interface whose address and port - * both match those of 'addr'. Return a pointer to it, or NULL if not found. - */ -static ns_interface_t * -find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - ns_interface_t *ifp; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; - ifp = ISC_LIST_NEXT(ifp, link)) { - if (isc_sockaddr_equal(&ifp->addr, addr)) - break; - } - return (ifp); -} - -/*% - * Remove any interfaces whose generation number is not the current one. - */ -static void -purge_old_interfaces(ns_interfacemgr_t *mgr) { - ns_interface_t *ifp, *next; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { - INSIST(NS_INTERFACE_VALID(ifp)); - next = ISC_LIST_NEXT(ifp, link); - if (ifp->generation != mgr->generation) { - char sabuf[256]; - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "no longer listening on %s", sabuf); - ns_interface_shutdown(ifp); - ns_interface_detach(&ifp); - } - } -} - -static isc_result_t -clearacl(isc_mem_t *mctx, dns_acl_t **aclp) { - dns_acl_t *newacl = NULL; - isc_result_t result; - result = dns_acl_create(mctx, 0, &newacl); - if (result != ISC_R_SUCCESS) - return (result); - dns_acl_detach(aclp); - dns_acl_attach(newacl, aclp); - dns_acl_detach(&newacl); - return (ISC_R_SUCCESS); -} - -static bool -listenon_is_ip6_any(ns_listenelt_t *elt) { - REQUIRE(elt && elt->acl); - return dns_acl_isany(elt->acl); -} - -static isc_result_t -setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) { - isc_result_t result; - unsigned int prefixlen; - isc_netaddr_t *netaddr; - - netaddr = &interface->address; - - /* First add localhost address */ - prefixlen = (netaddr->family == AF_INET) ? 32 : 128; - result = dns_iptable_addprefix(mgr->aclenv.localhost->iptable, - netaddr, prefixlen, true); - if (result != ISC_R_SUCCESS) - return (result); - - /* Then add localnets prefix */ - result = isc_netaddr_masktoprefixlen(&interface->netmask, - &prefixlen); - - /* Non contiguous netmasks not allowed by IPv6 arch. */ - if (result != ISC_R_SUCCESS && netaddr->family == AF_INET6) - return (result); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "omitting IPv4 interface %s from " - "localnets ACL: %s", interface->name, - isc_result_totext(result)); - return (ISC_R_SUCCESS); - } - - if (prefixlen == 0U) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "omitting %s interface %s from localnets ACL: " - "zero prefix length detected", - (netaddr->family == AF_INET) ? "IPv4" : "IPv6", - interface->name); - return (ISC_R_SUCCESS); - } - - result = dns_iptable_addprefix(mgr->aclenv.localnets->iptable, - netaddr, prefixlen, true); - if (result != ISC_R_SUCCESS) - return (result); - - return (ISC_R_SUCCESS); -} - -static void -setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, - in_port_t port) -{ - isc_sockaddr_t *addr; - isc_sockaddr_t *old; - - addr = isc_mem_get(mgr->mctx, sizeof(*addr)); - if (addr == NULL) - return; - - isc_sockaddr_fromnetaddr(addr, &interface->address, port); - - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(addr, old)) - break; - - if (old != NULL) - isc_mem_put(mgr->mctx, addr, sizeof(*addr)); - else - ISC_LIST_APPEND(mgr->listenon, addr, link); -} - -static void -clearlistenon(ns_interfacemgr_t *mgr) { - isc_sockaddr_t *old; - - old = ISC_LIST_HEAD(mgr->listenon); - while (old != NULL) { - ISC_LIST_UNLINK(mgr->listenon, old, link); - isc_mem_put(mgr->mctx, old, sizeof(*old)); - old = ISC_LIST_HEAD(mgr->listenon); - } -} - -static isc_result_t -do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - bool verbose) -{ - isc_interfaceiter_t *iter = NULL; - bool scan_ipv4 = false; - bool scan_ipv6 = false; - bool adjusting = false; - bool ipv6only = true; - bool ipv6pktinfo = true; - isc_result_t result; - isc_netaddr_t zero_address, zero_address6; - ns_listenelt_t *le; - isc_sockaddr_t listen_addr; - ns_interface_t *ifp; - bool log_explicit = false; - bool dolistenon; - char sabuf[ISC_SOCKADDR_FORMATSIZE]; - bool tried_listening; - bool all_addresses_in_use; - - if (ext_listen != NULL) - adjusting = true; - - if (isc_net_probeipv6() == ISC_R_SUCCESS) - scan_ipv6 = true; -#ifdef WANT_IPV6 - else if (!ns_g_disable6) - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv6 interfaces found"); -#endif - - if (isc_net_probeipv4() == ISC_R_SUCCESS) - scan_ipv4 = true; - else if (!ns_g_disable4) - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv4 interfaces found"); - - /* - * A special, but typical case; listen-on-v6 { any; }. - * When we can make the socket IPv6-only, open a single wildcard - * socket for IPv6 communication. Otherwise, make separate socket - * for each IPv6 address in order to avoid accepting IPv4 packets - * as the form of mapped addresses unintentionally unless explicitly - * allowed. - */ -#ifndef ISC_ALLOW_MAPPED - if (scan_ipv6 == true && - isc_net_probe_ipv6only() != ISC_R_SUCCESS) { - ipv6only = false; - log_explicit = true; - } -#endif - if (scan_ipv6 == true && - isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { - ipv6pktinfo = false; - log_explicit = true; - } - if (scan_ipv6 == true && ipv6only && ipv6pktinfo) { - for (le = ISC_LIST_HEAD(mgr->listenon6->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) { - struct in6_addr in6a; - - if (!listenon_is_ip6_any(le)) - continue; - - in6a = in6addr_any; - isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); - - ifp = find_matching_interface(mgr, &listen_addr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - if (le->dscp != -1 && ifp->dscp == -1) - ifp->dscp = le->dscp; - else if (le->dscp != ifp->dscp) { - isc_sockaddr_format(&listen_addr, - sabuf, - sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "%s: conflicting DSCP " - "values, using %d", - sabuf, ifp->dscp); - } - } else { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "listening on IPv6 " - "interfaces, port %u", - le->port); - result = ns_interface_setup(mgr, &listen_addr, - "", &ifp, - true, - le->dscp, - NULL); - if (result == ISC_R_SUCCESS) - ifp->flags |= NS_INTERFACEFLAG_ANYADDR; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "listening on all IPv6 " - "interfaces failed"); - /* Continue. */ - } - } - } - - isc_netaddr_any(&zero_address); - isc_netaddr_any6(&zero_address6); - - result = isc_interfaceiter_create(mgr->mctx, &iter); - if (result != ISC_R_SUCCESS) - return (result); - - if (adjusting == false) { - result = clearacl(mgr->mctx, &mgr->aclenv.localhost); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - result = clearacl(mgr->mctx, &mgr->aclenv.localnets); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - clearlistenon(mgr); - } - - tried_listening = false; - all_addresses_in_use = true; - for (result = isc_interfaceiter_first(iter); - result == ISC_R_SUCCESS; - result = isc_interfaceiter_next(iter)) - { - isc_interface_t interface; - ns_listenlist_t *ll; - unsigned int family; - - result = isc_interfaceiter_current(iter, &interface); - if (result != ISC_R_SUCCESS) - break; - - family = interface.address.family; - if (family != AF_INET && family != AF_INET6) - continue; - if (scan_ipv4 == false && family == AF_INET) - continue; - if (scan_ipv6 == false && family == AF_INET6) - continue; - - /* - * Test for the address being nonzero rather than testing - * INTERFACE_F_UP, because on some systems the latter - * follows the media state and we could end up ignoring - * the interface for an entire rescan interval due to - * a temporary media glitch at rescan time. - */ - if (family == AF_INET && - isc_netaddr_equal(&interface.address, &zero_address)) { - continue; - } - if (family == AF_INET6 && - isc_netaddr_equal(&interface.address, &zero_address6)) { - continue; - } - - if (adjusting == false) { - /* - * If running with -T fixedlocal, then we only - * want 127.0.0.1 and ::1 in the localhost ACL. - */ - if (ns_g_fixedlocal && - !isc_netaddr_isloopback(&interface.address)) - { - goto listenon; - } - - result = setup_locals(mgr, &interface); - if (result != ISC_R_SUCCESS) - goto ignore_interface; - } - - listenon: - ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; - dolistenon = true; - for (le = ISC_LIST_HEAD(ll->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) - { - int match; - bool ipv6_wildcard = false; - isc_netaddr_t listen_netaddr; - isc_sockaddr_t listen_sockaddr; - - /* - * Construct a socket address for this IP/port - * combination. - */ - if (family == AF_INET) { - isc_netaddr_fromin(&listen_netaddr, - &interface.address.type.in); - } else { - isc_netaddr_fromin6(&listen_netaddr, - &interface.address.type.in6); - isc_netaddr_setzone(&listen_netaddr, - interface.address.zone); - } - isc_sockaddr_fromnetaddr(&listen_sockaddr, - &listen_netaddr, - le->port); - - /* - * See if the address matches the listen-on statement; - * if not, ignore the interface. - */ - (void)dns_acl_match(&listen_netaddr, NULL, le->acl, - &mgr->aclenv, &match, NULL); - if (match <= 0) - continue; - - if (adjusting == false && dolistenon == true) { - setup_listenon(mgr, &interface, le->port); - dolistenon = false; - } - - /* - * The case of "any" IPv6 address will require - * special considerations later, so remember it. - */ - if (family == AF_INET6 && ipv6only && ipv6pktinfo && - listenon_is_ip6_any(le)) - ipv6_wildcard = true; - - /* - * When adjusting interfaces with extra a listening - * list, see if the address matches the extra list. - * If it does, and is also covered by a wildcard - * interface, we need to listen on the address - * explicitly. - */ - if (adjusting == true) { - ns_listenelt_t *ele; - - match = 0; - for (ele = ISC_LIST_HEAD(ext_listen->elts); - ele != NULL; - ele = ISC_LIST_NEXT(ele, link)) { - (void)dns_acl_match(&listen_netaddr, - NULL, ele->acl, - NULL, &match, NULL); - if (match > 0 && - (ele->port == le->port || - ele->port == 0)) - break; - else - match = 0; - } - if (ipv6_wildcard == true && match == 0) - continue; - } - - ifp = find_matching_interface(mgr, &listen_sockaddr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - if (le->dscp != -1 && ifp->dscp == -1) - ifp->dscp = le->dscp; - else if (le->dscp != ifp->dscp) { - isc_sockaddr_format(&listen_sockaddr, - sabuf, - sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "%s: conflicting DSCP " - "values, using %d", - sabuf, ifp->dscp); - } - } else { - bool addr_in_use = false; - - if (adjusting == false && - ipv6_wildcard == true) - continue; - - if (log_explicit && family == AF_INET6 && - !adjusting && listenon_is_ip6_any(le)) { - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : - ISC_LOG_DEBUG(1), - "IPv6 socket API is " - "incomplete; explicitly " - "binding to each IPv6 " - "address separately"); - log_explicit = false; - } - isc_sockaddr_format(&listen_sockaddr, - sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "%s" - "listening on %s interface " - "%s, %s", - (adjusting == true) ? - "additionally " : "", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name, sabuf); - - result = ns_interface_setup(mgr, - &listen_sockaddr, - interface.name, - &ifp, - (adjusting == true) ? - false : true, - le->dscp, - &addr_in_use); - - tried_listening = true; - if (!addr_in_use) - all_addresses_in_use = false; - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "creating %s interface " - "%s failed; interface " - "ignored", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name); - } - /* Continue. */ - } - - } - continue; - - ignore_interface: - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "ignoring %s interface %s: %s", - (family == AF_INET) ? "IPv4" : "IPv6", - interface.name, isc_result_totext(result)); - continue; - } - if (result != ISC_R_NOMORE) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "interface iteration failed: %s", - isc_result_totext(result)); - else - result = ((tried_listening && all_addresses_in_use) ? - ISC_R_ADDRINUSE : ISC_R_SUCCESS); - cleanup_iter: - isc_interfaceiter_destroy(&iter); - return (result); -} - -static isc_result_t -ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - bool verbose) -{ - isc_result_t result; - bool purge = true; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - mgr->generation++; /* Increment the generation count. */ - - result = do_scan(mgr, ext_listen, verbose); - if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) - purge = false; - - /* - * Now go through the interface list and delete anything that - * does not have the current generation number. This is - * how we catch interfaces that go away or change their - * addresses. - */ - if (purge) - purge_old_interfaces(mgr); - - /* - * Warn if we are not listening on any interface, unless - * we're in lwresd-only mode, in which case that is to - * be expected. - */ - if (ext_listen == NULL && - ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "not listening on any interfaces"); - } - - return (result); -} - -bool -ns_interfacemgr_islistening(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - return (ISC_LIST_EMPTY(mgr->interfaces) ? false : true); -} - -isc_result_t -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { - return (ns_interfacemgr_scan0(mgr, NULL, verbose)); -} - -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose) -{ - return (ns_interfacemgr_scan0(mgr, list, verbose)); -} - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_attach(value, &mgr->listenon4); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon6); - ns_listenlist_attach(value, &mgr->listenon6); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { - ns_interface_t *interface; - - LOCK(&mgr->lock); - interface = ISC_LIST_HEAD(mgr->interfaces); - while (interface != NULL) { - if (interface->clientmgr != NULL) - ns_client_dumprecursing(f, interface->clientmgr); - interface = ISC_LIST_NEXT(interface, link); - } - UNLOCK(&mgr->lock); -} - -bool -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - isc_sockaddr_t *old; - - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(old, addr)) - return (true); - return (false); -} diff --git a/bin/named-pkcs11/listenlist.c b/bin/named-pkcs11/listenlist.c deleted file mode 100644 index 289e2d5..0000000 --- a/bin/named-pkcs11/listenlist.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include - -#include - -#include - -static void -destroy(ns_listenlist_t *list); - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - dns_acl_t *acl, ns_listenelt_t **target) -{ - ns_listenelt_t *elt = NULL; - REQUIRE(target != NULL && *target == NULL); - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - elt->port = port; - elt->dscp = dscp; - elt->acl = acl; - *target = elt; - return (ISC_R_SUCCESS); -} - -void -ns_listenelt_destroy(ns_listenelt_t *elt) { - if (elt->acl != NULL) - dns_acl_detach(&elt->acl); - isc_mem_put(elt->mctx, elt, sizeof(*elt)); -} - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) { - ns_listenlist_t *list = NULL; - REQUIRE(target != NULL && *target == NULL); - list = isc_mem_get(mctx, sizeof(*list)); - if (list == NULL) - return (ISC_R_NOMEMORY); - list->mctx = mctx; - list->refcount = 1; - ISC_LIST_INIT(list->elts); - *target = list; - return (ISC_R_SUCCESS); -} - -static void -destroy(ns_listenlist_t *list) { - ns_listenelt_t *elt, *next; - for (elt = ISC_LIST_HEAD(list->elts); - elt != NULL; - elt = next) - { - next = ISC_LIST_NEXT(elt, link); - ns_listenelt_destroy(elt); - } - isc_mem_put(list->mctx, list, sizeof(*list)); -} - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) { - INSIST(source->refcount > 0); - source->refcount++; - *target = source; -} - -void -ns_listenlist_detach(ns_listenlist_t **listp) { - ns_listenlist_t *list = *listp; - INSIST(list->refcount > 0); - list->refcount--; - if (list->refcount == 0) - destroy(list); - *listp = NULL; -} - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - bool enabled, ns_listenlist_t **target) -{ - isc_result_t result; - dns_acl_t *acl = NULL; - ns_listenelt_t *elt = NULL; - ns_listenlist_t *list = NULL; - - REQUIRE(target != NULL && *target == NULL); - if (enabled) - result = dns_acl_any(mctx, &acl); - else - result = dns_acl_none(mctx, &acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_listenelt_create(mctx, port, dscp, acl, &elt); - if (result != ISC_R_SUCCESS) - goto cleanup_acl; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - goto cleanup_listenelt; - - ISC_LIST_APPEND(list->elts, elt, link); - - *target = list; - return (ISC_R_SUCCESS); - - cleanup_listenelt: - ns_listenelt_destroy(elt); - cleanup_acl: - dns_acl_detach(&acl); - cleanup: - return (result); -} diff --git a/bin/named-pkcs11/log.c b/bin/named-pkcs11/log.c deleted file mode 100644 index ea6f114..0000000 --- a/bin/named-pkcs11/log.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include - -#include - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/*% - * When adding a new category, be sure to add the appropriate - * \#define to and to update the list in - * bin/check/check-tool.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { "query-errors", 0 }, - { "trust-anchor-telemetry", 0 }, - { "serve-stale", 0 }, - { NULL, 0 } -}; - -/*% - * When adding a new module, be sure to add the appropriate - * \#define to . - */ -static isc_logmodule_t modules[] = { - { "main", 0 }, - { "client", 0 }, - { "server", 0 }, - { "query", 0 }, - { "interfacemgr", 0 }, - { "update", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "notify", 0 }, - { "control", 0 }, - { "lwresd", 0 }, - { NULL, 0 } -}; - -isc_result_t -ns_log_init(bool safe) { - isc_result_t result; - isc_logconfig_t *lcfg = NULL; - - ns_g_categories = categories; - ns_g_modules = modules; - - /* - * Setup a logging context. - */ - result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * named-checktool.c:setup_logging() needs to be kept in sync. - */ - isc_log_registercategories(ns_g_lctx, ns_g_categories); - isc_log_registermodules(ns_g_lctx, ns_g_modules); - isc_log_setcontext(ns_g_lctx); - dns_log_init(ns_g_lctx); - dns_log_setcontext(ns_g_lctx); - cfg_log_init(ns_g_lctx); - - if (safe) - result = ns_log_setsafechannels(lcfg); - else - result = ns_log_setdefaultchannels(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_log_setdefaultcategory(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); - - return (result); -} - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - /* - * By default, the logging library makes "default_debug" log to - * stderr. In BIND, we want to override this and log to named.run - * instead, unless the -g option was given. - */ - if (! ns_g_logstderr) { - destination.file.stream = NULL; - destination.file.name = "named.run"; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_DEBUGONLY); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (ns_g_logfile != NULL) { - destination.file.stream = NULL; - destination.file.name = ns_g_logfile; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_logfile", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_PRINTCATEGORY| - ISC_LOG_PRINTLEVEL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Set the initial debug level. - */ - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - if (! ns_g_logstderr) { - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TONULL, - ISC_LOG_DYNAMIC, - NULL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Setting the debug level to zero should get the output - * discarded a bit faster. - */ - isc_log_setdebuglevel(ns_g_lctx, 0); - } else { - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - } - - if (ns_g_logfile != NULL) { - destination.file.stream = NULL; - destination.file.name = ns_g_logfile; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_logfile", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_PRINTCATEGORY| - ISC_LOG_PRINTLEVEL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg) { - isc_result_t result = ISC_R_SUCCESS; - - result = isc_log_usechannel(lcfg, "default_debug", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (! ns_g_logstderr) { - if (ns_g_logfile != NULL) - result = isc_log_usechannel(lcfg, "default_logfile", - ISC_LOGCATEGORY_DEFAULT, - NULL); - else if (! ns_g_nosyslog) - result = isc_log_usechannel(lcfg, "default_syslog", - ISC_LOGCATEGORY_DEFAULT, - NULL); - } - - cleanup: - return (result); -} - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - result = isc_log_usechannel(lcfg, "null", - NS_LOGCATEGORY_UNMATCHED, NULL); - return (result); -} - -void -ns_log_shutdown(void) { - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); -} diff --git a/bin/named-pkcs11/logconf.c b/bin/named-pkcs11/logconf.c deleted file mode 100644 index c51e4ca..0000000 --- a/bin/named-pkcs11/logconf.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/*% - * Set up a logging category according to the named.conf data - * in 'ccat' and add it to 'logconfig'. - */ -static isc_result_t -category_fromconf(const cfg_obj_t *ccat, isc_logconfig_t *logconfig) { - isc_result_t result; - const char *catname; - isc_logcategory_t *category; - isc_logmodule_t *module; - const cfg_obj_t *destinations = NULL; - const cfg_listelt_t *element = NULL; - - catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name")); - category = isc_log_categorybyname(ns_g_lctx, catname); - if (category == NULL) { - cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR, - "unknown logging category '%s' ignored", - catname); - /* - * Allow further processing by returning success. - */ - return (ISC_R_SUCCESS); - } - - if (logconfig == NULL) - return (ISC_R_SUCCESS); - - module = NULL; - - destinations = cfg_tuple_get(ccat, "destinations"); - for (element = cfg_list_first(destinations); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - const char *channelname = cfg_obj_asstring(channel); - - result = isc_log_usechannel(logconfig, channelname, category, - module); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s': %s", channelname, - isc_result_totext(result)); - return (result); - } - } - return (ISC_R_SUCCESS); -} - -/*% - * Set up a logging channel according to the named.conf data - * in 'cchan' and add it to 'logconfig'. - */ -static isc_result_t -channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *logconfig) -{ - isc_result_t result; - isc_logdestination_t dest; - unsigned int type; - unsigned int flags = 0; - int level; - const char *channelname; - const cfg_obj_t *fileobj = NULL; - const cfg_obj_t *syslogobj = NULL; - const cfg_obj_t *nullobj = NULL; - const cfg_obj_t *stderrobj = NULL; - const cfg_obj_t *severity = NULL; - int i; - - channelname = cfg_obj_asstring(cfg_map_getname(channel)); - - (void)cfg_map_get(channel, "file", &fileobj); - (void)cfg_map_get(channel, "syslog", &syslogobj); - (void)cfg_map_get(channel, "null", &nullobj); - (void)cfg_map_get(channel, "stderr", &stderrobj); - - i = 0; - if (fileobj != NULL) - i++; - if (syslogobj != NULL) - i++; - if (nullobj != NULL) - i++; - if (stderrobj != NULL) - i++; - - if (i != 1) { - cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, - "channel '%s': exactly one of file, syslog, " - "null, and stderr must be present", channelname); - return (ISC_R_FAILURE); - } - - type = ISC_LOG_TONULL; - - if (fileobj != NULL) { - const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); - const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); - const cfg_obj_t *versionsobj = - cfg_tuple_get(fileobj, "versions"); - int32_t versions = ISC_LOG_ROLLNEVER; - isc_offset_t size = 0; - uint64_t maxoffset; - - /* - * isc_offset_t is a signed integer type, so the maximum - * value is all 1s except for the MSB. - */ - switch (sizeof(isc_offset_t)) { - case 4: - maxoffset = 0x7fffffffULL; - break; - case 8: - maxoffset = 0x7fffffffffffffffULL; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - type = ISC_LOG_TOFILE; - - if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) - versions = cfg_obj_asuint32(versionsobj); - if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && - strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) - versions = ISC_LOG_ROLLINFINITE; - if (sizeobj != NULL && - cfg_obj_isuint64(sizeobj) && - cfg_obj_asuint64(sizeobj) < maxoffset) - size = (isc_offset_t)cfg_obj_asuint64(sizeobj); - dest.file.stream = NULL; - dest.file.name = cfg_obj_asstring(pathobj); - dest.file.versions = versions; - dest.file.maximum_size = size; - } else if (syslogobj != NULL) { - int facility = LOG_DAEMON; - - type = ISC_LOG_TOSYSLOG; - - if (cfg_obj_isstring(syslogobj)) { - const char *facilitystr = cfg_obj_asstring(syslogobj); - (void)isc_syslog_facilityfromstring(facilitystr, - &facility); - } - dest.facility = facility; - } else if (stderrobj != NULL) { - type = ISC_LOG_TOFILEDESC; - dest.file.stream = stderr; - dest.file.name = NULL; - dest.file.versions = ISC_LOG_ROLLNEVER; - dest.file.maximum_size = 0; - } - - /* - * Munge flags. - */ - { - const cfg_obj_t *printcat = NULL; - const cfg_obj_t *printsev = NULL; - const cfg_obj_t *printtime = NULL; - const cfg_obj_t *buffered = NULL; - - (void)cfg_map_get(channel, "print-category", &printcat); - (void)cfg_map_get(channel, "print-severity", &printsev); - (void)cfg_map_get(channel, "print-time", &printtime); - (void)cfg_map_get(channel, "buffered", &buffered); - - if (printcat != NULL && cfg_obj_asboolean(printcat)) - flags |= ISC_LOG_PRINTCATEGORY; - if (printtime != NULL && cfg_obj_asboolean(printtime)) - flags |= ISC_LOG_PRINTTIME; - if (printsev != NULL && cfg_obj_asboolean(printsev)) - flags |= ISC_LOG_PRINTLEVEL; - if (buffered != NULL && cfg_obj_asboolean(buffered)) - flags |= ISC_LOG_BUFFERED; - } - - level = ISC_LOG_INFO; - if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { - if (cfg_obj_isstring(severity)) { - const char *str = cfg_obj_asstring(severity); - if (strcasecmp(str, "critical") == 0) - level = ISC_LOG_CRITICAL; - else if (strcasecmp(str, "error") == 0) - level = ISC_LOG_ERROR; - else if (strcasecmp(str, "warning") == 0) - level = ISC_LOG_WARNING; - else if (strcasecmp(str, "notice") == 0) - level = ISC_LOG_NOTICE; - else if (strcasecmp(str, "info") == 0) - level = ISC_LOG_INFO; - else if (strcasecmp(str, "dynamic") == 0) - level = ISC_LOG_DYNAMIC; - } else - /* debug */ - level = cfg_obj_asuint32(severity); - } - - if (logconfig == NULL) - result = ISC_R_SUCCESS; - else - result = isc_log_createchannel(logconfig, channelname, - type, level, &dest, flags); - - if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { - FILE *fp; - - /* - * Test to make sure that file is a plain file. - * Fix defect #22771 - */ - result = isc_file_isplainfile(dest.file.name); - if (result == ISC_R_SUCCESS || result == ISC_R_FILENOTFOUND) { - /* - * Test that the file can be opened, since - * isc_log_open() can't effectively report - * failures when called in isc_log_doit(). - */ - result = isc_stdio_open(dest.file.name, "a", &fp); - if (result != ISC_R_SUCCESS) { - if (logconfig != NULL && !ns_g_nosyslog) - syslog(LOG_ERR, - "isc_stdio_open '%s' failed: " - "%s", dest.file.name, - isc_result_totext(result)); - fprintf(stderr, - "isc_stdio_open '%s' failed: %s\n", - dest.file.name, - isc_result_totext(result)); - } else - (void)isc_stdio_close(fp); - goto done; - } - if (logconfig != NULL && !ns_g_nosyslog) - syslog(LOG_ERR, "isc_file_isplainfile '%s' failed: %s", - dest.file.name, isc_result_totext(result)); - fprintf(stderr, "isc_file_isplainfile '%s' failed: %s\n", - dest.file.name, isc_result_totext(result)); - } - - done: - return (result); -} - -isc_result_t -ns_log_configure(isc_logconfig_t *logconfig, const cfg_obj_t *logstmt) { - isc_result_t result; - const cfg_obj_t *channels = NULL; - const cfg_obj_t *categories = NULL; - const cfg_listelt_t *element; - bool default_set = false; - bool unmatched_set = false; - const cfg_obj_t *catname; - - if (logconfig != NULL) - CHECK(ns_log_setdefaultchannels(logconfig)); - - (void)cfg_map_get(logstmt, "channel", &channels); - for (element = cfg_list_first(channels); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - CHECK(channel_fromconf(channel, logconfig)); - } - - (void)cfg_map_get(logstmt, "category", &categories); - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *category = cfg_listelt_value(element); - CHECK(category_fromconf(category, logconfig)); - if (!default_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "default") == 0) - default_set = true; - } - if (!unmatched_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0) - unmatched_set = true; - } - } - - if (logconfig != NULL && !default_set) - CHECK(ns_log_setdefaultcategory(logconfig)); - - if (logconfig != NULL && !unmatched_set) - CHECK(ns_log_setunmatchedcategory(logconfig)); - - return (ISC_R_SUCCESS); - - cleanup: - return (result); -} diff --git a/bin/named-pkcs11/lwaddr.c b/bin/named-pkcs11/lwaddr.c deleted file mode 100644 index 50c43af..0000000 --- a/bin/named-pkcs11/lwaddr.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include - -#include - -#include - -/*% - * Convert addresses from lwres to isc format. - */ -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la) { - if (la->family != LWRES_ADDRTYPE_V4 && la->family != LWRES_ADDRTYPE_V6) - return (ISC_R_FAMILYNOSUPPORT); - - if (la->family == LWRES_ADDRTYPE_V4) { - struct in_addr ina; - memmove(&ina.s_addr, la->address, 4); - isc_netaddr_fromin(na, &ina); - } else { - struct in6_addr ina6; - memmove(&ina6.s6_addr, la->address, 16); - isc_netaddr_fromin6(na, &ina6); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port) -{ - isc_netaddr_t na; - isc_result_t result; - - result = lwaddr_netaddr_fromlwresaddr(&na, la); - if (result != ISC_R_SUCCESS) - return (result); - isc_sockaddr_fromnetaddr(sa, &na, port); - return (ISC_R_SUCCESS); -} - -/*% - * Convert addresses from isc to lwres format. - */ - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na) { - if (na->family != AF_INET && na->family != AF_INET6) - return (ISC_R_FAMILYNOSUPPORT); - - if (na->family == AF_INET) { - la->family = LWRES_ADDRTYPE_V4; - la->length = 4; - memmove(la->address, &na->type.in, 4); - } else { - la->family = LWRES_ADDRTYPE_V6; - la->length = 16; - memmove(la->address, &na->type.in6, 16); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa) { - isc_netaddr_t na; - isc_netaddr_fromsockaddr(&na, sa); - return (lwaddr_lwresaddr_fromnetaddr(la, &na)); -} diff --git a/bin/named-pkcs11/lwdclient.c b/bin/named-pkcs11/lwdclient.c deleted file mode 100644 index 13b8148..0000000 --- a/bin/named-pkcs11/lwdclient.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); - -void -ns_lwdclient_log(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_DEBUG(level), format, args); - va_end(args); -} - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, - isc_taskmgr_t *taskmgr) -{ - ns_lwresd_t *lwresd = listener->manager; - ns_lwdclientmgr_t *cm; - ns_lwdclient_t *client; - unsigned int i; - isc_result_t result; - - cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); - if (cm == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&cm->lock); - if (result != ISC_R_SUCCESS) - goto freecm; - - cm->listener = NULL; - ns_lwreslistener_attach(listener, &cm->listener); - cm->mctx = lwresd->mctx; - cm->sock = NULL; - isc_socket_attach(listener->sock, &cm->sock); - cm->view = lwresd->view; - cm->lwctx = NULL; - cm->task = NULL; - cm->flags = 0; - ISC_LINK_INIT(cm, link); - ISC_LIST_INIT(cm->idle); - ISC_LIST_INIT(cm->running); - - result = lwres_context_create(&cm->lwctx, cm->mctx, - ns__lwresd_memalloc, ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (result != ISC_R_SUCCESS) - goto errout; - - for (i = 0; i < nclients; i++) { - client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); - if (client != NULL) { - ns_lwdclient_log(50, "created client %p, manager %p", - client, cm); - ns_lwdclient_initialize(client, cm); - } - } - - /* - * If we could create no clients, clean up and return. - */ - if (ISC_LIST_EMPTY(cm->idle)) { - result = ISC_R_NOMEMORY; - goto errout; - } - - result = isc_task_create(taskmgr, 0, &cm->task); - if (result != ISC_R_SUCCESS) - goto errout; - isc_task_setname(cm->task, "lwdclient", NULL); - - /* - * This MUST be last, since there is no way to cancel an onshutdown... - */ - result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, - cm); - if (result != ISC_R_SUCCESS) - goto errout; - - ns_lwreslistener_linkcm(listener, cm); - - return (ISC_R_SUCCESS); - - errout: - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(lwresd->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (cm->task != NULL) - isc_task_detach(&cm->task); - - if (cm->lwctx != NULL) - lwres_context_destroy(&cm->lwctx); - - DESTROYLOCK(&cm->lock); - - freecm: - isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); - return (result); -} - -static void -lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - ns_lwreslistener_t *listener; - - LOCK(&cm->lock); - if (!SHUTTINGDOWN(cm)) { - UNLOCK(&cm->lock); - return; - } - - /* - * Run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (!ISC_LIST_EMPTY(cm->running)) { - UNLOCK(&cm->lock); - return; - } - - UNLOCK(&cm->lock); - - lwres_context_destroy(&cm->lwctx); - cm->view = NULL; - isc_socket_detach(&cm->sock); - isc_task_detach(&cm->task); - - DESTROYLOCK(&cm->lock); - - listener = cm->listener; - ns_lwreslistener_unlinkcm(listener, cm); - ns_lwdclient_log(50, "destroying manager %p", cm); - isc_mem_put(cm->mctx, cm, sizeof(*cm)); - ns_lwreslistener_detach(&listener); -} - -static void -process_request(ns_lwdclient_t *client) { - lwres_buffer_t b; - isc_result_t result; - - lwres_buffer_init(&b, client->buffer, client->recvlength); - lwres_buffer_add(&b, client->recvlength); - - result = lwres_lwpacket_parseheader(&b, &client->pkt); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, "invalid packet header received"); - goto restart; - } - - ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); - - switch (client->pkt.opcode) { - case LWRES_OPCODE_GETADDRSBYNAME: - ns_lwdclient_processgabn(client, &b); - return; - case LWRES_OPCODE_GETNAMEBYADDR: - ns_lwdclient_processgnba(client, &b); - return; - case LWRES_OPCODE_GETRDATABYNAME: - ns_lwdclient_processgrbn(client, &b); - return; - case LWRES_OPCODE_NOOP: - ns_lwdclient_processnoop(client, &b); - return; - default: - ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); - goto restart; - } - - /* - * Drop the packet. - */ - restart: - ns_lwdclient_log(50, "restarting client %p...", client); - ns_lwdclient_stateidle(client); -} - -void -ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - INSIST(dev->region.base == client->buffer); - INSIST(NS_LWDCLIENT_ISRECV(client)); - - NS_LWDCLIENT_SETRECVDONE(client); - - LOCK(&cm->lock); - INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - UNLOCK(&cm->lock); - - ns_lwdclient_log(50, - "event received: task %p, length %u, result %u (%s)", - task, dev->n, dev->result, - isc_result_totext(dev->result)); - - if (dev->result != ISC_R_SUCCESS) { - isc_event_free(&ev); - dev = NULL; - - /* - * Go idle. - */ - ns_lwdclient_stateidle(client); - - return; - } - - client->recvlength = dev->n; - client->address = dev->address; - if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->pktinfo = dev->pktinfo; - client->pktinfo_valid = true; - } else - client->pktinfo_valid = false; - isc_event_free(&ev); - dev = NULL; - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - - process_request(client); -} - -/* - * This function will start a new recv() on a socket for this client manager. - */ -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - isc_result_t result; - isc_region_t r; - bool destroy = false; - - - LOCK(&cm->lock); - if (SHUTTINGDOWN(cm)) { - destroy = true; - result = ISC_R_SUCCESS; - goto unlock; - } - - /* - * If a recv is already running, don't bother. - */ - if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) { - result = ISC_R_SUCCESS; - goto unlock; - } - - /* - * If we have no idle slots, just return success. - */ - client = ISC_LIST_HEAD(cm->idle); - if (client == NULL) { - result = ISC_R_SUCCESS; - goto unlock; - } - - INSIST(NS_LWDCLIENT_ISIDLE(client)); - - /* - * Set the flag to say there is a recv pending. If isc_socket_recv - * fails we will clear the flag otherwise it will be cleared by - * ns_lwdclient_recv. - */ - cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; - - /* - * Issue the recv. If it fails, return that it did. - */ - r.base = client->buffer; - r.length = LWRES_RECVLENGTH; - result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, - client); - if (result != ISC_R_SUCCESS) { - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - goto unlock; - } - - /* - * Remove the client from the idle list, and put it on the running - * list. - */ - NS_LWDCLIENT_SETRECV(client); - ISC_LIST_UNLINK(cm->idle, client, link); - ISC_LIST_APPEND(cm->running, client, link); - - unlock: - UNLOCK(&cm->lock); - - if (destroy) - lwdclientmgr_destroy(cm); - - return (result); -} - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { - ns_lwdclientmgr_t *cm = ev->ev_arg; - ns_lwdclient_t *client; - - REQUIRE(!SHUTTINGDOWN(cm)); - - ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", - task, cm); - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - LOCK(&cm->lock); - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - UNLOCK(&cm->lock); - - /* - * Cancel any pending I/O. - */ - isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); - - /* - * Run through the running client list and kill off any finds - * in progress. - */ - LOCK(&cm->lock); - client = ISC_LIST_HEAD(cm->running); - while (client != NULL) { - if (client->find != client->v4find - && client->find != client->v6find) - dns_adb_cancelfind(client->find); - if (client->v4find != NULL) - dns_adb_cancelfind(client->v4find); - if (client->v6find != NULL) - dns_adb_cancelfind(client->v6find); - client = ISC_LIST_NEXT(client, link); - } - - cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; - - UNLOCK(&cm->lock); - - isc_event_free(&ev); -} - -/* - * Do all the crap needed to move a client from the run queue to the idle - * queue. - */ -void -ns_lwdclient_stateidle(ns_lwdclient_t *client) { - ns_lwdclientmgr_t *cm; - isc_result_t result; - - cm = client->clientmgr; - - INSIST(client->sendbuf == NULL); - INSIST(client->sendlength == 0); - INSIST(client->arg == NULL); - INSIST(client->v4find == NULL); - INSIST(client->v6find == NULL); - - LOCK(&cm->lock); - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_PREPEND(cm->idle, client, link); - UNLOCK(&cm->lock); - - NS_LWDCLIENT_SETIDLE(client); - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); -} - -void -ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - UNUSED(task); - UNUSED(dev); - - INSIST(NS_LWDCLIENT_ISSEND(client)); - INSIST(client->sendbuf == dev->region.base); - - ns_lwdclient_log(50, "task %p for client %p got send-done event", - task, client); - - if (client->sendbuf != client->buffer) - lwres_context_freemem(cm->lwctx, client->sendbuf, - client->sendlength); - client->sendbuf = NULL; - client->sendlength = 0; - - ns_lwdclient_stateidle(client); - - isc_event_free(&ev); -} - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { - struct in6_pktinfo *pktinfo; - ns_lwdclientmgr_t *cm = client->clientmgr; - - if (client->pktinfo_valid) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, - client, &client->address, pktinfo)); -} - -void -ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { - client->clientmgr = cmgr; - ISC_LINK_INIT(client, link); - NS_LWDCLIENT_SETIDLE(client); - client->arg = NULL; - - client->recvlength = 0; - - client->sendbuf = NULL; - client->sendlength = 0; - - client->find = NULL; - client->v4find = NULL; - client->v6find = NULL; - client->find_wanted = 0; - - client->options = 0; - client->byaddr = NULL; - - client->lookup = NULL; - - client->pktinfo_valid = false; - - LOCK(&cmgr->lock); - ISC_LIST_APPEND(cmgr->idle, client, link); - UNLOCK(&cmgr->lock); -} diff --git a/bin/named-pkcs11/lwderror.c b/bin/named-pkcs11/lwderror.c deleted file mode 100644 index e219450..0000000 --- a/bin/named-pkcs11/lwderror.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -/*% - * Generate an error packet for the client, schedule a send, and put us in - * the SEND state. - * - * The client->pkt structure will be modified to form an error return. - * The receiver needs to verify that it is in fact an error, and do the - * right thing with it. The opcode will be unchanged. The result needs - * to be set before calling this function. - * - * The only change this code makes is to set the receive buffer size to the - * size we use, set the reply bit, and recompute any security information. - */ -void -ns_lwdclient_errorpktsend(ns_lwdclient_t *client, uint32_t _result) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t b; - - REQUIRE(NS_LWDCLIENT_ISRUNNING(client)); - - /* - * Since we are only sending the packet header, we can safely toss - * the receive buffer. This means we won't need to allocate space - * for sending an error reply. This is a Good Thing. - */ - client->pkt.length = LWRES_LWPACKET_LENGTH; - client->pkt.pktflags |= LWRES_LWPACKETFLAG_RESPONSE; - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = _result; - - lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH); - lwres = lwres_lwpacket_renderheader(&b, &client->pkt); - if (lwres != LWRES_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - r.base = client->buffer; - r.length = b.used; - client->sendbuf = client->buffer; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - NS_LWDCLIENT_SETSEND(client); -} diff --git a/bin/named-pkcs11/lwdgabn.c b/bin/named-pkcs11/lwdgabn.c deleted file mode 100644 index a999740..0000000 --- a/bin/named-pkcs11/lwdgabn.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define NEED_V4(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \ - && ((c)->v4find == NULL)) -#define NEED_V6(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \ - && ((c)->v6find == NULL)) - -static isc_result_t start_find(ns_lwdclient_t *); -static void restart_find(ns_lwdclient_t *); -static void init_gabn(ns_lwdclient_t *); - -/*% - * Destroy any finds. This can be used to "start over from scratch" and - * should only be called when events are _not_ being generated by the finds. - */ -static void -cleanup_gabn(ns_lwdclient_t *client) { - ns_lwdclient_log(50, "cleaning up client %p", client); - - if (client->v6find != NULL) { - if (client->v6find == client->v4find) - client->v6find = NULL; - else - dns_adb_destroyfind(&client->v6find); - } - if (client->v4find != NULL) - dns_adb_destroyfind(&client->v4find); -} - -static void -setup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) { - dns_adbaddrinfo_t *ai; - lwres_addr_t *addr; - int af; - const struct sockaddr *sa; - isc_result_t result; - - if (at == DNS_ADBFIND_INET) - af = AF_INET; - else - af = AF_INET6; - - ai = ISC_LIST_HEAD(find->list); - while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { - sa = &ai->sockaddr.type.sa; - if (sa->sa_family != af) - goto next; - - addr = &client->addrs[client->gabn.naddrs]; - - result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr); - if (result != ISC_R_SUCCESS) - goto next; - - ns_lwdclient_log(50, "adding address %p, family %d, length %d", - addr->address, addr->family, addr->length); - - client->gabn.naddrs++; - REQUIRE(!LWRES_LINK_LINKED(addr, link)); - LWRES_LIST_APPEND(client->gabn.addrs, addr, link); - - next: - ai = ISC_LIST_NEXT(ai, publink); - } -} - -typedef struct { - isc_netaddr_t address; - int rank; -} rankedaddress; - -static int -addr_compare(const void *av, const void *bv) { - const rankedaddress *a = (const rankedaddress *) av; - const rankedaddress *b = (const rankedaddress *) bv; - return (a->rank - b->rank); -} - -static void -sort_addresses(ns_lwdclient_t *client) { - unsigned int naddrs; - rankedaddress *addrs; - isc_netaddr_t remote; - dns_addressorderfunc_t order; - const void *arg; - ns_lwresd_t *lwresd = client->clientmgr->listener->manager; - unsigned int i; - isc_result_t result; - - naddrs = client->gabn.naddrs; - - if (naddrs <= 1 || lwresd->view->sortlist == NULL) - return; - - addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs); - if (addrs == NULL) - return; - - isc_netaddr_fromsockaddr(&remote, &client->address); - ns_sortlist_byaddrsetup(lwresd->view->sortlist, - &remote, &order, &arg); - if (order == NULL) { - isc_mem_put(lwresd->mctx, addrs, - sizeof(rankedaddress) * naddrs); - return; - } - for (i = 0; i < naddrs; i++) { - result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address, - &client->addrs[i]); - INSIST(result == ISC_R_SUCCESS); - addrs[i].rank = (*order)(&addrs[i].address, arg); - } - qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare); - for (i = 0; i < naddrs; i++) { - result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i], - &addrs[i].address); - INSIST(result == ISC_R_SUCCESS); - } - - isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs); -} - -static void -generate_reply(ns_lwdclient_t *client) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t lwb; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - lwb.base = NULL; - - ns_lwdclient_log(50, "generating gabn reply for client %p", client); - - /* - * We must make certain the client->find is not still active. - * If it is either the v4 or v6 answer, just set it to NULL and - * let the cleanup code destroy it. Otherwise, destroy it now. - */ - if (client->find == client->v4find || client->find == client->v6find) - client->find = NULL; - else - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - - /* - * perhaps there are some here? - */ - if (NEED_V6(client) && client->v4find != NULL) - client->v6find = client->v4find; - - /* - * Run through the finds we have and wire them up to the gabn - * structure. - */ - LWRES_LIST_INIT(client->gabn.addrs); - if (client->v4find != NULL) - setup_addresses(client, client->v4find, DNS_ADBFIND_INET); - if (client->v6find != NULL) - setup_addresses(client, client->v6find, DNS_ADBFIND_INET6); - - /* - * If there are no addresses, try the next element in the search - * path, if there are any more. Otherwise, fall through into - * the error handling code below. - */ - if (client->gabn.naddrs == 0) { - do { - result = ns_lwsearchctx_next(&client->searchctx); - if (result == ISC_R_SUCCESS) { - cleanup_gabn(client); - result = start_find(client); - if (result == ISC_R_SUCCESS) - return; - } - } while (result == ISC_R_SUCCESS); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - - /* - * If there are no addresses, return failure. - */ - if (client->gabn.naddrs != 0) - client->pkt.result = LWRES_R_SUCCESS; - else - client->pkt.result = LWRES_R_NOTFOUND; - - sort_addresses(client); - - lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - /* - * All done! - */ - cleanup_gabn(client); - - return; - - out: - cleanup_gabn(client); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -/* - * Take the current real name, move it to an alias slot (if any are - * open) then put this new name in as the real name for the target. - * - * Return success if it can be rendered, otherwise failure. Note that - * not having enough alias slots open is NOT a failure. - */ -static isc_result_t -add_alias(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - uint16_t naliases; - - b = client->recv_buffer; - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(dns_fixedname_name(&client->target_name), - true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Are there any open slots? - */ - naliases = client->gabn.naliases; - if (naliases < LWRES_MAX_ALIASES) { - client->gabn.aliases[naliases] = client->gabn.realname; - client->gabn.aliaslen[naliases] = client->gabn.realnamelen; - client->gabn.naliases++; - } - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *)(b.base) + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -store_realname(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - dns_name_t *tname; - - b = client->recv_buffer; - - tname = dns_fixedname_name(&client->target_name); - result = ns_lwsearchctx_current(&client->searchctx, tname); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(tname, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *) b.base + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static void -process_gabn_finddone(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - isc_eventtype_t evtype; - bool claimed; - - ns_lwdclient_log(50, "find done for task %p, client %p", task, client); - - evtype = ev->ev_type; - isc_event_free(&ev); - - /* - * No more info to be had? If so, we have all the good stuff - * right now, so we can render things. - */ - claimed = false; - if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { - if (NEED_V4(client)) { - client->v4find = client->find; - claimed = true; - } - if (NEED_V6(client)) { - client->v6find = client->find; - claimed = true; - } - if (client->find != NULL) { - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - } - generate_reply(client); - return; - } - - /* - * We probably don't need this find anymore. We're either going to - * reissue it, or an error occurred. Either way, we're done with - * it. - */ - if ((client->find != client->v4find) - && (client->find != client->v6find)) { - dns_adb_destroyfind(&client->find); - } else { - client->find = NULL; - } - - /* - * We have some new information we can gather. Run off and fetch - * it. - */ - if (evtype == DNS_EVENT_ADBMOREADDRESSES) { - restart_find(client); - return; - } - - /* - * An error or other strangeness happened. Drop this query. - */ - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -restart_find(ns_lwdclient_t *client) { - unsigned int options; - isc_result_t result; - bool claimed; - - ns_lwdclient_log(50, "starting find for client %p", client); - - /* - * Issue a find for the name contained in the request. We won't - * set the bit that says "anything is good enough" -- we want it - * all. - */ - options = 0; - options |= DNS_ADBFIND_WANTEVENT; - options |= DNS_ADBFIND_RETURNLAME; - - /* - * Set the bits up here to mark that we want this address family - * and that we do not currently have a find pending. We will - * set that bit again below if it turns out we will get an event. - */ - if (NEED_V4(client)) - options |= DNS_ADBFIND_INET; - if (NEED_V6(client)) - options |= DNS_ADBFIND_INET6; - - find_again: - INSIST(client->find == NULL); - result = dns_adb_createfind(client->clientmgr->view->adb, - client->clientmgr->task, - process_gabn_finddone, client, - dns_fixedname_name(&client->target_name), - dns_rootname, 0, options, 0, - dns_fixedname_name(&client->target_name), - client->clientmgr->view->dstport, - &client->find); - - /* - * Did we get an alias? If so, save it and re-issue the query. - */ - if (result == DNS_R_ALIAS) { - ns_lwdclient_log(50, "found alias, restarting query"); - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - result = add_alias(client); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, - "out of buffer space adding alias"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - goto find_again; - } - - ns_lwdclient_log(50, "find returned %d (%s)", result, - isc_result_totext(result)); - - /* - * Did we get an error? - */ - if (result != ISC_R_SUCCESS) { - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - - claimed = false; - - /* - * Did we get our answer to V4 addresses? - */ - if (NEED_V4(client) - && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { - ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", - client, client->find); - claimed = true; - client->v4find = client->find; - } - - /* - * Did we get our answer to V6 addresses? - */ - if (NEED_V6(client) - && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { - ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", - client, client->find); - claimed = true; - client->v6find = client->find; - } - - /* - * If we're going to get an event, set our internal pending flag - * and return. When we get an event back we'll do the right - * thing, basically by calling this function again, perhaps with a - * new target name. - * - * If we have both v4 and v6, and we are still getting an event, - * we have a programming error, so die hard. - */ - if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { - ns_lwdclient_log(50, "event will be sent"); - INSIST(client->v4find == NULL || client->v6find == NULL); - return; - } - ns_lwdclient_log(50, "no event will be sent"); - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - /* - * We seem to have everything we asked for, or at least we are - * able to respond with things we've learned. - */ - - generate_reply(client); -} - -static isc_result_t -start_find(ns_lwdclient_t *client) { - isc_result_t result; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gabn(client); - - result = store_realname(client); - if (result != ISC_R_SUCCESS) - return (result); - restart_find(client); - return (ISC_R_SUCCESS); - -} - -static void -init_gabn(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gabn.naliases = 0; - client->gabn.naddrs = 0; - client->gabn.realname = NULL; - client->gabn.aliases = client->aliases; - client->gabn.realnamelen = 0; - client->gabn.aliaslen = client->aliaslen; - LWRES_LIST_INIT(client->gabn.addrs); - client->gabn.base = NULL; - client->gabn.baselen = 0; - - /* - * Set up the internal buffer to point to the receive region. - */ - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -/* - * When we are called, we can be assured that: - * - * client->sockaddr contains the address we need to reply to, - * - * client->pkt contains the packet header data, - * - * the packet "checks out" overall -- any MD5 hashes or crypto - * bits have been verified, - * - * "b" points to the remaining data after the packet header - * was parsed off. - * - * We are in a the RECVDONE state. - * - * From this state we will enter the SEND state if we happen to have - * everything we need or we need to return an error packet, or to the - * FINDWAIT state if we need to look things up. - */ -void -ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { - isc_result_t result; - lwres_gabnrequest_t *req; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gabnrequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->target_name); - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, 0, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - client->find_wanted = req->addrtypes; - ns_lwdclient_log(50, "client %p looking for addrtypes %08x", - client, client->find_wanted); - - /* - * We no longer need to keep this around. - */ - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - /* - * Start the find. - */ - result = start_find(client); - if (result != ISC_R_SUCCESS) - goto out; - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-pkcs11/lwdgnba.c b/bin/named-pkcs11/lwdgnba.c deleted file mode 100644 index e827289..0000000 --- a/bin/named-pkcs11/lwdgnba.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include - -static void start_byaddr(ns_lwdclient_t *); - -static void -byaddr_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_byaddrevent_t *bevent; - int lwres; - lwres_buffer_t lwb; - dns_name_t *name; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_gnbaresponse_t *gnba; - uint16_t naliases; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); - - bevent = (dns_byaddrevent_t *)event; - gnba = &client->gnba; - - ns_lwdclient_log(50, "byaddr event result = %s", - isc_result_totext(bevent->result)); - - result = bevent->result; - if (result != ISC_R_SUCCESS) { - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - bevent = NULL; - - if (client->na.family != AF_INET6 || - (client->options & DNS_BYADDROPT_IPV6INT) != 0) { - if (result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET || - result == DNS_R_NXDOMAIN || - result == DNS_R_NXRRSET) - lwresult = LWRES_R_NOTFOUND; - else - lwresult = LWRES_R_FAILURE; - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - /* - * Fall back to ip6.int reverse if the default ip6.arpa - * fails. - */ - client->options |= DNS_BYADDROPT_IPV6INT; - - start_byaddr(client); - return; - } - - for (name = ISC_LIST_HEAD(bevent->names); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - { - b = client->recv_buffer; - - result = dns_name_totext(name, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwdclient_log(50, "found name '%.*s'", - (int)(client->recv_buffer.used - b.used), - (char *)(b.base) + b.used); - if (gnba->realname == NULL) { - gnba->realname = (char *)(b.base) + b.used; - gnba->realnamelen = client->recv_buffer.used - b.used; - } else { - naliases = gnba->naliases; - if (naliases >= LWRES_MAX_ALIASES) - break; - gnba->aliases[naliases] = (char *)(b.base) + b.used; - gnba->aliaslen[naliases] = - client->recv_buffer.used - b.used; - gnba->naliases++; - } - } - - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwres = lwres_gnbaresponse_render(cm->lwctx, - gnba, &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (client->byaddr != NULL) - dns_byaddr_destroy(&client->byaddr); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, - lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); -} - -static void -start_byaddr(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - - INSIST(client->byaddr == NULL); - - result = dns_byaddr_create(cm->mctx, &client->na, cm->view, - client->options, cm->task, byaddr_done, - client, &client->byaddr); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_gnba(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gnba.naliases = 0; - client->gnba.realname = NULL; - client->gnba.aliases = client->aliases; - client->gnba.realnamelen = 0; - client->gnba.aliaslen = client->aliaslen; - client->gnba.base = NULL; - client->gnba.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_gnbarequest_t *req; - isc_result_t result; - isc_sockaddr_t sa; - ns_lwdclientmgr_t *cm; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gnbarequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - - client->options = 0; - if (req->addr.family == LWRES_ADDRTYPE_V4) { - client->na.family = AF_INET; - if (req->addr.length != 4) - goto out; - memmove(&client->na.type.in, req->addr.address, 4); - } else if (req->addr.family == LWRES_ADDRTYPE_V6) { - client->na.family = AF_INET6; - if (req->addr.length != 16) - goto out; - memmove(&client->na.type.in6, req->addr.address, 16); - } else { - goto out; - } - isc_sockaddr_fromnetaddr(&sa, &client->na, 53); - - ns_lwdclient_log(50, "client %p looking for addrtype %08x", - client, req->addr.family); - - /* - * We no longer need to keep this around. - */ - lwres_gnbarequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gnba(client); - client->options = 0; - - /* - * Start the find. - */ - start_byaddr(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gnbarequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-pkcs11/lwdgrbn.c b/bin/named-pkcs11/lwdgrbn.c deleted file mode 100644 index 2295558..0000000 --- a/bin/named-pkcs11/lwdgrbn.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static void start_lookup(ns_lwdclient_t *); - -static isc_result_t -fill_array(int *pos, dns_rdataset_t *rdataset, - int size, unsigned char **rdatas, uint16_t *rdatalen) -{ - dns_rdata_t rdata; - isc_result_t result; - isc_region_t r; - - UNUSED(size); - - dns_rdata_init(&rdata); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - INSIST(*pos < size); - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - rdatas[*pos] = r.base; - rdatalen[*pos] = r.length; - dns_rdata_reset(&rdata); - (*pos)++; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - return (result); -} - -static isc_result_t -iterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, - isc_mem_t *mctx) -{ - int used = 0, count; - int size = 8, oldsize = 0; - unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; - uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; - dns_rdatasetiter_t *iter = NULL; - dns_rdataset_t set; - dns_ttl_t ttl = INT32_MAX; - uint32_t flags = LWRDATA_VALIDATED; - isc_result_t result = ISC_R_NOMEMORY; - - result = dns_db_allrdatasets(db, node, NULL, 0, &iter); - if (result != ISC_R_SUCCESS) - goto out; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - result = ISC_R_NOMEMORY; - dns_rdataset_init(&set); - dns_rdatasetiter_current(iter, &set); - - if (set.type != dns_rdatatype_rrsig) { - dns_rdataset_disassociate(&set); - continue; - } - - count = dns_rdataset_count(&set); - if (used + count > size) { - /* copy & reallocate */ - oldsize = size; - oldrdatas = rdatas; - oldlens = lens; - rdatas = NULL; - lens = NULL; - - size *= 2; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - memmove(rdatas, oldrdatas, used * sizeof(*rdatas)); - memmove(lens, oldlens, used * sizeof(*lens)); - isc_mem_put(mctx, oldrdatas, - oldsize * sizeof(*oldrdatas)); - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - oldrdatas = NULL; - oldlens = NULL; - } - if (set.ttl < ttl) - ttl = set.ttl; - if (set.trust != dns_trust_secure) - flags &= (~LWRDATA_VALIDATED); - result = fill_array(&used, &set, size, rdatas, lens); - dns_rdataset_disassociate(&set); - if (result != ISC_R_SUCCESS) - goto out; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - goto out; - dns_rdatasetiter_destroy(&iter); - - /* - * If necessary, shrink and copy the arrays. - */ - if (size != used) { - result = ISC_R_NOMEMORY; - newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); - if (newrdatas == NULL) - goto out; - newlens = isc_mem_get(mctx, used * sizeof(*lens)); - if (newlens == NULL) - goto out; - memmove(newrdatas, rdatas, used * sizeof(*rdatas)); - memmove(newlens, lens, used * sizeof(*lens)); - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - isc_mem_put(mctx, lens, size * sizeof(*lens)); - grbn->rdatas = newrdatas; - grbn->rdatalen = newlens; - } else { - grbn->rdatas = rdatas; - grbn->rdatalen = lens; - } - grbn->nrdatas = used; - grbn->ttl = ttl; - grbn->flags = flags; - return (ISC_R_SUCCESS); - - out: - dns_rdatasetiter_destroy(&iter); - if (rdatas != NULL) - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - if (lens != NULL) - isc_mem_put(mctx, lens, size * sizeof(*lens)); - if (oldrdatas != NULL) - isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); - if (oldlens != NULL) - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - if (newrdatas != NULL) - isc_mem_put(mctx, newrdatas, used * sizeof(*newrdatas)); - return (result); -} - -static void -lookup_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_lookupevent_t *levent; - lwres_buffer_t lwb; - dns_name_t *name; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_grbnresponse_t *grbn; - int i; - - REQUIRE(event != NULL); - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); - - levent = (dns_lookupevent_t *)event; - grbn = &client->grbn; - - ns_lwdclient_log(50, "lookup event result = %s", - isc_result_totext(levent->result)); - - result = levent->result; - if (result != ISC_R_SUCCESS) { - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - levent = NULL; - - switch (result) { - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - result = ns_lwsearchctx_next(&client->searchctx); - if (result != ISC_R_SUCCESS) - lwresult = LWRES_R_NOTFOUND; - else { - start_lookup(client); - return; - } - break; - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - lwresult = LWRES_R_TYPENOTFOUND; - break; - default: - lwresult = LWRES_R_FAILURE; - } - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - name = levent->name; - b = client->recv_buffer; - - grbn->flags = 0; - - grbn->nrdatas = 0; - grbn->rdatas = NULL; - grbn->rdatalen = NULL; - - grbn->nsigs = 0; - grbn->sigs = NULL; - grbn->siglen = NULL; - - result = dns_name_totext(name, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - grbn->realname = (char *)isc_buffer_used(&b); - grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - - isc_buffer_usedlength(&b); - ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, - grbn->realname); - - grbn->rdclass = cm->view->rdclass; - grbn->rdtype = client->rdtype; - - rdataset = levent->rdataset; - if (rdataset != NULL) { - /* The normal case */ - grbn->nrdatas = dns_rdataset_count(rdataset); - grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(unsigned char *)); - if (grbn->rdatas == NULL) - goto out; - grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(uint16_t)); - if (grbn->rdatalen == NULL) - goto out; - - i = 0; - result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, - grbn->rdatalen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nrdatas); - grbn->ttl = rdataset->ttl; - if (rdataset->trust == dns_trust_secure) - grbn->flags |= LWRDATA_VALIDATED; - } else { - /* The SIG query case */ - result = iterate_node(grbn, levent->db, levent->node, - cm->mctx); - if (result != ISC_R_SUCCESS) - goto out; - } - ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, - (grbn->nrdatas == 1) ? "" : "s"); - - sigrdataset = levent->sigrdataset; - if (sigrdataset != NULL) { - grbn->nsigs = dns_rdataset_count(sigrdataset); - grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(unsigned char *)); - if (grbn->sigs == NULL) - goto out; - grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(uint16_t)); - if (grbn->siglen == NULL) - goto out; - - i = 0; - result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, - grbn->siglen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nsigs); - ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, - (grbn->nsigs == 1) ? "" : "s"); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwresult = lwres_grbnresponse_render(cm->lwctx, - grbn, &client->pkt, &lwb); - if (lwresult != LWRES_R_SUCCESS) - goto out; - - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(uint16_t)); - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out2; - - NS_LWDCLIENT_SETSEND(client); - - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - - return; - - out: - if (grbn->rdatas != NULL) - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - if (grbn->rdatalen != NULL) - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(uint16_t)); - out2: - if (client->lookup != NULL) - dns_lookup_destroy(&client->lookup); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); - - isc_event_free(&event); - - ns_lwdclient_log(50, "error constructing getrrsetbyname response"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -start_lookup(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - dns_fixedname_t absname; - - cm = client->clientmgr; - - INSIST(client->lookup == NULL); - - dns_fixedname_init(&absname); - - /* - * Perform search across all search domains until success - * is returned. Return in case of failure. - */ - while (ns_lwsearchctx_current(&client->searchctx, - dns_fixedname_name(&absname)) != ISC_R_SUCCESS) { - if (ns_lwsearchctx_next(&client->searchctx) != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - } - - result = dns_lookup_create(cm->mctx, - dns_fixedname_name(&absname), - client->rdtype, cm->view, - client->options, cm->task, lookup_done, - client, &client->lookup); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_grbn(ns_lwdclient_t *client) { - client->grbn.rdclass = 0; - client->grbn.rdtype = 0; - client->grbn.ttl = 0; - client->grbn.nrdatas = 0; - client->grbn.realname = NULL; - client->grbn.realnamelen = 0; - client->grbn.rdatas = 0; - client->grbn.rdatalen = 0; - client->grbn.base = NULL; - client->grbn.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_grbnrequest_t *req; - isc_result_t result; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_grbnrequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - client->options = 0; - if (req->rdclass != cm->view->rdclass) - goto out; - - if (req->rdclass == dns_rdataclass_any || - req->rdtype == dns_rdatatype_any) - goto out; - - client->rdtype = req->rdtype; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, 0, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - ns_lwdclient_log(50, "client %p looking for type %d", - client, client->rdtype); - - /* - * We no longer need to keep this around. - */ - lwres_grbnrequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_grbn(client); - - /* - * Start the find. - */ - start_lookup(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_grbnrequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-pkcs11/lwdnoop.c b/bin/named-pkcs11/lwdnoop.c deleted file mode 100644 index 7d4de0d..0000000 --- a/bin/named-pkcs11/lwdnoop.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -void -ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_nooprequest_t *req; - lwres_noopresponse_t resp; - isc_result_t result; - lwres_result_t lwres; - isc_region_t r; - lwres_buffer_t lwb; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - req = NULL; - - result = lwres_nooprequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto send_error; - - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - resp.datalength = req->datalength; - resp.data = req->data; - - lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto cleanup_req; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto cleanup_lwb; - - /* - * We can now destroy request. - */ - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - NS_LWDCLIENT_SETSEND(client); - - return; - - cleanup_lwb: - lwres_context_freemem(client->clientmgr->lwctx, lwb.base, lwb.length); - - cleanup_req: - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - send_error: - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-pkcs11/lwresd.8 b/bin/named-pkcs11/lwresd.8 deleted file mode 100644 index aa2c33b..0000000 --- a/bin/named-pkcs11/lwresd.8 +++ /dev/null @@ -1,250 +0,0 @@ -.\" Copyright (C) 2000, 2001, 2004, 2005, 2007-2009, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: lwresd -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2009-01-20 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "LWRESD" "8" "2009\-01\-20" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -lwresd \- lightweight resolver daemon -.SH "SYNOPSIS" -.HP \w'\fBlwresd\fR\ 'u -\fBlwresd\fR [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-C\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-i\ \fR\fB\fIpid\-file\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-P\ \fR\fB\fIport\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [[\fB\-4\fR] | [\fB\-6\fR]] -.SH "DESCRIPTION" -.PP -\fBlwresd\fR -is the daemon providing name lookup services to clients that use the BIND 9 lightweight resolver library\&. It is essentially a stripped\-down, caching\-only name server that answers queries using the BIND 9 lightweight resolver protocol rather than the DNS protocol\&. -.PP -\fBlwresd\fR -listens for resolver queries on a UDP port on the IPv4 loopback interface, 127\&.0\&.0\&.1\&. This means that -\fBlwresd\fR -can only be used by processes running on the local machine\&. By default, UDP port number 921 is used for lightweight resolver requests and responses\&. -.PP -Incoming lightweight resolver requests are decoded by the server which then resolves them using the DNS protocol\&. When the DNS lookup completes, -\fBlwresd\fR -encodes the answers in the lightweight resolver format and returns them to the client that made the request\&. -.PP -If -/etc/resolv\&.conf -contains any -\fBnameserver\fR -entries, -\fBlwresd\fR -sends recursive DNS queries to those servers\&. This is similar to the use of forwarders in a caching name server\&. If no -\fBnameserver\fR -entries are present, or if forwarding fails, -\fBlwresd\fR -resolves the queries autonomously starting at the root name servers, using a built\-in list of root server hints\&. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/lwresd\&.conf\&. -\fB\-c\fR -can not be used with -\fB\-C\fR\&. -.RE -.PP -\-C \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/resolv\&.conf\&. -\fB\-C\fR -can not be used with -\fB\-c\fR\&. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon\*(Aqs debug level to -\fIdebug\-level\fR\&. Debugging traces from -\fBlwresd\fR -become more verbose as the debug level increases\&. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i\&.e\&. do not daemonize)\&. -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -stderr\&. -.RE -.PP -\-i \fIpid\-file\fR -.RS 4 -Use -\fIpid\-file\fR -as the PID file instead of the default, -/var/run/lwresd/lwresd\&.pid\&. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags\&. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR\&. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\&. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs\&. If not specified, -\fBlwresd\fR -will try to determine the number of CPUs present and create one thread per CPU\&. If it is unable to determine the number of CPUs, a single worker thread will be created\&. -.RE -.PP -\-P \fIport\fR -.RS 4 -Listen for lightweight resolver queries on port -\fIport\fR\&. If not specified, the default is port 921\&. -.RE -.PP -\-p \fIport\fR -.RS 4 -Send DNS lookups to port -\fIport\fR\&. If not specified, the default is port 53\&. This provides a way of testing the lightweight resolver daemon with a name server that listens for queries on a non\-standard port number\&. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -stdout -on exit\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn\*(Aqt enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail\&. -.sp .5v -.RE -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports\&. -.RE -.PP -\-v -.RS 4 -Report the version number and exit\&. -.RE -.SH "FILES" -.PP -/etc/resolv\&.conf -.RS 4 -The default configuration file\&. -.RE -.PP -/var/run/lwresd\&.pid -.RS 4 -The default process\-id file\&. -.RE -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBlwres\fR(3), -\fBresolver\fR(5)\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000, 2001, 2004, 2005, 2007-2009, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-pkcs11/lwresd.c b/bin/named-pkcs11/lwresd.c deleted file mode 100644 index f2e480e..0000000 --- a/bin/named-pkcs11/lwresd.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file - * \brief - * Main program for the Lightweight Resolver Daemon. - * - * To paraphrase the old saying about X11, "It's not a lightweight daemon - * for resolvers, it's a daemon for lightweight resolvers". - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D') -#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC) - -#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L') -#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC) - -#define LWRESD_NCLIENTS_MAX 32768 /*%< max clients per task */ - -typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t; - -static ns_lwreslistenerlist_t listeners; -static isc_mutex_t listeners_lock; -static isc_once_t once = ISC_ONCE_INIT; - - -static void -initialize_mutex(void) { - RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); -} - - -/*% - * Wrappers around our memory management stuff, for the lwres functions. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -static isc_result_t -buffer_putstr(isc_buffer_t *b, const char *s) { - unsigned int len = strlen(s); - if (isc_buffer_availablelength(b) <= len) - return (ISC_R_NOSPACE); - isc_buffer_putmem(b, (const unsigned char *)s, len); - return (ISC_R_SUCCESS); -} - -/* - * Convert a resolv.conf file into a config structure. - */ -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp) -{ - char text[4096]; - char str[16]; - isc_buffer_t b; - lwres_context_t *lwctx = NULL; - lwres_conf_t *lwc = NULL; - isc_sockaddr_t sa; - isc_netaddr_t na; - int i; - isc_result_t result; - lwres_result_t lwresult; - - lwctx = NULL; - lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, - ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (lwresult != LWRES_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); - if (lwresult != LWRES_R_SUCCESS) { - result = DNS_R_SYNTAX; - goto cleanup; - } - - lwc = lwres_conf_get(lwctx); - INSIST(lwc != NULL); - - isc_buffer_init(&b, text, sizeof(text)); - - CHECK(buffer_putstr(&b, "options {\n")); - - /* - * Build the list of forwarders. - */ - if (lwc->nsnext > 0) { - CHECK(buffer_putstr(&b, "\tforwarders {\n")); - - for (i = 0; i < lwc->nsnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr( - &sa, - &lwc->nameservers[i], - ns_g_port)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the sortlist - */ - if (lwc->sortlistnxt > 0) { - CHECK(buffer_putstr(&b, "\tsortlist {\n")); - CHECK(buffer_putstr(&b, "\t\t{\n")); - CHECK(buffer_putstr(&b, "\t\t\tany;\n")); - CHECK(buffer_putstr(&b, "\t\t\t{\n")); - for (i = 0; i < lwc->sortlistnxt; i++) { - lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; - lwres_addr_t *lwmask = &lwc->sortlist[i].mask; - unsigned int mask; - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - result = isc_netaddr_masktoprefixlen(&na, &mask); - if (result != ISC_R_SUCCESS) { - char addrtext[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_format(&na, addrtext, - sizeof(addrtext)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_ERROR, - "processing sortlist: '%s' is " - "not a valid netmask", - addrtext); - goto cleanup; - } - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - - CHECK(buffer_putstr(&b, "\t\t\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - snprintf(str, sizeof(str), "%u", mask); - CHECK(buffer_putstr(&b, "/")); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t\t\t};\n")); - CHECK(buffer_putstr(&b, "\t\t};\n")); - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n\n")); - - CHECK(buffer_putstr(&b, "lwres {\n")); - - /* - * Build the search path - */ - if (lwc->searchnxt > 0) { - CHECK(buffer_putstr(&b, "\tsearch {\n")); - for (i = 0; i < lwc->searchnxt; i++) { - CHECK(buffer_putstr(&b, "\t\t\"")); - CHECK(buffer_putstr(&b, lwc->search[i])); - CHECK(buffer_putstr(&b, "\";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the ndots line - */ - if (lwc->ndots != 1) { - CHECK(buffer_putstr(&b, "\tndots ")); - snprintf(str, sizeof(str), "%u", lwc->ndots); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - - /* - * Build the listen-on line - */ - if (lwc->lwnext > 0) { - CHECK(buffer_putstr(&b, "\tlisten-on {\n")); - - for (i = 0; i < lwc->lwnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, - &lwc->lwservers[i], - 0)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n")); - -#if 0 - printf("%.*s\n", - (int)isc_buffer_usedlength(&b), - (char *)isc_buffer_base(&b)); -#endif - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); - - cleanup: - - if (lwctx != NULL) { - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - } - - return (result); -} - - -/* - * Handle lwresd manager objects - */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp) -{ - ns_lwresd_t *lwresd; - const char *vname; - dns_rdataclass_t vclass; - const cfg_obj_t *obj, *viewobj, *searchobj; - const cfg_listelt_t *element; - isc_result_t result; - - INSIST(lwresdp != NULL && *lwresdp == NULL); - - lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); - if (lwresd == NULL) - return (ISC_R_NOMEMORY); - - lwresd->mctx = NULL; - isc_mem_attach(mctx, &lwresd->mctx); - lwresd->view = NULL; - lwresd->search = NULL; - lwresd->refs = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "ndots", &obj); - if (obj != NULL) - lwresd->ndots = cfg_obj_asuint32(obj); - else - lwresd->ndots = 1; - - RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); - - lwresd->shutting_down = false; - - viewobj = NULL; - (void)cfg_map_get(lwres, "view", &viewobj); - if (viewobj != NULL) { - vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); - obj = cfg_tuple_get(viewobj, "class"); - result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); - if (result != ISC_R_SUCCESS) - goto fail; - } else { - vname = "_default"; - vclass = dns_rdataclass_in; - } - - result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, - &lwresd->view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't find view %s", vname); - goto fail; - } - - searchobj = NULL; - (void)cfg_map_get(lwres, "search", &searchobj); - if (searchobj != NULL) { - lwresd->search = NULL; - result = ns_lwsearchlist_create(lwresd->mctx, - &lwresd->search); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't create searchlist"); - goto fail; - } - for (element = cfg_list_first(searchobj); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *search; - const char *searchstr; - isc_buffer_t namebuf; - dns_fixedname_t fname; - dns_name_t *name; - - search = cfg_listelt_value(element); - searchstr = cfg_obj_asstring(search); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - isc_buffer_constinit(&namebuf, searchstr, - strlen(searchstr)); - isc_buffer_add(&namebuf, strlen(searchstr)); - result = dns_name_fromtext(name, &namebuf, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "invalid name %s in searchlist", - searchstr); - continue; - } - - result = ns_lwsearchlist_append(lwresd->search, name); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "couldn't update searchlist"); - goto fail; - } - } - } - - obj = NULL; - (void)cfg_map_get(lwres, "lwres-tasks", &obj); - if (obj != NULL) - lwresd->ntasks = cfg_obj_asuint32(obj); - else - lwresd->ntasks = ns_g_cpus; - - if (lwresd->ntasks == 0) - lwresd->ntasks = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "lwres-clients", &obj); - if (obj != NULL) { - lwresd->nclients = cfg_obj_asuint32(obj); - if (lwresd->nclients > LWRESD_NCLIENTS_MAX) - lwresd->nclients = LWRESD_NCLIENTS_MAX; - } else if (ns_g_lwresdonly) - lwresd->nclients = 1024; - else - lwresd->nclients = 256; - - lwresd->magic = LWRESD_MAGIC; - - *lwresdp = lwresd; - return (ISC_R_SUCCESS); - - fail: - if (lwresd->view != NULL) - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - if (lwresd->mctx != NULL) - isc_mem_detach(&lwresd->mctx); - isc_mem_put(mctx, lwresd, sizeof(ns_lwresd_t)); - return (result); -} - -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { - INSIST(VALID_LWRESD(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp) { - ns_lwresd_t *lwresd; - isc_mem_t *mctx; - bool done = false; - - INSIST(lwresdp != NULL && *lwresdp != NULL); - INSIST(VALID_LWRESD(*lwresdp)); - - lwresd = *lwresdp; - *lwresdp = NULL; - - LOCK(&lwresd->lock); - INSIST(lwresd->refs > 0); - lwresd->refs--; - if (lwresd->refs == 0) - done = true; - UNLOCK(&lwresd->lock); - - if (!done) - return; - - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - mctx = lwresd->mctx; - lwresd->magic = 0; - isc_mem_put(mctx, lwresd, sizeof(*lwresd)); - isc_mem_detach(&mctx); -} - - -/* - * Handle listener objects - */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp) -{ - INSIST(VALID_LWRESLISTENER(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - bool done = false; - - INSIST(listenerp != NULL && *listenerp != NULL); - INSIST(VALID_LWRESLISTENER(*listenerp)); - - listener = *listenerp; - *listenerp = NULL; - - LOCK(&listener->lock); - INSIST(listener->refs > 0); - listener->refs--; - if (listener->refs == 0) - done = true; - UNLOCK(&listener->lock); - - if (!done) - return; - - if (listener->manager != NULL) - ns_lwdmanager_detach(&listener->manager); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - listener->magic = 0; - mctx = listener->mctx; - isc_mem_put(mctx, listener, sizeof(*listener)); - isc_mem_detach(&mctx); -} - -static isc_result_t -listener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd, - ns_lwreslistener_t **listenerp) -{ - ns_lwreslistener_t *listener; - isc_result_t result; - - REQUIRE(listenerp != NULL && *listenerp == NULL); - - listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&listener->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, listener, sizeof(ns_lwreslistener_t)); - return (result); - } - - listener->magic = LWRESLISTENER_MAGIC; - listener->refs = 1; - - listener->sock = NULL; - - listener->manager = NULL; - ns_lwdmanager_attach(lwresd, &listener->manager); - - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->cmgrs); - - *listenerp = listener; - return (ISC_R_SUCCESS); -} - -static isc_result_t -listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - int pf; - - pf = isc_sockaddr_pf(address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - return (ISC_R_FAMILYNOSUPPORT); - - listener->address = *address; - - if (isc_sockaddr_getport(&listener->address) == 0) { - in_port_t port; - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - isc_sockaddr_setport(&listener->address, port); - } - - sock = NULL; - result = isc_socket_create(ns_g_socketmgr, pf, - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to create lwres socket: %s", - isc_result_totext(result)); - return (result); - } - - result = isc_socket_bind(sock, &listener->address, - ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_socket_detach(&sock); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to add lwres socket: %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - listener->sock = sock; - return (ISC_R_SUCCESS); -} - -static void -listener_copysock(ns_lwreslistener_t *oldlistener, - ns_lwreslistener_t *newlistener) -{ - newlistener->address = oldlistener->address; - isc_socket_attach(oldlistener->sock, &newlistener->sock); -} - -static isc_result_t -listener_startclients(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm, *next; - unsigned int i; - isc_result_t result = ISC_R_SUCCESS; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_DEBUG(6), - "listener_startclients: creating %d " - "managers with %d clients each", - listener->manager->ntasks, listener->manager->nclients); - - /* - * Create the client managers. - */ - for (i = 0; i < listener->manager->ntasks; i++) { - result = ns_lwdclientmgr_create(listener, - listener->manager->nclients, - ns_g_taskmgr); - if (result != ISC_R_SUCCESS) - break; - } - - /* - * If the list is empty return now with the previous - * ns_lwdclientmgr_create() result. - */ - if (ISC_LIST_EMPTY(listener->cmgrs)) - return (result); - - /* - * Walk the list of clients and start each one up. - */ - LOCK(&listener->lock); - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - next = ISC_LIST_NEXT(cm, link); - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - cm = next; - } - UNLOCK(&listener->lock); - - return (ISC_R_SUCCESS); -} - -static void -listener_shutdown(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - isc_task_shutdown(cm->task); - cm = ISC_LIST_NEXT(cm, link); - } -} - -static isc_result_t -find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - - INSIST(listenerp != NULL && *listenerp == NULL); - - for (listener = ISC_LIST_HEAD(listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - { - if (!isc_sockaddr_equal(address, &listener->address)) - continue; - *listenerp = listener; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) -{ - REQUIRE(VALID_LWRESLISTENER(listener)); - - LOCK(&listener->lock); - ISC_LIST_UNLINK(listener->cmgrs, cm, link); - UNLOCK(&listener->lock); -} - -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) { - REQUIRE(VALID_LWRESLISTENER(listener)); - - /* - * This does no locking, since it's called early enough that locking - * isn't needed. - */ - ISC_LIST_APPEND(listener->cmgrs, cm, link); -} - -static isc_result_t -configure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd, - isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners) -{ - ns_lwreslistener_t *listener, *oldlistener = NULL; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - - (void)find_listener(address, &oldlistener); - listener = NULL; - result = listener_create(mctx, lwresd, &listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres failed to configure %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - - /* - * If there's already a listener, don't rebind the socket. - */ - if (oldlistener == NULL) { - result = listener_bind(listener, address); - if (result != ISC_R_SUCCESS) { - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - } else - listener_copysock(oldlistener, listener); - - result = listener_startclients(listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres: failed to start %s: %s", socktext, - isc_result_totext(result)); - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - - if (oldlistener != NULL) { - /* - * Remove the old listener from the old list and shut it down. - */ - ISC_LIST_UNLINK(listeners, oldlistener, link); - listener_shutdown(oldlistener); - ns_lwreslistener_detach(&oldlistener); - } else { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres listening on %s", socktext); - } - - ISC_LIST_APPEND(*newlisteners, listener, link); - return (result); -} - -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) { - const cfg_obj_t *lwreslist = NULL; - const cfg_obj_t *lwres = NULL; - const cfg_obj_t *listenerslist = NULL; - const cfg_listelt_t *element = NULL; - ns_lwreslistener_t *listener; - ns_lwreslistenerlist_t newlisteners; - isc_result_t result; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t *addrs = NULL; - ns_lwresd_t *lwresd = NULL; - uint32_t count = 0; - - REQUIRE(mctx != NULL); - REQUIRE(config != NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - ISC_LIST_INIT(newlisteners); - - result = cfg_map_get(config, "lwres", &lwreslist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - LOCK(&listeners_lock); - /* - * Run through the new lwres address list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicates addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - for (element = cfg_list_first(lwreslist); - element != NULL; - element = cfg_list_next(element)) - { - in_port_t port; - - lwres = cfg_listelt_value(element); - CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd)); - - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - - listenerslist = NULL; - (void)cfg_map_get(lwres, "listen-on", &listenerslist); - if (listenerslist == NULL) { - struct in_addr localhost; - isc_sockaddr_t address; - - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&address, &localhost, port); - CHECK(configure_listener(&address, lwresd, mctx, - &newlisteners)); - } else { - uint32_t i; - - CHECK(ns_config_getiplist(config, listenerslist, - port, mctx, &addrs, NULL, - &count)); - for (i = 0; i < count; i++) - CHECK(configure_listener(&addrs[i], lwresd, - mctx, &newlisteners)); - ns_config_putiplist(mctx, &addrs, NULL, count); - } - ns_lwdmanager_detach(&lwresd); - } - - /* - * Shutdown everything on the listeners list, and remove them from - * the list. Then put all of the new listeners on it. - */ - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - - isc_sockaddr_format(&listener->address, - socktext, sizeof(socktext)); - - listener_shutdown(listener); - ns_lwreslistener_detach(&listener); - - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres no longer listening on %s", socktext); - } - - cleanup: - ISC_LIST_APPENDLIST(listeners, newlisteners, link); - - if (addrs != NULL) - ns_config_putiplist(mctx, &addrs, NULL, count); - - if (lwresd != NULL) - ns_lwdmanager_detach(&lwresd); - - UNLOCK(&listeners_lock); - - return (result); -} - -void -ns_lwresd_shutdown(void) { - ns_lwreslistener_t *listener; - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - LOCK(&listeners_lock); - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - UNLOCK(&listeners_lock); - ns_lwreslistener_detach(&listener); - LOCK(&listeners_lock); - } - UNLOCK(&listeners_lock); -} diff --git a/bin/named-pkcs11/lwresd.docbook b/bin/named-pkcs11/lwresd.docbook deleted file mode 100644 index d1c3cdc..0000000 --- a/bin/named-pkcs11/lwresd.docbook +++ /dev/null @@ -1,365 +0,0 @@ - - - - - - 2009-01-20 - - - ISC - Internet Systems Consortium, Inc. - - - - lwresd - 8 - BIND9 - - - - lwresd - lightweight resolver daemon - - - - - 2000 - 2001 - 2004 - 2005 - 2007 - 2008 - 2009 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - lwresd - - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - - lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. - - - lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default, UDP port - number 921 is used for lightweight resolver requests and - responses. - - - Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. - - - If /etc/resolv.conf contains any - entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. - - - - OPTIONS - - - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - can not be used with . - - - - - - -C config-file - - - Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - can not be used with . - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -i pid-file - - - Use pid-file as the - PID file instead of the default, - /var/run/lwresd/lwresd.pid. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -P port - - - Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. - - - - - - -p port - - - Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. - - - - - - -s - - - Write memory usage statistics to stdout - on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - - - -v - - - Report the version number and exit. - - - - - - - - - FILES - - - - - - /etc/resolv.conf - - - The default configuration file. - - - - - - /var/run/lwresd.pid - - - The default process-id file. - - - - - - - - - SEE ALSO - - - named8 - , - - lwres3 - , - - resolver5 - . - - - - diff --git a/bin/named-pkcs11/lwresd.html b/bin/named-pkcs11/lwresd.html deleted file mode 100644 index ad4bf61..0000000 --- a/bin/named-pkcs11/lwresd.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - -lwresd - - -
-
-
-

Name

-

lwresd — lightweight resolver daemon

-
-
-

Synopsis

-

lwresd [-c config-file] [-C config-file] [-d debug-level] [-f] [-g] [-i pid-file] [-m flag] [-n #cpus] [-P port] [-p port] [-s] [-t directory] [-u user] [-v] [[-4] | [-6]]

-
-
-

DESCRIPTION

-

lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. -

-

lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default, UDP port - number 921 is used for lightweight resolver requests and - responses. -

-

- Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. -

-

- If /etc/resolv.conf contains any - nameserver entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - nameserver entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - -c can not be used with -C. -

-
-C config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - -C can not be used with -c. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. -

-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-i pid-file
-

- Use pid-file as the - PID file instead of the default, - /var/run/lwresd/lwresd.pid. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-P port
-

- Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. -

-
-p port
-

- Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. -

-
-s
-
-

- Write memory usage statistics to stdout - on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-u user
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-v
-

- Report the version number and exit. -

-
-
-
-

FILES

-
-
/etc/resolv.conf
-

- The default configuration file. -

-
/var/run/lwresd.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

named(8), - lwres(3), - resolver(5). -

-
-
- diff --git a/bin/named-pkcs11/lwsearch.c b/bin/named-pkcs11/lwsearch.c deleted file mode 100644 index f56dc7b..0000000 --- a/bin/named-pkcs11/lwsearch.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L') -#define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC) - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(listp != NULL && *listp == NULL); - - list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); - if (list == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&list->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - return (result); - } - list->mctx = NULL; - isc_mem_attach(mctx, &list->mctx); - list->refs = 1; - ISC_LIST_INIT(list->names); - list->magic = LWSEARCHLIST_MAGIC; - - *listp = list; - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) { - REQUIRE(VALID_LWSEARCHLIST(source)); - REQUIRE(target != NULL && *target == NULL); - - LOCK(&source->lock); - INSIST(source->refs > 0); - source->refs++; - INSIST(source->refs != 0); - UNLOCK(&source->lock); - - *target = source; -} - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_mem_t *mctx; - - REQUIRE(listp != NULL); - list = *listp; - REQUIRE(VALID_LWSEARCHLIST(list)); - - LOCK(&list->lock); - INSIST(list->refs > 0); - list->refs--; - UNLOCK(&list->lock); - - *listp = NULL; - if (list->refs != 0) - return; - - mctx = list->mctx; - while (!ISC_LIST_EMPTY(list->names)) { - dns_name_t *name = ISC_LIST_HEAD(list->names); - ISC_LIST_UNLINK(list->names, name, link); - dns_name_free(name, list->mctx); - isc_mem_put(list->mctx, name, sizeof(dns_name_t)); - } - list->magic = 0; - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - isc_mem_detach(&mctx); -} - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { - dns_name_t *newname; - isc_result_t result; - - REQUIRE(VALID_LWSEARCHLIST(list)); - REQUIRE(name != NULL); - - newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); - if (newname == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(newname, NULL); - result = dns_name_dup(name, list->mctx, newname); - if (result != ISC_R_SUCCESS) { - isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); - return (result); - } - ISC_LINK_INIT(newname, link); - ISC_LIST_APPEND(list->names, newname, link); - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots) -{ - INSIST(sctx != NULL); - sctx->relname = name; - sctx->searchname = NULL; - sctx->doneexact = false; - sctx->exactfirst = false; - sctx->ndots = ndots; - if (dns_name_isabsolute(name) || list == NULL) { - sctx->list = NULL; - return; - } - sctx->list = list; - sctx->searchname = ISC_LIST_HEAD(sctx->list->names); - if (dns_name_countlabels(name) > ndots) - sctx->exactfirst = true; -} - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - UNUSED(sctx); -} - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - - if (sctx->list == NULL) - return (ISC_R_NOMORE); - - if (sctx->searchname == NULL) { - if (sctx->exactfirst || sctx->doneexact) - return (ISC_R_NOMORE); - sctx->doneexact = true; - } else { - if (sctx->exactfirst && !sctx->doneexact) - sctx->doneexact = true; - else { - sctx->searchname = ISC_LIST_NEXT(sctx->searchname, - link); - if (sctx->searchname == NULL && sctx->doneexact) - return (ISC_R_NOMORE); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) { - dns_name_t *tname; - bool useexact = false; - - REQUIRE(sctx != NULL); - - if (sctx->list == NULL || - sctx->searchname == NULL || - (sctx->exactfirst && !sctx->doneexact)) - useexact = true; - - if (useexact) { - if (dns_name_isabsolute(sctx->relname)) - tname = NULL; - else - tname = dns_rootname; - } else - tname = sctx->searchname; - - return (dns_name_concatenate(sctx->relname, tname, absname, NULL)); -} diff --git a/bin/named-pkcs11/main.c b/bin/named-pkcs11/main.c deleted file mode 100644 index d9127cd..0000000 --- a/bin/named-pkcs11/main.c +++ /dev/null @@ -1,1630 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#ifdef PKCS11CRYPTO -#include -#endif - -#include - -#ifdef HAVE_GPERFTOOLS_PROFILER -#include -#endif - -#ifdef HAVE_GEOIP2 -#include -#endif - -/* - * Defining NS_MAIN provides storage declarations (rather than extern) - * for variables in named/globals.h. - */ -#define NS_MAIN 1 - -#include -#include -#include -#include -#include /* Explicit, though named/log.h includes it. */ -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -#ifdef OPENSSL -#include -#include -#endif -#ifdef HAVE_LIBXML2 -#include -#endif -#ifdef HAVE_ZLIB -#include -#endif -/* - * Include header files for database drivers here. - */ -/* #include "xxdb.h" */ - -#ifdef CONTRIB_DLZ -/* - * Include contributed DLZ drivers if appropriate. - */ -#include -#endif - -/* - * The maximum number of stack frames to dump on assertion failure. - */ -#ifndef BACKTRACE_MAXFRAME -#define BACKTRACE_MAXFRAME 128 -#endif - -LIBISC_EXTERNAL_DATA extern int isc_dscp_check_value; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_hour; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_day; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_month; - -static bool want_stats = false; -static char program_name[NAME_MAX] = "named"; -static char absolute_conffile[PATH_MAX]; -static char saved_command_line[512]; -static char version[512]; -static unsigned int maxsocks = 0; -static int maxudp = 0; - -void -ns_main_earlywarning(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - format, args); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); -} - -void -ns_main_earlyfatal(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to early fatal error)"); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); - - exit(1); -} - -ISC_PLATFORM_NORETURN_PRE static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) ISC_PLATFORM_NORETURN_POST; - -static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ - void *tracebuf[BACKTRACE_MAXFRAME]; - int i, nframes; - isc_result_t result; - const char *logsuffix = ""; - const char *fname; - - /* - * Handle assertion failures. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the assertion callback in case it is the log - * routines causing the assertion. - */ - isc_assertion_setcallback(NULL); - - result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, - &nframes); - if (result == ISC_R_SUCCESS && nframes > 0) - logsuffix = ", back trace"; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: %s(%s) failed%s", file, line, - isc_assertion_typetotext(type), cond, logsuffix); - if (result == ISC_R_SUCCESS) { - for (i = 0; i < nframes; i++) { - unsigned long offset; - - fname = NULL; - result = isc_backtrace_getsymbol(tracebuf[i], - &fname, - &offset); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, - ISC_LOG_CRITICAL, - "#%d %p in %s()+0x%lx", i, - tracebuf[i], fname, - offset); - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, - ISC_LOG_CRITICAL, - "#%d %p in ??", i, - tracebuf[i]); - } - } - } - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to assertion failure)"); - } else { - fprintf(stderr, "%s:%d: %s(%s) failed\n", - file, line, isc_assertion_typetotext(type), cond); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -ISC_PLATFORM_NORETURN_PRE static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -ISC_FORMAT_PRINTF(3, 0) ISC_PLATFORM_NORETURN_POST; - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_fatal() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the error callback in case it is the log - * routines causing the assertion. - */ - isc_error_setfatal(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: fatal error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to fatal error in library)"); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_unexpected() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - "%s:%d: unexpected error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - format, args); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } -} - -static void -lwresd_usage(void) { - fprintf(stderr, - "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] " - "[-d debuglevel] [-f|-g]\n" - " [-i pidfile] [-n number_of_cpus] " - "[-p port] [-P listen-port]\n" - " [-s] [-S sockets] [-t chrootdir] [-u username] " - "[-U listeners]\n" - " [-m {usage|trace|record|size|mctx}]\n" - "usage: lwresd [-v|-V]\n"); -} - -static void -usage(void) { - if (ns_g_lwresdonly) { - lwresd_usage(); - return; - } - fprintf(stderr, - "usage: named [-4|-6] [-c conffile] [-d debuglevel] " - "[-E engine] [-f|-g]\n" - " [-n number_of_cpus] [-p port] [-s] " - "[-S sockets] [-t chrootdir]\n" - " [-u username] [-U listeners] " - "[-m {usage|trace|record|size|mctx}]\n" - "usage: named [-v|-V]\n"); -} - -static void -save_command_line(int argc, char *argv[]) { - int i; - char *src; - char *dst; - char *eob; - const char truncated[] = "..."; - bool quoted = false; - - dst = saved_command_line; - eob = saved_command_line + sizeof(saved_command_line); - - for (i = 1; i < argc && dst < eob; i++) { - *dst++ = ' '; - - src = argv[i]; - while (*src != '\0' && dst < eob) { - /* - * This won't perfectly produce a shell-independent - * pastable command line in all circumstances, but - * comes close, and for practical purposes will - * nearly always be fine. - */ - if (quoted || isalnum(*src & 0xff) || - *src == ',' || *src == '-' || *src == '_' || - *src == '.' || *src == '/') { - *dst++ = *src++; - quoted = false; - } else { - *dst++ = '\\'; - quoted = true; - } - } - } - - INSIST(sizeof(saved_command_line) >= sizeof(truncated)); - - if (dst == eob) - strcpy(eob - sizeof(truncated), truncated); - else - *dst = '\0'; -} - -static int -parse_int(char *arg, const char *desc) { - char *endp; - int tmp; - long int ltmp; - - ltmp = strtol(arg, &endp, 10); - tmp = (int) ltmp; - if (*endp != '\0') - ns_main_earlyfatal("%s '%s' must be numeric", desc, arg); - if (tmp < 0 || tmp != ltmp) - ns_main_earlyfatal("%s '%s' out of range", desc, arg); - return (tmp); -} - -static struct flag_def { - const char *name; - unsigned int value; -} mem_debug_flags[] = { - { "none", 0}, - { "trace", ISC_MEM_DEBUGTRACE }, - { "record", ISC_MEM_DEBUGRECORD }, - { "usage", ISC_MEM_DEBUGUSAGE }, - { "size", ISC_MEM_DEBUGSIZE }, - { "mctx", ISC_MEM_DEBUGCTX }, - { NULL, 0 } -}; - -static void -set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) { - bool clear = false; - - for (;;) { - const struct flag_def *def; - const char *end = strchr(arg, ','); - int arglen; - if (end == NULL) - end = arg + strlen(arg); - arglen = (int)(end - arg); - for (def = defs; def->name != NULL; def++) { - if (arglen == (int)strlen(def->name) && - memcmp(arg, def->name, arglen) == 0) { - if (def->value == 0) - clear = true; - *ret |= def->value; - goto found; - } - } - ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg); - found: - if (clear || (*end == '\0')) - break; - arg = end + 1; - } - - if (clear) - *ret = 0; -} - -static void -printversion(bool verbose) { - char rndcconf[PATH_MAX], *dot = NULL; - isc_mem_t *mctx = NULL; - cfg_parser_t *parser = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *defaults = NULL, *obj = NULL; - - printf("%s %s%s%s \n", - ns_g_product, ns_g_version, - (*ns_g_description != '\0') ? " " : "", - ns_g_description, ns_g_srcid); - - if (!verbose) { - return; - } - printf("running on %s\n", ns_os_uname()); - printf("built by %s with %s\n", ns_g_builder, ns_g_configargs); -#ifdef __clang__ - printf("compiled by CLANG %s\n", __VERSION__); -#else -#if defined(__ICC) || defined(__INTEL_COMPILER) - printf("compiled by ICC %s\n", __VERSION__); -#else -#ifdef __GNUC__ - printf("compiled by GCC %s\n", __VERSION__); -#endif -#endif -#endif -#ifdef _MSC_VER - printf("compiled by MSVC %d\n", _MSC_VER); -#endif -#ifdef __SUNPRO_C - printf("compiled by Solaris Studio %x\n", __SUNPRO_C); -#endif -#ifdef OPENSSL - printf("compiled with OpenSSL version: %s\n", OPENSSL_VERSION_TEXT); -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 or higher */ - printf("linked to OpenSSL version: %s\n", - OpenSSL_version(OPENSSL_VERSION)); -#else - printf("linked to OpenSSL version: %s\n", - SSLeay_version(SSLEAY_VERSION)); -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -#endif -#ifdef HAVE_LIBXML2 - printf("compiled with libxml2 version: %s\n", LIBXML_DOTTED_VERSION); - printf("linked to libxml2 version: %s\n", xmlParserVersion); -#endif -#if defined(HAVE_JSON) && defined(JSON_C_VERSION) - printf("compiled with libjson-c version: %s\n", JSON_C_VERSION); - printf("linked to libjson-c version: %s\n", json_c_version()); -#endif -#if defined(HAVE_ZLIB) && defined(ZLIB_VERSION) - printf("compiled with zlib version: %s\n", ZLIB_VERSION); - printf("linked to zlib version: %s\n", zlibVersion()); -#endif -#if defined(HAVE_GEOIP2) - /* Unfortunately, no version define on link time */ - printf("linked to maxminddb version: %s\n", - MMDB_lib_version()); -#endif -#if defined(HAVE_DNSTAP) - printf("compiled with protobuf-c version: %s\n", - PROTOBUF_C_VERSION); - printf("linked to protobuf-c version: %s\n", - protobuf_c_version()); -#endif -#ifdef ISC_PLATFORM_USETHREADS - printf("threads support is enabled\n"); -#else - printf("threads support is disabled\n"); -#endif - - /* - * The default rndc.conf and rndc.key paths are in the same - * directory, but named only has rndc.key defined internally. - * We construct the rndc.conf path from it. (We could use - * NAMED_SYSCONFDIR here but the result would look wrong on - * Windows.) - */ - strlcpy(rndcconf, ns_g_keyfile, sizeof(rndcconf)); - dot = strrchr(rndcconf, '.'); - if (dot != NULL) { - size_t len = dot - rndcconf + 1; - snprintf(dot + 1, PATH_MAX - len, "conf"); - } - -#define RTC(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS) - RTC(isc_mem_create(0, 0, &mctx)); - RTC(cfg_parser_create(mctx, ns_g_lctx, &parser)); - RTC(ns_config_parsedefaults(parser, &config)); - RTC(cfg_map_get(config, "options", &defaults)); - - /* - * Print default configuration paths. - */ - printf("\n"); - printf("default paths:\n"); - printf(" named configuration: %s\n", ns_g_conffile); - printf(" rndc configuration: %s\n", rndcconf); - RTC(cfg_map_get(defaults, "bindkeys-file", &obj)); - printf(" DNSSEC root key: %s\n", cfg_obj_asstring(obj)); - printf(" nsupdate session key: %s\n", ns_g_defaultsessionkeyfile); - printf(" named PID file: %s\n", ns_g_defaultpidfile); - printf(" named lock file: %s\n", ns_g_defaultlockfile); -#if defined(HAVE_GEOIP2) - obj = NULL; - RTC(cfg_map_get(defaults, "geoip-directory", &obj)); - if (cfg_obj_isstring(obj)) { - printf(" geoip-directory: %s\n", cfg_obj_asstring(obj)); - } -#endif /* HAVE_GEOIP2 */ - cfg_obj_destroy(parser, &config); - cfg_parser_destroy(&parser); - isc_mem_detach(&mctx); -} - -static void -parse_fuzz_arg(void) { - if (!strncmp(isc_commandline_argument, "client:", 7)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 7; - ns_g_fuzz_type = ns_fuzz_client; - } else if (!strncmp(isc_commandline_argument, "tcp:", 4)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 4; - ns_g_fuzz_type = ns_fuzz_tcpclient; - } else if (!strncmp(isc_commandline_argument, "resolver:", 9)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 9; - ns_g_fuzz_type = ns_fuzz_resolver; - } else if (!strncmp(isc_commandline_argument, "http:", 5)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 5; - ns_g_fuzz_type = ns_fuzz_http; - } else if (!strncmp(isc_commandline_argument, "rndc:", 5)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 5; - ns_g_fuzz_type = ns_fuzz_rndc; - } else { - ns_main_earlyfatal("unknown fuzzing type '%s'", - isc_commandline_argument); - } -} - -static void -parse_T_opt(char *option) { - const char *p; - /* - * force the server to behave (or misbehave) in - * specified ways for testing purposes. - * - * clienttest: make clients single shot with their - * own memory context. - * delay=xxxx: delay client responses by xxxx ms to - * simulate remote servers. - * dscp=x: check that dscp values are as - * expected and assert otherwise. - */ - if (!strcmp(option, "clienttest")) { - ns_g_clienttest = true; - } else if (!strncmp(option, "delay=", 6)) { - ns_g_delay = atoi(option + 6); - } else if (!strcmp(option, "dropedns")) { - ns_g_dropedns = true; - } else if (!strncmp(option, "dscp=", 5)) { - isc_dscp_check_value = atoi(option + 5); - } else if (!strcmp(option, "ednsformerr")) { - ns_g_ednsformerr = true; - } else if (!strcmp(option, "ednsnotimp")) { - ns_g_ednsnotimp = true; - } else if (!strcmp(option, "ednsrefused")) { - ns_g_ednsrefused = true; - } else if (!strcmp(option, "fixedlocal")) { - ns_g_fixedlocal = true; - } else if (!strcmp(option, "keepstderr")) { - ns_g_keepstderr = true; - } else if (!strcmp(option, "noaa")) { - ns_g_noaa = true; - } else if (!strcmp(option, "noedns")) { - ns_g_noedns = true; - } else if (!strcmp(option, "nonearest")) { - ns_g_nonearest = true; - } else if (!strcmp(option, "nosoa")) { - ns_g_nosoa = true; - } else if (!strcmp(option, "nosyslog")) { - ns_g_nosyslog = true; - } else if (!strcmp(option, "notcp")) { - ns_g_notcp = true; - } else if (!strcmp(option, "maxudp512")) { - maxudp = 512; - } else if (!strcmp(option, "maxudp1460")) { - maxudp = 1460; - } else if (!strncmp(option, "maxudp=", 7)) { - maxudp = atoi(option + 7); - if (maxudp <= 0) { - ns_main_earlyfatal("bad maxudp"); - } - } else if (!strncmp(option, "mkeytimers=", 11)) { - p = strtok(option + 11, "/"); - if (p == NULL) { - ns_main_earlyfatal("bad mkeytimer"); - } - - dns_zone_mkey_hour = atoi(p); - if (dns_zone_mkey_hour == 0) { - ns_main_earlyfatal("bad mkeytimer"); - } - - p = strtok(NULL, "/"); - if (p == NULL) { - dns_zone_mkey_day = (24 * dns_zone_mkey_hour); - dns_zone_mkey_month = (30 * dns_zone_mkey_day); - return; - } - - dns_zone_mkey_day = atoi(p); - if (dns_zone_mkey_day < dns_zone_mkey_hour) - ns_main_earlyfatal("bad mkeytimer"); - - p = strtok(NULL, "/"); - if (p == NULL) { - dns_zone_mkey_month = (30 * dns_zone_mkey_day); - return; - } - - dns_zone_mkey_month = atoi(p); - if (dns_zone_mkey_month < dns_zone_mkey_day) { - ns_main_earlyfatal("bad mkeytimer"); - } - } else if (!strcmp(option, "sigvalinsecs")) { - ns_g_sigvalinsecs = true; - } else if (!strncmp(option, "tat=", 4)) { - ns_g_tat_interval = atoi(option + 4); - } else { - fprintf(stderr, "unknown -T flag '%s'\n", option); - } -} - -static void -parse_command_line(int argc, char *argv[]) { - int ch; - int port; - const char *p; - - save_command_line(argc, argv); - - /* - * NS_MAIN_ARGS is defined in main.h, so that it can be used - * both by named and by ntservice hooks. - */ - isc_commandline_errprint = false; - while ((ch = isc_commandline_parse(argc, argv, NS_MAIN_ARGS)) != -1) { - switch (ch) { - case '4': - if (ns_g_disable4) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv4() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv4 not supported by OS"); - isc_net_disableipv6(); - ns_g_disable6 = true; - break; - case '6': - if (ns_g_disable6) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv6() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv6 not supported by OS"); - isc_net_disableipv4(); - ns_g_disable4 = true; - break; - case 'A': - parse_fuzz_arg(); - break; - case 'c': - ns_g_conffile = isc_commandline_argument; - lwresd_g_conffile = isc_commandline_argument; - if (lwresd_g_useresolvconf) - ns_main_earlyfatal("cannot specify -c and -C"); - ns_g_conffileset = true; - break; - case 'C': - lwresd_g_resolvconffile = isc_commandline_argument; - if (ns_g_conffileset) - ns_main_earlyfatal("cannot specify -c and -C"); - lwresd_g_useresolvconf = true; - break; - case 'd': - ns_g_debuglevel = parse_int(isc_commandline_argument, - "debug level"); - break; - case 'D': - /* Descriptive comment for 'ps'. */ - break; - case 'E': - ns_g_engine = isc_commandline_argument; - break; - case 'f': - ns_g_foreground = true; - break; - case 'g': - ns_g_foreground = true; - ns_g_logstderr = true; - break; - /* XXXBEW -i should be removed */ - case 'i': - lwresd_g_defaultpidfile = isc_commandline_argument; - break; - case 'l': - ns_g_lwresdonly = true; - break; - case 'L': - ns_g_logfile = isc_commandline_argument; - break; - case 'M': - if (strcmp(isc_commandline_argument, "external") == 0) - isc_mem_defaultflags = 0; - break; - case 'm': - set_flags(isc_commandline_argument, mem_debug_flags, - &isc_mem_debugging); - break; - case 'N': /* Deprecated. */ - case 'n': - ns_g_cpus = parse_int(isc_commandline_argument, - "number of cpus"); - if (ns_g_cpus == 0) - ns_g_cpus = 1; - break; - case 'p': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - ns_g_port = port; - break; - /* XXXBEW Should -P be removed? */ - case 'P': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - lwresd_g_listenport = port; - break; - case 's': - /* XXXRTH temporary syntax */ - want_stats = true; - break; - case 'S': - maxsocks = parse_int(isc_commandline_argument, - "max number of sockets"); - break; - case 't': - /* XXXJAB should we make a copy? */ - ns_g_chrootdir = isc_commandline_argument; - break; - case 'T': /* NOT DOCUMENTED */ - parse_T_opt(isc_commandline_argument); - break; - case 'U': - ns_g_udpdisp = parse_int(isc_commandline_argument, - "number of UDP listeners " - "per interface"); - break; - case 'u': - ns_g_username = isc_commandline_argument; - break; - case 'v': - printversion(false); - exit(0); - case 'V': - printversion(true); - exit(0); - case 'x': - /* Obsolete. No longer in use. Ignore. */ - break; - case 'X': - ns_g_forcelock = true; - if (strcasecmp(isc_commandline_argument, "none") != 0) - ns_g_defaultlockfile = isc_commandline_argument; - else - ns_g_defaultlockfile = NULL; - break; - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - usage(); - if (isc_commandline_option == '?') - exit(0); - p = strchr(NS_MAIN_ARGS, isc_commandline_option); - if (p == NULL || *++p != ':') - ns_main_earlyfatal("unknown option '-%c'", - isc_commandline_option); - else - ns_main_earlyfatal("option '-%c' requires " - "an argument", - isc_commandline_option); - /* FALLTHROUGH */ - default: - ns_main_earlyfatal("parsing options returned %d", ch); - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - POST(argv); - - if (argc > 0) { - usage(); - ns_main_earlyfatal("extra command line arguments"); - } -} - -static isc_result_t -create_managers(void) { - isc_result_t result; - unsigned int socks; - - INSIST(ns_g_cpus_detected > 0); - -#ifdef ISC_PLATFORM_USETHREADS - if (ns_g_cpus == 0) - ns_g_cpus = ns_g_cpus_detected; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", - ns_g_cpus_detected, ns_g_cpus_detected == 1 ? "" : "s", - ns_g_cpus, ns_g_cpus == 1 ? "" : "s"); -#else - ns_g_cpus = 1; -#endif -#ifdef WIN32 - ns_g_udpdisp = 1; -#else - if (ns_g_udpdisp == 0) { - if (ns_g_cpus_detected == 1) - ns_g_udpdisp = 1; - else - ns_g_udpdisp = ns_g_cpus_detected - 1; - } - if (ns_g_udpdisp > ns_g_cpus) - ns_g_udpdisp = ns_g_cpus; -#endif -#ifdef ISC_PLATFORM_USETHREADS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "using %u UDP listener%s per interface", - ns_g_udpdisp, ns_g_udpdisp == 1 ? "" : "s"); -#endif - - result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_taskmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timermgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_socketmgr_create2(ns_g_mctx, &ns_g_socketmgr, maxsocks); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socketmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - isc__socketmgr_maxudp(ns_g_socketmgr, maxudp); - result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &socks); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "using up to %u sockets", socks); - } - - result = isc_entropy_create(ns_g_mctx, &ns_g_entropy); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_entropy_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_hash_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -static void -destroy_managers(void) { - ns_lwresd_shutdown(); - - /* - * isc_taskmgr_destroy() will block until all tasks have exited, - */ - isc_taskmgr_destroy(&ns_g_taskmgr); - isc_timermgr_destroy(&ns_g_timermgr); - isc_socketmgr_destroy(&ns_g_socketmgr); - - /* - * isc_hash_destroy() cannot be called as long as a resolver may be - * running. Calling this after isc_taskmgr_destroy() ensures the - * call is safe. - */ - isc_hash_destroy(); -} - -static void -dump_symboltable(void) { - int i; - isc_result_t result; - const char *fname; - const void *addr; - - if (isc__backtrace_nsymbols == 0) - return; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99))) - return; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_DEBUG(99), "Symbol table:"); - - for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) { - addr = NULL; - fname = NULL; - result = isc_backtrace_getsymbolfromindex(i, &addr, &fname); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99), - "[%d] %p %s", i, addr, fname); - } - } -} - -#ifdef HAVE_LIBSECCOMP -static void -setup_seccomp() { - scmp_filter_ctx ctx; - unsigned int i; - int ret; - - /* Make sure the lists are in sync */ - INSIST((sizeof(scmp_syscalls) / sizeof(int)) == - (sizeof(scmp_syscall_names) / sizeof(const char *))); - - ctx = seccomp_init(SCMP_ACT_KILL); - if (ctx == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp activation failed"); - return; - } - - for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) { - ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, - scmp_syscalls[i], 0); - if (ret < 0) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp rule failed: %s", - scmp_syscall_names[i]); - - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(9), - "added libseccomp rule: %s", - scmp_syscall_names[i]); - } - - ret = seccomp_load(ctx); - if (ret < 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp unable to load filter"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "libseccomp sandboxing active"); - } - - /* - * Release filter in ctx. Filters already loaded are not - * affected. - */ - seccomp_release(ctx); -} -#endif /* HAVE_LIBSECCOMP */ - -static void -setup(void) { - isc_result_t result; - isc_resourcevalue_t old_openfiles; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Get the user and group information before changing the root - * directory, so the administrator does not need to keep a copy - * of the user and group databases in the chroot'ed environment. - */ - ns_os_inituserinfo(ns_g_username); - - /* - * Initialize time conversion information - */ - ns_os_tzset(); - - ns_os_opendevnull(); - -#ifdef HAVE_LIBSCF - /* Check if named is under smf control, before chroot. */ - result = ns_smf_get_instance(&instance, 0, ns_g_mctx); - /* We don't care about instance, just check if we got one. */ - if (result == ISC_R_SUCCESS) - ns_smf_got_instance = 1; - else - ns_smf_got_instance = 0; - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); -#endif /* HAVE_LIBSCF */ - -#ifdef PATH_RANDOMDEV - /* - * Initialize system's random device as fallback entropy source - * if running chroot'ed. - */ - if (ns_g_chrootdir != NULL) { - result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_entropy_create() failed: %s", - isc_result_totext(result)); - - result = isc_entropy_createfilesource(ns_g_fallbackentropy, - PATH_RANDOMDEV); - if (result != ISC_R_SUCCESS) { - ns_main_earlywarning("could not open pre-chroot " - "entropy source %s: %s", - PATH_RANDOMDEV, - isc_result_totext(result)); - isc_entropy_detach(&ns_g_fallbackentropy); - } - } -#endif - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Check for the number of cpu's before ns_os_chroot(). - */ - ns_g_cpus_detected = isc_os_ncpus(); -#endif - - ns_os_chroot(ns_g_chrootdir); - - /* - * For operating systems which have a capability mechanism, now - * is the time to switch to minimal privs and change our user id. - * On traditional UNIX systems, this call will be a no-op, and we - * will change the user ID after reading the config file the first - * time. (We need to read the config file to know which possibly - * privileged ports to bind() to.) - */ - ns_os_minprivs(); - - result = ns_log_init((ns_g_username != NULL)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("ns_log_init() failed: %s", - isc_result_totext(result)); - - /* - * Now is the time to daemonize (if we're not running in the - * foreground). We waited until now because we wanted to get - * a valid logging context setup. We cannot daemonize any later, - * because calling create_managers() will create threads, which - * would be lost after fork(). - */ - if (!ns_g_foreground) - ns_os_daemonize(); - - /* - * We call isc_app_start() here as some versions of FreeBSD's fork() - * destroys all the signal handling it sets up. - */ - result = isc_app_start(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_app_start() failed: %s", - isc_result_totext(result)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "starting %s %s%s%s ", - ns_g_product, ns_g_version, - *ns_g_description ? " " : "", ns_g_description, - ns_g_srcid); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "running on %s", ns_os_uname()); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "built with %s", ns_g_configargs); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "running as: %s%s", - program_name, saved_command_line); -#ifdef __clang__ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by CLANG %s", __VERSION__); -#else -#if defined(__ICC) || defined(__INTEL_COMPILER) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by ICC %s", __VERSION__); -#else -#ifdef __GNUC__ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by GCC %s", __VERSION__); -#endif -#endif -#endif -#ifdef _MSC_VER - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by MSVC %d", _MSC_VER); -#endif -#ifdef __SUNPRO_C - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by Solaris Studio %x", __SUNPRO_C); -#endif -#ifdef OPENSSL - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with OpenSSL version: %s", - OPENSSL_VERSION_TEXT); -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 or higher */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to OpenSSL version: %s", - OpenSSL_version(OPENSSL_VERSION)); -#else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to OpenSSL version: %s", - SSLeay_version(SSLEAY_VERSION)); -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -#endif -#ifdef HAVE_LIBXML2 - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with libxml2 version: %s", - LIBXML_DOTTED_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to libxml2 version: %s", xmlParserVersion); -#endif -#if defined(HAVE_JSON) && defined(JSON_C_VERSION) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with libjson-c version: %s", JSON_C_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to libjson-c version: %s", json_c_version()); -#endif -#if defined(HAVE_ZLIB) && defined(ZLIB_VERSION) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with zlib version: %s", ZLIB_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to zlib version: %s", zlibVersion()); -#endif -#ifdef ISC_PLATFORM_USETHREADS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "threads support is enabled"); -#else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "threads support is disabled"); -#endif - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "----------------------------------------------------"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "BIND 9 is maintained by Internet Systems Consortium,"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "Inc. (ISC), a non-profit 501(c)(3) public-benefit "); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "corporation. Support and training for BIND 9 are "); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "available at https://www.isc.org/support"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "----------------------------------------------------"); - - dump_symboltable(); - - /* - * Get the initial resource limits. - */ - (void)isc_resource_getlimit(isc_resource_stacksize, - &ns_g_initstacksize); - (void)isc_resource_getlimit(isc_resource_datasize, - &ns_g_initdatasize); - (void)isc_resource_getlimit(isc_resource_coresize, - &ns_g_initcoresize); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - - /* - * System resources cannot effectively be tuned on some systems. - * Raise the limit in such cases for safety. - */ - old_openfiles = ns_g_initopenfiles; - ns_os_adjustnofile(); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - if (old_openfiles != ns_g_initopenfiles) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "adjusted limit on open files from " - "%" PRIu64 " to " - "%" PRIu64, - old_openfiles, ns_g_initopenfiles); - } - - /* - * If the named configuration filename is relative, prepend the current - * directory's name before possibly changing to another directory. - */ - if (! isc_file_isabsolute(ns_g_conffile)) { - result = isc_file_absolutepath(ns_g_conffile, - absolute_conffile, - sizeof(absolute_conffile)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("could not construct absolute path " - "of configuration file: %s", - isc_result_totext(result)); - ns_g_conffile = absolute_conffile; - } - - /* - * Record the server's startup time. - */ - result = isc_time_now(&ns_g_boottime); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_time_now() failed: %s", - isc_result_totext(result)); - - result = create_managers(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("create_managers() failed: %s", - isc_result_totext(result)); - - ns_builtin_init(); - - /* - * Add calls to register sdb drivers here. - */ - /* xxdb_init(); */ - -#ifdef ISC_DLZ_DLOPEN - /* - * Register the DLZ "dlopen" driver. - */ - result = dlz_dlopen_init(ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("dlz_dlopen_init() failed: %s", - isc_result_totext(result)); -#endif - -#if CONTRIB_DLZ - /* - * Register any other contributed DLZ drivers. - */ - result = dlz_drivers_init(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("dlz_drivers_init() failed: %s", - isc_result_totext(result)); -#endif - - ns_server_create(ns_g_mctx, &ns_g_server); - -#ifdef HAVE_LIBSECCOMP - setup_seccomp(); -#endif /* HAVE_LIBSECCOMP */ -} - -static void -cleanup(void) { - destroy_managers(); - - if (ns_g_mapped != NULL) - dns_acl_detach(&ns_g_mapped); - - ns_server_destroy(&ns_g_server); - - isc_entropy_detach(&ns_g_entropy); - if (ns_g_fallbackentropy != NULL) - isc_entropy_detach(&ns_g_fallbackentropy); - - ns_builtin_deinit(); - - /* - * Add calls to unregister sdb drivers here. - */ - /* xxdb_clear(); */ - -#ifdef CONTRIB_DLZ - /* - * Unregister contributed DLZ drivers. - */ - dlz_drivers_clear(); -#endif -#ifdef ISC_DLZ_DLOPEN - /* - * Unregister "dlopen" DLZ driver. - */ - dlz_dlopen_clear(); -#endif - - dns_name_destroy(); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "exiting"); - ns_log_shutdown(); -} - -static char *memstats = NULL; - -void -ns_main_setmemstats(const char *filename) { - /* - * Caller has to ensure locking. - */ - - if (memstats != NULL) { - free(memstats); - memstats = NULL; - } - - if (filename == NULL) - return; - - memstats = strdup(filename); -} - -#ifdef HAVE_LIBSCF -/* - * Get FMRI for the named process. - */ -isc_result_t -ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { - scf_handle_t *h = NULL; - int namelen; - char *instance; - - REQUIRE(ins_name != NULL && *ins_name == NULL); - - if ((h = scf_handle_create(SCF_VERSION)) == NULL) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_create() failed: %s", - scf_strerror(scf_error())); - return (ISC_R_FAILURE); - } - - if (scf_handle_bind(h) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_bind() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((namelen = scf_myname(h, NULL, 0)) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_smf_get_instance memory " - "allocation failed: %s", - isc_result_totext(ISC_R_NOMEMORY)); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if (scf_myname(h, instance, namelen + 1) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - isc_mem_free(mctx, instance); - return (ISC_R_FAILURE); - } - - scf_handle_destroy(h); - *ins_name = instance; - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ - -/* main entry point, possibly hooked */ - -int -main(int argc, char *argv[]) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - -#ifdef HAVE_GPERFTOOLS_PROFILER - (void) ProfilerStart(NULL); -#endif - -#ifdef WIN32 - /* - * Prevent unbuffered I/O from crippling named performance on Windows - * when it is logging to stderr (e.g. in system tests). Use full - * buffering (_IOFBF) as line buffering (_IOLBF) is unavailable on - * Windows and fflush() is called anyway after each log message gets - * written to the default stderr logging channels created by libisc. - */ - setvbuf(stderr, NULL, _IOFBF, BUFSIZ); -#endif - -#ifdef HAVE_LIBXML2 - xmlInitThreads(); -#endif /* HAVE_LIBXML2 */ - - /* - * Record version in core image. - * strings named.core | grep "named version:" - */ - strlcat(version, -#if defined(NO_VERSION_DATE) || !defined(__DATE__) - "named version: BIND " VERSION " <" SRCID ">", -#else - "named version: BIND " VERSION " <" SRCID "> (" __DATE__ ")", -#endif - sizeof(version)); - result = isc_file_progname(*argv, program_name, sizeof(program_name)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("program name too long"); - - if (strcmp(program_name, "lwresd") == 0) - ns_g_lwresdonly = true; - - isc_assertion_setcallback(assertion_failed); - isc_error_setfatal(library_fatal_error); - isc_error_setunexpected(library_unexpected_error); - - ns_os_init(program_name); - - dns_result_register(); - dst_result_register(); - isccc_result_register(); -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - - parse_command_line(argc, argv); - -#ifdef ENABLE_AFL - if (ns_g_fuzz_type != ns_fuzz_none) { - named_fuzz_setup(); - } - - if (ns_g_fuzz_type == ns_fuzz_resolver) { - dns_resolver_setfuzzing(); - } else if (ns_g_fuzz_type == ns_fuzz_http) { - isc_httpd_setfinishhook(named_fuzz_notify); - } -#endif - /* - * Warn about common configuration error. - */ - if (ns_g_chrootdir != NULL) { - int len = strlen(ns_g_chrootdir); - if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 && - (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\')) - ns_main_earlywarning("config filename (-c %s) contains " - "chroot path (-t %s)", - ns_g_conffile, ns_g_chrootdir); - } - - result = isc_mem_create(0, 0, &ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_mem_create() failed: %s", - isc_result_totext(result)); - isc_mem_setname(ns_g_mctx, "main", NULL); - - setup(); - - /* - * Start things running and then wait for a shutdown request - * or reload. - */ - do { - result = isc_app_run(); - - if (result == ISC_R_RELOAD) { - ns_server_reloadwanted(ns_g_server); - } else if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run(): %s", - isc_result_totext(result)); - /* - * Force exit. - */ - result = ISC_R_SUCCESS; - } - } while (result != ISC_R_SUCCESS); - -#ifdef HAVE_LIBSCF - if (ns_smf_want_disable == 1) { - result = ns_smf_get_instance(&instance, 1, ns_g_mctx); - if (result == ISC_R_SUCCESS && instance != NULL) { - if (smf_disable_instance(instance, 0) != 0) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "smf_disable_instance() " - "failed for %s : %s", - instance, - scf_strerror(scf_error())); - } - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); - } -#endif /* HAVE_LIBSCF */ - - cleanup(); - - if (want_stats) { - isc_mem_stats(ns_g_mctx, stdout); - isc_mutex_stats(stdout); - } - - if (ns_g_memstatistics && memstats != NULL) { - FILE *fp = NULL; - result = isc_stdio_open(memstats, "w", &fp); - if (result == ISC_R_SUCCESS) { - isc_mem_stats(ns_g_mctx, fp); - isc_mutex_stats(fp); - (void) isc_stdio_close(fp); - } - } - isc_mem_destroy(&ns_g_mctx); - isc_mem_checkdestroyed(stderr); - - ns_main_setmemstats(NULL); - - isc_app_finish(); - - ns_os_closedevnull(); - - ns_os_shutdown(); - -#ifdef HAVE_LIBXML2 - xmlCleanupThreads(); -#endif /* HAVE_LIBXML2 */ - -#ifdef HAVE_GPERFTOOLS_PROFILER - ProfilerStop(); -#endif - - return (0); -} diff --git a/bin/named-pkcs11/named.8 b/bin/named-pkcs11/named.8 deleted file mode 100644 index 0acd6b5..0000000 --- a/bin/named-pkcs11/named.8 +++ /dev/null @@ -1,379 +0,0 @@ -.\" Copyright (C) 2000, 2001, 2003-2009, 2011, 2013-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: named -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2014-02-19 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "NAMED" "8" "2014\-02\-19" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -named \- Internet domain name server -.SH "SYNOPSIS" -.HP \w'\fBnamed\fR\ 'u -\fBnamed\fR [[\fB\-4\fR] | [\fB\-6\fR]] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-D\ \fR\fB\fIstring\fR\fR] [\fB\-E\ \fR\fB\fIengine\-name\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-L\ \fR\fB\fIlogfile\fR\fR] [\fB\-M\ \fR\fB\fIoption\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-U\ \fR\fB\fI#listeners\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-X\ \fR\fB\fIlock\-file\fR\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR] -.SH "DESCRIPTION" -.PP -\fBnamed\fR -is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC\&. For more information on the DNS, see RFCs 1033, 1034, and 1035\&. -.PP -When invoked without arguments, -\fBnamed\fR -will read the default configuration file -/etc/named\&.conf, read any initial data, and listen for queries\&. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/named\&.conf\&. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible -\fBdirectory\fR -option in the configuration file, -\fIconfig\-file\fR -should be an absolute pathname\&. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon\*(Aqs debug level to -\fIdebug\-level\fR\&. Debugging traces from -\fBnamed\fR -become more verbose as the debug level increases\&. -.RE -.PP -\-D \fIstring\fR -.RS 4 -Specifies a string that is used to identify a instance of -\fBnamed\fR -in a process listing\&. The contents of -\fIstring\fR -are not examined\&. -.RE -.PP -\-E \fIengine\-name\fR -.RS 4 -When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i\&.e\&. do not daemonize)\&. -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -stderr\&. -.RE -.PP -\-L \fIlogfile\fR -.RS 4 -Log to the file -\fBlogfile\fR -by default instead of the system log\&. -.RE -.PP -\-M \fIoption\fR -.RS 4 -Sets the default memory context options\&. Currently the only supported option is -\fIexternal\fR, which causes the internal memory manager to be bypassed in favor of system\-provided memory allocation functions\&. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags\&. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR\&. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\&. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs\&. If not specified, -\fBnamed\fR -will try to determine the number of CPUs present and create one thread per CPU\&. If it is unable to determine the number of CPUs, a single worker thread will be created\&. -.RE -.PP -\-p \fIport\fR -.RS 4 -Listen for queries on port -\fIport\fR\&. If not specified, the default is port 53\&. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -stdout -on exit\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.PP -\-S \fI#max\-socks\fR -.RS 4 -Allow -\fBnamed\fR -to use up to -\fI#max\-socks\fR -sockets\&. The default value is 4096 on systems built with default configuration options, and 21000 on systems built with "configure \-\-with\-tuning=large"\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be unnecessary for the vast majority of users\&. The use of this option could even be harmful because the specified value may exceed the limitation of the underlying system API\&. It is therefore set only when the default configuration causes exhaustion of file descriptors and the operational environment is known to support the specified number of sockets\&. Note also that the actual maximum number is normally a little fewer than the specified value because -\fBnamed\fR -reserves some file descriptors for its internal use\&. -.sp .5v -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn\*(Aqt enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail\&. -.sp .5v -.RE -.RE -.PP -\-U \fI#listeners\fR -.RS 4 -Use -\fI#listeners\fR -worker threads to listen for incoming UDP packets on each address\&. If not specified, -\fBnamed\fR -will calculate a default value based on the number of detected CPUs: 1 for 1 CPU, and the number of detected CPUs minus one for machines with more than 1 CPU\&. This cannot be increased to a value higher than the number of CPUs\&. If -\fB\-n\fR -has been set to a higher value than the number of detected CPUs, then -\fB\-U\fR -may be increased as high as that value, but no higher\&. On Windows, the number of UDP listeners is hardwired to 1 and this option has no effect\&. -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -On Linux, -\fBnamed\fR -uses the kernel\*(Aqs capability mechanism to drop all root privileges except the ability to -\fBbind(2)\fR -to a privileged port and set process resource limits\&. Unfortunately, this means that the -\fB\-u\fR -option only works when -\fBnamed\fR -is run on kernel 2\&.2\&.18 or later, or kernel 2\&.3\&.99\-pre3 or later, since previous kernels did not allow privileges to be retained after -\fBsetuid(2)\fR\&. -.sp .5v -.RE -.RE -.PP -\-v -.RS 4 -Report the version number and exit\&. -.RE -.PP -\-V -.RS 4 -Report the version number and build options, and exit\&. -.RE -.PP -\-X \fIlock\-file\fR -.RS 4 -Acquire a lock on the specified file at runtime; this helps to prevent duplicate -\fBnamed\fR -instances from running simultaneously\&. Use of this option overrides the -\fBlock\-file\fR -option in -named\&.conf\&. If set to -none, the lock file check is disabled\&. -.RE -.PP -\-x \fIcache\-file\fR -.RS 4 -Load data from -\fIcache\-file\fR -into the cache of the default view\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option must not be used\&. It is only of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.SH "SIGNALS" -.PP -In routine operation, signals should not be used to control the nameserver; -\fBrndc\fR -should be used instead\&. -.PP -SIGHUP -.RS 4 -Force a reload of the server\&. -.RE -.PP -SIGINT, SIGTERM -.RS 4 -Shut down the server\&. -.RE -.PP -The result of sending any other signals to the server is undefined\&. -.SH "CONFIGURATION" -.PP -The -\fBnamed\fR -configuration file is too complex to describe in detail here\&. A complete description is provided in the -BIND 9 Administrator Reference Manual\&. -.PP -\fBnamed\fR -inherits the -\fBumask\fR -(file creation mode mask) from the parent process\&. If files created by -\fBnamed\fR, such as journal files, need to have custom permissions, the -\fBumask\fR -should be set explicitly in the script used to start the -\fBnamed\fR -process\&. -.SH "FILES" -.PP -/etc/named\&.conf -.RS 4 -The default configuration file\&. -.RE -.PP -/var/run/named/named\&.pid -.RS 4 -The default process\-id file\&. -.RE -.SH "SEE ALSO" -.PP -RFC 1033, -RFC 1034, -RFC 1035, -\fBnamed-checkconf\fR(8), -\fBnamed-checkzone\fR(8), -\fBrndc\fR(8), -\fBlwresd\fR(8), -\fBnamed.conf\fR(5), -BIND 9 Administrator Reference Manual\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000, 2001, 2003-2009, 2011, 2013-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-pkcs11/named.conf.5 b/bin/named-pkcs11/named.conf.5 deleted file mode 100644 index 7d5b3ca..0000000 --- a/bin/named-pkcs11/named.conf.5 +++ /dev/null @@ -1,1026 +0,0 @@ -.\" Copyright (C) 2004-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: named.conf -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2020-03-12 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "NAMED\&.CONF" "5" "2020\-03\-12" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -named.conf \- configuration file for \fBnamed\fR -.SH "SYNOPSIS" -.HP \w'\fBnamed\&.conf\fR\ 'u -\fBnamed\&.conf\fR -.SH "DESCRIPTION" -.PP -named\&.conf -is the configuration file for -\fBnamed\fR\&. Statements are enclosed in braces and terminated with a semi\-colon\&. Clauses in the statements are also semi\-colon terminated\&. The usual comment styles are supported: -.PP -C style: /* */ -.PP -C++ style: // to end of line -.PP -Unix style: # to end of line -.SH "ACL" -.sp -.if n \{\ -.RS 4 -.\} -.nf -acl \fIstring\fR { \fIaddress_match_element\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "CONTROLS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -controls { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | - * ) [ port ( \fIinteger\fR | * ) ] allow - { \fIaddress_match_element\fR; \&.\&.\&. } [ - keys { \fIstring\fR; \&.\&.\&. } ] [ read\-only - \fIboolean\fR ]; - unix \fIquoted_string\fR perm \fIinteger\fR - owner \fIinteger\fR group \fIinteger\fR [ - keys { \fIstring\fR; \&.\&.\&. } ] [ read\-only - \fIboolean\fR ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "DLZ" -.sp -.if n \{\ -.RS 4 -.\} -.nf -dlz \fIstring\fR { - database \fIstring\fR; - search \fIboolean\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "DYNDB" -.sp -.if n \{\ -.RS 4 -.\} -.nf -dyndb \fIstring\fR \fIquoted_string\fR { - \fIunspecified\-text\fR }; -.fi -.if n \{\ -.RE -.\} -.SH "KEY" -.sp -.if n \{\ -.RS 4 -.\} -.nf -key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "LOGGING" -.sp -.if n \{\ -.RS 4 -.\} -.nf -logging { - category \fIstring\fR { \fIstring\fR; \&.\&.\&. }; - channel \fIstring\fR { - buffered \fIboolean\fR; - file \fIquoted_string\fR [ versions ( "unlimited" | \fIinteger\fR ) - ] [ size \fIsize\fR ]; - null; - print\-category \fIboolean\fR; - print\-severity \fIboolean\fR; - print\-time \fIboolean\fR; - severity \fIlog_severity\fR; - stderr; - syslog [ \fIsyslog_facility\fR ]; - }; -}; -.fi -.if n \{\ -.RE -.\} -.SH "LWRES" -.sp -.if n \{\ -.RS 4 -.\} -.nf -lwres { - listen\-on [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - lwres\-clients \fIinteger\fR; - lwres\-tasks \fIinteger\fR; - ndots \fIinteger\fR; - search { \fIstring\fR; \&.\&.\&. }; - view \fIstring\fR [ \fIclass\fR ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "MANAGED\-KEYS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -managed\-keys { \fIstring\fR \fIstring\fR \fIinteger\fR - \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "MASTERS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -masters \fIstring\fR [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ - port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "OPTIONS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -options { - acache\-cleaning\-interval \fIinteger\fR; - acache\-enable \fIboolean\fR; - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - allow\-new\-zones \fIboolean\fR; - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - answer\-cookie \fIboolean\fR; - attach\-cache \fIstring\fR; - auth\-nxdomain \fIboolean\fR; // default changed - auto\-dnssec ( allow | maintain | off ); - automatic\-interface\-scan \fIboolean\fR; - avoid\-v4\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - avoid\-v6\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - bindkeys\-file \fIquoted_string\fR; - blackhole { \fIaddress_match_element\fR; \&.\&.\&. }; - cache\-file \fIquoted_string\fR; - catalog\-zones { zone \fIstring\fR [ default\-masters [ port \fIinteger\fR ] - [ dscp \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ port - \fIinteger\fR ] | \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key - \fIstring\fR ]; \&.\&.\&. } ] [ zone\-directory \fIquoted_string\fR ] [ - in\-memory \fIboolean\fR ] [ min\-update\-interval \fIinteger\fR ]; \&.\&.\&. }; - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( master | slave | response - ) ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - cleaning\-interval \fIinteger\fR; - clients\-per\-query \fIinteger\fR; - cookie\-algorithm ( aes | sha1 | sha256 | siphash24 ); - cookie\-secret \fIstring\fR; - coresize ( default | unlimited | \fIsizeval\fR ); - datasize ( default | unlimited | \fIsizeval\fR ); - deny\-answer\-addresses { \fIaddress_match_element\fR; \&.\&.\&. } [ - except\-from { \fIquoted_string\fR; \&.\&.\&. } ]; - deny\-answer\-aliases { \fIquoted_string\fR; \&.\&.\&. } [ except\-from { - \fIquoted_string\fR; \&.\&.\&. } ]; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - directory \fIquoted_string\fR; - disable\-algorithms \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-ds\-digests \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-empty\-zone \fIstring\fR; - dns64 \fInetprefix\fR { - break\-dnssec \fIboolean\fR; - clients { \fIaddress_match_element\fR; \&.\&.\&. }; - exclude { \fIaddress_match_element\fR; \&.\&.\&. }; - mapped { \fIaddress_match_element\fR; \&.\&.\&. }; - recursive\-only \fIboolean\fR; - suffix \fIipv6_address\fR; - }; - dns64\-contact \fIstring\fR; - dns64\-server \fIstring\fR; - dnssec\-accept\-expired \fIboolean\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-enable \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-lookaside ( \fIstring\fR trust\-anchor - \fIstring\fR | auto | no ); - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - dnssec\-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; \&.\&.\&. }; - dnstap\-identity ( \fIquoted_string\fR | none | - hostname ); - dnstap\-output ( file | unix ) \fIquoted_string\fR; - dnstap\-version ( \fIquoted_string\fR | none ); - dscp \fIinteger\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { ( \fIquoted_string\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv4_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] ); \&.\&.\&. }; - dump\-file \fIquoted_string\fR; - edns\-udp\-size \fIinteger\fR; - empty\-contact \fIstring\fR; - empty\-server \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - fetch\-quota\-params \fIinteger\fR \fIfixedpoint\fR \fIfixedpoint\fR \fIfixedpoint\fR; - fetches\-per\-server \fIinteger\fR [ ( drop | fail ) ]; - fetches\-per\-zone \fIinteger\fR [ ( drop | fail ) ]; - files ( default | unlimited | \fIsizeval\fR ); - filter\-aaaa { \fIaddress_match_element\fR; \&.\&.\&. }; - filter\-aaaa\-on\-v4 ( break\-dnssec | \fIboolean\fR ); - filter\-aaaa\-on\-v6 ( break\-dnssec | \fIboolean\fR ); - flush\-zones\-on\-shutdown \fIboolean\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - fstrm\-set\-buffer\-hint \fIinteger\fR; - fstrm\-set\-flush\-timeout \fIinteger\fR; - fstrm\-set\-input\-queue\-size \fIinteger\fR; - fstrm\-set\-output\-notify\-threshold \fIinteger\fR; - fstrm\-set\-output\-queue\-model ( mpsc | spsc ); - fstrm\-set\-output\-queue\-size \fIinteger\fR; - fstrm\-set\-reopen\-interval \fIinteger\fR; - geoip\-directory ( \fIquoted_string\fR | none ); - geoip\-use\-ecs \fIboolean\fR; - heartbeat\-interval \fIinteger\fR; - hostname ( \fIquoted_string\fR | none ); - inline\-signing \fIboolean\fR; - interface\-interval \fIinteger\fR; - ixfr\-from\-differences ( master | slave | \fIboolean\fR ); - keep\-response\-order { \fIaddress_match_element\fR; \&.\&.\&. }; - key\-directory \fIquoted_string\fR; - lame\-ttl \fIttlval\fR; - listen\-on [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { - \fIaddress_match_element\fR; \&.\&.\&. }; - listen\-on\-v6 [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { - \fIaddress_match_element\fR; \&.\&.\&. }; - lmdb\-mapsize \fIsizeval\fR; - lock\-file ( \fIquoted_string\fR | none ); - managed\-keys\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - match\-mapped\-addresses \fIboolean\fR; - max\-acache\-size ( unlimited | \fIsizeval\fR ); - max\-cache\-size ( default | unlimited | \fIsizeval\fR | \fIpercentage\fR ); - max\-cache\-ttl \fIinteger\fR; - max\-clients\-per\-query \fIinteger\fR; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-ncache\-ttl \fIinteger\fR; - max\-records \fIinteger\fR; - max\-recursion\-depth \fIinteger\fR; - max\-recursion\-queries \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-rsa\-exponent\-size \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - memstatistics \fIboolean\fR; - memstatistics\-file \fIquoted_string\fR; - message\-compression \fIboolean\fR; - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - minimal\-any \fIboolean\fR; - minimal\-responses ( no\-auth | no\-auth\-recursive | \fIboolean\fR ); - multi\-master \fIboolean\fR; - no\-case\-compress { \fIaddress_match_element\fR; \&.\&.\&. }; - nocookie\-udp\-size \fIinteger\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-rate \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - nta\-lifetime \fIttlval\fR; - nta\-recheck \fIttlval\fR; - nxdomain\-redirect \fIstring\fR; - pid\-file ( \fIquoted_string\fR | none ); - port \fIinteger\fR; - preferred\-glue \fIstring\fR; - prefetch \fIinteger\fR [ \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - querylog \fIboolean\fR; - random\-device \fIquoted_string\fR; - rate\-limit { - all\-per\-second \fIinteger\fR; - errors\-per\-second \fIinteger\fR; - exempt\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - ipv4\-prefix\-length \fIinteger\fR; - ipv6\-prefix\-length \fIinteger\fR; - log\-only \fIboolean\fR; - max\-table\-size \fIinteger\fR; - min\-table\-size \fIinteger\fR; - nodata\-per\-second \fIinteger\fR; - nxdomains\-per\-second \fIinteger\fR; - qps\-scale \fIinteger\fR; - referrals\-per\-second \fIinteger\fR; - responses\-per\-second \fIinteger\fR; - slip \fIinteger\fR; - window \fIinteger\fR; - }; - recursing\-file \fIquoted_string\fR; - recursion \fIboolean\fR; - recursive\-clients \fIinteger\fR; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - require\-server\-cookie \fIboolean\fR; - reserved\-sockets \fIinteger\fR; - resolver\-query\-timeout \fIinteger\fR; - response\-policy { zone \fIstring\fR [ log \fIboolean\fR ] [ max\-policy\-ttl - \fIinteger\fR ] [ policy ( cname | disabled | drop | given | no\-op - | nodata | nxdomain | passthru | tcp\-only \fIquoted_string\fR ) ] [ - recursive\-only \fIboolean\fR ]; \&.\&.\&. } [ break\-dnssec \fIboolean\fR ] [ - max\-policy\-ttl \fIinteger\fR ] [ min\-ns\-dots \fIinteger\fR ] [ - nsip\-wait\-recurse \fIboolean\fR ] [ qname\-wait\-recurse \fIboolean\fR ] - [ recursive\-only \fIboolean\fR ]; - root\-delegation\-only [ exclude { \fIquoted_string\fR; \&.\&.\&. } ]; - root\-key\-sentinel \fIboolean\fR; - rrset\-order { [ class \fIstring\fR ] [ type \fIstring\fR ] [ name - \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; \&.\&.\&. }; - secroots\-file \fIquoted_string\fR; - send\-cookie \fIboolean\fR; - serial\-query\-rate \fIinteger\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-id ( \fIquoted_string\fR | none | hostname ); - servfail\-ttl \fIttlval\fR; - session\-keyalg \fIstring\fR; - session\-keyfile ( \fIquoted_string\fR | none ); - session\-keyname \fIstring\fR; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - sortlist { \fIaddress_match_element\fR; \&.\&.\&. }; - stacksize ( default | unlimited | \fIsizeval\fR ); - startup\-notify\-rate \fIinteger\fR; - statistics\-file \fIquoted_string\fR; - tcp\-clients \fIinteger\fR; - tcp\-listen\-queue \fIinteger\fR; - tkey\-dhkey \fIquoted_string\fR \fIinteger\fR; - tkey\-domain \fIquoted_string\fR; - tkey\-gssapi\-credential \fIquoted_string\fR; - tkey\-gssapi\-keytab \fIquoted_string\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-message\-size \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - transfers\-in \fIinteger\fR; - transfers\-out \fIinteger\fR; - transfers\-per\-ns \fIinteger\fR; - trust\-anchor\-telemetry \fIboolean\fR; // experimental - try\-tcp\-refresh \fIboolean\fR; - update\-check\-ksk \fIboolean\fR; - use\-alt\-transfer\-source \fIboolean\fR; - use\-v4\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - use\-v6\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - v6\-bias \fIinteger\fR; - version ( \fIquoted_string\fR | none ); - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "SERVER" -.sp -.if n \{\ -.RS 4 -.\} -.nf -server \fInetprefix\fR { - bogus \fIboolean\fR; - edns \fIboolean\fR; - edns\-udp\-size \fIinteger\fR; - edns\-version \fIinteger\fR; - keys \fIserver_key\fR; - max\-udp\-size \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - send\-cookie \fIboolean\fR; - tcp\-only \fIboolean\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - transfers \fIinteger\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "STATISTICS\-CHANNELS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -statistics\-channels { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | - * ) [ port ( \fIinteger\fR | * ) ] [ - allow { \fIaddress_match_element\fR; \&.\&.\&. - } ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "TRUSTED\-KEYS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -trusted\-keys { \fIstring\fR \fIinteger\fR \fIinteger\fR - \fIinteger\fR \fIquoted_string\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "VIEW" -.sp -.if n \{\ -.RS 4 -.\} -.nf -view \fIstring\fR [ \fIclass\fR ] { - acache\-cleaning\-interval \fIinteger\fR; - acache\-enable \fIboolean\fR; - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - allow\-new\-zones \fIboolean\fR; - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - attach\-cache \fIstring\fR; - auth\-nxdomain \fIboolean\fR; // default changed - auto\-dnssec ( allow | maintain | off ); - cache\-file \fIquoted_string\fR; - catalog\-zones { zone \fIstring\fR [ default\-masters [ port \fIinteger\fR ] - [ dscp \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ port - \fIinteger\fR ] | \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key - \fIstring\fR ]; \&.\&.\&. } ] [ zone\-directory \fIquoted_string\fR ] [ - in\-memory \fIboolean\fR ] [ min\-update\-interval \fIinteger\fR ]; \&.\&.\&. }; - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( master | slave | response - ) ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - cleaning\-interval \fIinteger\fR; - clients\-per\-query \fIinteger\fR; - deny\-answer\-addresses { \fIaddress_match_element\fR; \&.\&.\&. } [ - except\-from { \fIquoted_string\fR; \&.\&.\&. } ]; - deny\-answer\-aliases { \fIquoted_string\fR; \&.\&.\&. } [ except\-from { - \fIquoted_string\fR; \&.\&.\&. } ]; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - disable\-algorithms \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-ds\-digests \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-empty\-zone \fIstring\fR; - dlz \fIstring\fR { - database \fIstring\fR; - search \fIboolean\fR; - }; - dns64 \fInetprefix\fR { - break\-dnssec \fIboolean\fR; - clients { \fIaddress_match_element\fR; \&.\&.\&. }; - exclude { \fIaddress_match_element\fR; \&.\&.\&. }; - mapped { \fIaddress_match_element\fR; \&.\&.\&. }; - recursive\-only \fIboolean\fR; - suffix \fIipv6_address\fR; - }; - dns64\-contact \fIstring\fR; - dns64\-server \fIstring\fR; - dnssec\-accept\-expired \fIboolean\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-enable \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-lookaside ( \fIstring\fR trust\-anchor - \fIstring\fR | auto | no ); - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - dnssec\-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; \&.\&.\&. }; - dual\-stack\-servers [ port \fIinteger\fR ] { ( \fIquoted_string\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv4_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] ); \&.\&.\&. }; - dyndb \fIstring\fR \fIquoted_string\fR { - \fIunspecified\-text\fR }; - edns\-udp\-size \fIinteger\fR; - empty\-contact \fIstring\fR; - empty\-server \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - fetch\-quota\-params \fIinteger\fR \fIfixedpoint\fR \fIfixedpoint\fR \fIfixedpoint\fR; - fetches\-per\-server \fIinteger\fR [ ( drop | fail ) ]; - fetches\-per\-zone \fIinteger\fR [ ( drop | fail ) ]; - filter\-aaaa { \fIaddress_match_element\fR; \&.\&.\&. }; - filter\-aaaa\-on\-v4 ( break\-dnssec | \fIboolean\fR ); - filter\-aaaa\-on\-v6 ( break\-dnssec | \fIboolean\fR ); - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences ( master | slave | \fIboolean\fR ); - key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; - }; - key\-directory \fIquoted_string\fR; - lame\-ttl \fIttlval\fR; - lmdb\-mapsize \fIsizeval\fR; - managed\-keys { \fIstring\fR \fIstring\fR - \fIinteger\fR \fIinteger\fR \fIinteger\fR - \fIquoted_string\fR; \&.\&.\&. }; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - match\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - match\-destinations { \fIaddress_match_element\fR; \&.\&.\&. }; - match\-recursive\-only \fIboolean\fR; - max\-acache\-size ( unlimited | \fIsizeval\fR ); - max\-cache\-size ( default | unlimited | \fIsizeval\fR | \fIpercentage\fR ); - max\-cache\-ttl \fIinteger\fR; - max\-clients\-per\-query \fIinteger\fR; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-ncache\-ttl \fIinteger\fR; - max\-records \fIinteger\fR; - max\-recursion\-depth \fIinteger\fR; - max\-recursion\-queries \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - message\-compression \fIboolean\fR; - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - minimal\-any \fIboolean\fR; - minimal\-responses ( no\-auth | no\-auth\-recursive | \fIboolean\fR ); - multi\-master \fIboolean\fR; - no\-case\-compress { \fIaddress_match_element\fR; \&.\&.\&. }; - nocookie\-udp\-size \fIinteger\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - nta\-lifetime \fIttlval\fR; - nta\-recheck \fIttlval\fR; - nxdomain\-redirect \fIstring\fR; - preferred\-glue \fIstring\fR; - prefetch \fIinteger\fR [ \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - rate\-limit { - all\-per\-second \fIinteger\fR; - errors\-per\-second \fIinteger\fR; - exempt\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - ipv4\-prefix\-length \fIinteger\fR; - ipv6\-prefix\-length \fIinteger\fR; - log\-only \fIboolean\fR; - max\-table\-size \fIinteger\fR; - min\-table\-size \fIinteger\fR; - nodata\-per\-second \fIinteger\fR; - nxdomains\-per\-second \fIinteger\fR; - qps\-scale \fIinteger\fR; - referrals\-per\-second \fIinteger\fR; - responses\-per\-second \fIinteger\fR; - slip \fIinteger\fR; - window \fIinteger\fR; - }; - recursion \fIboolean\fR; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - require\-server\-cookie \fIboolean\fR; - resolver\-query\-timeout \fIinteger\fR; - response\-policy { zone \fIstring\fR [ log \fIboolean\fR ] [ max\-policy\-ttl - \fIinteger\fR ] [ policy ( cname | disabled | drop | given | no\-op - | nodata | nxdomain | passthru | tcp\-only \fIquoted_string\fR ) ] [ - recursive\-only \fIboolean\fR ]; \&.\&.\&. } [ break\-dnssec \fIboolean\fR ] [ - max\-policy\-ttl \fIinteger\fR ] [ min\-ns\-dots \fIinteger\fR ] [ - nsip\-wait\-recurse \fIboolean\fR ] [ qname\-wait\-recurse \fIboolean\fR ] - [ recursive\-only \fIboolean\fR ]; - root\-delegation\-only [ exclude { \fIquoted_string\fR; \&.\&.\&. } ]; - root\-key\-sentinel \fIboolean\fR; - rrset\-order { [ class \fIstring\fR ] [ type \fIstring\fR ] [ name - \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; \&.\&.\&. }; - send\-cookie \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server \fInetprefix\fR { - bogus \fIboolean\fR; - edns \fIboolean\fR; - edns\-udp\-size \fIinteger\fR; - edns\-version \fIinteger\fR; - keys \fIserver_key\fR; - max\-udp\-size \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * - ) ] [ dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR - | * ) ] [ dscp \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port - ( \fIinteger\fR | * ) ] ) | ( [ [ address ] ( - \fIipv4_address\fR | * ) ] port ( \fIinteger\fR | * ) ) ) [ - dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ - port ( \fIinteger\fR | * ) ] ) | ( [ [ address ] ( - \fIipv6_address\fR | * ) ] port ( \fIinteger\fR | * ) ) ) [ - dscp \fIinteger\fR ]; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - send\-cookie \fIboolean\fR; - tcp\-only \fIboolean\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - transfers \fIinteger\fR; - }; - servfail\-ttl \fIttlval\fR; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - sortlist { \fIaddress_match_element\fR; \&.\&.\&. }; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - trust\-anchor\-telemetry \fIboolean\fR; // experimental - trusted\-keys { \fIstring\fR \fIinteger\fR - \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; - \&.\&.\&. }; - try\-tcp\-refresh \fIboolean\fR; - update\-check\-ksk \fIboolean\fR; - use\-alt\-transfer\-source \fIboolean\fR; - v6\-bias \fIinteger\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - zone \fIstring\fR [ \fIclass\fR ] { - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( - \fImasters\fR | \fIipv4_address\fR [ port \fIinteger\fR ] | - \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key \fIstring\fR ]; - \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - auto\-dnssec ( allow | maintain | off ); - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - dialup ( notify | notify\-passive | passive | refresh | - \fIboolean\fR ); - dlz \fIstring\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - file \fIquoted_string\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( - \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ - dscp \fIinteger\fR ]; \&.\&.\&. }; - in\-view \fIstring\fR; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences \fIboolean\fR; - journal \fIquoted_string\fR; - key\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - masters [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR - | \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ - port \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - max\-ixfr\-log\-size ( default | unlimited | - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-records \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * - ) ] [ dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR - | * ) ] [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - pubkey \fIinteger\fR - \fIinteger\fR - \fIinteger\fR - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-addresses { ( \fIipv4_address\fR | \fIipv6_address\fR ); \&.\&.\&. }; - server\-names { \fIquoted_string\fR; \&.\&.\&. }; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - try\-tcp\-refresh \fIboolean\fR; - type ( delegation\-only | forward | hint | master | redirect - | slave | static\-stub | stub ); - update\-check\-ksk \fIboolean\fR; - update\-policy ( local | { ( deny | grant ) \fIstring\fR ( - 6to4\-self | external | krb5\-self | krb5\-selfsub | - krb5\-subdomain | ms\-self | ms\-selfsub | ms\-subdomain | - name | self | selfsub | selfwild | subdomain | tcp\-self - | wildcard | zonesub ) [ \fIstring\fR ] \fIrrtypelist\fR; \&.\&.\&. }; - use\-alt\-transfer\-source \fIboolean\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); - }; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "ZONE" -.sp -.if n \{\ -.RS 4 -.\} -.nf -zone \fIstring\fR [ \fIclass\fR ] { - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - auto\-dnssec ( allow | maintain | off ); - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - dlz \fIstring\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - file \fIquoted_string\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - in\-view \fIstring\fR; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences \fIboolean\fR; - journal \fIquoted_string\fR; - key\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - masters [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-records \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - pubkey \fIinteger\fR \fIinteger\fR - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-addresses { ( \fIipv4_address\fR | \fIipv6_address\fR ); \&.\&.\&. }; - server\-names { \fIquoted_string\fR; \&.\&.\&. }; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - try\-tcp\-refresh \fIboolean\fR; - type ( delegation\-only | forward | hint | master | redirect | slave - | static\-stub | stub ); - update\-check\-ksk \fIboolean\fR; - update\-policy ( local | { ( deny | grant ) \fIstring\fR ( 6to4\-self | - external | krb5\-self | krb5\-selfsub | krb5\-subdomain | ms\-self - | ms\-selfsub | ms\-subdomain | name | self | selfsub | selfwild - | subdomain | tcp\-self | wildcard | zonesub ) [ \fIstring\fR ] - \fIrrtypelist\fR; \&.\&.\&. }; - use\-alt\-transfer\-source \fIboolean\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "FILES" -.PP -/etc/named\&.conf -.SH "SEE ALSO" -.PP -\fBddns-confgen\fR(8), -\fBnamed\fR(8), -\fBnamed-checkconf\fR(8), -\fBrndc\fR(8), -\fBrndc-confgen\fR(8), -BIND 9 Administrator Reference Manual\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2004-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-pkcs11/named.conf.docbook b/bin/named-pkcs11/named.conf.docbook deleted file mode 100644 index ed137f2..0000000 --- a/bin/named-pkcs11/named.conf.docbook +++ /dev/null @@ -1,1005 +0,0 @@ - - - - - - - 2020-03-12 - - - ISC - Internet Systems Consortium, Inc. - - - - named.conf - 5 - BIND9 - - - - named.conf - configuration file for named - - - - - 2004 - 2005 - 2006 - 2007 - 2008 - 2009 - 2010 - 2011 - 2012 - 2013 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - named.conf - - - - DESCRIPTION - - named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - - - C style: /* */ - - - C++ style: // to end of line - - - Unix style: # to end of line - - - - ACL - - -acl string { address_match_element; ... }; - - - - CONTROLS - - -controls { - inet ( ipv4_address | ipv6_address | - * ) [ port ( integer | * ) ] allow - { address_match_element; ... } [ - keys { string; ... } ] [ read-only - boolean ]; - unix quoted_string perm integer - owner integer group integer [ - keys { string; ... } ] [ read-only - boolean ]; -}; - - - - DLZ - - -dlz string { - database string; - search boolean; -}; - - - - DYNDB - - -dyndb string quoted_string { - unspecified-text }; - - - - KEY - - -key string { - algorithm string; - secret string; -}; - - - - LOGGING - - -logging { - category string { string; ... }; - channel string { - buffered boolean; - file quoted_string [ versions ( "unlimited" | integer ) - ] [ size size ]; - null; - print-category boolean; - print-severity boolean; - print-time boolean; - severity log_severity; - stderr; - syslog [ syslog_facility ]; - }; -}; - - - - LWRES - - -lwres { - listen-on [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - lwres-clients integer; - lwres-tasks integer; - ndots integer; - search { string; ... }; - view string [ class ]; -}; - - - - MANAGED-KEYS - - -managed-keys { string string integer - integer integer quoted_string; ... }; - - - - MASTERS - - -masters string [ port integer ] [ dscp - integer ] { ( masters | ipv4_address [ - port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - - - - OPTIONS - - -options { - acache-cleaning-interval integer; - acache-enable boolean; - additional-from-auth boolean; - additional-from-cache boolean; - allow-new-zones boolean; - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-query-cache-on { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-recursion { address_match_element; ... }; - allow-recursion-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - answer-cookie boolean; - attach-cache string; - auth-nxdomain boolean; // default changed - auto-dnssec ( allow | maintain | off ); - automatic-interface-scan boolean; - avoid-v4-udp-ports { portrange; ... }; - avoid-v6-udp-ports { portrange; ... }; - bindkeys-file quoted_string; - blackhole { address_match_element; ... }; - cache-file quoted_string; - catalog-zones { zone string [ default-masters [ port integer ] - [ dscp integer ] { ( masters | ipv4_address [ port - integer ] | ipv6_address [ port integer ] ) [ key - string ]; ... } ] [ zone-directory quoted_string ] [ - in-memory boolean ] [ min-update-interval integer ]; ... }; - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( master | slave | response - ) ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - cleaning-interval integer; - clients-per-query integer; - cookie-algorithm ( aes | sha1 | sha256 | siphash24 ); - cookie-secret string; - coresize ( default | unlimited | sizeval ); - datasize ( default | unlimited | sizeval ); - deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; - dialup ( notify | notify-passive | passive | refresh | boolean ); - directory quoted_string; - disable-algorithms string { string; - ... }; - disable-ds-digests string { string; - ... }; - disable-empty-zone string; - dns64 netprefix { - break-dnssec boolean; - clients { address_match_element; ... }; - exclude { address_match_element; ... }; - mapped { address_match_element; ... }; - recursive-only boolean; - suffix ipv6_address; - }; - dns64-contact string; - dns64-server string; - dnssec-accept-expired boolean; - dnssec-dnskey-kskonly boolean; - dnssec-enable boolean; - dnssec-loadkeys-interval integer; - dnssec-lookaside ( string trust-anchor - string | auto | no ); - dnssec-must-be-secure string boolean; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dnstap-identity ( quoted_string | none | - hostname ); - dnstap-output ( file | unix ) quoted_string; - dnstap-version ( quoted_string | none ); - dscp integer; - dual-stack-servers [ port integer ] { ( quoted_string [ port - integer ] [ dscp integer ] | ipv4_address [ port - integer ] [ dscp integer ] | ipv6_address [ port - integer ] [ dscp integer ] ); ... }; - dump-file quoted_string; - edns-udp-size integer; - empty-contact string; - empty-server string; - empty-zones-enable boolean; - fetch-quota-params integer fixedpoint fixedpoint fixedpoint; - fetches-per-server integer [ ( drop | fail ) ]; - fetches-per-zone integer [ ( drop | fail ) ]; - files ( default | unlimited | sizeval ); - filter-aaaa { address_match_element; ... }; - filter-aaaa-on-v4 ( break-dnssec | boolean ); - filter-aaaa-on-v6 ( break-dnssec | boolean ); - flush-zones-on-shutdown boolean; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - fstrm-set-buffer-hint integer; - fstrm-set-flush-timeout integer; - fstrm-set-input-queue-size integer; - fstrm-set-output-notify-threshold integer; - fstrm-set-output-queue-model ( mpsc | spsc ); - fstrm-set-output-queue-size integer; - fstrm-set-reopen-interval integer; - geoip-directory ( quoted_string | none ); - geoip-use-ecs boolean; - heartbeat-interval integer; - hostname ( quoted_string | none ); - inline-signing boolean; - interface-interval integer; - ixfr-from-differences ( master | slave | boolean ); - keep-response-order { address_match_element; ... }; - key-directory quoted_string; - lame-ttl ttlval; - listen-on [ port integer ] [ dscp - integer ] { - address_match_element; ... }; - listen-on-v6 [ port integer ] [ dscp - integer ] { - address_match_element; ... }; - lmdb-mapsize sizeval; - lock-file ( quoted_string | none ); - managed-keys-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - match-mapped-addresses boolean; - max-acache-size ( unlimited | sizeval ); - max-cache-size ( default | unlimited | sizeval | percentage ); - max-cache-ttl integer; - max-clients-per-query integer; - max-journal-size ( unlimited | sizeval ); - max-ncache-ttl integer; - max-records integer; - max-recursion-depth integer; - max-recursion-queries integer; - max-refresh-time integer; - max-retry-time integer; - max-rsa-exponent-size integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-udp-size integer; - max-zone-ttl ( unlimited | ttlval ); - memstatistics boolean; - memstatistics-file quoted_string; - message-compression boolean; - min-refresh-time integer; - min-retry-time integer; - minimal-any boolean; - minimal-responses ( no-auth | no-auth-recursive | boolean ); - multi-master boolean; - no-case-compress { address_match_element; ... }; - nocookie-udp-size integer; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-rate integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - nta-lifetime ttlval; - nta-recheck ttlval; - nxdomain-redirect string; - pid-file ( quoted_string | none ); - port integer; - preferred-glue string; - prefetch integer [ integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - querylog boolean; - random-device quoted_string; - rate-limit { - all-per-second integer; - errors-per-second integer; - exempt-clients { address_match_element; ... }; - ipv4-prefix-length integer; - ipv6-prefix-length integer; - log-only boolean; - max-table-size integer; - min-table-size integer; - nodata-per-second integer; - nxdomains-per-second integer; - qps-scale integer; - referrals-per-second integer; - responses-per-second integer; - slip integer; - window integer; - }; - recursing-file quoted_string; - recursion boolean; - recursive-clients integer; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - require-server-cookie boolean; - reserved-sockets integer; - resolver-query-timeout integer; - response-policy { zone string [ log boolean ] [ max-policy-ttl - integer ] [ policy ( cname | disabled | drop | given | no-op - | nodata | nxdomain | passthru | tcp-only quoted_string ) ] [ - recursive-only boolean ]; ... } [ break-dnssec boolean ] [ - max-policy-ttl integer ] [ min-ns-dots integer ] [ - nsip-wait-recurse boolean ] [ qname-wait-recurse boolean ] - [ recursive-only boolean ]; - root-delegation-only [ exclude { quoted_string; ... } ]; - root-key-sentinel boolean; - rrset-order { [ class string ] [ type string ] [ name - quoted_string ] string string; ... }; - secroots-file quoted_string; - send-cookie boolean; - serial-query-rate integer; - serial-update-method ( date | increment | unixtime ); - server-id ( quoted_string | none | hostname ); - servfail-ttl ttlval; - session-keyalg string; - session-keyfile ( quoted_string | none ); - session-keyname string; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - sortlist { address_match_element; ... }; - stacksize ( default | unlimited | sizeval ); - startup-notify-rate integer; - statistics-file quoted_string; - tcp-clients integer; - tcp-listen-queue integer; - tkey-dhkey quoted_string integer; - tkey-domain quoted_string; - tkey-gssapi-credential quoted_string; - tkey-gssapi-keytab quoted_string; - transfer-format ( many-answers | one-answer ); - transfer-message-size integer; - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - transfers-in integer; - transfers-out integer; - transfers-per-ns integer; - trust-anchor-telemetry boolean; // experimental - try-tcp-refresh boolean; - update-check-ksk boolean; - use-alt-transfer-source boolean; - use-v4-udp-ports { portrange; ... }; - use-v6-udp-ports { portrange; ... }; - v6-bias integer; - version ( quoted_string | none ); - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - zone-statistics ( full | terse | none | boolean ); -}; - - - - SERVER - - -server netprefix { - bogus boolean; - edns boolean; - edns-udp-size integer; - edns-version integer; - keys server_key; - max-udp-size integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - send-cookie boolean; - tcp-only boolean; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - transfers integer; -}; - - - - STATISTICS-CHANNELS - - -statistics-channels { - inet ( ipv4_address | ipv6_address | - * ) [ port ( integer | * ) ] [ - allow { address_match_element; ... - } ]; -}; - - - - TRUSTED-KEYS - - -trusted-keys { string integer integer - integer quoted_string; ... }; - - - - VIEW - - -view string [ class ] { - acache-cleaning-interval integer; - acache-enable boolean; - additional-from-auth boolean; - additional-from-cache boolean; - allow-new-zones boolean; - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-query-cache-on { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-recursion { address_match_element; ... }; - allow-recursion-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - attach-cache string; - auth-nxdomain boolean; // default changed - auto-dnssec ( allow | maintain | off ); - cache-file quoted_string; - catalog-zones { zone string [ default-masters [ port integer ] - [ dscp integer ] { ( masters | ipv4_address [ port - integer ] | ipv6_address [ port integer ] ) [ key - string ]; ... } ] [ zone-directory quoted_string ] [ - in-memory boolean ] [ min-update-interval integer ]; ... }; - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( master | slave | response - ) ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - cleaning-interval integer; - clients-per-query integer; - deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; - dialup ( notify | notify-passive | passive | refresh | boolean ); - disable-algorithms string { string; - ... }; - disable-ds-digests string { string; - ... }; - disable-empty-zone string; - dlz string { - database string; - search boolean; - }; - dns64 netprefix { - break-dnssec boolean; - clients { address_match_element; ... }; - exclude { address_match_element; ... }; - mapped { address_match_element; ... }; - recursive-only boolean; - suffix ipv6_address; - }; - dns64-contact string; - dns64-server string; - dnssec-accept-expired boolean; - dnssec-dnskey-kskonly boolean; - dnssec-enable boolean; - dnssec-loadkeys-interval integer; - dnssec-lookaside ( string trust-anchor - string | auto | no ); - dnssec-must-be-secure string boolean; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dual-stack-servers [ port integer ] { ( quoted_string [ port - integer ] [ dscp integer ] | ipv4_address [ port - integer ] [ dscp integer ] | ipv6_address [ port - integer ] [ dscp integer ] ); ... }; - dyndb string quoted_string { - unspecified-text }; - edns-udp-size integer; - empty-contact string; - empty-server string; - empty-zones-enable boolean; - fetch-quota-params integer fixedpoint fixedpoint fixedpoint; - fetches-per-server integer [ ( drop | fail ) ]; - fetches-per-zone integer [ ( drop | fail ) ]; - filter-aaaa { address_match_element; ... }; - filter-aaaa-on-v4 ( break-dnssec | boolean ); - filter-aaaa-on-v6 ( break-dnssec | boolean ); - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - inline-signing boolean; - ixfr-from-differences ( master | slave | boolean ); - key string { - algorithm string; - secret string; - }; - key-directory quoted_string; - lame-ttl ttlval; - lmdb-mapsize sizeval; - managed-keys { string string - integer integer integer - quoted_string; ... }; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - match-clients { address_match_element; ... }; - match-destinations { address_match_element; ... }; - match-recursive-only boolean; - max-acache-size ( unlimited | sizeval ); - max-cache-size ( default | unlimited | sizeval | percentage ); - max-cache-ttl integer; - max-clients-per-query integer; - max-journal-size ( unlimited | sizeval ); - max-ncache-ttl integer; - max-records integer; - max-recursion-depth integer; - max-recursion-queries integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-udp-size integer; - max-zone-ttl ( unlimited | ttlval ); - message-compression boolean; - min-refresh-time integer; - min-retry-time integer; - minimal-any boolean; - minimal-responses ( no-auth | no-auth-recursive | boolean ); - multi-master boolean; - no-case-compress { address_match_element; ... }; - nocookie-udp-size integer; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - nta-lifetime ttlval; - nta-recheck ttlval; - nxdomain-redirect string; - preferred-glue string; - prefetch integer [ integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - rate-limit { - all-per-second integer; - errors-per-second integer; - exempt-clients { address_match_element; ... }; - ipv4-prefix-length integer; - ipv6-prefix-length integer; - log-only boolean; - max-table-size integer; - min-table-size integer; - nodata-per-second integer; - nxdomains-per-second integer; - qps-scale integer; - referrals-per-second integer; - responses-per-second integer; - slip integer; - window integer; - }; - recursion boolean; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - require-server-cookie boolean; - resolver-query-timeout integer; - response-policy { zone string [ log boolean ] [ max-policy-ttl - integer ] [ policy ( cname | disabled | drop | given | no-op - | nodata | nxdomain | passthru | tcp-only quoted_string ) ] [ - recursive-only boolean ]; ... } [ break-dnssec boolean ] [ - max-policy-ttl integer ] [ min-ns-dots integer ] [ - nsip-wait-recurse boolean ] [ qname-wait-recurse boolean ] - [ recursive-only boolean ]; - root-delegation-only [ exclude { quoted_string; ... } ]; - root-key-sentinel boolean; - rrset-order { [ class string ] [ type string ] [ name - quoted_string ] string string; ... }; - send-cookie boolean; - serial-update-method ( date | increment | unixtime ); - server netprefix { - bogus boolean; - edns boolean; - edns-udp-size integer; - edns-version integer; - keys server_key; - max-udp-size integer; - notify-source ( ipv4_address | * ) [ port ( integer | * - ) ] [ dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer - | * ) ] [ dscp integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port - ( integer | * ) ] ) | ( [ [ address ] ( - ipv4_address | * ) ] port ( integer | * ) ) ) [ - dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ - port ( integer | * ) ] ) | ( [ [ address ] ( - ipv6_address | * ) ] port ( integer | * ) ) ) [ - dscp integer ]; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - send-cookie boolean; - tcp-only boolean; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - transfers integer; - }; - servfail-ttl ttlval; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - sortlist { address_match_element; ... }; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - trust-anchor-telemetry boolean; // experimental - trusted-keys { string integer - integer integer quoted_string; - ... }; - try-tcp-refresh boolean; - update-check-ksk boolean; - use-alt-transfer-source boolean; - v6-bias integer; - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - zone string [ class ] { - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( - masters | ipv4_address [ port integer ] | - ipv6_address [ port integer ] ) [ key string ]; - ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - auto-dnssec ( allow | maintain | off ); - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - database string; - delegation-only boolean; - dialup ( notify | notify-passive | passive | refresh | - boolean ); - dlz string; - dnssec-dnskey-kskonly boolean; - dnssec-loadkeys-interval integer; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - file quoted_string; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( - ipv4_address | ipv6_address ) [ port integer ] [ - dscp integer ]; ... }; - in-view string; - inline-signing boolean; - ixfr-from-differences boolean; - journal quoted_string; - key-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - masters [ port integer ] [ dscp integer ] { ( masters - | ipv4_address [ port integer ] | ipv6_address [ - port integer ] ) [ key string ]; ... }; - max-ixfr-log-size ( default | unlimited | - max-journal-size ( unlimited | sizeval ); - max-records integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-zone-ttl ( unlimited | ttlval ); - min-refresh-time integer; - min-retry-time integer; - multi-master boolean; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * - ) ] [ dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer - | * ) ] [ dscp integer ]; - notify-to-soa boolean; - pubkey integer - integer - integer - request-expire boolean; - request-ixfr boolean; - serial-update-method ( date | increment | unixtime ); - server-addresses { ( ipv4_address | ipv6_address ); ... }; - server-names { quoted_string; ... }; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - transfer-source ( ipv4_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - try-tcp-refresh boolean; - type ( delegation-only | forward | hint | master | redirect - | slave | static-stub | stub ); - update-check-ksk boolean; - update-policy ( local | { ( deny | grant ) string ( - 6to4-self | external | krb5-self | krb5-selfsub | - krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | - name | self | selfsub | selfwild | subdomain | tcp-self - | wildcard | zonesub ) [ string ] rrtypelist; ... }; - use-alt-transfer-source boolean; - zero-no-soa-ttl boolean; - zone-statistics ( full | terse | none | boolean ); - }; - zone-statistics ( full | terse | none | boolean ); -}; - - - - ZONE - - -zone string [ class ] { - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - auto-dnssec ( allow | maintain | off ); - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - database string; - delegation-only boolean; - dialup ( notify | notify-passive | passive | refresh | boolean ); - dlz string; - dnssec-dnskey-kskonly boolean; - dnssec-loadkeys-interval integer; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - file quoted_string; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - in-view string; - inline-signing boolean; - ixfr-from-differences boolean; - journal quoted_string; - key-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - masters [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - max-journal-size ( unlimited | sizeval ); - max-records integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-zone-ttl ( unlimited | ttlval ); - min-refresh-time integer; - min-retry-time integer; - multi-master boolean; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - pubkey integer integer - request-expire boolean; - request-ixfr boolean; - serial-update-method ( date | increment | unixtime ); - server-addresses { ( ipv4_address | ipv6_address ); ... }; - server-names { quoted_string; ... }; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - try-tcp-refresh boolean; - type ( delegation-only | forward | hint | master | redirect | slave - | static-stub | stub ); - update-check-ksk boolean; - update-policy ( local | { ( deny | grant ) string ( 6to4-self | - external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self - | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild - | subdomain | tcp-self | wildcard | zonesub ) [ string ] - rrtypelist; ... }; - use-alt-transfer-source boolean; - zero-no-soa-ttl boolean; - zone-statistics ( full | terse | none | boolean ); -}; - - - - FILES - - /etc/named.conf - - - - SEE ALSO - - - ddns-confgen8 - , - - named8 - , - - named-checkconf8 - , - - rndc8 - , - - rndc-confgen8 - , - BIND 9 Administrator Reference Manual. - - - - diff --git a/bin/named-pkcs11/named.conf.html b/bin/named-pkcs11/named.conf.html deleted file mode 100644 index e0bcac8..0000000 --- a/bin/named-pkcs11/named.conf.html +++ /dev/null @@ -1,940 +0,0 @@ - - - - - -named.conf - - -
-
-
-

Name

-

named.conf — configuration file for named

-
-
-

Synopsis

-

named.conf

-
-
-

DESCRIPTION

-

named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: -

-

- C style: /* */ -

-

- C++ style: // to end of line -

-

- Unix style: # to end of line -

-
-
-

ACL

-


-acl�string�{�address_match_element;�...�};
-

-
-
-

CONTROLS

-


-controls�{
- inet�(�ipv4_address�|�ipv6_address�|
- ����*�)�[�port�(�integer�|�*�)�]�allow
- ����{�address_match_element;�...�}�[
- ����keys�{�string;�...�}�]�[�read-only
- ����boolean�];
- unix�quoted_string�perm�integer
- ����owner�integer�group�integer�[
- ����keys�{�string;�...�}�]�[�read-only
- ����boolean�];
-};
-

-
-
-

DLZ

-


-dlz�string�{
- database�string;
- search�boolean;
-};
-

-
-
-

DYNDB

-


-dyndb�string�quoted_string�{
-����unspecified-text�};
-

-
-
-

KEY

-


-key�string�{
- algorithm�string;
- secret�string;
-};
-

-
-
-

LOGGING

-


-logging�{
- category�string�{�string;�...�};
- channel�string�{
- buffered�boolean;
- file�quoted_string�[�versions�(�"unlimited"�|�integer�)
- ����]�[�size�size�];
- null;
- print-category�boolean;
- print-severity�boolean;
- print-time�boolean;
- severity�log_severity;
- stderr;
- syslog�[�syslog_facility�];
- };
-};
-

-
-
-

LWRES

-


-lwres�{
- listen-on�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- lwres-clients�integer;
- lwres-tasks�integer;
- ndots�integer;
- search�{�string;�...�};
- view�string�[�class�];
-};
-

-
-
-

MANAGED-KEYS

-


-managed-keys�{�string�string�integer
-����integer�integer�quoted_string;�...�};
-

-
-
-

MASTERS

-


-masters�string�[�port�integer�]�[�dscp
-����integer�]�{�(�masters�|�ipv4_address�[
-����port�integer�]�|�ipv6_address�[�port
-����integer�]�)�[�key�string�];�...�};
-

-
-
-

OPTIONS

-


-options�{
- acache-cleaning-interval�integer;
- acache-enable�boolean;
- additional-from-auth�boolean;
- additional-from-cache�boolean;
- allow-new-zones�boolean;
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-cache�{�address_match_element;�...�};
- allow-query-cache-on�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-recursion�{�address_match_element;�...�};
- allow-recursion-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- answer-cookie�boolean;
- attach-cache�string;
- auth-nxdomain�boolean;�//�default�changed
- auto-dnssec�(�allow�|�maintain�|�off�);
- automatic-interface-scan�boolean;
- avoid-v4-udp-ports�{�portrange;�...�};
- avoid-v6-udp-ports�{�portrange;�...�};
- bindkeys-file�quoted_string;
- blackhole�{�address_match_element;�...�};
- cache-file�quoted_string;
- catalog-zones�{�zone�string�[�default-masters�[�port�integer�]
- ����[�dscp�integer�]�{�(�masters�|�ipv4_address�[�port
- ����integer�]�|�ipv6_address�[�port�integer�]�)�[�key
- ����string�];�...�}�]�[�zone-directory�quoted_string�]�[
- ����in-memory�boolean�]�[�min-update-interval�integer�];�...�};
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�master�|�slave�|�response
- ����)�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- cleaning-interval�integer;
- clients-per-query�integer;
- cookie-algorithm�(�aes�|�sha1�|�sha256�|�siphash24�);
- cookie-secret�string;
- coresize�(�default�|�unlimited�|�sizeval�);
- datasize�(�default�|�unlimited�|�sizeval�);
- deny-answer-addresses�{�address_match_element;�...�}�[
- ����except-from�{�quoted_string;�...�}�];
- deny-answer-aliases�{�quoted_string;�...�}�[�except-from�{
- ����quoted_string;�...�}�];
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- directory�quoted_string;
- disable-algorithms�string�{�string;
- ����...�};
- disable-ds-digests�string�{�string;
- ����...�};
- disable-empty-zone�string;
- dns64�netprefix�{
- break-dnssec�boolean;
- clients�{�address_match_element;�...�};
- exclude�{�address_match_element;�...�};
- mapped�{�address_match_element;�...�};
- recursive-only�boolean;
- suffix�ipv6_address;
- };
- dns64-contact�string;
- dns64-server�string;
- dnssec-accept-expired�boolean;
- dnssec-dnskey-kskonly�boolean;
- dnssec-enable�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-lookaside�(�string�trust-anchor
- ����string�|�auto�|�no�);
- dnssec-must-be-secure�string�boolean;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- dnssec-validation�(�yes�|�no�|�auto�);
- dnstap�{�(�all�|�auth�|�client�|�forwarder�|
- ����resolver�)�[�(�query�|�response�)�];�...�};
- dnstap-identity�(�quoted_string�|�none�|
- ����hostname�);
- dnstap-output�(�file�|�unix�)�quoted_string;
- dnstap-version�(�quoted_string�|�none�);
- dscp�integer;
- dual-stack-servers�[�port�integer�]�{�(�quoted_string�[�port
- ����integer�]�[�dscp�integer�]�|�ipv4_address�[�port
- ����integer�]�[�dscp�integer�]�|�ipv6_address�[�port
- ����integer�]�[�dscp�integer�]�);�...�};
- dump-file�quoted_string;
- edns-udp-size�integer;
- empty-contact�string;
- empty-server�string;
- empty-zones-enable�boolean;
- fetch-quota-params�integer�fixedpoint�fixedpoint�fixedpoint;
- fetches-per-server�integer�[�(�drop�|�fail�)�];
- fetches-per-zone�integer�[�(�drop�|�fail�)�];
- files�(�default�|�unlimited�|�sizeval�);
- filter-aaaa�{�address_match_element;�...�};
- filter-aaaa-on-v4�(�break-dnssec�|�boolean�);
- filter-aaaa-on-v6�(�break-dnssec�|�boolean�);
- flush-zones-on-shutdown�boolean;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- fstrm-set-buffer-hint�integer;
- fstrm-set-flush-timeout�integer;
- fstrm-set-input-queue-size�integer;
- fstrm-set-output-notify-threshold�integer;
- fstrm-set-output-queue-model�(�mpsc�|�spsc�);
- fstrm-set-output-queue-size�integer;
- fstrm-set-reopen-interval�integer;
- geoip-directory�(�quoted_string�|�none�);
- geoip-use-ecs�boolean;
- heartbeat-interval�integer;
- hostname�(�quoted_string�|�none�);
- inline-signing�boolean;
- interface-interval�integer;
- ixfr-from-differences�(�master�|�slave�|�boolean�);
- keep-response-order�{�address_match_element;�...�};
- key-directory�quoted_string;
- lame-ttl�ttlval;
- listen-on�[�port�integer�]�[�dscp
- ����integer�]�{
- ����address_match_element;�...�};
- listen-on-v6�[�port�integer�]�[�dscp
- ����integer�]�{
- ����address_match_element;�...�};
- lmdb-mapsize�sizeval;
- lock-file�(�quoted_string�|�none�);
- managed-keys-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- match-mapped-addresses�boolean;
- max-acache-size�(�unlimited�|�sizeval�);
- max-cache-size�(�default�|�unlimited�|�sizeval�|�percentage�);
- max-cache-ttl�integer;
- max-clients-per-query�integer;
- max-journal-size�(�unlimited�|�sizeval�);
- max-ncache-ttl�integer;
- max-records�integer;
- max-recursion-depth�integer;
- max-recursion-queries�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-rsa-exponent-size�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-udp-size�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- memstatistics�boolean;
- memstatistics-file�quoted_string;
- message-compression�boolean;
- min-refresh-time�integer;
- min-retry-time�integer;
- minimal-any�boolean;
- minimal-responses�(�no-auth�|�no-auth-recursive�|�boolean�);
- multi-master�boolean;
- no-case-compress�{�address_match_element;�...�};
- nocookie-udp-size�integer;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-rate�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- nta-lifetime�ttlval;
- nta-recheck�ttlval;
- nxdomain-redirect�string;
- pid-file�(�quoted_string�|�none�);
- port�integer;
- preferred-glue�string;
- prefetch�integer�[�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- querylog�boolean;
- random-device�quoted_string;
- rate-limit�{
- all-per-second�integer;
- errors-per-second�integer;
- exempt-clients�{�address_match_element;�...�};
- ipv4-prefix-length�integer;
- ipv6-prefix-length�integer;
- log-only�boolean;
- max-table-size�integer;
- min-table-size�integer;
- nodata-per-second�integer;
- nxdomains-per-second�integer;
- qps-scale�integer;
- referrals-per-second�integer;
- responses-per-second�integer;
- slip�integer;
- window�integer;
- };
- recursing-file�quoted_string;
- recursion�boolean;
- recursive-clients�integer;
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- require-server-cookie�boolean;
- reserved-sockets�integer;
- resolver-query-timeout�integer;
- response-policy�{�zone�string�[�log�boolean�]�[�max-policy-ttl
- ����integer�]�[�policy�(�cname�|�disabled�|�drop�|�given�|�no-op
- ����|�nodata�|�nxdomain�|�passthru�|�tcp-only�quoted_string�)�]�[
- ����recursive-only�boolean�];�...�}�[�break-dnssec�boolean�]�[
- ����max-policy-ttl�integer�]�[�min-ns-dots�integer�]�[
- ����nsip-wait-recurse�boolean�]�[�qname-wait-recurse�boolean�]
- ����[�recursive-only�boolean�];
- root-delegation-only�[�exclude�{�quoted_string;�...�}�];
- root-key-sentinel�boolean;
- rrset-order�{�[�class�string�]�[�type�string�]�[�name
- ����quoted_string�]�string�string;�...�};
- secroots-file�quoted_string;
- send-cookie�boolean;
- serial-query-rate�integer;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-id�(�quoted_string�|�none�|�hostname�);
- servfail-ttl�ttlval;
- session-keyalg�string;
- session-keyfile�(�quoted_string�|�none�);
- session-keyname�string;
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- sortlist�{�address_match_element;�...�};
- stacksize�(�default�|�unlimited�|�sizeval�);
- startup-notify-rate�integer;
- statistics-file�quoted_string;
- tcp-clients�integer;
- tcp-listen-queue�integer;
- tkey-dhkey�quoted_string�integer;
- tkey-domain�quoted_string;
- tkey-gssapi-credential�quoted_string;
- tkey-gssapi-keytab�quoted_string;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-message-size�integer;
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- transfers-in�integer;
- transfers-out�integer;
- transfers-per-ns�integer;
- trust-anchor-telemetry�boolean;�//�experimental
- try-tcp-refresh�boolean;
- update-check-ksk�boolean;
- use-alt-transfer-source�boolean;
- use-v4-udp-ports�{�portrange;�...�};
- use-v6-udp-ports�{�portrange;�...�};
- v6-bias�integer;
- version�(�quoted_string�|�none�);
- zero-no-soa-ttl�boolean;
- zero-no-soa-ttl-cache�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

SERVER

-


-server�netprefix�{
- bogus�boolean;
- edns�boolean;
- edns-udp-size�integer;
- edns-version�integer;
- keys�server_key;
- max-udp-size�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- send-cookie�boolean;
- tcp-only�boolean;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- transfers�integer;
-};
-

-
-
-

STATISTICS-CHANNELS

-


-statistics-channels�{
- inet�(�ipv4_address�|�ipv6_address�|
- ����*�)�[�port�(�integer�|�*�)�]�[
- ����allow�{�address_match_element;�...
- ����}�];
-};
-

-
-
-

TRUSTED-KEYS

-


-trusted-keys�{�string�integer�integer
-����integer�quoted_string;�...�};
-

-
-
-

VIEW

-


-view�string�[�class�]�{
- acache-cleaning-interval�integer;
- acache-enable�boolean;
- additional-from-auth�boolean;
- additional-from-cache�boolean;
- allow-new-zones�boolean;
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-cache�{�address_match_element;�...�};
- allow-query-cache-on�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-recursion�{�address_match_element;�...�};
- allow-recursion-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- attach-cache�string;
- auth-nxdomain�boolean;�//�default�changed
- auto-dnssec�(�allow�|�maintain�|�off�);
- cache-file�quoted_string;
- catalog-zones�{�zone�string�[�default-masters�[�port�integer�]
- ����[�dscp�integer�]�{�(�masters�|�ipv4_address�[�port
- ����integer�]�|�ipv6_address�[�port�integer�]�)�[�key
- ����string�];�...�}�]�[�zone-directory�quoted_string�]�[
- ����in-memory�boolean�]�[�min-update-interval�integer�];�...�};
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�master�|�slave�|�response
- ����)�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- cleaning-interval�integer;
- clients-per-query�integer;
- deny-answer-addresses�{�address_match_element;�...�}�[
- ����except-from�{�quoted_string;�...�}�];
- deny-answer-aliases�{�quoted_string;�...�}�[�except-from�{
- ����quoted_string;�...�}�];
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- disable-algorithms�string�{�string;
- ����...�};
- disable-ds-digests�string�{�string;
- ����...�};
- disable-empty-zone�string;
- dlz�string�{
- database�string;
- search�boolean;
- };
- dns64�netprefix�{
- break-dnssec�boolean;
- clients�{�address_match_element;�...�};
- exclude�{�address_match_element;�...�};
- mapped�{�address_match_element;�...�};
- recursive-only�boolean;
- suffix�ipv6_address;
- };
- dns64-contact�string;
- dns64-server�string;
- dnssec-accept-expired�boolean;
- dnssec-dnskey-kskonly�boolean;
- dnssec-enable�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-lookaside�(�string�trust-anchor
- ����string�|�auto�|�no�);
- dnssec-must-be-secure�string�boolean;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- dnssec-validation�(�yes�|�no�|�auto�);
- dnstap�{�(�all�|�auth�|�client�|�forwarder�|
- ����resolver�)�[�(�query�|�response�)�];�...�};
- dual-stack-servers�[�port�integer�]�{�(�quoted_string�[�port
- ����integer�]�[�dscp�integer�]�|�ipv4_address�[�port
- ����integer�]�[�dscp�integer�]�|�ipv6_address�[�port
- ����integer�]�[�dscp�integer�]�);�...�};
- dyndb�string�quoted_string�{
- ����unspecified-text�};
- edns-udp-size�integer;
- empty-contact�string;
- empty-server�string;
- empty-zones-enable�boolean;
- fetch-quota-params�integer�fixedpoint�fixedpoint�fixedpoint;
- fetches-per-server�integer�[�(�drop�|�fail�)�];
- fetches-per-zone�integer�[�(�drop�|�fail�)�];
- filter-aaaa�{�address_match_element;�...�};
- filter-aaaa-on-v4�(�break-dnssec�|�boolean�);
- filter-aaaa-on-v6�(�break-dnssec�|�boolean�);
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- inline-signing�boolean;
- ixfr-from-differences�(�master�|�slave�|�boolean�);
- key�string�{
- algorithm�string;
- secret�string;
- };
- key-directory�quoted_string;
- lame-ttl�ttlval;
- lmdb-mapsize�sizeval;
- managed-keys�{�string�string
- ����integer�integer�integer
- ����quoted_string;�...�};
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- match-clients�{�address_match_element;�...�};
- match-destinations�{�address_match_element;�...�};
- match-recursive-only�boolean;
- max-acache-size�(�unlimited�|�sizeval�);
- max-cache-size�(�default�|�unlimited�|�sizeval�|�percentage�);
- max-cache-ttl�integer;
- max-clients-per-query�integer;
- max-journal-size�(�unlimited�|�sizeval�);
- max-ncache-ttl�integer;
- max-records�integer;
- max-recursion-depth�integer;
- max-recursion-queries�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-udp-size�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- message-compression�boolean;
- min-refresh-time�integer;
- min-retry-time�integer;
- minimal-any�boolean;
- minimal-responses�(�no-auth�|�no-auth-recursive�|�boolean�);
- multi-master�boolean;
- no-case-compress�{�address_match_element;�...�};
- nocookie-udp-size�integer;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- nta-lifetime�ttlval;
- nta-recheck�ttlval;
- nxdomain-redirect�string;
- preferred-glue�string;
- prefetch�integer�[�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- rate-limit�{
- all-per-second�integer;
- errors-per-second�integer;
- exempt-clients�{�address_match_element;�...�};
- ipv4-prefix-length�integer;
- ipv6-prefix-length�integer;
- log-only�boolean;
- max-table-size�integer;
- min-table-size�integer;
- nodata-per-second�integer;
- nxdomains-per-second�integer;
- qps-scale�integer;
- referrals-per-second�integer;
- responses-per-second�integer;
- slip�integer;
- window�integer;
- };
- recursion�boolean;
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- require-server-cookie�boolean;
- resolver-query-timeout�integer;
- response-policy�{�zone�string�[�log�boolean�]�[�max-policy-ttl
- ����integer�]�[�policy�(�cname�|�disabled�|�drop�|�given�|�no-op
- ����|�nodata�|�nxdomain�|�passthru�|�tcp-only�quoted_string�)�]�[
- ����recursive-only�boolean�];�...�}�[�break-dnssec�boolean�]�[
- ����max-policy-ttl�integer�]�[�min-ns-dots�integer�]�[
- ����nsip-wait-recurse�boolean�]�[�qname-wait-recurse�boolean�]
- ����[�recursive-only�boolean�];
- root-delegation-only�[�exclude�{�quoted_string;�...�}�];
- root-key-sentinel�boolean;
- rrset-order�{�[�class�string�]�[�type�string�]�[�name
- ����quoted_string�]�string�string;�...�};
- send-cookie�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server�netprefix�{
- bogus�boolean;
- edns�boolean;
- edns-udp-size�integer;
- edns-version�integer;
- keys�server_key;
- max-udp-size�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*
- ����)�]�[�dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer
- ����|�*�)�]�[�dscp�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port
- ����(�integer�|�*�)�]�)�|�(�[�[�address�]�(
- ����ipv4_address�|�*�)�]�port�(�integer�|�*�)�)�)�[
- ����dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[
- ����port�(�integer�|�*�)�]�)�|�(�[�[�address�]�(
- ����ipv6_address�|�*�)�]�port�(�integer�|�*�)�)�)�[
- ����dscp�integer�];
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- send-cookie�boolean;
- tcp-only�boolean;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- transfers�integer;
- };
- servfail-ttl�ttlval;
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- sortlist�{�address_match_element;�...�};
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- trust-anchor-telemetry�boolean;�//�experimental
- trusted-keys�{�string�integer
- ����integer�integer�quoted_string;
- ����...�};
- try-tcp-refresh�boolean;
- update-check-ksk�boolean;
- use-alt-transfer-source�boolean;
- v6-bias�integer;
- zero-no-soa-ttl�boolean;
- zero-no-soa-ttl-cache�boolean;
- zone�string�[�class�]�{
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(
- ����masters�|�ipv4_address�[�port�integer�]�|
- ����ipv6_address�[�port�integer�]�)�[�key�string�];
- ����...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- auto-dnssec�(�allow�|�maintain�|�off�);
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- database�string;
- delegation-only�boolean;
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|
- ����boolean�);
- dlz�string;
- dnssec-dnskey-kskonly�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- file�quoted_string;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(
- ����ipv4_address�|�ipv6_address�)�[�port�integer�]�[
- ����dscp�integer�];�...�};
- in-view�string;
- inline-signing�boolean;
- ixfr-from-differences�boolean;
- journal�quoted_string;
- key-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- masters�[�port�integer�]�[�dscp�integer�]�{�(�masters
- ����|�ipv4_address�[�port�integer�]�|�ipv6_address�[
- ����port�integer�]�)�[�key�string�];�...�};
- max-ixfr-log-size�(�default�|�unlimited�|
- max-journal-size�(�unlimited�|�sizeval�);
- max-records�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- min-refresh-time�integer;
- min-retry-time�integer;
- multi-master�boolean;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*
- ����)�]�[�dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer
- ����|�*�)�]�[�dscp�integer�];
- notify-to-soa�boolean;
- pubkey�integer
- ����integer
- ����integer
- request-expire�boolean;
- request-ixfr�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-addresses�{�(�ipv4_address�|�ipv6_address�);�...�};
- server-names�{�quoted_string;�...�};
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- try-tcp-refresh�boolean;
- type�(�delegation-only�|�forward�|�hint�|�master�|�redirect
- ����|�slave�|�static-stub�|�stub�);
- update-check-ksk�boolean;
- update-policy�(�local�|�{�(�deny�|�grant�)�string�(
- ����6to4-self�|�external�|�krb5-self�|�krb5-selfsub�|
- ����krb5-subdomain�|�ms-self�|�ms-selfsub�|�ms-subdomain�|
- ����name�|�self�|�selfsub�|�selfwild�|�subdomain�|�tcp-self
- ����|�wildcard�|�zonesub�)�[�string�]�rrtypelist;�...�};
- use-alt-transfer-source�boolean;
- zero-no-soa-ttl�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
- };
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

ZONE

-


-zone�string�[�class�]�{
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- auto-dnssec�(�allow�|�maintain�|�off�);
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- database�string;
- delegation-only�boolean;
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- dlz�string;
- dnssec-dnskey-kskonly�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- file�quoted_string;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- in-view�string;
- inline-signing�boolean;
- ixfr-from-differences�boolean;
- journal�quoted_string;
- key-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- masters�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- max-journal-size�(�unlimited�|�sizeval�);
- max-records�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- min-refresh-time�integer;
- min-retry-time�integer;
- multi-master�boolean;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- pubkey�integer�integer
- request-expire�boolean;
- request-ixfr�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-addresses�{�(�ipv4_address�|�ipv6_address�);�...�};
- server-names�{�quoted_string;�...�};
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- try-tcp-refresh�boolean;
- type�(�delegation-only�|�forward�|�hint�|�master�|�redirect�|�slave
- ����|�static-stub�|�stub�);
- update-check-ksk�boolean;
- update-policy�(�local�|�{�(�deny�|�grant�)�string�(�6to4-self�|
- ����external�|�krb5-self�|�krb5-selfsub�|�krb5-subdomain�|�ms-self
- ����|�ms-selfsub�|�ms-subdomain�|�name�|�self�|�selfsub�|�selfwild
- ����|�subdomain�|�tcp-self�|�wildcard�|�zonesub�)�[�string�]
- ����rrtypelist;�...�};
- use-alt-transfer-source�boolean;
- zero-no-soa-ttl�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

FILES

-

/etc/named.conf -

-
-
-

SEE ALSO

-

ddns-confgen(8), - named(8), - named-checkconf(8), - rndc(8), - rndc-confgen(8), - BIND 9 Administrator Reference Manual. -

-
-
- diff --git a/bin/named-pkcs11/named.docbook b/bin/named-pkcs11/named.docbook deleted file mode 100644 index b95a26f..0000000 --- a/bin/named-pkcs11/named.docbook +++ /dev/null @@ -1,621 +0,0 @@ - - - - - - 2014-02-19 - - - ISC - Internet Systems Consortium, Inc. - - - - named - 8 - BIND9 - - - - named - Internet domain name server - - - - - 2000 - 2001 - 2003 - 2004 - 2005 - 2006 - 2007 - 2008 - 2009 - 2011 - 2013 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - named - - - - - - - - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. - - - When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. - - - - OPTIONS - - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - option in the configuration - file, config-file should be - an absolute pathname. - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. - - - - - - -D string - - - Specifies a string that is used to identify a instance of - named in a process listing. The contents - of string are - not examined. - - - - - - -E engine-name - - - When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -L logfile - - - Log to the file by default - instead of the system log. - - - - - - -M option - - - Sets the default memory context options. Currently - the only supported option is - external, - which causes the internal memory manager to be bypassed - in favor of system-provided memory allocation functions. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -p port - - - Listen for queries on port port. If not - specified, the default is port 53. - - - - - - -s - - - Write memory usage statistics to stdout on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -S #max-socks - - - Allow named to use up to - #max-socks sockets. - The default value is 4096 on systems built with default - configuration options, and 21000 on systems built with - "configure --with-tuning=large". - - - - This option should be unnecessary for the vast majority - of users. - The use of this option could even be harmful because the - specified value may exceed the limitation of the - underlying system API. - It is therefore set only when the default configuration - causes exhaustion of file descriptors and the - operational environment is known to support the - specified number of sockets. - Note also that the actual maximum number is normally a little - fewer than the specified value because - named reserves some file descriptors - for its internal use. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -U #listeners - - - Use #listeners - worker threads to listen for incoming UDP packets on each - address. If not specified, named will - calculate a default value based on the number of detected - CPUs: 1 for 1 CPU, and the number of detected CPUs - minus one for machines with more than 1 CPU. This cannot - be increased to a value higher than the number of CPUs. - If has been set to a higher value than - the number of detected CPUs, then may - be increased as high as that value, but no higher. - On Windows, the number of UDP listeners is hardwired to 1 - and this option has no effect. - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). - - - - - - - -v - - - Report the version number and exit. - - - - - - -V - - - Report the version number and build options, and exit. - - - - - - -X lock-file - - - Acquire a lock on the specified file at runtime; this - helps to prevent duplicate named instances - from running simultaneously. - Use of this option overrides the lock-file - option in named.conf. - If set to none, the lock file check - is disabled. - - - - - - -x cache-file - - - Load data from cache-file into the - cache of the default view. - - - - This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. - - - - - - - - - - SIGNALS - - - In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. - - - - - - SIGHUP - - - Force a reload of the server. - - - - - - SIGINT, SIGTERM - - - Shut down the server. - - - - - - - - The result of sending any other signals to the server is undefined. - - - - - CONFIGURATION - - - The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. - - - - named inherits the umask - (file creation mode mask) from the parent process. If files - created by named, such as journal files, - need to have custom permissions, the umask - should be set explicitly in the script used to start the - named process. - - - - - FILES - - - - - - /etc/named.conf - - - The default configuration file. - - - - - - /var/run/named/named.pid - - - The default process-id file. - - - - - - - - - NOTES - Red Hat SELinux BIND Security Profile - - - By default, Red Hat ships BIND with the most secure SELinux policy - that will not prevent normal BIND operation and will prevent exploitation - of all known BIND security vulnerabilities . See the selinux(8) man page - for information about SElinux. - - - - It is not necessary to run named in a chroot environment if the Red Hat - SELinux policy for named is enabled. When enabled, this policy is far - more secure than a chroot environment. Users are recommended to enable - SELinux and remove the bind-chroot package. - - - - With this extra security comes some restrictions: - - - - By default, the SELinux policy allows named to write any master - zone database files. Only the root user may create files in the $ROOTDIR/var/named - zone database file directory (the options { "directory" } option), where - $ROOTDIR is set in /etc/sysconfig/named. - - - - The "named" group must be granted read privelege to - these files in order for named to be enabled to read them. - - - - Any file created in the zone database file directory is automatically assigned - the SELinux file context named_zone_t . - - - - By default, SELinux prevents any role from modifying named_zone_t files; this - means that files in the zone database directory cannot be modified by dynamic - DNS (DDNS) updates or zone transfers. - - - - The Red Hat BIND distribution and SELinux policy creates three directories where - named is allowed to create and modify files: /var/named/slaves, /var/named/dynamic - /var/named/data. By placing files you want named to modify, such as - slave or DDNS updateable zone files and database / statistics dump files in - these directories, named will work normally and no further operator action is - required. Files in these directories are automatically assigned the 'named_cache_t' - file context, which SELinux allows named to write. - - - - Red Hat BIND SDB support - - - Red Hat ships named with compiled in Simplified Database Backend modules that ISC - provides in the "contrib/sdb" directory. Install bind-sdb package if you want use them. - - - - The SDB modules for LDAP, PostGreSQL, DirDB and SQLite are compiled into named-sdb. - - - - See the documentation for the various SDB modules in /usr/share/doc/bind-sdb-*/ . - - - - - - SEE ALSO - - RFC 1033, - RFC 1034, - RFC 1035, - - named-checkconf - 8 - , - - named-checkzone - 8 - , - - rndc - 8 - , - - lwresd - 8 - , - - named.conf - 5 - , - BIND 9 Administrator Reference Manual. - - - - diff --git a/bin/named-pkcs11/named.html b/bin/named-pkcs11/named.html deleted file mode 100644 index 8637ed8..0000000 --- a/bin/named-pkcs11/named.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - - -named - - -
-
-
-

Name

-

named — Internet domain name server

-
-
-

Synopsis

-

named [[-4] | [-6]] [-c config-file] [-d debug-level] [-D string] [-E engine-name] [-f] [-g] [-L logfile] [-M option] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-U #listeners] [-u user] [-v] [-V] [-X lock-file] [-x cache-file]

-
-
-

DESCRIPTION

-

named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. -

-

- When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - directory option in the configuration - file, config-file should be - an absolute pathname. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. -

-
-D string
-

- Specifies a string that is used to identify a instance of - named in a process listing. The contents - of string are - not examined. -

-
-E engine-name
-
-

- When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-L logfile
-

- Log to the file logfile by default - instead of the system log. -

-
-M option
-

- Sets the default memory context options. Currently - the only supported option is - external, - which causes the internal memory manager to be bypassed - in favor of system-provided memory allocation functions. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-p port
-

- Listen for queries on port port. If not - specified, the default is port 53. -

-
-s
-
-

- Write memory usage statistics to stdout on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-S #max-socks
-
-

- Allow named to use up to - #max-socks sockets. - The default value is 4096 on systems built with default - configuration options, and 21000 on systems built with - "configure --with-tuning=large". -

-
-

Warning

-

- This option should be unnecessary for the vast majority - of users. - The use of this option could even be harmful because the - specified value may exceed the limitation of the - underlying system API. - It is therefore set only when the default configuration - causes exhaustion of file descriptors and the - operational environment is known to support the - specified number of sockets. - Note also that the actual maximum number is normally a little - fewer than the specified value because - named reserves some file descriptors - for its internal use. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-U #listeners
-

- Use #listeners - worker threads to listen for incoming UDP packets on each - address. If not specified, named will - calculate a default value based on the number of detected - CPUs: 1 for 1 CPU, and the number of detected CPUs - minus one for machines with more than 1 CPU. This cannot - be increased to a value higher than the number of CPUs. - If -n has been set to a higher value than - the number of detected CPUs, then -U may - be increased as high as that value, but no higher. - On Windows, the number of UDP listeners is hardwired to 1 - and this option has no effect. -

-
-u user
-
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-

Note

-

- On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the -u - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). -

-
-
-
-v
-

- Report the version number and exit. -

-
-V
-

- Report the version number and build options, and exit. -

-
-X lock-file
-

- Acquire a lock on the specified file at runtime; this - helps to prevent duplicate named instances - from running simultaneously. - Use of this option overrides the lock-file - option in named.conf. - If set to none, the lock file check - is disabled. -

-
-x cache-file
-
-

- Load data from cache-file into the - cache of the default view. -

-
-

Warning

-

- This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. -

-
-
-
-
-
-

SIGNALS

-

- In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. -

-
-
SIGHUP
-

- Force a reload of the server. -

-
SIGINT, SIGTERM
-

- Shut down the server. -

-
-

- The result of sending any other signals to the server is undefined. -

-
-
-

CONFIGURATION

-

- The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. -

-

- named inherits the umask - (file creation mode mask) from the parent process. If files - created by named, such as journal files, - need to have custom permissions, the umask - should be set explicitly in the script used to start the - named process. -

-
-
-

FILES

-
-
/etc/named.conf
-

- The default configuration file. -

-
/var/run/named/named.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

RFC 1033, - RFC 1034, - RFC 1035, - named-checkconf(8), - named-checkzone(8), - rndc(8), - lwresd(8), - named.conf(5), - BIND 9 Administrator Reference Manual. -

-
-
- diff --git a/bin/named-pkcs11/notify.c b/bin/named-pkcs11/notify.c deleted file mode 100644 index de4ca09..0000000 --- a/bin/named-pkcs11/notify.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*! \file - * \brief - * This module implements notify as in RFC1996. - */ - -static void -notify_log(ns_client_t *client, int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY, - level, fmt, ap); - va_end(ap); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - isc_result_t msg_result; - - message = client->message; - rcode = dns_result_torcode(result); - - msg_result = dns_message_reply(message, true); - if (msg_result != ISC_R_SUCCESS) - msg_result = dns_message_reply(message, false); - if (msg_result != ISC_R_SUCCESS) { - ns_client_next(client, msg_result); - return; - } - message->rcode = rcode; - if (rcode == dns_rcode_noerror) - message->flags |= DNS_MESSAGEFLAG_AA; - else - message->flags &= ~DNS_MESSAGEFLAG_AA; - ns_client_send(client); -} - -void -ns_notify_start(ns_client_t *client) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - char tsigbuf[DNS_NAME_FORMATSIZE * 2 + sizeof(": TSIG '' ()")]; - dns_tsigkey_t *tsigkey; - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section empty"); - result = DNS_R_FORMERR; - goto done; - } - - /* - * The question section must contain exactly one question. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - result = DNS_R_FORMERR; - goto done; - } - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - result = DNS_R_FORMERR; - goto done; - } - - /* The one rdataset must be an SOA. */ - if (zone_rdataset->type != dns_rdatatype_soa) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains no SOA"); - result = DNS_R_FORMERR; - goto done; - } - - tsigkey = dns_message_gettsigkey(request); - if (tsigkey != NULL) { - dns_name_format(&tsigkey->name, namebuf, sizeof(namebuf)); - - if (tsigkey->generated) { - char cnamebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(tsigkey->creator, cnamebuf, - sizeof(cnamebuf)); - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s' (%s)", - namebuf, cnamebuf); - } else { - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", - namebuf); - } - } else - tsigbuf[0] = '\0'; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, &zone); - if (result == ISC_R_SUCCESS) { - dns_zonetype_t zonetype = dns_zone_gettype(zone); - - if ((zonetype == dns_zone_master) || - (zonetype == dns_zone_slave) || - (zonetype == dns_zone_stub)) - { - isc_sockaddr_t *from = ns_client_getsockaddr(client); - isc_sockaddr_t *to = ns_client_getdestaddr(client); - notify_log(client, ISC_LOG_INFO, - "received notify for zone '%s'%s", - namebuf, tsigbuf); - result = dns_zone_notifyreceive2(zone, from, to, - request); - goto done; - } - } - - notify_log(client, ISC_LOG_NOTICE, - "received notify for zone '%s'%s: not authoritative", - namebuf, tsigbuf); - result = DNS_R_NOTAUTH; - - done: - if (zone != NULL) - dns_zone_detach(&zone); - respond(client, result); -} diff --git a/bin/named-pkcs11/query.c b/bin/named-pkcs11/query.c deleted file mode 100644 index a95f5ad..0000000 --- a/bin/named-pkcs11/query.c +++ /dev/null @@ -1,9888 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#define last_load(x) atomic_load((x)) -#define last_cmpxchg(x, e, r) atomic_compare_exchange_strong((x), (e), r) -#elif defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) -#define last_load(x) (isc_stdtime_t)isc_atomic_xadd((int32_t*)(x), 0) -#define last_cmpxchg(x, e, r) isc_atomic_cmpxchg((int32_t*)x, (*(int32_t*)(e)), (int32_t)(r)) -#else -#define last_load(x) (*(x)) -static inline bool -last_cmpxchg(isc_stdtime_t *x, isc_stdtime_t *e, isc_stdtime_t r) { - if (*x == *e) { - *x = r; - return (true); - } - return (false); -} -#endif - -#if 0 -/* - * It has been recommended that DNS64 be changed to return excluded - * AAAA addresses if DNS64 synthesis does not occur. This minimises - * the impact on the lookup results. While most DNS AAAA lookups are - * done to send IP packets to a host, not all of them are and filtering - * excluded addresses has a negative impact on those uses. - */ -#define dns64_bis_return_excluded_addresses 1 -#endif - -/*% Partial answer? */ -#define PARTIALANSWER(c) (((c)->query.attributes & \ - NS_QUERYATTR_PARTIALANSWER) != 0) -/*% Use Cache? */ -#define USECACHE(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEOK) != 0) -/*% Recursion OK? */ -#define RECURSIONOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSIONOK) != 0) -/*% Recursing? */ -#define RECURSING(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSING) != 0) -/*% Cache glue ok? */ -#define CACHEGLUEOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEGLUEOK) != 0) -/*% Want Recursion? */ -#define WANTRECURSION(c) (((c)->query.attributes & \ - NS_QUERYATTR_WANTRECURSION) != 0) -/*% Is TCP? */ -#define TCP(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -/*% Want DNSSEC? */ -#define WANTDNSSEC(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTDNSSEC) != 0) -/*% Want WANTAD? */ -#define WANTAD(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTAD) != 0) -/*% Client presented a valid COOKIE. */ -#define HAVECOOKIE(c) (((c)->attributes & \ - NS_CLIENTATTR_HAVECOOKIE) != 0) -/*% Client presented a COOKIE. */ -#define WANTCOOKIE(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTCOOKIE) != 0) -/*% No authority? */ -#define NOAUTHORITY(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOAUTHORITY) != 0) -/*% No additional? */ -#define NOADDITIONAL(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOADDITIONAL) != 0) -/*% Secure? */ -#define SECURE(c) (((c)->query.attributes & \ - NS_QUERYATTR_SECURE) != 0) -/*% DNS64 A lookup? */ -#define DNS64(c) (((c)->query.attributes & \ - NS_QUERYATTR_DNS64) != 0) - -#define DNS64EXCLUDE(c) (((c)->query.attributes & \ - NS_QUERYATTR_DNS64EXCLUDE) != 0) - -#define REDIRECT(c) (((c)->query.attributes & \ - NS_QUERYATTR_REDIRECT) != 0) - -/*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */ -#define NOQNAME(r) (((r)->attributes & \ - DNS_RDATASETATTR_NOQNAME) != 0) - -/*% Does the rdataset 'r' contain a stale answer? */ -#define STALE(r) (((r)->attributes & \ - DNS_RDATASETATTR_STALE) != 0) - -#ifdef WANT_QUERYTRACE -static inline void -client_trace(ns_client_t *client, int level, const char *message) { - if (client != NULL && client->query.qname != NULL) { - if (isc_log_wouldlog(ns_g_lctx, level)) { - char qbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(client->query.qname, - qbuf, sizeof(qbuf)); - dns_rdatatype_format(client->query.qtype, - tbuf, sizeof(tbuf)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, level, - "query client=%p thread=0x%lx " - "(%s/%s): %s", - client, - (unsigned long) isc_thread_self(), - qbuf, tbuf, message); - } - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, level, - "query client=%p thread=0x%lx " - "(): %s", - client, - (unsigned long) isc_thread_self(), - message); - } -} -#define CTRACE(l,m) client_trace(client, l, m) -#else -#define CTRACE(l,m) ((void)m) -#endif /* WANT_QUERYTRACE */ - - -#define DNS_GETDB_NOEXACT 0x01U -#define DNS_GETDB_NOLOG 0x02U -#define DNS_GETDB_PARTIAL 0x04U -#define DNS_GETDB_IGNOREACL 0x08U - -#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0) - -#define SFCACHE_CDFLAG 0x1 - -/* - * These have the same semantics as: - * - * foo_attach(b, a); - * foo_detach(&a); - * - * without the locking and magic testing. - * - * We use SAVE and RESTORE as that shows the operation being performed. - */ -#define SAVE(a, b) do { INSIST(a == NULL); a = b; b = NULL; } while (0) -#define RESTORE(a, b) SAVE(a, b) - -typedef struct client_additionalctx { - ns_client_t *client; - dns_rdataset_t *rdataset; -} client_additionalctx_t; - -static isc_result_t -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); - -static bool -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -static void -query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, - dns_dbversion_t *version, ns_client_t *client, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_name_t *fname, bool exact, - dns_name_t *found); - -static inline void -log_queryerror(ns_client_t *client, isc_result_t result, int line, int level); - -static void -rpz_st_clear(ns_client_t *client); - -static bool -rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain); - -/*% - * Increment query statistics counters. - */ -static inline void -inc_stats(ns_client_t *client, isc_statscounter_t counter) { - dns_zone_t *zone = client->query.authzone; - dns_rdatatype_t qtype; - dns_rdataset_t *rdataset; - isc_stats_t *zonestats; - dns_stats_t *querystats = NULL; - - isc_stats_increment(ns_g_server->nsstats, counter); - - if (zone == NULL) - return; - - /* Do regular response type stats */ - zonestats = dns_zone_getrequeststats(zone); - - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - - /* Do query type statistics - * - * We only increment per-type if we're using the authoritative - * answer counter, preventing double-counting. - */ - if (counter == dns_nsstatscounter_authans) { - querystats = dns_zone_getrcvquerystats(zone); - if (querystats != NULL) { - rdataset = ISC_LIST_HEAD(client->query.qname->list); - if (rdataset != NULL) { - qtype = rdataset->type; - dns_rdatatypestats_increment(querystats, qtype); - } - } - } -} - -static void -query_send(ns_client_t *client) { - isc_statscounter_t counter; - - if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) - inc_stats(client, dns_nsstatscounter_nonauthans); - else - inc_stats(client, dns_nsstatscounter_authans); - - if (client->message->rcode == dns_rcode_noerror) { - dns_section_t answer = DNS_SECTION_ANSWER; - if (ISC_LIST_EMPTY(client->message->sections[answer])) { - if (client->query.isreferral) - counter = dns_nsstatscounter_referral; - else - counter = dns_nsstatscounter_nxrrset; - } else - counter = dns_nsstatscounter_success; - } else if (client->message->rcode == dns_rcode_nxdomain) - counter = dns_nsstatscounter_nxdomain; - else if (client->message->rcode == dns_rcode_badcookie) - counter = dns_nsstatscounter_badcookie; - else /* We end up here in case of YXDOMAIN, and maybe others */ - counter = dns_nsstatscounter_failure; - - inc_stats(client, counter); - ns_client_send(client); -} - -static void -query_error(ns_client_t *client, isc_result_t result, int line) { - int loglevel = ISC_LOG_DEBUG(3); - - switch (result) { - case DNS_R_SERVFAIL: - loglevel = ISC_LOG_DEBUG(1); - inc_stats(client, dns_nsstatscounter_servfail); - break; - case DNS_R_FORMERR: - inc_stats(client, dns_nsstatscounter_formerr); - break; - default: - inc_stats(client, dns_nsstatscounter_failure); - break; - } - - if (ns_g_server->log_queries) - loglevel = ISC_LOG_INFO; - - log_queryerror(client, result, line, loglevel); - - ns_client_error(client, result); -} - -static void -query_next(ns_client_t *client, isc_result_t result) { - if (result == DNS_R_DUPLICATE) - inc_stats(client, dns_nsstatscounter_duplicate); - else if (result == DNS_R_DROP) - inc_stats(client, dns_nsstatscounter_dropped); - else - inc_stats(client, dns_nsstatscounter_failure); - ns_client_next(client, result); -} - -static inline void -query_freefreeversions(ns_client_t *client, bool everything) { - ns_dbversion_t *dbversion, *dbversion_next; - unsigned int i; - - for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; - dbversion != NULL; - dbversion = dbversion_next, i++) - { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - /* - * If we're not freeing everything, we keep the first three - * dbversions structures around. - */ - if (i > 3 || everything) { - ISC_LIST_UNLINK(client->query.freeversions, dbversion, - link); - isc_mem_put(client->mctx, dbversion, - sizeof(*dbversion)); - } - } -} - -void -ns_query_cancel(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - dns_resolver_cancelfetch(client->query.fetch); - - client->query.fetch = NULL; - } - UNLOCK(&client->query.fetchlock); -} - -static inline void -query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { - dns_rdataset_t *rdataset = *rdatasetp; - - CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset"); - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, rdatasetp); - } - CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset: done"); -} - -static inline void -query_reset(ns_client_t *client, bool everything) { - isc_buffer_t *dbuf, *dbuf_next; - ns_dbversion_t *dbversion, *dbversion_next; - - CTRACE(ISC_LOG_DEBUG(3), "query_reset"); - - /*% - * Reset the query state of a client to its default state. - */ - - /* - * Cancel the fetch if it's running. - */ - ns_query_cancel(client); - - /* - * Cleanup any active versions. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = dbversion_next) { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - dns_db_closeversion(dbversion->db, &dbversion->version, - false); - dns_db_detach(&dbversion->db); - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } - ISC_LIST_INIT(client->query.activeversions); - - if (client->query.authdb != NULL) - dns_db_detach(&client->query.authdb); - if (client->query.authzone != NULL) - dns_zone_detach(&client->query.authzone); - - if (client->query.dns64_aaaa != NULL) - query_putrdataset(client, &client->query.dns64_aaaa); - if (client->query.dns64_sigaaaa != NULL) - query_putrdataset(client, &client->query.dns64_sigaaaa); - if (client->query.dns64_aaaaok != NULL) { - isc_mem_put(client->mctx, client->query.dns64_aaaaok, - client->query.dns64_aaaaoklen * - sizeof(bool)); - client->query.dns64_aaaaok = NULL; - client->query.dns64_aaaaoklen = 0; - } - - query_putrdataset(client, &client->query.redirect.rdataset); - query_putrdataset(client, &client->query.redirect.sigrdataset); - if (client->query.redirect.db != NULL) { - if (client->query.redirect.node != NULL) - dns_db_detachnode(client->query.redirect.db, - &client->query.redirect.node); - dns_db_detach(&client->query.redirect.db); - } - if (client->query.redirect.zone != NULL) - dns_zone_detach(&client->query.redirect.zone); - - query_freefreeversions(client, everything); - - for (dbuf = ISC_LIST_HEAD(client->query.namebufs); - dbuf != NULL; - dbuf = dbuf_next) { - dbuf_next = ISC_LIST_NEXT(dbuf, link); - if (dbuf_next != NULL || everything) { - ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); - isc_buffer_free(&dbuf); - } - } - - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = NULL; - client->query.attributes = (NS_QUERYATTR_RECURSIONOK | - NS_QUERYATTR_CACHEOK | - NS_QUERYATTR_SECURE); - client->query.restarts = 0; - client->query.timerset = false; - if (client->query.rpz_st != NULL) { - rpz_st_clear(client); - if (everything) { - isc_mem_put(client->mctx, client->query.rpz_st, - sizeof(*client->query.rpz_st)); - client->query.rpz_st = NULL; - } - } - client->query.origqname = NULL; - client->query.dboptions = 0; - client->query.fetchoptions = 0; - client->query.gluedb = NULL; - client->query.authdbset = false; - client->query.isreferral = false; - client->query.dns64_options = 0; - client->query.dns64_ttl = UINT32_MAX; - recparam_update(&client->query.recparam, 0, NULL, NULL); - client->query.root_key_sentinel_keyid = 0; - client->query.root_key_sentinel_is_ta = false; - client->query.root_key_sentinel_not_ta = false; -} - -static void -query_next_callback(ns_client_t *client) { - query_reset(client, false); -} - -void -ns_query_free(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - query_reset(client, true); -} - -static inline isc_result_t -query_newnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf"); - /*% - * Allocate a name buffer. - */ - - dbuf = NULL; - result = isc_buffer_allocate(client->mctx, &dbuf, 1024); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newnamebuf: isc_buffer_allocate failed: done"); - return (result); - } - ISC_LIST_APPEND(client->query.namebufs, dbuf, link); - - CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf: done"); - return (ISC_R_SUCCESS); -} - -static inline isc_buffer_t * -query_getnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - isc_region_t r; - - CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf"); - /*% - * Return a name buffer with space for a maximal name, allocating - * a new one if necessary. - */ - - if (ISC_LIST_EMPTY(client->query.namebufs)) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - } - } - - dbuf = ISC_LIST_TAIL(client->query.namebufs); - INSIST(dbuf != NULL); - isc_buffer_availableregion(dbuf, &r); - if (r.length < DNS_NAME_MAXWIRE) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - - } - dbuf = ISC_LIST_TAIL(client->query.namebufs); - isc_buffer_availableregion(dbuf, &r); - INSIST(r.length >= 255); - } - CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf: done"); - return (dbuf); -} - -static inline void -query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { - isc_region_t r; - - CTRACE(ISC_LOG_DEBUG(3), "query_keepname"); - /*% - * 'name' is using space in 'dbuf', but 'dbuf' has not yet been - * adjusted to take account of that. We do the adjustment. - */ - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0); - - dns_name_toregion(name, &r); - isc_buffer_add(dbuf, r.length); - dns_name_setbuffer(name, NULL); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; -} - -static inline void -query_releasename(ns_client_t *client, dns_name_t **namep) { - dns_name_t *name = *namep; - - /*% - * 'name' is no longer needed. Return it to our pool of temporary - * names. If it is using a name buffer, relinquish its exclusive - * rights on the buffer. - */ - - CTRACE(ISC_LOG_DEBUG(3), "query_releasename"); - if (dns_name_hasbuffer(name)) { - INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) - != 0); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; - } - dns_message_puttempname(client->message, namep); - CTRACE(ISC_LOG_DEBUG(3), "query_releasename: done"); -} - -static inline dns_name_t * -query_newname(ns_client_t *client, isc_buffer_t *dbuf, - isc_buffer_t *nbuf) -{ - dns_name_t *name; - isc_region_t r; - isc_result_t result; - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); - - CTRACE(ISC_LOG_DEBUG(3), "query_newname"); - name = NULL; - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newname: dns_message_gettempname failed: done"); - return (NULL); - } - isc_buffer_availableregion(dbuf, &r); - isc_buffer_init(nbuf, r.base, r.length); - dns_name_init(name, NULL); - dns_name_setbuffer(name, nbuf); - client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; - - CTRACE(ISC_LOG_DEBUG(3), "query_newname: done"); - return (name); -} - -static inline dns_rdataset_t * -query_newrdataset(ns_client_t *client) { - dns_rdataset_t *rdataset; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset"); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newrdataset: " - "dns_message_gettemprdataset failed: done"); - return (NULL); - } - - CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: done"); - return (rdataset); -} - -static inline isc_result_t -query_newdbversion(ns_client_t *client, unsigned int n) { - unsigned int i; - ns_dbversion_t *dbversion; - - for (i = 0; i < n; i++) { - dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); - if (dbversion != NULL) { - dbversion->db = NULL; - dbversion->version = NULL; - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } else { - /* - * We only return ISC_R_NOMEMORY if we couldn't - * allocate anything. - */ - if (i == 0) - return (ISC_R_NOMEMORY); - else - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_SUCCESS); -} - -static inline ns_dbversion_t * -query_getdbversion(ns_client_t *client) { - isc_result_t result; - ns_dbversion_t *dbversion; - - if (ISC_LIST_EMPTY(client->query.freeversions)) { - result = query_newdbversion(client, 1); - if (result != ISC_R_SUCCESS) - return (NULL); - } - dbversion = ISC_LIST_HEAD(client->query.freeversions); - INSIST(dbversion != NULL); - ISC_LIST_UNLINK(client->query.freeversions, dbversion, link); - - return (dbversion); -} - -isc_result_t -ns_query_init(ns_client_t *client) { - isc_result_t result; - - REQUIRE(NS_CLIENT_VALID(client)); - - ISC_LIST_INIT(client->query.namebufs); - ISC_LIST_INIT(client->query.activeversions); - ISC_LIST_INIT(client->query.freeversions); - client->query.restarts = 0; - client->query.timerset = false; - client->query.rpz_st = NULL; - client->query.qname = NULL; - /* - * This mutex is destroyed when the client is destroyed in - * exit_check(). - */ - result = isc_mutex_init(&client->query.fetchlock); - if (result != ISC_R_SUCCESS) - return (result); - client->query.fetch = NULL; - client->query.prefetch = NULL; - client->query.authdb = NULL; - client->query.authzone = NULL; - client->query.authdbset = false; - client->query.isreferral = false; - client->query.dns64_aaaa = NULL; - client->query.dns64_sigaaaa = NULL; - client->query.dns64_aaaaok = NULL; - client->query.dns64_aaaaoklen = 0; - client->query.redirect.db = NULL; - client->query.redirect.node = NULL; - client->query.redirect.zone = NULL; - client->query.redirect.qtype = dns_rdatatype_none; - client->query.redirect.result = ISC_R_SUCCESS; - client->query.redirect.rdataset = NULL; - client->query.redirect.sigrdataset = NULL; - client->query.redirect.authoritative = false; - client->query.redirect.is_zone = false; - client->query.redirect.fname = - dns_fixedname_initname(&client->query.redirect.fixed); - query_reset(client, false); - result = query_newdbversion(client, 3); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&client->query.fetchlock); - return (result); - } - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - query_freefreeversions(client, true); - DESTROYLOCK(&client->query.fetchlock); - } - - return (result); -} - -static ns_dbversion_t * -query_findversion(ns_client_t *client, dns_db_t *db) { - ns_dbversion_t *dbversion; - - /*% - * We may already have done a query related to this - * database. If so, we must be sure to make subsequent - * queries from the same version. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = ISC_LIST_NEXT(dbversion, link)) { - if (dbversion->db == db) - break; - } - - if (dbversion == NULL) { - /* - * This is a new zone for this query. Add it to - * the active list. - */ - dbversion = query_getdbversion(client); - if (dbversion == NULL) - return (NULL); - dns_db_attach(db, &dbversion->db); - dns_db_currentversion(db, &dbversion->version); - dbversion->acl_checked = false; - dbversion->queryok = false; - ISC_LIST_APPEND(client->query.activeversions, - dbversion, link); - } - - return (dbversion); -} - -static inline isc_result_t -query_validatezonedb(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t qtype, unsigned int options, - dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t **versionp) -{ - isc_result_t result; - dns_acl_t *queryacl, *queryonacl; - ns_dbversion_t *dbversion; - - REQUIRE(zone != NULL); - REQUIRE(db != NULL); - - /* - * This limits our searching to the zone where the first name - * (the query target) was looked for. This prevents following - * CNAMES or DNAMES into other zones and prevents returning - * additional data from other zones. - */ - if (!client->view->additionalfromauth && - client->query.authdbset && - db != client->query.authdb) - return (DNS_R_REFUSED); - - /* - * Non recursive query to a static-stub zone is prohibited; its - * zone content is not public data, but a part of local configuration - * and should not be disclosed. - */ - if (dns_zone_gettype(zone) == dns_zone_staticstub && - !RECURSIONOK(client)) { - return (DNS_R_REFUSED); - } - - /* - * If the zone has an ACL, we'll check it, otherwise - * we use the view's "allow-query" ACL. Each ACL is only checked - * once per query. - * - * Also, get the database version to use. - */ - - /* - * Get the current version of this database. - */ - dbversion = query_findversion(client, db); - if (dbversion == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to get db version"); - return (DNS_R_SERVFAIL); - } - - if ((options & DNS_GETDB_IGNOREACL) != 0) - goto approved; - if (dbversion->acl_checked) { - if (!dbversion->queryok) - return (DNS_R_REFUSED); - goto approved; - } - - queryacl = dns_zone_getqueryacl(zone); - if (queryacl == NULL) { - queryacl = client->view->queryacl; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOKVALID) != 0) { - /* - * We've evaluated the view's queryacl already. If - * NS_QUERYATTR_QUERYOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - dbversion->acl_checked = true; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOK) == 0) { - dbversion->queryok = false; - return (DNS_R_REFUSED); - } - dbversion->queryok = true; - goto approved; - } - } - - result = ns_client_checkaclsilent(client, NULL, queryacl, true); - if ((options & DNS_GETDB_NOLOG) == 0) { - char msg[NS_CLIENT_ACLMSGSIZE("query")]; - if (result == ISC_R_SUCCESS) { - if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - } - - if (queryacl == client->view->queryacl) { - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the default - * "allow-query" ACL. Remember this so we - * don't have to check again. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOK; - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_QUERYOK attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; - } - - /* If and only if we've gotten this far, check allow-query-on too */ - if (result == ISC_R_SUCCESS) { - queryonacl = dns_zone_getqueryonacl(zone); - if (queryonacl == NULL) - queryonacl = client->view->queryonacl; - - result = ns_client_checkaclsilent(client, &client->destaddr, - queryonacl, true); - if ((options & DNS_GETDB_NOLOG) == 0 && - result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "query-on denied"); - } - - dbversion->acl_checked = true; - if (result != ISC_R_SUCCESS) { - dbversion->queryok = false; - return (DNS_R_REFUSED); - } - dbversion->queryok = true; - - approved: - /* Transfer ownership, if necessary. */ - if (versionp != NULL) - *versionp = dbversion->version; - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp) -{ - isc_result_t result; - unsigned int ztoptions; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - bool partial = false; - - REQUIRE(zonep != NULL && *zonep == NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a zone database to answer the query. - */ - ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ? - DNS_ZTFIND_NOEXACT : 0; - - result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, - &zone); - - if (result == DNS_R_PARTIALMATCH) - partial = true; - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - result = dns_zone_getdb(zone, &db); - - if (result != ISC_R_SUCCESS) - goto fail; - - result = query_validatezonedb(client, name, qtype, options, zone, db, - versionp); - - if (result != ISC_R_SUCCESS) - goto fail; - - /* Transfer ownership. */ - *zonep = zone; - *dbp = db; - - if (partial && (options & DNS_GETDB_PARTIAL) != 0) - return (DNS_R_PARTIALMATCH); - return (ISC_R_SUCCESS); - - fail: - if (zone != NULL) - dns_zone_detach(&zone); - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static void -rpz_log_rewrite(ns_client_t *client, bool disabled, - dns_rpz_policy_t policy, dns_rpz_type_t type, - dns_zone_t *p_zone, dns_name_t *p_name, - dns_name_t *cname, dns_rpz_num_t rpz_num) -{ - char cname_buf[DNS_NAME_FORMATSIZE] = { 0 }; - char p_name_buf[DNS_NAME_FORMATSIZE]; - char qname_buf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - const char *s1 = cname_buf, *s2 = cname_buf; - dns_rdataset_t *rdataset; - dns_rpz_st_t *st; - isc_stats_t *zonestats; - - /* - * Count enabled rewrites in the global counter. - * Count both enabled and disabled rewrites for each zone. - */ - if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_rpz_rewrites); - } - if (p_zone != NULL) { - zonestats = dns_zone_getrequeststats(p_zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, - dns_nsstatscounter_rpz_rewrites); - } - - if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) - return; - - st = client->query.rpz_st; - if ((st->popt.no_log & DNS_RPZ_ZBIT(rpz_num)) != 0) - return; - - dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf)); - dns_name_format(p_name, p_name_buf, sizeof(p_name_buf)); - if (cname != NULL) { - s1 = " (CNAME to: "; - dns_name_format(cname, cname_buf, sizeof(cname_buf)); - s2 = ")"; - } - - /* - * Log Qclass and Qtype in addition to existing - * fields. - */ - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - INSIST(rdataset != NULL); - dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - - ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, -#ifdef RPZ_LOG_QTYPE_QCLASS - "%srpz %s %s rewrite %s/%s/%s via %s%s%s%s", -#else /* RPZ_LOG_QTYPE_QCLASS */ - "%srpz %s %s rewrite %s via %s%s%s%s", -#endif /* RPZ_LOG_QTYPE_QCLASS */ - disabled ? "disabled " : "", - dns_rpz_type2str(type), dns_rpz_policy2str(policy), - qname_buf, -#ifdef RPZ_LOG_QTYPE_QCLASS - typebuf, classbuf, -#endif /* RPZ_LOG_QTYPE_QCLASS */ - p_name_buf, s1, cname_buf, s2); -} - -static void -rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name, - dns_rpz_type_t rpz_type1, dns_rpz_type_t rpz_type2, - const char *str, isc_result_t result) -{ - char qnamebuf[DNS_NAME_FORMATSIZE]; - char p_namebuf[DNS_NAME_FORMATSIZE]; - const char *failed; - const char *slash; - const char *via; - const char *str_blank; - const char *rpztypestr1; - const char *rpztypestr2; - - if (!isc_log_wouldlog(ns_g_lctx, level)) - return; - - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems. - */ - if (level <= DNS_RPZ_DEBUG_LEVEL1) - failed = "failed: "; - else - failed = ": "; - - rpztypestr1 = dns_rpz_type2str(rpz_type1); - if (rpz_type2 != DNS_RPZ_TYPE_BAD) { - slash = "/"; - rpztypestr2 = dns_rpz_type2str(rpz_type2); - } else { - slash = ""; - rpztypestr2 = ""; - } - - str_blank = (*str != ' ' && *str != '\0') ? " " : ""; - dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf)); - if (p_name != NULL) { - via = " via "; - dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); - } else { - via = ""; - p_namebuf[0] = '\0'; - } - - ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, - NS_LOGMODULE_QUERY, level, - "rpz %s%s%s rewrite %s%s%s%s%s%s : %s", - rpztypestr1, slash, rpztypestr2, - qnamebuf, via, p_namebuf, str_blank, - str, failed, isc_result_totext(result)); -} - -static void -rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name, - dns_rpz_type_t rpz_type, const char *str, isc_result_t result) -{ - rpz_log_fail_helper(client, level, p_name, - rpz_type, DNS_RPZ_TYPE_BAD, str, result); -} - -/* - * Get a policy rewrite zone database. - */ -static isc_result_t -rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type, - dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) -{ - char qnamebuf[DNS_NAME_FORMATSIZE]; - char p_namebuf[DNS_NAME_FORMATSIZE]; - dns_dbversion_t *rpz_version = NULL; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_getdb"); - - result = query_getzonedb(client, p_name, dns_rdatatype_any, - DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version); - if (result == ISC_R_SUCCESS) { - dns_rpz_st_t *st = client->query.rpz_st; - - /* - * It isn't meaningful to log this message when - * logging is disabled for some policy zones. - */ - if (st->popt.no_log == 0 && - isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) - { - dns_name_format(client->query.qname, qnamebuf, - sizeof(qnamebuf)); - dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); - ns_client_log(client, DNS_LOGCATEGORY_RPZ, - NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2, - "try rpz %s rewrite %s via %s", - dns_rpz_type2str(rpz_type), - qnamebuf, p_namebuf); - } - *versionp = rpz_version; - return (ISC_R_SUCCESS); - } - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, - " query_getzonedb()", result); - return (result); -} - -static inline isc_result_t -query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - dns_db_t **dbp, unsigned int options) -{ - isc_result_t result; - bool check_acl; - dns_db_t *db = NULL; - - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a cache database to answer the query. - * This may fail with DNS_R_REFUSED if the client - * is not allowed to use the cache. - */ - - if (!USECACHE(client)) - return (DNS_R_REFUSED); - dns_db_attach(client->view->cachedb, &db); - - if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) { - /* - * We've evaluated the view's cacheacl already. If - * NS_QUERYATTR_CACHEACLOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - check_acl = false; - if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0) - goto refuse; - } else { - /* - * We haven't evaluated the view's queryacl yet. - */ - check_acl = true; - } - - if (check_acl) { - bool log = !(options & DNS_GETDB_NOLOG); - char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; - - result = ns_client_checkaclsilent(client, NULL, - client->view->cacheacl, - true); - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the "allow-query-cache" ACL. - * Remember this so we don't have to check again. - */ - client->query.attributes |= - NS_QUERYATTR_CACHEACLOK; - if (log && isc_log_wouldlog(ns_g_lctx, - ISC_LOG_DEBUG(3))) - { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else if (log) { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, msg, - sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID; - - if (result != ISC_R_SUCCESS) - goto refuse; - } - - /* Approved. */ - - /* Transfer ownership. */ - *dbp = db; - - return (ISC_R_SUCCESS); - - refuse: - result = DNS_R_REFUSED; - - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static inline isc_result_t -query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, bool *is_zonep) -{ - isc_result_t result; - - isc_result_t tresult; - unsigned int namelabels; - unsigned int zonelabels; - dns_zone_t *zone = NULL; - - REQUIRE(zonep != NULL && *zonep == NULL); - - /* Calculate how many labels are in name. */ - namelabels = dns_name_countlabels(name); - zonelabels = 0; - - /* Try to find name in bind's standard database. */ - result = query_getzonedb(client, name, qtype, options, &zone, - dbp, versionp); - - /* See how many labels are in the zone's name. */ - if (result == ISC_R_SUCCESS && zone != NULL) - zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); - - /* - * If # zone labels < # name labels, try to find an even better match - * Only try if DLZ drivers are loaded for this view - */ - if (ISC_UNLIKELY(zonelabels < namelabels && - !ISC_LIST_EMPTY(client->view->dlz_searched))) - { - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_db_t *tdbp; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - tdbp = NULL; - tresult = dns_view_searchdlz(client->view, name, - zonelabels, &cm, &ci, &tdbp); - /* If we successful, we found a better match. */ - if (tresult == ISC_R_SUCCESS) { - ns_dbversion_t *dbversion; - - /* - * If the previous search returned a zone, detach it. - */ - if (zone != NULL) - dns_zone_detach(&zone); - - /* - * If the previous search returned a database, - * detach it. - */ - if (*dbp != NULL) - dns_db_detach(dbp); - - /* - * If the previous search returned a version, clear it. - */ - *versionp = NULL; - - dbversion = query_findversion(client, tdbp); - if (dbversion == NULL) { - tresult = ISC_R_NOMEMORY; - } else { - /* - * Be sure to return our database. - */ - *dbp = tdbp; - *versionp = dbversion->version; - } - - /* - * We return a null zone, No stats for DLZ zones. - */ - zone = NULL; - result = tresult; - } - } - - /* If successful, Transfer ownership of zone. */ - if (result == ISC_R_SUCCESS) { - *zonep = zone; - /* - * If neither attempt above succeeded, return the cache instead - */ - *is_zonep = true; - } else if (result == ISC_R_NOTFOUND) { - result = query_getcachedb(client, name, qtype, dbp, options); - *is_zonep = false; - } - return (result); -} - -static inline bool -query_isduplicate(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t type, dns_name_t **mnamep) -{ - dns_section_t section; - dns_name_t *mname = NULL; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate"); - - for (section = DNS_SECTION_ANSWER; - section <= DNS_SECTION_ADDITIONAL; - section++) { - result = dns_message_findname(client->message, section, - name, type, 0, &mname, NULL); - if (result == ISC_R_SUCCESS) { - /* - * We've already got this RRset in the response. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_isduplicate: true: done"); - return (true); - } else if (result == DNS_R_NXRRSET) { - /* - * The name exists, but the rdataset does not. - */ - if (section == DNS_SECTION_ADDITIONAL) - break; - } else - RUNTIME_CHECK(result == DNS_R_NXDOMAIN); - mname = NULL; - } - - if (mnamep != NULL) - *mnamep = mname; - - CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done"); - return (false); -} - -static isc_result_t -query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - ns_client_t *client = arg; - isc_result_t result, eresult; - dns_dbnode_t *node; - dns_db_t *db; - dns_name_t *fname, *mname; - dns_rdataset_t *rdataset, *sigrdataset, *trdataset; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version; - bool added_something, need_addname; - dns_zone_t *zone; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_rdatasetadditional_t additionaltype; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(qtype != dns_rdatatype_any); - - if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) - return (ISC_R_SUCCESS); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional"); - - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - trdataset = NULL; - db = NULL; - version = NULL; - node = NULL; - added_something = false; - need_addname = false; - zone = NULL; - additionaltype = dns_rdatasetadditional_fromauth; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - */ - if (qtype == dns_rdatatype_a) - type = dns_rdatatype_any; - else - type = qtype; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) - goto try_cache; - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - result = dns_db_findext(db, name, version, type, - client->query.dboptions, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (sigrdataset != NULL && !dns_db_issecure(db) && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - goto found; - } - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - additionaltype = dns_rdatasetadditional_fromcache; - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - /* - * Attempt to validate glue. - */ - if (sigrdataset == NULL) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - result = dns_db_findext(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - - dns_cache_updatestats(client->view->cache, result); - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - if (result == ISC_R_SUCCESS) - goto found; - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poison caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - dns_db_attach(client->query.gluedb, &db); - - additionaltype = dns_rdatasetadditional_fromglue; - result = dns_db_findext(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) - goto cleanup; - - found: - /* - * We have found a potential additional data rdataset, or - * at least a node to iterate over. - */ - query_keepname(client, fname, dbuf); - - /* - * If we have an rdataset, add it to the additional data - * section. - */ - mname = NULL; - if (dns_rdataset_isassociated(rdataset) && - !query_isduplicate(client, fname, type, &mname)) { - if (mname != NULL) { - INSIST(mname != fname); - query_releasename(client, &fname); - fname = mname; - } else - need_addname = true; - ISC_LIST_APPEND(fname->list, rdataset, link); - trdataset = rdataset; - rdataset = NULL; - added_something = true; - /* - * Note: we only add SIGs if we've added the type they cover, - * so we do not need to check if the SIG rdataset is already - * in the response. - */ - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, sigrdataset, link); - sigrdataset = NULL; - } - } - - if (qtype == dns_rdatatype_a) { -#ifdef ALLOW_FILTER_AAAA - bool have_a = false; -#endif - - /* - * We now go looking for A and AAAA records, along with - * their signatures. - * - * XXXRTH This code could be more efficient. - */ - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - } else { - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - } - if (sigrdataset != NULL) { - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto addname; - } - if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) - goto aaaa_lookup; - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - rdataset, sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - bool invalid = false; - mname = NULL; -#ifdef ALLOW_FILTER_AAAA - have_a = true; -#endif - if (additionaltype == - dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - /* validate() may change rdataset->trust */ - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (!query_isduplicate(client, fname, - dns_rdatatype_a, &mname)) - { - if (mname != fname) { - if (mname != NULL) { - query_releasename(client, - &fname); - fname = mname; - } else - need_addname = true; - } - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = true; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = - query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - if (WANTDNSSEC(client) && sigrdataset == NULL) - goto addname; - } else { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - } - aaaa_lookup: - if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) - goto addname; - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_aaaa, 0, - client->now, - rdataset, sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - bool invalid = false; - mname = NULL; - /* - * There's an A; check whether we're filtering AAAA - */ -#ifdef ALLOW_FILTER_AAAA - if (have_a && - (client->filter_aaaa == dns_aaaa_break_dnssec || - (client->filter_aaaa == dns_aaaa_filter && - (!WANTDNSSEC(client) || sigrdataset == NULL || - !dns_rdataset_isassociated(sigrdataset))))) - goto addname; -#endif - if (additionaltype == - dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - /* validate() may change rdataset->trust */ - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (!query_isduplicate(client, fname, - dns_rdatatype_aaaa, &mname)) - { - if (mname != fname) { - if (mname != NULL) { - query_releasename(client, - &fname); - fname = mname; - } else - need_addname = true; - } - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = true; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = NULL; - } - rdataset = NULL; - } - } - } - - addname: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: addname"); - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be false. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - /* - * In a few cases, we want to add additional data for additional - * data. It's simpler to just deal with special cases here than - * to try to create a general purpose mechanism and allow the - * rdata implementations to do it themselves. - * - * This involves recursion, but the depth is limited. The - * most complex case is adding a SRV rdataset, which involves - * recursing to add address records, which in turn can cause - * recursion to add KEYs. - */ - if (type == dns_rdatatype_srv && trdataset != NULL) { - /* - * If we're adding SRV records to the additional data - * section, it's helpful if we add the SRV additional data - * as well. - */ - eresult = dns_rdataset_additionaldata(trdataset, - query_addadditional, - client); - } - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done"); - return (eresult); -} - -static inline void -query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base, - dns_rdatasetadditional_t additionaltype, - dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, dns_dbnode_t **nodep, - dns_name_t *fname) -{ - dns_rdataset_t *rdataset; - - while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) { - ISC_LIST_UNLINK(fname->list, rdataset, link); - query_putrdataset(client, &rdataset); - } - if (*versionp != NULL) - dns_db_closeversion(*dbp, versionp, false); - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - if (*dbp != NULL) - dns_db_detach(dbp); - if (*zonep != NULL) - dns_zone_detach(zonep); - (void)dns_rdataset_putadditional(client->view->acache, rdataset_base, - additionaltype, type); -} - -static inline isc_result_t -query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0, - dns_dbversion_t *version) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_dbversion_t *version_current = NULL; - dns_db_t *db_current = db0; - - if (db_current == NULL) { - result = dns_zone_getdb(zone, &db_current); - if (result != ISC_R_SUCCESS) - return (result); - } - dns_db_currentversion(db_current, &version_current); - if (db_current != db || version_current != version) { - result = ISC_R_FAILURE; - goto cleanup; - } - - cleanup: - dns_db_closeversion(db_current, &version_current, false); - if (db0 == NULL && db_current != NULL) - dns_db_detach(&db_current); - - return (result); -} - -static isc_result_t -query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - client_additionalctx_t *additionalctx = arg; - dns_rdataset_t *rdataset_base; - ns_client_t *client; - isc_result_t result, eresult; - dns_dbnode_t *node, *cnode; - dns_db_t *db, *cdb; - dns_name_t *fname, *mname0, cfname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_rdataset_t *crdataset, *crdataset_next; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version, *cversion; - bool added_something, need_addname, needadditionalcache; - bool need_sigrrset; - dns_zone_t *zone; - dns_rdatatype_t type; - dns_rdatasetadditional_t additionaltype; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - bool invalid; - - /* - * If we don't have an additional cache call query_addadditional. - */ - client = additionalctx->client; - REQUIRE(NS_CLIENT_VALID(client)); - - if (qtype != dns_rdatatype_a || client->view->acache == NULL) { - /* - * This function is optimized for "address" types. For other - * types, use a generic routine. - * XXX: ideally, this function should be generic enough. - */ - return (query_addadditional(additionalctx->client, - name, qtype)); - } - - /* - * Initialization. - */ - rdataset_base = additionalctx->rdataset; - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - db = NULL; - cdb = NULL; - version = NULL; - cversion = NULL; - node = NULL; - cnode = NULL; - added_something = false; - need_addname = false; - zone = NULL; - needadditionalcache = false; - POST(needadditionalcache); - additionaltype = dns_rdatasetadditional_fromauth; - dns_name_init(&cfname, NULL); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2"); - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - * XXXJT: this approach can cause a suboptimal result when the cache - * DB only has partial address types and the glue DB has remaining - * ones. - */ - type = dns_rdatatype_any; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - goto cleanup; - dns_name_setbuffer(&cfname, &b); /* share the buffer */ - - /* Check additional cache */ - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, &zone, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findauthdb; - if (zone == NULL) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: auth zone not found"); - goto try_cache; - } - - /* Is the cached DB up-to-date? */ - result = query_iscachevalid(zone, cdb, NULL, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: old auth additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findauthdb; - } - - if (cnode == NULL) { - /* - * We have a negative cache. We don't have to check the zone - * ACL, since the result (not using this zone) would be same - * regardless of the result. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: negative auth additional cache"); - dns_db_closeversion(cdb, &cversion, false); - dns_db_detach(&cdb); - dns_zone_detach(&zone); - goto try_cache; - } - - result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG, - zone, cdb, NULL); - if (result != ISC_R_SUCCESS) { - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto try_cache; - } - - /* We've got an active cache. */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: auth additional cache"); - dns_db_closeversion(cdb, &cversion, false); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - findauthdb: - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) { - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, NULL, NULL, NULL, - NULL); - goto try_cache; - } - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - node = NULL; - result = dns_db_findext(db, name, version, type, - client->query.dboptions, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, zone, db, - version, NULL, fname); - - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - additionaltype = dns_rdatasetadditional_fromcache; - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - - result = dns_db_findext(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poison caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - /* Check additional cache */ - additionaltype = dns_rdatasetadditional_fromglue; - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, NULL, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findglue; - - result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: old glue additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findglue; - } - - if (cnode == NULL) { - /* We have a negative cache. */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: negative glue additional cache"); - dns_db_closeversion(cdb, &cversion, false); - dns_db_detach(&cdb); - goto cleanup; - } - - /* Cache hit. */ - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: glue additional cache"); - dns_db_closeversion(cdb, &cversion, false); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - findglue: - dns_db_attach(client->query.gluedb, &db); - result = dns_db_findext(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) { - /* cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, db, version, NULL, - fname); - goto cleanup; - } - - found: - /* - * We have found a DB node to iterate over from a DB. - * We are going to look for address RRsets (i.e., A and AAAA) in the DB - * node we've just found. We'll then store the complete information - * in the additional data cache. - */ - dns_name_clone(fname, &cfname); - query_keepname(client, fname, dbuf); - needadditionalcache = true; - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto cleanup; - - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - - if (additionaltype == dns_rdatasetadditional_fromcache && - query_isduplicate(client, fname, dns_rdatatype_a, NULL)) - goto aaaa_lookup; - /* - * Find A RRset with sig RRset. Even if we don't find a sig RRset - * for a client using DNSSEC, we'll continue the process to make a - * complete list to be cached. However, we need to cancel the - * caching when something unexpected happens, in order to avoid - * caching incomplete information. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, - client->now, rdataset, sigrdataset); - - /* - * Try to promote pending/glue from the cache to secure. - * If unable to do so, drop it from the response unless - * it's glue, in which case it may still be needed. - */ - invalid = false; - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == DNS_R_NCACHENXDOMAIN) - goto setcache; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - /* Remember the result as a cache */ - ISC_LIST_APPEND(cfname.list, rdataset, link); - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (sigrdataset == NULL || rdataset == NULL) { - /* do not cache incomplete information */ - goto foundcache; - } - } - - aaaa_lookup: - if (additionaltype == dns_rdatasetadditional_fromcache && - query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) - goto foundcache; - /* Find AAAA RRset with sig RRset */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, - 0, client->now, rdataset, sigrdataset); - /* - * Try to promote pending/glue from the cache to secure. - * If unable to do so, drop it from the response unless - * it's glue, in which case it may still be needed. - */ - invalid = false; - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == ISC_R_SUCCESS) { - ISC_LIST_APPEND(cfname.list, rdataset, link); - rdataset = NULL; - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = NULL; - } - } - - setcache: - /* - * Set the new result in the cache if required. We do not support - * caching additional data from a cache DB. - */ - if (needadditionalcache == true && - (additionaltype == dns_rdatasetadditional_fromauth || - additionaltype == dns_rdatasetadditional_fromglue)) { - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - zone, db, version, node, - &cfname); - } - - foundcache: - need_sigrrset = false; - mname0 = NULL; - for (crdataset = ISC_LIST_HEAD(cfname.list); - crdataset != NULL; - crdataset = crdataset_next) { - dns_name_t *mname; - - crdataset_next = ISC_LIST_NEXT(crdataset, link); - - mname = NULL; - if (crdataset->type == dns_rdatatype_a || - crdataset->type == dns_rdatatype_aaaa) { - if (!query_isduplicate(client, fname, crdataset->type, - &mname)) { - if (mname != fname) { - if (mname != NULL) { - /* - * A different type of this name is - * already stored in the additional - * section. We'll reuse the name. - * Note that this should happen at most - * once. Otherwise, fname->link could - * leak below. - */ - INSIST(mname0 == NULL); - - query_releasename(client, &fname); - fname = mname; - mname0 = mname; - } else - need_addname = true; - } - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = true; - need_sigrrset = true; - } else - need_sigrrset = false; - } else if (crdataset->type == dns_rdatatype_rrsig && - need_sigrrset && WANTDNSSEC(client)) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = true; /* just in case */ - need_sigrrset = false; - } - } - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: addname"); - - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be false. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: cleanup"); - - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - query_putrdataset(client, &crdataset); - } - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: done"); - return (eresult); -} - -static inline void -query_addrdataset(ns_client_t *client, dns_name_t *fname, - dns_rdataset_t *rdataset) -{ - client_additionalctx_t additionalctx; - - /* - * Add 'rdataset' and any pertinent additional data to - * 'fname', a name in the response message for 'client'. - */ - - CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset"); - - ISC_LIST_APPEND(fname->list, rdataset, link); - - if (client->view->order != NULL) - rdataset->attributes |= dns_order_find(client->view->order, - fname, rdataset->type, - rdataset->rdclass); - rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; - - if (NOADDITIONAL(client)) - return; - - /* - * Add additional data. - * - * We don't care if dns_rdataset_additionaldata() fails. - */ - additionalctx.client = client; - additionalctx.rdataset = rdataset; - (void)dns_rdataset_additionaldata(rdataset, query_addadditional2, - &additionalctx); - CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done"); -} - -static isc_result_t -query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf, - dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdata_t *dns64_rdata; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t *dns64_rdatalist; - dns_rdataset_t *dns64_rdataset; - dns_rdataset_t *mrdataset; - isc_buffer_t *buffer; - isc_region_t r; - isc_result_t result; - dns_view_t *view = client->view; - isc_netaddr_t netaddr; - dns_dns64_t *dns64; - unsigned int flags = 0; - - /*% - * To the current response for 'client', add the answer RRset - * '*rdatasetp' and an optional signature set '*sigrdatasetp', with - * owner name '*namep', to section 'section', unless they are - * already there. Also add any pertinent additional data. - * - * If 'dbuf' is not NULL, then '*namep' is the name whose data is - * stored in 'dbuf'. In this case, query_addrrset() guarantees that - * when it returns the name will either have been kept or released. - */ - CTRACE(ISC_LOG_DEBUG(3), "query_dns64"); - name = *namep; - mname = NULL; - mrdataset = NULL; - buffer = NULL; - dns64_rdata = NULL; - dns64_rdataset = NULL; - dns64_rdatalist = NULL; - result = dns_message_findname(client->message, section, - name, dns_rdatatype_aaaa, - rdataset->covers, - &mname, &mrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - * There's nothing else to do; - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_dns64: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - return (ISC_R_SUCCESS); - } else if (result == DNS_R_NXDOMAIN) { - /* - * The name doesn't exist. - */ - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - *namep = NULL; - mname = name; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt * - 16 * dns_rdataset_count(rdataset)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(client->message, &dns64_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdatalist(client->message, - &dns64_rdatalist); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdatalist_init(dns64_rdatalist); - dns64_rdatalist->rdclass = dns_rdataclass_in; - dns64_rdatalist->type = dns_rdatatype_aaaa; - if (client->query.dns64_ttl != UINT32_MAX) - dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, - client->query.dns64_ttl); - else - dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600); - - if (RECURSIONOK(client)) - flags |= DNS_DNS64_RECURSIVE; - - /* - * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC - * as this provides a easy way to see if the answer was signed. - */ - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - flags |= DNS_DNS64_DNSSEC; - - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - for (dns64 = ISC_LIST_HEAD(client->view->dns64); - dns64 != NULL; dns64 = dns_dns64_next(dns64)) { - - dns_rdataset_current(rdataset, &rdata); - isc_buffer_availableregion(buffer, &r); - INSIST(r.length >= 16); - result = dns_dns64_aaaafroma(dns64, &netaddr, - client->signer, - &ns_g_server->aclenv, - flags, rdata.data, r.base); - if (result != ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - continue; - } - isc_buffer_add(buffer, 16); - isc_buffer_remainingregion(buffer, &r); - isc_buffer_forward(buffer, 16); - result = dns_message_gettemprdata(client->message, - &dns64_rdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdata_init(dns64_rdata); - dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in, - dns_rdatatype_aaaa, &r); - ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata, - link); - dns64_rdata = NULL; - dns_rdata_reset(&rdata); - } - } - if (result != ISC_R_NOMORE) - goto cleanup; - - if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) - goto cleanup; - - result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_setownercase(dns64_rdataset, mname); - client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; - dns64_rdataset->trust = rdataset->trust; - query_addrdataset(client, mname, dns64_rdataset); - dns64_rdataset = NULL; - dns64_rdatalist = NULL; - dns_message_takebuffer(client->message, &buffer); - inc_stats(client, dns_nsstatscounter_dns64); - result = ISC_R_SUCCESS; - - cleanup: - if (buffer != NULL) - isc_buffer_free(&buffer); - - if (dns64_rdata != NULL) - dns_message_puttemprdata(client->message, &dns64_rdata); - - if (dns64_rdataset != NULL) - dns_message_puttemprdataset(client->message, &dns64_rdataset); - - if (dns64_rdatalist != NULL) { - for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata); - dns64_rdata != NULL; - dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata)) - { - ISC_LIST_UNLINK(dns64_rdatalist->rdata, - dns64_rdata, link); - dns_message_puttemprdata(client->message, &dns64_rdata); - } - dns_message_puttemprdatalist(client->message, &dns64_rdatalist); - } - - CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done"); - return (result); -} - -static void -query_filter64(ns_client_t *client, dns_name_t **namep, - dns_rdataset_t *rdataset, isc_buffer_t *dbuf, - dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdata_t *myrdata; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t *myrdatalist; - dns_rdataset_t *myrdataset; - isc_buffer_t *buffer; - isc_region_t r; - isc_result_t result; - unsigned int i; - - CTRACE(ISC_LOG_DEBUG(3), "query_filter64"); - - INSIST(client->query.dns64_aaaaok != NULL); - INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset)); - - name = *namep; - mname = NULL; - buffer = NULL; - myrdata = NULL; - myrdataset = NULL; - myrdatalist = NULL; - result = dns_message_findname(client->message, section, - name, dns_rdatatype_aaaa, - rdataset->covers, - &mname, &myrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - * There's nothing else to do; - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_filter64: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - return; - } else if (result == DNS_R_NXDOMAIN) { - mname = name; - *namep = NULL; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - dbuf = NULL; - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - - result = isc_buffer_allocate(client->mctx, &buffer, - 16 * dns_rdataset_count(rdataset)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(client->message, &myrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdatalist(client->message, &myrdatalist); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdatalist_init(myrdatalist); - myrdatalist->rdclass = dns_rdataclass_in; - myrdatalist->type = dns_rdatatype_aaaa; - myrdatalist->ttl = rdataset->ttl; - - i = 0; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - if (!client->query.dns64_aaaaok[i++]) - continue; - dns_rdataset_current(rdataset, &rdata); - INSIST(rdata.length == 16); - isc_buffer_putmem(buffer, rdata.data, rdata.length); - isc_buffer_remainingregion(buffer, &r); - isc_buffer_forward(buffer, rdata.length); - result = dns_message_gettemprdata(client->message, &myrdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdata_init(myrdata); - dns_rdata_fromregion(myrdata, dns_rdataclass_in, - dns_rdatatype_aaaa, &r); - ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link); - myrdata = NULL; - dns_rdata_reset(&rdata); - } - if (result != ISC_R_NOMORE) - goto cleanup; - - result = dns_rdatalist_tordataset(myrdatalist, myrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_setownercase(myrdataset, name); - client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; - if (mname == name) { - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - dbuf = NULL; - } - myrdataset->trust = rdataset->trust; - query_addrdataset(client, mname, myrdataset); - myrdataset = NULL; - myrdatalist = NULL; - dns_message_takebuffer(client->message, &buffer); - - cleanup: - if (buffer != NULL) - isc_buffer_free(&buffer); - - if (myrdata != NULL) - dns_message_puttemprdata(client->message, &myrdata); - - if (myrdataset != NULL) - dns_message_puttemprdataset(client->message, &myrdataset); - - if (myrdatalist != NULL) { - for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata); - myrdata != NULL; - myrdata = ISC_LIST_HEAD(myrdatalist->rdata)) - { - ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link); - dns_message_puttemprdata(client->message, &myrdata); - } - dns_message_puttemprdatalist(client->message, &myrdatalist); - } - if (dbuf != NULL) - query_releasename(client, &name); - - CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done"); -} - -static void -query_addrrset(ns_client_t *client, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, - isc_buffer_t *dbuf, dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdataset_t *rdataset, *mrdataset, *sigrdataset; - isc_result_t result; - - /*% - * To the current response for 'client', add the answer RRset - * '*rdatasetp' and an optional signature set '*sigrdatasetp', with - * owner name '*namep', to section 'section', unless they are - * already there. Also add any pertinent additional data. - * - * If 'dbuf' is not NULL, then '*namep' is the name whose data is - * stored in 'dbuf'. In this case, query_addrrset() guarantees that - * when it returns the name will either have been kept or released. - */ - CTRACE(ISC_LOG_DEBUG(3), "query_addrrset"); - name = *namep; - rdataset = *rdatasetp; - if (sigrdatasetp != NULL) - sigrdataset = *sigrdatasetp; - else - sigrdataset = NULL; - mname = NULL; - mrdataset = NULL; - result = dns_message_findname(client->message, section, - name, rdataset->type, rdataset->covers, - &mname, &mrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addrrset: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) - mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - return; - } else if (result == DNS_R_NXDOMAIN) { - /* - * The name doesn't exist. - */ - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - *namep = NULL; - mname = name; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - /* - * Note: we only add SIGs if we've added the type they cover, so - * we do not need to check if the SIG rdataset is already in the - * response. - */ - query_addrdataset(client, mname, rdataset); - *rdatasetp = NULL; - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { - /* - * We have a signature. Add it to the response. - */ - ISC_LIST_APPEND(mname->list, sigrdataset, link); - *sigrdatasetp = NULL; - } - CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done"); -} - -static inline isc_result_t -query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, - unsigned int override_ttl, bool isassociated, - dns_section_t section) -{ - dns_name_t *name; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addsoa"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Don't add the SOA record for test which set "-T nosoa". - */ - if (ns_g_nosoa && (!WANTDNSSEC(client) || !isassociated)) - return (ISC_R_SUCCESS); - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client) && dns_db_issecure(db)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the SOA. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_soa, 0, client->now, - rdataset, sigrdataset); - } else { - dns_fixedname_t foundname; - dns_name_t *fname; - - fname = dns_fixedname_initname(&foundname); - - result = dns_db_findext(db, name, version, dns_rdatatype_soa, - client->query.dboptions, 0, &node, - fname, &cm, &ci, rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * This is bad. We tried to get the SOA RR at the zone top - * and it didn't work! - */ - CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex"); - eresult = DNS_R_SERVFAIL; - } else { - /* - * Extract the SOA MINIMUM. - */ - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (override_ttl != UINT32_MAX && - override_ttl < rdataset->ttl) { - rdataset->ttl = override_ttl; - if (sigrdataset != NULL) - sigrdataset->ttl = override_ttl; - } - - /* - * Add the SOA and its SIG to the response, with the - * TTLs adjusted per RFC2308 section 3. - */ - if (rdataset->ttl > soa.minimum) - rdataset->ttl = soa.minimum; - if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) - sigrdataset->ttl = soa.minimum; - - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - - if (section == DNS_SECTION_ADDITIONAL) - rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - section); - } - - cleanup: - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (eresult); -} - -static inline isc_result_t -query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { - dns_name_t *name, *fname; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_fixedname_t foundname; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addns"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - fname = dns_fixedname_initname(&foundname); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addns: dns_message_gettempname failed: done"); - return (result); - } - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client) && dns_db_issecure(db)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the NS rdataset. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_ns, 0, client->now, - rdataset, sigrdataset); - } else { - CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find"); - result = dns_db_findext(db, name, NULL, dns_rdatatype_ns, - client->query.dboptions, 0, &node, - fname, &cm, &ci, rdataset, sigrdataset); - CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete"); - } - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_addns: " - "dns_db_findrdataset or dns_db_find failed"); - /* - * This is bad. We tried to get the NS rdataset at the zone - * top and it didn't work! - */ - eresult = DNS_R_SERVFAIL; - } else { - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - DNS_SECTION_AUTHORITY); - } - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - CTRACE(ISC_LOG_DEBUG(3), "query_addns: done"); - return (eresult); -} -static isc_result_t -query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, - dns_trust_t trust, dns_ttl_t ttl) -{ - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_region_t r; - dns_name_t *aname; - isc_result_t result; - - /* - * We assume the name data referred to by tname won't go away. - */ - - aname = NULL; - result = dns_message_gettempname(client->message, &aname); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_name_dup(qname, client->mctx, aname); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - return (result); - } - - rdatalist = NULL; - result = dns_message_gettemprdatalist(client->message, &rdatalist); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - return (result); - } - rdata = NULL; - result = dns_message_gettemprdata(client->message, &rdata); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - dns_message_puttemprdatalist(client->message, &rdatalist); - return (result); - } - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - dns_message_puttemprdatalist(client->message, &rdatalist); - dns_message_puttemprdata(client->message, &rdata); - return (result); - } - rdatalist->type = dns_rdatatype_cname; - rdatalist->rdclass = client->message->rdclass; - rdatalist->ttl = ttl; - - dns_name_toregion(tname, &r); - rdata->data = r.base; - rdata->length = r.length; - rdata->rdclass = client->message->rdclass; - rdata->type = dns_rdatatype_cname; - - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); - rdataset->trust = trust; - dns_rdataset_setownercase(rdataset, aname); - - query_addrrset(client, &aname, &rdataset, NULL, NULL, - DNS_SECTION_ANSWER); - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, &rdataset); - } - if (aname != NULL) - dns_message_puttempname(client->message, &aname); - - return (ISC_R_SUCCESS); -} - -static bool -get_root_key_sentinel_id(ns_client_t *client, const char *ndata) { - unsigned int v = 0; - int i; - - for (i = 0; i < 5; i++) { - if (ndata[i] < '0' || ndata[i] > '9') { - return (false); - } - v *= 10; - v += ndata[i] - '0'; - } - if (v > 65535U) { - return (false); - } - client->query.root_key_sentinel_keyid = v; - return (true); -} - -/*% - * Find out if the query is for a root key sentinel and if so, record the type - * of root key sentinel query and the key id that is being checked for. - * - * The code is assuming a zero padded decimal field of width 5. - */ -static void -root_key_sentinel_detect(ns_client_t *client) { - const char *ndata = (const char *)client->query.qname->ndata; - - if (client->query.qname->length > 30 && ndata[0] == 29 && - strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0) - { - if (!get_root_key_sentinel_id(client, ndata + 25)) { - return; - } - client->query.root_key_sentinel_is_ta = true; - ns_client_log(client, NS_LOGCATEGORY_TAT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "root-key-sentinel-is-ta query label found"); - } else if (client->query.qname->length > 31 && ndata[0] == 30 && - strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0) - { - if (!get_root_key_sentinel_id(client, ndata + 26)) { - return; - } - client->query.root_key_sentinel_not_ta = true; - ns_client_log(client, NS_LOGCATEGORY_TAT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "root-key-sentinel-not-ta query label found"); - } -} - -/* - * Mark the RRsets as secure. Update the cache (db) to reflect the - * change in trust level. - */ -static void -mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - isc_stdtime_t now; - - rdataset->trust = dns_trust_secure; - sigrdataset->trust = dns_trust_secure; - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Save the updated secure state. Ignore failures. - */ - result = dns_db_findnodeext(db, name, true, &cm, &ci, &node); - if (result != ISC_R_SUCCESS) - return; - - isc_stdtime_get(&now); - dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now, - client->view->acceptexpired); - - (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, - 0, NULL); - (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, - 0, NULL); - dns_db_detachnode(db, &node); -} - -/* - * Find the secure key that corresponds to rrsig. - * Note: 'keyrdataset' maintains state between successive calls, - * there may be multiple keys with the same keyid. - * Return false if we have exhausted all the possible keys. - */ -static bool -get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, - dns_rdataset_t *keyrdataset, dst_key_t **keyp) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - bool secure = false; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (!dns_rdataset_isassociated(keyrdataset)) { - result = dns_db_findnodeext(db, &rrsig->signer, false, - &cm, &ci, &node); - if (result != ISC_R_SUCCESS) - return (false); - - result = dns_db_findrdataset(db, node, NULL, - dns_rdatatype_dnskey, 0, - client->now, keyrdataset, NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - return (false); - - if (keyrdataset->trust != dns_trust_secure) - return (false); - - result = dns_rdataset_first(keyrdataset); - } else - result = dns_rdataset_next(keyrdataset); - - for ( ; result == ISC_R_SUCCESS; - result = dns_rdataset_next(keyrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t b; - - dns_rdataset_current(keyrdataset, &rdata); - isc_buffer_init(&b, rdata.data, rdata.length); - isc_buffer_add(&b, rdata.length); - result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, - client->mctx, keyp); - if (result != ISC_R_SUCCESS) - continue; - if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && - rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && - dst_key_iszonekey(*keyp)) { - secure = true; - break; - } - dst_key_free(keyp); - } - return (secure); -} - -static bool -verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, - dns_rdata_t *rdata, ns_client_t *client) -{ - isc_result_t result; - dns_fixedname_t fixed; - bool ignore = false; - - dns_fixedname_init(&fixed); - -again: - result = dns_dnssec_verify3(name, rdataset, key, ignore, - client->view->maxbits, client->mctx, - rdata, NULL); - if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) { - ignore = true; - goto again; - } - if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) - return (true); - return (false); -} - -/* - * Validate the rdataset if possible with available records. - */ -static bool -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t rrsig; - dst_key_t *key = NULL; - dns_rdataset_t keyrdataset; - - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return (false); - - for (result = dns_rdataset_first(sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(sigrdataset)) { - - dns_rdata_reset(&rdata); - dns_rdataset_current(sigrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rrsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (!dns_resolver_algorithm_supported(client->view->resolver, - name, rrsig.algorithm)) - continue; - if (!dns_name_issubdomain(name, &rrsig.signer)) - continue; - dns_rdataset_init(&keyrdataset); - do { - if (!get_key(client, db, &rrsig, &keyrdataset, &key)) - break; - if (verify(key, name, rdataset, &rdata, client)) { - dst_key_free(&key); - dns_rdataset_disassociate(&keyrdataset); - mark_secure(client, db, name, &rrsig, - rdataset, sigrdataset); - return (true); - } - dst_key_free(&key); - } while (1); - if (dns_rdataset_isassociated(&keyrdataset)) - dns_rdataset_disassociate(&keyrdataset); - } - return (false); -} - -static void -query_addbestns(ns_client_t *client) { - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_name_t *fname, *zfname; - dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; - bool is_zone, use_zone; - isc_buffer_t *dbuf; - isc_result_t result; - dns_dbversion_t *version; - dns_zone_t *zone; - isc_buffer_t b; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addbestns"); - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - is_zone = false; - use_zone = false; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Find the right database. - */ - result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, - &zone, &db, &version, &is_zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - db_find: - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - /* - * Get the RRSIGs if the client requested them or if we may - * need to validate answers from the cache. - */ - if (WANTDNSSEC(client) || !is_zone) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Now look for the zonecut. - */ - if (is_zone) { - result = dns_db_findext(db, client->query.qname, version, - dns_rdatatype_ns, - client->query.dboptions, - client->now, &node, fname, - &cm, &ci, rdataset, sigrdataset); - if (result != DNS_R_DELEGATION) - goto cleanup; - if (USECACHE(client)) { - query_keepname(client, fname, dbuf); - dns_db_detachnode(db, &node); - SAVE(zdb, db); - SAVE(zfname, fname); - SAVE(zrdataset, rdataset); - SAVE(zsigrdataset, sigrdataset); - version = NULL; - dns_db_attach(client->view->cachedb, &db); - is_zone = false; - goto db_find; - } - } else { - result = dns_db_findzonecut(db, client->query.qname, - client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (zfname != NULL && - !dns_name_issubdomain(fname, zfname)) { - /* - * We found a zonecut in the cache, but our - * zone delegation is better. - */ - use_zone = true; - } - } else if (result == ISC_R_NOTFOUND && zfname != NULL) { - /* - * We didn't find anything in the cache, but we - * have a zone delegation, so use it. - */ - use_zone = true; - } else - goto cleanup; - } - - if (use_zone) { - query_releasename(client, &fname); - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - RESTORE(db, zdb); - RESTORE(fname, zfname); - RESTORE(rdataset, zrdataset); - RESTORE(sigrdataset, zsigrdataset); - } - - /* - * Attempt to validate RRsets that are pending or that are glue. - */ - if ((DNS_TRUST_PENDING(rdataset->trust) || - (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) - && !validate(client, db, fname, rdataset, sigrdataset) && - !PENDINGOK(client->query.dboptions)) - goto cleanup; - - if ((DNS_TRUST_GLUE(rdataset->trust) || - (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) && - !validate(client, db, fname, rdataset, sigrdataset) && - SECURE(client) && WANTDNSSEC(client)) - goto cleanup; - - /* - * If the answer is secure only add NS records if they are secure - * when the client may be looking for AD in the response. - */ - if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) && - ((rdataset->trust != dns_trust_secure) || - (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure))) - goto cleanup; - - /* - * If the client doesn't want DNSSEC we can discard the sigrdataset - * now. - */ - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } -} - -static void -fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) { - if (*rdataset == NULL) - *rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(*rdataset)) - dns_rdataset_disassociate(*rdataset); -} - -static void -fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf, - isc_buffer_t *nbuf) -{ - if (*fname == NULL) { - *dbuf = query_getnamebuf(client); - if (*dbuf == NULL) - return; - *fname = query_newname(client, *dbuf, nbuf); - } -} - -static void -query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_name_t *name) -{ - dns_fixedname_t fixed; - dns_name_t *fname = NULL; - dns_name_t *rname; - dns_rdataset_t *rdataset, *sigrdataset; - isc_buffer_t *dbuf, b; - isc_result_t result; - unsigned int count; - - CTRACE(ISC_LOG_DEBUG(3), "query_addds"); - rname = NULL; - rdataset = NULL; - sigrdataset = NULL; - - /* - * We'll need some resources... - */ - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - /* - * Look for the DS record, which may or may not be present. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0, - client->now, rdataset, sigrdataset); - /* - * If we didn't find it, look for an NSEC. - */ - if (result == ISC_R_NOTFOUND) - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec, 0, client->now, - rdataset, sigrdataset); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto addnsec3; - if (!dns_rdataset_isassociated(rdataset) || - !dns_rdataset_isassociated(sigrdataset)) - goto addnsec3; - - /* - * We've already added the NS record, so if the name's not there, - * we have other problems. Use this name rather than calling - * query_addrrset(). - */ - result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rname = NULL; - dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, - &rname); - result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_APPEND(rname->list, rdataset, link); - ISC_LIST_APPEND(rname->list, sigrdataset, link); - rdataset = NULL; - sigrdataset = NULL; - return; - - addnsec3: - if (!dns_db_iszone(db)) - goto cleanup; - /* - * Add the NSEC3 which proves the DS does not exist. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - dns_fixedname_init(&fixed); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - query_findclosestnsec3(name, db, version, client, rdataset, - sigrdataset, fname, true, - dns_fixedname_name(&fixed)); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - /* - * Did we find the closest provable encloser instead? - * If so add the nearest to the closest provable encloser. - */ - if (!dns_name_equal(name, dns_fixedname_name(&fixed))) { - count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1; - dns_name_getlabelsequence(name, - dns_name_countlabels(name) - count, - count, dns_fixedname_name(&fixed)); - fixfname(client, &fname, &dbuf, &b); - fixrdataset(client, &rdataset); - fixrdataset(client, &sigrdataset); - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - query_findclosestnsec3(dns_fixedname_name(&fixed), db, version, - client, rdataset, sigrdataset, fname, - false, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - } - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); -} - -static void -query_addwildcardproof(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t *name, - bool ispositive, bool nodata) -{ - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_fixedname_t wfixed; - dns_name_t *wname; - dns_dbnode_t *node; - unsigned int options; - unsigned int olabels, nlabels, labels; - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec_t nsec; - bool have_wname; - int order; - dns_fixedname_t cfixed; - dns_name_t *cname; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof"); - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - node = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Get the NOQNAME proof then if !ispositive - * get the NOWILDCARD proof. - * - * DNS_DBFIND_NOWILD finds the NSEC records that covers the - * name ignoring any wildcard. From the owner and next names - * of this record you can compute which wildcard (if it exists) - * will match by finding the longest common suffix of the - * owner name and next names with the qname and prefixing that - * with the wildcard label. - * - * e.g. - * Given: - * example SOA - * example NSEC b.example - * b.example A - * b.example NSEC a.d.example - * a.d.example A - * a.d.example NSEC g.f.example - * g.f.example A - * g.f.example NSEC z.i.example - * z.i.example A - * z.i.example NSEC example - * - * QNAME: - * a.example -> example NSEC b.example - * owner common example - * next common example - * wild *.example - * d.b.example -> b.example NSEC a.d.example - * owner common b.example - * next common example - * wild *.b.example - * a.f.example -> a.d.example NSEC g.f.example - * owner common example - * next common f.example - * wild *.f.example - * j.example -> z.i.example NSEC example - * owner common example - * next common example - * wild *.example - */ - options = client->query.dboptions | DNS_DBFIND_NOWILD; - wname = dns_fixedname_initname(&wfixed); - again: - have_wname = false; - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - result = dns_db_findext(db, name, version, dns_rdatatype_nsec, - options, 0, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - if (!dns_rdataset_isassociated(rdataset)) { - /* - * No NSEC proof available, return NSEC3 proofs instead. - */ - cname = dns_fixedname_initname(&cfixed); - /* - * Find the closest encloser. - */ - dns_name_copy(name, cname, NULL); - while (result == DNS_R_NXDOMAIN) { - labels = dns_name_countlabels(cname) - 1; - /* - * Sanity check. - */ - if (labels == 0U) - goto cleanup; - dns_name_split(cname, labels, NULL, cname); - result = dns_db_findext(db, cname, version, - dns_rdatatype_nsec, - options, 0, NULL, fname, - &cm, &ci, NULL, NULL); - } - /* - * Add closest (provable) encloser NSEC3. - */ - query_findclosestnsec3(cname, db, version, client, rdataset, - sigrdataset, fname, true, cname); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - if (!ispositive) - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - /* - * Replace resources which were consumed by query_addrrset. - */ - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - - if (rdataset == NULL) - rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (sigrdataset == NULL) - sigrdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - /* - * Add no qname proof. - */ - labels = dns_name_countlabels(cname) + 1; - if (dns_name_countlabels(name) == labels) - dns_name_copy(name, wname, NULL); - else - dns_name_split(name, labels, NULL, wname); - - query_findclosestnsec3(wname, db, version, client, rdataset, - sigrdataset, fname, false, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - if (ispositive) - goto cleanup; - - /* - * Replace resources which were consumed by query_addrrset. - */ - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - - if (rdataset == NULL) - rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (sigrdataset == NULL) - sigrdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - /* - * Add the no wildcard proof. - */ - result = dns_name_concatenate(dns_wildcardname, - cname, wname, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - query_findclosestnsec3(wname, db, version, client, rdataset, - sigrdataset, fname, nodata, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - goto cleanup; - } else if (result == DNS_R_NXDOMAIN) { - if (!ispositive) - result = dns_rdataset_first(rdataset); - if (result == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - (void)dns_name_fullcompare(name, fname, &order, - &olabels); - (void)dns_name_fullcompare(name, &nsec.next, &order, - &nlabels); - /* - * Check for a pathological condition created when - * serving some malformed signed zones and bail out. - */ - if (dns_name_countlabels(name) == nlabels) - goto cleanup; - - if (olabels > nlabels) - dns_name_split(name, olabels, NULL, wname); - else - dns_name_split(name, nlabels, NULL, wname); - result = dns_name_concatenate(dns_wildcardname, - wname, wname, NULL); - if (result == ISC_R_SUCCESS) - have_wname = true; - dns_rdata_freestruct(&nsec); - } - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (have_wname) { - ispositive = true; /* prevent loop */ - if (!dns_name_equal(name, wname)) { - name = wname; - goto again; - } - } - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); -} - -static void -query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp) -{ - dns_name_t *name; - dns_rdataset_t *sigrdataset; - dns_rdata_t sigrdata; - dns_rdata_rrsig_t sig; - unsigned int labels; - isc_buffer_t *dbuf, b; - dns_name_t *fname; - isc_result_t result; - - name = *namep; - if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) { - query_addrrset(client, namep, rdatasetp, sigrdatasetp, - NULL, DNS_SECTION_AUTHORITY); - return; - } - - if (sigrdatasetp == NULL) - return; - - sigrdataset = *sigrdatasetp; - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return; - result = dns_rdataset_first(sigrdataset); - if (result != ISC_R_SUCCESS) - return; - dns_rdata_init(&sigrdata); - dns_rdataset_current(sigrdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &sig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - labels = dns_name_countlabels(name); - if ((unsigned int)sig.labels + 1 >= labels) - return; - - /* XXX */ - query_addwildcardproof(client, db, version, client->query.qname, - true, false); - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - return; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - return; - dns_name_split(name, sig.labels + 1, NULL, fname); - /* This will succeed, since we've stripped labels. */ - RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, - NULL) == ISC_R_SUCCESS); - query_addrrset(client, &fname, rdatasetp, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); -} - -static void -free_devent(ns_client_t *client, isc_event_t **eventp, - dns_fetchevent_t **deventp) -{ - dns_fetchevent_t *devent = *deventp; - - REQUIRE((void*)(*eventp) == (void *)(*deventp)); - - if (devent->fetch != NULL) - dns_resolver_destroyfetch(&devent->fetch); - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - if (devent->rdataset != NULL) - query_putrdataset(client, &devent->rdataset); - if (devent->sigrdataset != NULL) - query_putrdataset(client, &devent->sigrdataset); - /* - * If the two pointers are the same then leave the setting of - * (*deventp) to NULL to isc_event_free. - */ - if ((void *)eventp != (void *)deventp) - (*deventp) = NULL; - isc_event_free(eventp); -} - -/*% - * Check the configured trust anchors for a root zone trust anchor - * with a key id that matches client->query.root_key_sentinel_keyid. - * - * Return true when found, otherwise return false. - */ -static bool -has_ta(ns_client_t *client) { - dns_keytable_t *keytable = NULL; - dns_keynode_t *keynode = NULL; - isc_result_t result; - - result = dns_view_getsecroots(client->view, &keytable); - if (result != ISC_R_SUCCESS) { - return (false); - } - - result = dns_keytable_find(keytable, dns_rootname, &keynode); - while (result == ISC_R_SUCCESS) { - dns_keynode_t *nextnode = NULL; - dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode)); - if (keyid == client->query.root_key_sentinel_keyid) { - dns_keytable_detachkeynode(keytable, &keynode); - dns_keytable_detach(&keytable); - return (true); - } - result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); - dns_keytable_detachkeynode(keytable, &keynode); - keynode = nextnode; - } - dns_keytable_detach(&keytable); - - return (false); -} - -/*% - * Check if a root key sentinel SERVFAIL should be returned. - */ -static bool -root_key_sentinel_return_servfail(ns_client_t *client, bool is_zone, - dns_rdataset_t *rdataset, isc_result_t result) -{ - /* - * Are we looking at a "root-key-sentinel" query? - */ - if (!client->query.root_key_sentinel_is_ta && - !client->query.root_key_sentinel_not_ta) - { - return (false); - } - - /* - * We only care about the query if 'result' indicates we have a cached - * answer. - */ - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_CNAME: - case DNS_R_DNAME: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - break; - default: - return (false); - } - - /* - * Do we meet the specified conditions to return SERVFAIL? - */ - if (!is_zone && rdataset->trust == dns_trust_secure && - ((client->query.root_key_sentinel_is_ta && !has_ta(client)) || - (client->query.root_key_sentinel_not_ta && has_ta(client)))) - { - return (true); - } - - /* - * As special processing may only be triggered by the original QNAME, - * disable it after following a CNAME/DNAME. - */ - client->query.root_key_sentinel_is_ta = false; - client->query.root_key_sentinel_not_ta = false; - - return (false); -} - -static void -query_resume(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - dns_fetch_t *fetch = NULL; - ns_client_t *client; - bool fetch_canceled, client_shuttingdown; - isc_result_t result; - isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_ERRORS; - int errorloglevel; - - /* - * Resume a query after recursion. - */ - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - client = devent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(RECURSING(client)); - - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - /* - * This is the fetch we've been waiting for. - */ - INSIST(devent->fetch == client->query.fetch); - client->query.fetch = NULL; - fetch_canceled = false; - /* - * Update client->now. - */ - isc_stdtime_get(&client->now); - } else { - /* - * This is a fetch completion event for a canceled fetch. - * Clean up and don't resume the find. - */ - fetch_canceled = true; - } - UNLOCK(&client->query.fetchlock); - INSIST(client->query.fetch == NULL); - - client->query.attributes &= ~NS_QUERYATTR_RECURSING; - SAVE(fetch, devent->fetch); - - /* - * If this client is shutting down, or this transaction - * has timed out, do not resume the find. - */ - client_shuttingdown = ns_client_shuttingdown(client); - if (fetch_canceled || client_shuttingdown) { - free_devent(client, &event, &devent); - if (fetch_canceled) { - CTRACE(ISC_LOG_ERROR, "fetch cancelled"); - query_error(client, DNS_R_SERVFAIL, __LINE__); - } else - query_next(client, ISC_R_CANCELED); - /* - * This may destroy the client. - */ - ns_client_detach(&client); - } else { - result = query_find(client, devent, 0); - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_SERVFAIL) - errorloglevel = ISC_LOG_DEBUG(2); - else - errorloglevel = ISC_LOG_DEBUG(4); - if (isc_log_wouldlog(ns_g_lctx, errorloglevel)) { - dns_resolver_logfetch(fetch, ns_g_lctx, - logcategory, - NS_LOGMODULE_QUERY, - errorloglevel, false); - } - } - } - - dns_resolver_destroyfetch(&fetch); -} - -static void -prefetch_done(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - ns_client_t *client; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - client = devent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - LOCK(&client->query.fetchlock); - if (client->query.prefetch != NULL) { - INSIST(devent->fetch == client->query.prefetch); - client->query.prefetch = NULL; - } - UNLOCK(&client->query.fetchlock); - free_devent(client, &event, &devent); - ns_client_detach(&client); -} - -static void -query_prefetch(ns_client_t *client, dns_name_t *qname, - dns_rdataset_t *rdataset) -{ - isc_result_t result; - isc_sockaddr_t *peeraddr; - dns_rdataset_t *tmprdataset; - ns_client_t *dummy = NULL; - unsigned int options; - - if (client->query.prefetch != NULL || - client->view->prefetch_trigger == 0U || - rdataset->ttl > client->view->prefetch_trigger || - (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) - return; - - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client)) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - return; - } - - tmprdataset = query_newrdataset(client); - if (tmprdataset == NULL) - return; - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - ns_client_attach(client, &dummy); - options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH; - result = dns_resolver_createfetch3(client->view->resolver, - qname, rdataset->type, NULL, NULL, - NULL, peeraddr, client->message->id, - options, 0, NULL, client->task, - prefetch_done, client, - tmprdataset, NULL, - &client->query.prefetch); - if (result != ISC_R_SUCCESS) { - query_putrdataset(client, &tmprdataset); - ns_client_detach(&dummy); - } - dns_rdataset_clearprefetch(rdataset); -} - - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -static void -log_quota(ns_client_t *client, _Atomic(isc_stdtime_t) *last, isc_stdtime_t now, - const char *fmt, const char *tail) -#else -static void -log_quota(ns_client_t *client, isc_stdtime_t *last, isc_stdtime_t now, - const char *fmt, const char *tail) -#endif -{ - isc_stdtime_t old = last_load(last); - if (now > old || (old + 1) > now) { - if (last_cmpxchg(last, &old, now)) { - LOCK(&ns_g_server->recursionquota.lock); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, fmt, - ns_g_server->recursionquota.used, - ns_g_server->recursionquota.soft, - ns_g_server->recursionquota.max, - tail); - UNLOCK(&ns_g_server->recursionquota.lock); - } - } -} - -/*% - * Check whether the recursion parameters in 'param' match the current query's - * recursion parameters provided in 'qtype', 'qname', and 'qdomain'. - */ -static bool -recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - REQUIRE(param != NULL); - - return (param->qtype == qtype && - param->qname != NULL && qname != NULL && - param->qdomain != NULL && qdomain != NULL && - dns_name_equal(param->qname, qname) && - dns_name_equal(param->qdomain, qdomain)); -} - -/*% - * Update 'param' with current query's recursion parameters provided in - * 'qtype', 'qname', and 'qdomain'. - */ -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - isc_result_t result; - - REQUIRE(param != NULL); - - param->qtype = qtype; - - if (qname == NULL) { - param->qname = NULL; - } else { - param->qname = dns_fixedname_initname(¶m->fqname); - result = dns_name_copy(qname, param->qname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - if (qdomain == NULL) { - param->qdomain = NULL; - } else { - param->qdomain = dns_fixedname_initname(¶m->fqdomain); - result = dns_name_copy(qdomain, param->qdomain, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } -} - -static isc_result_t -query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, - dns_name_t *qdomain, dns_rdataset_t *nameservers, - bool resuming) -{ - isc_result_t result; - dns_rdataset_t *rdataset, *sigrdataset; - isc_sockaddr_t *peeraddr; - - /* - * Check recursion parameters from the previous query to see if they - * match. If not, update recursion parameters and proceed. - */ - if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "recursion loop detected"); - return (ISC_R_FAILURE); - } - - recparam_update(&client->query.recparam, qtype, qname, qdomain); - - if (!resuming) - inc_stats(client, dns_nsstatscounter_recursion); - - /* - * We are about to recurse, which means that this client will - * be unavailable for serving new requests for an indeterminate - * amount of time. If this client is currently responsible - * for handling incoming queries, set up a new client - * object to handle them while we are waiting for a - * response. There is no need to replace TCP clients - * because those have already been replaced when the - * connection was accepted (if allowed by the TCP quota). - */ - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - - if (result == ISC_R_SOFTQUOTA) { -#ifdef ISC_PLATFORM_HAVESTDATOMIC - static _Atomic(isc_stdtime_t) last = 0; -#else - static isc_stdtime_t last = 0; -#endif - isc_stdtime_t now; - isc_stdtime_get(&now); - log_quota(client, &last, now, - "recursive-clients soft limit exceeded " - "(%d/%d/%d) %s", "aborting oldest query"); - ns_client_killoldestquery(client); - result = ISC_R_SUCCESS; - } else if (result == ISC_R_QUOTA) { -#ifdef ISC_PLATFORM_HAVESTDATOMIC - static _Atomic(isc_stdtime_t) last = 0; -#else - static isc_stdtime_t last = 0; -#endif - isc_stdtime_t now; - isc_stdtime_get(&now); - log_quota(client, &last, now, - "no more recursive clients (%d/%d/%d): %s", - isc_result_totext(result)); - ns_client_killoldestquery(client); - } - if (result == ISC_R_SUCCESS && !client->mortal && - !TCP(client)) { - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "ns_client_replace() failed: %s", - isc_result_totext(result)); - isc_quota_detach(&client->recursionquota); - isc_stats_decrement(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - } - if (result != ISC_R_SUCCESS) - return (result); - ns_client_recursing(client); - } - - /* - * Invoke the resolver. - */ - REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); - REQUIRE(client->query.fetch == NULL); - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - return (ISC_R_NOMEMORY); - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - query_putrdataset(client, &rdataset); - return (ISC_R_NOMEMORY); - } - } else - sigrdataset = NULL; - - if (client->query.timerset == false) - ns_client_settimeout(client, 60); - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - result = dns_resolver_createfetch3(client->view->resolver, - qname, qtype, qdomain, nameservers, - NULL, peeraddr, client->message->id, - client->query.fetchoptions, 0, NULL, - client->task, query_resume, client, - rdataset, sigrdataset, - &client->query.fetch); - - if (result == ISC_R_SUCCESS) { - /* - * Record that we're waiting for an event. A client which - * is shutting down will not be destroyed until all the - * events have been received. - */ - } else { - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - } - - return (result); -} - -static inline void -rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep, - dns_rdataset_t **rdatasetp) -{ - if (nodep != NULL && *nodep != NULL) { - REQUIRE(dbp != NULL && *dbp != NULL); - dns_db_detachnode(*dbp, nodep); - } - if (dbp != NULL && *dbp != NULL) - dns_db_detach(dbp); - if (zonep != NULL && *zonep != NULL) - dns_zone_detach(zonep); - if (rdatasetp != NULL && *rdatasetp != NULL && - dns_rdataset_isassociated(*rdatasetp)) - dns_rdataset_disassociate(*rdatasetp); -} - -static inline void -rpz_match_clear(dns_rpz_st_t *st) { - rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); - st->m.version = NULL; -} - -static inline isc_result_t -rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) { - REQUIRE(rdatasetp != NULL); - - CTRACE(ISC_LOG_DEBUG(3), "rpz_ready"); - - if (*rdatasetp == NULL) { - *rdatasetp = query_newrdataset(client); - if (*rdatasetp == NULL) { - CTRACE(ISC_LOG_ERROR, - "rpz_ready: query_newrdataset failed"); - return (DNS_R_SERVFAIL); - } - } else if (dns_rdataset_isassociated(*rdatasetp)) { - dns_rdataset_disassociate(*rdatasetp); - } - return (ISC_R_SUCCESS); -} - -static void -rpz_st_clear(ns_client_t *client) { - dns_rpz_st_t *st = client->query.rpz_st; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_st_clear"); - - if (st->m.rdataset != NULL) - query_putrdataset(client, &st->m.rdataset); - rpz_match_clear(st); - - rpz_clean(NULL, &st->r.db, NULL, NULL); - if (st->r.ns_rdataset != NULL) - query_putrdataset(client, &st->r.ns_rdataset); - if (st->r.r_rdataset != NULL) - query_putrdataset(client, &st->r.r_rdataset); - - rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL); - if (st->q.rdataset != NULL) - query_putrdataset(client, &st->q.rdataset); - if (st->q.sigrdataset != NULL) - query_putrdataset(client, &st->q.sigrdataset); - st->state = 0; - st->m.type = DNS_RPZ_TYPE_BAD; - st->m.policy = DNS_RPZ_POLICY_MISS; -} - -static dns_rpz_zbits_t -rpz_get_zbits(ns_client_t *client, - dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type) -{ - dns_rpz_st_t *st; - dns_rpz_zbits_t zbits; - - REQUIRE(client != NULL); - REQUIRE(client->query.rpz_st != NULL); - - st = client->query.rpz_st; - - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - zbits = st->have.client_ip; - break; - case DNS_RPZ_TYPE_QNAME: - zbits = st->have.qname; - break; - case DNS_RPZ_TYPE_IP: - if (ip_type == dns_rdatatype_a) { - zbits = st->have.ipv4; - } else if (ip_type == dns_rdatatype_aaaa) { - zbits = st->have.ipv6; - } else { - zbits = st->have.ip; - } - break; - case DNS_RPZ_TYPE_NSDNAME: - zbits = st->have.nsdname; - break; - case DNS_RPZ_TYPE_NSIP: - if (ip_type == dns_rdatatype_a) { - zbits = st->have.nsipv4; - } else if (ip_type == dns_rdatatype_aaaa) { - zbits = st->have.nsipv6; - } else { - zbits = st->have.nsip; - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - break; - } - - /* - * Choose - * the earliest configured policy zone (rpz->num) - * QNAME over IP over NSDNAME over NSIP (rpz_type) - * the smallest name, - * the longest IP address prefix, - * the lexically smallest address. - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.type >= rpz_type) { - zbits &= DNS_RPZ_ZMASK(st->m.rpz->num); - } else{ - zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1; - } - } - - /* - * If the client wants recursion, allow only compatible policies. - */ - if (!RECURSIONOK(client)) - zbits &= st->popt.no_rd_ok; - - return (zbits); -} - -static void -query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) { - isc_result_t result; - isc_sockaddr_t *peeraddr; - dns_rdataset_t *tmprdataset; - ns_client_t *dummy = NULL; - unsigned int options; - - if (client->query.prefetch != NULL) - return; - - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client)) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - return; - } - - tmprdataset = query_newrdataset(client); - if (tmprdataset == NULL) - return; - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - ns_client_attach(client, &dummy); - options = client->query.fetchoptions; - result = dns_resolver_createfetch3(client->view->resolver, qname, type, - NULL, NULL, NULL, peeraddr, - client->message->id, options, 0, - NULL, client->task, prefetch_done, - client, tmprdataset, NULL, - &client->query.prefetch); - if (result != ISC_R_SUCCESS) { - query_putrdataset(client, &tmprdataset); - ns_client_detach(&dummy); - } -} - -/* - * Get an NS, A, or AAAA rrset related to the response for the client - * to check the contents of that rrset for hits by eligible policy zones. - */ -static isc_result_t -rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, - dns_rpz_type_t rpz_type, dns_db_t **dbp, - dns_dbversion_t *version, dns_rdataset_t **rdatasetp, - bool resuming) -{ - dns_rpz_st_t *st; - bool is_zone; - dns_dbnode_t *node; - dns_fixedname_t fixed; - dns_name_t *found; - isc_result_t result; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find"); - - st = client->query.rpz_st; - if ((st->state & DNS_RPZ_RECURSING) != 0) { - INSIST(st->r.r_type == type); - INSIST(dns_name_equal(name, st->r_name)); - INSIST(*rdatasetp == NULL || - !dns_rdataset_isassociated(*rdatasetp)); - st->state &= ~DNS_RPZ_RECURSING; - RESTORE(*dbp, st->r.db); - if (*rdatasetp != NULL) - query_putrdataset(client, rdatasetp); - RESTORE(*rdatasetp, st->r.r_rdataset); - result = st->r.r_result; - if (result == DNS_R_DELEGATION) { - CTRACE(ISC_LOG_ERROR, "RPZ recursing"); - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " rpz_rrset_find(1)", result); - st->m.policy = DNS_RPZ_POLICY_ERROR; - result = DNS_R_SERVFAIL; - } - return (result); - } - - result = rpz_ready(client, rdatasetp); - if (result != ISC_R_SUCCESS) { - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (result); - } - if (*dbp != NULL) { - is_zone = false; - } else { - dns_zone_t *zone; - - version = NULL; - zone = NULL; - result = query_getdb(client, name, type, 0, &zone, dbp, - &version, &is_zone); - if (result != ISC_R_SUCCESS) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " rpz_rrset_find(2)", result); - st->m.policy = DNS_RPZ_POLICY_ERROR; - if (zone != NULL) - dns_zone_detach(&zone); - return (result); - } - if (zone != NULL) - dns_zone_detach(&zone); - } - - node = NULL; - found = dns_fixedname_initname(&fixed); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK, - client->now, &node, found, - &cm, &ci, *rdatasetp, NULL); - if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { - /* - * Try the cache if we're authoritative for an - * ancestor but not the domain itself. - */ - rpz_clean(NULL, dbp, &node, rdatasetp); - version = NULL; - dns_db_attach(client->view->cachedb, dbp); - result = dns_db_findext(*dbp, name, version, type, - 0, client->now, &node, found, - &cm, &ci, *rdatasetp, NULL); - } - rpz_clean(NULL, dbp, &node, NULL); - if (result == DNS_R_DELEGATION) { - rpz_clean(NULL, NULL, NULL, rdatasetp); - /* - * Recurse for NS rrset or A or AAAA rrset for an NS. - * Do not recurse for addresses for the query name. - */ - if (rpz_type == DNS_RPZ_TYPE_IP) { - result = DNS_R_NXRRSET; - } else if (!client->view->rpzs->p.nsip_wait_recurse) { - query_rpzfetch(client, name, type); - result = DNS_R_NXRRSET; - } else { - dns_name_copy(name, st->r_name, NULL); - result = query_recurse(client, type, st->r_name, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - st->state |= DNS_RPZ_RECURSING; - result = DNS_R_DELEGATION; - } - } - } - return (result); -} - -/* - * Compute a policy owner name, p_name, in a policy zone given the needed - * policy type and the trigger name. - */ -static isc_result_t -rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, - dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_name_t *trig_name) -{ - dns_offsets_t prefix_offsets; - dns_name_t prefix, *suffix; - unsigned int first, labels; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_get_p_name"); - - /* - * The policy owner name consists of a suffix depending on the type - * and policy zone and a prefix that is the longest possible string - * from the trigger name that keesp the resulting policy owner name - * from being too long. - */ - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - suffix = &rpz->client_ip; - break; - case DNS_RPZ_TYPE_QNAME: - suffix = &rpz->origin; - break; - case DNS_RPZ_TYPE_IP: - suffix = &rpz->ip; - break; - case DNS_RPZ_TYPE_NSDNAME: - suffix = &rpz->nsdname; - break; - case DNS_RPZ_TYPE_NSIP: - suffix = &rpz->nsip; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Start with relative version of the full trigger name, - * and trim enough allow the addition of the suffix. - */ - dns_name_init(&prefix, prefix_offsets); - labels = dns_name_countlabels(trig_name); - first = 0; - for (;;) { - dns_name_getlabelsequence(trig_name, first, labels-first-1, - &prefix); - result = dns_name_concatenate(&prefix, suffix, p_name, NULL); - if (result == ISC_R_SUCCESS) - break; - INSIST(result == DNS_R_NAMETOOLONG); - /* - * Trim the trigger name until the combination is not too long. - */ - if (labels-first < 2) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix, - rpz_type, " concatenate()", result); - return (ISC_R_FAILURE); - } - /* - * Complain once about trimming the trigger name. - */ - if (first == 0) { - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix, - rpz_type, " concatenate()", result); - } - ++first; - } - return (ISC_R_SUCCESS); -} - -/* - * Look in policy zone rpz for a policy of rpz_type by p_name. - * The self-name (usually the client qname or an NS name) is compared with - * the target of a CNAME policy for the old style passthru encoding. - * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep, - * *rdatasetp, and *policyp. - * The target DNS type, qtype, chooses the best rdataset for *rdatasetp. - * The caller must decide if the found policy is most suitable, including - * better than a previously found policy. - * If it is best, the caller records it in client->query.rpz_st->m. - */ -static isc_result_t -rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype, - dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, - dns_rpz_policy_t *policyp) -{ - dns_fixedname_t foundf; - dns_name_t *found; - isc_result_t result; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - bool found_a = false; - - REQUIRE(nodep != NULL); - - CTRACE(ISC_LOG_DEBUG(3), "rpz_find_p"); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Try to find either a CNAME or the type of record demanded by the - * request from the policy zone. - */ - rpz_clean(zonep, dbp, nodep, rdatasetp); - result = rpz_ready(client, rdatasetp); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, "rpz_ready() failed"); - return (DNS_R_SERVFAIL); - } - *versionp = NULL; - result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp); - if (result != ISC_R_SUCCESS) - return (DNS_R_NXDOMAIN); - found = dns_fixedname_initname(&foundf); - - result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0, - client->now, nodep, found, &cm, &ci, - *rdatasetp, NULL); - /* - * Choose the best rdataset if we found something. - */ - if (result == ISC_R_SUCCESS) { - dns_rdatasetiter_t *rdsiter; - - rdsiter = NULL; - result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0, - &rdsiter); - if (result != ISC_R_SUCCESS) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, - rpz_type, " allrdatasets()", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: allrdatasets failed"); - return (DNS_R_SERVFAIL); - } - if (qtype == dns_rdatatype_aaaa && - !ISC_LIST_EMPTY(client->view->dns64)) { - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, *rdatasetp); - if ((*rdatasetp)->type == dns_rdatatype_a) { - found_a = true; - } - dns_rdataset_disassociate(*rdatasetp); - } - } - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, *rdatasetp); - if ((*rdatasetp)->type == dns_rdatatype_cname || - (*rdatasetp)->type == qtype) - break; - dns_rdataset_disassociate(*rdatasetp); - } - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_SUCCESS) { - if (result != ISC_R_NOMORE) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, - p_name, rpz_type, - " rdatasetiter", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: rdatasetiter failed"); - return (DNS_R_SERVFAIL); - } - /* - * Ask again to get the right DNS_R_DNAME/NXRRSET/... - * result if there is neither a CNAME nor target type. - */ - if (dns_rdataset_isassociated(*rdatasetp)) - dns_rdataset_disassociate(*rdatasetp); - dns_db_detachnode(*dbp, nodep); - - if (qtype == dns_rdatatype_rrsig || - qtype == dns_rdatatype_sig) - result = DNS_R_NXRRSET; - else - result = dns_db_findext(*dbp, p_name, *versionp, - qtype, 0, client->now, - nodep, found, &cm, &ci, - *rdatasetp, NULL); - } - } - switch (result) { - case ISC_R_SUCCESS: - if ((*rdatasetp)->type != dns_rdatatype_cname) { - *policyp = DNS_RPZ_POLICY_RECORD; - } else { - *policyp = dns_rpz_decode_cname(rpz, *rdatasetp, - self_name); - if ((*policyp == DNS_RPZ_POLICY_RECORD || - *policyp == DNS_RPZ_POLICY_WILDCNAME) && - qtype != dns_rdatatype_cname && - qtype != dns_rdatatype_any) - return (DNS_R_CNAME); - } - return (ISC_R_SUCCESS); - case DNS_R_NXRRSET: - if (found_a) { - *policyp = DNS_RPZ_POLICY_DNS64; - } else { - *policyp = DNS_RPZ_POLICY_NODATA; - } - return (result); - case DNS_R_DNAME: - /* - * DNAME policy RRs have very few if any uses that are not - * better served with simple wildcards. Making them work would - * require complications to get the number of labels matched - * in the name or the found name to the main DNS_R_DNAME case - * in query_find(). The domain also does not appear in the - * summary database at the right level, so this happens only - * with a single policy zone when we have no summary database. - * Treat it as a miss. - */ - case DNS_R_NXDOMAIN: - case DNS_R_EMPTYNAME: - return (DNS_R_NXDOMAIN); - default: - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, - "", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: unexpected result"); - return (DNS_R_SERVFAIL); - } -} - -static void -rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix, - isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, - dns_dbversion_t *version) -{ - dns_rdataset_t *trdataset = NULL; - - rpz_match_clear(st); - st->m.rpz = rpz; - st->m.type = rpz_type; - st->m.policy = policy; - dns_name_copy(p_name, st->p_name, NULL); - st->m.prefix = prefix; - st->m.result = result; - SAVE(st->m.zone, *zonep); - SAVE(st->m.db, *dbp); - SAVE(st->m.node, *nodep); - if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) { - /* - * Save the replacement rdataset from the policy - * and make the previous replacement rdataset scratch. - */ - SAVE(trdataset, st->m.rdataset); - SAVE(st->m.rdataset, *rdatasetp); - SAVE(*rdatasetp, trdataset); - st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl); - } else { - st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl); - } - SAVE(st->m.version, version); -} - -/* - * Check this address in every eligible policy zone. - */ -static isc_result_t -rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_st_t *st; - dns_rpz_zone_t *rpz; - dns_rpz_prefix_t prefix; - dns_rpz_num_t rpz_num; - dns_fixedname_t ip_namef, p_namef; - dns_name_t *ip_name, *p_name; - dns_zone_t *p_zone; - dns_db_t *p_db; - dns_dbversion_t *p_version; - dns_dbnode_t *p_node; - dns_rpz_policy_t policy; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip"); - - ip_name = dns_fixedname_initname(&ip_namef); - - p_zone = NULL; - p_db = NULL; - p_node = NULL; - - rpzs = client->view->rpzs; - st = client->query.rpz_st; - while (zbits != 0) { - rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr, - ip_name, &prefix); - if (rpz_num == DNS_RPZ_INVALID_NUM) - break; - zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1); - - /* - * Do not try applying policy zones that cannot replace a - * previously found policy zone. - * Stop looking if the next best choice cannot - * replace what we already have. - */ - rpz = rpzs->zones[rpz_num]; - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.rpz->num < rpz->num) - break; - if (st->m.rpz->num == rpz->num && - (st->m.type < rpz_type || - st->m.prefix > prefix)) - break; - } - - /* - * Get the policy for a prefix at least as long - * as the prefix of the entry we had before. - */ - p_name = dns_fixedname_initname(&p_namef); - result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name); - if (result != ISC_R_SUCCESS) - continue; - result = rpz_find_p(client, ip_name, qtype, - p_name, rpz, rpz_type, - &p_zone, &p_db, &p_version, &p_node, - p_rdatasetp, &policy); - switch (result) { - case DNS_R_NXDOMAIN: - /* - * Continue after a policy record that is missing - * contrary to the summary data. The summary - * data can out of date during races with and among - * policy zone updates. - */ - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_ip: mismatched summary data; " - "continuing"); - continue; - case DNS_R_SERVFAIL: - rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (DNS_R_SERVFAIL); - default: - /* - * Forget this policy if it is not preferable - * to the previously found policy. - * If this policy is not good, then stop looking - * because none of the later policy zones would work. - * - * With more than one applicable policy, prefer - * the earliest configured policy, - * client-IP over QNAME over IP over NSDNAME over NSIP, - * the longest prefix - * the lexically smallest address. - * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num. - * We can compare new and current p_name because - * both are of the same type and in the same zone. - * The tests above eliminate other reasons to - * reject this policy. If this policy can't work, - * then neither can later zones. - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS && - rpz->num == st->m.rpz->num && - (st->m.type == rpz_type && - st->m.prefix == prefix && - 0 > dns_name_rdatacompare(st->p_name, p_name))) - break; - - /* - * Stop checking after saving an enabled hit in this - * policy zone. The radix tree in the policy zone - * ensures that we found the longest match. - */ - if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { - CTRACE(ISC_LOG_DEBUG(3), - "rpz_rewrite_ip: rpz_save_p"); - rpz_save_p(st, rpz, rpz_type, - policy, p_name, prefix, result, - &p_zone, &p_db, &p_node, - p_rdatasetp, p_version); - break; - } - - /* - * Log DNS_RPZ_POLICY_DISABLED zones - * and try the next eligible policy zone. - */ - rpz_log_rewrite(client, true, policy, rpz_type, - p_zone, p_name, NULL, rpz_num); - } - } - - rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); - return (ISC_R_SUCCESS); -} - -/* - * Check the IP addresses in the A or AAAA rrsets for name against - * all eligible rpz_type (IP or NSIP) response policy rewrite rules. - */ -static isc_result_t -rpz_rewrite_ip_rrset(ns_client_t *client, - dns_name_t *name, dns_rdatatype_t qtype, - dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type, - dns_db_t **ip_dbp, dns_dbversion_t *ip_version, - dns_rdataset_t **ip_rdatasetp, - dns_rdataset_t **p_rdatasetp, bool resuming) -{ - dns_rpz_zbits_t zbits; - isc_netaddr_t netaddr; - struct in_addr ina; - struct in6_addr in6a; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrset"); - - zbits = rpz_get_zbits(client, ip_type, rpz_type); - if (zbits == 0) - return (ISC_R_SUCCESS); - - /* - * Get the A or AAAA rdataset. - */ - result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp, - ip_version, ip_rdatasetp, resuming); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_GLUE: - case DNS_R_ZONECUT: - break; - case DNS_R_EMPTYNAME: - case DNS_R_EMPTYWILD: - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - case ISC_R_NOTFOUND: - return (ISC_R_SUCCESS); - case DNS_R_DELEGATION: - case DNS_R_DUPLICATE: - case DNS_R_DROP: - return (result); - case DNS_R_CNAME: - case DNS_R_DNAME: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type, - " NS address rewrite rrset", result); - return (ISC_R_SUCCESS); - default: - if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { - client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR; - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " NS address rewrite rrset", - result); - } - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_ip_rrset: unexpected result"); - return (DNS_R_SERVFAIL); - } - - /* - * Check all of the IP addresses in the rdataset. - */ - for (result = dns_rdataset_first(*ip_rdatasetp); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(*ip_rdatasetp)) { - - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(*ip_rdatasetp, &rdata); - switch (rdata.type) { - case dns_rdatatype_a: - INSIST(rdata.length == 4); - memmove(&ina.s_addr, rdata.data, 4); - isc_netaddr_fromin(&netaddr, &ina); - break; - case dns_rdatatype_aaaa: - INSIST(rdata.length == 16); - memmove(in6a.s6_addr, rdata.data, 16); - isc_netaddr_fromin6(&netaddr, &in6a); - break; - default: - continue; - } - - result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type, - zbits, p_rdatasetp); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (ISC_R_SUCCESS); -} - -/* - * Look for IP addresses in A and AAAA rdatasets - * that trigger all eligible IP or NSIP policy rules. - */ -static isc_result_t -rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rdataset_t **ip_rdatasetp, bool resuming) -{ - dns_rpz_st_t *st; - dns_dbversion_t *ip_version; - dns_db_t *ip_db; - dns_rdataset_t *p_rdataset; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrsets"); - - st = client->query.rpz_st; - ip_version = NULL; - ip_db = NULL; - p_rdataset = NULL; - if ((st->state & DNS_RPZ_DONE_IPv4) == 0 && - (qtype == dns_rdatatype_a || - qtype == dns_rdatatype_any || - rpz_type == DNS_RPZ_TYPE_NSIP)) { - /* - * Rewrite based on an IPv4 address that will appear - * in the ANSWER section or if we are checking IP addresses. - */ - result = rpz_rewrite_ip_rrset(client, name, qtype, - rpz_type, dns_rdatatype_a, - &ip_db, ip_version, ip_rdatasetp, - &p_rdataset, resuming); - if (result == ISC_R_SUCCESS) - st->state |= DNS_RPZ_DONE_IPv4; - } else { - result = ISC_R_SUCCESS; - } - if (result == ISC_R_SUCCESS && - (qtype == dns_rdatatype_aaaa || - qtype == dns_rdatatype_any || - rpz_type == DNS_RPZ_TYPE_NSIP)) { - /* - * Rewrite based on IPv6 addresses that will appear - * in the ANSWER section or if we are checking IP addresses. - */ - result = rpz_rewrite_ip_rrset(client, name, qtype, - rpz_type, dns_rdatatype_aaaa, - &ip_db, ip_version, ip_rdatasetp, - &p_rdataset, resuming); - } - if (ip_db != NULL) - dns_db_detach(&ip_db); - query_putrdataset(client, &p_rdataset); - return (result); -} - -/* - * Try to rewrite a request for a qtype rdataset based on the trigger name - * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME). - * Record the results including the replacement rdataset if any - * in client->query.rpz_st. - * *rdatasetp is a scratch rdataset. - */ -static isc_result_t -rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t allowed_zbits, dns_rdataset_t **rdatasetp) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_zone_t *rpz; - dns_rpz_st_t *st; - dns_fixedname_t p_namef; - dns_name_t *p_name; - dns_rpz_zbits_t zbits; - dns_rpz_num_t rpz_num; - dns_zone_t *p_zone; - dns_db_t *p_db; - dns_dbversion_t *p_version; - dns_dbnode_t *p_node; - dns_rpz_policy_t policy; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name"); - - zbits = rpz_get_zbits(client, qtype, rpz_type); - zbits &= allowed_zbits; - if (zbits == 0) - return (ISC_R_SUCCESS); - - rpzs = client->view->rpzs; - - /* - * Use the summary database to find the bit mask of policy zones - * with policies for this trigger name. We do this even if there - * is only one eligible policy zone so that wildcard triggers - * are matched correctly, and not into their parent. - */ - zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name); - if (zbits == 0) - return (ISC_R_SUCCESS); - - p_name = dns_fixedname_initname(&p_namef); - - p_zone = NULL; - p_db = NULL; - p_node = NULL; - - st = client->query.rpz_st; - - /* - * Check the trigger name in every policy zone that the summary data - * says has a hit for the trigger name. - * Most of the time there are no eligible zones and the summary data - * keeps us from getting this far. - * We check the most eligible zone first and so usually check only - * one policy zone. - */ - for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) { - if ((zbits & 1) == 0) - continue; - - /* - * Do not check policy zones that cannot replace a previously - * found policy. - */ - rpz = rpzs->zones[rpz_num]; - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.rpz->num < rpz->num) - break; - if (st->m.rpz->num == rpz->num && - st->m.type < rpz_type) - break; - } - - /* - * Get the next policy zone's record for this trigger name. - */ - result = rpz_get_p_name(client, p_name, rpz, rpz_type, - trig_name); - if (result != ISC_R_SUCCESS) - continue; - result = rpz_find_p(client, trig_name, qtype, p_name, - rpz, rpz_type, - &p_zone, &p_db, &p_version, &p_node, - rdatasetp, &policy); - switch (result) { - case DNS_R_NXDOMAIN: - /* - * Continue after a missing policy record - * contrary to the summary data. The summary - * data can out of date during races with and among - * policy zone updates. - */ - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_name: mismatched summary data; " - "continuing"); - continue; - case DNS_R_SERVFAIL: - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (DNS_R_SERVFAIL); - default: - /* - * With more than one applicable policy, prefer - * the earliest configured policy, - * client-IP over QNAME over IP over NSDNAME over NSIP, - * and the smallest name. - * We known st->m.rpz->num >= rpz->num and either - * st->m.rpz->num > rpz->num or st->m.type >= rpz_type - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS && - rpz->num == st->m.rpz->num && - (st->m.type < rpz_type || - (st->m.type == rpz_type && - 0 >= dns_name_compare(p_name, st->p_name)))) - continue; -#if 0 - /* - * This code would block a customer reported information - * leak of rpz rules by rewriting requests in the - * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs. - * Without this code, a bad guy could request - * 24.0.3.2.10.rpz-ip. to find the policy rule for - * 10.2.3.0/14. It is an insignificant leak and this - * code is not worth its cost, because the bad guy - * could publish "evil.com A 10.2.3.4" and request - * evil.com to get the same information. - * Keep code with "#if 0" in case customer demand - * is irresistible. - * - * We have the less frequent case of a triggered - * policy. Check that we have not trigger on one - * of the pretend RPZ TLDs. - * This test would make it impossible to rewrite - * names in TLDs that start with "rpz-" should - * ICANN ever allow such TLDs. - */ - unsigned int labels; - labels = dns_name_countlabels(trig_name); - if (labels >= 2) { - dns_label_t label; - - dns_name_getlabel(trig_name, labels-2, &label); - if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 && - strncasecmp((const char *)label.base+1, - DNS_RPZ_PREFIX, - sizeof(DNS_RPZ_PREFIX)-1) == 0) - continue; - } -#endif - if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { - CTRACE(ISC_LOG_DEBUG(3), - "rpz_rewrite_name: rpz_save_p"); - rpz_save_p(st, rpz, rpz_type, - policy, p_name, 0, result, - &p_zone, &p_db, &p_node, - rdatasetp, p_version); - /* - * After a hit, higher numbered policy zones - * are irrelevant - */ - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - return (ISC_R_SUCCESS); - } - /* - * Log DNS_RPZ_POLICY_DISABLED zones - * and try the next eligible policy zone. - */ - rpz_log_rewrite(client, true, policy, rpz_type, - p_zone, p_name, NULL, rpz_num); - break; - } - } - - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - return (ISC_R_SUCCESS); -} - -static void -rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname, - isc_result_t result, int level, const char *str) -{ - dns_rpz_st_t *st; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ns_skip"); - - st = client->query.rpz_st; - - if (str != NULL) - rpz_log_fail_helper(client, level, nsname, - DNS_RPZ_TYPE_NSIP, DNS_RPZ_TYPE_NSDNAME, - str, result); - if (st->r.ns_rdataset != NULL && - dns_rdataset_isassociated(st->r.ns_rdataset)) - dns_rdataset_disassociate(st->r.ns_rdataset); - - st->r.label--; -} - -/* - * RPZ query result types - */ -typedef enum { - RPZ_QRESULT_TYPE_DONE, - RPZ_QRESULT_TYPE_RESTART, - RPZ_QRESULT_TYPE_RECURSE, -} rpz_qresult_type_t; - -/* - * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting. - */ -static isc_result_t -rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, - isc_result_t qresult, bool resuming, - dns_rdataset_t *ordataset, dns_rdataset_t *osigset) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_st_t *st; - dns_rdataset_t *rdataset; - dns_fixedname_t nsnamef; - dns_name_t *nsname; - rpz_qresult_type_t qresult_type; - dns_rpz_zbits_t zbits; - isc_result_t result = ISC_R_SUCCESS; - dns_rpz_have_t have; - dns_rpz_popt_t popt; - int rpz_ver; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite"); - - rpzs = client->view->rpzs; - st = client->query.rpz_st; - - if (rpzs == NULL || - (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0)) - return (DNS_R_DISALLOWED); - - RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); - if (rpzs->p.num_zones == 0 || - (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) || - !rpz_ck_dnssec(client, qresult, ordataset, osigset)) - { - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - return (DNS_R_DISALLOWED); - } - have = rpzs->have; - popt = rpzs->p; - rpz_ver = rpzs->rpz_ver; - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - - if (st == NULL) { - st = isc_mem_get(client->mctx, sizeof(*st)); - if (st == NULL) - return (ISC_R_NOMEMORY); - st->state = 0; - } - if (st->state == 0) { - st->state |= DNS_RPZ_ACTIVE; - memset(&st->m, 0, sizeof(st->m)); - st->m.type = DNS_RPZ_TYPE_BAD; - st->m.policy = DNS_RPZ_POLICY_MISS; - st->m.ttl = ~0; - memset(&st->r, 0, sizeof(st->r)); - memset(&st->q, 0, sizeof(st->q)); - st->p_name = dns_fixedname_initname(&st->_p_namef); - st->r_name = dns_fixedname_initname(&st->_r_namef); - st->fname = dns_fixedname_initname(&st->_fnamef); - st->have = have; - st->popt = popt; - st->rpz_ver = rpz_ver; - client->query.rpz_st = st; - } - - /* - * There is nothing to rewrite if the main query failed. - */ - switch (qresult) { - case ISC_R_SUCCESS: - case DNS_R_GLUE: - case DNS_R_ZONECUT: - qresult_type = RPZ_QRESULT_TYPE_DONE; - break; - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - case DNS_R_NXDOMAIN: - case DNS_R_EMPTYWILD: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - case DNS_R_CNAME: - case DNS_R_DNAME: - qresult_type = RPZ_QRESULT_TYPE_RESTART; - break; - case DNS_R_DELEGATION: - case ISC_R_NOTFOUND: - /* - * If recursion is on, do only tentative rewriting. - * If recursion is off, this the normal and only time we - * can rewrite. - */ - if (RECURSIONOK(client)) - qresult_type = RPZ_QRESULT_TYPE_RECURSE; - else - qresult_type = RPZ_QRESULT_TYPE_RESTART; - break; - case ISC_R_FAILURE: - case ISC_R_TIMEDOUT: - case DNS_R_BROKENCHAIN: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, client->query.qname, - DNS_RPZ_TYPE_QNAME, - " stop on qresult in rpz_rewrite()", qresult); - return (ISC_R_SUCCESS); - default: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, client->query.qname, - DNS_RPZ_TYPE_QNAME, - " stop on unrecognized qresult in rpz_rewrite()", - qresult); - return (ISC_R_SUCCESS); - } - - rdataset = NULL; - - if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) != - (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) { - isc_netaddr_t netaddr; - dns_rpz_zbits_t allowed; - - if (qresult_type == RPZ_QRESULT_TYPE_RECURSE) { - /* - * This request needs recursion that has not been done. - * Get bits for the policy zones that do not need - * to wait for the results of recursion. - */ - allowed = st->have.qname_skip_recurse; - if (allowed == 0) - return (ISC_R_SUCCESS); - } else { - allowed = DNS_RPZ_ALL_ZBITS; - } - - /* - * Check once for triggers for the client IP address. - */ - if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) { - zbits = rpz_get_zbits(client, dns_rdatatype_none, - DNS_RPZ_TYPE_CLIENT_IP); - zbits &= allowed; - if (zbits != 0) { - isc_netaddr_fromsockaddr(&netaddr, - &client->peeraddr); - result = rpz_rewrite_ip(client, &netaddr, qtype, - DNS_RPZ_TYPE_CLIENT_IP, - zbits, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - - /* - * Check triggers for the query name if this is the first time - * for the current qname. - * There is a first time for each name in a CNAME chain - */ - if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { - result = rpz_rewrite_name(client, client->query.qname, - qtype, DNS_RPZ_TYPE_QNAME, - allowed, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Check IPv4 addresses in A RRs next. - * Reset to the start of the NS names. - */ - st->r.label = dns_name_countlabels(client->query.qname); - st->state &= ~(DNS_RPZ_DONE_QNAME_IP | - DNS_RPZ_DONE_IPv4); - - } - - /* - * Quit if this was an attempt to find a qname or - * client-IP trigger before recursion. - * We will be back if no pre-recursion triggers hit. - * For example, consider 2 policy zones, both with qname and - * IP address triggers. If the qname misses the 1st zone, - * then we cannot know whether a hit for the qname in the - * 2nd zone matters until after recursing to get the A RRs and - * testing them in the first zone. - * Do not bother saving the work from this attempt, - * because recursion is so slow. - */ - if (qresult_type == RPZ_QRESULT_TYPE_RECURSE) - goto cleanup; - - /* - * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP - * is reset at the end of dealing with each CNAME. - */ - st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME); - } - - /* - * Check known IP addresses for the query name if the database - * lookup resulted in some addresses (qresult_type == - * RPZ_QRESULT_TYPE_DONE) and if we have not already checked them. - * Any recursion required for the query has already happened. - * Do not check addresses that will not be in the ANSWER section. - */ - if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && - qresult_type == RPZ_QRESULT_TYPE_DONE && - rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) { - result = rpz_rewrite_ip_rrsets(client, - client->query.qname, qtype, - DNS_RPZ_TYPE_IP, - &rdataset, resuming); - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * We are finished checking the IP addresses for the qname. - * Start with IPv4 if we will check NS IP addresses. - */ - st->state |= DNS_RPZ_DONE_QNAME_IP; - st->state &= ~DNS_RPZ_DONE_IPv4; - } - - /* - * Stop looking for rules if there are none of the other kinds - * that could override what we already have. - */ - if (rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSDNAME) == 0 && - rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSIP) == 0) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - dns_fixedname_init(&nsnamef); - dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); - while (st->r.label > st->popt.min_ns_labels) { - /* - * Get NS rrset for each domain in the current qname. - */ - if (st->r.label == dns_name_countlabels(client->query.qname)) { - nsname = client->query.qname; - } else { - nsname = dns_fixedname_name(&nsnamef); - dns_name_split(client->query.qname, st->r.label, - NULL, nsname); - } - if (st->r.ns_rdataset == NULL || - !dns_rdataset_isassociated(st->r.ns_rdataset)) - { - dns_db_t *db = NULL; - result = rpz_rrset_find(client, nsname, - dns_rdatatype_ns, - DNS_RPZ_TYPE_NSDNAME, - &db, NULL, &st->r.ns_rdataset, - resuming); - if (db != NULL) - dns_db_detach(&db); - if (st->m.policy == DNS_RPZ_POLICY_ERROR) - goto cleanup; - switch (result) { - case ISC_R_SUCCESS: - result = dns_rdataset_first(st->r.ns_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - st->state &= ~(DNS_RPZ_DONE_NSDNAME | - DNS_RPZ_DONE_IPv4); - break; - case DNS_R_DELEGATION: - case DNS_R_DUPLICATE: - case DNS_R_DROP: - goto cleanup; - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - case DNS_R_EMPTYWILD: - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - case ISC_R_NOTFOUND: - case DNS_R_CNAME: - case DNS_R_DNAME: - rpz_rewrite_ns_skip(client, nsname, result, - 0, NULL); - continue; - case ISC_R_TIMEDOUT: - case DNS_R_BROKENCHAIN: - case ISC_R_FAILURE: - rpz_rewrite_ns_skip(client, nsname, result, - DNS_RPZ_DEBUG_LEVEL3, - " NS rpz_rrset_find()"); - continue; - default: - rpz_rewrite_ns_skip(client, nsname, result, - DNS_RPZ_INFO_LEVEL, - " unrecognized NS" - " rpz_rrset_find()"); - continue; - } - } - /* - * Check all NS names. - */ - do { - dns_rdata_ns_t ns; - dns_rdata_t nsrdata = DNS_RDATA_INIT; - - dns_rdataset_current(st->r.ns_rdataset, &nsrdata); - result = dns_rdata_tostruct(&nsrdata, &ns, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&nsrdata); - /* - * Do nothing about "NS ." - */ - if (dns_name_equal(&ns.name, dns_rootname)) { - dns_rdata_freestruct(&ns); - result = dns_rdataset_next(st->r.ns_rdataset); - continue; - } - /* - * Check this NS name if we did not handle it - * during a previous recursion. - */ - if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) { - result = rpz_rewrite_name(client, &ns.name, - qtype, - DNS_RPZ_TYPE_NSDNAME, - DNS_RPZ_ALL_ZBITS, - &rdataset); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ns); - goto cleanup; - } - st->state |= DNS_RPZ_DONE_NSDNAME; - } - /* - * Check all IP addresses for this NS name. - */ - result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype, - DNS_RPZ_TYPE_NSIP, - &rdataset, resuming); - dns_rdata_freestruct(&ns); - if (result != ISC_R_SUCCESS) - goto cleanup; - st->state &= ~(DNS_RPZ_DONE_NSDNAME | - DNS_RPZ_DONE_IPv4); - result = dns_rdataset_next(st->r.ns_rdataset); - } while (result == ISC_R_SUCCESS); - dns_rdataset_disassociate(st->r.ns_rdataset); - st->r.label--; - - if (rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSDNAME) == 0 && - rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSIP) == 0) - break; - } - - /* - * Use the best hit, if any. - */ - result = ISC_R_SUCCESS; - -cleanup: - if (st->m.policy != DNS_RPZ_POLICY_MISS && - st->m.policy != DNS_RPZ_POLICY_ERROR && - st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN) - st->m.policy = st->m.rpz->policy; - if (st->m.policy == DNS_RPZ_POLICY_MISS || - st->m.policy == DNS_RPZ_POLICY_PASSTHRU || - st->m.policy == DNS_RPZ_POLICY_ERROR) { - if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU && - result != DNS_R_DELEGATION) - rpz_log_rewrite(client, false, st->m.policy, - st->m.type, st->m.zone, st->p_name, - NULL, st->m.rpz->num); - rpz_match_clear(st); - } - if (st->m.policy == DNS_RPZ_POLICY_ERROR) { - CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy"); - st->m.type = DNS_RPZ_TYPE_BAD; - result = DNS_R_SERVFAIL; - } - query_putrdataset(client, &rdataset); - if ((st->state & DNS_RPZ_RECURSING) == 0) - rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset); - - return (result); -} - -/* - * See if response policy zone rewriting is allowed by a lack of interest - * by the client in DNSSEC or a lack of signatures. - */ -static bool -rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_fixedname_t fixed; - dns_name_t *found; - dns_rdataset_t trdataset; - dns_rdatatype_t type; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_ck_dnssec"); - - if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) - return (true); - - /* - * We do not know if there are signatures if we have not recursed - * for them. - */ - if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND) - return (false); - - if (sigrdataset == NULL) - return (true); - if (dns_rdataset_isassociated(sigrdataset)) - return (false); - - /* - * We are happy to rewrite nothing. - */ - if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) - return (true); - /* - * Do not rewrite if there is any sign of signatures. - */ - if (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3 || - rdataset->type == dns_rdatatype_rrsig) - return (false); - - /* - * Look for a signature in a negative cache rdataset. - */ - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0) - return (true); - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (false); - } - return (true); -} - -/* - * Add a CNAME to the query response, including translating foo.evil.com and - * *.evil.com CNAME *.example.com - * to - * foo.evil.com CNAME foo.evil.com.example.com - */ -static isc_result_t -rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st, - dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf) -{ - dns_fixedname_t prefix, suffix; - unsigned int labels; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_add_cname"); - - labels = dns_name_countlabels(cname); - if (labels > 2 && dns_name_iswildcard(cname)) { - dns_fixedname_init(&prefix); - dns_name_split(client->query.qname, 1, - dns_fixedname_name(&prefix), NULL); - dns_fixedname_init(&suffix); - dns_name_split(cname, labels-1, - NULL, dns_fixedname_name(&suffix)); - result = dns_name_concatenate(dns_fixedname_name(&prefix), - dns_fixedname_name(&suffix), - fname, NULL); - if (result == DNS_R_NAMETOOLONG) - client->message->rcode = dns_rcode_yxdomain; - } else { - result = dns_name_copy(cname, fname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) - return (result); - query_keepname(client, fname, dbuf); - result = query_add_cname(client, client->query.qname, - fname, dns_trust_authanswer, st->m.ttl); - if (result != ISC_R_SUCCESS) - return (result); - rpz_log_rewrite(client, false, st->m.policy, - st->m.type, st->m.zone, st->p_name, fname, - st->m.rpz->num); - ns_client_qnamereplace(client, fname); - /* - * Turn off DNSSEC because the results of a - * response policy zone cannot verify. - */ - client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | - NS_CLIENTATTR_WANTAD); - return (ISC_R_SUCCESS); -} - -#define MAX_RESTARTS 16 - -#define QUERY_ERROR(r) \ -do { \ - eresult = r; \ - want_restart = false; \ - line = __LINE__; \ -} while (0) - -#define RECURSE_ERROR(r) \ -do { \ - if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \ - QUERY_ERROR(r); \ - else \ - QUERY_ERROR(DNS_R_SERVFAIL); \ -} while (0) - -/* - * Extract a network address from the RDATA of an A or AAAA - * record. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. - */ -static isc_result_t -rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { - struct in_addr ina; - struct in6_addr in6a; - - switch (rdata->type) { - case dns_rdatatype_a: - INSIST(rdata->length == 4); - memmove(&ina.s_addr, rdata->data, 4); - isc_netaddr_fromin(netaddr, &ina); - return (ISC_R_SUCCESS); - case dns_rdatatype_aaaa: - INSIST(rdata->length == 16); - memmove(in6a.s6_addr, rdata->data, 16); - isc_netaddr_fromin6(netaddr, &in6a); - return (ISC_R_SUCCESS); - default: - return (ISC_R_NOTIMPLEMENTED); - } -} - -/* - * Find the sort order of 'rdata' in the topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ -static int -query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder2(&netaddr, arg)); -} - -/* - * Find the sort order of 'rdata' in the matching element - * of a 1-element top-level sortlist statement. - */ -static int -query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder1(&netaddr, arg)); -} - -/* - * Find the sortlist statement that applies to 'client' and set up - * the sortlist info in in client->message appropriately. - */ -static void -setup_query_sortlist(ns_client_t *client) { - isc_netaddr_t netaddr; - dns_rdatasetorderfunc_t order = NULL; - const void *order_arg = NULL; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (ns_sortlist_setup(client->view->sortlist, - &netaddr, &order_arg)) { - case NS_SORTLISTTYPE_1ELEMENT: - order = query_sortlist_order_1element; - break; - case NS_SORTLISTTYPE_2ELEMENT: - order = query_sortlist_order_2element; - break; - case NS_SORTLISTTYPE_NONE: - order = NULL; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - break; - } - dns_message_setsortorder(client->message, order, order_arg); -} - -static void -query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) { - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *neg, *negsig; - isc_result_t result = ISC_R_NOMEMORY; - - CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof"); - - fname = NULL; - neg = NULL; - negsig = NULL; - - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - neg = query_newrdataset(client); - negsig = query_newrdataset(client); - if (fname == NULL || neg == NULL || negsig == NULL) - goto cleanup; - - result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - query_addrrset(client, &fname, &neg, &negsig, dbuf, - DNS_SECTION_AUTHORITY); - - if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) == 0) - goto cleanup; - - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - if (neg == NULL) - neg = query_newrdataset(client); - else if (dns_rdataset_isassociated(neg)) - dns_rdataset_disassociate(neg); - if (negsig == NULL) - negsig = query_newrdataset(client); - else if (dns_rdataset_isassociated(negsig)) - dns_rdataset_disassociate(negsig); - if (fname == NULL || neg == NULL || negsig == NULL) - goto cleanup; - result = dns_rdataset_getclosest(rdataset, fname, neg, negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - query_addrrset(client, &fname, &neg, &negsig, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (neg != NULL) - query_putrdataset(client, &neg); - if (negsig != NULL) - query_putrdataset(client, &negsig); - if (fname != NULL) - query_releasename(client, &fname); -} - -static inline void -answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { - dns_name_t *name; - dns_message_t *msg; - dns_section_t section = DNS_SECTION_ADDITIONAL; - dns_rdataset_t *rdataset = NULL; - - msg = client->message; - for (name = ISC_LIST_HEAD(msg->sections[section]); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - if (dns_name_equal(name, client->query.qname)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - if (rdataset->type == qtype) - break; - break; - } - if (rdataset != NULL) { - ISC_LIST_UNLINK(msg->sections[section], name, link); - ISC_LIST_PREPEND(msg->sections[section], name, link); - ISC_LIST_UNLINK(name->list, rdataset, link); - ISC_LIST_PREPEND(name->list, rdataset, link); - rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - } -} - -static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; -static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; -static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; - -static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; - -static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; - -static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; - -static dns_name_t rfc1918names[] = { - DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets), - DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets) -}; - - -static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; -static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org"; - -static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; -static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; - -static dns_name_t prisoner = - DNS_NAME_INITABSOLUTE(prisoner_data, prisoner_offsets); -static dns_name_t hostmaster = - DNS_NAME_INITABSOLUTE(hostmaster_data, hostmaster_offsets); - -static void -warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { - unsigned int i; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - dns_rdataset_t found; - isc_result_t result; - - for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) { - if (dns_name_issubdomain(fname, &rfc1918names[i])) { - dns_rdataset_init(&found); - result = dns_ncache_getrdataset(rdataset, - &rfc1918names[i], - dns_rdatatype_soa, - &found); - if (result != ISC_R_SUCCESS) - return; - - result = dns_rdataset_first(&found); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(&found, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dns_name_equal(&soa.origin, &prisoner) && - dns_name_equal(&soa.contact, &hostmaster)) { - char buf[DNS_NAME_FORMATSIZE]; - dns_name_format(fname, buf, sizeof(buf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "RFC 1918 response from " - "Internet for %s", buf); - } - dns_rdataset_disassociate(&found); - return; - } - } -} - -static void -query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, - dns_dbversion_t *version, ns_client_t *client, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_name_t *fname, bool exact, - dns_name_t *found) -{ - unsigned char salt[256]; - size_t salt_length; - uint16_t iterations; - isc_result_t result; - unsigned int dboptions; - dns_fixedname_t fixed; - dns_hash_t hash; - dns_name_t name; - unsigned int skip = 0, labels; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - bool optout; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - salt_length = sizeof(salt); - result = dns_db_getnsec3parameters(db, version, &hash, NULL, - &iterations, salt, &salt_length); - if (result != ISC_R_SUCCESS) - return; - - dns_name_init(&name, NULL); - dns_name_clone(qname, &name); - labels = dns_name_countlabels(&name); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Map unknown algorithm to known value. - */ - if (hash == DNS_NSEC3_UNKNOWNALG) - hash = 1; - - again: - dns_fixedname_init(&fixed); - result = dns_nsec3_hashname(&fixed, NULL, NULL, &name, - dns_db_origin(db), hash, - iterations, salt, salt_length); - if (result != ISC_R_SUCCESS) - return; - - dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; - result = dns_db_findext(db, dns_fixedname_name(&fixed), version, - dns_rdatatype_nsec3, dboptions, client->now, - NULL, fname, &cm, &ci, rdataset, sigrdataset); - - if (result == DNS_R_NXDOMAIN) { - if (!dns_rdataset_isassociated(rdataset)) { - return; - } - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - optout = (nsec3.flags & DNS_NSEC3FLAG_OPTOUT); - if (found != NULL && optout && - dns_name_issubdomain(&name, dns_db_origin(db))) - { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - skip++; - dns_name_getlabelsequence(qname, skip, labels - skip, - &name); - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3), - "looking for closest provable encloser"); - goto again; - } - if (exact) - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_WARNING, - "expected a exact match NSEC3, got " - "a covering record"); - - } else if (result != ISC_R_SUCCESS) { - return; - } else if (!exact) - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_WARNING, - "expected covering NSEC3, got an exact match"); - if (found == qname) { - if (skip != 0U) - dns_name_getlabelsequence(qname, skip, labels - skip, - found); - } else if (found != NULL) - dns_name_copy(&name, found, NULL); - return; -} - -#ifdef ALLOW_FILTER_AAAA -static bool -is_v4_client(ns_client_t *client) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) - return (true); - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) - return (true); - return (false); -} - -static bool -is_v6_client(ns_client_t *client) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && - !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) - return (true); - return (false); -} -#endif - -static uint32_t -dns64_ttl(dns_db_t *db, dns_dbversion_t *version) { - dns_dbnode_t *node = NULL; - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - isc_result_t result; - uint32_t ttl = UINT32_MAX; - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - ttl = ISC_MIN(rdataset.ttl, soa.minimum); - -cleanup: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (ttl); -} - -static bool -dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - isc_netaddr_t netaddr; - dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64); - unsigned int flags = 0; - unsigned int i, count; - bool *aaaaok; - - INSIST(client->query.dns64_aaaaok == NULL); - INSIST(client->query.dns64_aaaaoklen == 0); - INSIST(client->query.dns64_aaaa == NULL); - INSIST(client->query.dns64_sigaaaa == NULL); - - if (dns64 == NULL) - return (true); - - if (RECURSIONOK(client)) - flags |= DNS_DNS64_RECURSIVE; - - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - flags |= DNS_DNS64_DNSSEC; - - count = dns_rdataset_count(rdataset); - aaaaok = isc_mem_get(client->mctx, sizeof(bool) * count); - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, - &ns_g_server->aclenv, flags, rdataset, - aaaaok, count)) { - for (i = 0; i < count; i++) { - if (aaaaok != NULL && !aaaaok[i]) { - SAVE(client->query.dns64_aaaaok, aaaaok); - client->query.dns64_aaaaoklen = count; - break; - } - } - if (aaaaok != NULL) - isc_mem_put(client->mctx, aaaaok, - sizeof(bool) * count); - return (true); - } - if (aaaaok != NULL) - isc_mem_put(client->mctx, aaaaok, - sizeof(bool) * count); - return (false); -} - -/* - * Look for the name and type in the redirection zone. If found update - * the arguments as appropriate. Return true if a update was - * performed. - * - * Only perform the update if the client is in the allow query acl and - * returning the update would not cause a DNSSEC validation failure. - */ -static isc_result_t -redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_rdatatype_t qtype) -{ - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_name_t *found; - dns_rdataset_t trdataset; - isc_result_t result; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - ns_dbversion_t *dbversion; - - CTRACE(ISC_LOG_DEBUG(3), "redirect"); - - if (client->view->redirect == NULL) - return (ISC_R_NOTFOUND); - - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) - return (ISC_R_NOTFOUND); - - if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { - if (rdataset->trust == dns_trust_secure) - return (ISC_R_NOTFOUND); - if (rdataset->trust == dns_trust_ultimate && - (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3)) - return (ISC_R_NOTFOUND); - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (ISC_R_NOTFOUND); - } - } - } - - result = ns_client_checkaclsilent(client, NULL, - dns_zone_getqueryacl(client->view->redirect), - true); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - - result = dns_zone_getdb(client->view->redirect, &db); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - - dbversion = query_findversion(client, db); - if (dbversion == NULL) { - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - /* - * Lookup the requested data in the redirect zone. - */ - result = dns_db_findext(db, client->query.qname, dbversion->version, - qtype, DNS_DBFIND_NOZONECUT, client->now, - &node, found, &cm, &ci, &trdataset, NULL); - if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - goto nxrrset; - } else if (result != ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done"); - dns_name_copy(found, name, NULL); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) { - dns_rdataset_clone(&trdataset, rdataset); - dns_rdataset_disassociate(&trdataset); - } - nxrrset: - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - dns_db_detach(dbp); - dns_db_attachnode(db, node, nodep); - dns_db_attach(db, dbp); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - *versionp = dbversion->version; - - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - return (result); -} - -static isc_result_t -redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_rdatatype_t qtype, bool *is_zonep) -{ - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_fixedname_t fixedredirect; - dns_name_t *found, *redirectname; - dns_rdataset_t trdataset; - isc_result_t result; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *version = NULL; - dns_zone_t *zone = NULL; - bool is_zone; - unsigned int labels; - unsigned int options; - - CTRACE(ISC_LOG_DEBUG(3), "redirect2"); - - if (client->view->redirectzone == NULL) - return (ISC_R_NOTFOUND); - - if (dns_name_issubdomain(name, client->view->redirectzone)) - return (ISC_R_NOTFOUND); - - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) - return (ISC_R_NOTFOUND); - - if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { - if (rdataset->trust == dns_trust_secure) - return (ISC_R_NOTFOUND); - if (rdataset->trust == dns_trust_ultimate && - (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3)) - return (ISC_R_NOTFOUND); - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (ISC_R_NOTFOUND); - } - } - } - - redirectname = dns_fixedname_initname(&fixedredirect); - labels = dns_name_countlabels(client->query.qname); - if (labels > 1U) { - dns_name_t prefix; - - dns_name_init(&prefix, NULL); - dns_name_getlabelsequence(client->query.qname, 0, labels - 1, - &prefix); - result = dns_name_concatenate(&prefix, - client->view->redirectzone, - redirectname, NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - } else - dns_name_copy(redirectname, client->view->redirectzone, NULL); - - options = 0; - result = query_getdb(client, redirectname, qtype, options, &zone, - &db, &version, &is_zone); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - if (zone != NULL) - dns_zone_detach(&zone); - - /* - * Lookup the requested data in the redirect zone. - */ - result = dns_db_findext(db, redirectname, version, - qtype, 0, client->now, - &node, found, &cm, &ci, &trdataset, NULL); - if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - goto nxrrset; - } else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) { - /* - * Cleanup. - */ - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - /* - * Don't loop forever if the lookup failed last time. - */ - if (!REDIRECT(client)) { - result = query_recurse(client, qtype, redirectname, - NULL, NULL, true); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - client->query.attributes |= - NS_QUERYATTR_REDIRECT; - return (DNS_R_CONTINUE); - } - } - return (ISC_R_NOTFOUND); - } else if (result != ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done"); - /* - * Adjust the found name to not include the redirectzone suffix. - */ - dns_name_split(found, dns_name_countlabels(client->view->redirectzone), - found, NULL); - /* - * Make the name absolute. - */ - result = dns_name_concatenate(found, dns_rootname, found, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_name_copy(found, name, NULL); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) { - dns_rdataset_clone(&trdataset, rdataset); - dns_rdataset_disassociate(&trdataset); - } - nxrrset: - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - dns_db_detach(dbp); - dns_db_attachnode(db, node, nodep); - dns_db_attach(db, dbp); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - *is_zonep = is_zone; - *versionp = version; - - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - return (result); -} - -/* - * Do the bulk of query processing for the current query of 'client'. - * If 'event' is non-NULL, we are returning from recursion and 'qtype' - * is ignored. Otherwise, 'qtype' is the query type. - */ -static isc_result_t -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) -{ - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_rdatatype_t type = qtype; - dns_name_t *fname, *zfname, *tname, *prefix; - dns_rdataset_t *rdataset, *trdataset; - dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset; - dns_rdataset_t **sigrdatasetp; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatasetiter_t *rdsiter; - bool want_restart, is_zone, need_wildcardproof; - bool is_staticstub_zone; - bool authoritative = false; - bool answer_has_ns = false; - unsigned int n, nlabels; - dns_namereln_t namereln; - int order; - isc_buffer_t *dbuf; - isc_buffer_t b; - isc_result_t result, eresult, tresult; - dns_fixedname_t fixed; - dns_fixedname_t wildcardname; - dns_dbversion_t *version, *zversion; - dns_zone_t *zone; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - unsigned int options; - bool empty_wild; - dns_rdataset_t *noqname; - dns_rpz_st_t *rpz_st; - bool resuming; - int line = -1; - bool dns64_exclude, dns64, rpz; - bool nxrewrite = false; - bool want_stale = false; - bool redirected = false; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - char errmsg[256]; - bool associated; - dns_section_t section; - dns_ttl_t ttl; - bool failcache; - uint32_t flags; -#ifdef WANT_QUERYTRACE - char mbuf[4 * DNS_NAME_FORMATSIZE]; - char qbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; -#endif - dns_name_t *rpzqname; - - CTRACE(ISC_LOG_DEBUG(3), "query_find"); - - /* - * One-time initialization. - * - * It's especially important to initialize anything that the cleanup - * code might cleanup. - */ - - eresult = ISC_R_SUCCESS; - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - zversion = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - need_wildcardproof = false; - empty_wild = false; - dns64_exclude = dns64 = rpz = false; - options = 0; - resuming = false; - is_zone = false; - is_staticstub_zone = false; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - -#ifdef WANT_QUERYTRACE - if (client->query.origqname != NULL) - dns_name_format(client->query.origqname, qbuf, - sizeof(qbuf)); - else - snprintf(qbuf, sizeof(qbuf), ""); - - snprintf(mbuf, sizeof(mbuf) - 1, - "client attr:0x%x, query attr:0x%X, restarts:%u, " - "origqname:%s, timer:%d, authdb:%d, referral:%d", - client->attributes, - client->query.attributes, - client->query.restarts, qbuf, - (int) client->query.timerset, - (int) client->query.authdbset, - (int) client->query.isreferral); - CTRACE(ISC_LOG_DEBUG(3), mbuf); -#endif - - if (event != NULL) { - /* - * We're returning from recursion. Restore the query context - * and resume. - */ - want_restart = false; - - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) - { - CTRACE(ISC_LOG_DEBUG(3), "resume from RPZ recursion"); -#ifdef WANT_QUERYTRACE - { - char pbuf[DNS_NAME_FORMATSIZE] = ""; - char fbuf[DNS_NAME_FORMATSIZE] = ""; - if (rpz_st->r_name != NULL) - dns_name_format(rpz_st->r_name, - qbuf, sizeof(qbuf)); - else - snprintf(qbuf, sizeof(qbuf), - ""); - if (rpz_st->p_name != NULL) - dns_name_format(rpz_st->p_name, - pbuf, sizeof(pbuf)); - if (rpz_st->fname != NULL) - dns_name_format(rpz_st->fname, - fbuf, sizeof(fbuf)); - - snprintf(mbuf, sizeof(mbuf) - 1, - "rpz rname:%s, pname:%s, fname:%s", - qbuf, pbuf, fbuf); - CTRACE(ISC_LOG_DEBUG(3), mbuf); - } -#endif - - is_zone = rpz_st->q.is_zone; - authoritative = rpz_st->q.authoritative; - RESTORE(zone, rpz_st->q.zone); - RESTORE(node, rpz_st->q.node); - RESTORE(db, rpz_st->q.db); - RESTORE(rdataset, rpz_st->q.rdataset); - RESTORE(sigrdataset, rpz_st->q.sigrdataset); - qtype = rpz_st->q.qtype; - - if (event->node != NULL) - dns_db_detachnode(event->db, &event->node); - SAVE(rpz_st->r.db, event->db); - rpz_st->r.r_type = event->qtype; - SAVE(rpz_st->r.r_rdataset, event->rdataset); - query_putrdataset(client, &event->sigrdataset); - } else if (REDIRECT(client)) { - /* - * Restore saved state. - */ - CTRACE(ISC_LOG_DEBUG(3), - "resume from redirect recursion"); -#ifdef WANT_QUERYTRACE - dns_name_format(client->query.redirect.fname, - qbuf, sizeof(qbuf)); - dns_rdatatype_format(client->query.redirect.qtype, - tbuf, sizeof(tbuf)); - snprintf(mbuf, sizeof(mbuf) - 1, - "redirect fname:%s, qtype:%s, auth:%d", - qbuf, tbuf, - client->query.redirect.authoritative); - CTRACE(ISC_LOG_DEBUG(3), mbuf); -#endif - qtype = client->query.redirect.qtype; - INSIST(client->query.redirect.rdataset != NULL); - RESTORE(rdataset, client->query.redirect.rdataset); - RESTORE(sigrdataset, - client->query.redirect.sigrdataset); - RESTORE(db, client->query.redirect.db); - RESTORE(node, client->query.redirect.node); - RESTORE(zone, client->query.redirect.zone); - authoritative = client->query.redirect.authoritative; - is_zone = client->query.redirect.is_zone; - - /* - * Free resources used while recursing. - */ - query_putrdataset(client, &event->rdataset); - query_putrdataset(client, &event->sigrdataset); - if (event->node != NULL) - dns_db_detachnode(event->db, &event->node); - if (event->db != NULL) - dns_db_detach(&event->db); - } else { - CTRACE(ISC_LOG_DEBUG(3), - "resume from normal recursion"); - authoritative = false; - - qtype = event->qtype; - SAVE(db, event->db); - SAVE(node, event->node); - SAVE(rdataset, event->rdataset); - SAVE(sigrdataset, event->sigrdataset); - } - INSIST(rdataset != NULL); - - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - - if (DNS64(client)) { - client->query.attributes &= ~NS_QUERYATTR_DNS64; - dns64 = true; - } - if (DNS64EXCLUDE(client)) { - client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE; - dns64_exclude = true; - } - - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) - { - /* - * Has response policy changed out from under us? - */ - if (rpz_st->rpz_ver != client->view->rpzs->rpz_ver) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, - "query_find: RPZ settings " - "out of date " - "(rpz_ver %d, expected %d)", - client->view->rpzs->rpz_ver, - rpz_st->rpz_ver); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getnamebuf failed (1)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newname failed (1)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) { - tname = rpz_st->fname; - } else if (REDIRECT(client)) { - tname = client->query.redirect.fname; - } else { - tname = dns_fixedname_name(&event->foundname); - } - result = dns_name_copy(tname, fname, NULL); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_find: dns_name_copy failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) { - rpz_st->r.r_result = event->result; - result = rpz_st->q.result; - free_devent(client, ISC_EVENT_PTR(&event), &event); - } else if (REDIRECT(client)) { - result = client->query.redirect.result; - is_zone = client->query.redirect.is_zone; - } else { - result = event->result; - } - resuming = true; - goto resume; - } - - /* - * Not returning from recursion. - * - * First, check for a recent match in the view's SERVFAIL cache. - * If we find one, and it was from a query with CD=1, *or* - * if the current query has CD=0, then we can just return - * SERVFAIL now. - */ - if (RECURSIONOK(client)) { - flags = 0; -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_resolver) { - failcache = false; - } else { - failcache = dns_badcache_find(client->view->failcache, - client->query.qname, qtype, - &flags, &client->tnow); - } -#else - failcache = dns_badcache_find(client->view->failcache, - client->query.qname, qtype, - &flags, &client->tnow); -#endif - if (failcache && - (((flags & NS_FAILCACHE_CD) != 0) || - ((client->message->flags & DNS_MESSAGEFLAG_CD) == 0))) - { - if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1))) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_name_format(client->query.qname, - namebuf, sizeof(namebuf)); - dns_rdatatype_format(qtype, typebuf, - sizeof(typebuf)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(1), - "servfail cache hit %s/%s (%s)", - namebuf, typebuf, - ((flags & NS_FAILCACHE_CD) != 0) - ? "CD=1" - : "CD=0"); - } - client->attributes |= NS_CLIENTATTR_NOSETFC; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * If it's a SIG query, we'll iterate the node. - */ - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - - restart: - // query_start - CTRACE(ISC_LOG_DEBUG(3), "query_find: restart"); - want_restart = false; - authoritative = false; - version = NULL; - zversion = NULL; - need_wildcardproof = false; - rpz = false; - - /* - * If we require a server cookie then send back BADCOOKIE - * before we have done too much work. - */ - if (!TCP(client) && client->view->requireservercookie && - WANTCOOKIE(client) && !HAVECOOKIE(client)) - { - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - client->message->rcode = dns_rcode_badcookie; - goto cleanup; - } - - if (client->view->checknames && - !dns_rdata_checkowner(client->query.qname, - client->message->rdclass, - qtype, false)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdatatype_format(qtype, typebuf, sizeof(typebuf)); - dns_rdataclass_format(client->message->rdclass, classbuf, - sizeof(classbuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_ERROR, - "check-names failure %s/%s/%s", namebuf, - typebuf, classbuf); - QUERY_ERROR(DNS_R_REFUSED); - goto cleanup; - } - - /* - * Setup for root key sentinel processing. - */ - if (client->view->root_key_sentinel && - client->query.restarts == 0 && - (qtype == dns_rdatatype_a || - qtype == dns_rdatatype_aaaa) && - (client->message->flags & DNS_MESSAGEFLAG_CD) == 0) - { - root_key_sentinel_detect(client); - } - - /* - * First we must find the right database. - */ - options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ - if (dns_rdatatype_atparent(qtype) && - !dns_name_equal(client->query.qname, dns_rootname)) - options |= DNS_GETDB_NOEXACT; - result = query_getdb(client, client->query.qname, qtype, options, - &zone, &db, &version, &is_zone); - if (ISC_UNLIKELY((result != ISC_R_SUCCESS || !is_zone) && - qtype == dns_rdatatype_ds && - !RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0)) - { - /* - * If the query type is DS, look to see if we are - * authoritative for the child zone. - */ - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - - tresult = query_getzonedb(client, client->query.qname, qtype, - DNS_GETDB_PARTIAL, &tzone, &tdb, - &tversion); - if (tresult == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = NULL; - RESTORE(version, tversion); - RESTORE(db, tdb); - RESTORE(zone, tzone); - is_zone = true; - result = ISC_R_SUCCESS; - } else { - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - } - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_REFUSED) { - if (WANTRECURSION(client)) { - inc_stats(client, - dns_nsstatscounter_recurserej); - } else - inc_stats(client, dns_nsstatscounter_authrej); - if (!PARTIALANSWER(client)) - QUERY_ERROR(DNS_R_REFUSED); - } else { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getdb failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - } - goto cleanup; - } - - is_staticstub_zone = false; - if (is_zone) { - authoritative = true; - if (zone != NULL && - dns_zone_gettype(zone) == dns_zone_staticstub) - is_staticstub_zone = true; - } - - if (event == NULL && client->query.restarts == 0) { - if (is_zone) { - if (zone != NULL) { - /* - * if is_zone = true, zone = NULL then this is - * a DLZ zone. Don't attempt to attach zone. - */ - dns_zone_attach(zone, &client->query.authzone); - } - dns_db_attach(db, &client->query.authdb); - } - client->query.authdbset = true; - - /* Track TCP vs UDP stats per zone */ - if (TCP(client)) - inc_stats(client, dns_nsstatscounter_tcp); - else - inc_stats(client, dns_nsstatscounter_udp); - } - - db_find: - // query_lookup - CTRACE(ISC_LOG_DEBUG(3), "query_find: db_find"); - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (ISC_UNLIKELY(dbuf == NULL)) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getnamebuf failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (ISC_UNLIKELY(fname == NULL || rdataset == NULL)) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newname failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newrdataset failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * Now look for an answer in the database. If this is a dns64 - * AAAA lookup on a rpz database adjust the qname. - */ - if (dns64 && rpz) - rpzqname = client->query.rpz_st->p_name; - else - rpzqname = client->query.qname; - - result = dns_db_findext(db, rpzqname, version, type, - client->query.dboptions, client->now, - &node, fname, &cm, &ci, rdataset, sigrdataset); - /* - * Fixup fname and sigrdataset. - */ - if (dns64 && rpz) { - isc_result_t rresult; - - rresult = dns_name_copy(client->query.qname, fname, NULL); - RUNTIME_CHECK(rresult == ISC_R_SUCCESS); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - - if (!is_zone) - dns_cache_updatestats(client->view->cache, result); - - if (want_stale) { - char namebuf[DNS_NAME_FORMATSIZE]; - bool success; - - client->query.dboptions &= ~DNS_DBFIND_STALEOK; - want_stale = false; - - if (dns_rdataset_isassociated(rdataset) && - dns_rdataset_count(rdataset) > 0 && - STALE(rdataset)) { - rdataset->ttl = client->view->staleanswerttl; - success = true; - } else { - success = false; - } - - dns_name_format(client->query.qname, - namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_SERVE_STALE, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s resolver failure, stale answer %s", - namebuf, success ? "used" : "unavailable"); - - if (!success) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - resume: - CTRACE(ISC_LOG_DEBUG(3), "query_find: resume"); - - /* - * Rate limit these responses to this client. - * Do not delay counting and handling obvious referrals, - * since those won't come here again. - * Delay handling delegations for which we are certain to recurse and - * return here (DNS_R_DELEGATION, not a child of one of our - * own zones, and recursion enabled) - * Don't mess with responses rewritten by RPZ - * Count each response at most once. - */ - if (client->view->rrl != NULL && !HAVECOOKIE(client) && - ((fname != NULL && dns_name_isabsolute(fname)) || - (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) && - !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) && - (client->query.rpz_st == NULL || - (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&& - (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) - { - dns_rdataset_t nc_rdataset; - bool wouldlog; - char log_buf[DNS_RRL_LOG_BUF_LEN]; - isc_result_t nc_result, resp_result; - dns_rrl_result_t rrl_result; - - client->query.attributes |= NS_QUERYATTR_RRL_CHECKED; - - wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP); - tname = fname; - if (result == DNS_R_NXDOMAIN) { - /* - * Use the database origin name to rate limit NXDOMAIN - */ - if (db != NULL) - tname = dns_db_origin(db); - resp_result = result; - } else if (result == DNS_R_NCACHENXDOMAIN && - rdataset != NULL && - dns_rdataset_isassociated(rdataset) && - (rdataset->attributes & - DNS_RDATASETATTR_NEGATIVE) != 0) { - /* - * Try to use owner name in the negative cache SOA. - */ - dns_fixedname_init(&fixed); - dns_rdataset_init(&nc_rdataset); - for (nc_result = dns_rdataset_first(rdataset); - nc_result == ISC_R_SUCCESS; - nc_result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, - dns_fixedname_name(&fixed), - &nc_rdataset); - if (nc_rdataset.type == dns_rdatatype_soa) { - dns_rdataset_disassociate(&nc_rdataset); - tname = dns_fixedname_name(&fixed); - break; - } - dns_rdataset_disassociate(&nc_rdataset); - } - resp_result = DNS_R_NXDOMAIN; - } else if (result == DNS_R_NXRRSET || - result == DNS_R_EMPTYNAME) { - resp_result = DNS_R_NXRRSET; - } else if (result == DNS_R_DELEGATION) { - resp_result = result; - } else if (result == ISC_R_NOTFOUND) { - /* - * Handle referral to ".", including when recursion - * is off or not requested and the hints have not - * been loaded or we have "additional-from-cache no". - */ - tname = dns_rootname; - resp_result = DNS_R_DELEGATION; - } else { - resp_result = ISC_R_SUCCESS; - } - rrl_result = dns_rrl(client->view, &client->peeraddr, - TCP(client), client->message->rdclass, - qtype, tname, resp_result, client->now, - wouldlog, log_buf, sizeof(log_buf)); - if (rrl_result != DNS_RRL_RESULT_OK) { - /* - * Log dropped or slipped responses in the query - * category so that requests are not silently lost. - * Starts of rate-limited bursts are logged in - * DNS_LOGCATEGORY_RRL. - * - * Dropped responses are counted with dropped queries - * in QryDropped while slipped responses are counted - * with other truncated responses in RespTruncated. - */ - if (wouldlog) { - ns_client_log(client, DNS_LOGCATEGORY_RRL, - NS_LOGMODULE_QUERY, - DNS_RRL_LOG_DROP, - "%s", log_buf); - } - if (!client->view->rrl->log_only) { - if (rrl_result == DNS_RRL_RESULT_DROP) { - /* - * These will also be counted in - * dns_nsstatscounter_dropped - */ - inc_stats(client, - dns_nsstatscounter_ratedropped); - QUERY_ERROR(DNS_R_DROP); - } else { - /* - * These will also be counted in - * dns_nsstatscounter_truncatedresp - */ - inc_stats(client, - dns_nsstatscounter_rateslipped); - if (WANTCOOKIE(client)) { - client->message->flags &= - ~DNS_MESSAGEFLAG_AA; - client->message->flags &= - ~DNS_MESSAGEFLAG_AD; - client->message->rcode = - dns_rcode_badcookie; - } else { - client->message->flags |= - DNS_MESSAGEFLAG_TC; - if (resp_result == - DNS_R_NXDOMAIN) - client->message->rcode = - dns_rcode_nxdomain; - } - } - goto cleanup; - } - } - } else if (!TCP(client) && client->view->requireservercookie && - WANTCOOKIE(client) && !HAVECOOKIE(client)) { - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - client->message->rcode = dns_rcode_badcookie; - goto cleanup; - } - - if (!RECURSING(client) && - !dns_name_equal(client->query.qname, dns_rootname)) - { - isc_result_t rresult; - - rresult = rpz_rewrite(client, qtype, result, resuming, - rdataset, sigrdataset); - rpz_st = client->query.rpz_st; - switch (rresult) { - case ISC_R_SUCCESS: - break; - case DNS_R_DISALLOWED: - goto norpz; - case DNS_R_DELEGATION: - /* - * recursing for NS names or addresses, - * so save the main query state - */ - rpz_st->q.qtype = qtype; - rpz_st->q.is_zone = is_zone; - rpz_st->q.authoritative = authoritative; - SAVE(rpz_st->q.zone, zone); - SAVE(rpz_st->q.db, db); - SAVE(rpz_st->q.node, node); - SAVE(rpz_st->q.rdataset, rdataset); - SAVE(rpz_st->q.sigrdataset, sigrdataset); - dns_name_copy(fname, rpz_st->fname, NULL); - rpz_st->q.result = result; - client->query.attributes |= NS_QUERYATTR_RECURSING; - goto cleanup; - default: - RECURSE_ERROR(rresult); - goto cleanup; - } - - if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS) - rpz_st->state |= DNS_RPZ_REWRITTEN; - if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS && - rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU && - (rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY || - !TCP(client)) && - rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) - { - /* - * We got a hit and are going to answer with our - * fiction. Ensure that we answer with the name - * we looked up even if we were stopped short - * in recursion or for a deferral. - */ - rresult = dns_name_copy(client->query.qname, - fname, NULL); - RUNTIME_CHECK(rresult == ISC_R_SUCCESS); - rpz_clean(&zone, &db, &node, NULL); - if (rpz_st->m.rdataset != NULL) { - query_putrdataset(client, &rdataset); - RESTORE(rdataset, rpz_st->m.rdataset); - } else if (rdataset != NULL && - dns_rdataset_isassociated(rdataset)) { - dns_rdataset_disassociate(rdataset); - } - version = NULL; - - RESTORE(node, rpz_st->m.node); - RESTORE(db, rpz_st->m.db); - RESTORE(version, rpz_st->m.version); - RESTORE(zone, rpz_st->m.zone); - - switch (rpz_st->m.policy) { - case DNS_RPZ_POLICY_TCP_ONLY: - client->message->flags |= DNS_MESSAGEFLAG_TC; - if (result == DNS_R_NXDOMAIN || - result == DNS_R_NCACHENXDOMAIN) - client->message->rcode = - dns_rcode_nxdomain; - rpz_log_rewrite(client, false, - rpz_st->m.policy, - rpz_st->m.type, zone, - rpz_st->p_name, NULL, - rpz_st->m.rpz->num); - goto cleanup; - case DNS_RPZ_POLICY_DROP: - QUERY_ERROR(DNS_R_DROP); - rpz_log_rewrite(client, false, - rpz_st->m.policy, - rpz_st->m.type, zone, - rpz_st->p_name, NULL, - rpz_st->m.rpz->num); - goto cleanup; - case DNS_RPZ_POLICY_NXDOMAIN: - result = DNS_R_NXDOMAIN; - nxrewrite = true; - rpz = true; - break; - case DNS_RPZ_POLICY_NODATA: - nxrewrite = true; - /* FALLTHROUGH */ - case DNS_RPZ_POLICY_DNS64: - result = DNS_R_NXRRSET; - rpz = true; - break; - case DNS_RPZ_POLICY_RECORD: - result = rpz_st->m.result; - if (qtype == dns_rdatatype_any && - result != DNS_R_CNAME) { - /* - * We will add all of the rdatasets of - * the node by iterating later, - * and set the TTL then. - */ - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - } else { - /* - * We will add this rdataset. - */ - rdataset->ttl = ISC_MIN(rdataset->ttl, - rpz_st->m.ttl); - } - rpz = true; - break; - case DNS_RPZ_POLICY_WILDCNAME: - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - result = rpz_add_cname(client, rpz_st, - &cname.cname, - fname, dbuf); - if (result != ISC_R_SUCCESS) - goto cleanup; - fname = NULL; - want_restart = true; - goto cleanup; - case DNS_RPZ_POLICY_CNAME: - /* - * Add overriding CNAME from a named.conf - * response-policy statement - */ - result = rpz_add_cname(client, rpz_st, - &rpz_st->m.rpz->cname, - fname, dbuf); - if (result != ISC_R_SUCCESS) - goto cleanup; - fname = NULL; - want_restart = true; - goto cleanup; - default: - INSIST(0); - } - - /* - * Turn off DNSSEC because the results of a - * response policy zone cannot verify. - */ - client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | - NS_CLIENTATTR_WANTAD); - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - query_putrdataset(client, &sigrdataset); - is_zone = true; - rpz_log_rewrite(client, false, rpz_st->m.policy, - rpz_st->m.type, zone, rpz_st->p_name, - NULL, rpz_st->m.rpz->num); - } - } - - norpz: - /* - * If required, handle special "root-key-sentinel-is-ta-" and - * "root-key-sentinel-not-ta-" labels by returning SERVFAIL. - */ - if (root_key_sentinel_return_servfail(client, is_zone, - rdataset, result)) - { - /* - * Don't record this response in the SERVFAIL cache. - */ - client->attributes |= NS_CLIENTATTR_NOSETFC; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - switch (result) { - case ISC_R_SUCCESS: - /* - * This case is handled in the main line below. - */ - break; - case DNS_R_GLUE: - case DNS_R_ZONECUT: - /* - * These cases are handled in the main line below. - */ - INSIST(is_zone); - authoritative = false; - break; - case ISC_R_NOTFOUND: - /* - * The cache doesn't even have the root NS. Get them from - * the hints DB. - */ - // query_notfound - INSIST(!is_zone); - if (db != NULL) - dns_db_detach(&db); - - if (client->view->hints == NULL) { - /* We have no hints. */ - result = ISC_R_FAILURE; - } else { - dns_db_attach(client->view->hints, &db); - result = dns_db_findext(db, dns_rootname, - NULL, dns_rdatatype_ns, - 0, client->now, &node, - fname, &cm, &ci, - rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * Nonsensical root hints may require cleanup. - */ - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - /* - * We don't have any root server hints, but - * we may have working forwarders, so try to - * recurse anyway. - */ - if (RECURSIONOK(client)) { - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } else { - /* Unable to give root server referral. */ - CTRACE(ISC_LOG_ERROR, - "unable to give root server referral"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - /* - * XXXRTH We should trigger root server priming here. - */ - /* FALLTHROUGH */ - case DNS_R_DELEGATION: - // query_delegation - authoritative = false; - if (is_zone) { - /* - * Look to see if we are authoritative for the - * child zone if the query type is DS. - */ - // query_zone_delegation - if (!RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0 && - qtype == dns_rdatatype_ds) { - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - result = query_getzonedb(client, - client->query.qname, - qtype, - DNS_GETDB_PARTIAL, - &tzone, &tdb, - &tversion); - if (result == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - if (fname != NULL) - query_releasename(client, - &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = NULL; - RESTORE(version, tversion); - RESTORE(db, tdb); - RESTORE(zone, tzone); - authoritative = true; - goto db_find; - } - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - /* - * We're authoritative for an ancestor of QNAME. - */ - if (!USECACHE(client) || !RECURSIONOK(client)) { - bool detach = false; - - dns_fixedname_init(&fixed); - dns_name_copy(fname, - dns_fixedname_name(&fixed), NULL); - - /* - * If we don't have a cache, this is the best - * answer. - * - * If the client is making a nonrecursive - * query we always give out the authoritative - * delegation. This way even if we get - * junk in our cache, we won't fail in our - * role as the delegating authority if another - * nameserver asks us about a delegated - * subzone. - * - * We enable the retrieval of glue for this - * database by setting client->query.gluedb. - */ - if (db != NULL && - client->query.gluedb == NULL) { - dns_db_attach(db, - &client->query.gluedb); - detach = true; - } - client->query.isreferral = true; - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - if (detach) { - dns_db_detach(&client->query.gluedb); - } - if (WANTDNSSEC(client)) - query_addds(client, db, node, version, - dns_fixedname_name(&fixed)); - } else { - /* - * We might have a better answer or delegation - * in the cache. We'll remember the current - * values of fname, rdataset, and sigrdataset. - * We'll then go looking for QNAME in the - * cache. If we find something better, we'll - * use it instead. - */ - query_keepname(client, fname, dbuf); - dns_db_detachnode(db, &node); - SAVE(zdb, db); - SAVE(zfname, fname); - SAVE(zversion, version); - SAVE(zrdataset, rdataset); - SAVE(zsigrdataset, sigrdataset); - dns_db_attach(client->view->cachedb, &db); - is_zone = false; - goto db_find; - } - } else { - if (zfname != NULL && - (!dns_name_issubdomain(fname, zfname) || - (is_staticstub_zone && - dns_name_equal(fname, zfname)))) { - /* - * In the following cases use "authoritative" - * data instead of the cache delegation: - * 1. We've already got a delegation from - * authoritative data, and it is better - * than what we found in the cache. - * 2. The query name matches the origin name - * of a static-stub zone. This needs to be - * considered for the case where the NS of - * the static-stub zone and the cached NS - * are different. We still need to contact - * the nameservers configured in the - * static-stub zone. - */ - query_releasename(client, &fname); - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - version = NULL; - - RESTORE(fname, zfname); - RESTORE(version, zversion); - RESTORE(rdataset, zrdataset); - RESTORE(sigrdataset, zsigrdataset); - /* - * We don't clean up zdb here because we - * may still need it. It will get cleaned - * up by the main cleanup code. - */ - } - - if (RECURSIONOK(client)) { - /* - * Recurse! - */ - INSIST(!REDIRECT(client)); - if (dns_rdatatype_atparent(type)) - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - else if (dns64) - result = query_recurse(client, - dns_rdatatype_a, - client->query.qname, - NULL, NULL, resuming); - else - result = query_recurse(client, qtype, - client->query.qname, - fname, rdataset, - resuming); - - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) - QUERY_ERROR(result); - else - RECURSE_ERROR(result); - } else { - bool detach = false; - - dns_fixedname_init(&fixed); - dns_name_copy(fname, - dns_fixedname_name(&fixed), NULL); - /* - * This is the best answer. - */ - client->query.attributes |= - NS_QUERYATTR_CACHEGLUEOK; - client->query.isreferral = true; - - if (zdb != NULL && - client->query.gluedb == NULL) { - dns_db_attach(zdb, - &client->query.gluedb); - detach = true; - } - - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - client->query.attributes &= - ~NS_QUERYATTR_CACHEGLUEOK; - if (detach) { - dns_db_detach(&client->query.gluedb); - } - - if (WANTDNSSEC(client)) - query_addds(client, db, node, version, - dns_fixedname_name(&fixed)); - } - } - goto cleanup; - - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - iszone_nxrrset: - INSIST(is_zone); - -#ifdef dns64_bis_return_excluded_addresses - if (dns64) -#else - if (dns64 && !dns64_exclude) -#endif - { - /* - * Restore the answers from the previous AAAA lookup. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - RESTORE(rdataset, client->query.dns64_aaaa); - RESTORE(sigrdataset, client->query.dns64_sigaaaa); - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_getnamebuf failed (3)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_newname failed (3)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - dns_name_copy(client->query.qname, fname, NULL); - dns64 = false; -#ifdef dns64_bis_return_excluded_addresses - /* - * Resume the diverted processing of the AAAA response? - */ - if (dns64_excluded) - break; -#endif - } else if (result == DNS_R_NXRRSET && - !ISC_LIST_EMPTY(client->view->dns64) && - !nxrewrite && - client->message->rdclass == dns_rdataclass_in && - qtype == dns_rdatatype_aaaa) - { - /* - * Look to see if there are A records for this - * name. - */ - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - client->query.dns64_ttl = dns64_ttl(db, version); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64 = true; - goto db_find; - } - - /* - * Look for a NSEC3 record if we don't have a NSEC record. - */ - nxrrset_rrsig: - if (redirected) - goto cleanup; - if (!dns_rdataset_isassociated(rdataset) && - WANTDNSSEC(client)) { - if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) { - dns_name_t *found; - dns_name_t *qname; - - found = dns_fixedname_initname(&fixed); - qname = client->query.qname; - - query_findclosestnsec3(qname, db, version, - client, rdataset, - sigrdataset, fname, - true, found); - /* - * Did we find the closest provable encloser - * instead? If so add the nearest to the - * closest provable encloser. - */ - if (dns_rdataset_isassociated(rdataset) && - !dns_name_equal(qname, found) && - !(ns_g_nonearest && - qtype != dns_rdatatype_ds)) - { - unsigned int count; - unsigned int skip; - - /* - * Add the closest provable encloser. - */ - query_addrrset(client, &fname, - &rdataset, &sigrdataset, - dbuf, - DNS_SECTION_AUTHORITY); - - count = dns_name_countlabels(found) - + 1; - skip = dns_name_countlabels(qname) - - count; - dns_name_getlabelsequence(qname, skip, - count, - found); - - fixfname(client, &fname, &dbuf, &b); - fixrdataset(client, &rdataset); - fixrdataset(client, &sigrdataset); - if (fname == NULL || - rdataset == NULL || - sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "failure getting " - "closest encloser"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - /* - * 'nearest' doesn't exist so - * 'exist' is set to false. - */ - query_findclosestnsec3(found, db, - version, - client, - rdataset, - sigrdataset, - fname, - false, - NULL); - } - } else { - query_releasename(client, &fname); - query_addwildcardproof(client, db, version, - client->query.qname, - false, true); - } - } - // query_nxdomain - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else if (fname != NULL) { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - - /* - * Add SOA to the additional section if generated by a RPZ - * rewrite. - */ - associated = dns_rdataset_isassociated(rdataset); - section = nxrewrite ? DNS_SECTION_ADDITIONAL : - DNS_SECTION_AUTHORITY; - - result = query_addsoa(client, db, version, UINT32_MAX, - associated, section); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - - /* - * Add NSEC record if we found one. - */ - if (WANTDNSSEC(client)) { - if (dns_rdataset_isassociated(rdataset)) - query_addnxrrsetnsec(client, db, version, - &fname, &rdataset, - &sigrdataset); - } - goto cleanup; - - case DNS_R_EMPTYWILD: - empty_wild = true; - /* FALLTHROUGH */ - - case DNS_R_NXDOMAIN: - INSIST(is_zone || REDIRECT(client)); - if (!empty_wild) { - tresult = redirect(client, fname, rdataset, &node, - &db, &version, type); - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - is_zone = false; - goto ncache_nxrrset; - } - tresult = redirect2(client, fname, rdataset, &node, - &db, &version, type, &is_zone); - if (tresult == DNS_R_CONTINUE) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect_rlookup); - client->query.redirect.qtype = qtype; - INSIST(rdataset != NULL); - SAVE(client->query.redirect.rdataset, rdataset); - SAVE(client->query.redirect.sigrdataset, - sigrdataset); - SAVE(client->query.redirect.db, db); - SAVE(client->query.redirect.node, node); - SAVE(client->query.redirect.zone, zone); - client->query.redirect.result = DNS_R_NXDOMAIN; - dns_name_copy(fname, - client->query.redirect.fname, - NULL); - client->query.redirect.authoritative = - authoritative; - client->query.redirect.is_zone = is_zone; - goto cleanup; - } - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - is_zone = false; - goto ncache_nxrrset; - } - } - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else if (fname != NULL) { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - - /* - * Add SOA to the additional section if generated by a - * RPZ rewrite. - * - * If the query was for a SOA record force the - * ttl to zero so that it is possible for clients to find - * the containing zone of an arbitrary name with a stub - * resolver and not have it cached. - */ - associated = dns_rdataset_isassociated(rdataset); - section = nxrewrite ? DNS_SECTION_ADDITIONAL : - DNS_SECTION_AUTHORITY; - ttl = UINT32_MAX; - if (!nxrewrite && qtype == dns_rdatatype_soa && - zone != NULL && dns_zone_getzeronosoattl(zone)) - ttl = 0; - result = query_addsoa(client, db, version, ttl, associated, - section); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - - if (WANTDNSSEC(client)) { - /* - * Add NSEC record if we found one. - */ - if (dns_rdataset_isassociated(rdataset)) - query_addrrset(client, &fname, &rdataset, - &sigrdataset, - NULL, DNS_SECTION_AUTHORITY); - query_addwildcardproof(client, db, version, - client->query.qname, false, - false); - } - - /* - * Set message rcode. - */ - if (empty_wild) - client->message->rcode = dns_rcode_noerror; - else - client->message->rcode = dns_rcode_nxdomain; - goto cleanup; - - case DNS_R_NCACHENXDOMAIN: - tresult = redirect(client, fname, rdataset, &node, - &db, &version, type); - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - is_zone = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - result = tresult; - goto ncache_nxrrset; - } - tresult = redirect2(client, fname, rdataset, &node, - &db, &version, type, &is_zone); - if (tresult == DNS_R_CONTINUE) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect_rlookup); - SAVE(client->query.redirect.db, db); - SAVE(client->query.redirect.node, node); - SAVE(client->query.redirect.zone, zone); - client->query.redirect.qtype = qtype; - INSIST(rdataset != NULL); - SAVE(client->query.redirect.rdataset, rdataset); - SAVE(client->query.redirect.sigrdataset, sigrdataset); - client->query.redirect.result = DNS_R_NCACHENXDOMAIN; - dns_name_copy(fname, client->query.redirect.fname, - NULL); - client->query.redirect.authoritative = authoritative; - client->query.redirect.is_zone = is_zone; - goto cleanup; - } - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - is_zone = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - result = tresult; - goto ncache_nxrrset; - } - /* FALLTHROUGH */ - - case DNS_R_NCACHENXRRSET: - ncache_nxrrset: - INSIST(!is_zone); - authoritative = false; - /* - * Set message rcode, if required. - */ - if (result == DNS_R_NCACHENXDOMAIN) - client->message->rcode = dns_rcode_nxdomain; - /* - * Look for RFC 1918 leakage from Internet. - */ - if (result == DNS_R_NCACHENXDOMAIN && - qtype == dns_rdatatype_ptr && - client->message->rdclass == dns_rdataclass_in && - dns_name_countlabels(fname) == 7) - warn_rfc1918(client, fname, rdataset); - -#ifdef dns64_bis_return_excluded_addresses - if (dns64) -#else - if (dns64 && !dns64_exclude) -#endif - { - /* - * Restore the answers from the previous AAAA lookup. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - RESTORE(rdataset, client->query.dns64_aaaa); - RESTORE(sigrdataset, client->query.dns64_sigaaaa); - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_getnamebuf failed (4)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_newname failed (4)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - dns_name_copy(client->query.qname, fname, NULL); - dns64 = false; -#ifdef dns64_bis_return_excluded_addresses - if (dns64_excluded) - break; -#endif - } else if (result == DNS_R_NCACHENXRRSET && - !ISC_LIST_EMPTY(client->view->dns64) && - client->message->rdclass == dns_rdataclass_in && - qtype == dns_rdatatype_aaaa) - { - /* - * Look to see if there are A records for this - * name. - */ - - /* - * If the ttl is zero we need to workout if we have just - * decremented to zero or if there was no negative cache - * ttl in the answer. - */ - if (rdataset->ttl != 0) - client->query.dns64_ttl = rdataset->ttl; - else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS) - client->query.dns64_ttl = 0; - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64 = true; - goto db_find; - } - - /* - * We don't call query_addrrset() because we don't need any - * of its extra features (and things would probably break!). - */ - if (dns_rdataset_isassociated(rdataset)) { - query_keepname(client, fname, dbuf); - dns_message_addname(client->message, fname, - DNS_SECTION_AUTHORITY); - ISC_LIST_APPEND(fname->list, rdataset, link); - fname = NULL; - rdataset = NULL; - } - goto cleanup; - - case DNS_R_CNAME: - /* - * If we have a zero ttl from the cache refetch it. - */ - // query_cname - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && - RECURSIONOK(client)) - { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } - - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the CNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = true; - } - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Reset qname to be the target name of the CNAME and restart - * the query. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - dns_name_init(tname, NULL); - result = dns_name_dup(&cname.cname, client->mctx, tname); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - dns_rdata_freestruct(&cname); - goto cleanup; - } - dns_rdata_freestruct(&cname); - ns_client_qnamereplace(client, tname); - want_restart = true; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - goto addauth; - case DNS_R_DNAME: - /* - * Compare the current qname to the found name. We need - * to know how many labels and bits are in common because - * we're going to have to split qname later on. - */ - namereln = dns_name_fullcompare(client->query.qname, fname, - &order, &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the DNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = true; - } - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Get the target name of the DNAME. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - dns_name_clone(&dname.dname, tname); - dns_rdata_freestruct(&dname); - /* - * Construct the new qname consisting of - * . - */ - prefix = dns_fixedname_initname(&fixed); - dns_name_split(client->query.qname, nlabels, prefix, NULL); - INSIST(fname == NULL); - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - result = dns_name_concatenate(prefix, tname, fname, NULL); - dns_message_puttempname(client->message, &tname); - - /* - * RFC2672, section 4.1, subsection 3c says - * we should return YXDOMAIN if the constructed - * name would be too long. - */ - if (result == DNS_R_NAMETOOLONG) - client->message->rcode = dns_rcode_yxdomain; - if (result != ISC_R_SUCCESS) - goto cleanup; - - query_keepname(client, fname, dbuf); - /* - * Synthesize a CNAME consisting of - * CNAME - * with - * - * Synthesize a CNAME so old old clients that don't understand - * DNAME can chain. - * - * We do not try to synthesize a signature because we hope - * that security aware servers will understand DNAME. Also, - * even if we had an online key, making a signature - * on-the-fly is costly, and not really legitimate anyway - * since the synthesized CNAME is NOT in the zone. - */ - result = query_add_cname(client, client->query.qname, fname, - trdataset->trust, trdataset->ttl); - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * If the original query was not for a CNAME or ANY then - * follow the CNAME. - */ - if (qtype != dns_rdatatype_cname && - qtype != dns_rdatatype_any) - { - /* - * Switch to the new qname and restart. - */ - ns_client_qnamereplace(client, fname); - fname = NULL; - want_restart = true; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - } - goto addauth; - default: - /* - * Something has gone wrong. - */ - snprintf(errmsg, sizeof(errmsg) - 1, - "query_find: unexpected error after resuming: %s", - isc_result_totext(result)); - CTRACE(ISC_LOG_ERROR, errmsg); - if (resuming) { - want_stale = true; - } else { - QUERY_ERROR(DNS_R_SERVFAIL); - } - goto cleanup; - } - - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL); - need_wildcardproof = true; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * The filter-aaaa-on-v4 option should suppress AAAAs for IPv4 - * clients if there is an A; filter-aaaa-on-v6 option does the same - * for IPv6 clients. - */ - client->filter_aaaa = dns_aaaa_ok; - if (client->view->v4_aaaa != dns_aaaa_ok || - client->view->v6_aaaa != dns_aaaa_ok) - { - result = ns_client_checkaclsilent(client, NULL, - client->view->aaaa_acl, - true); - if (result == ISC_R_SUCCESS && - client->view->v4_aaaa != dns_aaaa_ok && - is_v4_client(client)) - client->filter_aaaa = client->view->v4_aaaa; - else if (result == ISC_R_SUCCESS && - client->view->v6_aaaa != dns_aaaa_ok && - is_v6_client(client)) - client->filter_aaaa = client->view->v6_aaaa; - } - -#endif - - if (type == dns_rdatatype_any) { - /* - * For minimal-any, we only add records that - * match this type or cover this type. - */ - dns_rdatatype_t onetype = 0; -#ifdef ALLOW_FILTER_AAAA - bool have_aaaa, have_a, have_sig; - - /* - * If we are not authoritative, assume there is a A - * even in if it is not in our cache. This assumption could - * be wrong but it is a good bet. - */ - have_aaaa = false; - have_a = !authoritative; - have_sig = false; -#endif - /* - * XXXRTH Need to handle zonecuts with special case - * code. - */ - n = 0; - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_find: type any; allrdatasets failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - /* - * Calling query_addrrset() with a non-NULL dbuf is going - * to either keep or release the name. We don't want it to - * release fname, since we may have to call query_addrrset() - * more than once. That means we have to call query_keepname() - * now, and pass a NULL dbuf to query_addrrset(). - * - * If we do a query_addrrset() below, we must set fname to - * NULL before leaving this block, otherwise we might try to - * cleanup fname even though we're using it! - */ - query_keepname(client, fname, dbuf); - tname = fname; - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, rdataset); -#ifdef ALLOW_FILTER_AAAA - /* - * Notice the presence of A and AAAAs so - * that AAAAs can be hidden from IPv4 clients. - */ - if (client->filter_aaaa != dns_aaaa_ok) { - if (rdataset->type == dns_rdatatype_aaaa) - have_aaaa = true; - else if (rdataset->type == dns_rdatatype_a) - have_a = true; - } -#endif - /* - * We found an NS RRset; no need to add one later. - */ - if (qtype == dns_rdatatype_any && - rdataset->type == dns_rdatatype_ns) - { - answer_has_ns = true; - } - - if (is_zone && qtype == dns_rdatatype_any && - !dns_db_issecure(db) && - dns_rdatatype_isdnssec(rdataset->type)) { - /* - * The zone is transitioning from insecure - * to secure. Hide the dnssec records from - * ANY queries. - */ - dns_rdataset_disassociate(rdataset); - } else if (client->view->minimal_any && - !TCP(client) && !WANTDNSSEC(client) && - qtype == dns_rdatatype_any && - (rdataset->type == dns_rdatatype_sig || - rdataset->type == dns_rdatatype_rrsig)) { - CTRACE(ISC_LOG_DEBUG(5), "query_find: " - "minimal-any skip signature"); - dns_rdataset_disassociate(rdataset); - } else if (client->view->minimal_any && - !TCP(client) && onetype != 0 && - rdataset->type != onetype && - rdataset->covers != onetype) { - CTRACE(ISC_LOG_DEBUG(5), "query_find: " - "minimal-any skip rdataset"); - dns_rdataset_disassociate(rdataset); - } else if ((qtype == dns_rdatatype_any || - rdataset->type == qtype) && rdataset->type != 0) { -#ifdef ALLOW_FILTER_AAAA - if (dns_rdatatype_isdnssec(rdataset->type)) - have_sig = true; -#endif - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - rpz_st = client->query.rpz_st; - if (rpz_st != NULL) - rdataset->ttl = ISC_MIN(rdataset->ttl, - rpz_st->m.ttl); - if (!is_zone && RECURSIONOK(client)) { - dns_name_t *name; - name = (fname != NULL) ? fname : tname; - query_prefetch(client, name, rdataset); - } - /* - * Remember the first RRtype we find so we - * can skip others with minimal-any. - */ - if (rdataset->type == dns_rdatatype_sig || - rdataset->type == dns_rdatatype_rrsig) - onetype = rdataset->covers; - else - onetype = rdataset->type; - query_addrrset(client, - fname != NULL ? &fname : &tname, - &rdataset, NULL, - NULL, DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - n++; - INSIST(tname != NULL); - /* - * rdataset is non-NULL only in certain - * pathological cases involving DNAMEs. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - rdataset = query_newrdataset(client); - if (rdataset == NULL) - break; - } else { - /* - * We're not interested in this rdataset. - */ - dns_rdataset_disassociate(rdataset); - } - result = dns_rdatasetiter_next(rdsiter); - } - -#ifdef ALLOW_FILTER_AAAA - /* - * Filter AAAAs if there is an A and there is no signature - * or we are supposed to break DNSSEC. - */ - if (client->filter_aaaa == dns_aaaa_break_dnssec) - client->attributes |= NS_CLIENTATTR_FILTER_AAAA; - else if (client->filter_aaaa != dns_aaaa_ok && - have_aaaa && have_a && - (!have_sig || !WANTDNSSEC(client))) - client->attributes |= NS_CLIENTATTR_FILTER_AAAA; -#endif - if (fname != NULL) - dns_message_puttempname(client->message, &fname); - - if (n == 0) { - /* - * No matching rdatasets found in cache. If we were - * searching for RRSIG/SIG, that's probably okay; - * otherwise this is an error condition. - */ - if ((qtype == dns_rdatatype_rrsig || - qtype == dns_rdatatype_sig) && - result == ISC_R_NOMORE) { - if (!is_zone) { - authoritative = false; - dns_rdatasetiter_destroy(&rdsiter); - client->attributes &= ~NS_CLIENTATTR_RA; - goto addauth; - } - - if (qtype == dns_rdatatype_rrsig && - dns_db_issecure(db)) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(client->query.qname, - namebuf, - sizeof(namebuf)); - ns_client_log(client, - DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "missing signature " - "for %s", namebuf); - } - - dns_rdatasetiter_destroy(&rdsiter); - fname = query_newname(client, dbuf, &b); - goto nxrrset_rrsig; - } else { - CTRACE(ISC_LOG_ERROR, - "query_find: no matching rdatasets " - "in cache"); - result = DNS_R_SERVFAIL; - } - } - - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_NOMORE) { - CTRACE(ISC_LOG_ERROR, - "query_find: dns_rdatasetiter_destroy failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } else { - /* - * This is the "normal" case -- an ordinary question to which - * we know the answer. - */ - - /* - * If we have a zero ttl from the cache refetch it. - */ - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && - RECURSIONOK(client)) - { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - // query_respond - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } - - /* - * Check to see if the AAAA RRset has non-excluded addresses - * in it. If not look for a A RRset. - * - * Note: the order of dns64_aaaaok() and filter_aaaa check is - * important. Both result is fetches being called but the - * dns64 case goes to db_find while the filter_aaaa case - * adds the records now for later potential exclusion. - */ - INSIST(client->query.dns64_aaaaok == NULL); - - if (qtype == dns_rdatatype_aaaa && !dns64_exclude && - !ISC_LIST_EMPTY(client->view->dns64) && - client->message->rdclass == dns_rdataclass_in && - !dns64_aaaaok(client, rdataset, sigrdataset)) { - /* - * Look to see if there are A records for this - * name. - */ - client->query.dns64_ttl = rdataset->ttl; - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64_exclude = dns64 = true; - goto db_find; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * Optionally hide AAAAs from IPv4 clients if there is an A. - * We add the AAAAs now, but might refuse to render them later - * after DNSSEC is figured out. - * This could be more efficient, but the whole idea is - * so fundamentally wrong, unavoidably inaccurate, and - * unneeded that it is best to keep it as short as possible. - */ - if (client->filter_aaaa == dns_aaaa_break_dnssec || - (client->filter_aaaa == dns_aaaa_filter && - (!WANTDNSSEC(client) || sigrdataset == NULL || - !dns_rdataset_isassociated(sigrdataset)))) - { - if (qtype == dns_rdatatype_aaaa) { - trdataset = query_newrdataset(client); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - trdataset, NULL); - if (dns_rdataset_isassociated(trdataset)) - dns_rdataset_disassociate(trdataset); - query_putrdataset(client, &trdataset); - - /* - * We have an AAAA but the A is not in our cache. - * Assume any result other than DNS_R_DELEGATION - * or ISC_R_NOTFOUND means there is no A and - * so AAAAs are ok. - * Assume there is no A if we can't recurse - * for this client, although that could be - * the wrong answer. What else can we do? - * Besides, that we have the AAAA and are using - * this mechanism suggests that we care more - * about As than AAAAs and would have cached - * the A if it existed. - */ - if (result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA; - - } else if (authoritative || - !RECURSIONOK(client) || - (result != DNS_R_DELEGATION && - result != ISC_R_NOTFOUND)) { - client->attributes &= - ~NS_CLIENTATTR_FILTER_AAAA; - } else { - /* - * This is an ugly kludge to recurse - * for the A and discard the result. - * - * Continue to add the AAAA now. - * We'll make a note to not render it - * if the recursion for the A succeeds. - */ - INSIST(!REDIRECT(client)); - result = query_recurse(client, - dns_rdatatype_a, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA_RC; - client->query.attributes |= - NS_QUERYATTR_RECURSING; - } - } - - } else if (qtype == dns_rdatatype_a && - (client->attributes & - NS_CLIENTATTR_FILTER_AAAA_RC) != 0) { - client->attributes &= - ~NS_CLIENTATTR_FILTER_AAAA_RC; - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA; - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - goto cleanup; - } - } -#endif - - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - /* - * Special case NS handling - */ - if (is_zone && qtype == dns_rdatatype_ns) { - /* - * We've already got an NS, no need to add one in - * the authority section - */ - if (dns_name_equal(client->query.qname, - dns_db_origin(db))) - { - answer_has_ns = true; - } - - /* - * Always add glue for root priming queries, regardless - * of "minimal-responses" setting. - */ - if (dns_name_equal(client->query.qname, dns_rootname)) { - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - dns_db_attach(db, &client->query.gluedb); - } - } - - /* - * Return the time to expire for slave and master zones. - */ - if (zone != NULL && is_zone && qtype == dns_rdatatype_soa && - (client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 && - client->query.restarts == 0) { - dns_zone_t *raw = NULL, *mayberaw; - - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - if (dns_zone_gettype(mayberaw) == dns_zone_slave) { - isc_time_t expiretime; - uint32_t secs; - dns_zone_getexpiretime(zone, &expiretime); - secs = isc_time_seconds(&expiretime); - if (secs >= client->now && - result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_HAVEEXPIRE; - client->expire = secs - client->now; - } - } - if (dns_zone_gettype(mayberaw) == dns_zone_master) { - dns_rdata_soa_t soa; - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - client->expire = soa.expire; - client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; - } - if (raw != NULL) - dns_zone_detach(&raw); - } - - if (dns64) { - qtype = type = dns_rdatatype_aaaa; - result = query_dns64(client, &fname, rdataset, - sigrdataset, dbuf, - DNS_SECTION_ANSWER); - noqname = NULL; - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, &rdataset); - if (result == ISC_R_NOMORE) { -#ifndef dns64_bis_return_excluded_addresses - if (dns64_exclude) { - if (!is_zone) - goto cleanup; - /* - * Add a fake SOA record. - */ - (void)query_addsoa(client, db, version, - 600, false, - DNS_SECTION_AUTHORITY); - goto cleanup; - } -#endif - if (is_zone) - goto iszone_nxrrset; - else - goto ncache_nxrrset; - } else if (result != ISC_R_SUCCESS) { - eresult = result; - goto cleanup; - } - } else if (client->query.dns64_aaaaok != NULL) { - query_filter64(client, &fname, rdataset, dbuf, - DNS_SECTION_ANSWER); - query_putrdataset(client, &rdataset); - } else { - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, - sigrdatasetp, dbuf, DNS_SECTION_ANSWER); - } - - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. - */ - INSIST(rdataset == NULL); - } - - addauth: - CTRACE(ISC_LOG_DEBUG(3), "query_find: addauth"); - /* - * Add NS records to the authority section (if we haven't already - * added them to the answer section). - */ - if (!want_restart && !NOAUTHORITY(client)) { - if (is_zone) { - if (!answer_has_ns) { - (void)query_addns(client, db, version); - } - } else if (!answer_has_ns && qtype != dns_rdatatype_ns) { - if (fname != NULL) { - query_releasename(client, &fname); - } - query_addbestns(client); - } - } - - /* - * Add NSEC records to the authority section if they're needed for - * DNSSEC wildcard proofs. - */ - if (need_wildcardproof && dns_db_issecure(db)) - query_addwildcardproof(client, db, version, - dns_fixedname_name(&wildcardname), - true, false); - cleanup: - // query_done - CTRACE(ISC_LOG_DEBUG(3), "query_find: cleanup"); - /* - * General cleanup. - */ - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) { - rpz_match_clear(rpz_st); - rpz_st->state &= ~DNS_RPZ_DONE_QNAME; - } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } - if (event != NULL) { - free_devent(client, ISC_EVENT_PTR(&event), &event); - } - - if (client->query.gluedb != NULL) { - dns_db_detach(&client->query.gluedb); - } - - /* - * AA bit. - */ - if (client->query.restarts == 0 && !authoritative) { - /* - * We're not authoritative, so we must ensure the AA bit - * isn't set. - */ - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - } - - /* - * Restart the query? - */ - if (want_restart && client->query.restarts < MAX_RESTARTS) { - client->query.restarts++; - goto restart; - } - - if (want_stale) { - dns_ttl_t stale_ttl = 0; - isc_result_t result; - bool staleanswersok = false; - - /* - * Stale answers only make sense if stale_ttl > 0 but - * we want rndc to be able to control returning stale - * answers if they are configured. - */ - dns_db_attach(client->view->cachedb, &db); - result = dns_db_getservestalettl(db, &stale_ttl); - if (result == ISC_R_SUCCESS && stale_ttl > 0) { - switch (client->view->staleanswersok) { - case dns_stale_answer_yes: - staleanswersok = true; - break; - case dns_stale_answer_conf: - staleanswersok = - client->view->staleanswersenable; - break; - case dns_stale_answer_no: - staleanswersok = false; - break; - } - } else { - staleanswersok = false; - } - - if (staleanswersok) { - client->query.dboptions |= DNS_DBFIND_STALEOK; - inc_stats(client, dns_nsstatscounter_trystale); - if (client->query.fetch != NULL) - dns_resolver_destroyfetch( - &client->query.fetch); - goto db_find; - } - dns_db_detach(&db); - want_stale = false; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - if (eresult != ISC_R_SUCCESS && - (!PARTIALANSWER(client) || WANTRECURSION(client) - || eresult == DNS_R_DROP)) { - if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) { - /* - * This was a duplicate query that we are - * recursing on or the result of rate limiting. - * Don't send a response now for a duplicate query, - * because the original will still cause a response. - */ - query_next(client, eresult); - } else { - /* - * If we don't have any answer to give the client, - * or if the client requested recursion and thus wanted - * the complete answer, send an error response. - */ - INSIST(line >= 0); - query_error(client, eresult, line); - } - ns_client_detach(&client); - } else if (!RECURSING(client)) { - /* - * We are done. Set up sortlist data for the message - * rendering code, make a final tweak to the AA bit if the - * auth-nxdomain config option says so, then render and - * send the response. - */ - setup_query_sortlist(client); - - /* - * If this is a referral and the answer to the question - * is in the glue sort it to the start of the additional - * section. - */ - if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) && - client->message->rcode == dns_rcode_noerror && - (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa)) - answer_in_glue(client, qtype); - - if (client->message->rcode == dns_rcode_nxdomain && - client->view->auth_nxdomain == true) - client->message->flags |= DNS_MESSAGEFLAG_AA; - - /* - * If the response is somehow unexpected for the client and this - * is a result of recursion, return an error to the caller - * to indicate it may need to be logged. - */ - if (resuming && - (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) || - client->message->rcode != dns_rcode_noerror)) - eresult = ISC_R_FAILURE; - - query_send(client); - ns_client_detach(&client); - } - CTRACE(ISC_LOG_DEBUG(3), "query_find: done"); - - return (eresult); -} - -static inline void -log_tat(ns_client_t *client) { - char namebuf[DNS_NAME_FORMATSIZE]; - char clientbuf[ISC_NETADDR_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - isc_netaddr_t netaddr; - char *tags = NULL; - size_t taglen = 0; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_INFO)) { - return; - } - - if ((client->query.qtype != dns_rdatatype_null || - !dns_name_istat(client->query.qname)) && - (client->keytag == NULL || - client->query.qtype != dns_rdatatype_dnskey)) - { - return; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - isc_netaddr_format(&netaddr, clientbuf, sizeof(clientbuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - if (client->query.qtype == dns_rdatatype_dnskey) { - uint16_t keytags = client->keytag_len / 2; - size_t len = taglen = sizeof("65000") * keytags + 1; - char *cp = tags = isc_mem_get(client->mctx, taglen); - int i = 0; - - INSIST(client->keytag != NULL); - if (tags != NULL) { - while (keytags-- > 0U) { - int n; - uint16_t keytag; - keytag = (client->keytag[i * 2] << 8) | - client->keytag[i * 2 + 1]; - n = snprintf(cp, len, " %u", keytag); - if (n > 0 && (size_t)n <= len) { - cp += n; - len -= n; - i++; - } else { - break; - } - } - } - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY, - ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s", - namebuf, classbuf, clientbuf, tags != NULL? tags : ""); - if (tags != NULL) { - isc_mem_put(client->mctx, tags, taglen); - } -} - -static inline void -log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - char onbuf[ISC_NETADDR_FORMATSIZE]; - char ednsbuf[sizeof("E(65535)")] = { 0 }; - dns_rdataset_t *rdataset; - int level = ISC_LOG_INFO; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf)); - - if (client->ednsversion >= 0) - snprintf(ednsbuf, sizeof(ednsbuf), "E(%hd)", - client->ednsversion); - - ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, - level, "query: %s %s %s %s%s%s%s%s%s%s (%s)", namebuf, - classbuf, typebuf, WANTRECURSION(client) ? "+" : "-", - (client->signer != NULL) ? "S" : "", ednsbuf, - TCP(client) ? "T" : "", - ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "", - ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "", - HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "", - onbuf); -} - -static inline void -log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - const char *namep, *typep, *classp, *sep1, *sep2; - dns_rdataset_t *rdataset; - - if (!isc_log_wouldlog(ns_g_lctx, level)) - return; - - namep = typep = classp = sep1 = sep2 = ""; - - /* - * Query errors can happen for various reasons. In some cases we cannot - * even assume the query contains a valid question section, so we should - * expect exceptional cases. - */ - if (client->query.origqname != NULL) { - dns_name_format(client->query.origqname, namebuf, - sizeof(namebuf)); - namep = namebuf; - sep1 = " for "; - - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - if (rdataset != NULL) { - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - classp = classbuf; - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - typep = typebuf; - sep2 = "/"; - } - } - - ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY, - level, "query failed (%s)%s%s%s%s%s%s at %s:%d", - isc_result_totext(result), sep1, namep, sep2, - classp, sep2, typep, __FILE__, line); -} - -void -ns_query_start(ns_client_t *client) { - isc_result_t result; - dns_message_t *message; - dns_rdataset_t *rdataset; - ns_client_t *qclient; - dns_rdatatype_t qtype; - unsigned int saved_extflags; - unsigned int saved_flags; - - REQUIRE(NS_CLIENT_VALID(client)); - - message = client->message; - saved_extflags = client->extflags; - saved_flags = client->message->flags; - - CTRACE(ISC_LOG_DEBUG(3), "ns_query_start"); - - /* - * Test only. - */ - if (ns_g_clienttest && !TCP(client)) { - result = ns_client_replace(client); - if (result == ISC_R_SHUTTINGDOWN) { - ns_client_next(client, result); - return; - } else if (result != ISC_R_SUCCESS) { - query_error(client, result, __LINE__); - return; - } - } - - /* - * Ensure that appropriate cleanups occur. - */ - client->next = query_next_callback; - - /* - * Behave as if we don't support DNSSEC if not enabled. - */ - if (!client->view->enablednssec) { - message->flags &= ~DNS_MESSAGEFLAG_CD; - client->extflags &= ~DNS_MESSAGEEXTFLAG_DO; - } - - if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) - client->query.attributes |= NS_QUERYATTR_WANTRECURSION; - - if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) - client->attributes |= NS_CLIENTATTR_WANTDNSSEC; - - switch (client->view->minimalresponses) { - case dns_minimal_no: - break; - case dns_minimal_yes: - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - break; - case dns_minimal_noauth: - client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; - break; - case dns_minimal_noauthrec: - if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) - client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; - break; - } - - if ((client->view->cachedb == NULL) - || (!client->view->additionalfromcache)) { - /* - * We don't have a cache. Turn off cache support and - * recursion. - */ - client->query.attributes &= - ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); - client->attributes |= NS_CLIENTATTR_NOSETFC; - } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || - (message->flags & DNS_MESSAGEFLAG_RD) == 0) { - /* - * If the client isn't allowed to recurse (due to - * "recursion no", the allow-recursion ACL, or the - * lack of a resolver in this view), or if it - * doesn't want recursion, turn recursion off. - */ - client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; - client->attributes |= NS_CLIENTATTR_NOSETFC; - } - - /* - * Check for multiple question queries, since edns1 is dead. - */ - if (message->counts[DNS_SECTION_QUESTION] > 1) { - query_error(client, DNS_R_FORMERR, __LINE__); - return; - } - - /* - * Get the question name. - */ - result = dns_message_firstname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - query_error(client, result, __LINE__); - return; - } - dns_message_currentname(message, DNS_SECTION_QUESTION, - &client->query.qname); - client->query.origqname = client->query.qname; - result = dns_message_nextname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) { - if (result == ISC_R_SUCCESS) { - /* - * There's more than one QNAME in the question - * section. - */ - query_error(client, DNS_R_FORMERR, __LINE__); - } else - query_error(client, result, __LINE__); - return; - } - - if (ns_g_server->log_queries) - log_query(client, saved_flags, saved_extflags); - - /* - * Check for meta-queries like IXFR and AXFR. - */ - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - client->query.qtype = qtype = rdataset->type; - dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype); - - log_tat(client); - - if (dns_rdatatype_ismeta(qtype)) { - switch (qtype) { - case dns_rdatatype_any: - break; /* Let query_find handle it. */ - case dns_rdatatype_ixfr: - case dns_rdatatype_axfr: - ns_xfr_start(client, rdataset->type); - return; - case dns_rdatatype_maila: - case dns_rdatatype_mailb: - query_error(client, DNS_R_NOTIMP, __LINE__); - return; - case dns_rdatatype_tkey: - result = dns_tkey_processquery(client->message, - ns_g_server->tkeyctx, - client->view->dynamickeys); - if (result == ISC_R_SUCCESS) - query_send(client); - else - query_error(client, result, __LINE__); - return; - default: /* TSIG, etc. */ - query_error(client, DNS_R_FORMERR, __LINE__); - return; - } - } - - /* - * Turn on minimal response for (C)DNSKEY and (C)DS queries. - */ - if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds || - qtype == dns_rdatatype_cdnskey || qtype == dns_rdatatype_cds) - { - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - } else if (qtype == dns_rdatatype_ns) { - /* - * Always turn on additional records for NS queries. - */ - client->query.attributes &= ~(NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - } - - /* - * Maybe turn on minimal responses for ANY queries. - */ - if (qtype == dns_rdatatype_any && - client->view->minimal_any && !TCP(client)) - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - /* - * Turn on minimal responses for EDNS/UDP bufsize 512 queries. - */ - if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client)) - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - /* - * If the client has requested that DNSSEC checking be disabled, - * allow lookups to return pending data and instruct the resolver - * to return data before validation has completed. - * - * We don't need to set DNS_DBFIND_PENDINGOK when validation is - * disabled as there will be no pending data. - */ - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0 || - qtype == dns_rdatatype_rrsig) - { - client->query.dboptions |= DNS_DBFIND_PENDINGOK; - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - } else if (!client->view->enablevalidation) - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - - /* - * Allow glue NS records to be added to the authority section - * if the answer is secure. - */ - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) { - client->query.attributes &= ~NS_QUERYATTR_SECURE; - } - - /* - * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query. - * This allows AD to be returned on queries without DO set. - */ - if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) - client->attributes |= NS_CLIENTATTR_WANTAD; - - /* - * This is an ordinary query. - */ - result = dns_message_reply(message, true); - if (result != ISC_R_SUCCESS) { - query_next(client, result); - return; - } - - /* - * Assume authoritative response until it is known to be - * otherwise. - * - * If "-T noaa" has been set on the command line don't set - * AA on authoritative answers. - */ - if (!ns_g_noaa) - message->flags |= DNS_MESSAGEFLAG_AA; - - /* - * Set AD. We must clear it if we add non-validated data to a - * response. - */ - if (WANTDNSSEC(client) || WANTAD(client)) - message->flags |= DNS_MESSAGEFLAG_AD; - - qclient = NULL; - ns_client_attach(client, &qclient); - (void)query_find(qclient, NULL, qtype); -} diff --git a/bin/named-pkcs11/server.c b/bin/named-pkcs11/server.c deleted file mode 100644 index 3a5ba91..0000000 --- a/bin/named-pkcs11/server.c +++ /dev/null @@ -1,14734 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -#include -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#include -#endif - -#ifdef HAVE_LMDB -#include -#define count_newzones count_newzones_db -#define configure_newzones configure_newzones_db -#define dumpzone dumpzone_db -#else /* HAVE_LMDB */ -#define count_newzones count_newzones_file -#define configure_newzones configure_newzones_file -#define dumpzone dumpzone_file -#endif /* HAVE_LMDB */ - -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)-1) -#endif - -#ifndef SIZE_AS_PERCENT -#define SIZE_AS_PERCENT ((size_t)-2) -#endif - -#ifdef TUNE_LARGE -#define RESOLVER_NTASKS 523 -#define UDPBUFFERS 32768 -#define EXCLBUFFERS 32768 -#else -#define RESOLVER_NTASKS 31 -#define UDPBUFFERS 1000 -#define EXCLBUFFERS 4096 -#endif /* TUNE_LARGE */ - -/*% - * Check an operation for failure. Assumes that the function - * using it has a 'result' variable and a 'cleanup' label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -#define TCHECK(op) \ - do { tresult = (op); \ - if (tresult != ISC_R_SUCCESS) { \ - isc_buffer_clear(*text); \ - goto cleanup; \ - } \ - } while (0) - -#define CHECKM(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s: %s", msg, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKMF(op, msg, file) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s '%s': %s", msg, file, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKFATAL(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) \ - fatal(server, msg, result); \ - } while (0) \ - -/*% - * Maximum ADB size for views that share a cache. Use this limit to suppress - * the total of memory footprint, which should be the main reason for sharing - * a cache. Only effective when a finite max-cache-size is specified. - * This is currently defined to be 8MB. - */ -#define MAX_ADB_SIZE_FOR_CACHESHARE 8388608U - -struct ns_dispatch { - isc_sockaddr_t addr; - unsigned int dispatchgen; - dns_dispatch_t *dispatch; - ISC_LINK(struct ns_dispatch) link; -}; - -struct ns_cache { - dns_cache_t *cache; - dns_view_t *primaryview; - bool needflush; - bool adbsizeadjusted; - dns_rdataclass_t rdclass; - ISC_LINK(ns_cache_t) link; -}; - -struct dumpcontext { - isc_mem_t *mctx; - bool dumpcache; - bool dumpzones; - bool dumpadb; - bool dumpbad; - bool dumpfail; - FILE *fp; - ISC_LIST(struct viewlistentry) viewlist; - struct viewlistentry *view; - struct zonelistentry *zone; - dns_dumpctx_t *mdctx; - dns_db_t *db; - dns_db_t *cache; - isc_task_t *task; - dns_dbversion_t *version; -}; - -struct viewlistentry { - dns_view_t *view; - ISC_LINK(struct viewlistentry) link; - ISC_LIST(struct zonelistentry) zonelist; -}; - -struct zonelistentry { - dns_zone_t *zone; - ISC_LINK(struct zonelistentry) link; -}; - -/*% - * Configuration context to retain for each view that allows - * new zones to be added at runtime. - */ -typedef struct ns_cfgctx { - isc_mem_t * mctx; - cfg_parser_t * conf_parser; - cfg_parser_t * add_parser; - cfg_obj_t * config; - cfg_obj_t * vconfig; - cfg_obj_t * nzf_config; - cfg_aclconfctx_t * actx; -} ns_cfgctx_t; - -/*% - * A function to write out added-zone configuration to the new_zone_file - * specified in 'view'. Maybe called by delete_zoneconf(). - */ -typedef isc_result_t (*nzfwriter_t)(const cfg_obj_t *config, dns_view_t *view); - -/*% - * Holds state information for the initial zone loading process. - * Uses the isc_refcount structure to count the number of views - * with pending zone loads, dereferencing as each view finishes. - */ -typedef struct { - ns_server_t *server; - bool reconfig; - isc_refcount_t refs; -} ns_zoneload_t; - -typedef struct { - ns_server_t *server; -} catz_cb_data_t; - -typedef struct catz_chgzone_event { - ISC_EVENT_COMMON(struct catz_chgzone_event); - dns_catz_entry_t *entry; - dns_catz_zone_t *origin; - dns_view_t *view; - catz_cb_data_t *cbd; - bool mod; -} catz_chgzone_event_t; - -typedef struct { - unsigned int magic; -#define DZARG_MAGIC ISC_MAGIC('D', 'z', 'a', 'r') - isc_buffer_t **text; - isc_result_t result; -} ns_dzarg_t; - -/* - * These zones should not leak onto the Internet. - */ -const char *empty_zones[] = { - /* RFC 1918 */ - "10.IN-ADDR.ARPA", - "16.172.IN-ADDR.ARPA", - "17.172.IN-ADDR.ARPA", - "18.172.IN-ADDR.ARPA", - "19.172.IN-ADDR.ARPA", - "20.172.IN-ADDR.ARPA", - "21.172.IN-ADDR.ARPA", - "22.172.IN-ADDR.ARPA", - "23.172.IN-ADDR.ARPA", - "24.172.IN-ADDR.ARPA", - "25.172.IN-ADDR.ARPA", - "26.172.IN-ADDR.ARPA", - "27.172.IN-ADDR.ARPA", - "28.172.IN-ADDR.ARPA", - "29.172.IN-ADDR.ARPA", - "30.172.IN-ADDR.ARPA", - "31.172.IN-ADDR.ARPA", - "168.192.IN-ADDR.ARPA", - - /* RFC 6598 */ - "64.100.IN-ADDR.ARPA", - "65.100.IN-ADDR.ARPA", - "66.100.IN-ADDR.ARPA", - "67.100.IN-ADDR.ARPA", - "68.100.IN-ADDR.ARPA", - "69.100.IN-ADDR.ARPA", - "70.100.IN-ADDR.ARPA", - "71.100.IN-ADDR.ARPA", - "72.100.IN-ADDR.ARPA", - "73.100.IN-ADDR.ARPA", - "74.100.IN-ADDR.ARPA", - "75.100.IN-ADDR.ARPA", - "76.100.IN-ADDR.ARPA", - "77.100.IN-ADDR.ARPA", - "78.100.IN-ADDR.ARPA", - "79.100.IN-ADDR.ARPA", - "80.100.IN-ADDR.ARPA", - "81.100.IN-ADDR.ARPA", - "82.100.IN-ADDR.ARPA", - "83.100.IN-ADDR.ARPA", - "84.100.IN-ADDR.ARPA", - "85.100.IN-ADDR.ARPA", - "86.100.IN-ADDR.ARPA", - "87.100.IN-ADDR.ARPA", - "88.100.IN-ADDR.ARPA", - "89.100.IN-ADDR.ARPA", - "90.100.IN-ADDR.ARPA", - "91.100.IN-ADDR.ARPA", - "92.100.IN-ADDR.ARPA", - "93.100.IN-ADDR.ARPA", - "94.100.IN-ADDR.ARPA", - "95.100.IN-ADDR.ARPA", - "96.100.IN-ADDR.ARPA", - "97.100.IN-ADDR.ARPA", - "98.100.IN-ADDR.ARPA", - "99.100.IN-ADDR.ARPA", - "100.100.IN-ADDR.ARPA", - "101.100.IN-ADDR.ARPA", - "102.100.IN-ADDR.ARPA", - "103.100.IN-ADDR.ARPA", - "104.100.IN-ADDR.ARPA", - "105.100.IN-ADDR.ARPA", - "106.100.IN-ADDR.ARPA", - "107.100.IN-ADDR.ARPA", - "108.100.IN-ADDR.ARPA", - "109.100.IN-ADDR.ARPA", - "110.100.IN-ADDR.ARPA", - "111.100.IN-ADDR.ARPA", - "112.100.IN-ADDR.ARPA", - "113.100.IN-ADDR.ARPA", - "114.100.IN-ADDR.ARPA", - "115.100.IN-ADDR.ARPA", - "116.100.IN-ADDR.ARPA", - "117.100.IN-ADDR.ARPA", - "118.100.IN-ADDR.ARPA", - "119.100.IN-ADDR.ARPA", - "120.100.IN-ADDR.ARPA", - "121.100.IN-ADDR.ARPA", - "122.100.IN-ADDR.ARPA", - "123.100.IN-ADDR.ARPA", - "124.100.IN-ADDR.ARPA", - "125.100.IN-ADDR.ARPA", - "126.100.IN-ADDR.ARPA", - "127.100.IN-ADDR.ARPA", - - /* RFC 5735 and RFC 5737 */ - "0.IN-ADDR.ARPA", /* THIS NETWORK */ - "127.IN-ADDR.ARPA", /* LOOPBACK */ - "254.169.IN-ADDR.ARPA", /* LINK LOCAL */ - "2.0.192.IN-ADDR.ARPA", /* TEST NET */ - "100.51.198.IN-ADDR.ARPA", /* TEST NET 2 */ - "113.0.203.IN-ADDR.ARPA", /* TEST NET 3 */ - "255.255.255.255.IN-ADDR.ARPA", /* BROADCAST */ - - /* Local IPv6 Unicast Addresses */ - "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", - "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", - /* LOCALLY ASSIGNED LOCAL ADDRESS SCOPE */ - "D.F.IP6.ARPA", - "8.E.F.IP6.ARPA", /* LINK LOCAL */ - "9.E.F.IP6.ARPA", /* LINK LOCAL */ - "A.E.F.IP6.ARPA", /* LINK LOCAL */ - "B.E.F.IP6.ARPA", /* LINK LOCAL */ - - /* Example Prefix, RFC 3849. */ - "8.B.D.0.1.0.0.2.IP6.ARPA", - - /* RFC 7534 */ - "EMPTY.AS112.ARPA", - - /* RFC 8375 */ - "HOME.ARPA", - - NULL -}; - -ISC_PLATFORM_NORETURN_PRE static void -fatal(ns_server_t *server,const char *msg, isc_result_t result) -ISC_PLATFORM_NORETURN_POST; - -static void -ns_server_reload(isc_task_t *task, isc_event_t *event); - -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenelt_t **target); -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenlist_t **target); - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype); - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates); - -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf, - bool added, bool old_rpz_ok, - bool modify); - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx); - -static isc_result_t -add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx); - -static void -end_reserved_dispatches(ns_server_t *server, bool all); - -static void -newzone_cfgctx_destroy(void **cfgp); - -static inline isc_result_t -putstr(isc_buffer_t **b, const char *str); - -static isc_result_t -putmem(isc_buffer_t **b, const char *str, size_t len); - -static isc_result_t -putuint8(isc_buffer_t **b, uint8_t val); - -static inline isc_result_t -putnull(isc_buffer_t **b); - -static int -count_zones(const cfg_obj_t *conf); - -#ifdef HAVE_LMDB -static isc_result_t -migrate_nzf(dns_view_t *view); - -static isc_result_t -nzd_writable(dns_view_t *view); - -static isc_result_t -nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi); - -static isc_result_t -nzd_env_reopen(dns_view_t *view); - -static void -nzd_env_close(dns_view_t *view); - -static isc_result_t -nzd_close(MDB_txn **txnp, bool commit); - -static isc_result_t -nzd_count(dns_view_t *view, int *countp); -#else -static isc_result_t -nzf_append(dns_view_t *view, const cfg_obj_t *zconfig); -#endif - -/*% - * Configure a single view ACL at '*aclp'. Get its configuration from - * 'vconfig' (for per-view configuration) and maybe from 'config' - */ -static isc_result_t -configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config, - const cfg_obj_t *gconfig, const char *aclname, - const char *acltuplename, cfg_aclconfctx_t *actx, - isc_mem_t *mctx, dns_acl_t **aclp) -{ - isc_result_t result; - const cfg_obj_t *maps[4]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) { - dns_acl_detach(aclp); - } - if (vconfig != NULL) { - maps[i++] = cfg_tuple_get(vconfig, "options"); - } - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - if (gconfig != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(gconfig, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - maps[i] = NULL; - - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - /* - * No value available. *aclp == NULL. - */ - return (ISC_R_SUCCESS); - } - - if (acltuplename != NULL) { - /* - * If the ACL is given in an optional tuple, retrieve it. - * The parser should have ensured that a valid object be - * returned. - */ - aclobj = cfg_tuple_get(aclobj, acltuplename); - } - - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, - actx, mctx, 0, aclp); - - return (result); -} - -/*% - * Configure a sortlist at '*aclp'. Essentially the same as - * configure_view_acl() except it calls cfg_acl_fromconfig with a - * nest_level value of 2. - */ -static isc_result_t -configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - dns_acl_t **aclp) -{ - isc_result_t result; - const cfg_obj_t *maps[3]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) - dns_acl_detach(aclp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - (void)ns_config_get(maps, "sortlist", &aclobj); - if (aclobj == NULL) - return (ISC_R_SUCCESS); - - /* - * Use a nest level of 3 for the "top level" of the sortlist; - * this means each entry in the top three levels will be stored - * as lists of separate, nested ACLs, rather than merged together - * into IP tables as is usually done with ACLs. - */ - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, - actx, mctx, 3, aclp); - - return (result); -} - -static isc_result_t -configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, - const char *confname, const char *conftuplename, - isc_mem_t *mctx, dns_rbt_t **rbtp) -{ - isc_result_t result; - const cfg_obj_t *maps[3]; - const cfg_obj_t *obj = NULL; - const cfg_listelt_t *element; - int i = 0; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - const char *str; - const cfg_obj_t *nameobj; - - if (*rbtp != NULL) - dns_rbt_destroy(rbtp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - (void)ns_config_get(maps, confname, &obj); - if (obj == NULL) - /* - * No value available. *rbtp == NULL. - */ - return (ISC_R_SUCCESS); - - if (conftuplename != NULL) { - obj = cfg_tuple_get(obj, conftuplename); - if (cfg_obj_isvoid(obj)) - return (ISC_R_SUCCESS); - } - - result = dns_rbt_create(mctx, NULL, NULL, rbtp); - if (result != ISC_R_SUCCESS) - return (result); - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) { - nameobj = cfg_listelt_value(element); - str = cfg_obj_asstring(nameobj); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - /* - * We don't need the node data, but need to set dummy data to - * avoid a partial match with an empty node. For example, if - * we have foo.example.com and bar.example.com, we'd get a match - * for baz.example.com, which is not the expected result. - * We simply use (void *)1 as the dummy data. - */ - result = dns_rbt_addname(*rbtp, name, (void *)1); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR, - "failed to add %s for %s: %s", - str, confname, isc_result_totext(result)); - goto cleanup; - } - - } - - return (result); - - cleanup: - dns_rbt_destroy(rbtp); - return (result); - -} - -static isc_result_t -dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, - bool managed, dst_key_t **target, isc_mem_t *mctx) -{ - dns_rdataclass_t viewclass; - dns_rdata_dnskey_t keystruct; - uint32_t flags, proto, alg; - const char *keystr, *keynamestr; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; - unsigned char rrdata[4096]; - isc_buffer_t rrdatabuf; - isc_region_t r; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - isc_buffer_t namebuf; - isc_result_t result; - dst_key_t *dstkey = NULL; - - INSIST(target != NULL && *target == NULL); - - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); - keyname = dns_fixedname_name(&fkeyname); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - - if (managed) { - const char *initmethod; - initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init")); - - if (strcasecmp(initmethod, "initial-key") != 0) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "managed key '%s': " - "invalid initialization method '%s'", - keynamestr, initmethod); - result = ISC_R_FAILURE; - goto cleanup; - } - } - - if (vconfig == NULL) - viewclass = dns_rdataclass_in; - else { - const cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - } - keystruct.common.rdclass = viewclass; - keystruct.common.rdtype = dns_rdatatype_dnskey; - /* - * The key data in keystruct is not dynamically allocated. - */ - keystruct.mctx = NULL; - - ISC_LINK_INIT(&keystruct.common, link); - - if (flags > 0xffff) - CHECKM(ISC_R_RANGE, "key flags"); - if (proto > 0xff) - CHECKM(ISC_R_RANGE, "key protocol"); - if (alg > 0xff) - CHECKM(ISC_R_RANGE, "key algorithm"); - keystruct.flags = (uint16_t)flags; - keystruct.protocol = (uint8_t)proto; - keystruct.algorithm = (uint8_t)alg; - - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - CHECK(isc_base64_decodestring(keystr, &keydatabuf)); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; - - if ((keystruct.algorithm == DST_ALG_RSASHA1 || - keystruct.algorithm == DST_ALG_RSAMD5) && - r.length > 1 && r.base[0] == 1 && r.base[1] == 3) - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "%s key '%s' has a weak exponent", - managed ? "managed" : "trusted", - keynamestr); - - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf)); - dns_fixedname_init(&fkeyname); - isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL)); - CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, - mctx, &dstkey)); - - *target = dstkey; - return (ISC_R_SUCCESS); - - cleanup: - if (result == DST_R_NOCRYPTO) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "ignoring %s key for '%s': no crypto support", - managed ? "managed" : "trusted", - keynamestr); - } else if (result == DST_R_UNSUPPORTEDALG) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "skipping %s key for '%s': %s", - managed ? "managed" : "trusted", - keynamestr, isc_result_totext(result)); - } else { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring %s key for '%s': %s", - managed ? "managed" : "trusted", - keynamestr, isc_result_totext(result)); - result = ISC_R_FAILURE; - } - - if (dstkey != NULL) - dst_key_free(&dstkey); - - return (result); -} - -static isc_result_t -load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig, - dns_view_t *view, bool managed, - dns_name_t *keyname, isc_mem_t *mctx) -{ - const cfg_listelt_t *elt, *elt2; - const cfg_obj_t *key, *keylist; - dst_key_t *dstkey = NULL; - isc_result_t result; - dns_keytable_t *secroots = NULL; - - CHECK(dns_view_getsecroots(view, &secroots)); - - for (elt = cfg_list_first(keys); - elt != NULL; - elt = cfg_list_next(elt)) { - keylist = cfg_listelt_value(elt); - - for (elt2 = cfg_list_first(keylist); - elt2 != NULL; - elt2 = cfg_list_next(elt2)) { - key = cfg_listelt_value(elt2); - result = dstkey_fromconfig(vconfig, key, managed, - &dstkey, mctx); - if (result == DST_R_UNSUPPORTEDALG) { - result = ISC_R_SUCCESS; - continue; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * If keyname was specified, we only add that key. - */ - if (keyname != NULL && - !dns_name_equal(keyname, dst_key_name(dstkey))) - { - dst_key_free(&dstkey); - continue; - } - - CHECK(dns_keytable_add(secroots, managed, &dstkey)); - } - } - - cleanup: - if (dstkey != NULL) - dst_key_free(&dstkey); - if (secroots != NULL) - dns_keytable_detach(&secroots); - if (result == DST_R_NOCRYPTO) - result = ISC_R_SUCCESS; - return (result); -} - -/*% - * Check whether a key has been successfully loaded. - */ -static bool -keyloaded(dns_view_t *view, dns_name_t *name) { - isc_result_t result; - dns_keytable_t *secroots = NULL; - dns_keynode_t *keynode = NULL; - - result = dns_view_getsecroots(view, &secroots); - if (result != ISC_R_SUCCESS) - return (false); - - result = dns_keytable_find(secroots, name, &keynode); - - if (keynode != NULL) - dns_keytable_detachkeynode(secroots, &keynode); - if (secroots != NULL) - dns_keytable_detach(&secroots); - - return (result == ISC_R_SUCCESS); -} - -/*% - * Configure DNSSEC keys for a view. - * - * The per-view configuration values and the server-global defaults are read - * from 'vconfig' and 'config'. - */ -static isc_result_t -configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig, - const cfg_obj_t *config, const cfg_obj_t *bindkeys, - bool auto_root, isc_mem_t *mctx) -{ - isc_result_t result = ISC_R_SUCCESS; - const cfg_obj_t *view_keys = NULL; - const cfg_obj_t *global_keys = NULL; - const cfg_obj_t *view_managed_keys = NULL; - const cfg_obj_t *global_managed_keys = NULL; - const cfg_obj_t *maps[4]; - const cfg_obj_t *voptions = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *obj = NULL; - const char *directory; - bool need_mkey_dir = false; - int i = 0; - - /* We don't need trust anchors for the _bind view */ - if (strcmp(view->name, "_bind") == 0 && - view->rdclass == dns_rdataclass_chaos) - { - return (ISC_R_SUCCESS); - } - - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - if (voptions != NULL) { - (void) cfg_map_get(voptions, "trusted-keys", - &view_keys); - (void) cfg_map_get(voptions, "managed-keys", - &view_managed_keys); - maps[i++] = voptions; - } - } - - if (config != NULL) { - (void)cfg_map_get(config, "trusted-keys", &global_keys); - (void)cfg_map_get(config, "managed-keys", &global_managed_keys); - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = dns_view_initsecroots(view, mctx); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "couldn't create keytable"); - return (ISC_R_UNEXPECTED); - } - - result = dns_view_initntatable(view, ns_g_taskmgr, ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "couldn't create NTA table"); - return (ISC_R_UNEXPECTED); - } - - if (auto_root && view->rdclass == dns_rdataclass_in) { - const cfg_obj_t *builtin_keys = NULL; - const cfg_obj_t *builtin_managed_keys = NULL; - - /* - * If bind.keys exists and is populated, it overrides - * the managed-keys clause hard-coded in ns_g_config. - */ - if (bindkeys != NULL) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "obtaining root key for view %s " - "from '%s'", - view->name, ns_g_server->bindkeysfile); - - (void)cfg_map_get(bindkeys, "trusted-keys", - &builtin_keys); - (void)cfg_map_get(bindkeys, "managed-keys", - &builtin_managed_keys); - - if ((builtin_keys == NULL) && - (builtin_managed_keys == NULL)) - isc_log_write(ns_g_lctx, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "dnssec-validation auto: " - "WARNING: root zone key " - "not found"); - } - - if ((builtin_keys == NULL) && - (builtin_managed_keys == NULL)) - { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using built-in root key for view %s", - view->name); - - (void)cfg_map_get(ns_g_config, "trusted-keys", - &builtin_keys); - (void)cfg_map_get(ns_g_config, "managed-keys", - &builtin_managed_keys); - } - - if (builtin_keys != NULL) - CHECK(load_view_keys(builtin_keys, vconfig, view, - false, dns_rootname, mctx)); - if (builtin_managed_keys != NULL) - CHECK(load_view_keys(builtin_managed_keys, vconfig, - view, true, dns_rootname, - mctx)); - - if (!keyloaded(view, dns_rootname)) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "root key not loaded"); - result = ISC_R_FAILURE; - goto cleanup; - } - } - - CHECK(load_view_keys(view_keys, vconfig, view, false, - NULL, mctx)); - CHECK(load_view_keys(view_managed_keys, vconfig, view, true, - NULL, mctx)); - - if (view->rdclass == dns_rdataclass_in) { - CHECK(load_view_keys(global_keys, vconfig, view, false, - NULL, mctx)); - CHECK(load_view_keys(global_managed_keys, vconfig, view, - true, NULL, mctx)); - } - - /* - * Add key zone for managed-keys. - */ - need_mkey_dir = (auto_root || view_managed_keys != NULL); - - obj = NULL; - (void)ns_config_get(maps, "managed-keys-directory", &obj); - directory = (obj != NULL ? cfg_obj_asstring(obj) : NULL); - if (directory != NULL) { - result = isc_file_isdirectory(directory); - } - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "invalid managed-keys-directory %s: %s", - directory, isc_result_totext(result)); - goto cleanup; - - } else if (need_mkey_dir && directory != NULL) { - if (!isc_file_isdirwritable(directory)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "managed-keys-directory '%s' " - "is not writable", directory); - result = ISC_R_NOPERM; - goto cleanup; - } - } else if (need_mkey_dir) { - char cwd[PATH_MAX]; - - if (getcwd(cwd, sizeof(cwd)) == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to retrieve " - "current working directory"); - result = ISC_R_FAILURE; - goto cleanup; - } - - if (!isc_file_isdirwritable(cwd)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "working directory '%s' " - "is not writable", cwd); - result = ISC_R_NOPERM; - goto cleanup; - } - } - - CHECK(add_keydata_zone(view, directory, ns_g_mctx)); - - cleanup: - return (result); -} - -static isc_result_t -mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) { - const cfg_listelt_t *element; - const cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - bool value; - isc_result_t result; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(mbs); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - value = cfg_obj_asboolean(cfg_tuple_get(obj, "value")); - CHECK(dns_resolver_setmustbesecure(resolver, name, value)); - } - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -/*% - * Get a dispatch appropriate for the resolver of a given view. - */ -static isc_result_t -get_view_querysource_dispatch(const cfg_obj_t **maps, int af, - dns_dispatch_t **dispatchp, isc_dscp_t *dscpp, - bool is_firstview) -{ - isc_result_t result = ISC_R_FAILURE; - dns_dispatch_t *disp; - isc_sockaddr_t sa; - unsigned int attrs, attrmask; - const cfg_obj_t *obj = NULL; - unsigned int maxdispatchbuffers = UDPBUFFERS; - isc_dscp_t dscp = -1; - - switch (af) { - case AF_INET: - result = ns_config_get(maps, "query-source", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - case AF_INET6: - result = ns_config_get(maps, "query-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - sa = *(cfg_obj_assockaddr(obj)); - INSIST(isc_sockaddr_pf(&sa) == af); - - dscp = cfg_obj_getdscp(obj); - if (dscp != -1 && dscpp != NULL) - *dscpp = dscp; - - /* - * If we don't support this address family, we're done! - */ - switch (af) { - case AF_INET: - result = isc_net_probeipv4(); - break; - case AF_INET6: - result = isc_net_probeipv6(); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - /* - * Try to find a dispatcher that we can share. - */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (af) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - } - if (isc_sockaddr_getport(&sa) == 0) { - attrs |= DNS_DISPATCHATTR_EXCLUSIVE; - maxdispatchbuffers = EXCLBUFFERS; - } else { - INSIST(obj != NULL); - if (is_firstview) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_INFO, - "using specific query-source port " - "suppresses port randomization and can be " - "insecure."); - } - } - - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - disp = NULL; - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &sa, 4096, - maxdispatchbuffers, 32768, 16411, 16433, - attrs, attrmask, &disp); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_t any; - char buf[ISC_SOCKADDR_FORMATSIZE]; - - switch (af) { - case AF_INET: - isc_sockaddr_any(&any); - break; - case AF_INET6: - isc_sockaddr_any6(&any); - break; - } - if (isc_sockaddr_equal(&sa, &any)) - return (ISC_R_SUCCESS); - isc_sockaddr_format(&sa, buf, sizeof(buf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not get query source dispatcher (%s)", - buf); - return (result); - } - - *dispatchp = disp; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_order(dns_order_t *order, const cfg_obj_t *ent) { - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - const cfg_obj_t *obj; - dns_fixedname_t fixed; - unsigned int mode = 0; - const char *str; - isc_buffer_t b; - isc_result_t result; - bool addroot; - - result = ns_config_getclass(cfg_tuple_get(ent, "class"), - dns_rdataclass_any, &rdclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_config_gettype(cfg_tuple_get(ent, "type"), - dns_rdatatype_any, &rdtype); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "name"); - if (cfg_obj_isstring(obj)) - str = cfg_obj_asstring(obj); - else - str = "*"; - addroot = (strcmp(str, "*") == 0); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dns_fixedname_init(&fixed); - result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "ordering"); - INSIST(cfg_obj_isstring(obj)); - str = cfg_obj_asstring(obj); - if (!strcasecmp(str, "fixed")) { -#if DNS_RDATASET_FIXED - mode = DNS_RDATASETATTR_FIXEDORDER; -#else - mode = 0; -#endif /* DNS_RDATASET_FIXED */ - } else if (!strcasecmp(str, "random")) { - mode = DNS_RDATASETATTR_RANDOMIZE; - } else if (!strcasecmp(str, "cyclic")) { - mode = 0; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * "*" should match everything including the root (BIND 8 compat). - * As dns_name_matcheswildcard(".", "*.") returns FALSE add a - * explicit entry for "." when the name is "*". - */ - if (addroot) { - result = dns_order_add(order, dns_rootname, - rdtype, rdclass, mode); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (dns_order_add(order, dns_fixedname_name(&fixed), - rdtype, rdclass, mode)); -} - -static isc_result_t -configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { - isc_netaddr_t na; - dns_peer_t *peer; - const cfg_obj_t *obj; - const char *str; - isc_result_t result; - unsigned int prefixlen; - - cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen); - - peer = NULL; - result = dns_peer_newprefix(mctx, &na, prefixlen, &peer); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - (void)cfg_map_get(cpeer, "bogus", &obj); - if (obj != NULL) - CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "provide-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-expire", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestexpire(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-nsid", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "send-cookie", &obj); - if (obj != NULL) - CHECK(dns_peer_setsendcookie(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns", &obj); - if (obj != NULL) - CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns-udp-size", &obj); - if (obj != NULL) { - uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setudpsize(peer, (uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "edns-version", &obj); - if (obj != NULL) { - uint32_t ednsversion = cfg_obj_asuint32(obj); - if (ednsversion > 255) - ednsversion = 255; - CHECK(dns_peer_setednsversion(peer, (uint8_t)ednsversion)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "max-udp-size", &obj); - if (obj != NULL) { - uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setmaxudp(peer, (uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "tcp-only", &obj); - if (obj != NULL) - CHECK(dns_peer_setforcetcp(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfers", &obj); - if (obj != NULL) - CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfer-format", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) { - CHECK(dns_peer_settransferformat(peer, - dns_many_answers)); - } else if (strcasecmp(str, "one-answer") == 0) { - CHECK(dns_peer_settransferformat(peer, - dns_one_answer)); - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - (void)cfg_map_get(cpeer, "keys", &obj); - if (obj != NULL) { - result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "transfer-source", &obj); - else - (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_settransfersource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_settransferdscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "notify-source", &obj); - else - (void)cfg_map_get(cpeer, "notify-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setnotifysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_setnotifydscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "query-source", &obj); - else - (void)cfg_map_get(cpeer, "query-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setquerysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_setquerydscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - *peerp = peer; - return (ISC_R_SUCCESS); - - cleanup: - dns_peer_detach(&peer); - return (result); -} - -#ifdef HAVE_DLOPEN -static isc_result_t -configure_dyndb(const cfg_obj_t *dyndb, isc_mem_t *mctx, - const dns_dyndbctx_t *dctx) -{ - isc_result_t result = ISC_R_SUCCESS; - const cfg_obj_t *obj; - const char *name, *library; - - /* Get the name of the dyndb instance and the library path . */ - name = cfg_obj_asstring(cfg_tuple_get(dyndb, "name")); - library = cfg_obj_asstring(cfg_tuple_get(dyndb, "library")); - - obj = cfg_tuple_get(dyndb, "parameters"); - if (obj != NULL) - result = dns_dyndb_load(library, name, cfg_obj_asstring(obj), - cfg_obj_file(obj), cfg_obj_line(obj), - mctx, dctx); - - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dynamic database '%s' configuration failed: %s", - name, isc_result_totext(result)); - return (result); -} -#endif - - -static isc_result_t -disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - const cfg_obj_t *algorithms; - const cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - - algorithms = cfg_tuple_get(disabled, "algorithms"); - for (element = cfg_list_first(algorithms); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_secalg_t alg; - - DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); - r.length = strlen(r.base); - - result = dns_secalg_fromtext(&alg, &r); - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { - uint8_t ui; - result = isc_parse_uint8(&ui, r.base, 10); - alg = ui; - } - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); - } - cleanup: - return (result); -} - -static isc_result_t -disable_ds_digests(const cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - const cfg_obj_t *digests; - const cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - - digests = cfg_tuple_get(disabled, "digests"); - for (element = cfg_list_first(digests); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_dsdigest_t digest; - - DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); - r.length = strlen(r.base); - - /* disable_ds_digests handles numeric values. */ - result = dns_dsdigest_fromtext(&digest, &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_ds_digest(resolver, name, digest)); - } - cleanup: - return (result); -} - -static bool -on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) { - const cfg_listelt_t *element; - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - const cfg_obj_t *value; - const char *str; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - - for (element = cfg_list_first(disablelist); - element != NULL; - element = cfg_list_next(element)) - { - value = cfg_listelt_value(element); - str = cfg_obj_asstring(value); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(name, &b, dns_rootname, - 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dns_name_equal(name, zonename)) - return (true); - } - return (false); -} - -static isc_result_t -check_dbtype(dns_zone_t *zone, unsigned int dbtypec, const char **dbargv, - isc_mem_t *mctx) -{ - char **argv = NULL; - unsigned int i; - isc_result_t result = ISC_R_SUCCESS; - - CHECK(dns_zone_getdbtype(zone, &argv, mctx)); - - /* - * Check that all the arguments match. - */ - for (i = 0; i < dbtypec; i++) - if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) - CHECK(ISC_R_FAILURE); - - /* - * Check that there are not extra arguments. - */ - if (i == dbtypec && argv[i] != NULL) - result = ISC_R_FAILURE; - - cleanup: - isc_mem_free(mctx, argv); - return (result); -} - -static isc_result_t -setquerystats(dns_zone_t *zone, isc_mem_t *mctx, dns_zonestat_level_t level) { - isc_result_t result; - isc_stats_t *zoneqrystats; - - dns_zone_setstatlevel(zone, level); - - zoneqrystats = NULL; - if (level == dns_zonestat_full) { - result = isc_stats_create(mctx, &zoneqrystats, - dns_nsstatscounter_max); - if (result != ISC_R_SUCCESS) - return (result); - } - dns_zone_setrequeststats(zone, zoneqrystats); - if (zoneqrystats != NULL) - isc_stats_detach(&zoneqrystats); - - return (ISC_R_SUCCESS); -} - -static ns_cache_t * -cachelist_find(ns_cachelist_t *cachelist, const char *cachename, - dns_rdataclass_t rdclass) -{ - ns_cache_t *nsc; - - for (nsc = ISC_LIST_HEAD(*cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (nsc->rdclass == rdclass && - strcmp(dns_cache_getname(nsc->cache), cachename) == 0) - return (nsc); - } - - return (NULL); -} - -static bool -cache_reusable(dns_view_t *originview, dns_view_t *view, - bool new_zero_no_soattl) -{ - if (originview->rdclass != view->rdclass || - originview->checknames != view->checknames || - dns_resolver_getzeronosoattl(originview->resolver) != - new_zero_no_soattl || - originview->acceptexpired != view->acceptexpired || - originview->enablevalidation != view->enablevalidation || - originview->maxcachettl != view->maxcachettl || - originview->maxncachettl != view->maxncachettl) { - return (false); - } - - return (true); -} - -static bool -cache_sharable(dns_view_t *originview, dns_view_t *view, - bool new_zero_no_soattl, - unsigned int new_cleaning_interval, - uint64_t new_max_cache_size, - uint32_t new_stale_ttl) -{ - /* - * If the cache cannot even reused for the same view, it cannot be - * shared with other views. - */ - if (!cache_reusable(originview, view, new_zero_no_soattl)) - return (false); - - /* - * Check other cache related parameters that must be consistent among - * the sharing views. - */ - if (dns_cache_getcleaninginterval(originview->cache) != - new_cleaning_interval || - dns_cache_getservestalettl(originview->cache) != new_stale_ttl || - dns_cache_getcachesize(originview->cache) != new_max_cache_size) { - return (false); - } - - return (true); -} - -/* - * Callback from DLZ configure when the driver sets up a writeable zone - */ -static isc_result_t -dlzconfigure_callback(dns_view_t *view, dns_dlzdb_t *dlzdb, dns_zone_t *zone) { - dns_name_t *origin = dns_zone_getorigin(zone); - dns_rdataclass_t zclass = view->rdclass; - isc_result_t result; - - result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone); - if (result != ISC_R_SUCCESS) - return (result); - dns_zone_setstats(zone, ns_g_server->zonestats); - - return (ns_zone_configure_writeable_dlz(dlzdb, zone, zclass, origin)); -} - -static isc_result_t -dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na, - unsigned int prefixlen, const char *server, - const char *contact) -{ - char reverse[48+sizeof("ip6.arpa.")] = { 0 }; - char buf[sizeof("x.x.")]; - const char *dns64_dbtype[4] = { "_dns64", "dns64", ".", "." }; - const char *sep = ": view "; - const char *viewname = view->name; - const unsigned char *s6; - dns_fixedname_t fixed; - dns_name_t *name; - dns_zone_t *zone = NULL; - int dns64_dbtypec = 4; - isc_buffer_t b; - isc_result_t result; - - REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 || - prefixlen == 56 || prefixlen == 64 || prefixlen == 96); - - if (!strcmp(viewname, "_default")) { - sep = ""; - viewname = ""; - } - - /* - * Construct the reverse name of the zone. - */ - s6 = na->type.in6.s6_addr; - while (prefixlen > 0) { - prefixlen -= 8; - snprintf(buf, sizeof(buf), "%x.%x.", s6[prefixlen/8] & 0xf, - (s6[prefixlen/8] >> 4) & 0xf); - strlcat(reverse, buf, sizeof(reverse)); - } - strlcat(reverse, "ip6.arpa.", sizeof(reverse)); - - /* - * Create the actual zone. - */ - if (server != NULL) - dns64_dbtype[2] = server; - if (contact != NULL) - dns64_dbtype[3] = contact; - name = dns_fixedname_initname(&fixed); - isc_buffer_constinit(&b, reverse, strlen(reverse)); - isc_buffer_add(&b, strlen(reverse)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - CHECK(dns_zone_create(&zone, mctx)); - CHECK(dns_zone_setorigin(zone, name)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - dns_zone_setclass(zone, view->rdclass); - dns_zone_settype(zone, dns_zone_master); - dns_zone_setstats(zone, ns_g_server->zonestats); - CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype)); - if (view->queryacl != NULL) - dns_zone_setqueryacl(zone, view->queryacl); - if (view->queryonacl != NULL) - dns_zone_setqueryonacl(zone, view->queryonacl); - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - CHECK(setquerystats(zone, mctx, dns_zonestat_none)); /* XXXMPA */ - CHECK(dns_view_addzone(view, zone)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep, - viewname, reverse); - -cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - return (result); -} - -static isc_result_t -configure_rpz_name(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, - const char *str, const char *msg) -{ - isc_result_t result; - - result = dns_name_fromstring(name, str, DNS_NAME_DOWNCASE, view->mctx); - if (result != ISC_R_SUCCESS) - cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid %s '%s'", msg, str); - return (result); -} - -static isc_result_t -configure_rpz_name2(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, - const char *str, const dns_name_t *origin) -{ - isc_result_t result; - - result = dns_name_fromstring2(name, str, origin, DNS_NAME_DOWNCASE, - view->mctx); - if (result != ISC_R_SUCCESS) - cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone '%s'", str); - return (result); -} - -static isc_result_t -configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element, - bool recursive_only_def, dns_ttl_t ttl_def, - const dns_rpz_zone_t *old, bool *old_rpz_okp) -{ - const cfg_obj_t *rpz_obj, *obj; - const char *str; - dns_rpz_zone_t *new; - isc_result_t result; - dns_rpz_num_t rpz_num; - - REQUIRE(old != NULL || !*old_rpz_okp); - - rpz_obj = cfg_listelt_value(element); - - if (view->rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "limit of %d response policy zones exceeded", - DNS_RPZ_MAX_ZONES); - return (ISC_R_FAILURE); - } - - new = isc_mem_get(view->rpzs->mctx, sizeof(*new)); - if (new == NULL) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "no memory for response policy zones"); - return (ISC_R_NOMEMORY); - } - - memset(new, 0, sizeof(*new)); - result = isc_refcount_init(&new->refs, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(view->rpzs->mctx, new, sizeof(*new)); - return (result); - } - dns_name_init(&new->origin, NULL); - dns_name_init(&new->client_ip, NULL); - dns_name_init(&new->ip, NULL); - dns_name_init(&new->nsdname, NULL); - dns_name_init(&new->nsip, NULL); - dns_name_init(&new->passthru, NULL); - dns_name_init(&new->drop, NULL); - dns_name_init(&new->tcp_only, NULL); - dns_name_init(&new->cname, NULL); - new->num = view->rpzs->p.num_zones++; - view->rpzs->zones[new->num] = new; - - obj = cfg_tuple_get(rpz_obj, "recursive-only"); - if (cfg_obj_isvoid(obj) ? recursive_only_def : cfg_obj_asboolean(obj)) { - view->rpzs->p.no_rd_ok &= ~DNS_RPZ_ZBIT(new->num); - } else { - view->rpzs->p.no_rd_ok |= DNS_RPZ_ZBIT(new->num); - } - - obj = cfg_tuple_get(rpz_obj, "log"); - if (!cfg_obj_isvoid(obj) && !cfg_obj_asboolean(obj)) { - view->rpzs->p.no_log |= DNS_RPZ_ZBIT(new->num); - } else { - view->rpzs->p.no_log &= ~DNS_RPZ_ZBIT(new->num); - } - - obj = cfg_tuple_get(rpz_obj, "max-policy-ttl"); - if (cfg_obj_isuint32(obj)) { - new->max_policy_ttl = cfg_obj_asuint32(obj); - } else { - new->max_policy_ttl = ttl_def; - } - if (*old_rpz_okp && new->max_policy_ttl != old->max_policy_ttl) - *old_rpz_okp = false; - - str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "zone name")); - result = configure_rpz_name(view, rpz_obj, &new->origin, str, "zone"); - if (result != ISC_R_SUCCESS) - return (result); - if (dns_name_equal(&new->origin, dns_rootname)) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone name '%s'", str); - return (DNS_R_EMPTYLABEL); - } - for (rpz_num = 0; rpz_num < view->rpzs->p.num_zones-1; ++rpz_num) { - if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin, - &new->origin)) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "duplicate '%s'", str); - result = DNS_R_DUPLICATE; - return (result); - } - } - if (*old_rpz_okp && !dns_name_equal(&old->origin, &new->origin)) - *old_rpz_okp = false; - - result = configure_rpz_name2(view, rpz_obj, &new->client_ip, - DNS_RPZ_CLIENT_IP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->ip, - DNS_RPZ_IP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->nsdname, - DNS_RPZ_NSDNAME_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->nsip, - DNS_RPZ_NSIP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->passthru, - DNS_RPZ_PASSTHRU_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->drop, - DNS_RPZ_DROP_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->tcp_only, - DNS_RPZ_TCP_ONLY_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(rpz_obj, "policy"); - if (cfg_obj_isvoid(obj)) { - new->policy = DNS_RPZ_POLICY_GIVEN; - } else { - str = cfg_obj_asstring(cfg_tuple_get(obj, "policy name")); - new->policy = dns_rpz_str2policy(str); - INSIST(new->policy != DNS_RPZ_POLICY_ERROR); - if (new->policy == DNS_RPZ_POLICY_CNAME) { - str = cfg_obj_asstring(cfg_tuple_get(obj, "cname")); - result = configure_rpz_name(view, rpz_obj, &new->cname, - str, "cname"); - if (result != ISC_R_SUCCESS) - return (result); - } - } - if (*old_rpz_okp && (new->policy != old->policy || - !dns_name_equal(&old->cname, &new->cname))) - *old_rpz_okp = false; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_rpz(dns_view_t *view, const cfg_obj_t *rpz_obj, - bool *old_rpz_okp) -{ - const cfg_listelt_t *zone_element; - const cfg_obj_t *sub_obj; - bool recursive_only_def; - dns_ttl_t ttl_def; - dns_rpz_zones_t *new; - const dns_rpz_zones_t *old; - dns_view_t *pview; - const dns_rpz_zone_t *old_zone; - isc_result_t result; - int i; - - *old_rpz_okp = false; - - zone_element = cfg_list_first(cfg_tuple_get(rpz_obj, "zone list")); - if (zone_element == NULL) - return (ISC_R_SUCCESS); - - result = dns_rpz_new_zones(&view->rpzs, view->mctx); - if (result != ISC_R_SUCCESS) - return (result); - new = view->rpzs; - - sub_obj = cfg_tuple_get(rpz_obj, "recursive-only"); - if (!cfg_obj_isvoid(sub_obj) && - !cfg_obj_asboolean(sub_obj)) - recursive_only_def = false; - else - recursive_only_def = true; - - sub_obj = cfg_tuple_get(rpz_obj, "break-dnssec"); - if (!cfg_obj_isvoid(sub_obj) && - cfg_obj_asboolean(sub_obj)) - new->p.break_dnssec = true; - else - new->p.break_dnssec = false; - - sub_obj = cfg_tuple_get(rpz_obj, "max-policy-ttl"); - if (cfg_obj_isuint32(sub_obj)) - ttl_def = cfg_obj_asuint32(sub_obj); - else - ttl_def = DNS_RPZ_MAX_TTL_DEFAULT; - - sub_obj = cfg_tuple_get(rpz_obj, "min-ns-dots"); - if (cfg_obj_isuint32(sub_obj)) - new->p.min_ns_labels = cfg_obj_asuint32(sub_obj) + 1; - else - new->p.min_ns_labels = 2; - - sub_obj = cfg_tuple_get(rpz_obj, "qname-wait-recurse"); - if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) - new->p.qname_wait_recurse = true; - else - new->p.qname_wait_recurse = false; - - sub_obj = cfg_tuple_get(rpz_obj, "nsip-wait-recurse"); - if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) - new->p.nsip_wait_recurse = true; - else - new->p.nsip_wait_recurse = false; - - pview = NULL; - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, &pview); - if (result == ISC_R_SUCCESS) { - old = pview->rpzs; - } else { - old = NULL; - } - if (old == NULL) { - *old_rpz_okp = false; - } else { - *old_rpz_okp = true; - } - - for (i = 0; - zone_element != NULL; - ++i, zone_element = cfg_list_next(zone_element)) - { - INSIST(!*old_rpz_okp || old != NULL); - if (*old_rpz_okp && i < old->p.num_zones) { - old_zone = old->zones[i]; - } else { - *old_rpz_okp = false; - old_zone = NULL; - } - result = configure_rpz_zone(view, zone_element, - recursive_only_def, ttl_def, - old_zone, old_rpz_okp); - if (result != ISC_R_SUCCESS) { - if (pview != NULL) - dns_view_detach(&pview); - return (result); - } - } - - /* - * If this is a reloading and the parameters and list of policy - * zones are unchanged, then use the same policy data. - * Data for individual zones that must be reloaded will be merged. - */ - if (old != NULL && memcmp(&old->p, &new->p, sizeof(new->p)) != 0) - *old_rpz_okp = false; - if (*old_rpz_okp) { - dns_rpz_detach_rpzs(&view->rpzs); - dns_rpz_attach_rpzs(pview->rpzs, &view->rpzs); - } else if (old != NULL && pview != NULL) { - pview->rpzs->rpz_ver += 1; - view->rpzs->rpz_ver = pview->rpzs->rpz_ver; - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_DEBUG_LEVEL1, - "updated RPZ policy: version %d", - view->rpzs->rpz_ver); - } - - if (pview != NULL) { - dns_view_detach(&pview); - } - - return (ISC_R_SUCCESS); -} - -static void -catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) { - catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0; - isc_result_t result; - isc_buffer_t namebuf; - isc_buffer_t *confbuf; - char nameb[DNS_NAME_FORMATSIZE]; - const cfg_obj_t *zlist = NULL; - cfg_obj_t *zoneconf = NULL; - cfg_obj_t *zoneobj = NULL; - ns_cfgctx_t *cfg; - dns_zone_t *zone = NULL; - - cfg = (ns_cfgctx_t *) ev->view->new_zone_config; - if (cfg == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: allow-new-zones statement missing from " - "config; cannot add zone from the catalog"); - goto cleanup; - } - - isc_buffer_init(&namebuf, nameb, DNS_NAME_FORMATSIZE); - dns_name_totext(dns_catz_entry_getname(ev->entry), true, &namebuf); - isc_buffer_putuint8(&namebuf, 0); - - /* Zone shouldn't already exist */ - result = dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone); - - if (ev->mod == true) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to " - "modify zone \"%s\"", - isc_result_totext(result), - nameb); - goto cleanup; - } else { - if (!dns_zone_getadded(zone)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "catz: catz_addmodzone_taskaction: " - "zone '%s' is not a dynamically " - "added zone", - nameb); - goto cleanup; - } - if (dns_zone_get_parentcatz(zone) != ev->origin) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' exists in multiple " - "catalog zones", - nameb); - goto cleanup; - } - dns_zone_detach(&zone); - } - - } else { - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "catz: zone \"%s\" is overridden " - "by explicitly configured zone", - nameb); - goto cleanup; - } else if (result != ISC_R_NOTFOUND && - result != DNS_R_PARTIALMATCH) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to " - "add zone \"%s\"", - isc_result_totext(result), - nameb); - goto cleanup; - } else { /* this can happen in case of DNS_R_PARTIALMATCH */ - if (zone != NULL) - dns_zone_detach(&zone); - } - } - RUNTIME_CHECK(zone == NULL); - /* Create a config for new zone */ - confbuf = NULL; - result = dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf); - if (result == ISC_R_SUCCESS) { - cfg_parser_reset(cfg->add_parser); - result = cfg_parse_buffer3(cfg->add_parser, confbuf, "catz", 0, - &cfg_type_addzoneconf, &zoneconf); - isc_buffer_free(&confbuf); - } - /* - * Fail if either dns_catz_generate_zonecfg() or cfg_parse_buffer3() - * failed. - */ - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: error \"%s\" while trying to generate " - "config for zone \"%s\"", - isc_result_totext(result), nameb); - goto cleanup; - } - CHECK(cfg_map_get(zoneconf, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - /* For now we only support adding one zone at a time */ - zoneobj = cfg_listelt_value(cfg_list_first(zlist)); - - /* Mark view unfrozen so that zone can be added */ - - result = isc_task_beginexclusive(task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_view_thaw(ev->view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - ev->cbd->server->mctx, ev->view, - &ev->cbd->server->viewlist, cfg->actx, - true, false, ev->mod); - dns_view_freeze(ev->view); - isc_task_endexclusive(task); - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: failed to configure zone \"%s\" - %d", - nameb, result); - goto cleanup; - } - - /* Is it there yet? */ - CHECK(dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone)); - - /* - * Load the zone from the master file. If this fails, we'll - * need to undo the configuration we've done already. - */ - result = dns_zone_loadnew(zone); - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: dns_zone_loadnew() failed " - "with %s; reverting.", - isc_result_totext(result)); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(ev->view->zonetable, zone); - goto cleanup; - } - - /* Flag the zone as having been added at runtime */ - dns_zone_setadded(zone, true); - dns_zone_set_parentcatz(zone, ev->origin); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (zoneconf != NULL) - cfg_obj_destroy(cfg->add_parser, &zoneconf); - dns_catz_entry_detach(ev->origin, &ev->entry); - dns_catz_zone_detach(&ev->origin); - dns_view_detach(&ev->view); - isc_event_free(ISC_EVENT_PTR(&ev)); -} - -static void -catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) { - catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0; - isc_result_t result; - dns_zone_t *zone = NULL; - dns_db_t *dbp = NULL; - char cname[DNS_NAME_FORMATSIZE]; - const char * file; - - result = isc_task_beginexclusive(task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_name_format(dns_catz_entry_getname(ev->entry), cname, - DNS_NAME_FORMATSIZE); - result = dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' not found", cname); - goto cleanup; - } - - if (!dns_zone_getadded(zone)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' is not a dynamically added zone", - cname); - goto cleanup; - } - - if (dns_zone_get_parentcatz(zone) != ev->origin) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: zone " - "'%s' exists in multiple catalog zones", - cname); - goto cleanup; - } - - /* Stop answering for this zone */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - CHECK(dns_zt_unmount(ev->view->zonetable, zone)); - file = dns_zone_getfile(zone); - if (file != NULL) - isc_file_remove(file); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' deleted", cname); - cleanup: - isc_task_endexclusive(task); - if (zone != NULL) - dns_zone_detach(&zone); - dns_catz_entry_detach(ev->origin, &ev->entry); - dns_catz_zone_detach(&ev->origin); - dns_view_detach(&ev->view); - isc_event_free(ISC_EVENT_PTR(&ev)); -} - -static isc_result_t -catz_create_chg_task(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata, - isc_eventtype_t type) -{ - catz_chgzone_event_t *event; - isc_task_t *task; - isc_result_t result; - isc_taskaction_t action = NULL; - - switch (type) { - case DNS_EVENT_CATZADDZONE: - case DNS_EVENT_CATZMODZONE: - action = catz_addmodzone_taskaction; - break; - case DNS_EVENT_CATZDELZONE: - action = catz_delzone_taskaction; - break; - default: - REQUIRE(0); - } - - event = (catz_chgzone_event_t *) isc_event_allocate(view->mctx, origin, - type, action, NULL, - sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - - event->cbd = (catz_cb_data_t *) udata; - event->entry = NULL; - event->origin = NULL; - event->view = NULL; - event->mod = (type == DNS_EVENT_CATZMODZONE); - dns_catz_entry_attach(entry, &event->entry); - dns_catz_zone_attach(origin, &event->origin); - dns_view_attach(view, &event->view); - - task = NULL; - result = isc_taskmgr_excltask(taskmgr, &task); - REQUIRE(result == ISC_R_SUCCESS); - isc_task_send(task, ISC_EVENT_PTR(&event)); - isc_task_detach(&task); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -catz_addzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZADDZONE)); -} - -static isc_result_t -catz_delzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZDELZONE)); -} - -static isc_result_t -catz_modzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZMODZONE)); -} - -static isc_result_t -configure_catz_zone(dns_view_t *view, const cfg_obj_t *config, - const cfg_listelt_t *element) -{ - const cfg_obj_t *catz_obj, *obj; - dns_catz_zone_t *zone = NULL; - const char *str; - isc_result_t result; - dns_name_t origin; - dns_catz_options_t *opts; - dns_view_t *pview = NULL; - - dns_name_init(&origin, NULL); - catz_obj = cfg_listelt_value(element); - - str = cfg_obj_asstring(cfg_tuple_get(catz_obj, "zone name")); - - result = dns_name_fromstring(&origin, str, DNS_NAME_DOWNCASE, - view->mctx); - if (result == ISC_R_SUCCESS && dns_name_equal(&origin, dns_rootname)) - result = DNS_R_EMPTYLABEL; - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: invalid zone name '%s'", str); - goto cleanup; - } - - result = dns_catz_add_zone(view->catzs, &origin, &zone); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: unable to create catalog zone '%s', " - "error %s", - str, isc_result_totext(result)); - goto cleanup; - } - - if (result == ISC_R_EXISTS) { - isc_ht_iter_t *it = NULL; - - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, - view->rdclass, &pview); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * xxxwpk todo: reconfigure the zone!!!! - */ - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: catalog zone '%s' will not be reconfigured", - str); - /* - * We have to walk through all the member zones and attach - * them to current view - */ - result = dns_catz_get_iterator(zone, &it); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: unable to create iterator"); - goto cleanup; - } - - for (result = isc_ht_iter_first(it); - result == ISC_R_SUCCESS; - result = isc_ht_iter_next(it)) - { - dns_name_t *name = NULL; - dns_zone_t *dnszone = NULL; - dns_catz_entry_t *entry = NULL; - isc_result_t tresult; - - isc_ht_iter_current(it, (void **) &entry); - name = dns_catz_entry_getname(entry); - - tresult = dns_view_findzone(pview, name, &dnszone); - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); - - dns_zone_setview(dnszone, view); - if (view->acache != NULL) - dns_zone_setacache(dnszone, view->acache); - dns_view_addzone(view, dnszone); - - /* - * The dns_view_findzone() call above increments the - * zone's reference count, which we need to decrement - * back. However, as dns_zone_detach() sets the - * supplied pointer to NULL, calling it is deferred - * until the dnszone variable is no longer used. - */ - dns_zone_detach(&dnszone); - } - - isc_ht_iter_destroy(&it); - - result = ISC_R_SUCCESS; - } - - dns_catz_zone_resetdefoptions(zone); - opts = dns_catz_zone_getdefoptions(zone); - - obj = cfg_tuple_get(catz_obj, "default-masters"); - if (obj != NULL && cfg_obj_istuple(obj)) - result = ns_config_getipandkeylist(config, obj, - view->mctx, &opts->masters); - - obj = cfg_tuple_get(catz_obj, "in-memory"); - if (obj != NULL && cfg_obj_isboolean(obj)) - opts->in_memory = cfg_obj_asboolean(obj); - - obj = cfg_tuple_get(catz_obj, "zone-directory"); - if (!opts->in_memory && obj != NULL && cfg_obj_isstring(obj)) { - opts->zonedir = isc_mem_strdup(view->mctx, - cfg_obj_asstring(obj)); - if (isc_file_isdirectory(opts->zonedir) != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: zone-directory '%s' " - "not found; zone files will not be " - "saved", opts->zonedir); - opts->in_memory = true; - } - } - - obj = cfg_tuple_get(catz_obj, "min-update-interval"); - if (obj != NULL && cfg_obj_isuint32(obj)) - opts->min_update_interval = cfg_obj_asuint32(obj); - - cleanup: - if (pview != NULL) - dns_view_detach(&pview); - dns_name_free(&origin, view->mctx); - - return (result); -} - -static catz_cb_data_t ns_catz_cbdata; -static dns_catz_zonemodmethods_t ns_catz_zonemodmethods = { - catz_addzone, - catz_modzone, - catz_delzone, - &ns_catz_cbdata -}; - -static isc_result_t -configure_catz(dns_view_t *view, const cfg_obj_t *config, - const cfg_obj_t *catz_obj) -{ - const cfg_listelt_t *zone_element; - const dns_catz_zones_t *old = NULL; - dns_view_t *pview = NULL; - isc_result_t result; - - /* xxxwpk TODO do it cleaner, once, somewhere */ - ns_catz_cbdata.server = ns_g_server; - - zone_element = cfg_list_first(cfg_tuple_get(catz_obj, "zone list")); - if (zone_element == NULL) - return (ISC_R_SUCCESS); - - CHECK(dns_catz_new_zones(&view->catzs, &ns_catz_zonemodmethods, - view->mctx, ns_g_taskmgr, ns_g_timermgr)); - - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result == ISC_R_SUCCESS) - old = pview->catzs; - - if (old != NULL) { - dns_catz_catzs_detach(&view->catzs); - dns_catz_catzs_attach(pview->catzs, &view->catzs); - dns_catz_prereconfig(view->catzs); - } - - while (zone_element != NULL) { - CHECK(configure_catz_zone(view, config, zone_element)); - zone_element = cfg_list_next(zone_element); - } - - if (old != NULL) - dns_catz_postreconfig(view->catzs); - - result = ISC_R_SUCCESS; - - cleanup: - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -#define CHECK_RRL(cond, pat, val1, val2) \ - do { \ - if (!(cond)) { \ - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, \ - pat, val1, val2); \ - result = ISC_R_RANGE; \ - goto cleanup; \ - } \ - } while (0) - -#define CHECK_RRL_RATE(rate, def, max_rate, name) \ - do { \ - obj = NULL; \ - rrl->rate.str = name; \ - result = cfg_map_get(map, name, &obj); \ - if (result == ISC_R_SUCCESS) { \ - rrl->rate.r = cfg_obj_asuint32(obj); \ - CHECK_RRL(rrl->rate.r <= max_rate, \ - name" %d > %d", \ - rrl->rate.r, max_rate); \ - } else { \ - rrl->rate.r = def; \ - } \ - rrl->rate.scaled = rrl->rate.r; \ - } while (0) - -static isc_result_t -configure_rrl(dns_view_t *view, const cfg_obj_t *config, const cfg_obj_t *map) { - const cfg_obj_t *obj; - dns_rrl_t *rrl; - isc_result_t result; - int min_entries, i, j; - - /* - * Most DNS servers have few clients, but intentinally open - * recursive and authoritative servers often have many. - * So start with a small number of entries unless told otherwise - * to reduce cold-start costs. - */ - min_entries = 500; - obj = NULL; - result = cfg_map_get(map, "min-table-size", &obj); - if (result == ISC_R_SUCCESS) { - min_entries = cfg_obj_asuint32(obj); - if (min_entries < 1) - min_entries = 1; - } - result = dns_rrl_init(&rrl, view, min_entries); - if (result != ISC_R_SUCCESS) - return (result); - - i = ISC_MAX(20000, min_entries); - obj = NULL; - result = cfg_map_get(map, "max-table-size", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= min_entries, - "max-table-size %d < min-table-size %d", - i, min_entries); - } - rrl->max_entries = i; - - CHECK_RRL_RATE(responses_per_second, 0, DNS_RRL_MAX_RATE, - "responses-per-second"); - CHECK_RRL_RATE(referrals_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "referrals-per-second"); - CHECK_RRL_RATE(nodata_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "nodata-per-second"); - CHECK_RRL_RATE(nxdomains_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "nxdomains-per-second"); - CHECK_RRL_RATE(errors_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "errors-per-second"); - - CHECK_RRL_RATE(all_per_second, 0, DNS_RRL_MAX_RATE, - "all-per-second"); - - CHECK_RRL_RATE(slip, 2, DNS_RRL_MAX_SLIP, - "slip"); - - i = 15; - obj = NULL; - result = cfg_map_get(map, "window", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 1 && i <= DNS_RRL_MAX_WINDOW, - "window %d < 1 or > %d", i, DNS_RRL_MAX_WINDOW); - } - rrl->window = i; - - i = 0; - obj = NULL; - result = cfg_map_get(map, "qps-scale", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 1, "invalid 'qps-scale %d'%s", i, ""); - } - rrl->qps_scale = i; - rrl->qps = 1.0; - - i = 24; - obj = NULL; - result = cfg_map_get(map, "ipv4-prefix-length", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 8 && i <= 32, - "invalid 'ipv4-prefix-length %d'%s", i, ""); - } - rrl->ipv4_prefixlen = i; - if (i == 32) - rrl->ipv4_mask = 0xffffffff; - else - rrl->ipv4_mask = htonl(0xffffffff << (32-i)); - - i = 56; - obj = NULL; - result = cfg_map_get(map, "ipv6-prefix-length", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 16 && i <= DNS_RRL_MAX_PREFIX, - "ipv6-prefix-length %d < 16 or > %d", - i, DNS_RRL_MAX_PREFIX); - } - rrl->ipv6_prefixlen = i; - for (j = 0; j < 4; ++j) { - if (i <= 0) { - rrl->ipv6_mask[j] = 0; - } else if (i < 32) { - rrl->ipv6_mask[j] = htonl(0xffffffff << (32-i)); - } else { - rrl->ipv6_mask[j] = 0xffffffff; - } - i -= 32; - } - - obj = NULL; - result = cfg_map_get(map, "exempt-clients", &obj); - if (result == ISC_R_SUCCESS) { - result = cfg_acl_fromconfig(obj, config, ns_g_lctx, - ns_g_aclconfctx, ns_g_mctx, - 0, &rrl->exempt); - CHECK_RRL(result == ISC_R_SUCCESS, - "invalid %s%s", "address match list", ""); - } - - obj = NULL; - result = cfg_map_get(map, "log-only", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_asboolean(obj)) - rrl->log_only = true; - else - rrl->log_only = false; - - return (ISC_R_SUCCESS); - - cleanup: - dns_rrl_view_destroy(view); - return (result); -} - -static isc_result_t -add_soa(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_name_t *origin, dns_name_t *contact) -{ - dns_dbnode_t *node = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - isc_result_t result; - unsigned char buf[DNS_SOA_BUFFERSIZE]; - - CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db), - 0, 28800, 7200, 604800, 86400, buf, &rdata)); - - dns_rdatalist_init(&rdatalist); - rdatalist.type = rdata.type; - rdatalist.rdclass = rdata.rdclass; - rdatalist.ttl = 86400; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - dns_rdataset_init(&rdataset); - CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); - CHECK(dns_db_findnode(db, name, true, &node)); - CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL)); - - cleanup: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -add_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_name_t *nsname) -{ - dns_dbnode_t *node = NULL; - dns_rdata_ns_t ns; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - isc_result_t result; - isc_buffer_t b; - unsigned char buf[DNS_NAME_MAXWIRE]; - - isc_buffer_init(&b, buf, sizeof(buf)); - - ns.common.rdtype = dns_rdatatype_ns; - ns.common.rdclass = dns_db_class(db); - ns.mctx = NULL; - dns_name_init(&ns.name, NULL); - dns_name_clone(nsname, &ns.name); - CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns, - &ns, &b)); - - dns_rdatalist_init(&rdatalist); - rdatalist.type = rdata.type; - rdatalist.rdclass = rdata.rdclass; - rdatalist.ttl = 86400; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - dns_rdataset_init(&rdataset); - CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); - CHECK(dns_db_findnode(db, name, true, &node)); - CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL)); - - cleanup: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, - const cfg_obj_t *zonelist, const char **empty_dbtype, - int empty_dbtypec, dns_zonestat_level_t statlevel) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - const cfg_listelt_t *element; - const cfg_obj_t *obj; - const cfg_obj_t *zconfig; - const cfg_obj_t *zoptions; - const char *rbt_dbtype[4] = { "rbt" }; - const char *sep = ": view "; - const char *str; - const char *viewname = view->name; - dns_db_t *db = NULL; - dns_dbversion_t *version = NULL; - dns_fixedname_t cfixed; - dns_fixedname_t fixed; - dns_fixedname_t nsfixed; - dns_name_t *contact; - dns_name_t *ns; - dns_name_t *zname; - dns_zone_t *myzone = NULL; - int rbt_dbtypec = 1; - isc_result_t result; - dns_namereln_t namereln; - int order; - unsigned int nlabels; - - zname = dns_fixedname_initname(&fixed); - ns = dns_fixedname_initname(&nsfixed); - contact = dns_fixedname_initname(&cfixed); - - /* - * Look for forward "zones" beneath this empty zone and if so - * create a custom db for the empty zone. - */ - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) { - - zconfig = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - CHECK(dns_name_fromstring(zname, str, 0, NULL)); - namereln = dns_name_fullcompare(zname, name, &order, &nlabels); - if (namereln != dns_namereln_subdomain) - continue; - - zoptions = cfg_tuple_get(zconfig, "options"); - - obj = NULL; - (void)cfg_map_get(zoptions, "type", &obj); - if (obj != NULL && - strcasecmp(cfg_obj_asstring(obj), "forward") == 0) { - obj = NULL; - (void)cfg_map_get(zoptions, "forward", &obj); - if (obj == NULL) - continue; - if (strcasecmp(cfg_obj_asstring(obj), "only") != 0) - continue; - } - if (db == NULL) { - CHECK(dns_db_create(view->mctx, "rbt", name, - dns_dbtype_zone, view->rdclass, - 0, NULL, &db)); - CHECK(dns_db_newversion(db, &version)); - if (strcmp(empty_dbtype[2], "@") == 0) - dns_name_clone(name, ns); - else - CHECK(dns_name_fromstring(ns, empty_dbtype[2], - 0, NULL)); - CHECK(dns_name_fromstring(contact, empty_dbtype[3], - 0, NULL)); - CHECK(add_soa(db, version, name, ns, contact)); - CHECK(add_ns(db, version, name, ns)); - } - CHECK(add_ns(db, version, zname, dns_rootname)); - } - - /* - * Is the existing zone the ok to use? - */ - if (zone != NULL) { - unsigned int typec; - const char **dbargv; - - if (db != NULL) { - typec = rbt_dbtypec; - dbargv = rbt_dbtype; - } else { - typec = empty_dbtypec; - dbargv = empty_dbtype; - } - - result = check_dbtype(zone, typec, dbargv, view->mctx); - if (result != ISC_R_SUCCESS) - zone = NULL; - - if (zone != NULL && dns_zone_gettype(zone) != dns_zone_master) - zone = NULL; - if (zone != NULL && dns_zone_getfile(zone) != NULL) - zone = NULL; - if (zone != NULL) { - dns_zone_getraw(zone, &myzone); - if (myzone != NULL) { - dns_zone_detach(&myzone); - zone = NULL; - } - } - } - - if (zone == NULL) { - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &myzone)); - zone = myzone; - CHECK(dns_zone_setorigin(zone, name)); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - if (db == NULL) - CHECK(dns_zone_setdbtype(zone, empty_dbtypec, - empty_dbtype)); - dns_zone_setclass(zone, view->rdclass); - dns_zone_settype(zone, dns_zone_master); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - - dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setautomatic(zone, true); - if (view->queryacl != NULL) - dns_zone_setqueryacl(zone, view->queryacl); - else - dns_zone_clearqueryacl(zone); - if (view->queryonacl != NULL) - dns_zone_setqueryonacl(zone, view->queryonacl); - else - dns_zone_clearqueryonacl(zone); - dns_zone_clearupdateacl(zone); - if (view->transferacl != NULL) - dns_zone_setxfracl(zone, view->transferacl); - else - dns_zone_clearxfracl(zone); - - CHECK(setquerystats(zone, view->mctx, statlevel)); - if (db != NULL) { - dns_db_closeversion(db, &version, true); - CHECK(dns_zone_replacedb(zone, db, false)); - } - dns_zone_setoption2(zone, DNS_ZONEOPT2_AUTOEMPTY, true); - dns_zone_setview(zone, view); - CHECK(dns_view_addzone(view, zone)); - - if (!strcmp(viewname, "_default")) { - sep = ""; - viewname = ""; - } - dns_name_format(name, namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "automatic empty zone%s%s: %s", - sep, viewname, namebuf); - - cleanup: - if (myzone != NULL) - dns_zone_detach(&myzone); - if (version != NULL) - dns_db_closeversion(db, &version, false); - if (db != NULL) - dns_db_detach(&db); - - INSIST(version == NULL); - - return (result); -} - -#ifdef HAVE_DNSTAP -static isc_result_t -configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) { - isc_result_t result; - const cfg_obj_t *obj, *obj2; - const cfg_listelt_t *element; - const char *dpath; - const cfg_obj_t *dlist = NULL; - dns_dtmsgtype_t dttypes = 0; - dns_dtmode_t dmode; - unsigned int i; - struct fstrm_iothr_options *fopt = NULL; - - result = ns_config_get(maps, "dnstap", &dlist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - for (element = cfg_list_first(dlist); - element != NULL; - element = cfg_list_next(element)) - { - const char *str; - dns_dtmsgtype_t dt = 0; - - obj = cfg_listelt_value(element); - obj2 = cfg_tuple_get(obj, "type"); - str = cfg_obj_asstring(obj2); - if (strcasecmp(str, "client") == 0) { - dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR; - } else if (strcasecmp(str, "auth") == 0) { - dt |= DNS_DTTYPE_AQ|DNS_DTTYPE_AR; - } else if (strcasecmp(str, "resolver") == 0) { - dt |= DNS_DTTYPE_RQ|DNS_DTTYPE_RR; - } else if (strcasecmp(str, "forwarder") == 0) { - dt |= DNS_DTTYPE_FQ|DNS_DTTYPE_FR; - } else if (strcasecmp(str, "all") == 0) { - dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR| - DNS_DTTYPE_AQ|DNS_DTTYPE_AR| - DNS_DTTYPE_RQ|DNS_DTTYPE_RR| - DNS_DTTYPE_FQ|DNS_DTTYPE_FR; - } - - obj2 = cfg_tuple_get(obj, "mode"); - if (obj2 == NULL || cfg_obj_isvoid(obj2)) { - dttypes |= dt; - continue; - } - - str = cfg_obj_asstring(obj2); - if (strcasecmp(str, "query") == 0) { - dt &= ~DNS_DTTYPE_RESPONSE; - } else if (strcasecmp(str, "response") == 0) { - dt &= ~DNS_DTTYPE_QUERY; - } - - dttypes |= dt; - } - - if (ns_g_server->dtenv == NULL && dttypes != 0) { - obj = NULL; - CHECKM(ns_config_get(maps, "dnstap-output", &obj), - "'dnstap-output' must be set if 'dnstap' is set"); - - obj2 = cfg_tuple_get(obj, "mode"); - if (obj2 == NULL) - CHECKM(ISC_R_FAILURE, "dnstap-output mode not found"); - if (strcasecmp(cfg_obj_asstring(obj2), "file") == 0) - dmode = dns_dtmode_file; - else - dmode = dns_dtmode_unix; - - obj2 = cfg_tuple_get(obj, "path"); - if (obj2 == NULL) - CHECKM(ISC_R_FAILURE, "dnstap-output path not found"); - - dpath = cfg_obj_asstring(obj2); - - fopt = fstrm_iothr_options_init(); - fstrm_iothr_options_set_num_input_queues(fopt, ns_g_cpus); - fstrm_iothr_options_set_queue_model(fopt, - FSTRM_IOTHR_QUEUE_MODEL_MPSC); - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-buffer-hint", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_buffer_hint(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-flush-timeout", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_flush_timeout(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-input-queue-size", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_input_queue_size(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, - "fstrm-set-output-notify-threshold", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_queue_notify_threshold(fopt, - i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-output-queue-model", - &obj); - if (result == ISC_R_SUCCESS) { - if (strcasecmp(cfg_obj_asstring(obj), "spsc") == 0) - i = FSTRM_IOTHR_QUEUE_MODEL_SPSC; - else - i = FSTRM_IOTHR_QUEUE_MODEL_MPSC; - fstrm_iothr_options_set_queue_model(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-output-queue-size", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_output_queue_size(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-reopen-interval", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_reopen_interval(fopt, i); - } - - CHECKM(dns_dt_create(ns_g_mctx, dmode, dpath, &fopt, - &ns_g_server->dtenv), - "unable to create dnstap environment"); - } - - if (ns_g_server->dtenv == NULL) - return (ISC_R_SUCCESS); - - obj = NULL; - result = ns_config_get(maps, "dnstap-version", &obj); - if (result != ISC_R_SUCCESS) { - /* not specified; use the product and version */ - dns_dt_setversion(ns_g_server->dtenv, PRODUCT " " VERSION); - } else if (result == ISC_R_SUCCESS && !cfg_obj_isvoid(obj)) { - /* Quoted string */ - dns_dt_setversion(ns_g_server->dtenv, cfg_obj_asstring(obj)); - } - - obj = NULL; - result = ns_config_get(maps, "dnstap-identity", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - /* "hostname" is interpreted as boolean true */ - char buf[256]; - result = ns_os_gethostname(buf, sizeof(buf)); - if (result == ISC_R_SUCCESS) - dns_dt_setidentity(ns_g_server->dtenv, buf); - } else if (result == ISC_R_SUCCESS && !cfg_obj_isvoid(obj)) { - /* Quoted string */ - dns_dt_setidentity(ns_g_server->dtenv, cfg_obj_asstring(obj)); - } - - dns_dt_attach(ns_g_server->dtenv, &view->dtenv); - view->dttypes = dttypes; - - result = ISC_R_SUCCESS; - - cleanup: - if (fopt != NULL) - fstrm_iothr_options_destroy(&fopt); - - return (result); -} -#endif /* HAVE_DNSTAP */ - -static isc_result_t -create_mapped_acl(void) { - isc_result_t result; - dns_acl_t *acl = NULL; - struct in6_addr in6 = IN6ADDR_V4MAPPED_INIT; - isc_netaddr_t addr; - - isc_netaddr_fromin6(&addr, &in6); - - result = dns_acl_create(ns_g_mctx, 1, &acl); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_iptable_addprefix2(acl->iptable, &addr, 96, - true, false); - if (result == ISC_R_SUCCESS) - dns_acl_attach(acl, &ns_g_mapped); - dns_acl_detach(&acl); - return (result); -} - -/* - * Configure 'view' according to 'vconfig', taking defaults from 'config' - * where values are missing in 'vconfig'. - * - * When configuring the default view, 'vconfig' will be NULL and the - * global defaults in 'config' used exclusively. - */ -static isc_result_t -configure_view(dns_view_t *view, dns_viewlist_t *viewlist, - cfg_obj_t *config, cfg_obj_t *vconfig, - ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys, - isc_mem_t *mctx, cfg_aclconfctx_t *actx, - bool need_hints) -{ - const cfg_obj_t *maps[4]; - const cfg_obj_t *cfgmaps[3]; - const cfg_obj_t *optionmaps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *voptions = NULL; - const cfg_obj_t *forwardtype; - const cfg_obj_t *forwarders; - const cfg_obj_t *alternates; - const cfg_obj_t *zonelist; - const cfg_obj_t *dlzlist; - const cfg_obj_t *dlz; - const cfg_obj_t *dlvobj = NULL; - unsigned int dlzargc; - char **dlzargv; - const cfg_obj_t *dyndb_list; - const cfg_obj_t *disabled; - const cfg_obj_t *obj, *obj2; - const cfg_listelt_t *element; - in_port_t port; - dns_cache_t *cache = NULL; - isc_result_t result; - unsigned int cleaning_interval; - size_t max_cache_size; - uint32_t max_cache_size_percent = 0; - size_t max_acache_size; - size_t max_adb_size; - uint32_t lame_ttl, fail_ttl; - uint32_t max_stale_ttl; - dns_tsig_keyring_t *ring = NULL; - dns_view_t *pview = NULL; /* Production view */ - isc_mem_t *cmctx = NULL, *hmctx = NULL; - dns_dispatch_t *dispatch4 = NULL; - dns_dispatch_t *dispatch6 = NULL; - bool reused_cache = false; - bool shared_cache = false; - int i = 0, j = 0, k = 0; - const char *str; - const char *cachename = NULL; - dns_order_t *order = NULL; - uint32_t udpsize; - uint32_t maxbits; - unsigned int resopts = 0; - dns_zone_t *zone = NULL; - uint32_t max_clients_per_query; - bool empty_zones_enable; - const cfg_obj_t *disablelist = NULL; - isc_stats_t *resstats = NULL; - dns_stats_t *resquerystats = NULL; - bool auto_root = false; - ns_cache_t *nsc; - bool zero_no_soattl; - dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL; - unsigned int query_timeout, ndisp; - bool old_rpz_ok = false; - isc_dscp_t dscp4 = -1, dscp6 = -1; - dns_dyndbctx_t *dctx = NULL; - unsigned int resolver_param; - - REQUIRE(DNS_VIEW_VALID(view)); - - if (config != NULL) - (void)cfg_map_get(config, "options", &options); - - /* - * maps: view options, options, defaults - * cfgmaps: view options, config - * optionmaps: view options, options - */ - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - maps[i++] = voptions; - optionmaps[j++] = voptions; - cfgmaps[k++] = voptions; - } - if (options != NULL) { - maps[i++] = options; - optionmaps[j++] = options; - } - - maps[i++] = ns_g_defaults; - maps[i] = NULL; - optionmaps[j] = NULL; - if (config != NULL) - cfgmaps[k++] = config; - cfgmaps[k] = NULL; - - /* - * Set the view's port number for outgoing queries. - */ - CHECKM(ns_config_getport(config, &port), "port"); - dns_view_setdstport(view, port); - - /* - * Create additional cache for this view and zones under the view - * if explicitly enabled. - * XXX950 default to on. - */ - obj = NULL; - (void)ns_config_get(maps, "acache-enable", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) { - cmctx = NULL; - CHECK(isc_mem_create(0, 0, &cmctx)); - CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr, - ns_g_timermgr)); - isc_mem_setname(cmctx, "acache", NULL); - isc_mem_detach(&cmctx); - } - if (view->acache != NULL) { - obj = NULL; - result = ns_config_get(maps, "acache-cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_acache_setcleaninginterval(view->acache, - cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-acache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_acache_size = 0; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > SIZE_MAX) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "'max-acache-size " - "%" PRIu64 "' " - "is too large for this " - "system; reducing to %lu", - value, (unsigned long)SIZE_MAX); - value = SIZE_MAX; - } - max_acache_size = (size_t) value; - } - dns_acache_setcachesize(view->acache, max_acache_size); - } - - /* - * Make the list of response policy zone names for a view that - * is used for real lookups and so cares about hints. - */ - obj = NULL; - if (view->rdclass == dns_rdataclass_in && need_hints && - ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) { - CHECK(configure_rpz(view, obj, &old_rpz_ok)); - } - - obj = NULL; - if (view->rdclass == dns_rdataclass_in && need_hints && - ns_config_get(maps, "catalog-zones", &obj) == ISC_R_SUCCESS) { - CHECK(configure_catz(view, config, obj)); - } - - /* - * Configure the zones. - */ - zonelist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "zone", &zonelist); - else - (void)cfg_map_get(config, "zone", &zonelist); - - /* - * Load zone configuration - */ - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, view, - viewlist, actx, false, old_rpz_ok, - false)); - } - - /* - * If we're allowing added zones, then load zone configuration - * from the newzone file for zones that were added during previous - * runs. - */ - CHECK(configure_newzones(view, config, vconfig, mctx, actx)); - - /* - * Create Dynamically Loadable Zone driver. - */ - dlzlist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "dlz", &dlzlist); - else - (void)cfg_map_get(config, "dlz", &dlzlist); - - for (element = cfg_list_first(dlzlist); - element != NULL; - element = cfg_list_next(element)) - { - dlz = cfg_listelt_value(element); - - obj = NULL; - (void)cfg_map_get(dlz, "database", &obj); - if (obj != NULL) { - dns_dlzdb_t *dlzdb = NULL; - const cfg_obj_t *name, *search = NULL; - char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - - if (s == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - result = isc_commandline_strtoargv(mctx, s, &dlzargc, - &dlzargv, 0); - if (result != ISC_R_SUCCESS) { - isc_mem_free(mctx, s); - goto cleanup; - } - - name = cfg_map_getname(dlz); - result = dns_dlzcreate(mctx, cfg_obj_asstring(name), - dlzargv[0], dlzargc, dlzargv, - &dlzdb); - isc_mem_free(mctx, s); - isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv)); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * If the DLZ backend supports configuration, - * and is searchable, then call its configure - * method now. If not searchable, we'll take - * care of it when we process the zone statement. - */ - (void)cfg_map_get(dlz, "search", &search); - if (search == NULL || cfg_obj_asboolean(search)) { - dlzdb->search = true; - result = dns_dlzconfigure(view, dlzdb, - dlzconfigure_callback); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(view->dlz_searched, - dlzdb, link); - } else { - dlzdb->search = false; - ISC_LIST_APPEND(view->dlz_unsearched, - dlzdb, link); - } - - } - } - - /* - * Obtain configuration parameters that affect the decision of whether - * we can reuse/share an existing cache. - */ - obj = NULL; - result = ns_config_get(maps, "cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - cleaning_interval = cfg_obj_asuint32(obj) * 60; - - obj = NULL; - result = ns_config_get(maps, "max-cache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_cache_size = 0; - } else if (cfg_obj_ispercentage(obj)) { - max_cache_size = SIZE_AS_PERCENT; - max_cache_size_percent = cfg_obj_aspercentage(obj); - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > SIZE_MAX) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "'max-cache-size " - "%" PRIu64 "' " - "is too large for this " - "system; reducing to %lu", - value, (unsigned long)SIZE_MAX); - value = SIZE_MAX; - } - max_cache_size = (size_t) value; - } - - if (max_cache_size == SIZE_AS_PERCENT) { - uint64_t totalphys = isc_meminfo_totalphys(); - - max_cache_size = - (size_t) (totalphys * max_cache_size_percent/100); - if (totalphys == 0) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "Unable to determine amount of physical " - "memory, setting 'max-cache-size' to " - "unlimited"); - } else { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_INFO, - "'max-cache-size %d%%' " - "- setting to %" PRIu64 "MB " - "(out of %" PRIu64 "MB)", - max_cache_size_percent, - (uint64_t)(max_cache_size / (1024*1024)), - totalphys / (1024*1024)); - } - } - - /* Check-names. */ - obj = NULL; - result = ns_checknames_get(maps, "response", &obj); - INSIST(result == ISC_R_SUCCESS); - - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "fail") == 0) { - resopts |= DNS_RESOLVER_CHECKNAMES | - DNS_RESOLVER_CHECKNAMESFAIL; - view->checknames = true; - } else if (strcasecmp(str, "warn") == 0) { - resopts |= DNS_RESOLVER_CHECKNAMES; - view->checknames = false; - } else if (strcasecmp(str, "ignore") == 0) { - view->checknames = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - zero_no_soattl = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dns64", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") && - strcmp(view->name, "_meta")) { - isc_netaddr_t na, suffix, *sp; - unsigned int prefixlen; - const char *server, *contact; - const cfg_obj_t *myobj; - - myobj = NULL; - result = ns_config_get(maps, "dns64-server", &myobj); - if (result == ISC_R_SUCCESS) - server = cfg_obj_asstring(myobj); - else - server = NULL; - - myobj = NULL; - result = ns_config_get(maps, "dns64-contact", &myobj); - if (result == ISC_R_SUCCESS) - contact = cfg_obj_asstring(myobj); - else - contact = NULL; - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *map = cfg_listelt_value(element); - dns_dns64_t *dns64 = NULL; - unsigned int dns64options = 0; - - cfg_obj_asnetprefix(cfg_map_getname(map), &na, - &prefixlen); - - obj = NULL; - (void)cfg_map_get(map, "suffix", &obj); - if (obj != NULL) { - sp = &suffix; - isc_netaddr_fromsockaddr(sp, - cfg_obj_assockaddr(obj)); - } else - sp = NULL; - - clients = mapped = excluded = NULL; - obj = NULL; - (void)cfg_map_get(map, "clients", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &clients); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - obj = NULL; - (void)cfg_map_get(map, "mapped", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &mapped); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - obj = NULL; - (void)cfg_map_get(map, "exclude", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &excluded); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else { - if (ns_g_mapped == NULL) { - result = create_mapped_acl(); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - dns_acl_attach(ns_g_mapped, &excluded); - } - - obj = NULL; - (void)cfg_map_get(map, "recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - dns64options |= DNS_DNS64_RECURSIVE_ONLY; - - obj = NULL; - (void)cfg_map_get(map, "break-dnssec", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - dns64options |= DNS_DNS64_BREAK_DNSSEC; - - result = dns_dns64_create(mctx, &na, prefixlen, sp, - clients, mapped, excluded, - dns64options, &dns64); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_dns64_append(&view->dns64, dns64); - view->dns64cnt++; - result = dns64_reverse(view, mctx, &na, prefixlen, - server, contact); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (clients != NULL) - dns_acl_detach(&clients); - if (mapped != NULL) - dns_acl_detach(&mapped); - if (excluded != NULL) - dns_acl_detach(&excluded); - } - } - - obj = NULL; - result = ns_config_get(maps, "dnssec-accept-expired", &obj); - INSIST(result == ISC_R_SUCCESS); - view->acceptexpired = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-validation", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - view->enablevalidation = cfg_obj_asboolean(obj); - } else { - /* If dnssec-validation is not boolean, it must be "auto" */ - view->enablevalidation = true; - auto_root = true; - } - - obj = NULL; - result = ns_config_get(maps, "max-cache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxcachettl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "max-ncache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxncachettl = cfg_obj_asuint32(obj); - if (view->maxncachettl > 7 * 24 * 3600) - view->maxncachettl = 7 * 24 * 3600; - - obj = NULL; - result = ns_config_get(maps, "max-stale-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - max_stale_ttl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "stale-answer-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswersenable = cfg_obj_asboolean(obj); - - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result == ISC_R_SUCCESS) { - view->staleanswersok = pview->staleanswersok; - dns_view_detach(&pview); - } else - view->staleanswersok = dns_stale_answer_conf; - - /* - * Configure the view's cache. - * - * First, check to see if there are any attach-cache options. If yes, - * attempt to lookup an existing cache at attach it to the view. If - * there is not one, then try to reuse an existing cache if possible; - * otherwise create a new cache. - * - * Note that the ADB is not preserved or shared in either case. - * - * When a matching view is found, the associated statistics are also - * retrieved and reused. - * - * XXX Determining when it is safe to reuse or share a cache is tricky. - * When the view's configuration changes, the cached data may become - * invalid because it reflects our old view of the world. We check - * some of the configuration parameters that could invalidate the cache - * or otherwise make it unshareable, but there are other configuration - * options that should be checked. For example, if a view uses a - * forwarder, changes in the forwarder configuration may invalidate - * the cache. At the moment, it's the administrator's responsibility to - * ensure these configuration options don't invalidate reusing/sharing. - */ - obj = NULL; - result = ns_config_get(maps, "attach-cache", &obj); - if (result == ISC_R_SUCCESS) - cachename = cfg_obj_asstring(obj); - else - cachename = view->name; - cache = NULL; - nsc = cachelist_find(cachelist, cachename, view->rdclass); - if (nsc != NULL) { - if (!cache_sharable(nsc->primaryview, view, zero_no_soattl, - cleaning_interval, max_cache_size, - max_stale_ttl)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "views %s and %s can't share the cache " - "due to configuration parameter mismatch", - nsc->primaryview->name, view->name); - result = ISC_R_FAILURE; - goto cleanup; - } - dns_cache_attach(nsc->cache, &cache); - shared_cache = true; - } else { - if (strcmp(cachename, view->name) == 0) { - result = dns_viewlist_find(&ns_g_server->viewlist, - cachename, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - if (!cache_reusable(pview, view, - zero_no_soattl)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), - "cache cannot be reused " - "for view %s due to " - "configuration parameter " - "mismatch", view->name); - } else { - INSIST(pview->cache != NULL); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(3), - "reusing existing cache"); - reused_cache = true; - dns_cache_attach(pview->cache, &cache); - } - dns_view_getresstats(pview, &resstats); - dns_view_getresquerystats(pview, - &resquerystats); - dns_view_detach(&pview); - } - } - if (cache == NULL) { - /* - * Create a cache with the desired name. This normally - * equals the view name, but may also be a forward - * reference to a view that share the cache with this - * view but is not yet configured. If it is not the - * view name but not a forward reference either, then it - * is simply a named cache that is not shared. - * - * We use two separate memory contexts for the - * cache, for the main cache memory and the heap - * memory. - */ - CHECK(isc_mem_create(0, 0, &cmctx)); - isc_mem_setname(cmctx, "cache", NULL); - CHECK(isc_mem_create(0, 0, &hmctx)); - isc_mem_setname(hmctx, "cache_heap", NULL); - CHECK(dns_cache_create3(cmctx, hmctx, ns_g_taskmgr, - ns_g_timermgr, view->rdclass, - cachename, "rbt", 0, NULL, - &cache)); - isc_mem_detach(&cmctx); - isc_mem_detach(&hmctx); - } - nsc = isc_mem_get(mctx, sizeof(*nsc)); - if (nsc == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - nsc->cache = NULL; - dns_cache_attach(cache, &nsc->cache); - nsc->primaryview = view; - nsc->needflush = false; - nsc->adbsizeadjusted = false; - nsc->rdclass = view->rdclass; - ISC_LINK_INIT(nsc, link); - ISC_LIST_APPEND(*cachelist, nsc, link); - } - dns_view_setcache2(view, cache, shared_cache); - - /* - * cache-file cannot be inherited if views are present, but this - * should be caught by the configuration checking stage. - */ - obj = NULL; - result = ns_config_get(maps, "cache-file", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { - CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); - if (!reused_cache && !shared_cache) - CHECK(dns_cache_load(cache)); - } - - dns_cache_setcleaninginterval(cache, cleaning_interval); - dns_cache_setcachesize(cache, max_cache_size); - dns_cache_setservestalettl(cache, max_stale_ttl); - - dns_cache_detach(&cache); - - obj = NULL; - result = ns_config_get(maps, "stale-answer-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswerttl = ISC_MAX(cfg_obj_asuint32(obj), 1); - - /* - * Resolver. - * - * XXXRTH Hardwired number of tasks. - */ - CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4, &dscp4, - (ISC_LIST_PREV(view, link) - == NULL))); - CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6, &dscp6, - (ISC_LIST_PREV(view, link) - == NULL))); - if (dispatch4 == NULL && dispatch6 == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unable to obtain neither an IPv4 nor" - " an IPv6 dispatch"); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - if (resstats == NULL) { - CHECK(isc_stats_create(mctx, &resstats, - dns_resstatscounter_max)); - } - dns_view_setresstats(view, resstats); - if (resquerystats == NULL) - CHECK(dns_rdatatypestats_create(mctx, &resquerystats)); - dns_view_setresquerystats(view, resquerystats); - - ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH); - CHECK(dns_view_createresolver(view, ns_g_taskmgr, RESOLVER_NTASKS, - ndisp, ns_g_socketmgr, ns_g_timermgr, - resopts, ns_g_dispatchmgr, - dispatch4, dispatch6)); - - if (dscp4 == -1) - dscp4 = ns_g_dscp; - if (dscp6 == -1) - dscp6 = ns_g_dscp; - if (dscp4 != -1) - dns_resolver_setquerydscp4(view->resolver, dscp4); - if (dscp6 != -1) - dns_resolver_setquerydscp6(view->resolver, dscp6); - - /* - * Set the ADB cache size to 1/8th of the max-cache-size or - * MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared. - */ - max_adb_size = 0; - if (max_cache_size != 0U) { - max_adb_size = max_cache_size / 8; - if (max_adb_size == 0U) - max_adb_size = 1; /* Force minimum. */ - if (view != nsc->primaryview && - max_adb_size > MAX_ADB_SIZE_FOR_CACHESHARE) { - max_adb_size = MAX_ADB_SIZE_FOR_CACHESHARE; - if (!nsc->adbsizeadjusted) { - dns_adb_setadbsize(nsc->primaryview->adb, - MAX_ADB_SIZE_FOR_CACHESHARE); - nsc->adbsizeadjusted = true; - } - } - } - dns_adb_setadbsize(view->adb, max_adb_size); - - /* - * Set up ADB quotas - */ - { - uint32_t fps, freq; - double low, high, discount; - - obj = NULL; - result = ns_config_get(maps, "fetches-per-server", &obj); - INSIST(result == ISC_R_SUCCESS); - obj2 = cfg_tuple_get(obj, "fetches"); - fps = cfg_obj_asuint32(obj2); - obj2 = cfg_tuple_get(obj, "response"); - if (!cfg_obj_isvoid(obj2)) { - const char *resp = cfg_obj_asstring(obj2); - isc_result_t r = DNS_R_SERVFAIL; - - if (strcasecmp(resp, "drop") == 0) { - r = DNS_R_DROP; - } else if (strcasecmp(resp, "fail") == 0) { - r = DNS_R_SERVFAIL; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - dns_resolver_setquotaresponse(view->resolver, - dns_quotatype_server, r); - } - - obj = NULL; - result = ns_config_get(maps, "fetch-quota-params", &obj); - INSIST(result == ISC_R_SUCCESS); - - obj2 = cfg_tuple_get(obj, "frequency"); - freq = cfg_obj_asuint32(obj2); - - obj2 = cfg_tuple_get(obj, "low"); - low = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - obj2 = cfg_tuple_get(obj, "high"); - high = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - obj2 = cfg_tuple_get(obj, "discount"); - discount = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - dns_adb_setquota(view->adb, fps, freq, low, high, discount); - } - - /* - * Set resolver's lame-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "lame-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - lame_ttl = cfg_obj_asuint32(obj); - if (lame_ttl > 1800) - lame_ttl = 1800; - dns_resolver_setlamettl(view->resolver, lame_ttl); - - /* - * Set the resolver's query timeout. - */ - obj = NULL; - result = ns_config_get(maps, "resolver-query-timeout", &obj); - INSIST(result == ISC_R_SUCCESS); - query_timeout = cfg_obj_asuint32(obj); - dns_resolver_settimeout(view->resolver, query_timeout); - - /* Specify whether to use 0-TTL for negative response for SOA query */ - dns_resolver_setzeronosoattl(view->resolver, zero_no_soattl); - - /* - * Set the resolver's EDNS UDP size. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - dns_resolver_setudpsize(view->resolver, (uint16_t)udpsize); - - /* - * Set the maximum UDP response size. - */ - obj = NULL; - result = ns_config_get(maps, "max-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - view->maxudp = udpsize; - - /* - * Set the maximum UDP when a COOKIE is not provided. - */ - obj = NULL; - result = ns_config_get(maps, "nocookie-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 128) - udpsize = 128; - if (udpsize > view->maxudp) - udpsize = view->maxudp; - view->nocookieudp = udpsize; - - /* - * Set the maximum rsa exponent bits. - */ - obj = NULL; - result = ns_config_get(maps, "max-rsa-exponent-size", &obj); - INSIST(result == ISC_R_SUCCESS); - maxbits = cfg_obj_asuint32(obj); - if (maxbits != 0 && maxbits < 35) - maxbits = 35; - if (maxbits > 4096) - maxbits = 4096; - view->maxbits = maxbits; - - /* - * Set resolver retry parameters. - */ - obj = NULL; - CHECK(ns_config_get(maps, "resolver-retry-interval", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setretryinterval(view->resolver, resolver_param); - - obj = NULL; - CHECK(ns_config_get(maps, "resolver-nonbackoff-tries", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setnonbackofftries(view->resolver, resolver_param); - - /* - * Set supported DNSSEC algorithms. - */ - dns_resolver_reset_algorithms(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-algorithms", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_algorithms(cfg_listelt_value(element), - view->resolver)); - } - - /* - * Set supported DS/DLV digest types. - */ - dns_resolver_reset_ds_digests(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-ds-digests", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_ds_digests(cfg_listelt_value(element), - view->resolver)); - } - - /* - * A global or view "forwarders" option, if present, - * creates an entry for "." in the forwarding table. - */ - forwardtype = NULL; - forwarders = NULL; - (void)ns_config_get(maps, "forward", &forwardtype); - (void)ns_config_get(maps, "forwarders", &forwarders); - if (forwarders != NULL) - CHECK(configure_forward(config, view, dns_rootname, - forwarders, forwardtype)); - - /* - * Dual Stack Servers. - */ - alternates = NULL; - (void)ns_config_get(maps, "dual-stack-servers", &alternates); - if (alternates != NULL) - CHECK(configure_alternates(config, view, alternates)); - - /* - * We have default hints for class IN if we need them. - */ - if (view->rdclass == dns_rdataclass_in && view->hints == NULL) - dns_view_sethints(view, ns_g_server->in_roothints); - - /* - * If we still have no hints, this is a non-IN view with no - * "hints zone" configured. Issue a warning, except if this - * is a root server. Root servers never need to consult - * their hints, so it's no point requiring users to configure - * them. - */ - if (view->hints == NULL) { - dns_zone_t *rootzone = NULL; - (void)dns_view_findzone(view, dns_rootname, &rootzone); - if (rootzone != NULL) { - dns_zone_detach(&rootzone); - need_hints = false; - } - if (need_hints) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "no root hints for view '%s'", - view->name); - } - - /* - * Configure the view's TSIG keys. - */ - CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); - if (ns_g_server->sessionkey != NULL) { - CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname, - ns_g_server->sessionkey)); - } - dns_view_setkeyring(view, ring); - dns_tsigkeyring_detach(&ring); - - /* - * See if we can re-use a dynamic key ring. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - dns_view_getdynamickeyring(pview, &ring); - if (ring != NULL) - dns_view_setdynamickeyring(view, ring); - dns_tsigkeyring_detach(&ring); - dns_view_detach(&pview); - } else - dns_view_restorekeyring(view); - - /* - * Configure the view's peer list. - */ - { - const cfg_obj_t *peers = NULL; - dns_peerlist_t *newpeers = NULL; - - (void)ns_config_get(cfgmaps, "server", &peers); - CHECK(dns_peerlist_new(mctx, &newpeers)); - for (element = cfg_list_first(peers); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *cpeer = cfg_listelt_value(element); - dns_peer_t *peer; - - CHECK(configure_peer(cpeer, mctx, &peer)); - dns_peerlist_addpeer(newpeers, peer); - dns_peer_detach(&peer); - } - dns_peerlist_detach(&view->peers); - view->peers = newpeers; /* Transfer ownership. */ - } - - /* - * Configure the views rrset-order. - */ - { - const cfg_obj_t *rrsetorder = NULL; - - (void)ns_config_get(maps, "rrset-order", &rrsetorder); - CHECK(dns_order_create(mctx, &order)); - for (element = cfg_list_first(rrsetorder); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *ent = cfg_listelt_value(element); - - CHECK(configure_order(order, ent)); - } - if (view->order != NULL) - dns_order_detach(&view->order); - dns_order_attach(order, &view->order); - dns_order_detach(&order); - } - /* - * Copy the aclenv object. - */ - dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); - - /* - * Configure the "match-clients" and "match-destinations" ACL. - * (These are only meaningful at the view level, but 'config' - * must be passed so that named ACLs defined at the global level - * can be retrieved.) - */ - CHECK(configure_view_acl(vconfig, config, NULL, "match-clients", - NULL, actx, ns_g_mctx, - &view->matchclients)); - CHECK(configure_view_acl(vconfig, config, NULL, "match-destinations", - NULL, actx, ns_g_mctx, - &view->matchdestinations)); - - /* - * Configure the "match-recursive-only" option. - */ - obj = NULL; - (void)ns_config_get(maps, "match-recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - view->matchrecursiveonly = true; - else - view->matchrecursiveonly = false; - - /* - * Configure other configurable data. - */ - obj = NULL; - result = ns_config_get(maps, "recursion", &obj); - INSIST(result == ISC_R_SUCCESS); - view->recursion = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "auth-nxdomain", &obj); - INSIST(result == ISC_R_SUCCESS); - view->auth_nxdomain = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-any", &obj); - INSIST(result == ISC_R_SUCCESS); - view->minimal_any = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-responses", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->minimalresponses = dns_minimal_yes; - else - view->minimalresponses = dns_minimal_no; - } else { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "no-auth") == 0) { - view->minimalresponses = dns_minimal_noauth; - } else if (strcasecmp(str, "no-auth-recursive") == 0) { - view->minimalresponses = dns_minimal_noauthrec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "transfer-format", &obj); - INSIST(result == ISC_R_SUCCESS); - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) { - view->transfer_format = dns_many_answers; - } else if (strcasecmp(str, "one-answer") == 0) { - view->transfer_format = dns_one_answer; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "trust-anchor-telemetry", &obj); - INSIST(result == ISC_R_SUCCESS); - view->trust_anchor_telemetry = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "root-key-sentinel", &obj); - INSIST(result == ISC_R_SUCCESS); - view->root_key_sentinel = cfg_obj_asboolean(obj); - - /* - * Set sources where additional data and CNAME/DNAME - * targets for authoritative answers may be found. - */ - obj = NULL; - result = ns_config_get(maps, "additional-from-auth", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromauth = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromauth) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-auth no' is only supported " - "with 'recursion no'"); - view->additionalfromauth = true; - } - - obj = NULL; - result = ns_config_get(maps, "additional-from-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromcache = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromcache) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-cache no' is only supported " - "with 'recursion no'"); - view->additionalfromcache = true; - } - - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-query-cache-on", NULL, actx, - ns_g_mctx, &view->cacheonacl)); - - /* - * Set the "allow-query", "allow-query-cache", "allow-recursion", - * and "allow-recursion-on" ACLs if configured in named.conf, but - * NOT from the global defaults. This is done by leaving the third - * argument to configure_view_acl() NULL. - * - * We ignore the global defaults here because these ACLs - * can inherit from each other. If any are still unset after - * applying the inheritance rules, we'll look up the defaults at - * that time. - */ - - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-query", NULL, actx, - ns_g_mctx, &view->queryacl)); - - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-query-cache", NULL, actx, - ns_g_mctx, &view->cacheacl)); - - if (strcmp(view->name, "_bind") != 0 && - view->rdclass != dns_rdataclass_chaos) - { - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-recursion", NULL, actx, - ns_g_mctx, &view->recursionacl)); - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-recursion-on", NULL, actx, - ns_g_mctx, &view->recursiononacl)); - } - - if (view->recursion) { - /* - * "allow-query-cache" inherits from "allow-recursion" if set, - * otherwise from "allow-query" if set. - * "allow-recursion" inherits from "allow-query-cache" if set, - * otherwise from "allow-query" if set. - */ - if (view->cacheacl == NULL) { - if (view->recursionacl != NULL) { - dns_acl_attach(view->recursionacl, - &view->cacheacl); - } else if (view->queryacl != NULL) { - dns_acl_attach(view->queryacl, - &view->cacheacl); - } - } - if (view->recursionacl == NULL) { - if (view->cacheacl != NULL) { - dns_acl_attach(view->cacheacl, - &view->recursionacl); - } else if (view->queryacl != NULL) { - dns_acl_attach(view->queryacl, - &view->recursionacl); - } - } - - /* - * If any are still unset, we now get default "allow-recursion", - * "allow-recursion-on" and "allow-query-cache" ACLs from - * the global config. - */ - /* cppcheck-suppress duplicateCondition */ - if (view->recursionacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-recursion", NULL, - actx, ns_g_mctx, - &view->recursionacl)); - } - /* cppcheck-suppress duplicateCondition */ - if (view->recursiononacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-recursion-on", NULL, - actx, ns_g_mctx, - &view->recursiononacl)); - } - if (view->cacheacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-query-cache", NULL, - actx, ns_g_mctx, - &view->cacheacl)); - } - } else if (view->cacheacl == NULL) { - /* - * We're not recursive; if "allow-query-cache" hasn't been - * set at the options/view level, set it to none. - */ - CHECK(dns_acl_none(mctx, &view->cacheacl)); - } - - if (view->queryacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-query", NULL, - actx, ns_g_mctx, - &view->queryacl)); - } - - /* - * Ignore case when compressing responses to the specified - * clients. This causes case not always to be preserved, - * and is needed by some broken clients. - */ - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "no-case-compress", NULL, actx, - ns_g_mctx, &view->nocasecompress)); - - /* - * Disable name compression completely, this is a tradeoff - * between CPU and network usage. - */ - obj = NULL; - result = ns_config_get(maps, "message-compression", &obj); - INSIST(result == ISC_R_SUCCESS); - view->msgcompression = cfg_obj_asboolean(obj); - - /* - * Filter setting on addresses in the answer section. - */ - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "deny-answer-addresses", "acl", - actx, ns_g_mctx, - &view->denyansweracl)); - CHECK(configure_view_nametable(vconfig, config, "deny-answer-addresses", - "except-from", ns_g_mctx, - &view->answeracl_exclude)); - - /* - * Filter setting on names (CNAME/DNAME targets) in the answer section. - */ - CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases", - "name", ns_g_mctx, - &view->denyanswernames)); - CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases", - "except-from", ns_g_mctx, - &view->answernames_exclude)); - - /* - * Configure sortlist, if set - */ - CHECK(configure_view_sortlist(vconfig, config, actx, ns_g_mctx, - &view->sortlist)); - - /* - * Configure default allow-notify, allow-update - * and allow-update-forwarding ACLs, so they can be - * inherited by zones. (Note these cannot be set at - * options/view level.) - */ - if (view->notifyacl == NULL) { - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-notify", NULL, actx, - ns_g_mctx, &view->notifyacl)); - } - if (view->updateacl == NULL) { - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-update", NULL, actx, - ns_g_mctx, &view->updateacl)); - } - if (view->upfwdacl == NULL) { - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-update-forwarding", NULL, actx, - ns_g_mctx, &view->upfwdacl)); - } - - /* - * Configure default allow-transer ACL so it can be inherited - * by zones. (Note this *can* be set at options or view level.) - */ - if (view->transferacl == NULL) { - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-transfer", NULL, actx, - ns_g_mctx, &view->transferacl)); - } - - obj = NULL; - result = ns_config_get(maps, "provide-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->provideixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "request-nsid", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requestnsid = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "send-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - view->sendcookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "require-server-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requireservercookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "v6-bias", &obj); - INSIST(result == ISC_R_SUCCESS); - view->v6bias = cfg_obj_asuint32(obj) * 1000; - - obj = NULL; - result = ns_config_get(maps, "max-clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - max_clients_per_query = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setclientsperquery(view->resolver, - cfg_obj_asuint32(obj), - max_clients_per_query); - - obj = NULL; - result = ns_config_get(maps, "max-recursion-depth", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-recursion-queries", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "fetches-per-zone", &obj); - INSIST(result == ISC_R_SUCCESS); - obj2 = cfg_tuple_get(obj, "fetches"); - dns_resolver_setfetchesperzone(view->resolver, cfg_obj_asuint32(obj2)); - obj2 = cfg_tuple_get(obj, "response"); - if (!cfg_obj_isvoid(obj2)) { - const char *resp = cfg_obj_asstring(obj2); - isc_result_t r = DNS_R_SERVFAIL; - - if (strcasecmp(resp, "drop") == 0) { - r = DNS_R_DROP; - } else if (strcasecmp(resp, "fail") == 0) { - r = DNS_R_SERVFAIL; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - dns_resolver_setquotaresponse(view->resolver, - dns_quotatype_zone, r); - } - -#ifdef ALLOW_FILTER_AAAA - obj = NULL; - result = ns_config_get(maps, "filter-aaaa-on-v4", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->v4_aaaa = dns_aaaa_filter; - else - view->v4_aaaa = dns_aaaa_ok; - } else { - const char *v4_aaaastr = cfg_obj_asstring(obj); - if (strcasecmp(v4_aaaastr, "break-dnssec") == 0) { - view->v4_aaaa = dns_aaaa_break_dnssec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "filter-aaaa-on-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->v6_aaaa = dns_aaaa_filter; - else - view->v6_aaaa = dns_aaaa_ok; - } else { - const char *v6_aaaastr = cfg_obj_asstring(obj); - if (strcasecmp(v6_aaaastr, "break-dnssec") == 0) { - view->v6_aaaa = dns_aaaa_break_dnssec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "filter-aaaa", NULL, actx, - ns_g_mctx, &view->aaaa_acl)); -#endif - obj = NULL; - result = ns_config_get(maps, "prefetch", &obj); - if (result == ISC_R_SUCCESS) { - const cfg_obj_t *trigger, *eligible; - - trigger = cfg_tuple_get(obj, "trigger"); - view->prefetch_trigger = cfg_obj_asuint32(trigger); - if (view->prefetch_trigger > 10) - view->prefetch_trigger = 10; - eligible = cfg_tuple_get(obj, "eligible"); - if (cfg_obj_isvoid(eligible)) { - int m; - for (m = 1; maps[m] != NULL; m++) { - obj = NULL; - result = ns_config_get(&maps[m], - "prefetch", &obj); - INSIST(result == ISC_R_SUCCESS); - eligible = cfg_tuple_get(obj, "eligible"); - if (cfg_obj_isuint32(eligible)) - break; - } - INSIST(cfg_obj_isuint32(eligible)); - } - view->prefetch_eligible = cfg_obj_asuint32(eligible); - if (view->prefetch_eligible < view->prefetch_trigger + 6) - view->prefetch_eligible = view->prefetch_trigger + 6; - } - - obj = NULL; - result = ns_config_get(maps, "dnssec-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->enablednssec = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(optionmaps, "dnssec-lookaside", &obj); - if (result == ISC_R_SUCCESS) { - /* "auto" is deprecated, log a warning if seen */ - const char *dom; - dlvobj = cfg_listelt_value(cfg_list_first(obj)); - dom = cfg_obj_asstring(cfg_tuple_get(dlvobj, "domain")); - if (cfg_obj_isvoid(cfg_tuple_get(dlvobj, "trust-anchor"))) { - /* If "no", skip; if "auto", log warning */ - if (!strcasecmp(dom, "no")) { - result = ISC_R_NOTFOUND; - } else if (!strcasecmp(dom, "auto")) { - /* - * Warning logged by libbind9. - */ - result = ISC_R_NOTFOUND; - } - } - } - - if (result == ISC_R_SUCCESS) { - dns_name_t *dlv, *iscdlv; - dns_fixedname_t f; - - /* Also log a warning if manually configured to dlv.isc.org */ - iscdlv = dns_fixedname_initname(&f); - CHECK(dns_name_fromstring(iscdlv, "dlv.isc.org", 0, NULL)); - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - obj = cfg_tuple_get(obj, "trust-anchor"); - - dlv = dns_fixedname_name(&view->dlv_fixed); - CHECK(dns_name_fromstring(dlv, cfg_obj_asstring(obj), - DNS_NAME_DOWNCASE, NULL)); - if (dns_name_equal(dlv, iscdlv)) { - /* - * Warning logged by libbind9. - */ - view->dlv = NULL; - } else { - view->dlv = dlv; - } - } - } else { - view->dlv = NULL; - } - - /* - * For now, there is only one kind of trusted keys, the - * "security roots". - */ - CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys, - auto_root, mctx)); - dns_resolver_resetmustbesecure(view->resolver); - obj = NULL; - result = ns_config_get(maps, "dnssec-must-be-secure", &obj); - if (result == ISC_R_SUCCESS) - CHECK(mustbesecure(obj, view->resolver)); - - obj = NULL; - result = ns_config_get(maps, "nta-recheck", &obj); - INSIST(result == ISC_R_SUCCESS); - view->nta_recheck = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "nta-lifetime", &obj); - INSIST(result == ISC_R_SUCCESS); - view->nta_lifetime = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "preferred-glue", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "a") == 0) - view->preferred_glue = dns_rdatatype_a; - else if (strcasecmp(str, "aaaa") == 0) - view->preferred_glue = dns_rdatatype_aaaa; - else - view->preferred_glue = 0; - } else - view->preferred_glue = 0; - - obj = NULL; - result = ns_config_get(maps, "root-delegation-only", &obj); - if (result == ISC_R_SUCCESS) - dns_view_setrootdelonly(view, true); - if (result == ISC_R_SUCCESS && ! cfg_obj_isvoid(obj)) { - const cfg_obj_t *exclude; - dns_fixedname_t fixed; - dns_name_t *name; - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - exclude = cfg_listelt_value(element); - CHECK(dns_name_fromstring(name, - cfg_obj_asstring(exclude), - 0, NULL)); - CHECK(dns_view_excludedelegationonly(view, name)); - } - } else - dns_view_setrootdelonly(view, false); - - /* - * Load DynDB modules. - */ - dyndb_list = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "dyndb", &dyndb_list); - else - (void)cfg_map_get(config, "dyndb", &dyndb_list); - -#ifdef HAVE_DLOPEN - for (element = cfg_list_first(dyndb_list); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *dyndb = cfg_listelt_value(element); - - if (dctx == NULL) { - const void *hashinit = isc_hash_get_initializer(); - CHECK(dns_dyndb_createctx(mctx, hashinit, - ns_g_lctx, view, - ns_g_server->zonemgr, - ns_g_server->task, - ns_g_timermgr, &dctx)); - } - - CHECK(configure_dyndb(dyndb, mctx, dctx)); - } -#endif - - /* - * Setup automatic empty zones. If recursion is off then - * they are disabled by default. - */ - obj = NULL; - (void)ns_config_get(maps, "empty-zones-enable", &obj); - (void)ns_config_get(maps, "disable-empty-zone", &disablelist); - if (obj == NULL && disablelist == NULL && - view->rdclass == dns_rdataclass_in) { - empty_zones_enable = view->recursion; - } else if (view->rdclass == dns_rdataclass_in) { - if (obj != NULL) - empty_zones_enable = cfg_obj_asboolean(obj); - else - empty_zones_enable = view->recursion; - } else { - empty_zones_enable = false; - } - - if (empty_zones_enable && !lwresd_g_useresolvconf) { - const char *empty; - int empty_zone = 0; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t buffer; - char server[DNS_NAME_FORMATSIZE + 1]; - char contact[DNS_NAME_FORMATSIZE + 1]; - const char *empty_dbtype[4] = - { "_builtin", "empty", NULL, NULL }; - int empty_dbtypec = 4; - dns_zonestat_level_t statlevel = dns_zonestat_none; - - name = dns_fixedname_initname(&fixed); - - obj = NULL; - result = ns_config_get(maps, "empty-server", &obj); - if (result == ISC_R_SUCCESS) { - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), - 0, NULL)); - isc_buffer_init(&buffer, server, sizeof(server) - 1); - CHECK(dns_name_totext(name, false, &buffer)); - server[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[2] = server; - } else - empty_dbtype[2] = "@"; - - obj = NULL; - result = ns_config_get(maps, "empty-contact", &obj); - if (result == ISC_R_SUCCESS) { - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), - 0, NULL)); - isc_buffer_init(&buffer, contact, sizeof(contact) - 1); - CHECK(dns_name_totext(name, false, &buffer)); - contact[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[3] = contact; - } else - empty_dbtype[3] = "."; - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - statlevel = dns_zonestat_full; - else - statlevel = dns_zonestat_none; - } else { - const char *levelstr = cfg_obj_asstring(obj); - if (strcasecmp(levelstr, "full") == 0) { - statlevel = dns_zonestat_full; - } else if (strcasecmp(levelstr, "terse") == 0) { - statlevel = dns_zonestat_terse; - } else if (strcasecmp(levelstr, "none") == 0) { - statlevel = dns_zonestat_none; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - for (empty = empty_zones[empty_zone]; - empty != NULL; - empty = empty_zones[++empty_zone]) - { - dns_forwarders_t *dnsforwarders = NULL; - - /* - * Look for zone on drop list. - */ - CHECK(dns_name_fromstring(name, empty, 0, NULL)); - if (disablelist != NULL && - on_disable_list(disablelist, name)) - continue; - - /* - * This zone already exists. - */ - (void)dns_view_findzone(view, name, &zone); - if (zone != NULL) { - dns_zone_detach(&zone); - continue; - } - - /* - * If we would forward this name don't add a - * empty zone for it. - */ - result = dns_fwdtable_find(view->fwdtable, name, - &dnsforwarders); - if (result == ISC_R_SUCCESS && - dnsforwarders->fwdpolicy == dns_fwdpolicy_only) - continue; - - /* - * See if we can re-use a existing zone. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && - result != ISC_R_SUCCESS) - goto cleanup; - - if (pview != NULL) { - (void)dns_view_findzone(pview, name, &zone); - dns_view_detach(&pview); - } - - CHECK(create_empty_zone(zone, name, view, zonelist, - empty_dbtype, empty_dbtypec, - statlevel)); - if (zone != NULL) - dns_zone_detach(&zone); - } - } - - obj = NULL; - result = ns_config_get(maps, "rate-limit", &obj); - if (result == ISC_R_SUCCESS) { - result = configure_rrl(view, config, obj); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - /* - * Set the servfail-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "servfail-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - fail_ttl = cfg_obj_asuint32(obj); - if (fail_ttl > 30) - fail_ttl = 30; - dns_view_setfailttl(view, fail_ttl); - - /* - * Name space to look up redirect information in. - */ - obj = NULL; - result = ns_config_get(maps, "nxdomain-redirect", &obj); - if (result == ISC_R_SUCCESS) { - dns_name_t *name = dns_fixedname_name(&view->redirectfixed); - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), 0, - NULL)); - view->redirectzone = name; - } else - view->redirectzone = NULL; - -#ifdef HAVE_DNSTAP - /* - * Set up the dnstap environment and configure message - * types to log. - */ - CHECK(configure_dnstap(maps, view)); -#endif /* HAVE_DNSTAP */ - - result = ISC_R_SUCCESS; - - cleanup: - if (clients != NULL) - dns_acl_detach(&clients); - if (mapped != NULL) - dns_acl_detach(&mapped); - if (excluded != NULL) - dns_acl_detach(&excluded); - if (ring != NULL) - dns_tsigkeyring_detach(&ring); - if (zone != NULL) - dns_zone_detach(&zone); - if (dispatch4 != NULL) - dns_dispatch_detach(&dispatch4); - if (dispatch6 != NULL) - dns_dispatch_detach(&dispatch6); - if (resstats != NULL) - isc_stats_detach(&resstats); - if (resquerystats != NULL) - dns_stats_detach(&resquerystats); - if (order != NULL) - dns_order_detach(&order); - if (cmctx != NULL) - isc_mem_detach(&cmctx); - if (hmctx != NULL) - isc_mem_detach(&hmctx); - - if (cache != NULL) - dns_cache_detach(&cache); - if (dctx != NULL) - dns_dyndb_destroyctx(&dctx); - - return (result); -} - -static isc_result_t -configure_hints(dns_view_t *view, const char *filename) { - isc_result_t result; - dns_db_t *db; - - db = NULL; - result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); - if (result == ISC_R_SUCCESS) { - dns_view_sethints(view, db); - dns_db_detach(&db); - } - - return (result); -} - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates) -{ - const cfg_obj_t *portobj; - const cfg_obj_t *addresses; - const cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - in_port_t port; - - /* - * Determine which port to send requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (alternates != NULL) { - portobj = cfg_tuple_get(alternates, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - addresses = NULL; - if (alternates != NULL) - addresses = cfg_tuple_get(alternates, "addresses"); - - for (element = cfg_list_first(addresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *alternate = cfg_listelt_value(element); - isc_sockaddr_t sa; - - if (!cfg_obj_issockaddr(alternate)) { - dns_fixedname_t fixed; - dns_name_t *name; - const char *str = cfg_obj_asstring(cfg_tuple_get( - alternate, "name")); - isc_buffer_t buffer; - in_port_t myport = port; - - isc_buffer_constinit(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - name = dns_fixedname_initname(&fixed); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0, - NULL)); - - portobj = cfg_tuple_get(alternate, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, - ISC_LOG_ERROR, - "port '%u' out of range", - val); - return (ISC_R_RANGE); - } - myport = (in_port_t) val; - } - CHECK(dns_resolver_addalternate(view->resolver, NULL, - name, myport)); - continue; - } - - sa = *cfg_obj_assockaddr(alternate); - if (isc_sockaddr_getport(&sa) == 0) - isc_sockaddr_setport(&sa, port); - CHECK(dns_resolver_addalternate(view->resolver, &sa, - NULL, 0)); - } - - cleanup: - return (result); -} - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype) -{ - const cfg_obj_t *portobj, *dscpobj; - const cfg_obj_t *faddresses; - const cfg_listelt_t *element; - dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; - dns_forwarderlist_t fwdlist; - dns_forwarder_t *fwd; - isc_result_t result; - in_port_t port; - isc_dscp_t dscp = -1; - - ISC_LIST_INIT(fwdlist); - - /* - * Determine which port to send forwarded requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (forwarders != NULL) { - portobj = cfg_tuple_get(forwarders, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - /* - * DSCP value for forwarded requests. - */ - dscp = ns_g_dscp; - if (forwarders != NULL) { - dscpobj = cfg_tuple_get(forwarders, "dscp"); - if (cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - } - - faddresses = NULL; - if (forwarders != NULL) - faddresses = cfg_tuple_get(forwarders, "addresses"); - - for (element = cfg_list_first(faddresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *forwarder = cfg_listelt_value(element); - fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t)); - if (fwd == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - fwd->addr = *cfg_obj_assockaddr(forwarder); - if (isc_sockaddr_getport(&fwd->addr) == 0) - isc_sockaddr_setport(&fwd->addr, port); - fwd->dscp = cfg_obj_getdscp(forwarder); - if (fwd->dscp == -1) - fwd->dscp = dscp; - ISC_LINK_INIT(fwd, link); - ISC_LIST_APPEND(fwdlist, fwd, link); - } - - if (ISC_LIST_EMPTY(fwdlist)) { - if (forwardtype != NULL) - cfg_obj_log(forwardtype, ns_g_lctx, ISC_LOG_WARNING, - "no forwarders seen; disabling " - "forwarding"); - fwdpolicy = dns_fwdpolicy_none; - } else { - if (forwardtype == NULL) { - fwdpolicy = dns_fwdpolicy_first; - } else { - const char *forwardstr = cfg_obj_asstring(forwardtype); - if (strcasecmp(forwardstr, "first") == 0) { - fwdpolicy = dns_fwdpolicy_first; - } else if (strcasecmp(forwardstr, "only") == 0) { - fwdpolicy = dns_fwdpolicy_only; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - } - - result = dns_fwdtable_addfwd(view->fwdtable, origin, &fwdlist, - fwdpolicy); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(origin, namebuf, sizeof(namebuf)); - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "could not set up forwarding for domain '%s': %s", - namebuf, isc_result_totext(result)); - goto cleanup; - } - - result = ISC_R_SUCCESS; - - cleanup: - - while (!ISC_LIST_EMPTY(fwdlist)) { - fwd = ISC_LIST_HEAD(fwdlist); - ISC_LIST_UNLINK(fwdlist, fwd, link); - isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t)); - } - - return (result); -} - -static isc_result_t -get_viewinfo(const cfg_obj_t *vconfig, const char **namep, - dns_rdataclass_t *classp) -{ - isc_result_t result = ISC_R_SUCCESS; - const char *viewname; - dns_rdataclass_t viewclass; - - REQUIRE(namep != NULL && *namep == NULL); - REQUIRE(classp != NULL); - - if (vconfig != NULL) { - const cfg_obj_t *classobj = NULL; - - viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); - classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - if (dns_rdataclass_ismeta(viewclass)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "view '%s': class must not be meta", - viewname); - CHECK(ISC_R_FAILURE); - } - } else { - viewname = "_default"; - viewclass = dns_rdataclass_in; - } - - *namep = viewname; - *classp = viewclass; - -cleanup: - return (result); -} - -/* - * Find a view based on its configuration info and attach to it. - * - * If 'vconfig' is NULL, attach to the default view. - */ -static isc_result_t -find_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, - dns_view_t **viewp) -{ - isc_result_t result; - const char *viewname = NULL; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - result = get_viewinfo(vconfig, &viewname, &viewclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result != ISC_R_SUCCESS) - return (result); - - *viewp = view; - return (ISC_R_SUCCESS); -} - -/* - * Create a new view and add it to the list. - * - * If 'vconfig' is NULL, create the default view. - * - * The view created is attached to '*viewp'. - */ -static isc_result_t -create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, - dns_view_t **viewp) -{ - isc_result_t result; - const char *viewname = NULL; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - result = get_viewinfo(vconfig, &viewname, &viewclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result == ISC_R_SUCCESS) - return (ISC_R_EXISTS); - if (result != ISC_R_NOTFOUND) - return (result); - INSIST(view == NULL); - - result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_entropy_getdata(ns_g_entropy, view->secret, - sizeof(view->secret), NULL, 0); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - return (result); - } - -#ifdef HAVE_GEOIP - view->aclenv.geoip = ns_g_geoip; -#endif - - ISC_LIST_APPEND(*viewlist, view, link); - dns_view_attach(view, viewp); - return (ISC_R_SUCCESS); -} - -/* - * Configure or reconfigure a zone. - */ -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf, - bool added, bool old_rpz_ok, - bool modify) -{ - dns_view_t *pview = NULL; /* Production view */ - dns_zone_t *zone = NULL; /* New or reused zone */ - dns_zone_t *raw = NULL; /* New or reused raw zone */ - dns_zone_t *dupzone = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *typeobj = NULL; - const cfg_obj_t *forwarders = NULL; - const cfg_obj_t *forwardtype = NULL; - const cfg_obj_t *ixfrfromdiffs = NULL; - const cfg_obj_t *only = NULL; - const cfg_obj_t *signing = NULL; - const cfg_obj_t *viewobj = NULL; - isc_result_t result; - isc_result_t tresult; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - const char *zname; - dns_rdataclass_t zclass; - const char *ztypestr; - dns_rpz_num_t rpz_num; - bool zone_is_catz = false; - - options = NULL; - (void)cfg_map_get(config, "options", &options); - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * Get the zone origin as a dns_name_t. - */ - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - isc_buffer_constinit(&buffer, zname, strlen(zname)); - isc_buffer_add(&buffer, strlen(zname)); - dns_fixedname_init(&fixorigin); - CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), - &buffer, dns_rootname, 0, NULL)); - origin = dns_fixedname_name(&fixorigin); - - CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - view->rdclass, &zclass)); - if (zclass != view->rdclass) { - const char *vname = NULL; - if (vconfig != NULL) - vname = cfg_obj_asstring(cfg_tuple_get(vconfig, - "name")); - else - vname = ""; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': wrong class for view '%s'", - zname, vname); - result = ISC_R_FAILURE; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "in-view", &viewobj); - if (viewobj != NULL) { - const char *inview = cfg_obj_asstring(viewobj); - dns_view_t *otherview = NULL; - - if (viewlist == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "'in-view' option is not permitted in " - "dynamically added zones"); - result = ISC_R_FAILURE; - goto cleanup; - } - - result = dns_viewlist_find(viewlist, inview, view->rdclass, - &otherview); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "view '%s' is not yet defined.", inview); - result = ISC_R_FAILURE; - goto cleanup; - } - - result = dns_view_findzone(otherview, origin, &zone); - dns_view_detach(&otherview); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' not defined in view '%s'", - zname, inview); - result = ISC_R_FAILURE; - goto cleanup; - } - - CHECK(dns_view_addzone(view, zone)); - dns_zone_detach(&zone); - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. Note: this is not inherited from the - * other view. - */ - forwarders = NULL; - result = cfg_map_get(zoptions, "forwarders", &forwarders); - if (result == ISC_R_SUCCESS) { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, - forwarders, forwardtype)); - } - result = ISC_R_SUCCESS; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "type", &typeobj); - if (typeobj == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' 'type' not specified", zname); - result = ISC_R_FAILURE; - goto cleanup; - } - ztypestr = cfg_obj_asstring(typeobj); - - /* - * "hints zones" aren't zones. If we've got one, - * configure it and return. - */ - if (strcasecmp(ztypestr, "hint") == 0) { - const cfg_obj_t *fileobj = NULL; - if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - result = ISC_R_FAILURE; - goto cleanup; - } - if (dns_name_equal(origin, dns_rootname)) { - const char *hintsfile = cfg_obj_asstring(fileobj); - - CHECK(configure_hints(view, hintsfile)); - - /* - * Hint zones may also refer to delegation only points. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", - &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "ignoring non-root hint zone '%s'", - zname); - result = ISC_R_SUCCESS; - } - /* Skip ordinary zone processing. */ - goto cleanup; - } - - /* - * "forward zones" aren't zones either. Translate this syntax into - * the appropriate selective forwarding configuration and return. - */ - if (strcasecmp(ztypestr, "forward") == 0) { - forwardtype = NULL; - forwarders = NULL; - - (void)cfg_map_get(zoptions, "forward", &forwardtype); - (void)cfg_map_get(zoptions, "forwarders", &forwarders); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - - /* - * Forward zones may also set delegation only. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - goto cleanup; - } - - /* - * "delegation-only zones" aren't zones either. - */ - if (strcasecmp(ztypestr, "delegation-only") == 0) { - result = dns_view_adddelegationonly(view, origin); - goto cleanup; - } - - /* - * Redirect zones only require minimal configuration. - */ - if (strcasecmp(ztypestr, "redirect") == 0) { - if (view->redirect != NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "redirect zone already exists"); - result = ISC_R_EXISTS; - goto cleanup; - } - result = dns_viewlist_find(viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL && pview->redirect != NULL) { - dns_zone_attach(pview->redirect, &zone); - dns_zone_setview(zone, view); - } else { - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, - &zone)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, - zone)); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, - zone, NULL)); - dns_zone_attach(zone, &view->redirect); - goto cleanup; - } - - if (!modify) { - /* - * Check for duplicates in the new zone table. - */ - result = dns_view_findzone(view, origin, &dupzone); - if (result == ISC_R_SUCCESS) { - /* - * We already have this zone! - */ - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' already exists", zname); - dns_zone_detach(&dupzone); - result = ISC_R_EXISTS; - goto cleanup; - } - INSIST(dupzone == NULL); - } - - /* - * Note whether this is a response policy zone and which one if so. - */ - for (rpz_num = 0; ; ++rpz_num) { - if (view->rpzs == NULL || rpz_num >= view->rpzs->p.num_zones) { - rpz_num = DNS_RPZ_INVALID_NUM; - break; - } - if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin, origin)) - break; - } - - if (view->catzs != NULL && - dns_catz_get_zone(view->catzs, origin) != NULL) - zone_is_catz = true; - - /* - * See if we can reuse an existing zone. This is - * only possible if all of these are true: - * - The zone's view exists - * - A zone with the right name exists in the view - * - The zone is compatible with the config - * options (e.g., an existing master zone cannot - * be reused if the options specify a slave zone) - * - The zone was not and is still not a response policy zone - * or the zone is a policy zone with an unchanged number - * and we are using the old policy zone summary data. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) - result = dns_view_findzone(pview, origin, &zone); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - - if (zone != NULL && !ns_zone_reusable(zone, zconfig)) - dns_zone_detach(&zone); - - if (zone != NULL && (rpz_num != dns_zone_get_rpz_num(zone) || - (rpz_num != DNS_RPZ_INVALID_NUM && !old_rpz_ok))) - dns_zone_detach(&zone); - - if (zone != NULL) { - /* - * We found a reusable zone. Make it use the - * new view. - */ - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - } else { - /* - * We cannot reuse an existing zone, we have - * to create a new one. - */ - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - if (rpz_num != DNS_RPZ_INVALID_NUM) { - result = dns_zone_rpz_enable(zone, view->rpzs, rpz_num); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': incompatible" - " masterfile-format or database" - " for a response policy zone", - zname); - goto cleanup; - } - } - - if (zone_is_catz) - dns_zone_catz_enable(zone, view->catzs); - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. - */ - forwarders = NULL; - if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) - { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - } - - /* - * Stub and forward zones may also refer to delegation only points. - */ - only = NULL; - if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) - { - if (cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } - - /* - * Mark whether the zone was originally added at runtime or not - */ - dns_zone_setadded(zone, added); - - signing = NULL; - if ((strcasecmp(ztypestr, "master") == 0 || - strcasecmp(ztypestr, "slave") == 0) && - cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS && - cfg_obj_asboolean(signing)) - { - dns_zone_getraw(zone, &raw); - if (raw == NULL) { - CHECK(dns_zone_create(&raw, mctx)); - CHECK(dns_zone_setorigin(raw, origin)); - dns_zone_setview(raw, view); - if (view->acache != NULL) - dns_zone_setacache(raw, view->acache); - dns_zone_setstats(raw, ns_g_server->zonestats); - CHECK(dns_zone_link(zone, raw)); - } - if (cfg_map_get(zoptions, "ixfr-from-differences", - &ixfrfromdiffs) == ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "zone '%s': 'ixfr-from-differences' is " - "ignored for inline-signed zones", - zname); - } - } - - /* - * Configure the zone. - */ - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone, raw)); - - /* - * Add the zone to its view in the new view list. - */ - if (!modify) - CHECK(dns_view_addzone(view, zone)); - - if (zone_is_catz) { - /* - * force catz reload if the zone is loaded; - * if it's not it'll get reloaded on zone load - */ - dns_db_t *db = NULL; - - tresult = dns_zone_getdb(zone, &db); - if (tresult == ISC_R_SUCCESS) { - dns_catz_dbupdate_callback(db, view->catzs); - dns_db_detach(&db); - } - - } - - /* - * Ensure that zone keys are reloaded on reconfig - */ - if ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0) - dns_zone_rekey(zone, false); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (raw != NULL) - dns_zone_detach(&raw); - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -/* - * Configure built-in zone for storing managed-key data. - */ - -static isc_result_t -add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) { - isc_result_t result; - dns_view_t *pview = NULL; - dns_zone_t *zone = NULL; - dns_acl_t *none = NULL; - char filename[PATH_MAX]; - bool defaultview; - - REQUIRE(view != NULL); - - /* See if we can re-use an existing keydata zone. */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && - result != ISC_R_SUCCESS) - return (result); - - if (pview != NULL && pview->managed_keys != NULL) { - dns_zone_attach(pview->managed_keys, &view->managed_keys); - dns_zone_setview(pview->managed_keys, view); - dns_view_detach(&pview); - dns_zone_synckeyzone(view->managed_keys); - return (ISC_R_SUCCESS); - } - - /* No existing keydata zone was found; create one */ - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone)); - CHECK(dns_zone_setorigin(zone, dns_rootname)); - - defaultview = (strcmp(view->name, "_default") == 0); - CHECK(isc_file_sanitize(directory, - defaultview ? "managed-keys" : view->name, - defaultview ? "bind" : "mkeys", - filename, sizeof(filename))); - CHECK(dns_zone_setfile(zone, filename)); - - dns_zone_setview(zone, view); - dns_zone_settype(zone, dns_zone_key); - dns_zone_setclass(zone, view->rdclass); - - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - - CHECK(dns_acl_none(mctx, &none)); - dns_zone_setqueryacl(zone, none); - dns_zone_setqueryonacl(zone, none); - dns_acl_detach(&none); - - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - dns_zone_setjournalsize(zone, 0); - - dns_zone_setstats(zone, ns_g_server->zonestats); - CHECK(setquerystats(zone, mctx, dns_zonestat_none)); - - if (view->managed_keys != NULL) - dns_zone_detach(&view->managed_keys); - dns_zone_attach(zone, &view->managed_keys); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "set up managed keys zone for view %s, file '%s'", - view->name, filename); - -cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (none != NULL) - dns_acl_detach(&none); - - return (result); -} - -/* - * Configure a single server quota. - */ -static void -configure_server_quota(const cfg_obj_t **maps, const char *name, - isc_quota_t *quota) -{ - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = ns_config_get(maps, name, &obj); - INSIST(result == ISC_R_SUCCESS); - isc_quota_max(quota, cfg_obj_asuint32(obj)); -} - -/* - * This function is called as soon as the 'directory' statement has been - * parsed. This can be extended to support other options if necessary. - */ -static isc_result_t -directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { - isc_result_t result; - const char *directory; - - REQUIRE(strcasecmp("directory", clausename) == 0); - - UNUSED(arg); - UNUSED(clausename); - - /* - * Change directory. - */ - directory = cfg_obj_asstring(obj); - - if (! isc_file_ischdiridempotent(directory)) - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "option 'directory' contains relative path '%s'", - directory); - - result = isc_dir_chdir(directory); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "change directory to '%s' failed: %s", - directory, isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -scan_interfaces(ns_server_t *server, bool verbose) { - isc_result_t result; - bool match_mapped = server->aclenv.match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - bool use_ecs = server->aclenv.geoip_use_ecs; -#endif - - result = ns_interfacemgr_scan(server->interfacemgr, verbose); - /* - * Update the "localhost" and "localnets" ACLs to match the - * current set of network interfaces. - */ - dns_aclenv_copy(&server->aclenv, - ns_interfacemgr_getaclenv(server->interfacemgr)); - - server->aclenv.match_mapped = match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - server->aclenv.geoip_use_ecs = use_ecs; -#endif - - return (result); -} - -static isc_result_t -add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr, - isc_dscp_t dscp, bool wcardport_ok) -{ - ns_listenelt_t *lelt = NULL; - dns_acl_t *src_acl = NULL; - isc_result_t result; - isc_sockaddr_t any_sa6; - isc_netaddr_t netaddr; - - REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); - - isc_sockaddr_any6(&any_sa6); - if (!isc_sockaddr_equal(&any_sa6, addr) && - (wcardport_ok || isc_sockaddr_getport(addr) != 0)) { - isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr); - - result = dns_acl_create(mctx, 0, &src_acl); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_iptable_addprefix(src_acl->iptable, - &netaddr, 128, true); - if (result != ISC_R_SUCCESS) - goto clean; - - result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), - dscp, src_acl, &lelt); - if (result != ISC_R_SUCCESS) - goto clean; - ISC_LIST_APPEND(list->elts, lelt, link); - } - - return (ISC_R_SUCCESS); - - clean: - INSIST(lelt == NULL); - dns_acl_detach(&src_acl); - - return (result); -} - -/* - * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() - * to update the listening interfaces accordingly. - * We currently only consider IPv6, because this only affects IPv6 wildcard - * sockets. - */ -static void -adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { - isc_result_t result; - ns_listenlist_t *list = NULL; - dns_view_t *view; - dns_zone_t *zone, *next; - isc_sockaddr_t addr, *addrp; - isc_dscp_t dscp = -1; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - return; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_dispatch_t *dispatch6; - - dispatch6 = dns_resolver_dispatchv6(view->resolver); - if (dispatch6 == NULL) - continue; - result = dns_dispatch_getlocaladdress(dispatch6, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * We always add non-wildcard address regardless of whether - * the port is 'any' (the fourth arg is TRUE): if the port is - * specific, we need to add it since it may conflict with a - * listening interface; if it's zero, we'll dynamically open - * query ports, and some of them may override an existing - * wildcard IPv6 port. - */ - /* XXXMPA fix dscp */ - result = add_listenelt(mctx, list, &addr, dscp, true); - if (result != ISC_R_SUCCESS) - goto fail; - } - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) { - dns_view_t *zoneview; - - /* - * At this point the zone list may contain a stale zone - * just removed from the configuration. To see the validity, - * check if the corresponding view is in our current view list. - * There may also be old zones that are still in the process - * of shutting down and have detached from their old view - * (zoneview == NULL). - */ - zoneview = dns_zone_getview(zone); - if (zoneview == NULL) - continue; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL && view != zoneview; - view = ISC_LIST_NEXT(view, link)) - ; - if (view == NULL) - continue; - - addrp = dns_zone_getnotifysrc6(zone); - dscp = dns_zone_getnotifysrc6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) - goto fail; - - addrp = dns_zone_getxfrsource6(zone); - dscp = dns_zone_getxfrsource6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) - goto fail; - } - - ns_interfacemgr_adjust(server->interfacemgr, list, true); - - clean: - ns_listenlist_detach(&list); - return; - - fail: - /* - * Even when we failed the procedure, most of other interfaces - * should work correctly. We therefore just warn it. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "could not adjust the listen-on list; " - "some interfaces may not work"); - goto clean; -} - -/* - * This event callback is invoked to do periodic network interface - * scanning. It is also called by ns_server_scan_interfaces(), - * invoked by "rndc scan" - */ - -static void -interface_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - INSIST(task == server->task); - UNUSED(task); - - isc_event_free(&event); - - /* - * XXX should scan interfaces unlocked and get exclusive access - * only to replace ACLs. - */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, false); - isc_task_endexclusive(server->task); -} - -static void -heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *) event->ev_arg; - dns_view_t *view; - - UNUSED(task); - isc_event_free(&event); - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - dns_view_dialup(view); - view = ISC_LIST_NEXT(view, link); - } -} - -typedef struct { - isc_mem_t *mctx; - isc_task_t *task; - dns_fetch_t *fetch; - dns_view_t *view; - dns_fixedname_t tatname; - dns_fixedname_t keyname; - dns_rdataset_t rdataset; - dns_rdataset_t sigrdataset; -} ns_tat_t; - -static int -cid(const void *a, const void *b) { - const uint16_t ida = *(const uint16_t *)a; - const uint16_t idb = *(const uint16_t *)b; - if (ida < idb) - return (-1); - else if (ida > idb) - return (1); - else - return (0); -} - -static void -tat_done(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent; - ns_tat_t *tat; - - INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); - INSIST(event->ev_arg != NULL); - - UNUSED(task); - - tat = event->ev_arg; - devent = (dns_fetchevent_t *) event; - - /* Free resources which are not of interest */ - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - isc_event_free(&event); - dns_resolver_destroyfetch(&tat->fetch); - if (dns_rdataset_isassociated(&tat->rdataset)) - dns_rdataset_disassociate(&tat->rdataset); - if (dns_rdataset_isassociated(&tat->sigrdataset)) - dns_rdataset_disassociate(&tat->sigrdataset); - dns_view_detach(&tat->view); - isc_task_detach(&tat->task); - isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat)); -} - -struct dotat_arg { - dns_view_t *view; - isc_task_t *task; -}; - -/*% - * Prepare the QNAME for the TAT query to be sent by processing the trust - * anchors present at 'keynode' of 'keytable'. Store the result in 'dst' and - * the domain name which 'keynode' is associated with in 'keyname'. - * - * A maximum of 12 key IDs can be reported in a single TAT query due to the - * 63-octet length limit for any single label in a domain name. If there are - * more than 12 keys configured at 'keynode', only the first 12 will be - * reported in the TAT query. - */ -static isc_result_t -get_tat_qname(dns_name_t *dst, dns_name_t **keyname, dns_keytable_t *keytable, - dns_keynode_t *keynode) -{ - dns_keynode_t *firstnode = keynode; - dns_keynode_t *nextnode; - unsigned int i, n = 0; - uint16_t ids[12]; - isc_textregion_t r; - char label[64]; - int m; - - REQUIRE(keyname != NULL && *keyname == NULL); - - do { - dst_key_t *key = dns_keynode_key(keynode); - if (key != NULL) { - *keyname = dst_key_name(key); - if (n < (sizeof(ids)/sizeof(ids[0]))) { - ids[n] = dst_key_id(key); - n++; - } - } - nextnode = NULL; - (void)dns_keytable_nextkeynode(keytable, keynode, &nextnode); - if (keynode != firstnode) - dns_keytable_detachkeynode(keytable, &keynode); - keynode = nextnode; - } while (keynode != NULL); - - if (n == 0) { - return (DNS_R_EMPTYNAME); - } - - if (n > 1) - qsort(ids, n, sizeof(ids[0]), cid); - - /* - * Encoded as "_ta-xxxx\(-xxxx\)*" where xxxx is the hex version of - * of the keyid. - */ - label[0] = 0; - r.base = label; - r.length = sizeof(label);; - m = snprintf(r.base, r.length, "_ta"); - if (m < 0 || (unsigned)m > r.length) { - return (ISC_R_FAILURE); - } - isc_textregion_consume(&r, m); - for (i = 0; i < n; i++) { - m = snprintf(r.base, r.length, "-%04x", ids[i]); - if (m < 0 || (unsigned)m > r.length) { - return (ISC_R_FAILURE); - } - isc_textregion_consume(&r, m); - } - - return (dns_name_fromstring2(dst, label, *keyname, 0, NULL)); -} - -static void -tat_send(isc_task_t *task, isc_event_t *event) { - ns_tat_t *tat; - char namebuf[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fdomain; - dns_name_t *domain; - dns_rdataset_t nameservers; - isc_result_t result; - dns_name_t *keyname; - dns_name_t *tatname; - - INSIST(event != NULL && event->ev_type == NS_EVENT_TATSEND); - INSIST(event->ev_arg != NULL); - - UNUSED(task); - - tat = event->ev_arg; - - tatname = dns_fixedname_name(&tat->tatname); - keyname = dns_fixedname_name(&tat->keyname); - - dns_name_format(tatname, namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "%s: sending trust-anchor-telemetry query '%s/NULL'", - tat->view->name, namebuf); - - /* - * TAT queries should be sent to the authoritative servers for a given - * zone. If this function is called for a keytable node corresponding - * to a locally served zone, calling dns_resolver_createfetch() with - * NULL 'domain' and 'nameservers' arguments will cause 'tatname' to be - * resolved locally, without sending any TAT queries upstream. - * - * Work around this issue by calling dns_view_findzonecut() first. If - * the zone is served locally, the NS RRset for the given domain name - * will be retrieved from local data; if it is not, the deepest zone - * cut we have for it will be retrieved from cache. In either case, - * passing the results to dns_resolver_createfetch() will prevent it - * from returning NXDOMAIN for 'tatname' while still allowing it to - * chase down any potential delegations returned by upstream servers in - * order to eventually find the destination host to send the TAT query - * to. - * - * 'keyname' holds the domain name at 'keynode', i.e. the domain name - * for which the trust anchors to be reported by this TAT query are - * defined. - * - * After the dns_view_findzonecut() call, 'domain' will hold the - * deepest zone cut we can find for 'keyname' while 'nameservers' will - * hold the NS RRset at that zone cut. - */ - domain = dns_fixedname_initname(&fdomain); - dns_rdataset_init(&nameservers); - result = dns_view_findzonecut(tat->view, keyname, domain, 0, 0, true, - &nameservers, NULL); - if (result == ISC_R_SUCCESS) { - result = dns_resolver_createfetch(tat->view->resolver, tatname, - dns_rdatatype_null, domain, - &nameservers, NULL, 0, - tat->task, tat_done, tat, - &tat->rdataset, - &tat->sigrdataset, - &tat->fetch); - } - - /* - * 'domain' holds the dns_name_t pointer inside a dst_key_t structure. - * dns_resolver_createfetch() creates its own copy of 'domain' if it - * succeeds. Thus, 'domain' is not freed here. - * - * Even if dns_view_findzonecut() returned something else than - * ISC_R_SUCCESS, it still could have associated 'nameservers'. - * dns_resolver_createfetch() creates its own copy of 'nameservers' if - * it succeeds. Thus, we need to check whether 'nameservers' is - * associated and release it if it is. - */ - if (dns_rdataset_isassociated(&nameservers)) { - dns_rdataset_disassociate(&nameservers); - } - - if (result != ISC_R_SUCCESS) { - dns_view_detach(&tat->view); - isc_task_detach(&tat->task); - isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat)); - } - isc_event_free(&event); -} - -static void -dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) { - struct dotat_arg *dotat_arg = arg; - dns_name_t *keyname = NULL; - isc_result_t result; - dns_view_t *view; - isc_task_t *task; - ns_tat_t *tat; - isc_event_t *event; - - REQUIRE(keytable != NULL); - REQUIRE(keynode != NULL); - REQUIRE(dotat_arg != NULL); - - view = dotat_arg->view; - task = dotat_arg->task; - - tat = isc_mem_get(dotat_arg->view->mctx, sizeof(*tat)); - - tat->fetch = NULL; - tat->mctx = NULL; - tat->task = NULL; - tat->view = NULL; - dns_rdataset_init(&tat->rdataset); - dns_rdataset_init(&tat->sigrdataset); - result = get_tat_qname(dns_fixedname_initname(&tat->tatname), &keyname, - keytable, keynode); - if (result != ISC_R_SUCCESS) { - isc_mem_put(dotat_arg->view->mctx, tat, sizeof(*tat)); - return; - } - dns_name_copy(keyname, dns_fixedname_initname(&tat->keyname), NULL); - isc_mem_attach(dotat_arg->view->mctx, &tat->mctx); - isc_task_attach(task, &tat->task); - dns_view_attach(view, &tat->view); - - /* - * We don't want to be holding the keytable lock when calling - * dns_view_findzonecut() as it creates a lock order loop so - * call dns_view_findzonecut() in a event handler. - * - * zone->lock (dns_zone_setviewcommit) while holding view->lock - * (dns_view_setviewcommit) - * - * keytable->lock (dns_keytable_find) while holding zone->lock - * (zone_asyncload) - * - * view->lock (dns_view_findzonecut) while holding keytable->lock - * (dns_keytable_forall) - */ - event = isc_event_allocate(tat->mctx, keytable, NS_EVENT_TATSEND, - tat_send, tat, sizeof(isc_event_t)); - isc_task_send(task, &event); -} - -static void -tat_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - struct dotat_arg arg; - dns_view_t *view; - dns_keytable_t *secroots = NULL; - - isc_event_free(&event); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (!view->trust_anchor_telemetry || - !view->enablevalidation) - { - continue; - } - - result = dns_view_getsecroots(view, &secroots); - if (result != ISC_R_SUCCESS) { - continue; - } - - arg.view = view; - arg.task = task; - (void)dns_keytable_forall(secroots, dotat, &arg); - dns_keytable_detach(&secroots); - } -} - -static void -pps_timer_tick(isc_task_t *task, isc_event_t *event) { - static unsigned int oldrequests = 0; - unsigned int requests = ncr_load(ns_client_requests); - - UNUSED(task); - isc_event_free(&event); - - /* - * Don't worry about wrapping as the overflow result will be right. - */ - dns_pps = (requests - oldrequests) / 1200; - oldrequests = requests; -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with a dynamically allocated copy of the - * null-terminated string pointed to by 'value', or NULL. - */ -static isc_result_t -setstring(ns_server_t *server, char **field, const char *value) { - char *copy; - - if (value != NULL) { - copy = isc_mem_strdup(server->mctx, value); - if (copy == NULL) - return (ISC_R_NOMEMORY); - } else { - copy = NULL; - } - - if (*field != NULL) - isc_mem_free(server->mctx, *field); - - *field = copy; - return (ISC_R_SUCCESS); -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with another dynamically allocated string - * or NULL if whether 'obj' is a string or void value, respectively. - */ -static isc_result_t -setoptstring(ns_server_t *server, char **field, const cfg_obj_t *obj) { - if (cfg_obj_isvoid(obj)) - return (setstring(server, field, NULL)); - else - return (setstring(server, field, cfg_obj_asstring(obj))); -} - -static void -set_limit(const cfg_obj_t **maps, const char *configname, - const char *description, isc_resource_t resourceid, - isc_resourcevalue_t defaultvalue) -{ - const cfg_obj_t *obj = NULL; - const char *resource; - isc_resourcevalue_t value; - isc_result_t result; - - if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) - return; - - if (cfg_obj_isstring(obj)) { - resource = cfg_obj_asstring(obj); - if (strcasecmp(resource, "unlimited") == 0) - value = ISC_RESOURCE_UNLIMITED; - else { - INSIST(strcasecmp(resource, "default") == 0); - value = defaultvalue; - } - } else - value = cfg_obj_asuint64(obj); - - result = isc_resource_setlimit(resourceid, value); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - result == ISC_R_SUCCESS ? - ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, - "set maximum %s to %" PRIu64 ": %s", - description, value, isc_result_totext(result)); -} - -#define SETLIMIT(cfgvar, resource, description) \ - set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ - ns_g_init ## resource) - -static void -set_limits(const cfg_obj_t **maps) { - SETLIMIT("stacksize", stacksize, "stack size"); - SETLIMIT("datasize", datasize, "data size"); - SETLIMIT("coresize", coresize, "core size"); - SETLIMIT("files", openfiles, "open files"); -} - -static void -portset_fromconf(isc_portset_t *portset, const cfg_obj_t *ports, - bool positive) -{ - const cfg_listelt_t *element; - - for (element = cfg_list_first(ports); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *obj = cfg_listelt_value(element); - - if (cfg_obj_isuint32(obj)) { - in_port_t port = (in_port_t)cfg_obj_asuint32(obj); - - if (positive) - isc_portset_add(portset, port); - else - isc_portset_remove(portset, port); - } else { - const cfg_obj_t *obj_loport, *obj_hiport; - in_port_t loport, hiport; - - obj_loport = cfg_tuple_get(obj, "loport"); - loport = (in_port_t)cfg_obj_asuint32(obj_loport); - obj_hiport = cfg_tuple_get(obj, "hiport"); - hiport = (in_port_t)cfg_obj_asuint32(obj_hiport); - - if (positive) - isc_portset_addrange(portset, loport, hiport); - else { - isc_portset_removerange(portset, loport, - hiport); - } - } - } -} - -static isc_result_t -removed(dns_zone_t *zone, void *uap) { - const char *type; - - if (dns_zone_getview(zone) != uap) - return (ISC_R_SUCCESS); - - switch (dns_zone_gettype(zone)) { - case dns_zone_master: - type = "master"; - break; - case dns_zone_slave: - type = "slave"; - break; - case dns_zone_stub: - type = "stub"; - break; - case dns_zone_staticstub: - type = "static-stub"; - break; - case dns_zone_redirect: - type = "redirect"; - break; - default: - type = "other"; - break; - } - dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type); - return (ISC_R_SUCCESS); -} - -static void -cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) { - if (server->session_keyfile != NULL) { - isc_file_remove(server->session_keyfile); - isc_mem_free(mctx, server->session_keyfile); - server->session_keyfile = NULL; - } - - if (server->session_keyname != NULL) { - if (dns_name_dynamic(server->session_keyname)) - dns_name_free(server->session_keyname, mctx); - isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t)); - server->session_keyname = NULL; - } - - if (server->sessionkey != NULL) - dns_tsigkey_detach(&server->sessionkey); - - server->session_keyalg = DST_ALG_UNKNOWN; - server->session_keybits = 0; -} - -static isc_result_t -generate_session_key(const char *filename, const char *keynamestr, - dns_name_t *keyname, const char *algstr, - dns_name_t *algname, unsigned int algtype, - uint16_t bits, isc_mem_t *mctx, bool first_time, - dns_tsigkey_t **tsigkeyp) -{ - isc_result_t result = ISC_R_SUCCESS; - dst_key_t *key = NULL; - isc_buffer_t key_txtbuffer; - isc_buffer_t key_rawbuffer; - char key_txtsecret[256]; - char key_rawsecret[64]; - isc_region_t key_rawregion; - isc_stdtime_t now; - dns_tsigkey_t *tsigkey = NULL; - FILE *fp = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "generating session key for dynamic DNS"); - - /* generate key */ - result = dst_key_generate(keyname, algtype, bits, 1, 0, - DNS_KEYPROTO_ANY, dns_rdataclass_in, - mctx, &key); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Dump the key to the buffer for later use. Should be done before - * we transfer the ownership of key to tsigkey. - */ - isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret)); - CHECK(dst_key_tobuffer(key, &key_rawbuffer)); - - isc_buffer_usedregion(&key_rawbuffer, &key_rawregion); - isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret)); - CHECK(isc_base64_totext(&key_rawregion, -1, "", &key_txtbuffer)); - - /* Store the key in tsigkey. */ - isc_stdtime_get(&now); - CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key, - false, NULL, now, now, mctx, NULL, - &tsigkey)); - - /* Dump the key to the key file. */ - fp = ns_os_openfile(filename, S_IRUSR|S_IWUSR, first_time); - if (fp == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not create %s", filename); - result = ISC_R_NOPERM; - goto cleanup; - } - - fprintf(fp, "key \"%s\" {\n" - "\talgorithm %s;\n" - "\tsecret \"%.*s\";\n};\n", keynamestr, algstr, - (int) isc_buffer_usedlength(&key_txtbuffer), - (char*) isc_buffer_base(&key_txtbuffer)); - - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - if (result != ISC_R_SUCCESS) - goto cleanup; - - dst_key_free(&key); - - *tsigkeyp = tsigkey; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to generate session key " - "for dynamic DNS: %s", isc_result_totext(result)); - if (fp != NULL) { - (void)isc_stdio_close(fp); - (void)isc_file_remove(filename); - } - if (tsigkey != NULL) - dns_tsigkey_detach(&tsigkey); - if (key != NULL) - dst_key_free(&key); - - return (result); -} - -static isc_result_t -configure_session_key(const cfg_obj_t **maps, ns_server_t *server, - isc_mem_t *mctx, bool first_time) -{ - const char *keyfile, *keynamestr, *algstr; - unsigned int algtype; - dns_fixedname_t fname; - dns_name_t *keyname, *algname; - isc_buffer_t buffer; - uint16_t bits; - const cfg_obj_t *obj; - bool need_deleteold = false; - bool need_createnew = false; - isc_result_t result; - - obj = NULL; - result = ns_config_get(maps, "session-keyfile", &obj); - if (result == ISC_R_SUCCESS) { - if (cfg_obj_isvoid(obj)) - keyfile = NULL; /* disable it */ - else - keyfile = cfg_obj_asstring(obj); - } else - keyfile = ns_g_defaultsessionkeyfile; - - obj = NULL; - result = ns_config_get(maps, "session-keyname", &obj); - INSIST(result == ISC_R_SUCCESS); - keynamestr = cfg_obj_asstring(obj); - isc_buffer_constinit(&buffer, keynamestr, strlen(keynamestr)); - isc_buffer_add(&buffer, strlen(keynamestr)); - keyname = dns_fixedname_initname(&fname); - result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = ns_config_get(maps, "session-keyalg", &obj); - INSIST(result == ISC_R_SUCCESS); - algstr = cfg_obj_asstring(obj); - algname = NULL; - result = ns_config_getkeyalgorithm2(algstr, &algname, &algtype, &bits); - if (result != ISC_R_SUCCESS) { - const char *s = " (keeping current key)"; - - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: " - "unsupported or unknown algorithm '%s'%s", - algstr, - server->session_keyfile != NULL ? s : ""); - return (result); - } - - /* See if we need to (re)generate a new key. */ - if (keyfile == NULL) { - if (server->session_keyfile != NULL) - need_deleteold = true; - } else if (server->session_keyfile == NULL) - need_createnew = true; - else if (strcmp(keyfile, server->session_keyfile) != 0 || - !dns_name_equal(server->session_keyname, keyname) || - server->session_keyalg != algtype || - server->session_keybits != bits) { - need_deleteold = true; - need_createnew = true; - } - - if (need_deleteold) { - INSIST(server->session_keyfile != NULL); - INSIST(server->session_keyname != NULL); - INSIST(server->sessionkey != NULL); - - cleanup_session_key(server, mctx); - } - - if (need_createnew) { - INSIST(server->sessionkey == NULL); - INSIST(server->session_keyfile == NULL); - INSIST(server->session_keyname == NULL); - INSIST(server->session_keyalg == DST_ALG_UNKNOWN); - INSIST(server->session_keybits == 0); - - server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t)); - if (server->session_keyname == NULL) - goto cleanup; - dns_name_init(server->session_keyname, NULL); - CHECK(dns_name_dup(keyname, mctx, server->session_keyname)); - - server->session_keyfile = isc_mem_strdup(mctx, keyfile); - if (server->session_keyfile == NULL) - goto cleanup; - - server->session_keyalg = algtype; - server->session_keybits = bits; - - CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr, - algname, algtype, bits, mctx, - first_time, &server->sessionkey)); - } - - return (result); - - cleanup: - cleanup_session_key(server, mctx); - return (result); -} - -#ifndef HAVE_LMDB -static isc_result_t -count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) { - isc_result_t result; - - /* The new zone file may not exist. That is OK. */ - if (!isc_file_exists(view->new_zone_file)) { - *num_zonesp = 0; - return (ISC_R_SUCCESS); - } - - /* - * In the case of NZF files, we also parse the configuration in - * the file at this stage. - * - * This may be called in multiple views, so we reset - * the parser each time. - */ - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_file(ns_g_addparser, view->new_zone_file, - &cfg_type_addzoneconf, &nzcfg->nzf_config); - if (result == ISC_R_SUCCESS) { - int num_zones; - - num_zones = count_zones(nzcfg->nzf_config); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "NZF file '%s' contains %d zones", - view->new_zone_file, num_zones); - if (num_zonesp != NULL) - *num_zonesp = num_zones; - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error parsing NZF file '%s': %s", - view->new_zone_file, - isc_result_totext(result)); - } - - return (result); -} - -#else /* HAVE_LMDB */ - -static isc_result_t -count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) { - isc_result_t result; - int n; - - UNUSED(nzcfg); - - REQUIRE(num_zonesp != NULL); - - LOCK(&view->new_zone_lock); - - CHECK(migrate_nzf(view)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD zone count from '%s' " - "for view '%s'", - view->new_zone_db, view->name); - - CHECK(nzd_count(view, &n)); - - *num_zonesp = n; - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "NZD database '%s' contains %d zones", - view->new_zone_db, n); - - cleanup: - if (result != ISC_R_SUCCESS) - *num_zonesp = 0; - - UNLOCK(&view->new_zone_lock); - - return (ISC_R_SUCCESS); -} - -#endif /* HAVE_LMDB */ - -static isc_result_t -setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - cfg_parser_t *conf_parser, cfg_aclconfctx_t *actx, - int *num_zones) -{ - isc_result_t result = ISC_R_SUCCESS; - bool allow = false; - ns_cfgctx_t *nzcfg = NULL; - const cfg_obj_t *maps[4]; - const cfg_obj_t *options = NULL, *voptions = NULL; - const cfg_obj_t *nz = NULL; - const cfg_obj_t *obj = NULL; - int i = 0; - uint64_t mapsize = 0ULL; - - REQUIRE(config != NULL); - - if (vconfig != NULL) - voptions = cfg_tuple_get(vconfig, "options"); - if (voptions != NULL) - maps[i++] = voptions; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "allow-new-zones", &nz); - if (result == ISC_R_SUCCESS) - allow = cfg_obj_asboolean(nz); - -#ifdef HAVE_LMDB - result = ns_config_get(maps, "lmdb-mapsize", &obj); - if (result == ISC_R_SUCCESS && obj != NULL) { - mapsize = cfg_obj_asuint64(obj); - if (mapsize < (1ULL << 20)) { /* 1 megabyte */ - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'lmdb-mapsize " - "%" PRId64 "' " - "is too small", - mapsize); - return (ISC_R_FAILURE); - } else if (mapsize > (1ULL << 40)) { /* 1 terabyte */ - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'lmdb-mapsize " - "%" PRId64 "' " - "is too large", - mapsize); - return (ISC_R_FAILURE); - } - } -#else - UNUSED(obj); -#endif /* HAVE_LMDB */ - - /* - * A non-empty catalog-zones statement implies allow-new-zones - */ - if (!allow) { - const cfg_obj_t *cz = NULL; - result = ns_config_get(maps, "catalog-zones", &cz); - if (result == ISC_R_SUCCESS) { - const cfg_listelt_t *e = - cfg_list_first(cfg_tuple_get(cz, "zone list")); - if (e != NULL) - allow = true; - } - } - - if (!allow) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - if (num_zones != NULL) - *num_zones = 0; - return (ISC_R_SUCCESS); - } - - nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg)); - if (nzcfg == NULL) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - return (ISC_R_NOMEMORY); - } - - /* - * We attach the parser that was used for config as well - * as the one that will be used for added zones, to avoid - * a shutdown race later. - */ - memset(nzcfg, 0, sizeof(*nzcfg)); - cfg_parser_attach(conf_parser, &nzcfg->conf_parser); - cfg_parser_attach(ns_g_addparser, &nzcfg->add_parser); - isc_mem_attach(view->mctx, &nzcfg->mctx); - cfg_aclconfctx_attach(actx, &nzcfg->actx); - - result = dns_view_setnewzones(view, allow, nzcfg, - newzone_cfgctx_destroy, mapsize); - if (result != ISC_R_SUCCESS) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - return (result); - } - - cfg_obj_attach(config, &nzcfg->config); - if (vconfig != NULL) - cfg_obj_attach(vconfig, &nzcfg->vconfig); - - result = count_newzones(view, nzcfg, num_zones); - return (result); -} - -static void -configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig, - dns_view_t *view) -{ - const char *zname; - dns_fixedname_t fixorigin; - dns_name_t *origin; - isc_result_t result2; - dns_view_t *pview = NULL; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - origin = dns_fixedname_initname(&fixorigin); - - result2 = dns_name_fromstring(origin, zname, 0, NULL); - if (result2 != ISC_R_SUCCESS) { - return; - } - - result2 = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result2 != ISC_R_SUCCESS) { - return; - } - - result2 = dns_view_findzone(pview, origin, &zone); - if (result2 != ISC_R_SUCCESS) { - dns_view_detach(&pview); - return; - } - - dns_zone_getraw(zone, &raw); - - if (result == ISC_R_SUCCESS) { - dns_zone_setviewcommit(zone); - if (raw != NULL) - dns_zone_setviewcommit(raw); - } else { - dns_zone_setviewrevert(zone); - if (raw != NULL) - dns_zone_setviewrevert(raw); - } - - if (raw != NULL) { - dns_zone_detach(&raw); - } - - dns_zone_detach(&zone); - dns_view_detach(&pview); -} - -#ifndef HAVE_LMDB - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx) -{ - isc_result_t result; - ns_cfgctx_t *nzctx; - const cfg_obj_t *zonelist; - const cfg_listelt_t *element; - - nzctx = view->new_zone_config; - if (nzctx == NULL || nzctx->nzf_config == NULL) { - return (ISC_R_SUCCESS); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "loading additional zones for view '%s'", - view->name); - - zonelist = NULL; - cfg_map_get(nzctx->nzf_config, "zone", &zonelist); - - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, - view, &ns_g_server->viewlist, actx, - true, false, false)); - } - - result = ISC_R_SUCCESS; - - cleanup: - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - configure_zone_setviewcommit(result, zconfig, view); - } - - return (result); -} - -#else /* HAVE_LMDB */ - -static isc_result_t -data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, - isc_buffer_t **text, cfg_obj_t **zoneconfig) -{ - isc_result_t result; - const char *zone_name; - size_t zone_name_len; - const char *zone_config; - size_t zone_config_len; - cfg_obj_t *zoneconf = NULL; - char bufname[DNS_NAME_FORMATSIZE]; - - REQUIRE(view != NULL); - REQUIRE(key != NULL); - REQUIRE(data != NULL); - REQUIRE(text != NULL); - REQUIRE(zoneconfig != NULL && *zoneconfig == NULL); - - if (*text == NULL) { - result = isc_buffer_allocate(view->mctx, text, 256); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else { - isc_buffer_clear(*text); - } - - zone_name = (const char *) key->mv_data; - zone_name_len = key->mv_size; - INSIST(zone_name != NULL && zone_name_len > 0); - - zone_config = (const char *) data->mv_data; - zone_config_len = data->mv_size; - INSIST(zone_config != NULL && zone_config_len > 0); - - /* zone zonename { config; }; */ - result = isc_buffer_reserve(text, 6 + zone_name_len + 2 + - zone_config_len + 2); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - CHECK(putstr(text, "zone \"")); - CHECK(putmem(text, (const void *) zone_name, zone_name_len)); - CHECK(putstr(text, "\" ")); - CHECK(putmem(text, (const void *) zone_config, zone_config_len)); - CHECK(putstr(text, ";\n")); - - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_buffer3(ns_g_addparser, *text, bufname, 0, - &cfg_type_addzoneconf, &zoneconf); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "parsing config for zone '%.*s' in " - "NZD database '%s' failed", - (int) zone_name_len, zone_name, - view->new_zone_db); - goto cleanup; - } - - *zoneconfig = zoneconf; - zoneconf = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (zoneconf != NULL) { - cfg_obj_destroy(ns_g_addparser, &zoneconf); - } - - return (result); -} - -/*% - * Prototype for a callback which can be used with for_all_newzone_cfgs(). - */ -typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj_t *zconfig, - cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx); - -/*% - * For each zone found in a NZD opened by the caller, create an object - * representing its configuration and invoke "callback" with the created - * object, "config", "vconfig", "mctx", "view" and "actx" as arguments (all - * these are non-global variables required to invoke configure_zone()). - * Immediately interrupt processing if an error is encountered while - * transforming NZD data into a zone configuration object or if "callback" - * returns an error. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx, MDB_txn *txn, MDB_dbi dbi) -{ - const cfg_obj_t *zconfig, *zlist; - isc_result_t result = ISC_R_SUCCESS; - cfg_obj_t *zconfigobj = NULL; - isc_buffer_t *text = NULL; - MDB_cursor *cursor = NULL; - MDB_val data, key; - int status; - - status = mdb_cursor_open(txn, dbi, &cursor); - if (status != MDB_SUCCESS) { - return (ISC_R_FAILURE); - } - - for (status = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); - status == MDB_SUCCESS; - status = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) - { - /* - * Create a configuration object from data fetched from NZD. - */ - result = data_to_cfg(view, &key, &data, &text, &zconfigobj); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Extract zone configuration from configuration object. - */ - zlist = NULL; - result = cfg_map_get(zconfigobj, "zone", &zlist); - if (result != ISC_R_SUCCESS) { - break; - } else if (!cfg_obj_islist(zlist)) { - result = ISC_R_FAILURE; - break; - } - zconfig = cfg_listelt_value(cfg_list_first(zlist)); - - /* - * Invoke callback. - */ - result = callback(zconfig, config, vconfig, mctx, view, actx); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Destroy the configuration object created in this iteration. - */ - cfg_obj_destroy(ns_g_addparser, &zconfigobj); - } - - if (text != NULL) { - isc_buffer_free(&text); - } - if (zconfigobj != NULL) { - cfg_obj_destroy(ns_g_addparser, &zconfigobj); - } - mdb_cursor_close(cursor); - - return (result); -} - -/*% - * Attempt to configure a zone found in NZD and return the result. - */ -static isc_result_t -configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx) -{ - return (configure_zone(config, zconfig, vconfig, mctx, view, - &ns_g_server->viewlist, actx, true, - false, false)); -} - -/*% - * Revert new view assignment for a zone found in NZD. - */ -static isc_result_t -configure_newzone_revert(const cfg_obj_t *zconfig, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx) -{ - UNUSED(config); - UNUSED(vconfig); - UNUSED(mctx); - UNUSED(actx); - - configure_zone_setviewcommit(ISC_R_FAILURE, zconfig, view); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx) -{ - isc_result_t result; - MDB_txn *txn = NULL; - MDB_dbi dbi; - - if (view->new_zone_config == NULL) { - return (ISC_R_SUCCESS); - } - - LOCK(&view->new_zone_lock); - - result = nzd_open(view, MDB_RDONLY, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - UNLOCK(&view->new_zone_lock); - return (ISC_R_SUCCESS); - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD configs from '%s' " - "for view '%s'", - view->new_zone_db, view->name); - - result = for_all_newzone_cfgs(configure_newzone, config, vconfig, mctx, - view, actx, txn, dbi); - if (result != ISC_R_SUCCESS) { - /* - * An error was encountered while attempting to configure zones - * found in NZD. As this error may have been caused by a - * configure_zone() failure, try restoring a sane configuration - * by reattaching all zones found in NZD to the old view. If - * this also fails, too bad, there is nothing more we can do in - * terms of trying to make things right. - */ - (void) for_all_newzone_cfgs(configure_newzone_revert, config, - vconfig, mctx, view, actx, txn, - dbi); - } - - (void) nzd_close(&txn, false); - - UNLOCK(&view->new_zone_lock); - - return (result); -} - -static isc_result_t -get_newzone_config(dns_view_t *view, const char *zonename, - cfg_obj_t **zoneconfig) -{ - isc_result_t result; - int status; - cfg_obj_t *zoneconf = NULL; - isc_buffer_t *text = NULL; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_val key, data; - char zname[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - - INSIST(zoneconfig != NULL && *zoneconfig == NULL); - - LOCK(&view->new_zone_lock); - - CHECK(nzd_open(view, MDB_RDONLY, &txn, &dbi)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD config from '%s' " - "for zone '%s'", - view->new_zone_db, zonename); - - /* Normalize zone name */ - isc_buffer_constinit(&b, zonename, strlen(zonename)); - isc_buffer_add(&b, strlen(zonename)); - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - DNS_NAME_DOWNCASE, NULL)); - dns_name_format(name, zname, sizeof(zname)); - - key.mv_data = zname; - key.mv_size = strlen(zname); - - status = mdb_get(txn, dbi, &key, &data); - if (status != MDB_SUCCESS) { - CHECK(ISC_R_FAILURE); - } - - CHECK(data_to_cfg(view, &key, &data, &text, &zoneconf)); - - *zoneconfig = zoneconf; - zoneconf = NULL; - result = ISC_R_SUCCESS; - - cleanup: - (void) nzd_close(&txn, false); - - UNLOCK(&view->new_zone_lock); - - if (zoneconf != NULL) { - cfg_obj_destroy(ns_g_addparser, &zoneconf); - } - if (text != NULL) { - isc_buffer_free(&text); - } - - return (result); -} - -#endif /* HAVE_LMDB */ - -static int -count_zones(const cfg_obj_t *conf) { - const cfg_obj_t *zonelist = NULL; - const cfg_listelt_t *element; - int n = 0; - - REQUIRE(conf != NULL); - - cfg_map_get(conf, "zone", &zonelist); - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - n++; - - return (n); -} - -static isc_result_t -check_lockfile(ns_server_t *server, const cfg_obj_t *config, - bool first_time) -{ - isc_result_t result; - const char *filename = NULL; - const cfg_obj_t *maps[3]; - const cfg_obj_t *options; - const cfg_obj_t *obj; - int i; - - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - obj = NULL; - (void) ns_config_get(maps, "lock-file", &obj); - - if (!first_time) { - if (obj != NULL && !cfg_obj_isstring(obj) && - server->lockfile != NULL && - strcmp(cfg_obj_asstring(obj), server->lockfile) != 0) - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "changing 'lock-file' " - "has no effect until the " - "server is restarted"); - - return (ISC_R_SUCCESS); - } - - if (obj != NULL) { - if (cfg_obj_isvoid(obj)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "skipping lock-file check "); - return (ISC_R_SUCCESS); - } else if (ns_g_forcelock) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "'lock-file' has no effect " - "because the server was run with -X"); - server->lockfile = isc_mem_strdup(server->mctx, - ns_g_defaultlockfile); - } else { - filename = cfg_obj_asstring(obj); - server->lockfile = isc_mem_strdup(server->mctx, - filename); - } - - if (server->lockfile == NULL) - return (ISC_R_NOMEMORY); - } - - if (ns_g_forcelock && ns_g_defaultlockfile != NULL) { - INSIST(server->lockfile == NULL); - server->lockfile = isc_mem_strdup(server->mctx, - ns_g_defaultlockfile); - } - - if (server->lockfile == NULL) - return (ISC_R_SUCCESS); - - if (ns_os_issingleton(server->lockfile)) - return (ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not lock %s; another named " - "process may be running", server->lockfile); - return (ISC_R_FAILURE); -} - -static isc_result_t -load_configuration(const char *filename, ns_server_t *server, - bool first_time) -{ - cfg_obj_t *config = NULL, *bindkeys = NULL; - cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *builtin_views; - const cfg_obj_t *maps[3]; - const cfg_obj_t *obj; - const cfg_obj_t *options; - const cfg_obj_t *usev4ports, *avoidv4ports, *usev6ports, *avoidv6ports; - const cfg_obj_t *views; - dns_view_t *view = NULL; - dns_view_t *view_next; - dns_viewlist_t tmpviewlist; - dns_viewlist_t viewlist, builtin_viewlist; - in_port_t listen_port, udpport_low, udpport_high; - int i; - int num_zones = 0; - bool exclusive = false; - isc_interval_t interval; - isc_logconfig_t *logc = NULL; - isc_portset_t *v4portset = NULL; - isc_portset_t *v6portset = NULL; - isc_resourcevalue_t nfiles; - isc_result_t result, tresult; - uint32_t heartbeat_interval; - uint32_t interface_interval; - uint32_t reserved; - uint32_t udpsize; - uint32_t transfer_message_size; - ns_cache_t *nsc; - ns_cachelist_t cachelist, tmpcachelist; - ns_altsecret_t *altsecret; - ns_altsecretlist_t altsecrets, tmpaltsecrets; - unsigned int maxsocks; - uint32_t softquota = 0; - - ISC_LIST_INIT(viewlist); - ISC_LIST_INIT(builtin_viewlist); - ISC_LIST_INIT(cachelist); - ISC_LIST_INIT(altsecrets); - - /* Create the ACL configuration context */ - if (ns_g_aclconfctx != NULL) { - cfg_aclconfctx_detach(&ns_g_aclconfctx); - } - CHECK(cfg_aclconfctx_create(ns_g_mctx, &ns_g_aclconfctx)); - - /* - * Shut down all dyndb instances. - */ - dns_dyndb_cleanup(false); - - /* - * Parse the global default pseudo-config file. - */ - if (first_time) { - result = ns_config_parsedefaults(ns_g_parser, &ns_g_config); - if (result != ISC_R_SUCCESS) { - ns_main_earlyfatal("unable to load " - "internal defaults: %s", - isc_result_totext(result)); - } - RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", - &ns_g_defaults) == ISC_R_SUCCESS); - } - - /* - * Parse the configuration file using the new config code. - */ - config = NULL; - - /* - * Unless this is lwresd with the -C option, parse the config file. - */ - if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - filename); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser)); - cfg_parser_setcallback(conf_parser, directory_callback, NULL); - result = cfg_parse_file(conf_parser, filename, - &cfg_type_namedconf, &config); - } - - /* - * If this is lwresd with the -C option, or lwresd with no -C or -c - * option where the above parsing failed, parse resolv.conf. - */ - if (ns_g_lwresdonly && - (lwresd_g_useresolvconf || - (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) - { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - lwresd_g_resolvconffile); - if (conf_parser != NULL) { - cfg_parser_destroy(&conf_parser); - } - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser)); - result = ns_lwresd_parseeresolvconf(ns_g_mctx, conf_parser, - &config); - } - CHECK(result); - - /* - * Check the validity of the configuration. - */ - CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx)); - - /* - * Fill in the maps array, used for resolving defaults. - */ - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) { - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - /* - * If bind.keys exists, load it. If "dnssec-validation auto" - * is turned on, the root key found there will be used as a - * default trust anchor. - */ - obj = NULL; - result = ns_config_get(maps, "bindkeys-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->bindkeysfile, - cfg_obj_asstring(obj)), "strdup"); - INSIST(server->bindkeysfile != NULL); - - if (access(server->bindkeysfile, R_OK) == 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reading built-in trust anchors " - "from file '%s'", server->bindkeysfile); - - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, - &bindkeys_parser)); - - result = cfg_parse_file(bindkeys_parser, server->bindkeysfile, - &cfg_type_bindkeys, &bindkeys); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "unable to parse '%s' error '%s'; using " - "built-in keys instead", - server->bindkeysfile, - isc_result_totext(result)); - } - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "unable to open '%s'; using built-in keys " - "instead", server->bindkeysfile); - } - - /* Ensure exclusive access to configuration data. */ - if (!exclusive) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - } - - /* - * Set process limits, which (usually) needs to be done as root. - */ - set_limits(maps); - - /* - * Check the process lockfile. - */ - CHECK(check_lockfile(server, config, first_time)); - - /* - * Check if max number of open sockets that the system allows is - * sufficiently large. Failing this condition is not necessarily fatal, - * but may cause subsequent runtime failures for a busy recursive - * server. - */ - result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &maxsocks); - if (result != ISC_R_SUCCESS) { - maxsocks = 0; - } - result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles); - if (result == ISC_R_SUCCESS && (isc_resourcevalue_t)maxsocks > nfiles) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "max open files (%" PRIu64 ")" - " is smaller than max sockets (%u)", - nfiles, maxsocks); - } - - /* - * Set the number of socket reserved for TCP, stdio etc. - */ - obj = NULL; - result = ns_config_get(maps, "reserved-sockets", &obj); - INSIST(result == ISC_R_SUCCESS); - reserved = cfg_obj_asuint32(obj); - if (maxsocks != 0) { - if (maxsocks < 128U) { /* Prevent underflow. */ - reserved = 0; - } else if (reserved > maxsocks - 128U) { /* Minimum UDP space. */ - reserved = maxsocks - 128; - } - } - /* Minimum TCP/stdio space. */ - if (reserved < 128U) { - reserved = 128; - } - if (reserved + 128U > maxsocks && maxsocks != 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "less than 128 UDP sockets available after " - "applying 'reserved-sockets' and 'maxsockets'"); - } - isc__socketmgr_setreserved(ns_g_socketmgr, reserved); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - /* - * Release any previously opened GeoIP2 databases. - */ - ns_geoip_shutdown(); - /* - * Initialize GeoIP databases from the configured location. - * This should happen before configuring any ACLs, so that we - * know what databases are available and can reject any GeoIP - * ACLs that can't work. - */ - obj = NULL; - result = ns_config_get(maps, "geoip-directory", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_isstring(obj)) { - char *dir; - DE_CONST(cfg_obj_asstring(obj), dir); - ns_geoip_load(dir); - } - ns_g_aclconfctx->geoip = ns_g_geoip; - - obj = NULL; - result = ns_config_get(maps, "geoip-use-ecs", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_server->aclenv.geoip_use_ecs = cfg_obj_asboolean(obj); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - /* - * Configure various server options. - */ - configure_server_quota(maps, "transfers-out", &server->xfroutquota); - configure_server_quota(maps, "tcp-clients", &server->tcpquota); - configure_server_quota(maps, "recursive-clients", - &server->recursionquota); - - if (server->recursionquota.max > 1000) { - int margin = ISC_MAX(100, ns_g_cpus + 1); - if (margin > server->recursionquota.max - 100) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "'recursive-clients %d' too low when " - "running with %d worker threads", - server->recursionquota.max, ns_g_cpus); - CHECK(ISC_R_RANGE); - } - softquota = server->recursionquota.max - margin; - } else { - softquota = (server->recursionquota.max * 90) / 100; - } - - isc_quota_soft(&server->recursionquota, softquota); - - /* - * Set "blackhole". Only legal at options level; there is - * no default. - */ - CHECK(configure_view_acl(NULL, config, NULL, "blackhole", NULL, - ns_g_aclconfctx, ns_g_mctx, - &server->blackholeacl)); - if (server->blackholeacl != NULL) { - dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, - server->blackholeacl); - } - - /* - * Set "keep-response-order". Only legal at options or - * global defaults level. - */ - CHECK(configure_view_acl(NULL, config, ns_g_config, - "keep-response-order", NULL, - ns_g_aclconfctx, ns_g_mctx, - &server->keepresporder)); - - obj = NULL; - result = ns_config_get(maps, "match-mapped-addresses", &obj); - INSIST(result == ISC_R_SUCCESS); - server->aclenv.match_mapped = cfg_obj_asboolean(obj); - - CHECKM(ns_statschannels_configure(ns_g_server, config, ns_g_aclconfctx), - "configuring statistics server(s)"); - - /* - * Configure sets of UDP query source ports. - */ - CHECKM(isc_portset_create(ns_g_mctx, &v4portset), - "creating UDP port set"); - CHECKM(isc_portset_create(ns_g_mctx, &v6portset), - "creating UDP port set"); - - usev4ports = NULL; - usev6ports = NULL; - avoidv4ports = NULL; - avoidv6ports = NULL; - - (void)ns_config_get(maps, "use-v4-udp-ports", &usev4ports); - if (usev4ports != NULL) { - portset_fromconf(v4portset, usev4ports, true); - } else { - CHECKM(isc_net_getudpportrange(AF_INET, &udpport_low, - &udpport_high), - "get the default UDP/IPv4 port range"); - if (udpport_low == udpport_high) { - isc_portset_add(v4portset, udpport_low); - } else { - isc_portset_addrange(v4portset, udpport_low, - udpport_high); - } - if (!ns_g_disable4) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using default UDP/IPv4 port range: " - "[%d, %d]", udpport_low, udpport_high); - } - } - (void)ns_config_get(maps, "avoid-v4-udp-ports", &avoidv4ports); - if (avoidv4ports != NULL) { - portset_fromconf(v4portset, avoidv4ports, false); - } - - (void)ns_config_get(maps, "use-v6-udp-ports", &usev6ports); - if (usev6ports != NULL) { - portset_fromconf(v6portset, usev6ports, true); - } else { - CHECKM(isc_net_getudpportrange(AF_INET6, &udpport_low, - &udpport_high), - "get the default UDP/IPv6 port range"); - if (udpport_low == udpport_high) { - isc_portset_add(v6portset, udpport_low); - } else { - isc_portset_addrange(v6portset, udpport_low, - udpport_high); - } - if (!ns_g_disable6) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using default UDP/IPv6 port range: " - "[%d, %d]", udpport_low, udpport_high); - } - } - (void)ns_config_get(maps, "avoid-v6-udp-ports", &avoidv6ports); - if (avoidv6ports != NULL) { - portset_fromconf(v6portset, avoidv6ports, false); - } - - dns_dispatchmgr_setavailports(ns_g_dispatchmgr, v4portset, v6portset); - - /* - * Set the EDNS UDP size when we don't match a view. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) { - udpsize = 512; - } - if (udpsize > 4096) { - udpsize = 4096; - } - ns_g_udpsize = (uint16_t)udpsize; - - /* Set the transfer message size for TCP */ - obj = NULL; - result = ns_config_get(maps, "transfer-message-size", &obj); - INSIST(result == ISC_R_SUCCESS); - transfer_message_size = cfg_obj_asuint32(obj); - if (transfer_message_size < 512) { - transfer_message_size = 512; - } else if (transfer_message_size > 65535) { - transfer_message_size = 65535; - } - server->transfer_tcp_message_size = (uint16_t) transfer_message_size; - - /* - * Configure the zone manager. - */ - obj = NULL; - result = ns_config_get(maps, "transfers-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfers-per-ns", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setnotifyrate(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "startup-notify-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setstartupnotifyrate(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "serial-query-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); - - /* - * Determine which port to use for listening for incoming connections. - */ - if (ns_g_port != 0) { - listen_port = ns_g_port; - } else { - CHECKM(ns_config_getport(config, &listen_port), "port"); - } - - /* - * Determining the default DSCP code point. - */ - CHECKM(ns_config_getdscp(config, &ns_g_dscp), "dscp"); - - /* - * Find the listen queue depth. - */ - obj = NULL; - result = ns_config_get(maps, "tcp-listen-queue", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_listen = cfg_obj_asuint32(obj); - if ((ns_g_listen > 0) && (ns_g_listen < 10)) { - ns_g_listen = 10; - } - - /* - * Configure the interface manager according to the "listen-on" - * statement. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - clistenon = NULL; - /* - * Even though listen-on is present in the default - * configuration, we can't use it here, since it isn't - * used if we're in lwresd mode. This way is easier. - */ - if (options != NULL) { - (void)cfg_map_get(options, "listen-on", &clistenon); - } - if (clistenon != NULL) { - /* check return code? */ - (void)ns_listenlist_fromconfig(clistenon, config, - ns_g_aclconfctx, - ns_g_mctx, AF_INET, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - -1, true, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon4(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - /* - * Ditto for IPv6. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - if (options != NULL) { - (void)cfg_map_get(options, "listen-on-v6", &clistenon); - } - if (clistenon != NULL) { - /* check return code? */ - (void)ns_listenlist_fromconfig(clistenon, config, - ns_g_aclconfctx, - ns_g_mctx, AF_INET6, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - -1, true, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon6(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - - /* - * Rescan the interface list to pick up changes in the - * listen-on option. It's important that we do this before we try - * to configure the query source, since the dispatcher we use might - * be shared with an interface. - */ - result = scan_interfaces(server, true); - - /* - * Check that named is able to TCP listen on at least one - * interface. Otherwise, another named process could be running - * and we should fail. - */ - if (first_time && (result == ISC_R_ADDRINUSE)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to listen on any configured interfaces"); - result = ISC_R_FAILURE; - goto cleanup; - } - - /* - * Arrange for further interface scanning to occur periodically - * as specified by the "interface-interval" option. - */ - obj = NULL; - result = ns_config_get(maps, "interface-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - interface_interval = cfg_obj_asuint32(obj) * 60; - if (interface_interval == 0) { - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_inactive, - NULL, NULL, true)); - } else if (server->interface_interval != interface_interval) { - isc_interval_set(&interval, interface_interval, 0); - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_ticker, - NULL, &interval, false)); - } - server->interface_interval = interface_interval; - - /* - * Enable automatic interface scans. - */ - obj = NULL; - result = ns_config_get(maps, "automatic-interface-scan", &obj); - INSIST(result == ISC_R_SUCCESS); - server->interface_auto = cfg_obj_asboolean(obj); - - /* - * Configure the dialup heartbeat timer. - */ - obj = NULL; - result = ns_config_get(maps, "heartbeat-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - heartbeat_interval = cfg_obj_asuint32(obj) * 60; - if (heartbeat_interval == 0) { - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_inactive, - NULL, NULL, true)); - } else if (server->heartbeat_interval != heartbeat_interval) { - isc_interval_set(&interval, heartbeat_interval, 0); - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_ticker, - NULL, &interval, false)); - } - server->heartbeat_interval = heartbeat_interval; - - isc_interval_set(&interval, 1200, 0); - CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL, - &interval, false)); - - isc_interval_set(&interval, ns_g_tat_interval, 0); - CHECK(isc_timer_reset(server->tat_timer, isc_timertype_ticker, NULL, - &interval, false)); - - /* - * Write the PID file. - */ - obj = NULL; - if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) { - if (cfg_obj_isvoid(obj)) { - ns_os_writepidfile(NULL, first_time); - } else { - ns_os_writepidfile(cfg_obj_asstring(obj), first_time); - } - } else if (ns_g_lwresdonly) { - ns_os_writepidfile(lwresd_g_defaultpidfile, first_time); - } else { - ns_os_writepidfile(ns_g_defaultpidfile, first_time); - } - - /* - * Configure the server-wide session key. This must be done before - * configure views because zone configuration may need to know - * session-keyname. - * - * Failure of session key generation isn't fatal at this time; if it - * turns out that a session key is really needed but doesn't exist, - * we'll treat it as a fatal error then. - */ - (void)configure_session_key(maps, server, ns_g_mctx, first_time); - - views = NULL; - (void)cfg_map_get(config, "view", &views); - - /* - * Create the views and count all the configured zones in - * order to correctly size the zone manager's task table. - * (We only count zones for configured views; the built-in - * "bind" view can be ignored as it only adds a negligible - * number of zones.) - * - * If we're allowing new zones, we need to be able to find the - * new zone file and count those as well. So we setup the new - * zone configuration context, but otherwise view configuration - * waits until after the zone manager's task list has been sized. - */ - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - const cfg_obj_t *voptions = cfg_tuple_get(vconfig, "options"); - int nzf_num_zones; - - view = NULL; - - CHECK(create_view(vconfig, &viewlist, &view)); - INSIST(view != NULL); - - num_zones += count_zones(voptions); - - CHECK(setup_newzones(view, config, vconfig, conf_parser, - ns_g_aclconfctx, &nzf_num_zones)); - num_zones += nzf_num_zones; - - dns_view_detach(&view); - } - - /* - * If there were no explicit views then we do the default - * view here. - */ - if (views == NULL) { - int nzf_num_zones; - - CHECK(create_view(NULL, &viewlist, &view)); - INSIST(view != NULL); - - num_zones = count_zones(config); - - CHECK(setup_newzones(view, config, NULL, conf_parser, - ns_g_aclconfctx, &nzf_num_zones)); - num_zones += nzf_num_zones; - - dns_view_detach(&view); - } - - /* - * Zones have been counted; set the zone manager task pool size. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "sizing zone task pool based on %d zones", num_zones); - CHECK(dns_zonemgr_setsize(ns_g_server->zonemgr, num_zones)); - - /* - * Configure and freeze all explicit views. Explicit - * views that have zones were already created at parsing - * time, but views with no zones must be created here. - */ - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - - view = NULL; - CHECK(find_view(vconfig, &viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, vconfig, - &cachelist, bindkeys, ns_g_mctx, - ns_g_aclconfctx, true)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Make sure we have a default view if and only if there - * were no explicit views. - */ - if (views == NULL) { - view = NULL; - CHECK(find_view(NULL, &viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, NULL, - &cachelist, bindkeys, - ns_g_mctx, ns_g_aclconfctx, true)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Create (or recreate) the built-in views. - */ - builtin_views = NULL; - RUNTIME_CHECK(cfg_map_get(ns_g_config, "view", - &builtin_views) == ISC_R_SUCCESS); - for (element = cfg_list_first(builtin_views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - - CHECK(create_view(vconfig, &builtin_viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, vconfig, - &cachelist, bindkeys, - ns_g_mctx, ns_g_aclconfctx, false)); - dns_view_freeze(view); - dns_view_detach(&view); - view = NULL; - } - - /* Now combine the two viewlists into one */ - ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link); - - /* - * Commit any dns_zone_setview() calls on all zones in the new - * view. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_view_setviewcommit(view); - } - - /* Swap our new view list with the production one. */ - tmpviewlist = server->viewlist; - server->viewlist = viewlist; - viewlist = tmpviewlist; - - /* Make the view list available to each of the views */ - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - view->viewlist = &server->viewlist; - view = ISC_LIST_NEXT(view, link); - } - - /* Swap our new cache list with the production one. */ - tmpcachelist = server->cachelist; - server->cachelist = cachelist; - cachelist = tmpcachelist; - - /* Load the TKEY information from the configuration. */ - if (options != NULL) { - dns_tkeyctx_t *t = NULL; - CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy, - &t), - "configuring TKEY"); - if (server->tkeyctx != NULL) { - dns_tkeyctx_destroy(&server->tkeyctx); - } - server->tkeyctx = t; - } - - /* - * Bind the control port(s). - */ - CHECKM(ns_controls_configure(ns_g_server->controls, config, - ns_g_aclconfctx), - "binding control channel(s)"); - - /* - * Bind the lwresd port(s). - */ - CHECKM(ns_lwresd_configure(ns_g_mctx, config), - "binding lightweight resolver ports"); - - /* - * Open the source of entropy. - */ - if (first_time) { - const char *randomdev = NULL; - int level = ISC_LOG_ERROR; - obj = NULL; - result = ns_config_get(maps, "random-device", &obj); - if (result == ISC_R_SUCCESS) { - if (!cfg_obj_isvoid(obj)) { - level = ISC_LOG_INFO; - randomdev = cfg_obj_asstring(obj); - } - } - if (randomdev == NULL) { -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_entropy_usehook(ns_g_entropy, true); -#else - if ((obj != NULL) && !cfg_obj_isvoid(obj)) - level = ISC_LOG_INFO; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, level, - "no source of entropy found"); - if ((obj == NULL) || cfg_obj_isvoid(obj)) { - CHECK(ISC_R_FAILURE); - } -#endif - } else { - result = isc_entropy_createfilesource(ns_g_entropy, - randomdev); -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - level = ISC_LOG_INFO; - } -#endif - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - level, - "could not open " - "entropy source %s: %s", - randomdev, - isc_result_totext(result)); - } -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "using pre-chroot entropy source " - "%s", - PATH_RANDOMDEV); - isc_entropy_detach(&ns_g_entropy); - isc_entropy_attach(ns_g_fallbackentropy, - &ns_g_entropy); - } - isc_entropy_detach(&ns_g_fallbackentropy); - } -#endif - } - -#ifdef HAVE_LMDB - /* - * If we're using LMDB, we may have created newzones - * databases as root, making it impossible to reopen - * them later after switching to a new userid. We - * close them now, and reopen after relinquishing - * privileges them. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; view = ISC_LIST_NEXT(view, link)) - { - nzd_env_close(view); - } -#endif /* HAVE_LMDB */ - - /* - * Relinquish root privileges. - */ - ns_os_changeuser(); - } - - /* - * Check that the working directory is writable. - */ - if (!isc_file_isdirwritable(".")) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "the working directory is not writable"); - } - -#ifdef HAVE_LMDB - /* - * Reopen NZD databases. - */ - if (first_time) { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - nzd_env_reopen(view); - } - } -#endif /* HAVE_LMDB */ - - /* - * Configure the logging system. - * - * Do this after changing UID to make sure that any log - * files specified in named.conf get created by the - * unprivileged user, not root. - */ - if (ns_g_logstderr) { - const cfg_obj_t *logobj = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "not using config file logging " - "statement for logging due to " - "-g option"); - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - result = ns_log_configure(NULL, logobj); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "checking logging configuration " - "failed: %s", - isc_result_totext(result)); - goto cleanup; - } - } - } else { - const cfg_obj_t *logobj = NULL; - - CHECKM(isc_logconfig_create(ns_g_lctx, &logc), - "creating new logging configuration"); - - logobj = NULL; - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - CHECKM(ns_log_configure(logc, logobj), - "configuring logging"); - } else { - CHECKM(ns_log_setdefaultchannels(logc), - "setting up default logging channels"); - CHECKM(ns_log_setunmatchedcategory(logc), - "setting up default 'category unmatched'"); - CHECKM(ns_log_setdefaultcategory(logc), - "setting up default 'category default'"); - } - - CHECKM(isc_logconfig_use(ns_g_lctx, logc), - "installing logging configuration"); - logc = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "now using logging configuration from " - "config file"); - } - - /* - * Set the default value of the query logging flag depending - * whether a "queries" category has been defined. This is - * a disgusting hack, but we need to do this for BIND 8 - * compatibility. - */ - if (first_time) { - const cfg_obj_t *logobj = NULL; - const cfg_obj_t *categories = NULL; - - obj = NULL; - if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) { - server->log_queries = cfg_obj_asboolean(obj); - } else { - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) - (void)cfg_map_get(logobj, "category", - &categories); - if (categories != NULL) { - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *catobj; - const char *str; - - obj = cfg_listelt_value(element); - catobj = cfg_tuple_get(obj, "name"); - str = cfg_obj_asstring(catobj); - if (strcasecmp(str, "queries") == 0) - server->log_queries = true; - } - } - } - } - - obj = NULL; - if (options != NULL && - cfg_map_get(options, "memstatistics", &obj) == ISC_R_SUCCESS) { - ns_g_memstatistics = cfg_obj_asboolean(obj); - } else { - ns_g_memstatistics = - ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0); - } - - obj = NULL; - if (ns_config_get(maps, "memstatistics-file", &obj) == ISC_R_SUCCESS) { - ns_main_setmemstats(cfg_obj_asstring(obj)); - } else if (ns_g_memstatistics) { - ns_main_setmemstats("named.memstats"); - } else { - ns_main_setmemstats(NULL); - } - - obj = NULL; - result = ns_config_get(maps, "statistics-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "dump-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "secroots-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->secrootsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "recursing-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "version", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->version, obj), "strdup"); - server->version_set = true; - } else { - server->version_set = false; - } - - obj = NULL; - result = ns_config_get(maps, "hostname", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->hostname, obj), "strdup"); - server->hostname_set = true; - } else { - server->hostname_set = false; - } - - obj = NULL; - result = ns_config_get(maps, "server-id", &obj); - server->server_usehostname = false; - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - /* The parser translates "hostname" to true */ - server->server_usehostname = cfg_obj_asboolean(obj); - result = setstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } else if (result == ISC_R_SUCCESS) { - /* Found a quoted string */ - CHECKM(setoptstring(server, &server->server_id, obj), "strdup"); - } else { - result = setstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - obj = NULL; - result = ns_config_get(maps, "flush-zones-on-shutdown", &obj); - if (result == ISC_R_SUCCESS) { - server->flushonshutdown = cfg_obj_asboolean(obj); - } else { - server->flushonshutdown = false; - } - - obj = NULL; - result = ns_config_get(maps, "answer-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - server->answercookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "cookie-algorithm", &obj); - INSIST(result == ISC_R_SUCCESS); - if (strcasecmp(cfg_obj_asstring(obj), "siphash24") == 0) { - server->cookiealg = ns_cookiealg_siphash24; - } else if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) { -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) - server->cookiealg = ns_cookiealg_aes; -#else - INSIST(0); - ISC_UNREACHABLE(); -#endif - } else if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0) { - server->cookiealg = ns_cookiealg_sha1; - } else if (strcasecmp(cfg_obj_asstring(obj), "sha256") == 0) { - server->cookiealg = ns_cookiealg_sha256; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "cookie-secret", &obj); - if (result == ISC_R_SUCCESS) { - const char *str; - bool first = true; - isc_buffer_t b; - unsigned int usedlength; - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - - if (first) { - memset(server->secret, 0, - sizeof(server->secret)); - isc_buffer_init(&b, server->secret, - sizeof(server->secret)); - result = isc_hex_decodestring(str, &b); - if (result != ISC_R_SUCCESS && - result != ISC_R_NOSPACE) - goto cleanup; - first = false; - } else { - altsecret = isc_mem_get(server->mctx, - sizeof(*altsecret)); - if (altsecret == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_buffer_init(&b, altsecret->secret, - sizeof(altsecret->secret)); - result = isc_hex_decodestring(str, &b); - if (result != ISC_R_SUCCESS && - result != ISC_R_NOSPACE) { - isc_mem_put(server->mctx, altsecret, - sizeof(*altsecret)); - goto cleanup; - } - ISC_LIST_INITANDAPPEND(altsecrets, - altsecret, link); - } - - usedlength = isc_buffer_usedlength(&b); - switch (server->cookiealg) { - case ns_cookiealg_siphash24: - if (usedlength != ISC_SIPHASH24_KEY_LENGTH) { - CHECKM(ISC_R_RANGE, - "SipHash-2-4 cookie-secret must be 128 bits"); - } - break; - case ns_cookiealg_aes: - if (usedlength != ISC_AES128_KEYLENGTH) { - CHECKM(ISC_R_RANGE, - "AES cookie-secret must be 128 bits"); - } - break; - case ns_cookiealg_sha1: - if (usedlength != ISC_SHA1_DIGESTLENGTH) { - CHECKM(ISC_R_RANGE, - "SHA1 cookie-secret must be " - "160 bits"); - } - break; - case ns_cookiealg_sha256: - if (usedlength != ISC_SHA256_DIGESTLENGTH) { - CHECKM(ISC_R_RANGE, - "SHA256 cookie-secret must be " - "256 bits"); - } - break; - } - } - } else { - result = isc_entropy_getdata(ns_g_entropy, - server->secret, - sizeof(server->secret), - NULL, - 0); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - - /* - * Swap altsecrets lists. - */ - tmpaltsecrets = server->altsecrets; - server->altsecrets = altsecrets; - altsecrets = tmpaltsecrets; - - (void) ns_server_loadnta(server); - - result = ISC_R_SUCCESS; - - cleanup: - if (logc != NULL) { - isc_logconfig_destroy(&logc); - } - - if (v4portset != NULL) { - isc_portset_destroy(ns_g_mctx, &v4portset); - } - - if (v6portset != NULL) { - isc_portset_destroy(ns_g_mctx, &v6portset); - } - - if (conf_parser != NULL) { - if (config != NULL) { - cfg_obj_destroy(conf_parser, &config); - } - cfg_parser_destroy(&conf_parser); - } - - if (bindkeys_parser != NULL) { - if (bindkeys != NULL) { - cfg_obj_destroy(bindkeys_parser, &bindkeys); - } - cfg_parser_destroy(&bindkeys_parser); - } - - if (view != NULL) { - dns_view_detach(&view); - } - - ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link); - - /* - * This cleans up either the old production view list - * or our temporary list depending on whether they - * were swapped above or not. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(viewlist, view, link); - if (result == ISC_R_SUCCESS && - strcmp(view->name, "_bind") != 0) - { - dns_view_setviewrevert(view); - (void)dns_zt_apply(view->zonetable, false, - removed, view); - } - dns_view_detach(&view); - } - - /* Same cleanup for cache list. */ - while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) { - ISC_LIST_UNLINK(cachelist, nsc, link); - dns_cache_detach(&nsc->cache); - isc_mem_put(server->mctx, nsc, sizeof(*nsc)); - } - - /* Same cleanup for altsecrets list. */ - while ((altsecret = ISC_LIST_HEAD(altsecrets)) != NULL) { - ISC_LIST_UNLINK(altsecrets, altsecret, link); - isc_mem_put(server->mctx, altsecret, sizeof(*altsecret)); - } - - /* - * Adjust the listening interfaces in accordance with the source - * addresses specified in views and zones. - */ - if (isc_net_probeipv6() == ISC_R_SUCCESS) { - adjust_interfaces(server, ns_g_mctx); - } - - /* - * Record the time of most recent configuration - */ - tresult = isc_time_now(&ns_g_configtime); - if (tresult != ISC_R_SUCCESS) { - ns_main_earlyfatal("isc_time_now() failed: %s", - isc_result_totext(result)); - } - - /* Relinquish exclusive access to configuration data. */ - if (exclusive) { - isc_task_endexclusive(server->task); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), "load_configuration: %s", - isc_result_totext(result)); - - return (result); -} - -static isc_result_t -view_loaded(void *arg) { - isc_result_t result; - ns_zoneload_t *zl = (ns_zoneload_t *) arg; - ns_server_t *server; - bool reconfig; - unsigned int refs; - - - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - * - * We use the zoneload reference counter to let us - * know when all views are finished. - */ - isc_refcount_decrement(&zl->refs, &refs); - if (refs != 0) - return (ISC_R_SUCCESS); - - server = zl->server; - reconfig = zl->reconfig; - - isc_refcount_destroy(&zl->refs); - isc_mem_put(server->mctx, zl, sizeof (*zl)); - - /* - * To maintain compatibility with log parsing tools that might - * be looking for this string after "rndc reconfig", we keep it - * as it is - */ - if (reconfig) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "any newly configured zones are now loaded"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, - "all zones loaded"); - } - - CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr), - "forcing zone maintenance"); - - ns_os_started(); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "running"); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_zones(ns_server_t *server, bool init, bool reconfig) { - isc_result_t result; - dns_view_t *view; - ns_zoneload_t *zl; - unsigned int refs = 0; - - zl = isc_mem_get(server->mctx, sizeof (*zl)); - if (zl == NULL) - return (ISC_R_NOMEMORY); - zl->server = server; - zl->reconfig = reconfig; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_refcount_init(&zl->refs, 1); - - /* - * Schedule zones to be loaded from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (view->managed_keys != NULL) { - result = dns_zone_load(view->managed_keys); - if (result != ISC_R_SUCCESS && - result != DNS_R_UPTODATE && - result != DNS_R_CONTINUE) - goto cleanup; - } - if (view->redirect != NULL) { - result = dns_zone_load(view->redirect); - if (result != ISC_R_SUCCESS && - result != DNS_R_UPTODATE && - result != DNS_R_CONTINUE) - goto cleanup; - } - - /* - * 'dns_view_asyncload' calls view_loaded if there are no - * zones. - */ - isc_refcount_increment(&zl->refs, NULL); - CHECK(dns_view_asyncload2(view, view_loaded, zl, reconfig)); - } - - cleanup: - isc_refcount_decrement(&zl->refs, &refs); - if (refs == 0) { - isc_refcount_destroy(&zl->refs); - isc_mem_put(server->mctx, zl, sizeof (*zl)); - } else if (init) { - /* - * Place the task manager into privileged mode. This - * ensures that after we leave task-exclusive mode, no - * other tasks will be able to run except for the ones - * that are loading zones. (This should only be done during - * the initial server setup; it isn't necessary during - * a reload.) - */ - isc_taskmgr_setmode(ns_g_taskmgr, isc_taskmgrmode_privileged); - } - - isc_task_endexclusive(server->task); - return (result); -} - -static void -run_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - - isc_event_free(&event); - - CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy, - &ns_g_dispatchmgr), - "creating dispatch manager"); - - dns_dispatchmgr_setstats(ns_g_dispatchmgr, server->resolverstats); - - CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, - ns_g_socketmgr, ns_g_dispatchmgr, - server->task, &server->interfacemgr), - "creating interface manager"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - interface_timer_tick, - server, &server->interface_timer), - "creating interface timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - heartbeat_timer_tick, - server, &server->heartbeat_timer), - "creating heartbeat timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, tat_timer_tick, - server, &server->tat_timer), - "creating trust anchor telemetry timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, pps_timer_tick, - server, &server->pps_timer), - "creating pps timer"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_parser), - "creating default configuration parser"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_addparser), - "creating additional configuration parser"); - - if (ns_g_lwresdonly) - CHECKFATAL(load_configuration(lwresd_g_conffile, server, - true), - "loading configuration"); - else - CHECKFATAL(load_configuration(ns_g_conffile, server, true), - "loading configuration"); - - isc_hash_init(); - - CHECKFATAL(load_zones(server, true, false), "loading zones"); -#ifdef ENABLE_AFL - ns_g_run_done = true; -#endif -} - -void -ns_server_flushonshutdown(ns_server_t *server, bool flush) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->flushonshutdown = flush; -} - -static void -shutdown_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_view_t *view, *view_next; - ns_server_t *server = (ns_server_t *)event->ev_arg; - bool flush = server->flushonshutdown; - ns_cache_t *nsc; - ns_altsecret_t *altsecret; - - UNUSED(task); - INSIST(task == server->task); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "shutting down%s", - flush ? ": flushing changes" : ""); - - ns_statschannels_shutdown(server); - ns_controls_shutdown(server->controls); - end_reserved_dispatches(server, true); - cleanup_session_key(server, server->mctx); - - if (ns_g_aclconfctx != NULL) - cfg_aclconfctx_detach(&ns_g_aclconfctx); - - cfg_obj_destroy(ns_g_parser, &ns_g_config); - cfg_parser_destroy(&ns_g_parser); - cfg_parser_destroy(&ns_g_addparser); - - (void) ns_server_saventa(server); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(server->viewlist, view, link); - if (flush) - dns_view_flushanddetach(&view); - else - dns_view_detach(&view); - } - - dns_dyndb_cleanup(true); - - while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) { - ISC_LIST_UNLINK(server->cachelist, nsc, link); - dns_cache_detach(&nsc->cache); - isc_mem_put(server->mctx, nsc, sizeof(*nsc)); - } - - while ((altsecret = ISC_LIST_HEAD(server->altsecrets)) != NULL) { - ISC_LIST_UNLINK(server->altsecrets, altsecret, link); - isc_mem_put(server->mctx, altsecret, sizeof(*altsecret)); - } - - isc_timer_detach(&server->interface_timer); - isc_timer_detach(&server->heartbeat_timer); - isc_timer_detach(&server->pps_timer); - isc_timer_detach(&server->tat_timer); - - ns_interfacemgr_shutdown(server->interfacemgr); - ns_interfacemgr_detach(&server->interfacemgr); - - dns_dispatchmgr_destroy(&ns_g_dispatchmgr); - - dns_zonemgr_shutdown(server->zonemgr); - - if (ns_g_sessionkey != NULL) { - dns_tsigkey_detach(&ns_g_sessionkey); - dns_name_free(&ns_g_sessionkeyname, server->mctx); - } - - if (server->keepresporder != NULL) - dns_acl_detach(&server->keepresporder); - - if (server->blackholeacl != NULL) - dns_acl_detach(&server->blackholeacl); - -#ifdef HAVE_DNSTAP - dns_dt_shutdown(); -#endif -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - ns_geoip_shutdown(); - dns_geoip_shutdown(); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - dns_db_detach(&server->in_roothints); - - isc_task_endexclusive(server->task); - - isc_task_detach(&server->task); - - isc_event_free(&event); -} - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { - isc_result_t result; - ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); - - if (server == NULL) - fatal(server, "allocating server object", ISC_R_NOMEMORY); - - server->mctx = mctx; - server->task = NULL; - - /* Initialize configuration data with default values. */ - result = isc_quota_init(&server->xfroutquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->tcpquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->recursionquota, 100); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_aclenv_init(mctx, &server->aclenv); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - /* Initialize GeoIP before using ACL environment */ - ns_geoip_init(); - server->aclenv.geoip = ns_g_geoip; -#endif - - /* Initialize server data structures. */ - server->zonemgr = NULL; - server->interfacemgr = NULL; - ISC_LIST_INIT(server->viewlist); - server->in_roothints = NULL; - server->blackholeacl = NULL; - server->keepresporder = NULL; - server->rngctx = NULL; - - /* Must be first. */ - CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, - ns_g_engine, ISC_ENTROPY_GOODONLY), - "initializing DST"); - - CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, - &server->in_roothints), - "setting up root hints"); - - CHECKFATAL(isc_mutex_init(&server->reload_event_lock), - "initializing reload event lock"); - server->reload_event = - isc_event_allocate(ns_g_mctx, server, - NS_EVENT_RELOAD, - ns_server_reload, - server, - sizeof(isc_event_t)); - CHECKFATAL(server->reload_event == NULL ? - ISC_R_NOMEMORY : ISC_R_SUCCESS, - "allocating reload event"); - - server->tkeyctx = NULL; - CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, - &server->tkeyctx), - "creating TKEY context"); - server->rngctx = NULL; - CHECKFATAL(isc_rng_create(ns_g_mctx, ns_g_entropy, &server->rngctx), - "creating random numbers context"); - - /* - * Setup the server task, which is responsible for coordinating - * startup and shutdown of the server, as well as all exclusive - * tasks. - */ - CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task), - "creating server task"); - isc_task_setname(server->task, "server", server); - isc_taskmgr_setexcltask(ns_g_taskmgr, server->task); - CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server), - "isc_task_onshutdown"); - CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server), - "isc_app_onrun"); - - server->interface_timer = NULL; - server->heartbeat_timer = NULL; - server->pps_timer = NULL; - server->tat_timer = NULL; - - server->interface_interval = 0; - server->heartbeat_interval = 0; - - CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, - ns_g_socketmgr, &server->zonemgr), - "dns_zonemgr_create"); - CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), - "dns_zonemgr_setsize"); - - server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); - CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - server->nsstats = NULL; - server->rcvquerystats = NULL; - server->opcodestats = NULL; - server->rcodestats = NULL; - server->zonestats = NULL; - server->resolverstats = NULL; - server->sockstats = NULL; - server->udpinstats4 = NULL; - server->udpoutstats4 = NULL; - server->udpinstats6 = NULL; - server->udpoutstats6 = NULL; - server->tcpinstats4 = NULL; - server->tcpoutstats4 = NULL; - server->tcpinstats6 = NULL; - server->tcpoutstats6 = NULL; - CHECKFATAL(isc_stats_create(server->mctx, &server->sockstats, - isc_sockstatscounter_max), - "isc_stats_create"); - isc_socketmgr_setstats(ns_g_socketmgr, server->sockstats); - - server->bindkeysfile = isc_mem_strdup(server->mctx, "bind.keys"); - CHECKFATAL(server->bindkeysfile == NULL ? ISC_R_NOMEMORY : - ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db"); - CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->secrootsfile = isc_mem_strdup(server->mctx, "named.secroots"); - CHECKFATAL(server->secrootsfile == NULL ? ISC_R_NOMEMORY : - ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->recfile = isc_mem_strdup(server->mctx, "named.recursing"); - CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->hostname_set = false; - server->hostname = NULL; - server->version_set = false; - server->version = NULL; - server->server_usehostname = false; - server->server_id = NULL; - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->nsstats, - dns_nsstatscounter_max), - "dns_stats_create (server)"); - - CHECKFATAL(dns_rdatatypestats_create(ns_g_mctx, - &server->rcvquerystats), - "dns_stats_create (rcvquery)"); - - CHECKFATAL(dns_opcodestats_create(ns_g_mctx, &server->opcodestats), - "dns_stats_create (opcode)"); - - CHECKFATAL(dns_rcodestats_create(ns_g_mctx, &server->rcodestats), - "dns_stats_create (rcode)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->zonestats, - dns_zonestatscounter_max), - "dns_stats_create (zone)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->resolverstats, - dns_resstatscounter_max), - "dns_stats_create (resolver)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats4, - dns_sizecounter_in_max), - "dns_stats_create (inbound UDP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats4, - dns_sizecounter_out_max), - "dns_stats_create (outbound UDP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats6, - dns_sizecounter_in_max), - "dns_stats_create (inbound UDP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats6, - dns_sizecounter_out_max), - "dns_stats_create (outbound UDP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats4, - dns_sizecounter_in_max), - "dns_stats_create (inbound TCP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats4, - dns_sizecounter_out_max), - "dns_stats_create (outbound TCP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats6, - dns_sizecounter_in_max), - "dns_stats_create (inbound TCP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats6, - dns_sizecounter_out_max), - "dns_stats_create (outbound TCP IPv6 traffic size)"); - - server->flushonshutdown = false; - server->log_queries = false; - - server->controls = NULL; - CHECKFATAL(ns_controls_create(server, &server->controls), - "ns_controls_create"); - server->dispatchgen = 0; - ISC_LIST_INIT(server->dispatches); - - ISC_LIST_INIT(server->statschannels); - - ISC_LIST_INIT(server->cachelist); - - ISC_LIST_INIT(server->altsecrets); - - server->sessionkey = NULL; - server->session_keyfile = NULL; - server->session_keyname = NULL; - server->session_keyalg = DST_ALG_UNKNOWN; - server->session_keybits = 0; - - server->lockfile = NULL; - - server->dtenv = NULL; - server->answercookie = true; - - server->magic = NS_SERVER_MAGIC; - *serverp = server; -} - -void -ns_server_destroy(ns_server_t **serverp) { - ns_server_t *server = *serverp; - REQUIRE(NS_SERVER_VALID(server)); - -#ifdef HAVE_DNSTAP - if (server->dtenv != NULL) - dns_dt_detach(&server->dtenv); -#endif /* HAVE_DNSTAP */ - - ns_controls_destroy(&server->controls); - - isc_stats_detach(&server->nsstats); - dns_stats_detach(&server->rcvquerystats); - dns_stats_detach(&server->opcodestats); - dns_stats_detach(&server->rcodestats); - isc_stats_detach(&server->zonestats); - isc_stats_detach(&server->resolverstats); - isc_stats_detach(&server->sockstats); - isc_stats_detach(&server->udpinstats4); - isc_stats_detach(&server->udpoutstats4); - isc_stats_detach(&server->udpinstats6); - isc_stats_detach(&server->udpoutstats6); - isc_stats_detach(&server->tcpinstats4); - isc_stats_detach(&server->tcpoutstats4); - isc_stats_detach(&server->tcpinstats6); - isc_stats_detach(&server->tcpoutstats6); - - isc_mem_free(server->mctx, server->statsfile); - isc_mem_free(server->mctx, server->bindkeysfile); - isc_mem_free(server->mctx, server->dumpfile); - isc_mem_free(server->mctx, server->secrootsfile); - isc_mem_free(server->mctx, server->recfile); - - if (server->version != NULL) - isc_mem_free(server->mctx, server->version); - if (server->hostname != NULL) - isc_mem_free(server->mctx, server->hostname); - if (server->server_id != NULL) - isc_mem_free(server->mctx, server->server_id); - if (server->lockfile != NULL) - isc_mem_free(server->mctx, server->lockfile); - - if (server->zonemgr != NULL) - dns_zonemgr_detach(&server->zonemgr); - if (server->rngctx != NULL) - isc_rng_detach(&server->rngctx); - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - - dst_lib_destroy(); - - isc_event_free(&server->reload_event); - - INSIST(ISC_LIST_EMPTY(server->viewlist)); - INSIST(ISC_LIST_EMPTY(server->cachelist)); - - dns_aclenv_destroy(&server->aclenv); - - isc_quota_destroy(&server->recursionquota); - isc_quota_destroy(&server->tcpquota); - isc_quota_destroy(&server->xfroutquota); - - server->magic = 0; - isc_mem_put(server->mctx, server, sizeof(*server)); - *serverp = NULL; -} - -static void -fatal(ns_server_t *server, const char *msg, isc_result_t result) { - if (server != NULL && server->task != NULL) { - /* - * Prevent races between the OpenSSL on_exit registered - * function and any other OpenSSL calls from other tasks - * by requesting exclusive access to the task manager. - */ - (void)isc_task_beginexclusive(server->task); - } - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "%s: %s", msg, - isc_result_totext(result)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "exiting (due to fatal error)"); - ns_os_shutdown(); - exit(1); -} - -static void -start_reserved_dispatches(ns_server_t *server) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->dispatchgen++; -} - -static void -end_reserved_dispatches(ns_server_t *server, bool all) { - ns_dispatch_t *dispatch, *nextdispatch; - - REQUIRE(NS_SERVER_VALID(server)); - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = nextdispatch) { - nextdispatch = ISC_LIST_NEXT(dispatch, link); - if (!all && server->dispatchgen == dispatch-> dispatchgen) - continue; - ISC_LIST_UNLINK(server->dispatches, dispatch, link); - dns_dispatch_detach(&dispatch->dispatch); - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - } -} - -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr) { - ns_dispatch_t *dispatch; - in_port_t port; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - unsigned int attrs, attrmask; - - REQUIRE(NS_SERVER_VALID(server)); - - port = isc_sockaddr_getport(addr); - if (port == 0 || port >= 1024) - return; - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = ISC_LIST_NEXT(dispatch, link)) { - if (isc_sockaddr_equal(&dispatch->addr, addr)) - break; - } - if (dispatch != NULL) { - dispatch->dispatchgen = server->dispatchgen; - return; - } - - dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); - if (dispatch == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - dispatch->addr = *addr; - dispatch->dispatchgen = server->dispatchgen; - dispatch->dispatch = NULL; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &dispatch->addr, 4096, - UDPBUFFERS, 32768, 16411, 16433, - attrs, attrmask, &dispatch->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); - - return; - - cleanup: - if (dispatch != NULL) - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "unable to create dispatch for reserved port %s: %s", - addrbuf, isc_result_totext(result)); -} - - -static isc_result_t -loadconfig(ns_server_t *server) { - isc_result_t result; - start_reserved_dispatches(server); - result = load_configuration(ns_g_lwresdonly ? - lwresd_g_conffile : ns_g_conffile, - server, false); - if (result == ISC_R_SUCCESS) { - end_reserved_dispatches(server, false); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reloading configuration succeeded"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading configuration failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -static isc_result_t -reload(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_zones(server, false, false); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reloading zones succeeded"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading zones failed: %s", - isc_result_totext(result)); - - cleanup: - return (result); -} - -/* - * Handle a reload event (from SIGHUP). - */ -static void -ns_server_reload(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - UNUSED(task); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "received SIGHUP signal to reload zones"); - (void)reload(server); - - LOCK(&server->reload_event_lock); - INSIST(server->reload_event == NULL); - server->reload_event = event; - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_reloadwanted(ns_server_t *server) { - LOCK(&server->reload_event_lock); - if (server->reload_event != NULL) - isc_task_send(server->task, &server->reload_event); - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_scan_interfaces(ns_server_t *server) { - isc_result_t result; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "automatic interface rescan"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, true); - isc_task_endexclusive(server->task); -} - -/* - * Get the next token from lexer 'lex'. - * - * NOTE: the token value for string tokens always uses the same pointer - * value. Multiple calls to this function on the same lexer will always - * return either that value (lex->data) or NULL. It is necessary to copy - * the token into local storage if it needs to be referenced after the next - * call to next_token(). - */ -static char * -next_token(isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - isc_token_t token; - - token.type = isc_tokentype_unknown; - result = isc_lex_gettoken(lex, ISC_LEXOPT_EOF|ISC_LEXOPT_QSTRING, - &token); - - switch (result) { - case ISC_R_NOMORE: - (void) isc_lex_close(lex); - break; - case ISC_R_SUCCESS: - if (token.type == isc_tokentype_eof) - (void) isc_lex_close(lex); - break; - case ISC_R_NOSPACE: - if (text != NULL) { - (void) putstr(text, "token too large"); - (void) putnull(text); - } - return (NULL); - default: - if (text != NULL) { - (void) putstr(text, isc_result_totext(result)); - (void) putnull(text); - } - return (NULL); - } - - if (token.type == isc_tokentype_string || - token.type == isc_tokentype_qstring) - return (token.value.as_textregion.base); - - return (NULL); -} - -/* - * Find the zone specified in the control channel command, if any. - * If a zone is specified, point '*zonep' at it, otherwise - * set '*zonep' to NULL, and f 'zonename' is not NULL, copy - * the zone name into it (N.B. 'zonename' must have space to hold - * a full DNS name). - * - * If 'zonetxt' is set, the caller has already pulled a token - * off the command line that is to be used as the zone name. (This - * is sometimes done when it's necessary to check for an optional - * argument before the zone name, as in "rndc sync [-clean] zone".) - */ -static isc_result_t -zone_from_args(ns_server_t *server, isc_lex_t *lex, const char *zonetxt, - dns_zone_t **zonep, char *zonename, - isc_buffer_t **text, bool skip) -{ - char *ptr; - char *classtxt; - const char *viewtxt = NULL; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - char problem[DNS_NAME_FORMATSIZE + 500] = ""; - char zonebuf[DNS_NAME_FORMATSIZE]; - - REQUIRE(zonep != NULL && *zonep == NULL); - - if (skip) { - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - } - - /* Look for the zone name. */ - if (zonetxt == NULL) - zonetxt = next_token(lex, text); - if (zonetxt == NULL) - return (ISC_R_SUCCESS); - - /* Copy zonetxt because it'll be overwritten by next_token() */ - strlcpy(zonebuf, zonetxt, DNS_NAME_FORMATSIZE); - if (zonename != NULL) - strlcpy(zonename, zonetxt, DNS_NAME_FORMATSIZE); - - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromstring(name, zonebuf, 0, NULL)); - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - CHECK(dns_rdataclass_fromtext(&rdclass, &r)); - - /* Look for the optional view name. */ - viewtxt = next_token(lex, text); - } else - rdclass = dns_rdataclass_in; - - if (viewtxt == NULL) { - result = dns_viewlist_findzone(&server->viewlist, name, - (classtxt == NULL), - rdclass, zonep); - if (result == ISC_R_NOTFOUND) - snprintf(problem, sizeof(problem), - "no matching zone '%s' in any view", - zonebuf); - else if (result == ISC_R_MULTIPLE) - snprintf(problem, sizeof(problem), - "zone '%s' was found in multiple views", - zonebuf); - } else { - result = dns_viewlist_find(&server->viewlist, viewtxt, - rdclass, &view); - if (result != ISC_R_SUCCESS) { - snprintf(problem, sizeof(problem), - "no matching view '%s'", viewtxt); - goto report; - } - - result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); - if (result != ISC_R_SUCCESS) - snprintf(problem, sizeof(problem), - "no matching zone '%s' in view '%s'", - zonebuf, viewtxt); - } - - /* Partial match? */ - if (result != ISC_R_SUCCESS && *zonep != NULL) - dns_zone_detach(zonep); - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - report: - if (result != ISC_R_SUCCESS) { - isc_result_t tresult; - - tresult = putstr(text, problem); - if (tresult == ISC_R_SUCCESS) - (void) putnull(text); - } - - cleanup: - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -/* - * Act on a "retransfer" command from the command channel. - */ -isc_result_t -ns_server_retransfercommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - dns_zonetype_t type; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) - dns_zone_forcereload(zone); - else - result = ISC_R_NOTFOUND; - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "reload" command from the command channel. - */ -isc_result_t -ns_server_reloadcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - const char *msg = NULL; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) { - result = reload(server); - if (result == ISC_R_SUCCESS) - msg = "server reload successful"; - } else { - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - msg = "zone refresh queued"; - } else { - result = dns_zone_load(zone); - dns_zone_detach(&zone); - switch (result) { - case ISC_R_SUCCESS: - msg = "zone reload successful"; - break; - case DNS_R_CONTINUE: - msg = "zone reload queued"; - result = ISC_R_SUCCESS; - break; - case DNS_R_UPTODATE: - msg = "zone reload up-to-date"; - result = ISC_R_SUCCESS; - break; - default: - /* failure message will be generated by rndc */ - break; - } - } - } - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - return (result); -} - -/* - * Act on a "reconfig" command from the command channel. - */ -isc_result_t -ns_server_reconfigcommand(ns_server_t *server) { - isc_result_t result; - - CHECK(loadconfig(server)); - - result = load_zones(server, false, true); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "scheduled loading new zones"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "loading new zones failed: %s", - isc_result_totext(result)); -cleanup: - return (result); -} - -/* - * Act on a "notify" command from the command channel. - */ -isc_result_t -ns_server_notifycommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - const char msg[] = "zone notify queued"; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_notify(zone); - dns_zone_detach(&zone); - (void) putstr(text, msg); - (void) putnull(text); - - return (ISC_R_SUCCESS); -} - -/* - * Act on a "refresh" command from the command channel. - */ -isc_result_t -ns_server_refreshcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL, *raw = NULL; - const char msg1[] = "zone refresh queued"; - const char msg2[] = "not a slave or stub zone"; - dns_zonetype_t type; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - (void) putstr(text, msg1); - (void) putnull(text); - return (ISC_R_SUCCESS); - } - - dns_zone_detach(&zone); - (void) putstr(text, msg2); - (void) putnull(text); - return (ISC_R_FAILURE); -} - -isc_result_t -ns_server_togglequerylog(ns_server_t *server, isc_lex_t *lex) { - bool value; - char *ptr; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, NULL); - if (ptr == NULL) { - value = server->log_queries ? false : true; - } else if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || - !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) { - value = true; - } else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || - !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) { - value = false; - } else { - return (DNS_R_SYNTAX); - } - - if (server->log_queries == value) - return (ISC_R_SUCCESS); - - server->log_queries = value; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "query logging is now %s", - server->log_queries ? "on" : "off"); - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenlist_t **target) -{ - isc_result_t result; - const cfg_listelt_t *element; - ns_listenlist_t *dlist = NULL; - - REQUIRE(target != NULL && *target == NULL); - - result = ns_listenlist_create(mctx, &dlist); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(listenlist); - element != NULL; - element = cfg_list_next(element)) - { - ns_listenelt_t *delt = NULL; - const cfg_obj_t *listener = cfg_listelt_value(element); - result = ns_listenelt_fromconfig(listener, config, actx, - mctx, family, &delt); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(dlist->elts, delt, link); - } - *target = dlist; - return (ISC_R_SUCCESS); - - cleanup: - ns_listenlist_detach(&dlist); - return (result); -} - -/* - * Create a listen list from the corresponding configuration - * data structure. - */ -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenelt_t **target) -{ - isc_result_t result; - const cfg_obj_t *portobj, *dscpobj; - in_port_t port; - isc_dscp_t dscp = -1; - ns_listenelt_t *delt = NULL; - REQUIRE(target != NULL && *target == NULL); - - portobj = cfg_tuple_get(listener, "port"); - if (!cfg_obj_isuint32(portobj)) { - if (ns_g_port != 0) { - port = ns_g_port; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - } else { - if (cfg_obj_asuint32(portobj) >= UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port value '%u' is out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - port = (in_port_t)cfg_obj_asuint32(portobj); - } - - dscpobj = cfg_tuple_get(listener, "dscp"); - if (!cfg_obj_isuint32(dscpobj)) - dscp = ns_g_dscp; - else { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - result = ns_listenelt_create(mctx, port, dscp, NULL, &delt); - if (result != ISC_R_SUCCESS) - return (result); - - result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), - config, ns_g_lctx, actx, mctx, 0, - family, &delt->acl); - if (result != ISC_R_SUCCESS) { - ns_listenelt_destroy(delt); - return (result); - } - *target = delt; - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_dumpstats(ns_server_t *server) { - isc_result_t result; - FILE *fp = NULL; - - CHECKMF(isc_stdio_open(server->statsfile, "a", &fp), - "could not open statistics dump file", server->statsfile); - - result = ns_stats_dump(server, fp); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpstats complete"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpstats failed: %s", - dns_result_totext(result)); - return (result); -} - -static isc_result_t -add_zone_tolist(dns_zone_t *zone, void *uap) { - struct dumpcontext *dctx = uap; - struct zonelistentry *zle; - - zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) - return (ISC_R_NOMEMORY); - zle->zone = NULL; - dns_zone_attach(zone, &zle->zone); - ISC_LINK_INIT(zle, link); - ISC_LIST_APPEND(ISC_LIST_TAIL(dctx->viewlist)->zonelist, zle, link); - return (ISC_R_SUCCESS); -} - -static isc_result_t -add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) { - struct viewlistentry *vle; - isc_result_t result = ISC_R_SUCCESS; - - /* - * Prevent duplicate views. - */ - for (vle = ISC_LIST_HEAD(dctx->viewlist); - vle != NULL; - vle = ISC_LIST_NEXT(vle, link)) - if (vle->view == view) - return (ISC_R_SUCCESS); - - vle = isc_mem_get(dctx->mctx, sizeof *vle); - if (vle == NULL) - return (ISC_R_NOMEMORY); - vle->view = NULL; - dns_view_attach(view, &vle->view); - ISC_LINK_INIT(vle, link); - ISC_LIST_INIT(vle->zonelist); - ISC_LIST_APPEND(dctx->viewlist, vle, link); - if (dctx->dumpzones) - result = dns_zt_apply(view->zonetable, true, - add_zone_tolist, dctx); - return (result); -} - -static void -dumpcontext_destroy(struct dumpcontext *dctx) { - struct viewlistentry *vle; - struct zonelistentry *zle; - - vle = ISC_LIST_HEAD(dctx->viewlist); - while (vle != NULL) { - ISC_LIST_UNLINK(dctx->viewlist, vle, link); - zle = ISC_LIST_HEAD(vle->zonelist); - while (zle != NULL) { - ISC_LIST_UNLINK(vle->zonelist, zle, link); - dns_zone_detach(&zle->zone); - isc_mem_put(dctx->mctx, zle, sizeof *zle); - zle = ISC_LIST_HEAD(vle->zonelist); - } - dns_view_detach(&vle->view); - isc_mem_put(dctx->mctx, vle, sizeof *vle); - vle = ISC_LIST_HEAD(dctx->viewlist); - } - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, false); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->cache != NULL) - dns_db_detach(&dctx->cache); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - if (dctx->fp != NULL) - (void)isc_stdio_close(dctx->fp); - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - isc_mem_put(dctx->mctx, dctx, sizeof *dctx); -} - -static void -dumpdone(void *arg, isc_result_t result) { - struct dumpcontext *dctx = arg; - char buf[1024+32]; - const dns_master_style_t *style; - - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - if (dctx->mdctx != NULL) { - dns_dumpctx_detach(&dctx->mdctx); - } - if (dctx->view == NULL) { - dctx->view = ISC_LIST_HEAD(dctx->viewlist); - if (dctx->view == NULL) { - goto done; - } - INSIST(dctx->zone == NULL); - } else { - goto resume; - } - nextview: - fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name); - resume: - if (dctx->dumpcache && dns_view_iscacheshared(dctx->view->view)) { - fprintf(dctx->fp, - ";\n; Cache of view '%s' is shared as '%s'\n", - dctx->view->view->name, - dns_cache_getname(dctx->view->view->cache)); - } else if (dctx->zone == NULL && dctx->cache == NULL && - dctx->dumpcache) - { - style = &dns_master_style_cache; - /* start cache dump */ - if (dctx->view->view->cachedb != NULL) { - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - } - if (dctx->cache != NULL) { - fprintf(dctx->fp, - ";\n; Cache dump of view '%s' (cache %s)\n;\n", - dctx->view->view->name, - dns_cache_getname(dctx->view->view->cache)); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->cache, NULL, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) { - return; - } - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - } else if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - } - - if ((dctx->dumpadb || dctx->dumpbad || dctx->dumpfail) && - dctx->cache == NULL && dctx->view->view->cachedb != NULL) { - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - } - - if (dctx->cache != NULL) { - if (dctx->dumpadb) { - dns_adb_dump(dctx->view->view->adb, dctx->fp); - } - if (dctx->dumpbad) { - dns_resolver_printbadcache(dctx->view->view->resolver, - dctx->fp); - } - if (dctx->dumpfail) { - dns_badcache_print(dctx->view->view->failcache, - "SERVFAIL cache", dctx->fp); - } - dns_db_detach(&dctx->cache); - } - if (dctx->dumpzones) { - style = &dns_master_style_full; - nextzone: - if (dctx->version != NULL) { - dns_db_closeversion(dctx->db, &dctx->version, - false); - } - if (dctx->db != NULL) { - dns_db_detach(&dctx->db); - } - if (dctx->zone == NULL) { - dctx->zone = ISC_LIST_HEAD(dctx->view->zonelist); - } else { - dctx->zone = ISC_LIST_NEXT(dctx->zone, link); - } - if (dctx->zone != NULL) { - /* start zone dump */ - dns_zone_name(dctx->zone->zone, buf, sizeof(buf)); - fprintf(dctx->fp, ";\n; Zone dump of '%s'\n;\n", buf); - result = dns_zone_getdb(dctx->zone->zone, &dctx->db); - if (result != ISC_R_SUCCESS) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - goto nextzone; - } - dns_db_currentversion(dctx->db, &dctx->version); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->db, - dctx->version, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) { - return; - } - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - result = ISC_R_SUCCESS; - POST(result); - goto nextzone; - } - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - } - if (dctx->view != NULL) { - dctx->view = ISC_LIST_NEXT(dctx->view, link); - if (dctx->view != NULL) { - goto nextview; - } - } - done: - fprintf(dctx->fp, "; Dump complete\n"); - result = isc_stdio_flush(dctx->fp); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb complete"); - } - cleanup: - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpdb failed: %s", dns_result_totext(result)); - } - dumpcontext_destroy(dctx); -} - -isc_result_t -ns_server_dumpdb(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - struct dumpcontext *dctx = NULL; - dns_view_t *view; - isc_result_t result; - char *ptr; - const char *sep; - bool found; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - dctx = isc_mem_get(server->mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - dctx->mctx = server->mctx; - dctx->dumpcache = true; - dctx->dumpadb = true; - dctx->dumpbad = true; - dctx->dumpfail = true; - dctx->dumpzones = false; - dctx->fp = NULL; - ISC_LIST_INIT(dctx->viewlist); - dctx->view = NULL; - dctx->zone = NULL; - dctx->cache = NULL; - dctx->mdctx = NULL; - dctx->db = NULL; - dctx->cache = NULL; - dctx->task = NULL; - dctx->version = NULL; - isc_task_attach(server->task, &dctx->task); - - CHECKMF(isc_stdio_open(server->dumpfile, "w", &dctx->fp), - "could not open dump file", server->dumpfile); - - ptr = next_token(lex, NULL); - sep = (ptr == NULL) ? "" : ": "; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb started%s%s", sep, (ptr != NULL) ? ptr : ""); - - if (ptr != NULL && strcmp(ptr, "-all") == 0) { - /* also dump zones */ - dctx->dumpzones = true; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-cache") == 0) { - /* this is the default */ - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-zones") == 0) { - /* only dump zones, suppress caches */ - dctx->dumpadb = false; - dctx->dumpbad = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - dctx->dumpzones = true; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-adb") == 0) { - /* only dump adb, suppress other caches */ - dctx->dumpbad = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-bad") == 0) { - /* only dump badcache, suppress other caches */ - dctx->dumpadb = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-fail") == 0) { - /* only dump servfail cache, suppress other caches */ - dctx->dumpadb = false; - dctx->dumpbad = false; - dctx->dumpcache = false; - ptr = next_token(lex, NULL); - } - - nextview: - found = false; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) - continue; - found = true; - CHECK(add_view_tolist(dctx, view)); - } - if (ptr != NULL) { - if (!found) { - CHECK(putstr(text, "view '")); - CHECK(putstr(text, ptr)); - CHECK(putstr(text, "' not found")); - CHECK(putnull(text)); - result = ISC_R_NOTFOUND; - dumpdone(dctx, result); - return (result); - } - ptr = next_token(lex, NULL); - if (ptr != NULL) - goto nextview; - } - dumpdone(dctx, ISC_R_SUCCESS); - return (ISC_R_SUCCESS); - - cleanup: - if (dctx != NULL) - dumpcontext_destroy(dctx); - return (result); -} - -isc_result_t -ns_server_dumpsecroots(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - dns_view_t *view; - dns_keytable_t *secroots = NULL; - dns_ntatable_t *ntatable = NULL; - isc_result_t result; - char *ptr; - FILE *fp = NULL; - isc_time_t now; - char tbuf[64]; - unsigned int used = isc_buffer_usedlength(*text); - bool first = true; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* "-" here means print the output instead of dumping to file */ - ptr = next_token(lex, text); - if (ptr != NULL && strcmp(ptr, "-") == 0) { - ptr = next_token(lex, text); - } else { - result = isc_stdio_open(server->secrootsfile, "w", &fp); - if (result != ISC_R_SUCCESS) { - (void) putstr(text, "could not open "); - (void) putstr(text, server->secrootsfile); - CHECKMF(result, "could not open secroots dump file", - server->secrootsfile); - } - } - - TIME_NOW(&now); - isc_time_formattimestamp(&now, tbuf, sizeof(tbuf)); - CHECK(putstr(text, "secure roots as of ")); - CHECK(putstr(text, tbuf)); - CHECK(putstr(text, ":\n")); - used = isc_buffer_usedlength(*text); - - do { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) { - continue; - } - if (secroots != NULL) { - dns_keytable_detach(&secroots); - } - result = dns_view_getsecroots(view, &secroots); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - if (first || used != isc_buffer_usedlength(*text)) { - CHECK(putstr(text, "\n")); - first = false; - } - CHECK(putstr(text, " Start view ")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, "\n Secure roots:\n\n")); - used = isc_buffer_usedlength(*text); - CHECK(dns_keytable_totext(secroots, text)); - - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - if (used != isc_buffer_usedlength(*text)) { - CHECK(putstr(text, "\n")); - } - CHECK(putstr(text, " Negative trust anchors:\n\n")); - used = isc_buffer_usedlength(*text); - CHECK(dns_ntatable_totext(ntatable, text)); - } - - if (ptr != NULL) { - ptr = next_token(lex, text); - } - } while (ptr != NULL); - - cleanup: - if (secroots != NULL) { - dns_keytable_detach(&secroots); - } - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - - if (fp != NULL) { - if (used != isc_buffer_usedlength(*text)) { - (void)putstr(text, "\n"); - } - fprintf(fp, "%.*s", (int) isc_buffer_usedlength(*text), - (char *) isc_buffer_base(*text)); - isc_buffer_clear(*text); - (void)isc_stdio_close(fp); - } else if (isc_buffer_usedlength(*text) > 0) { - (void)putnull(text); - } - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpsecroots complete"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpsecroots failed: %s", - dns_result_totext(result)); - } - return (result); -} - -isc_result_t -ns_server_dumprecursing(ns_server_t *server) { - FILE *fp = NULL; - dns_view_t *view; - isc_result_t result; - - CHECKMF(isc_stdio_open(server->recfile, "w", &fp), - "could not open dump file", server->recfile); - fprintf(fp, ";\n; Recursing Queries\n;\n"); - ns_interfacemgr_dumprecursing(fp, server->interfacemgr); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - fprintf(fp, ";\n; Active fetch domains [view: %s]\n;\n", - view->name); - dns_resolver_dumpfetches(view->resolver, - isc_statsformat_file, fp); - } - - fprintf(fp, "; Dump complete\n"); - - cleanup: - if (fp != NULL) - result = isc_stdio_close(fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumprecursing complete"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumprecursing failed: %s", - dns_result_totext(result)); - return (result); -} - -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, isc_lex_t *lex) { - char *ptr; - char *endp; - long newlevel; - - UNUSED(server); - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the new level name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) { - if (ns_g_debuglevel < 99) - ns_g_debuglevel++; - } else { - newlevel = strtol(ptr, &endp, 10); - if (*endp != '\0' || newlevel < 0 || newlevel > 99) - return (ISC_R_RANGE); - ns_g_debuglevel = (unsigned int)newlevel; - } - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "debug level is now %u", ns_g_debuglevel); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_validation(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - char *ptr; - dns_view_t *view; - bool changed = false; - isc_result_t result; - bool enable = true, set = true, first = true; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || - !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) { - enable = true; - } else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || - !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) { - enable = false; - } else if (!strcasecmp(ptr, "check") || !strcasecmp(ptr, "status")) { - set = false; - } else { - return (DNS_R_SYNTAX); - } - - /* Look for the view name. */ - ptr = next_token(lex, text); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcasecmp(ptr, view->name) != 0) - continue; - CHECK(dns_view_flushcache(view)); - - if (set) { - view->enablevalidation = enable; - changed = true; - } else { - if (!first) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "DNSSEC validation is ")); - CHECK(putstr(text, view->enablevalidation - ? "enabled" : "disabled")); - CHECK(putstr(text, " (view ")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ")")); - CHECK(putnull(text)); - first = false; - } - } - - if (!set) - result = ISC_R_SUCCESS; - else if (changed) - result = ISC_R_SUCCESS; - else - result = ISC_R_FAILURE; - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushcache(ns_server_t *server, isc_lex_t *lex) { - char *ptr; - dns_view_t *view; - bool flushed; - bool found; - isc_result_t result; - ns_cache_t *nsc; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the view name. */ - ptr = next_token(lex, NULL); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = true; - found = false; - - /* - * Flushing a cache is tricky when caches are shared by multiple views. - * We first identify which caches should be flushed in the local cache - * list, flush these caches, and then update other views that refer to - * the flushed cache DB. - */ - if (ptr != NULL) { - /* - * Mark caches that need to be flushed. This is an O(#view^2) - * operation in the very worst case, but should be normally - * much more lightweight because only a few (most typically just - * one) views will match. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (strcasecmp(ptr, view->name) != 0) - continue; - found = true; - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (nsc->cache == view->cache) - break; - } - INSIST(nsc != NULL); - nsc->needflush = true; - } - } else - found = true; - - /* Perform flush */ - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (ptr != NULL && !nsc->needflush) - continue; - nsc->needflush = true; - result = dns_view_flushcache2(nsc->primaryview, false); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing cache in view '%s' failed: %s", - nsc->primaryview->name, - isc_result_totext(result)); - } - } - - /* - * Fix up views that share a flushed cache: let the views update the - * cache DB they're referring to. This could also be an expensive - * operation, but should typically be marginal: the inner loop is only - * necessary for views that share a cache, and if there are many such - * views the number of shared cache should normally be small. - * A worst case is that we have n views and n/2 caches, each shared by - * two views. Then this will be a O(n^2/4) operation. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (!dns_view_iscacheshared(view)) - continue; - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (!nsc->needflush || nsc->cache != view->cache) - continue; - result = dns_view_flushcache2(view, true); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "fixing cache in view '%s' " - "failed: %s", view->name, - isc_result_totext(result)); - } - } - } - - /* Cleanup the cache list. */ - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - nsc->needflush = false; - } - - if (flushed && found) { - if (ptr != NULL) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing cache in view '%s' succeeded", - ptr); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing caches in all views succeeded"); - result = ISC_R_SUCCESS; - } else { - if (!found) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing cache in view '%s' failed: " - "view not found", ptr); - result = ISC_R_NOTFOUND; - } else - result = ISC_R_FAILURE; - } - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushnode(ns_server_t *server, isc_lex_t *lex, bool tree) { - char *ptr, *viewname; - char target[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - bool flushed; - bool found; - isc_result_t result; - isc_buffer_t b; - dns_fixedname_t fixed; - dns_name_t *name; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find the domain name to flush. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - strlcpy(target, ptr, DNS_NAME_FORMATSIZE); - isc_buffer_constinit(&b, target, strlen(target)); - isc_buffer_add(&b, strlen(target)); - name = dns_fixedname_initname(&fixed); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - /* Look for the view name. */ - viewname = next_token(lex, NULL); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = true; - found = false; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - found = true; - /* - * It's a little inefficient to try flushing name for all views - * if some of the views share a single cache. But since the - * operation is lightweight we prefer simplicity here. - */ - result = dns_view_flushnode(view, name, tree); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing %s '%s' in cache view '%s' " - "failed: %s", - tree ? "tree" : "name", - target, view->name, - isc_result_totext(result)); - } - } - if (flushed && found) { - if (viewname != NULL) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing %s '%s' in cache view '%s' " - "succeeded", - tree ? "tree" : "name", - target, viewname); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing %s '%s' in all cache views " - "succeeded", - tree ? "tree" : "name", - target); - result = ISC_R_SUCCESS; - } else { - if (!found) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing %s '%s' in cache view '%s' " - "failed: view not found", - tree ? "tree" : "name", - target, viewname); - result = ISC_R_FAILURE; - } - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t **text) { - isc_result_t result; - unsigned int zonecount, xferrunning, xferdeferred, soaqueries; - unsigned int automatic; - const char *ob = "", *cb = "", *alt = ""; - char boottime[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char configtime[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char line[1024], hostname[256]; - - if (ns_g_server->version_set) { - ob = " ("; - cb = ")"; - if (ns_g_server->version == NULL) - alt = "version.bind/txt/ch disabled"; - else - alt = ns_g_server->version; - } - zonecount = dns_zonemgr_getcount(server->zonemgr, DNS_ZONESTATE_ANY); - xferrunning = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERRUNNING); - xferdeferred = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERDEFERRED); - soaqueries = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_SOAQUERY); - automatic = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_AUTOMATIC); - - isc_time_formathttptimestamp(&ns_g_boottime, boottime, - sizeof(boottime)); - isc_time_formathttptimestamp(&ns_g_configtime, configtime, - sizeof(configtime)); - - snprintf(line, sizeof(line), "version: %s %s%s%s %s%s%s\n", - ns_g_product, ns_g_version, - (*ns_g_description != '\0') ? " " : "", - ns_g_description, ns_g_srcid, ob, alt, cb); - CHECK(putstr(text, line)); - - result = ns_os_gethostname(hostname, sizeof(hostname)); - if (result != ISC_R_SUCCESS) - strlcpy(hostname, "localhost", sizeof(hostname)); - snprintf(line, sizeof(line), "running on %s: %s\n", - hostname, ns_os_uname()); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "boot time: %s\n", boottime); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "last configured: %s\n", configtime); - CHECK(putstr(text, line)); - - if (ns_g_chrootdir != NULL) { - snprintf(line, sizeof(line), "configuration file: %s (%s%s)\n", - ns_g_conffile, ns_g_chrootdir, ns_g_conffile); - } else { - snprintf(line, sizeof(line), "configuration file: %s\n", - ns_g_conffile); - } - CHECK(putstr(text, line)); - -#ifdef ISC_PLATFORM_USETHREADS - snprintf(line, sizeof(line), "CPUs found: %u\n", ns_g_cpus_detected); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "worker threads: %u\n", ns_g_cpus); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "UDP listeners per interface: %u\n", - ns_g_udpdisp); - CHECK(putstr(text, line)); -#else - snprintf(line, sizeof(line), "CPUs found: N/A (threads disabled)\n"); - CHECK(putstr(text, line)); -#endif - - snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n", - zonecount, automatic); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "debug level: %u\n", ns_g_debuglevel); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "xfers running: %u\n", xferrunning); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "xfers deferred: %u\n", xferdeferred); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "soa queries in progress: %u\n", - soaqueries); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "query logging is %s\n", - server->log_queries ? "ON" : "OFF"); - CHECK(putstr(text, line)); - - LOCK(&server->recursionquota.lock); - snprintf(line, sizeof(line), "recursive clients: %d/%d/%d\n", - server->recursionquota.used, server->recursionquota.soft, - server->recursionquota.max); - UNLOCK(&server->recursionquota.lock); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "tcp clients: %d/%d\n", - server->tcpquota.used, server->tcpquota.max); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "TCP high-water: %" PRIu64 "\n", - isc_stats_get_counter(ns_g_server->nsstats, - dns_nsstatscounter_tcphighwater)); - CHECK(putstr(text, line)); - - CHECK(putstr(text, "server is up and running")); - CHECK(putnull(text)); - - return (ISC_R_SUCCESS); - cleanup: - return (result); -} - -isc_result_t -ns_server_testgen(isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - char *ptr; - unsigned long count; - unsigned long i; - const unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz0123456789"; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, text); - if (ptr == NULL) - count = 26; - else - count = strtoul(ptr, NULL, 10); - - CHECK(isc_buffer_reserve(text, count)); - for (i = 0; i < count; i++) - CHECK(putuint8(text, chars[i % (sizeof(chars) - 1)])); - - CHECK(putnull(text)); - - cleanup: - return (result); -} - -static isc_result_t -delete_keynames(dns_tsig_keyring_t *ring, char *target, - unsigned int *foundkeys) -{ - char namestr[DNS_NAME_FORMATSIZE]; - isc_result_t result; - dns_rbtnodechain_t chain; - dns_name_t foundname; - dns_fixedname_t fixedorigin; - dns_name_t *origin; - dns_rbtnode_t *node; - dns_tsigkey_t *tkey; - - dns_name_init(&foundname, NULL); - origin = dns_fixedname_initname(&fixedorigin); - - again: - dns_rbtnodechain_init(&chain, ring->mctx); - result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, - origin); - if (result == ISC_R_NOTFOUND) { - dns_rbtnodechain_invalidate(&chain); - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - - for (;;) { - node = NULL; - dns_rbtnodechain_current(&chain, &foundname, origin, &node); - tkey = node->data; - - if (tkey != NULL) { - if (!tkey->generated) - goto nextkey; - - dns_name_format(&tkey->name, namestr, sizeof(namestr)); - if (strcmp(namestr, target) == 0) { - (*foundkeys)++; - dns_rbtnodechain_invalidate(&chain); - (void)dns_rbt_deletename(ring->keys, - &tkey->name, - false); - goto again; - } - } - - nextkey: - result = dns_rbtnodechain_next(&chain, &foundname, origin); - if (result == ISC_R_NOMORE) - break; - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_tsigdelete(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_view_t *view; - unsigned int foundkeys = 0; - char *ptr, *viewname; - char target[DNS_NAME_FORMATSIZE]; - char fbuf[16]; - - (void)next_token(lex, text); /* skip command name */ - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(target, ptr, DNS_NAME_FORMATSIZE); - - viewname = next_token(lex, text); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (viewname == NULL || strcmp(view->name, viewname) == 0) { - RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_write); - result = delete_keynames(view->dynamickeys, target, - &foundkeys); - RWUNLOCK(&view->dynamickeys->lock, - isc_rwlocktype_write); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - } - } - isc_task_endexclusive(server->task); - - snprintf(fbuf, sizeof(fbuf), "%u", foundkeys); - - CHECK(putstr(text, fbuf)); - CHECK(putstr(text, " tsig keys deleted.")); - CHECK(putnull(text)); - - cleanup: - return (result); -} - -static isc_result_t -list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t **text, - unsigned int *foundkeys) -{ - char namestr[DNS_NAME_FORMATSIZE]; - char creatorstr[DNS_NAME_FORMATSIZE]; - isc_result_t result; - dns_rbtnodechain_t chain; - dns_name_t foundname; - dns_fixedname_t fixedorigin; - dns_name_t *origin; - dns_rbtnode_t *node; - dns_tsigkey_t *tkey; - const char *viewname; - - if (view != NULL) - viewname = view->name; - else - viewname = "(global)"; - - dns_name_init(&foundname, NULL); - origin = dns_fixedname_initname(&fixedorigin); - dns_rbtnodechain_init(&chain, ring->mctx); - result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, - origin); - if (result == ISC_R_NOTFOUND) { - dns_rbtnodechain_invalidate(&chain); - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - - for (;;) { - node = NULL; - dns_rbtnodechain_current(&chain, &foundname, origin, &node); - tkey = node->data; - - if (tkey != NULL) { - dns_name_format(&tkey->name, namestr, sizeof(namestr)); - if (tkey->generated) { - dns_name_format(tkey->creator, creatorstr, - sizeof(creatorstr)); - if (*foundkeys != 0) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "view \"")); - CHECK(putstr(text, viewname)); - CHECK(putstr(text, - "\"; type \"dynamic\"; key \"")); - CHECK(putstr(text, namestr)); - CHECK(putstr(text, "\"; creator \"")); - CHECK(putstr(text, creatorstr)); - CHECK(putstr(text, "\";")); - } else { - if (*foundkeys != 0) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "view \"")); - CHECK(putstr(text, viewname)); - CHECK(putstr(text, - "\"; type \"static\"; key \"")); - CHECK(putstr(text, namestr)); - CHECK(putstr(text, "\";")); - } - (*foundkeys)++; - } - result = dns_rbtnodechain_next(&chain, &foundname, origin); - if (result == ISC_R_NOMORE || result == DNS_R_NEWORIGIN) - break; - } - - return (ISC_R_SUCCESS); - cleanup: - dns_rbtnodechain_invalidate(&chain); - return (result); -} - -isc_result_t -ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text) { - isc_result_t result; - dns_view_t *view; - unsigned int foundkeys = 0; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - RWLOCK(&view->statickeys->lock, isc_rwlocktype_read); - result = list_keynames(view, view->statickeys, text, - &foundkeys); - RWUNLOCK(&view->statickeys->lock, isc_rwlocktype_read); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_read); - result = list_keynames(view, view->dynamickeys, text, - &foundkeys); - RWUNLOCK(&view->dynamickeys->lock, isc_rwlocktype_read); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - } - isc_task_endexclusive(server->task); - - if (foundkeys == 0) - CHECK(putstr(text, "no tsig keys found.")); - - if (isc_buffer_usedlength(*text) > 0) - CHECK(putnull(text)); - - cleanup: - return (result); -} - -/* - * Act on a "sign" or "loadkeys" command from the command channel. - */ -isc_result_t -ns_server_rekey(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - uint16_t keyopts; - bool fullsign = false; - char *ptr; - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, NS_COMMAND_SIGN) == 0) - fullsign = true; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, false); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); /* XXX: or do all zones? */ - - type = dns_zone_gettype(zone); - if (type != dns_zone_master) { - dns_zone_detach(&zone); - return (DNS_R_NOTMASTER); - } - - keyopts = dns_zone_getkeyopts(zone); - - /* "rndc loadkeys" requires "auto-dnssec maintain". */ - if ((keyopts & DNS_ZONEKEY_ALLOW) == 0) - result = ISC_R_NOPERM; - else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign) - result = ISC_R_NOPERM; - else - dns_zone_rekey(zone, fullsign); - - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "sync" command from the command channel. -*/ -static isc_result_t -synczone(dns_zone_t *zone, void *uap) { - bool cleanup = *(bool *)uap; - isc_result_t result; - dns_zone_t *raw = NULL; - char *journal; - - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - synczone(raw, uap); - dns_zone_detach(&raw); - } - - result = dns_zone_flush(zone); - if (result != ISC_R_SUCCESS) - cleanup = false; - if (cleanup) { - journal = dns_zone_getjournal(zone); - if (journal != NULL) - (void)isc_file_remove(journal); - } - - return (result); -} - -isc_result_t -ns_server_sync(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result, tresult; - dns_view_t *view; - dns_zone_t *zone = NULL; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - const char *vname, *sep, *arg; - bool cleanup = false; - - (void) next_token(lex, text); - - arg = next_token(lex, text); - if (arg != NULL && - (strcmp(arg, "-clean") == 0 || strcmp(arg, "-clear") == 0)) { - cleanup = true; - arg = next_token(lex, text); - } - - result = zone_from_args(server, lex, arg, &zone, NULL, - text, false); - if (result != ISC_R_SUCCESS) - return (result); - - if (zone == NULL) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tresult = ISC_R_SUCCESS; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - result = dns_zt_apply(view->zonetable, false, - synczone, &cleanup); - if (result != ISC_R_SUCCESS && - tresult == ISC_R_SUCCESS) - tresult = result; - } - isc_task_endexclusive(server->task); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumping all zones%s: %s", - cleanup ? ", removing journal files" : "", - isc_result_totext(result)); - return (tresult); - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = synczone(zone, &cleanup); - isc_task_endexclusive(server->task); - - view = dns_zone_getview(zone); - if (strcmp(view->name, "_default") == 0 || - strcmp(view->name, "_bind") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(zone), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "sync: dumping zone '%s/%s'%s%s%s: %s", - zonename, classstr, sep, vname, - cleanup ? ", removing journal file" : "", - isc_result_totext(result)); - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "freeze" or "thaw" command from the command channel. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, bool freeze, - isc_lex_t *lex, isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *mayberaw = NULL, *raw = NULL; - dns_zonetype_t type; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - const char *vname, *sep; - bool frozen; - const char *msg = NULL; - - result = zone_from_args(server, lex, NULL, &mayberaw, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (mayberaw == NULL) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tresult = ISC_R_SUCCESS; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - result = dns_view_freezezones(view, freeze); - if (result != ISC_R_SUCCESS && - tresult == ISC_R_SUCCESS) - tresult = result; - } - isc_task_endexclusive(server->task); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s all zones: %s", - freeze ? "freezing" : "thawing", - isc_result_totext(tresult)); - return (tresult); - } - dns_zone_getraw(mayberaw, &raw); - if (raw != NULL) { - dns_zone_detach(&mayberaw); - dns_zone_attach(raw, &mayberaw); - dns_zone_detach(&raw); - } - type = dns_zone_gettype(mayberaw); - if (type != dns_zone_master) { - dns_zone_detach(&mayberaw); - return (DNS_R_NOTMASTER); - } - - if (freeze && !dns_zone_isdynamic(mayberaw, true)) { - dns_zone_detach(&mayberaw); - return (DNS_R_NOTDYNAMIC); - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - frozen = dns_zone_getupdatedisabled(mayberaw); - if (freeze) { - if (frozen) { - msg = "WARNING: The zone was already frozen.\n" - "Someone else may be editing it or " - "it may still be re-loading."; - result = DNS_R_FROZEN; - } - if (result == ISC_R_SUCCESS) { - result = dns_zone_flush(mayberaw); - if (result != ISC_R_SUCCESS) - msg = "Flushing the zone updates to " - "disk failed."; - } - if (result == ISC_R_SUCCESS) - dns_zone_setupdatedisabled(mayberaw, freeze); - } else { - if (frozen) { - result = dns_zone_loadandthaw(mayberaw); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_UPTODATE: - msg = "The zone reload and thaw was " - "successful."; - result = ISC_R_SUCCESS; - break; - case DNS_R_CONTINUE: - msg = "A zone reload and thaw was started.\n" - "Check the logs to see the result."; - result = ISC_R_SUCCESS; - break; - } - } - } - isc_task_endexclusive(server->task); - - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - - view = dns_zone_getview(mayberaw); - if (strcmp(view->name, "_default") == 0 || - strcmp(view->name, "_bind") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(mayberaw), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(mayberaw), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone '%s/%s'%s%s: %s", - freeze ? "freezing" : "thawing", - zonename, classstr, sep, vname, - isc_result_totext(result)); - dns_zone_detach(&mayberaw); - return (result); -} - -#ifdef HAVE_LIBSCF -/* - * This function adds a message for rndc to echo if named - * is managed by smf and is also running chroot. - */ -isc_result_t -ns_smf_add_message(isc_buffer_t **text) { - return (putstr(text, "use svcadm(1M) to manage named")); -} -#endif /* HAVE_LIBSCF */ - -#ifndef HAVE_LMDB - -/* - * Emit a comment at the top of the nzf file containing the viewname - * Expects the fp to already be open for writing - */ -#define HEADER1 "# New zone file for view: " -#define HEADER2 "\n# This file contains configuration for zones added by\n" \ - "# the 'rndc addzone' command. DO NOT EDIT BY HAND.\n" -static isc_result_t -add_comment(FILE *fp, const char *viewname) { - isc_result_t result; - CHECK(isc_stdio_write(HEADER1, sizeof(HEADER1) - 1, 1, fp, NULL)); - CHECK(isc_stdio_write(viewname, strlen(viewname), 1, fp, NULL)); - CHECK(isc_stdio_write(HEADER2, sizeof(HEADER2) - 1, 1, fp, NULL)); - cleanup: - return (result); -} - -static void -dumpzone(void *arg, const char *buf, int len) { - FILE *fp = arg; - - (void) isc_stdio_write(buf, len, 1, fp, NULL); -} - -static isc_result_t -nzf_append(dns_view_t *view, const cfg_obj_t *zconfig) { - isc_result_t result; - off_t offset; - FILE *fp = NULL; - bool offsetok = false; - - LOCK(&view->new_zone_lock); - - CHECK(isc_stdio_open(view->new_zone_file, "a", &fp)); - CHECK(isc_stdio_seek(fp, 0, SEEK_END)); - - CHECK(isc_stdio_tell(fp, &offset)); - offsetok = true; - if (offset == 0) - CHECK(add_comment(fp, view->name)); - - CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL)); - cfg_printx(zconfig, CFG_PRINTER_ONELINE, dumpzone, fp); - CHECK(isc_stdio_write(";\n", 2, 1, fp, NULL)); - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - - cleanup: - if (fp != NULL) { - (void)isc_stdio_close(fp); - if (offsetok) { - isc_result_t result2; - - result2 = isc_file_truncate(view->new_zone_file, - offset); - if (result2 != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error truncating NZF file '%s' " - "during rollback from append: " - "%s", - view->new_zone_file, - isc_result_totext(result2)); - } - } - } - UNLOCK(&view->new_zone_lock); - return (result); -} - -static isc_result_t -nzf_writeconf(const cfg_obj_t *config, dns_view_t *view) { - const cfg_obj_t *zl = NULL; - cfg_list_t *list; - const cfg_listelt_t *elt; - - FILE *fp = NULL; - char tmp[1024]; - isc_result_t result; - - result = isc_file_template("", "nzf-XXXXXXXX", tmp, sizeof(tmp)); - if (result == ISC_R_SUCCESS) - result = isc_file_openunique(tmp, &fp); - if (result != ISC_R_SUCCESS) - return (result); - - cfg_map_get(config, "zone", &zl); - if (!cfg_obj_islist(zl)) - CHECK(ISC_R_FAILURE); - - DE_CONST(&zl->value.list, list); - - CHECK(add_comment(fp, view->name)); /* force a comment */ - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(elt); - - CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL)); - cfg_printx(zconfig, CFG_PRINTER_ONELINE, dumpzone, fp); - CHECK(isc_stdio_write(";\n", 2, 1, fp, NULL)); - } - - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - if (result != ISC_R_SUCCESS) - goto cleanup; - CHECK(isc_file_rename(tmp, view->new_zone_file)); - return (result); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - (void)isc_file_remove(tmp); - return (result); -} - -#else /* HAVE_LMDB */ - -static void -nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen) { - dns_fixedname_t fixed; - - dns_fixedname_init(&fixed); - dns_name_downcase(name, dns_fixedname_name(&fixed), NULL); - dns_name_format(dns_fixedname_name(&fixed), namebuf, buflen); - - key->mv_data = namebuf; - key->mv_size = strlen(namebuf); -} - -static void -dumpzone(void *arg, const char *buf, int len) { - ns_dzarg_t *dzarg = arg; - isc_result_t result; - - REQUIRE(dzarg != NULL && ISC_MAGIC_VALID(dzarg, DZARG_MAGIC)); - - result = putmem(dzarg->text, buf, len); - if (result != ISC_R_SUCCESS && dzarg->result == ISC_R_SUCCESS) { - dzarg->result = result; - } -} - -static isc_result_t -nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone, - const cfg_obj_t *zconfig) -{ - isc_result_t result; - int status; - dns_view_t *view; - bool commit = false; - isc_buffer_t *text = NULL; - char namebuf[1024]; - MDB_val key, data; - ns_dzarg_t dzarg; - - view = dns_zone_getview(zone); - - nzd_setkey(&key, dns_zone_getorigin(zone), namebuf, sizeof(namebuf)); - - if (zconfig == NULL) { - /* We're deleting the zone from the database */ - status = mdb_del(*txnp, dbi, &key, NULL); - if (status != MDB_SUCCESS && status != MDB_NOTFOUND) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error deleting zone %s " - "from NZD database: %s", - namebuf, mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } else if (status != MDB_NOTFOUND) { - commit = true; - } - } else { - /* We're creating or overwriting the zone */ - const cfg_obj_t *zoptions; - - result = isc_buffer_allocate(view->mctx, &text, 256); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Unable to allocate buffer in " - "nzd_save(): %s", - isc_result_totext(result)); - goto cleanup; - } - - zoptions = cfg_tuple_get(zconfig, "options"); - if (zoptions == NULL) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Unable to get options from config in " - "nzd_save()"); - result = ISC_R_FAILURE; - goto cleanup; - } - - dzarg.magic = DZARG_MAGIC; - dzarg.text = &text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg); - if (dzarg.result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error writing zone config to " - "buffer in nzd_save(): %s", - isc_result_totext(result)); - result = dzarg.result; - goto cleanup; - } - - data.mv_data = isc_buffer_base(text); - data.mv_size = isc_buffer_usedlength(text); - - status = mdb_put(*txnp, dbi, &key, &data, 0); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error inserting zone in " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - commit = true; - } - - result = ISC_R_SUCCESS; - - cleanup: - if (!commit || result != ISC_R_SUCCESS) { - (void) mdb_txn_abort(*txnp); - } else { - status = mdb_txn_commit(*txnp); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error committing " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - } - } - *txnp = NULL; - - if (text != NULL) { - isc_buffer_free(&text); - } - - return (result); -} - -/* - * Check whether the new zone database for 'view' can be opened for writing. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_writable(dns_view_t *view) { - isc_result_t result = ISC_R_SUCCESS; - int status; - MDB_dbi dbi; - MDB_txn *txn = NULL; - - REQUIRE(view != NULL); - - status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0, 0, &txn); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_txn_begin: %s", - mdb_strerror(status)); - return (ISC_R_FAILURE); - } - - status = mdb_dbi_open(txn, NULL, 0, &dbi); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_dbi_open: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - } - - mdb_txn_abort(txn); - return (result); -} - -/* - * Open the new zone database for 'view' and start a transaction for it. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) { - int status; - MDB_txn *txn = NULL; - - REQUIRE(view != NULL); - REQUIRE(txnp != NULL && *txnp == NULL); - REQUIRE(dbi != NULL); - - status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0, - flags, &txn); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_txn_begin: %s", - mdb_strerror(status)); - goto cleanup; - } - - status = mdb_dbi_open(txn, NULL, 0, dbi); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_dbi_open: %s", - mdb_strerror(status)); - goto cleanup; - } - - *txnp = txn; - - cleanup: - if (status != MDB_SUCCESS) { - if (txn != NULL) { - mdb_txn_abort(txn); - } - return (ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); -} - -/* - * nzd_env_close() and nzd_env_reopen are a kluge to address the - * problem of an NZD file possibly being created before we drop - * root privileges. - */ -static void -nzd_env_close(dns_view_t *view) { - const char *dbpath = NULL; - char dbpath_copy[PATH_MAX]; - char lockpath[PATH_MAX]; - int status, ret; - - if (view->new_zone_dbenv == NULL) { - return; - } - - status = mdb_env_get_path(view->new_zone_dbenv, &dbpath); - INSIST(status == MDB_SUCCESS); - snprintf(lockpath, sizeof(lockpath), "%s-lock", dbpath); - strlcpy(dbpath_copy, dbpath, sizeof(dbpath_copy)); - mdb_env_close((MDB_env *) view->new_zone_dbenv); - - /* - * Database files must be owned by the eventual user, not by root. - */ - ret = chown(dbpath_copy, ns_os_uid(), -1); - UNUSED(ret); - - /* - * Some platforms need the lockfile not to exist when we reopen the - * environment. - */ - (void) isc_file_remove(lockpath); - - view->new_zone_dbenv = NULL; -} - -static isc_result_t -nzd_env_reopen(dns_view_t *view) { - isc_result_t result; - MDB_env *env = NULL; - int status; - - if (view->new_zone_db == NULL) { - return (ISC_R_SUCCESS); - } - - nzd_env_close(view); - - status = mdb_env_create(&env); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_create failed: %s", - mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - - if (view->new_zone_mapsize != 0ULL) { - status = mdb_env_set_mapsize(env, view->new_zone_mapsize); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_set_mapsize failed: %s", - mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - } - - status = mdb_env_open(env, view->new_zone_db, DNS_LMDB_FLAGS, 0600); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_open of '%s' failed: %s", - view->new_zone_db, mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - - view->new_zone_dbenv = env; - env = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (env != NULL) { - mdb_env_close(env); - } - return (result); -} - -/* - * If 'commit' is true, commit the new zone database transaction pointed to by - * 'txnp'; otherwise, abort that transaction. - * - * Caller must hold 'view->new_zone_lock' for the view that the transaction - * pointed to by 'txnp' was started for. - */ -static isc_result_t -nzd_close(MDB_txn **txnp, bool commit) { - isc_result_t result = ISC_R_SUCCESS; - int status; - - REQUIRE(txnp != NULL); - - if (*txnp != NULL) { - if (commit) { - status = mdb_txn_commit(*txnp); - if (status != MDB_SUCCESS) { - result = ISC_R_FAILURE; - } - } else { - mdb_txn_abort(*txnp); - } - *txnp = NULL; - } - - return (result); -} - -/* - * Count the zones configured in the new zone database for 'view' and store the - * result in 'countp'. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_count(dns_view_t *view, int *countp) { - isc_result_t result; - int status; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_stat statbuf; - - REQUIRE(countp != NULL); - - result = nzd_open(view, MDB_RDONLY, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - status = mdb_stat(txn, dbi, &statbuf); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_stat: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - *countp = statbuf.ms_entries; - - cleanup: - (void) nzd_close(&txn, false); - - return (result); -} - -/* - * Migrate zone configuration from an NZF file to an NZD database. - * Caller must hold view->new_zone_lock. - */ -static isc_result_t -migrate_nzf(dns_view_t *view) { - isc_result_t result; - cfg_obj_t *nzf_config = NULL; - int status, n; - isc_buffer_t *text = NULL; - bool commit = false; - const cfg_obj_t *zonelist; - const cfg_listelt_t *element; - char tempname[PATH_MAX]; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_val key, data; - ns_dzarg_t dzarg; - - /* - * If NZF file doesn't exist, or NZD DB exists and already - * has data, return without attempting migration. - */ - if (!isc_file_exists(view->new_zone_file)) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - result = nzd_count(view, &n); - if (result == ISC_R_SUCCESS && n > 0) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "Migrating zones from NZF file '%s' to " - "NZD database '%s'", - view->new_zone_file, view->new_zone_db); - /* - * Instead of blindly copying lines, we parse the NZF file using - * the configuration parser, because it validates it against the - * config type, giving us a guarantee that valid configuration - * will be written to DB. - */ - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_file(ns_g_addparser, view->new_zone_file, - &cfg_type_addzoneconf, &nzf_config); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error parsing NZF file '%s': %s", - view->new_zone_file, - isc_result_totext(result)); - goto cleanup; - } - - zonelist = NULL; - CHECK(cfg_map_get(nzf_config, "zone", &zonelist)); - if (!cfg_obj_islist(zonelist)) { - CHECK(ISC_R_FAILURE); - } - - CHECK(nzd_open(view, 0, &txn, &dbi)); - - CHECK(isc_buffer_allocate(view->mctx, &text, 256)); - - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig; - const cfg_obj_t *zoptions; - char zname[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fname; - dns_name_t *name; - const char *origin; - isc_buffer_t b; - - zconfig = cfg_listelt_value(element); - - origin = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - if (origin == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - /* Normalize zone name */ - isc_buffer_constinit(&b, origin, strlen(origin)); - isc_buffer_add(&b, strlen(origin)); - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - DNS_NAME_DOWNCASE, NULL)); - dns_name_format(name, zname, sizeof(zname)); - - key.mv_data = zname; - key.mv_size = strlen(zname); - - zoptions = cfg_tuple_get(zconfig, "options"); - if (zoptions == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - isc_buffer_clear(text); - dzarg.magic = DZARG_MAGIC; - dzarg.text = &text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg); - if (dzarg.result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error writing zone config to " - "buffer in migrate_nzf(): %s", - isc_result_totext(result)); - result = dzarg.result; - goto cleanup; - } - - data.mv_data = isc_buffer_base(text); - data.mv_size = isc_buffer_usedlength(text); - - status = mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error inserting zone in " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - commit = true; - } - - result = ISC_R_SUCCESS; - - /* - * Leaving the NZF file in place is harmless as we won't use it - * if an NZD database is found for the view. But we rename NZF file - * to a backup name here. - */ - strlcpy(tempname, view->new_zone_file, sizeof(tempname)); - if (strlen(tempname) < sizeof(tempname) - 1) { - strlcat(tempname, "~", sizeof(tempname)); - isc_file_rename(view->new_zone_file, tempname); - } - - cleanup: - if (result != ISC_R_SUCCESS) { - (void) nzd_close(&txn, false); - } else { - result = nzd_close(&txn, commit); - } - - if (text != NULL) { - isc_buffer_free(&text); - } - - if (nzf_config != NULL) { - cfg_obj_destroy(ns_g_addparser, &nzf_config); - } - - return (result); -} - -#endif /* HAVE_LMDB */ - -static isc_result_t -newzone_parse(ns_server_t *server, char *command, dns_view_t **viewp, - cfg_obj_t **zoneconfp, const cfg_obj_t **zoneobjp, - isc_buffer_t **text) -{ - isc_result_t result; - isc_buffer_t argbuf; - cfg_obj_t *zoneconf = NULL; - const cfg_obj_t *zlist = NULL; - const cfg_obj_t *zoneobj = NULL; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *obj = NULL; - const char *viewname = NULL; - dns_rdataclass_t rdclass; - dns_view_t *view = NULL; - const char *bn = NULL; - - REQUIRE(viewp != NULL && *viewp == NULL); - REQUIRE(zoneobjp != NULL && *zoneobjp == NULL); - REQUIRE(zoneconfp != NULL && *zoneconfp == NULL); - - /* Try to parse the argument string */ - isc_buffer_init(&argbuf, command, (unsigned int) strlen(command)); - isc_buffer_add(&argbuf, strlen(command)); - - if (strncasecmp(command, "add", 3) == 0) { - bn = "addzone"; - } else if (strncasecmp(command, "mod", 3) == 0) { - bn = "modzone"; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Convert the "addzone" or "modzone" to just "zone", for - * the benefit of the parser - */ - isc_buffer_forward(&argbuf, 3); - - cfg_parser_reset(ns_g_addparser); - CHECK(cfg_parse_buffer3(ns_g_addparser, &argbuf, bn, 0, - &cfg_type_addzoneconf, &zoneconf)); - CHECK(cfg_map_get(zoneconf, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - /* For now we only support adding one zone at a time */ - zoneobj = cfg_listelt_value(cfg_list_first(zlist)); - - /* Check the zone type for ones that are not supported by addzone. */ - zoptions = cfg_tuple_get(zoneobj, "options"); - - obj = NULL; - (void)cfg_map_get(zoptions, "type", &obj); - if (obj == NULL) { - (void) cfg_map_get(zoptions, "in-view", &obj); - if (obj != NULL) { - (void) putstr(text, - "'in-view' zones not supported by "); - (void) putstr(text, bn); - } else - (void) putstr(text, "zone type not specified"); - CHECK(ISC_R_FAILURE); - } - - if (strcasecmp(cfg_obj_asstring(obj), "hint") == 0 || - strcasecmp(cfg_obj_asstring(obj), "forward") == 0 || - strcasecmp(cfg_obj_asstring(obj), "redirect") == 0 || - strcasecmp(cfg_obj_asstring(obj), "delegation-only") == 0) - { - (void) putstr(text, "'"); - (void) putstr(text, cfg_obj_asstring(obj)); - (void) putstr(text, "' zones not supported by "); - (void) putstr(text, bn); - CHECK(ISC_R_FAILURE); - } - - /* Make sense of optional class argument */ - obj = cfg_tuple_get(zoneobj, "class"); - CHECK(ns_config_getclass(obj, dns_rdataclass_in, &rdclass)); - - /* Make sense of optional view argument */ - obj = cfg_tuple_get(zoneobj, "view"); - if (obj && cfg_obj_isstring(obj)) - viewname = cfg_obj_asstring(obj); - if (viewname == NULL || *viewname == '\0') - viewname = "_default"; - result = dns_viewlist_find(&server->viewlist, viewname, rdclass, - &view); - if (result == ISC_R_NOTFOUND) { - (void) putstr(text, "no matching view found for '"); - (void) putstr(text, viewname); - (void) putstr(text, "'"); - goto cleanup; - } else if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - *viewp = view; - *zoneobjp = zoneobj; - *zoneconfp = zoneconf; - - return (ISC_R_SUCCESS); - - cleanup: - if (zoneconf != NULL) - cfg_obj_destroy(ns_g_addparser, &zoneconf); - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -static isc_result_t -delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, - const cfg_obj_t *config, const dns_name_t *zname, - nzfwriter_t nzfwriter) -{ - isc_result_t result = ISC_R_NOTFOUND; - const cfg_listelt_t *elt = NULL; - const cfg_obj_t *zl = NULL; - cfg_list_t *list; - dns_fixedname_t myfixed; - dns_name_t *myname; - - REQUIRE(view != NULL); - REQUIRE(pctx != NULL); - REQUIRE(config != NULL); - REQUIRE(zname != NULL); - - LOCK(&view->new_zone_lock); - - cfg_map_get(config, "zone", &zl); - - if (!cfg_obj_islist(zl)) - CHECK(ISC_R_FAILURE); - - DE_CONST(&zl->value.list, list); - - myname = dns_fixedname_initname(&myfixed); - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) - { - const cfg_obj_t *zconf = cfg_listelt_value(elt); - const char *zn; - cfg_listelt_t *e; - - zn = cfg_obj_asstring(cfg_tuple_get(zconf, "name")); - result = dns_name_fromstring(myname, zn, 0, NULL); - if (result != ISC_R_SUCCESS || - !dns_name_equal(zname, myname)) - continue; - - DE_CONST(elt, e); - ISC_LIST_UNLINK(*list, e, link); - cfg_obj_destroy(pctx, &e->obj); - isc_mem_put(pctx->mctx, e, sizeof(*e)); - result = ISC_R_SUCCESS; - break; - } - - /* - * Write config to NZF file if appropriate - */ - if (nzfwriter != NULL && view->new_zone_file != NULL) - result = nzfwriter(config, view); - - cleanup: - UNLOCK(&view->new_zone_lock); - return (result); -} - -static isc_result_t -do_addzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, - dns_name_t *name, cfg_obj_t *zoneconf, const cfg_obj_t *zoneobj, - isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *zone = NULL; -#ifndef HAVE_LMDB - FILE *fp = NULL; - bool cleanup_config = false; -#else /* HAVE_LMDB */ - MDB_txn *txn = NULL; - MDB_dbi dbi; - - UNUSED(zoneconf); - LOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - /* Zone shouldn't already exist */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result == ISC_R_SUCCESS) { - result = ISC_R_EXISTS; - goto cleanup; - } else if (result == DNS_R_PARTIALMATCH) { - /* Create our sub-zone anyway */ - dns_zone_detach(&zone); - zone = NULL; - } else if (result != ISC_R_NOTFOUND) - goto cleanup; - -#ifndef HAVE_LMDB - /* - * Make sure we can open the configuration save file - */ - result = isc_stdio_open(view->new_zone_file, "a", &fp); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to create '")); - TCHECK(putstr(text, view->new_zone_file)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - (void)isc_stdio_close(fp); - fp = NULL; -#else /* HAVE_LMDB */ - /* Make sure we can open the NZD database */ - result = nzd_writable(view); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open NZD database for '")); - TCHECK(putstr(text, view->new_zone_db)); - TCHECK(putstr(text, "'")); - result = ISC_R_FAILURE; - goto cleanup; - } -#endif /* HAVE_LMDB */ - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* Mark view unfrozen and configure zone */ - dns_view_thaw(view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - server->mctx, view, &server->viewlist, - cfg->actx, true, false, false); - dns_view_freeze(view); - - isc_task_endexclusive(server->task); - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "configure_zone failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - /* Is it there yet? */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "added new zone was not found: %s", - isc_result_totext(result)); - goto cleanup; - } - -#ifndef HAVE_LMDB - /* - * If there wasn't a previous newzone config, just save the one - * we've created. If there was a previous one, merge the new - * zone into it. - */ - if (cfg->nzf_config == NULL) { - cfg_obj_attach(zoneconf, &cfg->nzf_config); - } else { - cfg_obj_t *z; - DE_CONST(zoneobj, z); - CHECK(cfg_parser_mapadd(cfg->add_parser, - cfg->nzf_config, z, "zone")); - } - cleanup_config = true; -#endif /* HAVE_LMDB */ - - /* - * Load the zone from the master file. If this fails, we'll - * need to undo the configuration we've done already. - */ - result = dns_zone_loadnew(zone); - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - - TCHECK(putstr(text, "dns_zone_loadnew failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "addzone failed; reverting."); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(view->zonetable, zone); - goto cleanup; - } - - /* Flag the zone as having been added at runtime */ - dns_zone_setadded(zone, true); - -#ifdef HAVE_LMDB - /* Save the new zone configuration into the NZD */ - CHECK(nzd_open(view, 0, &txn, &dbi)); - CHECK(nzd_save(&txn, dbi, zone, zoneobj)); -#else - /* Append the zone configuration to the NZF */ - result = nzf_append(view, zoneobj); -#endif /* HAVE_LMDB */ - - cleanup: - -#ifndef HAVE_LMDB - if (fp != NULL) - (void)isc_stdio_close(fp); - if (result != ISC_R_SUCCESS && cleanup_config) { - tresult = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, name, - NULL); - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); - } -#else /* HAVE_LMDB */ - if (txn != NULL) - (void) nzd_close(&txn, false); - UNLOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -static isc_result_t -do_modzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, - dns_name_t *name, const char *zname, const cfg_obj_t *zoneobj, - isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *zone = NULL; - bool added; - bool exclusive = false; -#ifndef HAVE_LMDB - FILE *fp = NULL; - cfg_obj_t *z; -#else /* HAVE_LMDB */ - MDB_txn *txn = NULL; - MDB_dbi dbi; - LOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - /* Zone must already exist */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - added = dns_zone_getadded(zone); - dns_zone_detach(&zone); - -#ifndef HAVE_LMDB - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - TCHECK(putstr(text, "new zone config is not set")); - CHECK(ISC_R_FAILURE); - } -#endif - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - -#ifndef HAVE_LMDB - /* Make sure we can open the configuration save file */ - result = isc_stdio_open(view->new_zone_file, "a", &fp); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open '")); - TCHECK(putstr(text, view->new_zone_file)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - (void)isc_stdio_close(fp); - fp = NULL; -#else /* HAVE_LMDB */ - /* Make sure we can open the NZD database */ - result = nzd_writable(view); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open NZD database for '")); - TCHECK(putstr(text, view->new_zone_db)); - TCHECK(putstr(text, "'")); - result = ISC_R_FAILURE; - goto cleanup; - } -#endif /* HAVE_LMDB */ - - /* Reconfigure the zone */ - dns_view_thaw(view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - server->mctx, view, &server->viewlist, - cfg->actx, true, false, true); - dns_view_freeze(view); - - exclusive = false; - isc_task_endexclusive(server->task); - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "configure_zone failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - /* Is it there yet? */ - CHECK(dns_zt_find(view->zonetable, name, 0, NULL, &zone)); - -#ifndef HAVE_LMDB - /* Remove old zone from configuration (and NZF file if applicable) */ - if (added) { - result = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, - dns_zone_getorigin(zone), - nzf_writeconf); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "former zone configuration " - "not deleted: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - } -#endif /* HAVE_LMDB */ - - if (!added) { - if (cfg->vconfig == NULL) { - result = delete_zoneconf(view, cfg->conf_parser, - cfg->config, - dns_zone_getorigin(zone), - NULL); - } else { - const cfg_obj_t *voptions = - cfg_tuple_get(cfg->vconfig, "options"); - result = delete_zoneconf(view, cfg->conf_parser, - voptions, - dns_zone_getorigin(zone), - NULL); - } - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "former zone configuration " - "not deleted: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - } - - /* Load the zone from the master file if it needs reloading. */ - result = dns_zone_loadnew(zone); - - /* - * Dynamic zones need no reloading, so we can pass this result. - */ - if (result == DNS_R_DYNAMIC) - result = ISC_R_SUCCESS; - - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - - TCHECK(putstr(text, "failed to load zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - TCHECK(putstr(text, "\nThe zone is no longer being served. ")); - TCHECK(putstr(text, "Use 'rndc addzone' to correct\n")); - TCHECK(putstr(text, "the problem and restore service.")); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "modzone failed; removing zone."); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(view->zonetable, zone); - goto cleanup; - } - -#ifndef HAVE_LMDB - /* Store the new zone configuration; also in NZF if applicable */ - DE_CONST(zoneobj, z); - CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z, "zone")); -#endif /* HAVE_LMDB */ - - if (added) { -#ifdef HAVE_LMDB - CHECK(nzd_open(view, 0, &txn, &dbi)); - CHECK(nzd_save(&txn, dbi, zone, zoneobj)); -#else - result = nzf_append(view, zoneobj); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "\nNew zone config not saved: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } -#endif /* HAVE_LMDB */ - - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "' reconfigured.")); - - } else { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "' must also be reconfigured in\n")); - TCHECK(putstr(text, "named.conf to make changes permanent.")); - } - - cleanup: - if (exclusive) - isc_task_endexclusive(server->task); - -#ifndef HAVE_LMDB - if (fp != NULL) - (void)isc_stdio_close(fp); -#else /* HAVE_LMDB */ - if (txn != NULL) - (void) nzd_close(&txn, false); - UNLOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -/* - * Act on an "addzone" or "modzone" command from the command channel. - */ -isc_result_t -ns_server_changezone(ns_server_t *server, char *command, isc_buffer_t **text) { - isc_result_t result; - bool addzone; - ns_cfgctx_t *cfg = NULL; - cfg_obj_t *zoneconf = NULL; - const cfg_obj_t *zoneobj = NULL; - const char *zonename; - dns_view_t *view = NULL; - isc_buffer_t buf; - dns_fixedname_t fname; - dns_name_t *dnsname; - - if (strncasecmp(command, "add", 3) == 0) - addzone = true; - else { - INSIST(strncasecmp(command, "mod", 3) == 0); - addzone = false; - } - - CHECK(newzone_parse(server, command, &view, &zoneconf, - &zoneobj, text)); - - /* Are we accepting new zones in this view? */ -#ifdef HAVE_LMDB - if (view->new_zone_db == NULL) -#else - if (view->new_zone_file == NULL) -#endif /* HAVE_LMDB */ - { - (void) putstr(text, "Not allowing new zones in view '"); - (void) putstr(text, view->name); - (void) putstr(text, "'"); - result = ISC_R_NOPERM; - goto cleanup; - } - - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - zonename = cfg_obj_asstring(cfg_tuple_get(zoneobj, "name")); - isc_buffer_constinit(&buf, zonename, strlen(zonename)); - isc_buffer_add(&buf, strlen(zonename)); - - dnsname = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(dnsname, &buf, dns_rootname, 0, NULL)); - - if (addzone) - CHECK(do_addzone(server, cfg, view, dnsname, zoneconf, - zoneobj, text)); - else - CHECK(do_modzone(server, cfg, view, dnsname, zonename, - zoneobj, text)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone %s in view %s via %s", - addzone ? "added" : "updated", - zonename, view->name, - addzone ? NS_COMMAND_ADDZONE : NS_COMMAND_MODZONE); - - /* Changing a zone counts as reconfiguration */ - CHECK(isc_time_now(&ns_g_configtime)); - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (zoneconf != NULL) - cfg_obj_destroy(ns_g_addparser, &zoneconf); - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -static bool -inuse(const char* file, bool first, isc_buffer_t **text) { - if (file != NULL && isc_file_exists(file)) { - if (first) - (void) putstr(text, - "The following files were in use " - "and may now be removed:\n"); - else - (void) putstr(text, "\n"); - (void) putstr(text, file); - (void) putnull(text); - return (false); - } - return (first); -} - -typedef struct { - dns_zone_t *zone; - bool cleanup; -} ns_dzctx_t; - -/* - * Carry out a zone deletion scheduled by ns_server_delzone(). - */ -static void -rmzone(isc_task_t *task, isc_event_t *event) { - ns_dzctx_t *dz = (ns_dzctx_t *)event->ev_arg; - dns_zone_t *zone, *raw = NULL, *mayberaw; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - ns_cfgctx_t *cfg; - dns_db_t *dbp = NULL; - bool added; - isc_result_t result; -#ifdef HAVE_LMDB - MDB_txn *txn = NULL; - MDB_dbi dbi; -#endif - - REQUIRE(dz != NULL); - - isc_event_free(&event); - - /* Dig out configuration for this zone */ - zone = dz->zone; - view = dns_zone_getview(zone); - cfg = (ns_cfgctx_t *) view->new_zone_config; - dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "deleting zone %s in view %s via delzone", - zonename, view->name); - - /* Remove the zone from configuration (and NZF file if applicable) */ - added = dns_zone_getadded(zone); - - if (added && cfg != NULL) { -#ifdef HAVE_LMDB - /* Make sure we can open the NZD database */ - LOCK(&view->new_zone_lock); - result = nzd_open(view, 0, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "unable to open NZD database for '%s'", - view->new_zone_db); - } else { - result = nzd_save(&txn, dbi, zone, NULL); - } - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } - - if (txn != NULL) { - (void)nzd_close(&txn, false); - } - UNLOCK(&view->new_zone_lock); -#else - result = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, - dns_zone_getorigin(zone), - nzf_writeconf); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } -#endif /* HAVE_LMDB */ - } - - if (!added && cfg != NULL) { - if (cfg->vconfig != NULL) { - const cfg_obj_t *voptions = - cfg_tuple_get(cfg->vconfig, "options"); - result = delete_zoneconf(view, cfg->conf_parser, - voptions, - dns_zone_getorigin(zone), - NULL); - } else { - result = delete_zoneconf(view, cfg->conf_parser, - cfg->config, - dns_zone_getorigin(zone), - NULL); - } - if (result != ISC_R_SUCCESS){ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } - } - - /* Unload zone database */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Clean up stub/slave zone files if requested to do so */ - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - if (added && dz->cleanup) { - const char *file; - - file = dns_zone_getfile(mayberaw); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - file = dns_zone_getjournal(mayberaw); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - if (zone != mayberaw) { - file = dns_zone_getfile(zone); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - file = dns_zone_getjournal(zone); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - } - } - - if (raw != NULL) - dns_zone_detach(&raw); - dns_zone_detach(&zone); - isc_mem_put(ns_g_mctx, dz, sizeof(*dz)); - isc_task_detach(&task); -} - -/* - * Act on a "delzone" command from the command channel. - */ -isc_result_t -ns_server_delzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result, tresult; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - dns_zone_t *mayberaw; - dns_view_t *view = NULL; - char zonename[DNS_NAME_FORMATSIZE]; - bool cleanup = false; - const char *ptr; - bool added; - ns_dzctx_t *dz = NULL; - isc_event_t *dzevent = NULL; - isc_task_t *task = NULL; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcmp(ptr, "-clean") == 0 || strcmp(ptr, "-clear") == 0) { - cleanup = true; - ptr = next_token(lex, text); - } - - CHECK(zone_from_args(server, lex, ptr, &zone, zonename, - text, false)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - INSIST(zonename != NULL); - - /* Is this a policy zone? */ - if (dns_zone_get_rpz_num(zone) != DNS_RPZ_INVALID_NUM) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, - "' cannot be deleted: response-policy zone.")); - result = ISC_R_FAILURE; - goto cleanup; - } - - view = dns_zone_getview(zone); - CHECK(dns_zt_unmount(view->zonetable, zone)); - - /* Send cleanup event */ - dz = isc_mem_get(ns_g_mctx, sizeof(*dz)); - if (dz == NULL) - CHECK(ISC_R_NOMEMORY); - - dz->cleanup = cleanup; - dz->zone = NULL; - dns_zone_attach(zone, &dz->zone); - dzevent = isc_event_allocate(ns_g_mctx, server, NS_EVENT_DELZONE, - rmzone, dz, sizeof(isc_event_t)); - if (dzevent == NULL) - CHECK(ISC_R_NOMEMORY); - - dns_zone_gettask(zone, &task); - isc_task_send(task, &dzevent); - dz = NULL; - - /* Inform user about cleaning up stub/slave zone files */ - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - added = dns_zone_getadded(zone); - if (!added) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, - "' is no longer active and will be deleted.\n")); - TCHECK(putstr(text, "To keep it from returning ")); - TCHECK(putstr(text, "when the server is restarted, it\n")); - TCHECK(putstr(text, "must also be removed from named.conf.")); - } else if (cleanup) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, "' and associated files will be deleted.")); - } else if (dns_zone_gettype(mayberaw) == dns_zone_slave || - dns_zone_gettype(mayberaw) == dns_zone_stub) - { - bool first; - const char *file; - - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, "' will be deleted.")); - - file = dns_zone_getfile(mayberaw); - first = inuse(file, true, text); - - file = dns_zone_getjournal(mayberaw); - first = inuse(file, first, text); - - if (zone != mayberaw) { - file = dns_zone_getfile(zone); - first = inuse(file, first, text); - - file = dns_zone_getjournal(zone); - (void) inuse(file, first, text); - } - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "zone %s scheduled for removal via delzone", zonename); - - /* Removing a zone counts as reconfiguration */ - CHECK(isc_time_now(&ns_g_configtime)); - - result = ISC_R_SUCCESS; - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (raw != NULL) - dns_zone_detach(&raw); - if (zone != NULL) - dns_zone_detach(&zone); - if (dz != NULL) { - dns_zone_detach(&dz->zone); - isc_mem_put(ns_g_mctx, dz, sizeof(*dz)); - } - - return (result); -} - -static const cfg_obj_t * -find_name_in_list_from_map(const cfg_obj_t *config, - const char *map_key_for_list, - const char *name) -{ - const cfg_obj_t *list = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *obj = NULL; - dns_fixedname_t fixed1, fixed2; - dns_name_t *name1 = NULL, *name2 = NULL; - isc_result_t result; - - if (strcmp(map_key_for_list, "zone") == 0) { - name1 = dns_fixedname_initname(&fixed1); - name2 = dns_fixedname_initname(&fixed2); - result = dns_name_fromstring(name1, name, 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - cfg_map_get(config, map_key_for_list, &list); - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - const char *vname; - - obj = cfg_listelt_value(element); - INSIST(obj != NULL); - vname = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - if (vname == NULL) { - obj = NULL; - continue; - } - - if (name1 != NULL) { - result = dns_name_fromstring(name2, vname, 0, NULL); - if (result == ISC_R_SUCCESS && - dns_name_equal(name1, name2)) - break; - } else if (strcasecmp(vname, name) == 0) - break; - - obj = NULL; - } - - return (obj); -} - -static void -emitzone(void *arg, const char *buf, int len) { - ns_dzarg_t *dzarg = arg; - isc_result_t result; - - REQUIRE(dzarg != NULL && ISC_MAGIC_VALID(dzarg, DZARG_MAGIC)); - result = putmem(dzarg->text, buf, len); - if (result != ISC_R_SUCCESS && dzarg->result == ISC_R_SUCCESS) { - dzarg->result = result; - } -} - -/* - * Act on a "showzone" command from the command channel. - */ -isc_result_t -ns_server_showzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - const cfg_obj_t *vconfig = NULL, *zconfig = NULL; - char zonename[DNS_NAME_FORMATSIZE]; - const cfg_obj_t *map; - dns_view_t *view = NULL; - dns_zone_t *zone = NULL; - ns_cfgctx_t *cfg = NULL; - bool exclusive = false; -#ifdef HAVE_LMDB - cfg_obj_t *nzconfig = NULL; -#endif /* HAVE_LMDB */ - ns_dzarg_t dzarg; - - /* Parse parameters */ - CHECK(zone_from_args(server, lex, NULL, &zone, zonename, - text, true)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - view = dns_zone_getview(zone); - dns_zone_detach(&zone); - - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - - /* Find the view statement */ - vconfig = find_name_in_list_from_map(cfg->config, "view", view->name); - - /* Find the zone statement */ - if (vconfig != NULL) - map = cfg_tuple_get(vconfig, "options"); - else - map = cfg->config; - - zconfig = find_name_in_list_from_map(map, "zone", zonename); - -#ifndef HAVE_LMDB - if (zconfig == NULL && cfg->nzf_config != NULL) - zconfig = find_name_in_list_from_map(cfg->nzf_config, - "zone", zonename); -#else /* HAVE_LMDB */ - if (zconfig == NULL) { - const cfg_obj_t *zlist = NULL; - CHECK(get_newzone_config(view, zonename, &nzconfig)); - CHECK(cfg_map_get(nzconfig, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - zconfig = cfg_listelt_value(cfg_list_first(zlist)); - } -#endif /* HAVE_LMDB */ - - if (zconfig == NULL) - CHECK(ISC_R_NOTFOUND); - - CHECK(putstr(text, "zone ")); - dzarg.magic = DZARG_MAGIC; - dzarg.text = text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zconfig, CFG_PRINTER_ONELINE, emitzone, &dzarg); - CHECK(dzarg.result); - - CHECK(putstr(text, ";")); - - result = ISC_R_SUCCESS; - - cleanup: -#ifdef HAVE_LMDB - if (nzconfig != NULL) - cfg_obj_destroy(ns_g_addparser, &nzconfig); -#endif /* HAVE_LMDB */ - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (exclusive) - isc_task_endexclusive(server->task); - - return (result); -} - -static void -newzone_cfgctx_destroy(void **cfgp) { - ns_cfgctx_t *cfg; - - REQUIRE(cfgp != NULL && *cfgp != NULL); - - cfg = *cfgp; - - if (cfg->conf_parser != NULL) { - if (cfg->config != NULL) - cfg_obj_destroy(cfg->conf_parser, &cfg->config); - if (cfg->vconfig != NULL) - cfg_obj_destroy(cfg->conf_parser, &cfg->vconfig); - cfg_parser_destroy(&cfg->conf_parser); - } - if (cfg->add_parser != NULL) { - if (cfg->nzf_config != NULL) - cfg_obj_destroy(cfg->add_parser, &cfg->nzf_config); - cfg_parser_destroy(&cfg->add_parser); - } - - if (cfg->actx != NULL) - cfg_aclconfctx_detach(&cfg->actx); - - isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg)); - *cfgp = NULL; -} - -static isc_result_t -generate_salt(unsigned char *salt, size_t saltlen) { - size_t i, n; - union { - unsigned char rnd[256]; - uint16_t rnd16[128]; - } rnd; - unsigned char text[512 + 1]; - isc_region_t r; - isc_buffer_t buf; - isc_result_t result; - - if (saltlen > 256U) - return (ISC_R_RANGE); - - n = (saltlen + sizeof(uint16_t) - 1) / sizeof(uint16_t); - for (i = 0; i < n; i++) { - rnd.rnd16[i] = isc_rng_random(ns_g_server->rngctx); - } - - memmove(salt, rnd.rnd, saltlen); - - r.base = rnd.rnd; - r.length = (unsigned int) saltlen; - - isc_buffer_init(&buf, text, sizeof(text)); - result = isc_hex_totext(&r, 2, "", &buf); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - text[saltlen * 2] = 0; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "generated salt: %s", text); - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_signing(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result = ISC_R_SUCCESS; - dns_zone_t *zone = NULL; - dns_name_t *origin; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_dbversion_t *version = NULL; - dns_rdatatype_t privatetype; - dns_rdataset_t privset; - bool first = true; - bool list = false, clear = false; - bool chain = false; - bool setserial = false; - uint32_t serial = 0; - char keystr[DNS_SECALG_FORMATSIZE + 7]; /* <5-digit keyid>/ */ - unsigned short hash = 0, flags = 0, iter = 0, saltlen = 0; - unsigned char salt[255]; - const char *ptr; - size_t n; - - dns_rdataset_init(&privset); - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "-list") == 0) - list = true; - else if ((strcasecmp(ptr, "-clear") == 0) || - (strcasecmp(ptr, "-clean") == 0)) - { - clear = true; - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(keystr, ptr, sizeof(keystr)); - } else if (strcasecmp(ptr, "-nsec3param") == 0) { - char hashbuf[64], flagbuf[64], iterbuf[64]; - char nbuf[256]; - - chain = true; - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "none") == 0) - hash = 0; - else { - strlcpy(hashbuf, ptr, sizeof(hashbuf)); - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(flagbuf, ptr, sizeof(flagbuf)); - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(iterbuf, ptr, sizeof(iterbuf)); - - n = snprintf(nbuf, sizeof(nbuf), "%s %s %s", - hashbuf, flagbuf, iterbuf); - if (n == sizeof(nbuf)) - return (ISC_R_NOSPACE); - n = sscanf(nbuf, "%hu %hu %hu", &hash, &flags, &iter); - if (n != 3U) - return (ISC_R_BADNUMBER); - - if (hash > 0xffU || flags > 0xffU) - return (ISC_R_RANGE); - - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } else if (strcasecmp(ptr, "auto") == 0) { - /* Auto-generate a random salt. - * XXXMUKS: This currently uses the - * minimum recommended length by RFC - * 5155 (64 bits). It should be made - * configurable. - */ - saltlen = 8; - CHECK(generate_salt(salt, saltlen)); - } else if (strcmp(ptr, "-") != 0) { - isc_buffer_t buf; - - isc_buffer_init(&buf, salt, sizeof(salt)); - CHECK(isc_hex_decodestring(ptr, &buf)); - saltlen = isc_buffer_usedlength(&buf); - } - } - } else if (strcasecmp(ptr, "-serial") == 0) { - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - CHECK(isc_parse_uint32(&serial, ptr, 10)); - setserial = true; - } else - CHECK(DNS_R_SYNTAX); - - CHECK(zone_from_args(server, lex, NULL, &zone, NULL, - text, false)); - if (zone == NULL) - CHECK(ISC_R_UNEXPECTEDEND); - - if (clear) { - CHECK(dns_zone_keydone(zone, keystr)); - (void) putstr(text, "request queued"); - (void) putnull(text); - } else if (chain) { - CHECK(dns_zone_setnsec3param(zone, (uint8_t)hash, - (uint8_t)flags, iter, - (uint8_t)saltlen, salt, - true)); - (void) putstr(text, "nsec3param request queued"); - (void) putnull(text); - } else if (setserial) { - CHECK(dns_zone_setserial(zone, serial)); - (void) putstr(text, "serial request queued"); - (void) putnull(text); - } else if (list) { - privatetype = dns_zone_getprivatetype(zone); - origin = dns_zone_getorigin(zone); - CHECK(dns_zone_getdb(zone, &db)); - CHECK(dns_db_findnode(db, origin, false, &node)); - dns_db_currentversion(db, &version); - - result = dns_db_findrdataset(db, node, version, privatetype, - dns_rdatatype_none, 0, - &privset, NULL); - if (result == ISC_R_NOTFOUND) { - (void) putstr(text, "No signing records found"); - (void) putnull(text); - result = ISC_R_SUCCESS; - goto cleanup; - } - - for (result = dns_rdataset_first(&privset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&privset)) - { - dns_rdata_t priv = DNS_RDATA_INIT; - char output[BUFSIZ]; - isc_buffer_t buf; - - dns_rdataset_current(&privset, &priv); - - isc_buffer_init(&buf, output, sizeof(output)); - CHECK(dns_private_totext(&priv, &buf)); - if (!first) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, output)); - first = false; - } - if (!first) - CHECK(putnull(text)); - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - } - - cleanup: - if (dns_rdataset_isassociated(&privset)) - dns_rdataset_disassociate(&privset); - if (node != NULL) - dns_db_detachnode(db, &node); - if (version != NULL) - dns_db_closeversion(db, &version, false); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -static isc_result_t -putmem(isc_buffer_t **b, const char *str, size_t len) { - isc_result_t result; - - result = isc_buffer_reserve(b, (unsigned int)len); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOSPACE); - - isc_buffer_putmem(*b, (const unsigned char *)str, (unsigned int)len); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -putstr(isc_buffer_t **b, const char *str) { - return (putmem(b, str, strlen(str))); -} - -static isc_result_t -putuint8(isc_buffer_t **b, uint8_t val) { - isc_result_t result; - - result = isc_buffer_reserve(b, 1); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOSPACE); - - isc_buffer_putuint8(*b, val); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -putnull(isc_buffer_t **b) { - return (putuint8(b, 0)); -} - -isc_result_t -ns_server_zonestatus(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_zone_t *zone = NULL, *raw = NULL, *mayberaw = NULL; - const char *type, *file; - char zonename[DNS_NAME_FORMATSIZE]; - uint32_t serial, signed_serial, nodes; - char serbuf[16], sserbuf[16], nodebuf[16]; - char resignbuf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 2]; - char lbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char xbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char kbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char rtbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_t loadtime, expiretime, refreshtime; - isc_time_t refreshkeytime, resigntime; - dns_zonetype_t zonetype; - bool dynamic = false, frozen = false; - bool hasraw = false; - bool secure, maintain, allow; - dns_db_t *db = NULL, *rawdb = NULL; - char **incfiles = NULL; - int nfiles = 0; - - isc_time_settoepoch(&loadtime); - isc_time_settoepoch(&refreshtime); - isc_time_settoepoch(&expiretime); - isc_time_settoepoch(&refreshkeytime); - isc_time_settoepoch(&resigntime); - - CHECK(zone_from_args(server, lex, NULL, &zone, zonename, - text, true)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - /* Inline signing? */ - CHECK(dns_zone_getdb(zone, &db)); - dns_zone_getraw(zone, &raw); - hasraw = (raw != NULL); - if (hasraw) { - mayberaw = raw; - zonetype = dns_zone_gettype(raw); - CHECK(dns_zone_getdb(raw, &rawdb)); - } else { - mayberaw = zone; - zonetype = dns_zone_gettype(zone); - } - - switch (zonetype) { - case dns_zone_master: - type = "master"; - break; - case dns_zone_slave: - type = "slave"; - break; - case dns_zone_stub: - type = "stub"; - break; - case dns_zone_staticstub: - type = "staticstub"; - break; - case dns_zone_redirect: - type = "redirect"; - break; - case dns_zone_key: - type = "key"; - break; - case dns_zone_dlz: - type = "dlz"; - break; - default: - type = "unknown"; - } - - /* Serial number */ - serial = dns_zone_getserial(mayberaw); - snprintf(serbuf, sizeof(serbuf), "%u", serial); - if (hasraw) { - signed_serial = dns_zone_getserial(zone); - snprintf(sserbuf, sizeof(sserbuf), "%u", signed_serial); - } - - /* Database node count */ - nodes = dns_db_nodecount(hasraw ? rawdb : db); - snprintf(nodebuf, sizeof(nodebuf), "%u", nodes); - - /* Security */ - secure = dns_db_issecure(db); - allow = ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_ALLOW) != 0); - maintain = ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0); - - /* Master files */ - file = dns_zone_getfile(mayberaw); - nfiles = dns_zone_getincludes(mayberaw, &incfiles); - - /* Load time */ - dns_zone_getloadtime(zone, &loadtime); - isc_time_formathttptimestamp(&loadtime, lbuf, sizeof(lbuf)); - - /* Refresh/expire times */ - if (zonetype == dns_zone_slave || - zonetype == dns_zone_stub || - zonetype == dns_zone_redirect) - { - dns_zone_getexpiretime(mayberaw, &expiretime); - isc_time_formathttptimestamp(&expiretime, xbuf, sizeof(xbuf)); - dns_zone_getrefreshtime(mayberaw, &refreshtime); - isc_time_formathttptimestamp(&refreshtime, rbuf, sizeof(rbuf)); - } - - /* Key refresh time */ - if (zonetype == dns_zone_master || - (zonetype == dns_zone_slave && hasraw)) - { - dns_zone_getrefreshkeytime(zone, &refreshkeytime); - isc_time_formathttptimestamp(&refreshkeytime, kbuf, - sizeof(kbuf)); - } - - /* Dynamic? */ - if (zonetype == dns_zone_master) { - dynamic = dns_zone_isdynamic(mayberaw, true); - frozen = dynamic && !dns_zone_isdynamic(mayberaw, false); - } - - /* Next resign event */ - if (secure && (zonetype == dns_zone_master || - (zonetype == dns_zone_slave && hasraw)) && - ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_NORESIGN) == 0)) - { - dns_name_t *name; - dns_fixedname_t fixed; - dns_rdataset_t next; - - dns_rdataset_init(&next); - name = dns_fixedname_initname(&fixed); - - result = dns_db_getsigningtime(db, &next, name); - if (result == ISC_R_SUCCESS) { - isc_stdtime_t timenow; - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - isc_stdtime_get(&timenow); - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(next.covers, - typebuf, sizeof(typebuf)); - snprintf(resignbuf, sizeof(resignbuf), - "%s/%s", namebuf, typebuf); - isc_time_set(&resigntime, next.resign - - dns_zone_getsigresigninginterval(zone), 0); - isc_time_formathttptimestamp(&resigntime, rtbuf, - sizeof(rtbuf)); - dns_rdataset_disassociate(&next); - } - } - - /* Create text */ - CHECK(putstr(text, "name: ")); - CHECK(putstr(text, zonename)); - - CHECK(putstr(text, "\ntype: ")); - CHECK(putstr(text, type)); - - if (file != NULL) { - int i; - CHECK(putstr(text, "\nfiles: ")); - CHECK(putstr(text, file)); - for (i = 0; i < nfiles; i++) { - CHECK(putstr(text, ", ")); - if (incfiles[i] != NULL) { - CHECK(putstr(text, incfiles[i])); - } - } - } - - CHECK(putstr(text, "\nserial: ")); - CHECK(putstr(text, serbuf)); - if (hasraw) { - CHECK(putstr(text, "\nsigned serial: ")); - CHECK(putstr(text, sserbuf)); - } - - CHECK(putstr(text, "\nnodes: ")); - CHECK(putstr(text, nodebuf)); - - if (! isc_time_isepoch(&loadtime)) { - CHECK(putstr(text, "\nlast loaded: ")); - CHECK(putstr(text, lbuf)); - } - - if (! isc_time_isepoch(&refreshtime)) { - CHECK(putstr(text, "\nnext refresh: ")); - CHECK(putstr(text, rbuf)); - } - - if (! isc_time_isepoch(&expiretime)) { - CHECK(putstr(text, "\nexpires: ")); - CHECK(putstr(text, xbuf)); - } - - if (secure) { - CHECK(putstr(text, "\nsecure: yes")); - if (hasraw) { - CHECK(putstr(text, "\ninline signing: yes")); - } else { - CHECK(putstr(text, "\ninline signing: no")); - } - } else { - CHECK(putstr(text, "\nsecure: no")); - } - - if (maintain) { - CHECK(putstr(text, "\nkey maintenance: automatic")); - if (! isc_time_isepoch(&refreshkeytime)) { - CHECK(putstr(text, "\nnext key event: ")); - CHECK(putstr(text, kbuf)); - } - } else if (allow) { - CHECK(putstr(text, "\nkey maintenance: on command")); - } else if (secure || hasraw) { - CHECK(putstr(text, "\nkey maintenance: none")); - } - - if (!isc_time_isepoch(&resigntime)) { - CHECK(putstr(text, "\nnext resign node: ")); - CHECK(putstr(text, resignbuf)); - CHECK(putstr(text, "\nnext resign time: ")); - CHECK(putstr(text, rtbuf)); - } - - if (dynamic) { - CHECK(putstr(text, "\ndynamic: yes")); - if (frozen) { - CHECK(putstr(text, "\nfrozen: yes")); - } else { - CHECK(putstr(text, "\nfrozen: no")); - } - } else { - CHECK(putstr(text, "\ndynamic: no")); - } - - CHECK(putstr(text, "\nreconfigurable via modzone: ")); - CHECK(putstr(text, dns_zone_getadded(zone) ? "yes" : "no")); - - cleanup: - /* Indicate truncated output if possible. */ - if (result == ISC_R_NOSPACE) { - (void) putstr(text, "\n..."); - } - if ((result == ISC_R_SUCCESS || result == ISC_R_NOSPACE)) { - (void) putnull(text); - } - - if (db != NULL) { - dns_db_detach(&db); - } - if (rawdb != NULL) { - dns_db_detach(&rawdb); - } - if (incfiles != NULL && mayberaw != NULL) { - int i; - isc_mem_t *mctx = dns_zone_getmctx(mayberaw); - - for (i = 0; i < nfiles; i++) { - if (incfiles[i] != NULL) { - isc_mem_free(mctx, incfiles[i]); - } - } - isc_mem_free(mctx, incfiles); - } - if (raw != NULL) { - dns_zone_detach(&raw); - } - if (zone != NULL) { - dns_zone_detach(&zone); - } - return (result); -} - -static inline bool -argcheck(char *cmd, const char *full) { - size_t l; - - if (cmd == NULL || cmd[0] != '-') - return (false); - - cmd++; - l = strlen(cmd); - if (l > strlen(full) || strncasecmp(cmd, full, l) != 0) - return (false); - - return (true); -} - -isc_result_t -ns_server_nta(ns_server_t *server, isc_lex_t *lex, bool readonly, - isc_buffer_t **text) -{ - dns_view_t *view; - dns_ntatable_t *ntatable = NULL; - isc_result_t result = ISC_R_SUCCESS; - char *ptr, *nametext = NULL, *viewname; - char namebuf[DNS_NAME_FORMATSIZE]; - isc_stdtime_t now, when; - isc_time_t t; - char tbuf[64]; - const char *msg = NULL; - bool dump = false, force = false; - dns_fixedname_t fn; - dns_name_t *ntaname; - dns_ttl_t ntattl; - bool ttlset = false, excl = false; - dns_rdataclass_t rdclass = dns_rdataclass_in; - - UNUSED(force); - - ntaname = dns_fixedname_initname(&fn); - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - for (;;) { - /* Check for options */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - if (argcheck(ptr, "dump")) { - dump = true; - } else if (argcheck(ptr, "remove")) { - ntattl = 0; - ttlset = true; - } else if (argcheck(ptr, "force")) { - force = true; - continue; - } else if (argcheck(ptr, "lifetime")) { - isc_textregion_t tr; - - ptr = next_token(lex, text); - if (ptr == NULL) { - msg = "No lifetime specified"; - CHECK(ISC_R_UNEXPECTEDEND); - } - - tr.base = ptr; - tr.length = strlen(ptr); - result = dns_ttl_fromtext(&tr, &ntattl); - if (result != ISC_R_SUCCESS) { - msg = "could not parse NTA lifetime"; - CHECK(result); - } - - if (ntattl > 604800) { - msg = "NTA lifetime cannot exceed one week"; - CHECK(ISC_R_RANGE); - } - - ttlset = true; - continue; - } else if (argcheck(ptr, "class")) { - isc_textregion_t tr; - - ptr = next_token(lex, text); - if (ptr == NULL) { - msg = "No class specified"; - CHECK(ISC_R_UNEXPECTEDEND); - } - - tr.base = ptr; - tr.length = strlen(ptr); - CHECK(dns_rdataclass_fromtext(&rdclass, &tr)); - continue; - } else { - nametext = ptr; - } - - break; - } - - /* - * If -dump was specified, list NTA's and return - */ - if (dump) { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - continue; - } - CHECK(dns_ntatable_totext(ntatable, text)); - } - CHECK(putnull(text)); - - goto cleanup; - } - - if (readonly) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_INFO, - "rejecting restricted control channel " - "NTA command"); - CHECK(ISC_R_FAILURE); - } - - /* Get the NTA name. */ - if (nametext == NULL) { - nametext = next_token(lex, text); - } - if (nametext == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* Copy nametext as it'll be overwritten by next_token() */ - strlcpy(namebuf, nametext, DNS_NAME_FORMATSIZE); - - if (strcmp(namebuf, ".") == 0) { - ntaname = dns_rootname; - } else { - isc_buffer_t b; - isc_buffer_init(&b, namebuf, strlen(namebuf)); - isc_buffer_add(&b, strlen(namebuf)); - CHECK(dns_name_fromtext(ntaname, &b, dns_rootname, 0, NULL)); - } - - /* Look for the view name. */ - viewname = next_token(lex, text); - - isc_stdtime_get(&now); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - excl = true; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - static bool first = true; - - if (viewname != NULL && strcmp(view->name, viewname) != 0) { - continue; - } - - if (view->rdclass != rdclass && rdclass != dns_rdataclass_any) { - continue; - } - - if (view->nta_lifetime == 0) { - continue; - } - - if (!ttlset) { - ntattl = view->nta_lifetime; - } - - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - - result = dns_view_flushnode(view, ntaname, true); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flush tree '%s' in cache view '%s': %s", - namebuf, view->name, - isc_result_totext(result)); - - if (ntattl != 0) { - CHECK(dns_ntatable_add(ntatable, ntaname, - force, now, ntattl)); - - when = now + ntattl; - isc_time_set(&t, when, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); - - if (!first) { - CHECK(putstr(text, "\n")); - } - first = false; - - CHECK(putstr(text, "Negative trust anchor added: ")); - CHECK(putstr(text, namebuf)); - CHECK(putstr(text, "/")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ", expires ")); - CHECK(putstr(text, tbuf)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "added NTA '%s' (%d sec) in view '%s'", - namebuf, ntattl, view->name); - } else { - CHECK(dns_ntatable_delete(ntatable, ntaname)); - - if (!first) { - CHECK(putstr(text, "\n")); - } - first = false; - - CHECK(putstr(text, "Negative trust anchor removed: ")); - CHECK(putstr(text, namebuf)); - CHECK(putstr(text, "/")); - CHECK(putstr(text, view->name)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "removed NTA '%s' in view %s", - namebuf, view->name); - } - - result = dns_view_saventa(view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error writing NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - (void) putnull(text); - - cleanup: - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - if (excl) { - isc_task_endexclusive(server->task); - } - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - return (result); -} - -isc_result_t -ns_server_saventa(ns_server_t *server) { - dns_view_t *view; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - isc_result_t result = dns_view_saventa(view); - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error writing NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_loadnta(ns_server_t *server) { - dns_view_t *view; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - isc_result_t result = dns_view_loadnta(view); - - if ((result != ISC_R_SUCCESS) && - (result != ISC_R_FILENOTFOUND) && - (result != ISC_R_NOTFOUND)) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error loading NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -mkey_refresh(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - char msg[DNS_NAME_FORMATSIZE + 500] = ""; - - snprintf(msg, sizeof(msg), - "refreshing managed keys for '%s'", view->name); - CHECK(putstr(text, msg)); - CHECK(dns_zone_synckeyzone(view->managed_keys)); - - cleanup: - return (result); -} - -static isc_result_t -mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rriterator_t rrit; - isc_stdtime_t now; - dns_name_t *prevname = NULL; - - isc_stdtime_get(&now); - - CHECK(dns_zone_getdb(view->managed_keys, &db)); - dns_db_currentversion(db, &ver); - dns_rriterator_init(&rrit, db, ver, 0); - for (result = dns_rriterator_first(&rrit); - result == ISC_R_SUCCESS; - result = dns_rriterator_nextrrset(&rrit)) - { - char buf[DNS_NAME_FORMATSIZE + 500]; - dns_name_t *name = NULL; - dns_rdataset_t *kdset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_keydata_t kd; - uint32_t ttl; - - dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); - if (kdset == NULL || kdset->type != dns_rdatatype_keydata || - !dns_rdataset_isassociated(kdset)) - continue; - - if (name != prevname) { - char nbuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, nbuf, sizeof(nbuf)); - snprintf(buf, sizeof(buf), "\n\n name: %s", nbuf); - CHECK(putstr(text, buf)); - } - - - for (result = dns_rdataset_first(kdset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(kdset)) - { - char alg[DNS_SECALG_FORMATSIZE]; - char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - dns_keytag_t keyid; - isc_region_t r; - isc_time_t t; - bool revoked; - - dns_rdata_reset(&rdata); - dns_rdataset_current(kdset, &rdata); - result = dns_rdata_tostruct(&rdata, &kd, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_rdata_toregion(&rdata, &r); - isc_region_consume(&r, 12); - keyid = dst_region_computeid(&r, kd.algorithm); - - snprintf(buf, sizeof(buf), "\n keyid: %u", keyid); - CHECK(putstr(text, buf)); - - dns_secalg_format(kd.algorithm, alg, sizeof(alg)); - snprintf(buf, sizeof(buf), "\n\talgorithm: %s", alg); - CHECK(putstr(text, buf)); - - revoked = ((kd.flags & DNS_KEYFLAG_REVOKE) != 0); - snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s", - revoked ? " REVOKE" : "", - ((kd.flags & DNS_KEYFLAG_KSK) != 0) - ? " SEP" : "", - (kd.flags == 0) ? " (none)" : ""); - CHECK(putstr(text, buf)); - - isc_time_set(&t, kd.refresh, 0); - isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf)); - snprintf(buf, sizeof(buf), - "\n\tnext refresh: %s", tbuf); - CHECK(putstr(text, buf)); - - if (kd.removehd != 0) { - isc_time_set(&t, kd.removehd, 0); - isc_time_formathttptimestamp(&t, tbuf, - sizeof(tbuf)); - snprintf(buf, sizeof(buf), - "\n\tremove at: %s", tbuf); - CHECK(putstr(text, buf)); - } - - isc_time_set(&t, kd.addhd, 0); - isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf)); - if (kd.addhd == 0) - snprintf(buf, sizeof(buf), "\n\tno trust"); - else if (revoked) - snprintf(buf, sizeof(buf), - "\n\ttrust revoked"); - else if (kd.addhd <= now) - snprintf(buf, sizeof(buf), - "\n\ttrusted since: %s", tbuf); - else if (kd.addhd > now) - snprintf(buf, sizeof(buf), - "\n\ttrust pending: %s", tbuf); - CHECK(putstr(text, buf)); - } - } - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup: - if (ver != NULL) { - dns_rriterator_destroy(&rrit); - dns_db_closeversion(db, &ver, false); - } - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static isc_result_t -mkey_status(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - char msg[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_t t; - - CHECK(putstr(text, "view: ")); - CHECK(putstr(text, view->name)); - - CHECK(putstr(text, "\nnext scheduled event: ")); - - dns_zone_getrefreshkeytime(view->managed_keys, &t); - if (isc_time_isepoch(&t)) { - CHECK(putstr(text, "never")); - } else { - isc_time_formathttptimestamp(&t, msg, sizeof(msg)); - CHECK(putstr(text, msg)); - } - - CHECK(mkey_dumpzone(view, text)); - - cleanup: - return (result); -} - -isc_result_t -ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - char *cmd, *classtxt, *viewtxt = NULL; - isc_result_t result = ISC_R_SUCCESS; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - char msg[DNS_NAME_FORMATSIZE + 500] = ""; - enum { NONE, STATUS, REFRESH, SYNC } opt = NONE; - bool found = false; - bool first = true; - - /* Skip rndc command name */ - cmd = next_token(lex, text); - if (cmd == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* Get managed-keys subcommand */ - cmd = next_token(lex, text); - if (cmd == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - if (strcasecmp(cmd, "status") == 0) { - opt = STATUS; - } else if (strcasecmp(cmd, "refresh") == 0) { - opt = REFRESH; - } else if (strcasecmp(cmd, "sync") == 0) { - opt = SYNC; - } else { - snprintf(msg, sizeof(msg), "unknown command '%s'", cmd); - (void) putstr(text, msg); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - snprintf(msg, sizeof(msg), - "unknown class '%s'", classtxt); - (void) putstr(text, msg); - goto cleanup; - } - viewtxt = next_token(lex, text); - } - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewtxt != NULL && - (rdclass != view->rdclass || - strcmp(view->name, viewtxt) != 0)) - { - continue; - } - - if (view->managed_keys == NULL) { - if (viewtxt != NULL) { - snprintf(msg, sizeof(msg), - "view '%s': no managed keys", viewtxt); - CHECK(putstr(text, msg)); - goto cleanup; - } else { - continue; - } - } - - found = true; - - switch (opt) { - case REFRESH: - if (!first) { - CHECK(putstr(text, "\n")); - } - CHECK(mkey_refresh(view, text)); - break; - case STATUS: - if (!first) { - CHECK(putstr(text, "\n\n")); - } - CHECK(mkey_status(view, text)); - break; - case SYNC: - CHECK(dns_zone_flush(view->managed_keys)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (viewtxt != NULL) { - break; - } - - first = false; - } - - if (!found) { - CHECK(putstr(text, "no views with managed keys")); - } - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - - return (result); -} - -isc_result_t -ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { -#ifdef HAVE_DNSTAP - char *ptr; - isc_result_t result; - bool reopen = false; - int backups = 0; - - if (server->dtenv == NULL) - return (ISC_R_NOTFOUND); - - /* Check the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* "dnstap-reopen" was used in 9.11.0b1 */ - if (strcasecmp(ptr, "dnstap-reopen") == 0) { - reopen = true; - } else { - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - } - - if (reopen || strcasecmp(ptr, "-reopen") == 0) { - backups = -1; - } else if ((strcasecmp(ptr, "-roll") == 0)) { - unsigned int n; - ptr = next_token(lex, text); - if (ptr != NULL) { - unsigned int u; - n = sscanf(ptr, "%u", &u); - if (n != 1U || u > INT_MAX) - return (ISC_R_BADNUMBER); - backups = u; - } - } else - return (DNS_R_SYNTAX); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = dns_dt_reopen(server->dtenv, backups); - isc_task_endexclusive(server->task); - return (result); -#else - UNUSED(server); - UNUSED(lex); - UNUSED(text); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - char *ptr, *classtxt, *viewtxt = NULL; - char msg[128]; - dns_rdataclass_t rdclass = dns_rdataclass_in; - dns_view_t *view; - bool found = false; - dns_stale_answer_t staleanswersok = dns_stale_answer_conf; - bool wantstatus = false; - isc_result_t result = ISC_R_SUCCESS; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "on") == 0 || strcasecmp(ptr, "yes") == 0) { - staleanswersok = dns_stale_answer_yes; - } else if (strcasecmp(ptr, "off") == 0 || strcasecmp(ptr, "no") == 0) { - staleanswersok = dns_stale_answer_no; - } else if (strcasecmp(ptr, "reset") == 0) { - staleanswersok = dns_stale_answer_conf; - } else if (strcasecmp(ptr, "status") == 0) { - wantstatus = true; - } else - return (DNS_R_SYNTAX); - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - /* Look for the optional view name. */ - viewtxt = next_token(lex, text); - } - - if (classtxt != NULL) { - isc_textregion_t r; - - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - if (viewtxt == NULL) { - viewtxt = classtxt; - classtxt = NULL; - result = ISC_R_SUCCESS; - } else { - snprintf(msg, sizeof(msg), - "unknown class '%s'", classtxt); - (void) putstr(text, msg); - goto cleanup; - } - } - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_ttl_t stale_ttl = 0; - dns_db_t *db = NULL; - - if (classtxt != NULL && rdclass != view->rdclass) - continue; - - if (viewtxt != NULL && strcmp(view->name, viewtxt) != 0) - continue; - - if (!wantstatus) { - view->staleanswersok = staleanswersok; - found = true; - continue; - } - - db = NULL; - dns_db_attach(view->cachedb, &db); - (void)dns_db_getservestalettl(db, &stale_ttl); - dns_db_detach(&db); - if (found) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ": ")); - switch (view->staleanswersok) { - case dns_stale_answer_yes: - if (stale_ttl > 0) - CHECK(putstr(text, "on (rndc)")); - else - CHECK(putstr(text, "off (not-cached)")); - break; - case dns_stale_answer_no: - CHECK(putstr(text, "off (rndc)")); - break; - case dns_stale_answer_conf: - if (view->staleanswersenable && stale_ttl > 0) - CHECK(putstr(text, "on")); - else if (view->staleanswersenable) - CHECK(putstr(text, "off (not-cached)")); - else - CHECK(putstr(text, "off")); - break; - } - if (stale_ttl > 0) { - snprintf(msg, sizeof(msg), - " (stale-answer-ttl=%u max-stale-ttl=%u)", - view->staleanswerttl, stale_ttl); - CHECK(putstr(text, msg)); - } - found = true; - } - isc_task_endexclusive(ns_g_server->task); - - if (!found) - result = ISC_R_NOTFOUND; - -cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - - return (result); -} diff --git a/bin/named-pkcs11/sortlist.c b/bin/named-pkcs11/sortlist.c deleted file mode 100644 index b36b0a0..0000000 --- a/bin/named-pkcs11/sortlist.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp) -{ - unsigned int i; - - if (acl == NULL) - goto dont_sort; - - for (i = 0; i < acl->length; i++) { - /* - * 'e' refers to the current 'top level statement' - * in the sortlist (see ARM). - */ - dns_aclelement_t *e = &acl->elements[i]; - dns_aclelement_t *try_elt; - dns_aclelement_t *order_elt = NULL; - const dns_aclelement_t *matched_elt = NULL; - - if (e->type == dns_aclelementtype_nestedacl) { - dns_acl_t *inner = e->nestedacl; - - if (inner->length == 0) - try_elt = e; - else if (inner->length > 2) - goto dont_sort; - else if (inner->elements[0].negative) - goto dont_sort; - else { - try_elt = &inner->elements[0]; - if (inner->length == 2) - order_elt = &inner->elements[1]; - } - } else { - /* - * BIND 8 allows bare elements at the top level - * as an undocumented feature. - */ - try_elt = e; - } - - if (dns_aclelement_match(clientaddr, NULL, try_elt, - &ns_g_server->aclenv, - &matched_elt)) { - if (order_elt != NULL) { - if (order_elt->type == - dns_aclelementtype_nestedacl) { - *argp = order_elt->nestedacl; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localhost && - ns_g_server->aclenv.localhost != NULL) { - *argp = ns_g_server->aclenv.localhost; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localnets && - ns_g_server->aclenv.localnets != NULL) { - *argp = ns_g_server->aclenv.localnets; - return (NS_SORTLISTTYPE_2ELEMENT); - } else { - /* - * BIND 8 allows a bare IP prefix as - * the 2nd element of a 2-element - * sortlist statement. - */ - *argp = order_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } else { - INSIST(matched_elt != NULL); - *argp = matched_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } - } - - /* No match; don't sort. */ - dont_sort: - *argp = NULL; - return (NS_SORTLISTTYPE_NONE); -} - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) { - const dns_acl_t *sortacl = (const dns_acl_t *) arg; - int match; - - (void)dns_acl_match(addr, NULL, sortacl, - &ns_g_server->aclenv, - &match, NULL); - if (match > 0) - return (match); - else if (match < 0) - return (INT_MAX - (-match)); - else - return (INT_MAX / 2); -} - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) { - const dns_aclelement_t *matchelt = (const dns_aclelement_t *) arg; - if (dns_aclelement_match(addr, NULL, matchelt, - &ns_g_server->aclenv, - NULL)) { - return (0); - } else { - return (INT_MAX); - } -} - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp) -{ - ns_sortlisttype_t sortlisttype; - - sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp); - - switch (sortlisttype) { - case NS_SORTLISTTYPE_1ELEMENT: - *orderp = ns_sortlist_addrorder1; - break; - case NS_SORTLISTTYPE_2ELEMENT: - *orderp = ns_sortlist_addrorder2; - break; - case NS_SORTLISTTYPE_NONE: - *orderp = NULL; - break; - default: - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unexpected return from ns_sortlist_setup(): " - "%d", sortlisttype); - break; - } -} - diff --git a/bin/named-pkcs11/statschannel.c b/bin/named-pkcs11/statschannel.c deleted file mode 100644 index 4938c03..0000000 --- a/bin/named-pkcs11/statschannel.c +++ /dev/null @@ -1,3594 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bind9.xsl.h" - -struct ns_statschannel { - /* Unlocked */ - isc_httpdmgr_t *httpdmgr; - isc_sockaddr_t address; - isc_mem_t *mctx; - - /* - * Locked by channel lock: can be referenced and modified by both - * the server task and the channel task. - */ - isc_mutex_t lock; - dns_acl_t *acl; - - /* Locked by server task */ - ISC_LINK(struct ns_statschannel) link; -}; - -typedef struct -stats_dumparg { - isc_statsformat_t type; - void *arg; /* type dependent argument */ - int ncounters; /* for general statistics */ - int *counterindices; /* for general statistics */ - uint64_t *countervalues; /* for general statistics */ - isc_result_t result; -} stats_dumparg_t; - -static isc_once_t once = ISC_ONCE_INIT; - -#if defined(HAVE_LIBXML2) || defined(HAVE_JSON) -#define EXTENDED_STATS -#else -#undef EXTENDED_STATS -#endif - -#ifdef EXTENDED_STATS -static const char * -user_zonetype( dns_zone_t *zone ) { - dns_zonetype_t ztype; - dns_view_t *view; - static const struct zt { - const dns_zonetype_t type; - const char *const string; - } typemap[] = { - { dns_zone_none, "none" }, - { dns_zone_master, "master" }, - { dns_zone_slave, "slave" }, - { dns_zone_stub, "stub" }, - { dns_zone_staticstub, "static-stub" }, - { dns_zone_key, "key" }, - { dns_zone_dlz, "dlz" }, - { dns_zone_redirect, "redirect" }, - { 0, NULL } - }; - const struct zt *tp; - - if ((dns_zone_getoptions2(zone) & DNS_ZONEOPT2_AUTOEMPTY) != 0) - return ("builtin"); - - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_bind") == 0) - return ("builtin"); - - ztype = dns_zone_gettype(zone); - for (tp = typemap; tp->string != NULL && tp->type != ztype; tp++) - /* empty */; - return (tp->string); -} -#endif - -/*% - * Statistics descriptions. These could be statistically initialized at - * compile time, but we configure them run time in the init_desc() function - * below so that they'll be less susceptible to counter name changes. - */ -static const char *nsstats_desc[dns_nsstatscounter_max]; -static const char *resstats_desc[dns_resstatscounter_max]; -static const char *adbstats_desc[dns_adbstats_max]; -static const char *zonestats_desc[dns_zonestatscounter_max]; -static const char *sockstats_desc[isc_sockstatscounter_max]; -static const char *dnssecstats_desc[dns_dnssecstats_max]; -static const char *udpinsizestats_desc[dns_sizecounter_in_max]; -static const char *udpoutsizestats_desc[dns_sizecounter_out_max]; -static const char *tcpinsizestats_desc[dns_sizecounter_in_max]; -static const char *tcpoutsizestats_desc[dns_sizecounter_out_max]; -static const char *dnstapstats_desc[dns_dnstapcounter_max]; -#if defined(EXTENDED_STATS) -static const char *nsstats_xmldesc[dns_nsstatscounter_max]; -static const char *resstats_xmldesc[dns_resstatscounter_max]; -static const char *adbstats_xmldesc[dns_adbstats_max]; -static const char *zonestats_xmldesc[dns_zonestatscounter_max]; -static const char *sockstats_xmldesc[isc_sockstatscounter_max]; -static const char *dnssecstats_xmldesc[dns_dnssecstats_max]; -static const char *udpinsizestats_xmldesc[dns_sizecounter_in_max]; -static const char *udpoutsizestats_xmldesc[dns_sizecounter_out_max]; -static const char *tcpinsizestats_xmldesc[dns_sizecounter_in_max]; -static const char *tcpoutsizestats_xmldesc[dns_sizecounter_out_max]; -static const char *dnstapstats_xmldesc[dns_dnstapcounter_max]; -#else -#define nsstats_xmldesc NULL -#define resstats_xmldesc NULL -#define adbstats_xmldesc NULL -#define zonestats_xmldesc NULL -#define sockstats_xmldesc NULL -#define dnssecstats_xmldesc NULL -#define udpinsizestats_xmldesc NULL -#define udpoutsizestats_xmldesc NULL -#define tcpinsizestats_xmldesc NULL -#define tcpoutsizestats_xmldesc NULL -#define dnstapstats_xmldesc NULL -#endif /* EXTENDED_STATS */ - -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) - -/*% - * Mapping arrays to represent statistics counters in the order of our - * preference, regardless of the order of counter indices. For example, - * nsstats_desc[nsstats_index[0]] will be the description that is shown first. - */ -static int nsstats_index[dns_nsstatscounter_max]; -static int resstats_index[dns_resstatscounter_max]; -static int adbstats_index[dns_adbstats_max]; -static int zonestats_index[dns_zonestatscounter_max]; -static int sockstats_index[isc_sockstatscounter_max]; -static int dnssecstats_index[dns_dnssecstats_max]; -static int udpinsizestats_index[dns_sizecounter_in_max]; -static int udpoutsizestats_index[dns_sizecounter_out_max]; -static int tcpinsizestats_index[dns_sizecounter_in_max]; -static int tcpoutsizestats_index[dns_sizecounter_out_max]; -static int dnstapstats_index[dns_dnstapcounter_max]; - -static inline void -set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs, - const char *xdesc, const char **xdescs) -{ - REQUIRE(counter < maxcounter); - REQUIRE(fdescs != NULL && fdescs[counter] == NULL); -#if defined(EXTENDED_STATS) - REQUIRE(xdescs != NULL && xdescs[counter] == NULL); -#endif - - fdescs[counter] = fdesc; -#if defined(EXTENDED_STATS) - xdescs[counter] = xdesc; -#else - UNUSED(xdesc); - UNUSED(xdescs); -#endif -} - -static void -init_desc(void) { - int i; - - /* Initialize name server statistics */ - for (i = 0; i < dns_nsstatscounter_max; i++) - nsstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - nsstats_xmldesc[i] = NULL; -#endif - -#define SET_NSSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_nsstatscounter_ ## counterid, \ - dns_nsstatscounter_max, \ - desc, nsstats_desc, xmldesc, nsstats_xmldesc); \ - nsstats_index[i++] = dns_nsstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_NSSTATDESC(requestv4, "IPv4 requests received", "Requestv4"); - SET_NSSTATDESC(requestv6, "IPv6 requests received", "Requestv6"); - SET_NSSTATDESC(edns0in, "requests with EDNS(0) received", "ReqEdns0"); - SET_NSSTATDESC(badednsver, - "requests with unsupported EDNS version received", - "ReqBadEDNSVer"); - SET_NSSTATDESC(tsigin, "requests with TSIG received", "ReqTSIG"); - SET_NSSTATDESC(sig0in, "requests with SIG(0) received", "ReqSIG0"); - SET_NSSTATDESC(invalidsig, "requests with invalid signature", - "ReqBadSIG"); - SET_NSSTATDESC(requesttcp, "TCP requests received", "ReqTCP"); - SET_NSSTATDESC(tcphighwater, "TCP connection high-water", - "TCPConnHighWater"); - SET_NSSTATDESC(authrej, "auth queries rejected", "AuthQryRej"); - SET_NSSTATDESC(recurserej, "recursive queries rejected", "RecQryRej"); - SET_NSSTATDESC(xfrrej, "transfer requests rejected", "XfrRej"); - SET_NSSTATDESC(updaterej, "update requests rejected", "UpdateRej"); - SET_NSSTATDESC(response, "responses sent", "Response"); - SET_NSSTATDESC(truncatedresp, "truncated responses sent", - "TruncatedResp"); - SET_NSSTATDESC(edns0out, "responses with EDNS(0) sent", "RespEDNS0"); - SET_NSSTATDESC(tsigout, "responses with TSIG sent", "RespTSIG"); - SET_NSSTATDESC(sig0out, "responses with SIG(0) sent", "RespSIG0"); - SET_NSSTATDESC(success, "queries resulted in successful answer", - "QrySuccess"); - SET_NSSTATDESC(authans, "queries resulted in authoritative answer", - "QryAuthAns"); - SET_NSSTATDESC(nonauthans, - "queries resulted in non authoritative answer", - "QryNoauthAns"); - SET_NSSTATDESC(referral, "queries resulted in referral answer", - "QryReferral"); - SET_NSSTATDESC(nxrrset, "queries resulted in nxrrset", "QryNxrrset"); - SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL"); - SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR"); - SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN"); - SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion"); - SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate"); - SET_NSSTATDESC(dropped, "queries dropped", "QryDropped"); - SET_NSSTATDESC(failure, "other query failures", "QryFailure"); - SET_NSSTATDESC(xfrdone, "requested transfers completed", "XfrReqDone"); - SET_NSSTATDESC(updatereqfwd, "update requests forwarded", - "UpdateReqFwd"); - SET_NSSTATDESC(updaterespfwd, "update responses forwarded", - "UpdateRespFwd"); - SET_NSSTATDESC(updatefwdfail, "update forward failed", "UpdateFwdFail"); - SET_NSSTATDESC(updatedone, "updates completed", "UpdateDone"); - SET_NSSTATDESC(updatefail, "updates failed", "UpdateFail"); - SET_NSSTATDESC(updatebadprereq, - "updates rejected due to prerequisite failure", - "UpdateBadPrereq"); - SET_NSSTATDESC(recursclients, "recursing clients", - "RecursClients"); - SET_NSSTATDESC(dns64, "queries answered by DNS64", "DNS64"); - SET_NSSTATDESC(ratedropped, "responses dropped for rate limits", - "RateDropped"); - SET_NSSTATDESC(rateslipped, "responses truncated for rate limits", - "RateSlipped"); - SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites", - "RPZRewrites"); - SET_NSSTATDESC(udp, "UDP queries received", "QryUDP"); - SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP"); - SET_NSSTATDESC(nsidopt, "NSID option received", "NSIDOpt"); - SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt"); - SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt"); - SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn"); - SET_NSSTATDESC(cookienew, "COOKIE - client only", "CookieNew"); - SET_NSSTATDESC(cookiebadsize, "COOKIE - bad size", "CookieBadSize"); - SET_NSSTATDESC(cookiebadtime, "COOKIE - bad time", "CookieBadTime"); - SET_NSSTATDESC(cookienomatch, "COOKIE - no match", "CookieNoMatch"); - SET_NSSTATDESC(cookiematch, "COOKIE - match", "CookieMatch"); - SET_NSSTATDESC(ecsopt, "EDNS client subnet option received", "ECSOpt"); - SET_NSSTATDESC(nxdomainredirect, - "queries resulted in NXDOMAIN that were redirected", - "QryNXRedir"); - SET_NSSTATDESC(nxdomainredirect_rlookup, - "queries resulted in NXDOMAIN that were redirected and " - "resulted in a successful remote lookup", - "QryNXRedirRLookup"); - SET_NSSTATDESC(badcookie, "sent badcookie response", "QryBADCOOKIE"); - SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt"); - SET_NSSTATDESC(reclimitdropped, - "queries dropped due to recursive client limit", - "RecLimitDropped"); - SET_NSSTATDESC(trystale, - "attempts to use stale cache data after lookup failure", - "QryTryStale"); - SET_NSSTATDESC(usedstale, - "successful uses of stale cache data after lookup failure", - "QryUsedStale"); - INSIST(i == dns_nsstatscounter_max); - - /* Initialize resolver statistics */ - for (i = 0; i < dns_resstatscounter_max; i++) - resstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_resstatscounter_max; i++) - resstats_xmldesc[i] = NULL; -#endif - -#define SET_RESSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_resstatscounter_ ## counterid, \ - dns_resstatscounter_max, \ - desc, resstats_desc, xmldesc, resstats_xmldesc); \ - resstats_index[i++] = dns_resstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_RESSTATDESC(queryv4, "IPv4 queries sent", "Queryv4"); - SET_RESSTATDESC(queryv6, "IPv6 queries sent", "Queryv6"); - SET_RESSTATDESC(responsev4, "IPv4 responses received", "Responsev4"); - SET_RESSTATDESC(responsev6, "IPv6 responses received", "Responsev6"); - SET_RESSTATDESC(nxdomain, "NXDOMAIN received", "NXDOMAIN"); - SET_RESSTATDESC(servfail, "SERVFAIL received", "SERVFAIL"); - SET_RESSTATDESC(formerr, "FORMERR received", "FORMERR"); - SET_RESSTATDESC(othererror, "other errors received", "OtherError"); - SET_RESSTATDESC(edns0fail, "EDNS(0) query failures", "EDNS0Fail"); - SET_RESSTATDESC(mismatch, "mismatch responses received", "Mismatch"); - SET_RESSTATDESC(truncated, "truncated responses received", "Truncated"); - SET_RESSTATDESC(lame, "lame delegations received", "Lame"); - SET_RESSTATDESC(retry, "query retries", "Retry"); - SET_RESSTATDESC(dispabort, "queries aborted due to quota", - "QueryAbort"); - SET_RESSTATDESC(dispsockfail, "failures in opening query sockets", - "QuerySockFail"); - SET_RESSTATDESC(disprequdp, "UDP queries in progress", "QueryCurUDP"); - SET_RESSTATDESC(dispreqtcp, "TCP queries in progress", "QueryCurTCP"); - SET_RESSTATDESC(querytimeout, "query timeouts", "QueryTimeout"); - SET_RESSTATDESC(gluefetchv4, "IPv4 NS address fetches", "GlueFetchv4"); - SET_RESSTATDESC(gluefetchv6, "IPv6 NS address fetches", "GlueFetchv6"); - SET_RESSTATDESC(gluefetchv4fail, "IPv4 NS address fetch failed", - "GlueFetchv4Fail"); - SET_RESSTATDESC(gluefetchv6fail, "IPv6 NS address fetch failed", - "GlueFetchv6Fail"); - SET_RESSTATDESC(val, "DNSSEC validation attempted", "ValAttempt"); - SET_RESSTATDESC(valsuccess, "DNSSEC validation succeeded", "ValOk"); - SET_RESSTATDESC(valnegsuccess, "DNSSEC NX validation succeeded", - "ValNegOk"); - SET_RESSTATDESC(valfail, "DNSSEC validation failed", "ValFail"); - SET_RESSTATDESC(queryrtt0, "queries with RTT < " - DNS_RESOLVER_QRYRTTCLASS0STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS0STR); - SET_RESSTATDESC(queryrtt1, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS0STR "-" - DNS_RESOLVER_QRYRTTCLASS1STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS1STR); - SET_RESSTATDESC(queryrtt2, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS1STR "-" - DNS_RESOLVER_QRYRTTCLASS2STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS2STR); - SET_RESSTATDESC(queryrtt3, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS2STR "-" - DNS_RESOLVER_QRYRTTCLASS3STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS3STR); - SET_RESSTATDESC(queryrtt4, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS3STR "-" - DNS_RESOLVER_QRYRTTCLASS4STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR); - SET_RESSTATDESC(queryrtt5, "queries with RTT > " - DNS_RESOLVER_QRYRTTCLASS4STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR "+"); - SET_RESSTATDESC(nfetch, "active fetches", "NumFetch"); - SET_RESSTATDESC(buckets, "bucket size", "BucketSize"); - SET_RESSTATDESC(refused, "REFUSED received", "REFUSED"); - SET_RESSTATDESC(cookienew, "COOKIE send with client cookie only", - "ClientCookieOut"); - SET_RESSTATDESC(cookieout, "COOKIE sent with client and server cookie", - "ServerCookieOut"); - SET_RESSTATDESC(cookiein, "COOKIE replies received", "CookieIn"); - SET_RESSTATDESC(cookieok, "COOKIE client ok", "CookieClientOk"); - SET_RESSTATDESC(badvers, "bad EDNS version", "BadEDNSVersion"); - SET_RESSTATDESC(badcookie, "bad cookie rcode", "BadCookieRcode"); - SET_RESSTATDESC(zonequota, "spilled due to zone quota", "ZoneQuota"); - SET_RESSTATDESC(serverquota, "spilled due to server quota", - "ServerQuota"); - SET_RESSTATDESC(nextitem, "waited for next item", "NextItem"); - - INSIST(i == dns_resstatscounter_max); - - /* Initialize adb statistics */ - for (i = 0; i < dns_adbstats_max; i++) - adbstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_adbstats_max; i++) - adbstats_xmldesc[i] = NULL; -#endif - -#define SET_ADBSTATDESC(id, desc, xmldesc) \ - do { \ - set_desc(dns_adbstats_ ## id, dns_adbstats_max, \ - desc, adbstats_desc, xmldesc, adbstats_xmldesc); \ - adbstats_index[i++] = dns_adbstats_ ## id; \ - } while (0) - i = 0; - SET_ADBSTATDESC(nentries, "Address hash table size", "nentries"); - SET_ADBSTATDESC(entriescnt, "Addresses in hash table", "entriescnt"); - SET_ADBSTATDESC(nnames, "Name hash table size", "nnames"); - SET_ADBSTATDESC(namescnt, "Names in hash table", "namescnt"); - - INSIST(i == dns_adbstats_max); - - /* Initialize zone statistics */ - for (i = 0; i < dns_zonestatscounter_max; i++) - zonestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_zonestatscounter_max; i++) - zonestats_xmldesc[i] = NULL; -#endif - -#define SET_ZONESTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_zonestatscounter_ ## counterid, \ - dns_zonestatscounter_max, \ - desc, zonestats_desc, xmldesc, zonestats_xmldesc); \ - zonestats_index[i++] = dns_zonestatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_ZONESTATDESC(notifyoutv4, "IPv4 notifies sent", "NotifyOutv4"); - SET_ZONESTATDESC(notifyoutv6, "IPv6 notifies sent", "NotifyOutv6"); - SET_ZONESTATDESC(notifyinv4, "IPv4 notifies received", "NotifyInv4"); - SET_ZONESTATDESC(notifyinv6, "IPv6 notifies received", "NotifyInv6"); - SET_ZONESTATDESC(notifyrej, "notifies rejected", "NotifyRej"); - SET_ZONESTATDESC(soaoutv4, "IPv4 SOA queries sent", "SOAOutv4"); - SET_ZONESTATDESC(soaoutv6, "IPv6 SOA queries sent", "SOAOutv6"); - SET_ZONESTATDESC(axfrreqv4, "IPv4 AXFR requested", "AXFRReqv4"); - SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6"); - SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4"); - SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6"); - SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded", - "XfrSuccess"); - SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail"); - INSIST(i == dns_zonestatscounter_max); - - /* Initialize socket statistics */ - for (i = 0; i < isc_sockstatscounter_max; i++) - sockstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < isc_sockstatscounter_max; i++) - sockstats_xmldesc[i] = NULL; -#endif - -#define SET_SOCKSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(isc_sockstatscounter_ ## counterid, \ - isc_sockstatscounter_max, \ - desc, sockstats_desc, xmldesc, sockstats_xmldesc); \ - sockstats_index[i++] = isc_sockstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_SOCKSTATDESC(udp4open, "UDP/IPv4 sockets opened", "UDP4Open"); - SET_SOCKSTATDESC(udp6open, "UDP/IPv6 sockets opened", "UDP6Open"); - SET_SOCKSTATDESC(tcp4open, "TCP/IPv4 sockets opened", "TCP4Open"); - SET_SOCKSTATDESC(tcp6open, "TCP/IPv6 sockets opened", "TCP6Open"); - SET_SOCKSTATDESC(unixopen, "Unix domain sockets opened", "UnixOpen"); - SET_SOCKSTATDESC(rawopen, "Raw sockets opened", "RawOpen"); - SET_SOCKSTATDESC(udp4openfail, "UDP/IPv4 socket open failures", - "UDP4OpenFail"); - SET_SOCKSTATDESC(udp6openfail, "UDP/IPv6 socket open failures", - "UDP6OpenFail"); - SET_SOCKSTATDESC(tcp4openfail, "TCP/IPv4 socket open failures", - "TCP4OpenFail"); - SET_SOCKSTATDESC(tcp6openfail, "TCP/IPv6 socket open failures", - "TCP6OpenFail"); - SET_SOCKSTATDESC(unixopenfail, "Unix domain socket open failures", - "UnixOpenFail"); - SET_SOCKSTATDESC(rawopenfail, "Raw socket open failures", - "RawOpenFail"); - SET_SOCKSTATDESC(udp4close, "UDP/IPv4 sockets closed", "UDP4Close"); - SET_SOCKSTATDESC(udp6close, "UDP/IPv6 sockets closed", "UDP6Close"); - SET_SOCKSTATDESC(tcp4close, "TCP/IPv4 sockets closed", "TCP4Close"); - SET_SOCKSTATDESC(tcp6close, "TCP/IPv6 sockets closed", "TCP6Close"); - SET_SOCKSTATDESC(unixclose, "Unix domain sockets closed", "UnixClose"); - SET_SOCKSTATDESC(fdwatchclose, "FDwatch sockets closed", - "FDWatchClose"); - SET_SOCKSTATDESC(rawclose, "Raw sockets closed", "RawClose"); - SET_SOCKSTATDESC(udp4bindfail, "UDP/IPv4 socket bind failures", - "UDP4BindFail"); - SET_SOCKSTATDESC(udp6bindfail, "UDP/IPv6 socket bind failures", - "UDP6BindFail"); - SET_SOCKSTATDESC(tcp4bindfail, "TCP/IPv4 socket bind failures", - "TCP4BindFail"); - SET_SOCKSTATDESC(tcp6bindfail, "TCP/IPv6 socket bind failures", - "TCP6BindFail"); - SET_SOCKSTATDESC(unixbindfail, "Unix domain socket bind failures", - "UnixBindFail"); - SET_SOCKSTATDESC(fdwatchbindfail, "FDwatch socket bind failures", - "FdwatchBindFail"); - SET_SOCKSTATDESC(udp4connectfail, "UDP/IPv4 socket connect failures", - "UDP4ConnFail"); - SET_SOCKSTATDESC(udp6connectfail, "UDP/IPv6 socket connect failures", - "UDP6ConnFail"); - SET_SOCKSTATDESC(tcp4connectfail, "TCP/IPv4 socket connect failures", - "TCP4ConnFail"); - SET_SOCKSTATDESC(tcp6connectfail, "TCP/IPv6 socket connect failures", - "TCP6ConnFail"); - SET_SOCKSTATDESC(unixconnectfail, "Unix domain socket connect failures", - "UnixConnFail"); - SET_SOCKSTATDESC(fdwatchconnectfail, "FDwatch socket connect failures", - "FDwatchConnFail"); - SET_SOCKSTATDESC(udp4connect, "UDP/IPv4 connections established", - "UDP4Conn"); - SET_SOCKSTATDESC(udp6connect, "UDP/IPv6 connections established", - "UDP6Conn"); - SET_SOCKSTATDESC(tcp4connect, "TCP/IPv4 connections established", - "TCP4Conn"); - SET_SOCKSTATDESC(tcp6connect, "TCP/IPv6 connections established", - "TCP6Conn"); - SET_SOCKSTATDESC(unixconnect, "Unix domain connections established", - "UnixConn"); - SET_SOCKSTATDESC(fdwatchconnect, - "FDwatch domain connections established", - "FDwatchConn"); - SET_SOCKSTATDESC(tcp4acceptfail, "TCP/IPv4 connection accept failures", - "TCP4AcceptFail"); - SET_SOCKSTATDESC(tcp6acceptfail, "TCP/IPv6 connection accept failures", - "TCP6AcceptFail"); - SET_SOCKSTATDESC(unixacceptfail, - "Unix domain connection accept failures", - "UnixAcceptFail"); - SET_SOCKSTATDESC(tcp4accept, "TCP/IPv4 connections accepted", - "TCP4Accept"); - SET_SOCKSTATDESC(tcp6accept, "TCP/IPv6 connections accepted", - "TCP6Accept"); - SET_SOCKSTATDESC(unixaccept, "Unix domain connections accepted", - "UnixAccept"); - SET_SOCKSTATDESC(udp4sendfail, "UDP/IPv4 send errors", "UDP4SendErr"); - SET_SOCKSTATDESC(udp6sendfail, "UDP/IPv6 send errors", "UDP6SendErr"); - SET_SOCKSTATDESC(tcp4sendfail, "TCP/IPv4 send errors", "TCP4SendErr"); - SET_SOCKSTATDESC(tcp6sendfail, "TCP/IPv6 send errors", "TCP6SendErr"); - SET_SOCKSTATDESC(unixsendfail, "Unix domain send errors", - "UnixSendErr"); - SET_SOCKSTATDESC(fdwatchsendfail, "FDwatch send errors", - "FDwatchSendErr"); - SET_SOCKSTATDESC(udp4recvfail, "UDP/IPv4 recv errors", "UDP4RecvErr"); - SET_SOCKSTATDESC(udp6recvfail, "UDP/IPv6 recv errors", "UDP6RecvErr"); - SET_SOCKSTATDESC(tcp4recvfail, "TCP/IPv4 recv errors", "TCP4RecvErr"); - SET_SOCKSTATDESC(tcp6recvfail, "TCP/IPv6 recv errors", "TCP6RecvErr"); - SET_SOCKSTATDESC(unixrecvfail, "Unix domain recv errors", - "UnixRecvErr"); - SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors", - "FDwatchRecvErr"); - SET_SOCKSTATDESC(rawrecvfail, "Raw recv errors", "RawRecvErr"); - SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active"); - SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active"); - SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active"); - SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active"); - SET_SOCKSTATDESC(unixactive, "Unix domain sockets active", - "UnixActive"); - SET_SOCKSTATDESC(rawactive, "Raw sockets active", "RawActive"); - INSIST(i == isc_sockstatscounter_max); - - /* Initialize DNSSEC statistics */ - for (i = 0; i < dns_dnssecstats_max; i++) - dnssecstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_dnssecstats_max; i++) - dnssecstats_xmldesc[i] = NULL; -#endif - -#define SET_DNSSECSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_dnssecstats_ ## counterid, \ - dns_dnssecstats_max, \ - desc, dnssecstats_desc, \ - xmldesc, dnssecstats_xmldesc); \ - dnssecstats_index[i++] = dns_dnssecstats_ ## counterid; \ - } while (0) - - i = 0; - SET_DNSSECSTATDESC(asis, "dnssec validation success with signer " - "\"as is\"", "DNSSECasis"); - SET_DNSSECSTATDESC(downcase, "dnssec validation success with signer " - "lower cased", "DNSSECdowncase"); - SET_DNSSECSTATDESC(wildcard, "dnssec validation of wildcard signature", - "DNSSECwild"); - SET_DNSSECSTATDESC(fail, "dnssec validation failures", "DNSSECfail"); - INSIST(i == dns_dnssecstats_max); - - /* Initialize dnstap statistics */ - for (i = 0; i < dns_dnstapcounter_max; i++) - dnstapstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_dnstapcounter_max; i++) - dnstapstats_xmldesc[i] = NULL; -#endif - -#define SET_DNSTAPSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_dnstapcounter_ ## counterid, \ - dns_dnstapcounter_max, \ - desc, dnstapstats_desc, \ - xmldesc, dnstapstats_xmldesc); \ - dnstapstats_index[i++] = dns_dnstapcounter_ ## counterid; \ - } while (0) - i = 0; - SET_DNSTAPSTATDESC(success, "dnstap messages written", "DNSTAPsuccess"); - SET_DNSTAPSTATDESC(drop, "dnstap messages dropped", "DNSTAPdropped"); - INSIST(i == dns_dnstapcounter_max); - - /* Sanity check */ - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_desc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_desc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_desc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_desc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_desc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_desc[i] != NULL); - for (i = 0; i < dns_dnstapcounter_max; i++) - INSIST(dnstapstats_desc[i] != NULL); -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_xmldesc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_xmldesc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_xmldesc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_xmldesc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnstapcounter_max; i++) - INSIST(dnstapstats_xmldesc[i] != NULL); -#endif - - /* Initialize traffic size statistics */ - for (i = 0; i < dns_sizecounter_in_max; i++) { - udpinsizestats_desc[i] = NULL; - tcpinsizestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - udpinsizestats_xmldesc[i] = NULL; - tcpinsizestats_xmldesc[i] = NULL; -#endif - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - udpoutsizestats_desc[i] = NULL; - tcpoutsizestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - udpoutsizestats_xmldesc[i] = NULL; - tcpoutsizestats_xmldesc[i] = NULL; -#endif - } - -#define SET_SIZESTATDESC(counterid, desc, xmldesc, inout) \ - do { \ - set_desc(dns_sizecounter_ ## inout ## _ ## counterid, \ - dns_sizecounter_ ## inout ## _max, \ - desc, udp ## inout ## sizestats_desc, \ - xmldesc, udp ## inout ## sizestats_xmldesc); \ - set_desc(dns_sizecounter_ ## inout ## _ ## counterid, \ - dns_sizecounter_ ## inout ## _max, \ - desc, tcp ## inout ## sizestats_desc, \ - xmldesc, tcp ## inout ## sizestats_xmldesc); \ - udp ## inout ## sizestats_index[i] = dns_sizecounter_ ## inout ## _ ## counterid; \ - tcp ## inout ## sizestats_index[i] = dns_sizecounter_ ## inout ## _ ## counterid; \ - i++; \ - } while (0) - - i = 0; - SET_SIZESTATDESC(0, "requests received 0-15 bytes", "0-15", in); - SET_SIZESTATDESC(16, "requests received 16-31 bytes", "16-31", in); - SET_SIZESTATDESC(32, "requests received 32-47 bytes", "32-47", in); - SET_SIZESTATDESC(48, "requests received 48-63 bytes", "48-63", in); - SET_SIZESTATDESC(64, "requests received 64-79 bytes", "64-79", in); - SET_SIZESTATDESC(80, "requests received 80-95 bytes", "80-95", in); - SET_SIZESTATDESC(96, "requests received 96-111 bytes", "96-111", in); - SET_SIZESTATDESC(112, "requests received 112-127 bytes", "112-127", in); - SET_SIZESTATDESC(128, "requests received 128-143 bytes", "128-143", in); - SET_SIZESTATDESC(144, "requests received 144-159 bytes", "144-159", in); - SET_SIZESTATDESC(160, "requests received 160-175 bytes", "160-175", in); - SET_SIZESTATDESC(176, "requests received 176-191 bytes", "176-191", in); - SET_SIZESTATDESC(192, "requests received 192-207 bytes", "192-207", in); - SET_SIZESTATDESC(208, "requests received 208-223 bytes", "208-223", in); - SET_SIZESTATDESC(224, "requests received 224-239 bytes", "224-239", in); - SET_SIZESTATDESC(240, "requests received 240-255 bytes", "240-255", in); - SET_SIZESTATDESC(256, "requests received 256-271 bytes", "256-271", in); - SET_SIZESTATDESC(272, "requests received 272-287 bytes", "272-287", in); - SET_SIZESTATDESC(288, "requests received 288+ bytes", "288+", in); - INSIST(i == dns_sizecounter_in_max); - - i = 0; - SET_SIZESTATDESC(0, "responses sent 0-15 bytes", "0-15", out); - SET_SIZESTATDESC(16, "responses sent 16-31 bytes", "16-31", out); - SET_SIZESTATDESC(32, "responses sent 32-47 bytes", "32-47", out); - SET_SIZESTATDESC(48, "responses sent 48-63 bytes", "48-63", out); - SET_SIZESTATDESC(64, "responses sent 64-79 bytes", "64-79", out); - SET_SIZESTATDESC(80, "responses sent 80-95 bytes", "80-95", out); - SET_SIZESTATDESC(96, "responses sent 96-111 bytes", "96-111", out); - SET_SIZESTATDESC(112, "responses sent 112-127 bytes", "112-127", out); - SET_SIZESTATDESC(128, "responses sent 128-143 bytes", "128-143", out); - SET_SIZESTATDESC(144, "responses sent 144-159 bytes", "144-159", out); - SET_SIZESTATDESC(160, "responses sent 160-175 bytes", "160-175", out); - SET_SIZESTATDESC(176, "responses sent 176-191 bytes", "176-191", out); - SET_SIZESTATDESC(192, "responses sent 192-207 bytes", "192-207", out); - SET_SIZESTATDESC(208, "responses sent 208-223 bytes", "208-223", out); - SET_SIZESTATDESC(224, "responses sent 224-239 bytes", "224-239", out); - SET_SIZESTATDESC(240, "responses sent 240-255 bytes", "240-255", out); - SET_SIZESTATDESC(256, "responses sent 256-271 bytes", "256-271", out); - SET_SIZESTATDESC(272, "responses sent 272-287 bytes", "272-287", out); - SET_SIZESTATDESC(288, "responses sent 288-303 bytes", "288-303", out); - SET_SIZESTATDESC(304, "responses sent 304-319 bytes", "304-319", out); - SET_SIZESTATDESC(320, "responses sent 320-335 bytes", "320-335", out); - SET_SIZESTATDESC(336, "responses sent 336-351 bytes", "336-351", out); - SET_SIZESTATDESC(352, "responses sent 352-367 bytes", "352-367", out); - SET_SIZESTATDESC(368, "responses sent 368-383 bytes", "368-383", out); - SET_SIZESTATDESC(384, "responses sent 384-399 bytes", "384-399", out); - SET_SIZESTATDESC(400, "responses sent 400-415 bytes", "400-415", out); - SET_SIZESTATDESC(416, "responses sent 416-431 bytes", "416-431", out); - SET_SIZESTATDESC(432, "responses sent 432-447 bytes", "432-447", out); - SET_SIZESTATDESC(448, "responses sent 448-463 bytes", "448-463", out); - SET_SIZESTATDESC(464, "responses sent 464-479 bytes", "464-479", out); - SET_SIZESTATDESC(480, "responses sent 480-495 bytes", "480-495", out); - SET_SIZESTATDESC(496, "responses sent 496-511 bytes", "496-511", out); - SET_SIZESTATDESC(512, "responses sent 512-527 bytes", "512-527", out); - SET_SIZESTATDESC(528, "responses sent 528-543 bytes", "528-543", out); - SET_SIZESTATDESC(544, "responses sent 544-559 bytes", "544-559", out); - SET_SIZESTATDESC(560, "responses sent 560-575 bytes", "560-575", out); - SET_SIZESTATDESC(576, "responses sent 576-591 bytes", "576-591", out); - SET_SIZESTATDESC(592, "responses sent 592-607 bytes", "592-607", out); - SET_SIZESTATDESC(608, "responses sent 608-623 bytes", "608-623", out); - SET_SIZESTATDESC(624, "responses sent 624-639 bytes", "624-639", out); - SET_SIZESTATDESC(640, "responses sent 640-655 bytes", "640-655", out); - SET_SIZESTATDESC(656, "responses sent 656-671 bytes", "656-671", out); - SET_SIZESTATDESC(672, "responses sent 672-687 bytes", "672-687", out); - SET_SIZESTATDESC(688, "responses sent 688-703 bytes", "688-703", out); - SET_SIZESTATDESC(704, "responses sent 704-719 bytes", "704-719", out); - SET_SIZESTATDESC(720, "responses sent 720-735 bytes", "720-735", out); - SET_SIZESTATDESC(736, "responses sent 736-751 bytes", "736-751", out); - SET_SIZESTATDESC(752, "responses sent 752-767 bytes", "752-767", out); - SET_SIZESTATDESC(768, "responses sent 768-783 bytes", "768-783", out); - SET_SIZESTATDESC(784, "responses sent 784-799 bytes", "784-799", out); - SET_SIZESTATDESC(800, "responses sent 800-815 bytes", "800-815", out); - SET_SIZESTATDESC(816, "responses sent 816-831 bytes", "816-831", out); - SET_SIZESTATDESC(832, "responses sent 832-847 bytes", "832-847", out); - SET_SIZESTATDESC(848, "responses sent 848-863 bytes", "848-863", out); - SET_SIZESTATDESC(864, "responses sent 864-879 bytes", "864-879", out); - SET_SIZESTATDESC(880, "responses sent 880-895 bytes", "880-895", out); - SET_SIZESTATDESC(896, "responses sent 896-911 bytes", "896-911", out); - SET_SIZESTATDESC(912, "responses sent 912-927 bytes", "912-927", out); - SET_SIZESTATDESC(928, "responses sent 928-943 bytes", "928-943", out); - SET_SIZESTATDESC(944, "responses sent 944-959 bytes", "944-959", out); - SET_SIZESTATDESC(960, "responses sent 960-975 bytes", "960-975", out); - SET_SIZESTATDESC(976, "responses sent 976-991 bytes", "976-991", out); - SET_SIZESTATDESC(992, "responses sent 992-1007 bytes", "992-1007", out); - SET_SIZESTATDESC(1008, "responses sent 1008-1023 bytes", "1008-1023", out); - SET_SIZESTATDESC(1024, "responses sent 1024-1039 bytes", "1024-1039", out); - SET_SIZESTATDESC(1040, "responses sent 1040-1055 bytes", "1040-1055", out); - SET_SIZESTATDESC(1056, "responses sent 1056-1071 bytes", "1056-1071", out); - SET_SIZESTATDESC(1072, "responses sent 1072-1087 bytes", "1072-1087", out); - SET_SIZESTATDESC(1088, "responses sent 1088-1103 bytes", "1088-1103", out); - SET_SIZESTATDESC(1104, "responses sent 1104-1119 bytes", "1104-1119", out); - SET_SIZESTATDESC(1120, "responses sent 1120-1135 bytes", "1120-1135", out); - SET_SIZESTATDESC(1136, "responses sent 1136-1151 bytes", "1136-1151", out); - SET_SIZESTATDESC(1152, "responses sent 1152-1167 bytes", "1152-1167", out); - SET_SIZESTATDESC(1168, "responses sent 1168-1183 bytes", "1168-1183", out); - SET_SIZESTATDESC(1184, "responses sent 1184-1199 bytes", "1184-1199", out); - SET_SIZESTATDESC(1200, "responses sent 1200-1215 bytes", "1200-1215", out); - SET_SIZESTATDESC(1216, "responses sent 1216-1231 bytes", "1216-1231", out); - SET_SIZESTATDESC(1232, "responses sent 1232-1247 bytes", "1232-1247", out); - SET_SIZESTATDESC(1248, "responses sent 1248-1263 bytes", "1248-1263", out); - SET_SIZESTATDESC(1264, "responses sent 1264-1279 bytes", "1264-1279", out); - SET_SIZESTATDESC(1280, "responses sent 1280-1295 bytes", "1280-1295", out); - SET_SIZESTATDESC(1296, "responses sent 1296-1311 bytes", "1296-1311", out); - SET_SIZESTATDESC(1312, "responses sent 1312-1327 bytes", "1312-1327", out); - SET_SIZESTATDESC(1328, "responses sent 1328-1343 bytes", "1328-1343", out); - SET_SIZESTATDESC(1344, "responses sent 1344-1359 bytes", "1344-1359", out); - SET_SIZESTATDESC(1360, "responses sent 1360-1375 bytes", "1360-1375", out); - SET_SIZESTATDESC(1376, "responses sent 1376-1391 bytes", "1376-1391", out); - SET_SIZESTATDESC(1392, "responses sent 1392-1407 bytes", "1392-1407", out); - SET_SIZESTATDESC(1408, "responses sent 1408-1423 bytes", "1408-1423", out); - SET_SIZESTATDESC(1424, "responses sent 1424-1439 bytes", "1424-1439", out); - SET_SIZESTATDESC(1440, "responses sent 1440-1455 bytes", "1440-1455", out); - SET_SIZESTATDESC(1456, "responses sent 1456-1471 bytes", "1456-1471", out); - SET_SIZESTATDESC(1472, "responses sent 1472-1487 bytes", "1472-1487", out); - SET_SIZESTATDESC(1488, "responses sent 1488-1503 bytes", "1488-1503", out); - SET_SIZESTATDESC(1504, "responses sent 1504-1519 bytes", "1504-1519", out); - SET_SIZESTATDESC(1520, "responses sent 1520-1535 bytes", "1520-1535", out); - SET_SIZESTATDESC(1536, "responses sent 1536-1551 bytes", "1536-1551", out); - SET_SIZESTATDESC(1552, "responses sent 1552-1567 bytes", "1552-1567", out); - SET_SIZESTATDESC(1568, "responses sent 1568-1583 bytes", "1568-1583", out); - SET_SIZESTATDESC(1584, "responses sent 1584-1599 bytes", "1584-1599", out); - SET_SIZESTATDESC(1600, "responses sent 1600-1615 bytes", "1600-1615", out); - SET_SIZESTATDESC(1616, "responses sent 1616-1631 bytes", "1616-1631", out); - SET_SIZESTATDESC(1632, "responses sent 1632-1647 bytes", "1632-1647", out); - SET_SIZESTATDESC(1648, "responses sent 1648-1663 bytes", "1648-1663", out); - SET_SIZESTATDESC(1664, "responses sent 1664-1679 bytes", "1664-1679", out); - SET_SIZESTATDESC(1680, "responses sent 1680-1695 bytes", "1680-1695", out); - SET_SIZESTATDESC(1696, "responses sent 1696-1711 bytes", "1696-1711", out); - SET_SIZESTATDESC(1712, "responses sent 1712-1727 bytes", "1712-1727", out); - SET_SIZESTATDESC(1728, "responses sent 1728-1743 bytes", "1728-1743", out); - SET_SIZESTATDESC(1744, "responses sent 1744-1759 bytes", "1744-1759", out); - SET_SIZESTATDESC(1760, "responses sent 1760-1775 bytes", "1760-1775", out); - SET_SIZESTATDESC(1776, "responses sent 1776-1791 bytes", "1776-1791", out); - SET_SIZESTATDESC(1792, "responses sent 1792-1807 bytes", "1792-1807", out); - SET_SIZESTATDESC(1808, "responses sent 1808-1823 bytes", "1808-1823", out); - SET_SIZESTATDESC(1824, "responses sent 1824-1839 bytes", "1824-1839", out); - SET_SIZESTATDESC(1840, "responses sent 1840-1855 bytes", "1840-1855", out); - SET_SIZESTATDESC(1856, "responses sent 1856-1871 bytes", "1856-1871", out); - SET_SIZESTATDESC(1872, "responses sent 1872-1887 bytes", "1872-1887", out); - SET_SIZESTATDESC(1888, "responses sent 1888-1903 bytes", "1888-1903", out); - SET_SIZESTATDESC(1904, "responses sent 1904-1919 bytes", "1904-1919", out); - SET_SIZESTATDESC(1920, "responses sent 1920-1935 bytes", "1920-1935", out); - SET_SIZESTATDESC(1936, "responses sent 1936-1951 bytes", "1936-1951", out); - SET_SIZESTATDESC(1952, "responses sent 1952-1967 bytes", "1952-1967", out); - SET_SIZESTATDESC(1968, "responses sent 1968-1983 bytes", "1968-1983", out); - SET_SIZESTATDESC(1984, "responses sent 1984-1999 bytes", "1984-1999", out); - SET_SIZESTATDESC(2000, "responses sent 2000-2015 bytes", "2000-2015", out); - SET_SIZESTATDESC(2016, "responses sent 2016-2031 bytes", "2016-2031", out); - SET_SIZESTATDESC(2032, "responses sent 2032-2047 bytes", "2032-2047", out); - SET_SIZESTATDESC(2048, "responses sent 2048-2063 bytes", "2048-2063", out); - SET_SIZESTATDESC(2064, "responses sent 2064-2079 bytes", "2064-2079", out); - SET_SIZESTATDESC(2080, "responses sent 2080-2095 bytes", "2080-2095", out); - SET_SIZESTATDESC(2096, "responses sent 2096-2111 bytes", "2096-2111", out); - SET_SIZESTATDESC(2112, "responses sent 2112-2127 bytes", "2112-2127", out); - SET_SIZESTATDESC(2128, "responses sent 2128-2143 bytes", "2128-2143", out); - SET_SIZESTATDESC(2144, "responses sent 2144-2159 bytes", "2144-2159", out); - SET_SIZESTATDESC(2160, "responses sent 2160-2175 bytes", "2160-2175", out); - SET_SIZESTATDESC(2176, "responses sent 2176-2191 bytes", "2176-2191", out); - SET_SIZESTATDESC(2192, "responses sent 2192-2207 bytes", "2192-2207", out); - SET_SIZESTATDESC(2208, "responses sent 2208-2223 bytes", "2208-2223", out); - SET_SIZESTATDESC(2224, "responses sent 2224-2239 bytes", "2224-2239", out); - SET_SIZESTATDESC(2240, "responses sent 2240-2255 bytes", "2240-2255", out); - SET_SIZESTATDESC(2256, "responses sent 2256-2271 bytes", "2256-2271", out); - SET_SIZESTATDESC(2272, "responses sent 2272-2287 bytes", "2272-2287", out); - SET_SIZESTATDESC(2288, "responses sent 2288-2303 bytes", "2288-2303", out); - SET_SIZESTATDESC(2304, "responses sent 2304-2319 bytes", "2304-2319", out); - SET_SIZESTATDESC(2320, "responses sent 2320-2335 bytes", "2320-2335", out); - SET_SIZESTATDESC(2336, "responses sent 2336-2351 bytes", "2336-2351", out); - SET_SIZESTATDESC(2352, "responses sent 2352-2367 bytes", "2352-2367", out); - SET_SIZESTATDESC(2368, "responses sent 2368-2383 bytes", "2368-2383", out); - SET_SIZESTATDESC(2384, "responses sent 2384-2399 bytes", "2384-2399", out); - SET_SIZESTATDESC(2400, "responses sent 2400-2415 bytes", "2400-2415", out); - SET_SIZESTATDESC(2416, "responses sent 2416-2431 bytes", "2416-2431", out); - SET_SIZESTATDESC(2432, "responses sent 2432-2447 bytes", "2432-2447", out); - SET_SIZESTATDESC(2448, "responses sent 2448-2463 bytes", "2448-2463", out); - SET_SIZESTATDESC(2464, "responses sent 2464-2479 bytes", "2464-2479", out); - SET_SIZESTATDESC(2480, "responses sent 2480-2495 bytes", "2480-2495", out); - SET_SIZESTATDESC(2496, "responses sent 2496-2511 bytes", "2496-2511", out); - SET_SIZESTATDESC(2512, "responses sent 2512-2527 bytes", "2512-2527", out); - SET_SIZESTATDESC(2528, "responses sent 2528-2543 bytes", "2528-2543", out); - SET_SIZESTATDESC(2544, "responses sent 2544-2559 bytes", "2544-2559", out); - SET_SIZESTATDESC(2560, "responses sent 2560-2575 bytes", "2560-2575", out); - SET_SIZESTATDESC(2576, "responses sent 2576-2591 bytes", "2576-2591", out); - SET_SIZESTATDESC(2592, "responses sent 2592-2607 bytes", "2592-2607", out); - SET_SIZESTATDESC(2608, "responses sent 2608-2623 bytes", "2608-2623", out); - SET_SIZESTATDESC(2624, "responses sent 2624-2639 bytes", "2624-2639", out); - SET_SIZESTATDESC(2640, "responses sent 2640-2655 bytes", "2640-2655", out); - SET_SIZESTATDESC(2656, "responses sent 2656-2671 bytes", "2656-2671", out); - SET_SIZESTATDESC(2672, "responses sent 2672-2687 bytes", "2672-2687", out); - SET_SIZESTATDESC(2688, "responses sent 2688-2703 bytes", "2688-2703", out); - SET_SIZESTATDESC(2704, "responses sent 2704-2719 bytes", "2704-2719", out); - SET_SIZESTATDESC(2720, "responses sent 2720-2735 bytes", "2720-2735", out); - SET_SIZESTATDESC(2736, "responses sent 2736-2751 bytes", "2736-2751", out); - SET_SIZESTATDESC(2752, "responses sent 2752-2767 bytes", "2752-2767", out); - SET_SIZESTATDESC(2768, "responses sent 2768-2783 bytes", "2768-2783", out); - SET_SIZESTATDESC(2784, "responses sent 2784-2799 bytes", "2784-2799", out); - SET_SIZESTATDESC(2800, "responses sent 2800-2815 bytes", "2800-2815", out); - SET_SIZESTATDESC(2816, "responses sent 2816-2831 bytes", "2816-2831", out); - SET_SIZESTATDESC(2832, "responses sent 2832-2847 bytes", "2832-2847", out); - SET_SIZESTATDESC(2848, "responses sent 2848-2863 bytes", "2848-2863", out); - SET_SIZESTATDESC(2864, "responses sent 2864-2879 bytes", "2864-2879", out); - SET_SIZESTATDESC(2880, "responses sent 2880-2895 bytes", "2880-2895", out); - SET_SIZESTATDESC(2896, "responses sent 2896-2911 bytes", "2896-2911", out); - SET_SIZESTATDESC(2912, "responses sent 2912-2927 bytes", "2912-2927", out); - SET_SIZESTATDESC(2928, "responses sent 2928-2943 bytes", "2928-2943", out); - SET_SIZESTATDESC(2944, "responses sent 2944-2959 bytes", "2944-2959", out); - SET_SIZESTATDESC(2960, "responses sent 2960-2975 bytes", "2960-2975", out); - SET_SIZESTATDESC(2976, "responses sent 2976-2991 bytes", "2976-2991", out); - SET_SIZESTATDESC(2992, "responses sent 2992-3007 bytes", "2992-3007", out); - SET_SIZESTATDESC(3008, "responses sent 3008-3023 bytes", "3008-3023", out); - SET_SIZESTATDESC(3024, "responses sent 3024-3039 bytes", "3024-3039", out); - SET_SIZESTATDESC(3040, "responses sent 3040-3055 bytes", "3040-3055", out); - SET_SIZESTATDESC(3056, "responses sent 3056-3071 bytes", "3056-3071", out); - SET_SIZESTATDESC(3072, "responses sent 3072-3087 bytes", "3072-3087", out); - SET_SIZESTATDESC(3088, "responses sent 3088-3103 bytes", "3088-3103", out); - SET_SIZESTATDESC(3104, "responses sent 3104-3119 bytes", "3104-3119", out); - SET_SIZESTATDESC(3120, "responses sent 3120-3135 bytes", "3120-3135", out); - SET_SIZESTATDESC(3136, "responses sent 3136-3151 bytes", "3136-3151", out); - SET_SIZESTATDESC(3152, "responses sent 3152-3167 bytes", "3152-3167", out); - SET_SIZESTATDESC(3168, "responses sent 3168-3183 bytes", "3168-3183", out); - SET_SIZESTATDESC(3184, "responses sent 3184-3199 bytes", "3184-3199", out); - SET_SIZESTATDESC(3200, "responses sent 3200-3215 bytes", "3200-3215", out); - SET_SIZESTATDESC(3216, "responses sent 3216-3231 bytes", "3216-3231", out); - SET_SIZESTATDESC(3232, "responses sent 3232-3247 bytes", "3232-3247", out); - SET_SIZESTATDESC(3248, "responses sent 3248-3263 bytes", "3248-3263", out); - SET_SIZESTATDESC(3264, "responses sent 3264-3279 bytes", "3264-3279", out); - SET_SIZESTATDESC(3280, "responses sent 3280-3295 bytes", "3280-3295", out); - SET_SIZESTATDESC(3296, "responses sent 3296-3311 bytes", "3296-3311", out); - SET_SIZESTATDESC(3312, "responses sent 3312-3327 bytes", "3312-3327", out); - SET_SIZESTATDESC(3328, "responses sent 3328-3343 bytes", "3328-3343", out); - SET_SIZESTATDESC(3344, "responses sent 3344-3359 bytes", "3344-3359", out); - SET_SIZESTATDESC(3360, "responses sent 3360-3375 bytes", "3360-3375", out); - SET_SIZESTATDESC(3376, "responses sent 3376-3391 bytes", "3376-3391", out); - SET_SIZESTATDESC(3392, "responses sent 3392-3407 bytes", "3392-3407", out); - SET_SIZESTATDESC(3408, "responses sent 3408-3423 bytes", "3408-3423", out); - SET_SIZESTATDESC(3424, "responses sent 3424-3439 bytes", "3424-3439", out); - SET_SIZESTATDESC(3440, "responses sent 3440-3455 bytes", "3440-3455", out); - SET_SIZESTATDESC(3456, "responses sent 3456-3471 bytes", "3456-3471", out); - SET_SIZESTATDESC(3472, "responses sent 3472-3487 bytes", "3472-3487", out); - SET_SIZESTATDESC(3488, "responses sent 3488-3503 bytes", "3488-3503", out); - SET_SIZESTATDESC(3504, "responses sent 3504-3519 bytes", "3504-3519", out); - SET_SIZESTATDESC(3520, "responses sent 3520-3535 bytes", "3520-3535", out); - SET_SIZESTATDESC(3536, "responses sent 3536-3551 bytes", "3536-3551", out); - SET_SIZESTATDESC(3552, "responses sent 3552-3567 bytes", "3552-3567", out); - SET_SIZESTATDESC(3568, "responses sent 3568-3583 bytes", "3568-3583", out); - SET_SIZESTATDESC(3584, "responses sent 3584-3599 bytes", "3584-3599", out); - SET_SIZESTATDESC(3600, "responses sent 3600-3615 bytes", "3600-3615", out); - SET_SIZESTATDESC(3616, "responses sent 3616-3631 bytes", "3616-3631", out); - SET_SIZESTATDESC(3632, "responses sent 3632-3647 bytes", "3632-3647", out); - SET_SIZESTATDESC(3648, "responses sent 3648-3663 bytes", "3648-3663", out); - SET_SIZESTATDESC(3664, "responses sent 3664-3679 bytes", "3664-3679", out); - SET_SIZESTATDESC(3680, "responses sent 3680-3695 bytes", "3680-3695", out); - SET_SIZESTATDESC(3696, "responses sent 3696-3711 bytes", "3696-3711", out); - SET_SIZESTATDESC(3712, "responses sent 3712-3727 bytes", "3712-3727", out); - SET_SIZESTATDESC(3728, "responses sent 3728-3743 bytes", "3728-3743", out); - SET_SIZESTATDESC(3744, "responses sent 3744-3759 bytes", "3744-3759", out); - SET_SIZESTATDESC(3760, "responses sent 3760-3775 bytes", "3760-3775", out); - SET_SIZESTATDESC(3776, "responses sent 3776-3791 bytes", "3776-3791", out); - SET_SIZESTATDESC(3792, "responses sent 3792-3807 bytes", "3792-3807", out); - SET_SIZESTATDESC(3808, "responses sent 3808-3823 bytes", "3808-3823", out); - SET_SIZESTATDESC(3824, "responses sent 3824-3839 bytes", "3824-3839", out); - SET_SIZESTATDESC(3840, "responses sent 3840-3855 bytes", "3840-3855", out); - SET_SIZESTATDESC(3856, "responses sent 3856-3871 bytes", "3856-3871", out); - SET_SIZESTATDESC(3872, "responses sent 3872-3887 bytes", "3872-3887", out); - SET_SIZESTATDESC(3888, "responses sent 3888-3903 bytes", "3888-3903", out); - SET_SIZESTATDESC(3904, "responses sent 3904-3919 bytes", "3904-3919", out); - SET_SIZESTATDESC(3920, "responses sent 3920-3935 bytes", "3920-3935", out); - SET_SIZESTATDESC(3936, "responses sent 3936-3951 bytes", "3936-3951", out); - SET_SIZESTATDESC(3952, "responses sent 3952-3967 bytes", "3952-3967", out); - SET_SIZESTATDESC(3968, "responses sent 3968-3983 bytes", "3968-3983", out); - SET_SIZESTATDESC(3984, "responses sent 3984-3999 bytes", "3984-3999", out); - SET_SIZESTATDESC(4000, "responses sent 4000-4015 bytes", "4000-4015", out); - SET_SIZESTATDESC(4016, "responses sent 4016-4031 bytes", "4016-4031", out); - SET_SIZESTATDESC(4032, "responses sent 4032-4047 bytes", "4032-4047", out); - SET_SIZESTATDESC(4048, "responses sent 4048-4063 bytes", "4048-4063", out); - SET_SIZESTATDESC(4064, "responses sent 4064-4079 bytes", "4064-4079", out); - SET_SIZESTATDESC(4080, "responses sent 4080-4095 bytes", "4080-4095", out); - SET_SIZESTATDESC(4096, "responses sent 4096+ bytes", "4096+", out); - INSIST(i == dns_sizecounter_out_max); - - /* Sanity check */ - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_desc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_desc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_desc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_desc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_desc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_desc[i] != NULL); - for (i = 0; i < dns_sizecounter_in_max; i++) { - INSIST(udpinsizestats_desc[i] != NULL); - INSIST(tcpinsizestats_desc[i] != NULL); - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - INSIST(udpoutsizestats_desc[i] != NULL); - INSIST(tcpoutsizestats_desc[i] != NULL); - } -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_xmldesc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_xmldesc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_xmldesc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_xmldesc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_xmldesc[i] != NULL); - for (i = 0; i < dns_sizecounter_in_max; i++) { - INSIST(udpinsizestats_xmldesc[i] != NULL); - INSIST(tcpinsizestats_xmldesc[i] != NULL); - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - INSIST(udpoutsizestats_xmldesc[i] != NULL); - INSIST(tcpoutsizestats_xmldesc[i] != NULL); - } -#endif -} - -/*% - * Dump callback functions. - */ -static void -generalstat_dump(isc_statscounter_t counter, uint64_t val, void *arg) { - stats_dumparg_t *dumparg = arg; - - REQUIRE(counter < dumparg->ncounters); - dumparg->countervalues[counter] = val; -} - -static isc_result_t -dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg, - const char *category, const char **desc, int ncounters, - int *indices, uint64_t *values, int options) -{ - int i, idx; - uint64_t value; - stats_dumparg_t dumparg; - FILE *fp; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *job, *cat, *counter; -#endif - -#if !defined(EXTENDED_STATS) - UNUSED(category); -#endif - - dumparg.type = type; - dumparg.ncounters = ncounters; - dumparg.counterindices = indices; - dumparg.countervalues = values; - - memset(values, 0, sizeof(values[0]) * ncounters); - isc_stats_dump(stats, generalstat_dump, &dumparg, options); - -#ifdef HAVE_JSON - cat = job = (json_object *) arg; - if (ncounters > 0 && type == isc_statsformat_json) { - if (category != NULL) { - cat = json_object_new_object(); - if (cat == NULL) - return (ISC_R_NOMEMORY); - json_object_object_add(job, category, cat); - } - } -#endif - - for (i = 0; i < ncounters; i++) { - idx = indices[i]; - value = values[idx]; - - if (value == 0 && (options & ISC_STATSDUMP_VERBOSE) == 0) - continue; - - switch (dumparg.type) { - case isc_statsformat_file: - fp = arg; - fprintf(fp, "%20" PRIu64 " %s\n", - value, desc[idx]); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = (xmlTextWriterPtr) arg; - - if (category != NULL) { - /* */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - category)); - - /* inside category */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "name")); - TRY0(xmlTextWriterWriteString(writer, - ISC_XMLCHAR - desc[idx])); - TRY0(xmlTextWriterEndElement(writer)); - /* */ - - /* */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "counter")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, value)); - - TRY0(xmlTextWriterEndElement(writer)); - /* */ - TRY0(xmlTextWriterEndElement(writer)); - /* */ - - } else { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR - "name", - ISC_XMLCHAR - desc[idx])); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, value)); - TRY0(xmlTextWriterEndElement(writer)); - /* counter */ - } - -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - counter = json_object_new_int64(value); - if (counter == NULL) - return (ISC_R_NOMEMORY); - json_object_object_add(cat, desc[idx], counter); -#endif - break; - } - } - return (ISC_R_SUCCESS); -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at dump_counters()"); - return (ISC_R_FAILURE); -#endif -} - -static void -rdtypestat_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) { - char typebuf[64]; - const char *typestr; - stats_dumparg_t *dumparg = arg; - FILE *fp; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) - == 0) { - dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf, - sizeof(typebuf)); - typestr = typebuf; - } else - typestr = "Others"; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, typestr); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR typestr)); - - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - - TRY0(xmlTextWriterEndElement(writer)); /* type */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, typestr, obj); -#endif - break; - } - return; -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rdtypestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -static void -rdatasetstats_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) { - stats_dumparg_t *dumparg = arg; - FILE *fp; - char typebuf[64]; - const char *typestr; - bool nxrrset = false; - bool stale = false; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; - char buf[1024]; -#endif - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) - != 0) { - typestr = "NXDOMAIN"; - } else if ((DNS_RDATASTATSTYPE_ATTR(type) & - DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0) { - typestr = "Others"; - } else { - dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf, - sizeof(typebuf)); - typestr = typebuf; - } - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXRRSET) - != 0) - nxrrset = true; - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_STALE) - != 0) - stale = true; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s%s%s\n", val, - stale ? "#" : "", nxrrset ? "!" : "", typestr); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteFormatString(writer, "%s%s%s", - stale ? "#" : "", - nxrrset ? "!" : "", typestr)); - TRY0(xmlTextWriterEndElement(writer)); /* name */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ - - TRY0(xmlTextWriterEndElement(writer)); /* rrset */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - snprintf(buf, sizeof(buf), "%s%s%s", - stale ? "#" : "", nxrrset ? "!" : "", typestr); - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, buf, obj); -#endif - break; - } - return; -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rdatasetstats_dump()"); - dumparg->result = ISC_R_FAILURE; -#endif - -} - -static void -opcodestat_dump(dns_opcode_t code, uint64_t val, void *arg) { - FILE *fp; - isc_buffer_t b; - char codebuf[64]; - stats_dumparg_t *dumparg = arg; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); - dns_opcode_totext(code, &b); - codebuf[isc_buffer_usedlength(&b)] = '\0'; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR codebuf )); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, codebuf, obj); -#endif - break; - } - return; - -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at opcodestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -static void -rcodestat_dump(dns_rcode_t code, uint64_t val, void *arg) { - FILE *fp; - isc_buffer_t b; - char codebuf[64]; - stats_dumparg_t *dumparg = arg; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); - dns_rcode_totext(code, &b); - codebuf[isc_buffer_usedlength(&b)] = '\0'; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR codebuf )); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, codebuf, obj); -#endif - break; - } - return; - -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rcodestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -#ifdef HAVE_LIBXML2 -/* - * Which statistics to include when rendering to XML - */ -#define STATS_XML_STATUS 0x00 /* display only common statistics */ -#define STATS_XML_SERVER 0x01 -#define STATS_XML_ZONES 0x02 -#define STATS_XML_TASKS 0x04 -#define STATS_XML_NET 0x08 -#define STATS_XML_MEM 0x10 -#define STATS_XML_TRAFFIC 0x20 -#define STATS_XML_ALL 0xff - -static isc_result_t -zone_xmlrender(dns_zone_t *zone, void *arg) { - isc_result_t result; - char buf[1024 + 32]; /* sufficiently large for zone name and class */ - dns_rdataclass_t rdclass; - uint32_t serial; - xmlTextWriterPtr writer = arg; - isc_stats_t *zonestats; - dns_stats_t *rcvquerystats; - dns_zonestat_level_t statlevel; - uint64_t nsstat_values[dns_nsstatscounter_max]; - int xmlrc; - stats_dumparg_t dumparg; - const char *ztype; - - statlevel = dns_zone_getstatlevel(zone); - if (statlevel == dns_zonestat_none) - return (ISC_R_SUCCESS); - - dumparg.type = isc_statsformat_xml; - dumparg.arg = writer; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); - - dns_zone_nameonly(zone, buf, sizeof(buf)); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR buf)); - - rdclass = dns_zone_getclass(zone); - dns_rdataclass_format(rdclass, buf, sizeof(buf)); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass", - ISC_XMLCHAR buf)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); - ztype = user_zonetype(zone); - if (ztype != NULL) - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ztype)); - else - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "unknown")); - TRY0(xmlTextWriterEndElement(writer)); /* type */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial")); - if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS) - TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial)); - else - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-")); - TRY0(xmlTextWriterEndElement(writer)); /* serial */ - - zonestats = dns_zone_getrequeststats(zone); - rcvquerystats = dns_zone_getrcvquerystats(zone); - if (statlevel == dns_zonestat_full && zonestats != NULL) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "rcode")); - - result = dump_counters(zonestats, isc_statsformat_xml, writer, - NULL, nsstats_xmldesc, - dns_nsstatscounter_max, nsstats_index, - nsstat_values, ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - /* counters type="rcode"*/ - TRY0(xmlTextWriterEndElement(writer)); - } - - if (statlevel == dns_zonestat_full && rcvquerystats != NULL) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "qtype")); - - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if(dumparg.result != ISC_R_SUCCESS) - goto error; - - /* counters type="qtype"*/ - TRY0(xmlTextWriterEndElement(writer)); - } - - TRY0(xmlTextWriterEndElement(writer)); /* zone */ - - return (ISC_R_SUCCESS); - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "Failed at zone_xmlrender()"); - return (ISC_R_FAILURE); -} - -static isc_result_t -generatexml(ns_server_t *server, uint32_t flags, - int *buflen, xmlChar **buf) -{ - char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - isc_time_t now; - xmlTextWriterPtr writer = NULL; - xmlDocPtr doc = NULL; - int xmlrc; - dns_view_t *view; - stats_dumparg_t dumparg; - dns_stats_t *cacherrstats; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - uint64_t udpinsizestat_values[dns_sizecounter_in_max]; - uint64_t udpoutsizestat_values[dns_sizecounter_out_max]; - uint64_t tcpinsizestat_values[dns_sizecounter_in_max]; - uint64_t tcpoutsizestat_values[dns_sizecounter_out_max]; -#ifdef HAVE_DNSTAP - uint64_t dnstapstat_values[dns_dnstapcounter_max]; -#endif - isc_result_t result; - - isc_time_now(&now); - isc_time_formatISO8601ms(&ns_g_boottime, boottime, sizeof boottime); - isc_time_formatISO8601ms(&ns_g_configtime, configtime, sizeof configtime); - isc_time_formatISO8601ms(&now, nowstr, sizeof nowstr); - - writer = xmlNewTextWriterDoc(&doc, 0); - if (writer == NULL) - goto error; - TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); - TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", - ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "3.8")); - - /* Set common fields for statistics dump */ - dumparg.type = isc_statsformat_xml; - dumparg.arg = writer; - - /* Render server information */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime)); - TRY0(xmlTextWriterEndElement(writer)); /* boot-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "config-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR configtime)); - TRY0(xmlTextWriterEndElement(writer)); /* config-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr)); - TRY0(xmlTextWriterEndElement(writer)); /* current-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "version")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ns_g_version)); - TRY0(xmlTextWriterEndElement(writer)); /* version */ - - if ((flags & STATS_XML_SERVER) != 0) { - dumparg.result = ISC_R_SUCCESS; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "opcode")); - - dns_opcodestats_dump(server->opcodestats, opcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "rcode")); - - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "qtype")); - - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* counters */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "nsstat")); - - result = dump_counters(server->nsstats, isc_statsformat_xml, - writer, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /nsstat */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "zonestat")); - - result = dump_counters(server->zonestats, isc_statsformat_xml, - writer, NULL, zonestats_xmldesc, - dns_zonestatscounter_max, - zonestats_index, zonestat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /zonestat */ - - /* - * Most of the common resolver statistics entries are 0, so - * we don't use the verbose dump here. - */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resstat")); - result = dump_counters(server->resolverstats, - isc_statsformat_xml, writer, - NULL, resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* resstat */ - -#ifdef HAVE_DNSTAP - if (server->dtenv != NULL) { - isc_stats_t *dnstapstats = NULL; - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "type", - ISC_XMLCHAR "dnstap")); - dns_dt_getstats(ns_g_server->dtenv, &dnstapstats); - result = dump_counters(dnstapstats, - isc_statsformat_xml, writer, - NULL, dnstapstats_xmldesc, - dns_dnstapcounter_max, - dnstapstats_index, - dnstapstat_values, 0); - isc_stats_detach(&dnstapstats); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* dnstap */ - } -#endif - } - - if ((flags & STATS_XML_NET) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "sockstat")); - - result = dump_counters(server->sockstats, isc_statsformat_xml, - writer, NULL, sockstats_xmldesc, - isc_sockstatscounter_max, - sockstats_index, sockstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /sockstat */ - } - TRY0(xmlTextWriterEndElement(writer)); /* /server */ - - if ((flags & STATS_XML_TRAFFIC) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "traffic")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv4")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->udpinstats4, - isc_statsformat_xml, writer, - NULL, udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->udpoutstats4, - isc_statsformat_xml, writer, - NULL, udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->tcpinstats4, - isc_statsformat_xml, writer, - NULL, tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->tcpoutstats4, - isc_statsformat_xml, writer, - NULL, tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv6")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->udpinstats6, - isc_statsformat_xml, writer, - NULL, udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->udpoutstats6, - isc_statsformat_xml, writer, - NULL, udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->tcpinstats6, - isc_statsformat_xml, writer, - NULL, tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->tcpoutstats6, - isc_statsformat_xml, writer, - NULL, tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - } - - /* - * Render views. For each view we know of, call its - * rendering function. - */ - view = ISC_LIST_HEAD(server->viewlist); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); - while (view != NULL && - ((flags & (STATS_XML_SERVER | STATS_XML_ZONES)) != 0)) - { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR view->name)); - - if ((flags & STATS_XML_ZONES) != 0) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "zones")); - result = dns_zt_apply(view->zonetable, true, - zone_xmlrender, writer); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* /zones */ - } - - if ((flags & STATS_XML_SERVER) == 0) { - TRY0(xmlTextWriterEndElement(writer)); /* /view */ - view = ISC_LIST_NEXT(view, link); - continue; - } - - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resqtype")); - - if (view->resquerystats != NULL) { - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(view->resquerystats, - rdtypestat_dump, &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resstats")); - if (view->resstats != NULL) { - result = dump_counters(view->resstats, - isc_statsformat_xml, writer, - NULL, resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); /* */ - - cacherrstats = dns_db_getrrsetstats(view->cachedb); - if (cacherrstats != NULL) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "cache")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "name", - ISC_XMLCHAR - dns_cache_getname(view->cache))); - dumparg.result = ISC_R_SUCCESS; - dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* cache */ - } - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "adbstat")); - if (view->adbstats != NULL) { - result = dump_counters(view->adbstats, - isc_statsformat_xml, writer, - NULL, adbstats_xmldesc, - dns_adbstats_max, - adbstats_index, adbstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); /* */ - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "cachestats")); - TRY0(dns_cache_renderxml(view->cache, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterEndElement(writer)); /* view */ - - view = ISC_LIST_NEXT(view, link); - } - TRY0(xmlTextWriterEndElement(writer)); /* /views */ - - if ((flags & STATS_XML_NET) != 0) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "socketmgr")); - TRY0(isc_socketmgr_renderxml(ns_g_socketmgr, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /socketmgr */ - } - - if ((flags & STATS_XML_TASKS) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr")); - TRY0(isc_taskmgr_renderxml(ns_g_taskmgr, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /taskmgr */ - } - - if ((flags & STATS_XML_MEM) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); - TRY0(isc_mem_renderxml(writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /memory */ - } - - - TRY0(xmlTextWriterEndElement(writer)); /* /statistics */ - TRY0(xmlTextWriterEndDocument(writer)); - - xmlFreeTextWriter(writer); - - xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0); - if (*buf == NULL) - goto error; - xmlFreeDoc(doc); - return (ISC_R_SUCCESS); - - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed generating XML response"); - if (writer != NULL) - xmlFreeTextWriter(writer); - if (doc != NULL) - xmlFreeDoc(doc); - return (ISC_R_FAILURE); -} - -static void -wrap_xmlfree(isc_buffer_t *buffer, void *arg) { - UNUSED(arg); - - xmlFree(isc_buffer_base(buffer)); -} - -static isc_result_t -render_xml(uint32_t flags, const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - unsigned char *msg = NULL; - int msglen; - ns_server_t *server = arg; - isc_result_t result; - - UNUSED(url); - UNUSED(urlinfo); - UNUSED(headers); - UNUSED(querystring); - - result = generatexml(server, flags, &msglen, &msg); - - if (result == ISC_R_SUCCESS) { - *retcode = 200; - *retmsg = "OK"; - *mimetype = "text/xml"; - isc_buffer_reinit(b, msg, msglen); - isc_buffer_add(b, msglen); - *freecb = wrap_xmlfree; - *freecb_args = NULL; - } else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed at rendering XML()"); - - return (result); -} - -static isc_result_t -render_xml_all(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_ALL, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_status(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_STATUS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_server(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_SERVER, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_zones(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_ZONES, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_net(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_NET, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_tasks(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_TASKS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_mem(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_MEM, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_traffic(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_TRAFFIC, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -#endif /* HAVE_LIBXML2 */ - -#ifdef HAVE_JSON -/* - * Which statistics to include when rendering to JSON - */ -#define STATS_JSON_STATUS 0x00 /* display only common statistics */ -#define STATS_JSON_SERVER 0x01 -#define STATS_JSON_ZONES 0x02 -#define STATS_JSON_TASKS 0x04 -#define STATS_JSON_NET 0x08 -#define STATS_JSON_MEM 0x10 -#define STATS_JSON_TRAFFIC 0x20 -#define STATS_JSON_ALL 0xff - -#define CHECK(m) do { \ - result = (m); \ - if (result != ISC_R_SUCCESS) \ - goto error; \ -} while (0) - -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) - -static void -wrap_jsonfree(isc_buffer_t *buffer, void *arg) { - json_object_put(isc_buffer_base(buffer)); - if (arg != NULL) - json_object_put((json_object *) arg); -} - -static json_object * -addzone(char *name, char *classname, const char *ztype, - uint32_t serial, bool add_serial) -{ - json_object *node = json_object_new_object(); - - if (node == NULL) - return (NULL); - - json_object_object_add(node, "name", json_object_new_string(name)); - json_object_object_add(node, "class", - json_object_new_string(classname)); - if (add_serial) - json_object_object_add(node, "serial", - json_object_new_int64(serial)); - if (ztype != NULL) - json_object_object_add(node, "type", - json_object_new_string(ztype)); - return (node); -} - -static isc_result_t -zone_jsonrender(dns_zone_t *zone, void *arg) { - isc_result_t result = ISC_R_SUCCESS; - char buf[1024 + 32]; /* sufficiently large for zone name and class */ - char classbuf[64]; /* sufficiently large for class */ - char *zone_name_only = NULL; - char *class_only = NULL; - dns_rdataclass_t rdclass; - uint32_t serial; - uint64_t nsstat_values[dns_nsstatscounter_max]; - isc_stats_t *zonestats; - dns_stats_t *rcvquerystats; - json_object *zonearray = (json_object *) arg; - json_object *zoneobj = NULL; - dns_zonestat_level_t statlevel; - - statlevel = dns_zone_getstatlevel(zone); - if (statlevel == dns_zonestat_none) - return (ISC_R_SUCCESS); - - dns_zone_nameonly(zone, buf, sizeof(buf)); - zone_name_only = buf; - - rdclass = dns_zone_getclass(zone); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - class_only = classbuf; - - if (dns_zone_getserial2(zone, &serial) != ISC_R_SUCCESS) - zoneobj = addzone(zone_name_only, class_only, - user_zonetype(zone), 0, false); - else - zoneobj = addzone(zone_name_only, class_only, - user_zonetype(zone), serial, true); - - if (zoneobj == NULL) - return (ISC_R_NOMEMORY); - - zonestats = dns_zone_getrequeststats(zone); - rcvquerystats = dns_zone_getrcvquerystats(zone); - if (statlevel == dns_zonestat_full && zonestats != NULL) { - json_object *counters = json_object_new_object(); - if (counters == NULL) { - result = ISC_R_NOMEMORY; - goto error; - } - - result = dump_counters(zonestats, isc_statsformat_json, - counters, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, nsstats_index, - nsstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(zoneobj, "rcodes", counters); - else - json_object_put(counters); - } - - if (statlevel == dns_zonestat_full && rcvquerystats != NULL) { - stats_dumparg_t dumparg; - json_object *counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(zoneobj, "qtypes", counters); - else - json_object_put(counters); - } - - json_object_array_add(zonearray, zoneobj); - zoneobj = NULL; - result = ISC_R_SUCCESS; - - error: - if (zoneobj != NULL) - json_object_put(zoneobj); - return (result); -} - -static isc_result_t -generatejson(ns_server_t *server, size_t *msglen, - const char **msg, json_object **rootp, uint32_t flags) -{ - dns_view_t *view; - isc_result_t result = ISC_R_SUCCESS; - json_object *bindstats, *viewlist, *counters, *obj; - json_object *traffic = NULL; - json_object *udpreq4 = NULL, *udpresp4 = NULL; - json_object *tcpreq4 = NULL, *tcpresp4 = NULL; - json_object *udpreq6 = NULL, *udpresp6 = NULL; - json_object *tcpreq6 = NULL, *tcpresp6 = NULL; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - uint64_t udpinsizestat_values[dns_sizecounter_in_max]; - uint64_t udpoutsizestat_values[dns_sizecounter_out_max]; - uint64_t tcpinsizestat_values[dns_sizecounter_in_max]; - uint64_t tcpoutsizestat_values[dns_sizecounter_out_max]; -#ifdef HAVE_DNSTAP - uint64_t dnstapstat_values[dns_dnstapcounter_max]; -#endif - stats_dumparg_t dumparg; - char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - isc_time_t now; - - REQUIRE(msglen != NULL); - REQUIRE(msg != NULL && *msg == NULL); - REQUIRE(rootp == NULL || *rootp == NULL); - - bindstats = json_object_new_object(); - if (bindstats == NULL) - return (ISC_R_NOMEMORY); - - /* - * These statistics are included no matter which URL we use. - */ - obj = json_object_new_string("1.2"); - CHECKMEM(obj); - json_object_object_add(bindstats, "json-stats-version", obj); - - isc_time_now(&now); - isc_time_formatISO8601ms(&ns_g_boottime, - boottime, sizeof(boottime)); - isc_time_formatISO8601ms(&ns_g_configtime, - configtime, sizeof configtime); - isc_time_formatISO8601ms(&now, nowstr, sizeof(nowstr)); - - obj = json_object_new_string(boottime); - CHECKMEM(obj); - json_object_object_add(bindstats, "boot-time", obj); - - obj = json_object_new_string(configtime); - CHECKMEM(obj); - json_object_object_add(bindstats, "config-time", obj); - - obj = json_object_new_string(nowstr); - CHECKMEM(obj); - json_object_object_add(bindstats, "current-time", obj); - obj = json_object_new_string(ns_g_version); - CHECKMEM(obj); - json_object_object_add(bindstats, "version", obj); - - if ((flags & STATS_JSON_SERVER) != 0) { - /* OPCODE counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - - dns_opcodestats_dump(server->opcodestats, - opcodestat_dump, &dumparg, - ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "opcodes", counters); - else - json_object_put(counters); - - /* OPCODE counters */ - counters = json_object_new_object(); - - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "rcodes", counters); - else - json_object_put(counters); - - /* QTYPE counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - dns_rdatatypestats_dump(server->rcvquerystats, - rdtypestat_dump, &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "qtypes", counters); - else - json_object_put(counters); - - /* server stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->nsstats, isc_statsformat_json, - counters, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "nsstats", counters); - else - json_object_put(counters); - - /* zone stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->zonestats, isc_statsformat_json, - counters, NULL, zonestats_xmldesc, - dns_zonestatscounter_max, - zonestats_index, zonestat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "zonestats", - counters); - else - json_object_put(counters); - - /* resolver stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->resolverstats, - isc_statsformat_json, counters, NULL, - resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "resstats", counters); - else - json_object_put(counters); - -#ifdef HAVE_DNSTAP - /* dnstap stat counters */ - if (ns_g_server->dtenv != NULL) { - isc_stats_t *dnstapstats = NULL; - dns_dt_getstats(ns_g_server->dtenv, &dnstapstats); - counters = json_object_new_object(); - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - result = dump_counters(dnstapstats, - isc_statsformat_json, counters, - NULL, dnstapstats_xmldesc, - dns_dnstapcounter_max, - dnstapstats_index, - dnstapstat_values, 0); - isc_stats_detach(&dnstapstats); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, - "dnstapstats", - counters); - else - json_object_put(counters); - } -#endif - } - - if ((flags & (STATS_JSON_ZONES | STATS_JSON_SERVER)) != 0) { - viewlist = json_object_new_object(); - CHECKMEM(viewlist); - - json_object_object_add(bindstats, "views", viewlist); - - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - json_object *za, *v = json_object_new_object(); - - CHECKMEM(v); - json_object_object_add(viewlist, view->name, v); - - za = json_object_new_array(); - CHECKMEM(za); - - if ((flags & STATS_JSON_ZONES) != 0) { - result = dns_zt_apply(view->zonetable, true, - zone_jsonrender, za); - if (result != ISC_R_SUCCESS) { - goto error; - } - } - - if (json_object_array_length(za) != 0) - json_object_object_add(v, "zones", za); - else - json_object_put(za); - - if ((flags & STATS_JSON_SERVER) != 0) { - json_object *res; - dns_stats_t *dstats; - isc_stats_t *istats; - - res = json_object_new_object(); - CHECKMEM(res); - json_object_object_add(v, "resolver", res); - - istats = view->resstats; - if (istats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dump_counters(istats, - isc_statsformat_json, - counters, NULL, - resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, - resstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "stats", - counters); - } - - dstats = view->resquerystats; - if (dstats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(dstats, - rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "qtypes", - counters); - } - - dstats = dns_db_getrrsetstats(view->cachedb); - if (dstats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatasetstats_dump(dstats, - rdatasetstats_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, - "cache", - counters); - } - - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dns_cache_renderjson(view->cache, - counters); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - json_object_object_add(res, "cachestats", - counters); - - istats = view->adbstats; - if (istats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dump_counters(istats, - isc_statsformat_json, - counters, NULL, - adbstats_xmldesc, - dns_adbstats_max, - adbstats_index, - adbstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "adb", - counters); - } - } - - view = ISC_LIST_NEXT(view, link); - } - } - - if ((flags & STATS_JSON_NET) != 0) { - /* socket stat counters */ - json_object *sockets; - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->sockstats, - isc_statsformat_json, counters, - NULL, sockstats_xmldesc, - isc_sockstatscounter_max, - sockstats_index, sockstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "sockstats", - counters); - else - json_object_put(counters); - - sockets = json_object_new_object(); - CHECKMEM(sockets); - - result = isc_socketmgr_renderjson(ns_g_socketmgr, sockets); - if (result != ISC_R_SUCCESS) { - json_object_put(sockets); - goto error; - } - - json_object_object_add(bindstats, "socketmgr", sockets); - } - - if ((flags & STATS_JSON_TASKS) != 0) { - json_object *tasks = json_object_new_object(); - CHECKMEM(tasks); - - result = isc_taskmgr_renderjson(ns_g_taskmgr, tasks); - if (result != ISC_R_SUCCESS) { - json_object_put(tasks); - goto error; - } - - json_object_object_add(bindstats, "taskmgr", tasks); - } - - if ((flags & STATS_JSON_MEM) != 0) { - json_object *memory = json_object_new_object(); - CHECKMEM(memory); - - result = isc_mem_renderjson(memory); - if (result != ISC_R_SUCCESS) { - json_object_put(memory); - goto error; - } - - json_object_object_add(bindstats, "memory", memory); - } - - if ((flags & STATS_JSON_TRAFFIC) != 0) { - - traffic = json_object_new_object(); - CHECKMEM(traffic); - - udpreq4 = json_object_new_object(); - CHECKMEM(udpreq4); - - udpresp4 = json_object_new_object(); - CHECKMEM(udpresp4); - - tcpreq4 = json_object_new_object(); - CHECKMEM(tcpreq4); - - tcpresp4 = json_object_new_object(); - CHECKMEM(tcpresp4); - - udpreq6 = json_object_new_object(); - CHECKMEM(udpreq6); - - udpresp6 = json_object_new_object(); - CHECKMEM(udpresp6); - - tcpreq6 = json_object_new_object(); - CHECKMEM(tcpreq6); - - tcpresp6 = json_object_new_object(); - CHECKMEM(tcpresp6); - - CHECK(dump_counters(server->udpinstats4, - isc_statsformat_json, udpreq4, NULL, - udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0)); - - CHECK(dump_counters(server->udpoutstats4, - isc_statsformat_json, udpresp4, NULL, - udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0)); - - CHECK(dump_counters(server->tcpinstats4, - isc_statsformat_json, tcpreq4, NULL, - tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0)); - - CHECK(dump_counters(server->tcpoutstats4, - isc_statsformat_json, tcpresp4, NULL, - tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0)); - - CHECK(dump_counters(server->udpinstats6, - isc_statsformat_json, udpreq6, NULL, - udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0)); - - CHECK(dump_counters(server->udpoutstats6, - isc_statsformat_json, udpresp6, NULL, - udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0)); - - CHECK(dump_counters(server->tcpinstats6, - isc_statsformat_json, tcpreq6, NULL, - tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0)); - - CHECK(dump_counters(server->tcpoutstats6, - isc_statsformat_json, tcpresp6, NULL, - tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0)); - - json_object_object_add(traffic, - "dns-udp-requests-sizes-received-ipv4", - udpreq4); - json_object_object_add(traffic, - "dns-udp-responses-sizes-sent-ipv4", - udpresp4); - json_object_object_add(traffic, - "dns-tcp-requests-sizes-received-ipv4", - tcpreq4); - json_object_object_add(traffic, - "dns-tcp-responses-sizes-sent-ipv4", - tcpresp4); - json_object_object_add(traffic, - "dns-udp-requests-sizes-received-ipv6", - udpreq6); - json_object_object_add(traffic, - "dns-udp-responses-sizes-sent-ipv6", - udpresp6); - json_object_object_add(traffic, - "dns-tcp-requests-sizes-received-ipv6", - tcpreq6); - json_object_object_add(traffic, - "dns-tcp-responses-sizes-sent-ipv6", - tcpresp6); - json_object_object_add(bindstats, "traffic", traffic); - udpreq4 = NULL; - udpresp4 = NULL; - tcpreq4 = NULL; - tcpresp4 = NULL; - udpreq6 = NULL; - udpresp6 = NULL; - tcpreq6 = NULL; - tcpresp6 = NULL; - traffic = NULL; - } - - *msg = json_object_to_json_string_ext(bindstats, - JSON_C_TO_STRING_PRETTY); - *msglen = strlen(*msg); - - if (rootp != NULL) { - *rootp = bindstats; - bindstats = NULL; - } - - result = ISC_R_SUCCESS; - - error: - if (udpreq4 != NULL) - json_object_put(udpreq4); - if (udpresp4 != NULL) - json_object_put(udpresp4); - if (tcpreq4 != NULL) - json_object_put(tcpreq4); - if (tcpresp4 != NULL) - json_object_put(tcpresp4); - if (udpreq6 != NULL) - json_object_put(udpreq6); - if (udpresp6 != NULL) - json_object_put(udpresp6); - if (tcpreq6 != NULL) - json_object_put(tcpreq6); - if (tcpresp6 != NULL) - json_object_put(tcpresp6); - if (traffic != NULL) - json_object_put(traffic); - if (bindstats != NULL) - json_object_put(bindstats); - - return (result); -} - -static isc_result_t -render_json(uint32_t flags, - const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, - void *arg, unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - isc_result_t result; - json_object *bindstats = NULL; - ns_server_t *server = arg; - const char *msg = NULL; - size_t msglen = 0; - char *p; - - UNUSED(url); - UNUSED(urlinfo); - UNUSED(headers); - UNUSED(querystring); - - result = generatejson(server, &msglen, &msg, &bindstats, flags); - if (result == ISC_R_SUCCESS) { - *retcode = 200; - *retmsg = "OK"; - *mimetype = "application/json"; - DE_CONST(msg, p); - isc_buffer_reinit(b, p, msglen); - isc_buffer_add(b, msglen); - *freecb = wrap_jsonfree; - *freecb_args = bindstats; - } else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed at rendering JSON()"); - - return (result); -} - -static isc_result_t -render_json_all(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_ALL, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_status(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_STATUS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_server(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_SERVER, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_zones(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_ZONES, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_mem(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_MEM, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_tasks(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_TASKS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_net(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_NET, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_traffic(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_TRAFFIC, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -#endif /* HAVE_JSON */ - -static isc_result_t -render_xsl(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, - void *args, unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - isc_result_t result; - - UNUSED(url); - UNUSED(querystring); - UNUSED(args); - - *freecb = NULL; - *freecb_args = NULL; - *mimetype = "text/xslt+xml"; - - if (urlinfo->isstatic) { - isc_time_t when; - char *p = strcasestr(headers, "If-Modified-Since: "); - - if (p != NULL) { - time_t t1, t2; - p += strlen("If-Modified-Since: "); - result = isc_time_parsehttptimestamp(p, &when); - if (result != ISC_R_SUCCESS) - goto send; - - result = isc_time_secondsastimet(&when, &t1); - if (result != ISC_R_SUCCESS) - goto send; - - result = isc_time_secondsastimet(&urlinfo->loadtime, - &t2); - if (result != ISC_R_SUCCESS) - goto send; - - if (t1 < t2) - goto send; - - *retcode = 304; - *retmsg = "Not modified"; - return (ISC_R_SUCCESS); - } - } - - send: - *retcode = 200; - *retmsg = "OK"; - isc_buffer_reinit(b, xslmsg, strlen(xslmsg)); - isc_buffer_add(b, strlen(xslmsg)); - - return (ISC_R_SUCCESS); -} - -static void -shutdown_listener(ns_statschannel_t *listener) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "stopping statistics channel on %s", - socktext); - - isc_httpdmgr_shutdown(&listener->httpdmgr); -} - -static bool -client_ok(const isc_sockaddr_t *fromaddr, void *arg) { - ns_statschannel_t *listener = arg; - isc_netaddr_t netaddr; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - int match; - - REQUIRE(listener != NULL); - - isc_netaddr_fromsockaddr(&netaddr, fromaddr); - - LOCK(&listener->lock); - if (dns_acl_match(&netaddr, NULL, listener->acl, &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && match > 0) { - UNLOCK(&listener->lock); - return (true); - } - UNLOCK(&listener->lock); - - isc_sockaddr_format(fromaddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "rejected statistics connection from %s", socktext); - - return (false); -} - -static void -destroy_listener(void *arg) { - ns_statschannel_t *listener = arg; - - REQUIRE(listener != NULL); - REQUIRE(!ISC_LINK_LINKED(listener, link)); - - /* We don't have to acquire the lock here since it's already unlinked */ - dns_acl_detach(&listener->acl); - - DESTROYLOCK(&listener->lock); - isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); -} - -static isc_result_t -add_listener(ns_server_t *server, ns_statschannel_t **listenerp, - const cfg_obj_t *listen_params, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext) -{ - isc_result_t result; - ns_statschannel_t *listener; - isc_task_t *task = NULL; - isc_socket_t *sock = NULL; - const cfg_obj_t *allow; - dns_acl_t *new_acl = NULL; - - listener = isc_mem_get(server->mctx, sizeof(*listener)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - listener->httpdmgr = NULL; - listener->address = *addr; - listener->acl = NULL; - listener->mctx = NULL; - ISC_LINK_INIT(listener, link); - - result = isc_mutex_init(&listener->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, listener, sizeof(*listener)); - return (ISC_R_FAILURE); - } - - isc_mem_attach(server->mctx, &listener->mctx); - - allow = cfg_tuple_get(listen_params, "allow"); - if (allow != NULL && cfg_obj_islist(allow)) { - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else - result = dns_acl_any(listener->mctx, &new_acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - result = isc_task_create(ns_g_taskmgr, 0, &task); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_task_setname(task, "statchannel", NULL); - - result = isc_socket_create(ns_g_socketmgr, isc_sockaddr_pf(addr), - isc_sockettype_tcp, &sock); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_socket_setname(sock, "statchannel", NULL); - -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(sock, true); -#endif - - result = isc_socket_bind(sock, addr, ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_httpdmgr_create(server->mctx, sock, task, client_ok, - destroy_listener, listener, ns_g_timermgr, - &listener->httpdmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; - -#ifdef HAVE_LIBXML2 - isc_httpdmgr_addurl(listener->httpdmgr, "/", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/status", - render_xml_status, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/server", - render_xml_server, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/zones", - render_xml_zones, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/net", - render_xml_net, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/tasks", - render_xml_tasks, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/mem", - render_xml_mem, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/traffic", - render_xml_traffic, server); -#endif -#ifdef HAVE_JSON - isc_httpdmgr_addurl(listener->httpdmgr, "/json", - render_json_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1", - render_json_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/status", - render_json_status, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/server", - render_json_server, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/zones", - render_json_zones, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/tasks", - render_json_tasks, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/net", - render_json_net, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/mem", - render_json_mem, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/traffic", - render_json_traffic, server); -#endif - isc_httpdmgr_addurl2(listener->httpdmgr, "/bind9.xsl", true, - render_xsl, server); - - *listenerp = listener; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, - "statistics channel listening on %s", socktext); - -cleanup: - if (result != ISC_R_SUCCESS) { - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - DESTROYLOCK(&listener->lock); - isc_mem_putanddetach(&listener->mctx, listener, - sizeof(*listener)); - } - if (task != NULL) - isc_task_detach(&task); - if (sock != NULL) - isc_socket_detach(&sock); - - return (result); -} - -static void -update_listener(ns_server_t *server, ns_statschannel_t **listenerp, - const cfg_obj_t *listen_params, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext) -{ - ns_statschannel_t *listener; - const cfg_obj_t *allow = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(server->statschannels); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * Now, keep the old access list unless a new one can be made. - */ - allow = cfg_tuple_get(listen_params, "allow"); - if (allow != NULL && cfg_obj_islist(allow)) { - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else - result = dns_acl_any(listener->mctx, &new_acl); - - if (result == ISC_R_SUCCESS) { - LOCK(&listener->lock); - - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - UNLOCK(&listener->lock); - } else { - cfg_obj_log(listen_params, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "statistics channel %s: %s", - socktext, isc_result_totext(result)); - } - - *listenerp = listener; -} - -isc_result_t -ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx) -{ - ns_statschannel_t *listener, *listener_next; - ns_statschannellist_t new_listeners; - const cfg_obj_t *statschannellist = NULL; - const cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS); - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'statistics-channels' statements. - */ - (void)cfg_map_get(config, "statistics-channels", &statschannellist); - - /* - * Run through the new address/port list, noting sockets that are - * already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (statschannellist != NULL) { -#ifndef EXTENDED_STATS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels specified but not effective " - "due to missing XML and/or JSON library"); -#else /* EXTENDED_STATS */ -#ifndef HAVE_LIBXML2 - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels: XML library missing, " - "only JSON stats will be available"); -#endif /* !HAVE_LIBXML2 */ -#ifndef HAVE_JSON - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels: JSON library missing, " - "only XML stats will be available"); -#endif /* !HAVE_JSON */ -#endif /* EXTENDED_STATS */ - - for (element = cfg_list_first(statschannellist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *statschannel; - const cfg_obj_t *listenercfg = NULL; - - statschannel = cfg_listelt_value(element); - (void)cfg_map_get(statschannel, "inet", - &listenercfg); - if (listenercfg == NULL) - continue; - - for (element2 = cfg_list_first(listenercfg); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *listen_params; - const cfg_obj_t *obj; - isc_sockaddr_t addr; - - listen_params = cfg_listelt_value(element2); - - obj = cfg_tuple_get(listen_params, "address"); - addr = *cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, - NS_STATSCHANNEL_HTTPPORT); - - isc_sockaddr_format(&addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(9), - "processing statistics " - "channel %s", - socktext); - - update_listener(server, &listener, - listen_params, config, &addr, - aclconfctx, socktext); - - if (listener != NULL) { - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(server->statschannels, - listener, link); - } else { - /* - * This is a new listener. - */ - isc_result_t r; - - r = add_listener(server, &listener, - listen_params, config, - &addr, aclconfctx, - socktext); - if (r != ISC_R_SUCCESS) { - cfg_obj_log(listen_params, - ns_g_lctx, - ISC_LOG_WARNING, - "couldn't allocate " - "statistics channel" - " %s: %s", - socktext, - isc_result_totext(r)); - } - } - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, listener, - link); - } - } - } - - for (listener = ISC_LIST_HEAD(server->statschannels); - listener != NULL; - listener = listener_next) { - listener_next = ISC_LIST_NEXT(listener, link); - ISC_LIST_UNLINK(server->statschannels, listener, link); - shutdown_listener(listener); - } - - ISC_LIST_APPENDLIST(server->statschannels, new_listeners, link); - return (ISC_R_SUCCESS); -} - -void -ns_statschannels_shutdown(ns_server_t *server) { - ns_statschannel_t *listener; - - while ((listener = ISC_LIST_HEAD(server->statschannels)) != NULL) { - ISC_LIST_UNLINK(server->statschannels, listener, link); - shutdown_listener(listener); - } -} - -isc_result_t -ns_stats_dump(ns_server_t *server, FILE *fp) { - isc_stdtime_t now; - isc_result_t result; - dns_view_t *view; - dns_zone_t *zone, *next; - stats_dumparg_t dumparg; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - - RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS); - - /* Set common fields */ - dumparg.type = isc_statsformat_file; - dumparg.arg = fp; - - isc_stdtime_get(&now); - fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now); - - fprintf(fp, "++ Incoming Requests ++\n"); - dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); - - fprintf(fp, "++ Incoming Queries ++\n"); - dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, - &dumparg, 0); - - fprintf(fp, "++ Outgoing Rcodes ++\n"); - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, &dumparg, 0); - - fprintf(fp, "++ Outgoing Queries ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->resquerystats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump, - &dumparg, 0); - } - - fprintf(fp, "++ Name Server Statistics ++\n"); - (void) dump_counters(server->nsstats, isc_statsformat_file, fp, NULL, - nsstats_desc, dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - - fprintf(fp, "++ Zone Maintenance Statistics ++\n"); - (void) dump_counters(server->zonestats, isc_statsformat_file, fp, NULL, - zonestats_desc, dns_zonestatscounter_max, - zonestats_index, zonestat_values, 0); - - fprintf(fp, "++ Resolver Statistics ++\n"); - fprintf(fp, "[Common]\n"); - (void) dump_counters(server->resolverstats, isc_statsformat_file, fp, - NULL, resstats_desc, dns_resstatscounter_max, - resstats_index, resstat_values, 0); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->resstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - (void) dump_counters(view->resstats, isc_statsformat_file, fp, - NULL, resstats_desc, - dns_resstatscounter_max, resstats_index, - resstat_values, 0); - } - - fprintf(fp, "++ Cache Statistics ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s (Cache: %s)]\n", view->name, - dns_cache_getname(view->cache)); - /* - * Avoid dumping redundant statistics when the cache is shared. - */ - if (dns_view_iscacheshared(view)) - continue; - dns_cache_dumpstats(view->cache, fp); - } - - fprintf(fp, "++ Cache DB RRsets ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_stats_t *cacherrstats; - - cacherrstats = dns_db_getrrsetstats(view->cachedb); - if (cacherrstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s (Cache: %s)]\n", view->name, - dns_cache_getname(view->cache)); - if (dns_view_iscacheshared(view)) { - /* - * Avoid dumping redundant statistics when the cache is - * shared. - */ - continue; - } - dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump, - &dumparg, 0); - } - - fprintf(fp, "++ ADB stats ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->adbstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - (void) dump_counters(view->adbstats, isc_statsformat_file, fp, - NULL, adbstats_desc, dns_adbstats_max, - adbstats_index, adbstat_values, 0); - } - - fprintf(fp, "++ Socket I/O Statistics ++\n"); - (void) dump_counters(server->sockstats, isc_statsformat_file, fp, NULL, - sockstats_desc, isc_sockstatscounter_max, - sockstats_index, sockstat_values, 0); - - fprintf(fp, "++ Per Zone Query Statistics ++\n"); - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) - { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) { - char zonename[DNS_NAME_FORMATSIZE]; - - view = dns_zone_getview(zone); - if (view == NULL) - continue; - - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - fprintf(fp, "[%s", zonename); - if (strcmp(view->name, "_default") != 0) - fprintf(fp, " (view: %s)", view->name); - fprintf(fp, "]\n"); - - (void) dump_counters(zonestats, isc_statsformat_file, - fp, NULL, nsstats_desc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - } - } - - fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now); - - return (ISC_R_SUCCESS); /* this function currently always succeeds */ -} diff --git a/bin/named-pkcs11/tkeyconf.c b/bin/named-pkcs11/tkeyconf.c deleted file mode 100644 index a65a94a..0000000 --- a/bin/named-pkcs11/tkeyconf.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include - -#include -#include -#include -#include - -#include - -#include - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -#include -#define LOG(msg) \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s", msg) - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) -{ - isc_result_t result; - dns_tkeyctx_t *tctx = NULL; - const char *s; - uint32_t n; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - const cfg_obj_t *obj; - int type; - - result = dns_tkeyctx_create(mctx, ectx, &tctx); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(options, "tkey-dhkey", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; - RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, - type, NULL, mctx, &tctx->dhkey)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-domain", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); - if (tctx->domain == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(tctx->domain, NULL); - RETERR(dns_name_dup(name, mctx, tctx->domain)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-credential", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - RETERR(dst_gssapi_acquirecred(name, false, &tctx->gsscred)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-keytab", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - tctx->gssapi_keytab = isc_mem_strdup(mctx, s); - if (tctx->gssapi_keytab == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - } - - *tctxp = tctx; - return (ISC_R_SUCCESS); - - failure: - dns_tkeyctx_destroy(&tctx); - return (result); -} - diff --git a/bin/named-pkcs11/tsigconf.c b/bin/named-pkcs11/tsigconf.c deleted file mode 100644 index 7d732a5..0000000 --- a/bin/named-pkcs11/tsigconf.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -static isc_result_t -add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, - isc_mem_t *mctx) -{ - dns_tsigkey_t *tsigkey = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *key = NULL; - const char *keyid = NULL; - unsigned char *secret = NULL; - int secretalloc = 0; - int secretlen = 0; - isc_result_t ret; - isc_stdtime_t now; - uint16_t bits; - - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - dns_name_t keyname; - dns_name_t *alg; - const char *algstr; - char keynamedata[1024]; - isc_buffer_t keynamesrc, keynamebuf; - const char *secretstr; - isc_buffer_t secretbuf; - - key = cfg_listelt_value(element); - keyid = cfg_obj_asstring(cfg_map_getname(key)); - - algobj = NULL; - secretobj = NULL; - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - /* - * Create the key name. - */ - dns_name_init(&keyname, NULL); - isc_buffer_constinit(&keynamesrc, keyid, strlen(keyid)); - isc_buffer_add(&keynamesrc, strlen(keyid)); - isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); - ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, - DNS_NAME_DOWNCASE, &keynamebuf); - if (ret != ISC_R_SUCCESS) - goto failure; - - /* - * Create the algorithm. - */ - algstr = cfg_obj_asstring(algobj); - if (ns_config_getkeyalgorithm(algstr, &alg, &bits) - != ISC_R_SUCCESS) { - cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, - "key '%s': has a unsupported algorithm '%s'", - keyid, algstr); - ret = DNS_R_BADALG; - goto failure; - } - - secretstr = cfg_obj_asstring(secretobj); - secretalloc = secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_get(mctx, secretlen); - if (secret == NULL) { - ret = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&secretbuf, secret, secretlen); - ret = isc_base64_decodestring(secretstr, &secretbuf); - if (ret != ISC_R_SUCCESS) - goto failure; - secretlen = isc_buffer_usedlength(&secretbuf); - - isc_stdtime_get(&now); - ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, - false, NULL, now, now, - mctx, ring, &tsigkey); - isc_mem_put(mctx, secret, secretalloc); - secret = NULL; - if (ret != ISC_R_SUCCESS) - goto failure; - /* - * Set digest bits. - */ - dst_key_setbits(tsigkey->key, bits); - dns_tsigkey_detach(&tsigkey); - } - - return (ISC_R_SUCCESS); - - failure: - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring key '%s': %s", keyid, - isc_result_totext(ret)); - - if (secret != NULL) - isc_mem_put(mctx, secret, secretalloc); - return (ret); -} - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp) -{ - const cfg_obj_t *maps[3]; - const cfg_obj_t *keylist; - dns_tsig_keyring_t *ring = NULL; - isc_result_t result; - int i; - - REQUIRE(ringp != NULL && *ringp == NULL); - - i = 0; - if (config != NULL) - maps[i++] = config; - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - maps[i] = NULL; - - result = dns_tsigkeyring_create(mctx, &ring); - if (result != ISC_R_SUCCESS) - return (result); - - for (i = 0; ; i++) { - if (maps[i] == NULL) - break; - keylist = NULL; - result = cfg_map_get(maps[i], "key", &keylist); - if (result != ISC_R_SUCCESS) - continue; - result = add_initial_keys(keylist, ring, mctx); - if (result != ISC_R_SUCCESS) - goto failure; - } - - *ringp = ring; - return (ISC_R_SUCCESS); - - failure: - dns_tsigkeyring_detach(&ring); - return (result); -} diff --git a/bin/named-pkcs11/unix/Makefile.in b/bin/named-pkcs11/unix/Makefile.in deleted file mode 100644 index 1498222..0000000 --- a/bin/named-pkcs11/unix/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -EXT_CFLAGS = -fpie - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} \ - ${DNS_INCLUDES} ${ISC_INCLUDES} @DST_OPENSSL_INC@ - -CDEFINES = @CRYPTO@ -CWARNINGS = - -OBJS = os.@O@ dlz_dlopen_driver.@O@ - -SRCS = os.c dlz_dlopen_driver.c - -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ diff --git a/bin/named-pkcs11/unix/dlz_dlopen_driver.c b/bin/named-pkcs11/unix/dlz_dlopen_driver.c deleted file mode 100644 index 398df91..0000000 --- a/bin/named-pkcs11/unix/dlz_dlopen_driver.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include -#include -#include -#include -#if HAVE_DLFCN_H -#include -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#ifdef ISC_DLZ_DLOPEN -static dns_sdlzimplementation_t *dlz_dlopen = NULL; - - -typedef struct dlopen_data { - isc_mem_t *mctx; - char *dl_path; - char *dlzname; - void *dl_handle; - void *dbdata; - unsigned int flags; - isc_mutex_t lock; - int version; - bool in_configure; - - dlz_dlopen_version_t *dlz_version; - dlz_dlopen_create_t *dlz_create; - dlz_dlopen_findzonedb_t *dlz_findzonedb; - dlz_dlopen_lookup_t *dlz_lookup; - dlz_dlopen_authority_t *dlz_authority; - dlz_dlopen_allnodes_t *dlz_allnodes; - dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr; - dlz_dlopen_newversion_t *dlz_newversion; - dlz_dlopen_closeversion_t *dlz_closeversion; - dlz_dlopen_configure_t *dlz_configure; - dlz_dlopen_ssumatch_t *dlz_ssumatch; - dlz_dlopen_addrdataset_t *dlz_addrdataset; - dlz_dlopen_subrdataset_t *dlz_subrdataset; - dlz_dlopen_delrdataset_t *dlz_delrdataset; - dlz_dlopen_destroy_t *dlz_destroy; -} dlopen_data_t; - -/* Modules can choose whether they are lock-safe or not. */ -#define MAYBE_LOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - LOCK(&cd->lock); \ - } while (0) - -#define MAYBE_UNLOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - UNLOCK(&cd->lock); \ - } while (0) - -/* - * Log a message at the given level. - */ -static void dlopen_log(int level, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), - fmt, ap); - va_end(ap); -} - -/* - * SDLZ methods - */ - -static isc_result_t -dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata, - dns_sdlzallnodes_t *allnodes) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - - UNUSED(driverarg); - - if (cd->dlz_allnodes == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allnodes(zone, cd->dbdata, allnodes); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, - const char *client) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - - if (cd->dlz_allowzonexfr == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allowzonexfr(cd->dbdata, name, client); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_authority == NULL) { - return (ISC_R_NOTIMPLEMENTED); - } - - MAYBE_LOCK(cd); - result = cd->dlz_authority(zone, cd->dbdata, lookup); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, - methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Load a symbol from the library - */ -static void * -dl_load_symbol(dlopen_data_t *cd, const char *symbol, bool mandatory) { - void *ptr = dlsym(cd->dl_handle, symbol); - if (ptr == NULL && mandatory) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: library '%s' is missing " - "required symbol '%s'", cd->dl_path, symbol); - } - return (ptr); -} - -/* - * Called at startup for each dlopen zone in named.conf - */ -static isc_result_t -dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], - void *driverarg, void **dbdata) -{ - dlopen_data_t *cd; - isc_mem_t *mctx = NULL; - isc_result_t result = ISC_R_FAILURE; - int dlopen_flags = 0; - - UNUSED(driverarg); - - if (argc < 2) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen driver for '%s' needs a path to " - "the shared library", dlzname); - return (ISC_R_FAILURE); - } - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - - cd = isc_mem_get(mctx, sizeof(*cd)); - if (cd == NULL) { - isc_mem_destroy(&mctx); - return (ISC_R_NOMEMORY); - } - memset(cd, 0, sizeof(*cd)); - - cd->mctx = mctx; - - cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]); - if (cd->dl_path == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - cd->dlzname = isc_mem_strdup(cd->mctx, dlzname); - if (cd->dlzname == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - /* Initialize the lock */ - result = isc_mutex_init(&cd->lock); - if (result != ISC_R_SUCCESS) - goto failed; - - /* Open the library */ - dlopen_flags = RTLD_NOW|RTLD_GLOBAL; - -#if defined(RTLD_DEEPBIND) && !__SANITIZE_ADDRESS__ - /* - * If RTLD_DEEPBIND is available then use it. This can avoid - * issues with a module using a different version of a system - * library than one that bind9 uses. For example, bind9 may link - * to MIT kerberos, but the module may use Heimdal. If we don't - * use RTLD_DEEPBIND then we could end up with Heimdal functions - * calling MIT functions, which leads to bizarre results (usually - * a segfault). - */ - dlopen_flags |= RTLD_DEEPBIND; -#endif - - cd->dl_handle = dlopen(cd->dl_path, dlopen_flags); - if (cd->dl_handle == NULL) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen failed to open library '%s' - %s", - cd->dl_path, dlerror()); - result = ISC_R_FAILURE; - goto failed; - } - - /* Find the symbols */ - cd->dlz_version = (dlz_dlopen_version_t *) - dl_load_symbol(cd, "dlz_version", true); - cd->dlz_create = (dlz_dlopen_create_t *) - dl_load_symbol(cd, "dlz_create", true); - cd->dlz_lookup = (dlz_dlopen_lookup_t *) - dl_load_symbol(cd, "dlz_lookup", true); - cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *) - dl_load_symbol(cd, "dlz_findzonedb", true); - - if (cd->dlz_create == NULL || - cd->dlz_version == NULL || - cd->dlz_lookup == NULL || - cd->dlz_findzonedb == NULL) - { - /* We're missing a required symbol */ - result = ISC_R_FAILURE; - goto failed; - } - - cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *) - dl_load_symbol(cd, "dlz_allowzonexfr", false); - cd->dlz_allnodes = (dlz_dlopen_allnodes_t *) - dl_load_symbol(cd, "dlz_allnodes", - (cd->dlz_allowzonexfr != NULL)); - cd->dlz_authority = (dlz_dlopen_authority_t *) - dl_load_symbol(cd, "dlz_authority", false); - cd->dlz_newversion = (dlz_dlopen_newversion_t *) - dl_load_symbol(cd, "dlz_newversion", false); - cd->dlz_closeversion = (dlz_dlopen_closeversion_t *) - dl_load_symbol(cd, "dlz_closeversion", - (cd->dlz_newversion != NULL)); - cd->dlz_configure = (dlz_dlopen_configure_t *) - dl_load_symbol(cd, "dlz_configure", false); - cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *) - dl_load_symbol(cd, "dlz_ssumatch", false); - cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *) - dl_load_symbol(cd, "dlz_addrdataset", false); - cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *) - dl_load_symbol(cd, "dlz_subrdataset", false); - cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *) - dl_load_symbol(cd, "dlz_delrdataset", false); - cd->dlz_destroy = (dlz_dlopen_destroy_t *) - dl_load_symbol(cd, "dlz_destroy", false); - - /* Check the version of the API is the same */ - cd->version = cd->dlz_version(&cd->flags); - if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) || - cd->version > DLZ_DLOPEN_VERSION) - { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: %s: incorrect driver API version %d, " - "requires %d", - cd->dl_path, cd->version, DLZ_DLOPEN_VERSION); - result = ISC_R_FAILURE; - goto failed; - } - - /* - * Call the library's create function. Note that this is an - * extended version of dlz create, with the addition of - * named function pointers for helper functions that the - * driver will need. This avoids the need for the backend to - * link the BIND9 libraries - */ - MAYBE_LOCK(cd); - result = cd->dlz_create(dlzname, argc-1, argv+1, - &cd->dbdata, - "log", dlopen_log, - "putrr", dns_sdlz_putrr, - "putnamedrr", dns_sdlz_putnamedrr, - "writeable_zone", dns_dlz_writeablezone, - NULL); - MAYBE_UNLOCK(cd); - if (result != ISC_R_SUCCESS) - goto failed; - - *dbdata = cd; - - return (ISC_R_SUCCESS); - -failed: - dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname); - if (cd->dl_path != NULL) - isc_mem_free(mctx, cd->dl_path); - if (cd->dlzname != NULL) - isc_mem_free(mctx, cd->dlzname); - if (dlopen_flags != 0) - (void) isc_mutex_destroy(&cd->lock); -#ifdef HAVE_DLCLOSE - if (cd->dl_handle) - dlclose(cd->dl_handle); -#endif - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); - return (result); -} - -/* - * Called when bind is shutting down - */ -static void -dlopen_dlz_destroy(void *driverarg, void *dbdata) { - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_mem_t *mctx; - - UNUSED(driverarg); - - if (cd->dlz_destroy) { - MAYBE_LOCK(cd); - cd->dlz_destroy(cd->dbdata); - MAYBE_UNLOCK(cd); - } - - if (cd->dl_path) - isc_mem_free(cd->mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(cd->mctx, cd->dlzname); - -#ifdef HAVE_DLCLOSE - if (cd->dl_handle) - dlclose(cd->dl_handle); -#endif - - (void) isc_mutex_destroy(&cd->lock); - - mctx = cd->mctx; - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); -} - -/* - * Called to start a transaction - */ -static isc_result_t -dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata, - void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_newversion(zone, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Called to end a transaction - */ -static void -dlopen_dlz_closeversion(const char *zone, bool commit, - void *driverarg, void *dbdata, void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) { - *versionp = NULL; - return; - } - - MAYBE_LOCK(cd); - cd->dlz_closeversion(zone, commit, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); -} - -/* - * Called on startup to configure any writeable zones - */ -static isc_result_t -dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, - void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_configure == NULL) - return (ISC_R_SUCCESS); - - MAYBE_LOCK(cd); - cd->in_configure = true; - result = cd->dlz_configure(view, dlzdb, cd->dbdata); - cd->in_configure = false; - MAYBE_UNLOCK(cd); - - return (result); -} - - -/* - * Check for authority to change a name. - */ -static bool -dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, - const char *type, const char *key, uint32_t keydatalen, - unsigned char *keydata, void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - bool ret; - - UNUSED(driverarg); - - if (cd->dlz_ssumatch == NULL) - return (false); - - MAYBE_LOCK(cd); - ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen, - keydata, cd->dbdata); - MAYBE_UNLOCK(cd); - - return (ret); -} - - -/* - * Add an rdataset. - */ -static isc_result_t -dlopen_dlz_addrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_addrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Subtract an rdataset. - */ -static isc_result_t -dlopen_dlz_subrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_subrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Delete a rdataset. - */ -static isc_result_t -dlopen_dlz_delrdataset(const char *name, const char *type, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_delrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_delrdataset(name, type, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - - -static dns_sdlzmethods_t dlz_dlopen_methods = { - dlopen_dlz_create, - dlopen_dlz_destroy, - dlopen_dlz_findzonedb, - dlopen_dlz_lookup, - dlopen_dlz_authority, - dlopen_dlz_allnodes, - dlopen_dlz_allowzonexfr, - dlopen_dlz_newversion, - dlopen_dlz_closeversion, - dlopen_dlz_configure, - dlopen_dlz_ssumatch, - dlopen_dlz_addrdataset, - dlopen_dlz_subrdataset, - dlopen_dlz_delrdataset -}; -#endif - -/* - * Register driver with BIND - */ -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx) { -#ifndef ISC_DLZ_DLOPEN - UNUSED(mctx); - return (ISC_R_NOTIMPLEMENTED); -#else - isc_result_t result; - - dlopen_log(2, "Registering DLZ_dlopen driver"); - - result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL, - DNS_SDLZFLAG_RELATIVEOWNER | - DNS_SDLZFLAG_RELATIVERDATA | - DNS_SDLZFLAG_THREADSAFE, - mctx, &dlz_dlopen); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_sdlzregister() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - } - - return (result); -#endif -} - - -/* - * Unregister the driver - */ -void -dlz_dlopen_clear(void) { -#ifdef ISC_DLZ_DLOPEN - dlopen_log(2, "Unregistering DLZ_dlopen driver"); - if (dlz_dlopen != NULL) - dns_sdlzunregister(&dlz_dlopen); -#endif -} diff --git a/bin/named-pkcs11/unix/include/named/os.h b/bin/named-pkcs11/unix/include/named/os.h deleted file mode 100644 index 87498b8..0000000 --- a/bin/named-pkcs11/unix/include/named/os.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -/*! \file */ - -#include -#include - -#include - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -uid_t -ns_os_uid(void); - -void -ns_os_adjustnofile(void); - -void -ns_os_minprivs(void); - -FILE * -ns_os_openfile(const char *filename, mode_t mode, bool switch_user); - -void -ns_os_writepidfile(const char *filename, bool first_time); - -bool -ns_os_issingleton(const char *filename); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -const char * -ns_os_uname(void); - -#endif /* NS_OS_H */ diff --git a/bin/named-pkcs11/unix/os.c b/bin/named-pkcs11/unix/os.c deleted file mode 100644 index 42c6276..0000000 --- a/bin/named-pkcs11/unix/os.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include -#include - -#include /* dev_t FreeBSD 2.1 */ -#include -#ifdef HAVE_UNAME -#include -#endif - -#include -#include -#include -#include /* Required for initgroups() on IRIX. */ -#include -#include -#include -#include -#include -#ifdef HAVE_TZSET -#include -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static char *pidfile = NULL; -static char *lockfile = NULL; -static int devnullfd = -1; -static int singletonfd = -1; - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/* - * If there's no , we don't care about - */ -#ifndef HAVE_LINUX_CAPABILITY_H -#undef HAVE_SYS_PRCTL_H -#endif - -/* - * Linux defines: - * (T) HAVE_LINUXTHREADS - * (C) HAVE_SYS_CAPABILITY_H (or HAVE_LINUX_CAPABILITY_H) - * (P) HAVE_SYS_PRCTL_H - * The possible cases are: - * none: setuid() normally - * T: no setuid() - * C: setuid() normally, drop caps (keep CAP_SETUID) - * T+C: no setuid(), drop caps (don't keep CAP_SETUID) - * T+C+P: setuid() early, drop caps (keep CAP_SETUID) - * C+P: setuid() normally, drop caps (keep CAP_SETUID) - * P: not possible - * T+P: not possible - * - * if (C) - * caps = BIND_SERVICE + CHROOT + SETGID - * if ((T && C && P) || !T) - * caps += SETUID - * endif - * capset(caps) - * endif - * if (T && C && P && -u) - * setuid() - * else if (T && -u) - * fail - * --> start threads - * if (!T && -u) - * setuid() - * if (C && (P || !-u)) - * caps = BIND_SERVICE - * capset(caps) - * endif - * - * It will be nice when Linux threads work properly with setuid(). - */ - -#ifdef HAVE_LINUXTHREADS -static pid_t mainpid = 0; -#endif - -static struct passwd *runas_pw = NULL; -static bool done_setuid = false; -static int dfd[2] = { -1, -1 }; - -#ifdef HAVE_LINUX_CAPABILITY_H - -static bool non_root = false; -static bool non_root_caps = false; - -#ifdef HAVE_SYS_CAPABILITY_H -#include -#else -#ifdef HAVE_LINUX_TYPES_H -#include -#endif -/*% - * We define _LINUX_FS_H to prevent it from being included. We don't need - * anything from it, and the files it includes cause warnings with 2.2 - * kernels, and compilation failures (due to conflicts between - * and ) on 2.3 kernels. - */ -#define _LINUX_FS_H -#include -#include -#ifndef SYS_capset -#ifndef __NR_capset -#include /* Slackware 4.0 needs this. */ -#endif /* __NR_capset */ -#define SYS_capset __NR_capset -#endif /* SYS_capset */ -#endif /* HAVE_SYS_CAPABILITY_H */ - -#ifdef HAVE_SYS_PRCTL_H -#include /* Required for prctl(). */ - -/* - * If the value of PR_SET_KEEPCAPS is not in , define it - * here. This allows setuid() to work on systems running a new enough - * kernel but with /usr/include/linux pointing to "standard" kernel - * headers. - */ -#ifndef PR_SET_KEEPCAPS -#define PR_SET_KEEPCAPS 8 -#endif - -#endif /* HAVE_SYS_PRCTL_H */ - -#ifdef HAVE_LIBCAP -#define SETCAPS_FUNC "cap_set_proc " -#else -typedef unsigned int cap_t; -#define SETCAPS_FUNC "syscall(capset) " -#endif /* HAVE_LIBCAP */ - -static void -linux_setcaps(cap_t caps) { -#ifndef HAVE_LIBCAP - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct cap; -#endif - char strbuf[ISC_STRERRORSIZE]; - - if ((getuid() != 0 && !non_root_caps) || non_root) - return; -#ifndef HAVE_LIBCAP - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&cap, 0, sizeof(cap)); - cap.effective = caps; - cap.permitted = caps; - cap.inheritable = 0; -#endif -#ifdef HAVE_LIBCAP - if (cap_set_proc(caps) < 0) { -#else - if (syscall(SYS_capset, &caphead, &cap) < 0) { -#endif - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal(SETCAPS_FUNC "failed: %s:" - " please ensure that the capset kernel" - " module is loaded. see insmod(8)", - strbuf); - } -} - -#ifdef HAVE_LIBCAP -#define SET_CAP(flag) \ - do { \ - cap_flag_value_t curval; \ - capval = (flag); \ - err = cap_get_flag(curcaps, capval, CAP_PERMITTED, &curval); \ - if (err != -1 && curval) { \ - err = cap_set_flag(caps, CAP_EFFECTIVE, 1, &capval, CAP_SET); \ - if (err == -1) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \ - } \ - \ - err = cap_set_flag(caps, CAP_PERMITTED, 1, &capval, CAP_SET); \ - if (err == -1) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \ - } \ - } \ - } while (0) -#define INIT_CAP \ - do { \ - caps = cap_init(); \ - if (caps == NULL) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_init failed: %s", strbuf); \ - } \ - curcaps = cap_get_proc(); \ - if (curcaps == NULL) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_get_proc failed: %s", strbuf); \ - } \ - } while (0) -#define FREE_CAP \ - { \ - cap_free(caps); \ - cap_free(curcaps); \ - } while (0) -#else -#define SET_CAP(flag) \ - do { \ - if (curcaps & (1 << (flag))) { \ - caps |= (1 << (flag)); \ - } \ - } while (0) -#define INIT_CAP do { caps = 0; } while (0) -#endif /* HAVE_LIBCAP */ - -#ifndef HAVE_LIBCAP -/*% - * Store the bitmask representing the permitted capability set in 'capsp'. To - * match libcap-enabled behavior, capget() syscall errors are not reported, - * they just cause 'capsp' to be set to 0, which effectively prevents any - * capability from being subsequently requested. - */ -static void -linux_getpermittedcaps(cap_t *capsp) { - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct curcaps; - - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&curcaps, 0, sizeof(curcaps)); - syscall(SYS_capget, &caphead, &curcaps); - - *capsp = curcaps.permitted; -} -#endif /* HAVE_LIBCAP */ - -static void -linux_initialprivs(void) { - cap_t curcaps; - cap_t caps; -#ifdef HAVE_LIBCAP - cap_value_t capval; - char strbuf[ISC_STRERRORSIZE]; - int err; -#else - linux_getpermittedcaps(&curcaps); -#endif - - /*% - * We don't need most privileges, so we drop them right away. - * Later on linux_minprivs() will be called, which will drop our - * capabilities to the minimum needed to run the server. - */ - INIT_CAP; - - /* - * We need to be able to bind() to privileged ports, notably port 53! - */ - SET_CAP(CAP_NET_BIND_SERVICE); - - /* - * We need chroot() initially too. - */ - SET_CAP(CAP_SYS_CHROOT); - -#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS) - /* - * We can setuid() only if either the kernel supports keeping - * capabilities after setuid() (which we don't know until we've - * tried) or we're not using threads. If either of these is - * true, we want the setuid capability. - */ - SET_CAP(CAP_SETUID); -#endif - - /* - * Since we call initgroups, we need this. - */ - SET_CAP(CAP_SETGID); - - /* - * Without this, we run into problems reading a configuration file - * owned by a non-root user and non-world-readable on startup. - */ - SET_CAP(CAP_DAC_READ_SEARCH); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - SET_CAP(CAP_SYS_RESOURCE); - - /* - * We need to be able to set the ownership of the containing - * directory of the pid file when we create it. - */ - SET_CAP(CAP_CHOWN); - - linux_setcaps(caps); - -#ifdef HAVE_LIBCAP - FREE_CAP; -#endif -} - -static void -linux_minprivs(void) { - cap_t curcaps; - cap_t caps; -#ifdef HAVE_LIBCAP - cap_value_t capval; - char strbuf[ISC_STRERRORSIZE]; - int err; -#else - linux_getpermittedcaps(&curcaps); -#endif - - INIT_CAP; - /*% - * Drop all privileges except the ability to bind() to privileged - * ports. - * - * It's important that we drop CAP_SYS_CHROOT. If we didn't, it - * chroot() could be used to escape from the chrooted area. - */ - - SET_CAP(CAP_NET_BIND_SERVICE); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - SET_CAP(CAP_SYS_RESOURCE); - - linux_setcaps(caps); - -#ifdef HAVE_LIBCAP - FREE_CAP; -#endif -} - -#ifdef HAVE_SYS_PRCTL_H -static void -linux_keepcaps(void) { - char strbuf[ISC_STRERRORSIZE]; - /*% - * Ask the kernel to allow us to keep our capabilities after we - * setuid(). - */ - - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("prctl() failed: %s", strbuf); - } - } else { - non_root_caps = true; - if (getuid() != 0) - non_root = true; - } -} -#endif - -#endif /* HAVE_LINUX_CAPABILITY_H */ - - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - openlog(isc_file_basename(progname), options, ISC_FACILITY); -} - -void -ns_os_init(const char *progname) { - setup_syslog(progname); -#ifdef HAVE_LINUX_CAPABILITY_H - linux_initialprivs(); -#endif -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_IGN); -#endif -} - -void -ns_os_daemonize(void) { - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - - if (pipe(dfd) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("pipe(): %s", strbuf); - } - - pid = fork(); - if (pid == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("fork(): %s", strbuf); - } - if (pid != 0) { - int n; - /* - * Wait for the child to finish loading for the first time. - * This would be so much simpler if fork() worked once we - * were multi-threaded. - */ - (void)close(dfd[1]); - do { - char buf; - n = read(dfd[0], &buf, 1); - if (n == 1) - _exit(0); - } while (n == -1 && errno == EINTR); - _exit(1); - } - (void)close(dfd[0]); - - /* - * We're the child. - */ - -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif - - if (setsid() == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setsid(): %s", strbuf); - } - - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - * - * XXXMLG The close() calls here are unneeded on all but NetBSD, but - * are harmless to include everywhere. dup2() is supposed to close - * the FD if it is in use, but unproven-pthreads-0.16 is broken - * and will end up closing the wrong FD. This will be fixed eventually, - * and these calls will be removed. - */ - if (devnullfd != -1) { - if (devnullfd != STDIN_FILENO) { - (void)close(STDIN_FILENO); - (void)dup2(devnullfd, STDIN_FILENO); - } - if (devnullfd != STDOUT_FILENO) { - (void)close(STDOUT_FILENO); - (void)dup2(devnullfd, STDOUT_FILENO); - } - if (devnullfd != STDERR_FILENO && !ns_g_keepstderr) { - (void)close(STDERR_FILENO); - (void)dup2(devnullfd, STDERR_FILENO); - } - } -} - -void -ns_os_started(void) { - char buf = 0; - - /* - * Signal to the parent that we started successfully. - */ - if (dfd[0] != -1 && dfd[1] != -1) { - if (write(dfd[1], &buf, 1) != 1) - ns_main_earlyfatal("unable to signal parent that we " - "otherwise started successfully."); - close(dfd[1]); - dfd[0] = dfd[1] = -1; - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("/dev/null", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != STDIN_FILENO && - devnullfd != STDOUT_FILENO && - devnullfd != STDERR_FILENO) { - close(devnullfd); - devnullfd = -1; - } -} - -static bool -all_digits(const char *s) { - if (*s == '\0') - return (false); - while (*s != '\0') { - if (!isdigit((*s)&0xff)) - return (false); - s++; - } - return (true); -} - -void -ns_os_chroot(const char *root) { - char strbuf[ISC_STRERRORSIZE]; -#ifdef HAVE_LIBSCF - ns_smf_chroot = 0; -#endif - if (root != NULL) { -#ifdef HAVE_CHROOT - if (chroot(root) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chroot(): %s", strbuf); - } -#else - ns_main_earlyfatal("chroot(): disabled"); -#endif - if (chdir("/") < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chdir(/): %s", strbuf); - } -#ifdef HAVE_LIBSCF - /* Set ns_smf_chroot flag on successful chroot. */ - ns_smf_chroot = 1; -#endif - } -} - -void -ns_os_inituserinfo(const char *username) { - char strbuf[ISC_STRERRORSIZE]; - if (username == NULL) - return; - - if (all_digits(username)) - runas_pw = getpwuid((uid_t)atoi(username)); - else - runas_pw = getpwnam(username); - endpwent(); - - if (runas_pw == NULL) - ns_main_earlyfatal("user '%s' unknown", username); - - if (getuid() == 0) { - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("initgroups(): %s", strbuf); - } - } - -} - -void -ns_os_changeuser(void) { - char strbuf[ISC_STRERRORSIZE]; - if (runas_pw == NULL || done_setuid) - return; - - done_setuid = true; - -#ifdef HAVE_LINUXTHREADS -#ifdef HAVE_LINUX_CAPABILITY_H - if (!non_root_caps) - ns_main_earlyfatal("-u with Linux threads not supported: " - "requires kernel support for " - "prctl(PR_SET_KEEPCAPS)"); -#else - ns_main_earlyfatal("-u with Linux threads not supported: " - "no capabilities support or capabilities " - "disabled at build time"); -#endif -#endif - - if (setgid(runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setgid(): %s", strbuf); - } - - if (setuid(runas_pw->pw_uid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setuid(): %s", strbuf); - } - -#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) - /* - * Restore the ability of named to drop core after the setuid() - * call has disabled it. - */ - if (prctl(PR_SET_DUMPABLE,1,0,0,0) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("prctl(PR_SET_DUMPABLE) failed: %s", - strbuf); - } -#endif -#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -uid_t -ns_os_uid(void) { - if (runas_pw == NULL) - return (0); - return (runas_pw->pw_uid); -} - -void -ns_os_adjustnofile(void) { -#ifdef HAVE_LINUXTHREADS - isc_result_t result; - isc_resourcevalue_t newvalue; - - /* - * Linux: max number of open files specified by one thread doesn't seem - * to apply to other threads on Linux. - */ - newvalue = ISC_RESOURCE_UNLIMITED; - - result = isc_resource_setlimit(isc_resource_openfiles, newvalue); - if (result != ISC_R_SUCCESS) - ns_main_earlywarning("couldn't adjust limit on open files"); -#endif -} - -void -ns_os_minprivs(void) { -#ifdef HAVE_SYS_PRCTL_H - linux_keepcaps(); -#endif - -#ifdef HAVE_LINUXTHREADS - ns_os_changeuser(); /* Call setuid() before threads are started */ -#endif - -#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -static int -safe_open(const char *filename, mode_t mode, bool append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) { - errno = EOPNOTSUPP; - return (-1); - } - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode); - else { - if (unlink(filename) < 0 && errno != ENOENT) - return (-1); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - int n; - if (pidfile != NULL) { - n = unlink(pidfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", pidfile); - free(pidfile); - } - pidfile = NULL; -} - -static void -cleanup_lockfile(void) { - if (singletonfd != -1) { - close(singletonfd); - singletonfd = -1; - } - - if (lockfile != NULL) { - int n = unlink(lockfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", lockfile); - free(lockfile); - lockfile = NULL; - } -} - -/* - * Ensure that a directory exists. - * NOTE: This function overwrites the '/' characters in 'filename' with - * nulls. The caller should copy the filename to a fresh buffer first. - */ -static int -mkdirpath(char *filename, void (*report)(const char *, ...)) { - char *slash = strrchr(filename, '/'); - char strbuf[ISC_STRERRORSIZE]; - unsigned int mode; - - if (slash != NULL && slash != filename) { - struct stat sb; - *slash = '\0'; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't stat '%s': %s", filename, - strbuf); - goto error; - } - if (mkdirpath(filename, report) == -1) - goto error; - /* - * Handle "//", "/./" and "/../" in path. - */ - if (!strcmp(slash + 1, "") || - !strcmp(slash + 1, ".") || - !strcmp(slash + 1, "..")) { - *slash = '/'; - return (0); - } - mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */ - mode |= S_IRGRP | S_IXGRP; /* g=rx */ - mode |= S_IROTH | S_IXOTH; /* o=rx */ - if (mkdir(filename, mode) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't mkdir '%s': %s", filename, - strbuf); - goto error; - } - if (runas_pw != NULL && - chown(filename, runas_pw->pw_uid, - runas_pw->pw_gid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't chown '%s': %s", filename, - strbuf); - } - } - *slash = '/'; - } - return (0); - - error: - *slash = '/'; - return (-1); -} - -#ifndef HAVE_LINUXTHREADS -static void -setperms(uid_t uid, gid_t gid) { -#if defined(HAVE_SETEGID) || defined(HAVE_SETRESGID) - char strbuf[ISC_STRERRORSIZE]; -#endif -#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) - gid_t oldgid, tmpg; -#endif -#if !defined(HAVE_SETEUID) && defined(HAVE_SETRESUID) - uid_t olduid, tmpu; -#endif -#if defined(HAVE_SETEGID) - if (getegid() != gid && setegid(gid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective gid to %ld: %s", - (long)gid, strbuf); - } -#elif defined(HAVE_SETRESGID) - if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) { - if (setresgid(-1, gid, -1) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective " - "gid to %d: %s", gid, strbuf); - } - } -#endif - -#if defined(HAVE_SETEUID) - if (geteuid() != uid && seteuid(uid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective uid to %ld: %s", - (long)uid, strbuf); - } -#elif defined(HAVE_SETRESUID) - if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) { - if (setresuid(-1, uid, -1) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective " - "uid to %d: %s", uid, strbuf); - } - } -#endif -} -#endif /* !HAVE_LINUXTHREADS */ - -FILE * -ns_os_openfile(const char *filename, mode_t mode, bool switch_user) { - char strbuf[ISC_STRERRORSIZE], *f; - FILE *fp; - int fd; - - /* - * Make the containing directory if it doesn't exist. - */ - f = strdup(filename); - if (f == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("couldn't strdup() '%s': %s", - filename, strbuf); - return (NULL); - } - if (mkdirpath(f, ns_main_earlywarning) == -1) { - free(f); - return (NULL); - } - free(f); - - if (switch_user && runas_pw != NULL) { - uid_t olduid = getuid(); - gid_t oldgid = getgid(); -#ifdef HAVE_LINUXTHREADS - REQUIRE(olduid == runas_pw->pw_uid); - REQUIRE(oldgid == runas_pw->pw_gid); -#else - /* Set UID/GID to the one we'll be running with eventually */ - setperms(runas_pw->pw_uid, runas_pw->pw_gid); -#endif - fd = safe_open(filename, mode, false); - -#ifndef HAVE_LINUXTHREADS - /* Restore UID/GID to root */ - setperms(olduid, oldgid); -#endif /* HAVE_LINUXTHREADS */ - - if (fd == -1) { -#ifndef HAVE_LINUXTHREADS - fd = safe_open(filename, mode, false); - if (fd != -1) { - ns_main_earlywarning("Required root " - "permissions to open " - "'%s'.", filename); - } else { - ns_main_earlywarning("Could not open " - "'%s'.", filename); - } - ns_main_earlywarning("Please check file and " - "directory permissions " - "or reconfigure the filename."); -#else /* HAVE_LINUXTHREADS */ - ns_main_earlywarning("Could not open " - "'%s'.", filename); - ns_main_earlywarning("Please check file and " - "directory permissions " - "or reconfigure the filename."); -#endif /* HAVE_LINUXTHREADS */ - } - } else { - fd = safe_open(filename, mode, false); - } - - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not open file '%s': %s", - filename, strbuf); - return (NULL); - } - - fp = fdopen(fd, "w"); - if (fp == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not fdopen() file '%s': %s", - filename, strbuf); - } - - return (fp); -} - -void -ns_os_writepidfile(const char *filename, bool first_time) { - FILE *fh; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - pidfile = strdup(filename); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't strdup() '%s': %s", filename, strbuf); - return; - } - - fh = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, - first_time); - if (fh == NULL) { - cleanup_pidfile(); - return; - } -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - if (fprintf(fh, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(fh); - cleanup_pidfile(); - return; - } - if (fflush(fh) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(fh); - cleanup_pidfile(); - return; - } - (void)fclose(fh); -} - -bool -ns_os_issingleton(const char *filename) { - char strbuf[ISC_STRERRORSIZE]; - struct flock lock; - - if (singletonfd != -1) - return (true); - - if (strcasecmp(filename, "none") == 0) - return (true); - - /* - * Make the containing directory if it doesn't exist. - */ - lockfile = strdup(filename); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't allocate memory for '%s': %s", - filename, strbuf); - } else { - int ret = mkdirpath(lockfile, ns_main_earlywarning); - if (ret == -1) { - ns_main_earlywarning("couldn't create '%s'", filename); - cleanup_lockfile(); - return (false); - } - } - - /* - * ns_os_openfile() uses safeopen() which removes any existing - * files. We can't use that here. - */ - singletonfd = open(filename, O_WRONLY | O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (singletonfd == -1) { - cleanup_lockfile(); - return (false); - } - - memset(&lock, 0, sizeof(lock)); - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 1; - - /* Non-blocking (does not wait for lock) */ - if (fcntl(singletonfd, F_SETLK, &lock) == -1) { - close(singletonfd); - singletonfd = -1; - return (false); - } - - return (true); -} - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); - cleanup_lockfile(); -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - char *input, *ptr; - unsigned int n; - pid_t pid; - - input = command; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - if (strcmp(ptr, "-p") != 0) - return; - -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "pid: %ld", (long)pid); - /* Only send a message if it is complete. */ - if (n > 0 && n < isc_buffer_availablelength(text)) - isc_buffer_add(text, n); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} - -#ifdef HAVE_UNAME -static char unamebuf[sizeof(struct utsname)]; -#else -static const char unamebuf[] = { "unknown architecture" }; -#endif -static const char *unamep = NULL; - -static void -getuname(void) { -#ifdef HAVE_UNAME - struct utsname uts; - - memset(&uts, 0, sizeof(uts)); - if (uname(&uts) < 0) { - snprintf(unamebuf, sizeof(unamebuf), "unknown architecture"); - return; - } - - snprintf(unamebuf, sizeof(unamebuf), "%s %s %s %s", uts.sysname, - uts.machine, uts.release, uts.version); -#endif /* ifdef HAVE_UNAME */ - unamep = unamebuf; -} - -const char * -ns_os_uname(void) { - if (unamep == NULL) { - getuname(); - } - return (unamep); -} diff --git a/bin/named-pkcs11/update.c b/bin/named-pkcs11/update.c deleted file mode 100644 index ffd2caf..0000000 --- a/bin/named-pkcs11/update.c +++ /dev/null @@ -1,3513 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/*! \file - * \brief - * This module implements dynamic update as in RFC2136. - */ - -/* - * XXX TODO: - * - document strict minimality - */ - -/**************************************************************************/ - -/*% - * Log level for tracing dynamic update protocol requests. - */ -#define LOGLEVEL_PROTOCOL ISC_LOG_INFO - -/*% - * Log level for low-level debug tracing. - */ -#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) - -/*% - * Check an operation for failure. These macros all assume that - * the function using them has a 'result' variable and a 'failure' - * label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally with result 'code', which must not - * be ISC_R_SUCCESS. The reason for failure presumably has - * been logged already. - * - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ - -#define FAIL(code) \ - do { \ - result = (code); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s (%s)", _what, \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILC(code, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILC(code, msg); \ - } while (0) - -#define FAILN(code, name, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s: %s (%s)", _what, _nbuf, \ - msg, isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILN(code, name, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILN(code, name, msg); \ - } while (0) - -#define FAILNT(code, name, type, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s/%s: %s (%s)", \ - _what, _nbuf, _tbuf, msg, \ - isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILNT(code, name, type, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILNT(code, name, type, msg); \ - } while (0) - -/*% - * Fail unconditionally and log as a server error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILS(code, msg) \ - do { \ - result = (code); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "error: %s: %s", \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/* - * Return TRUE if NS_CLIENTATTR_TCP is set in the attributes other FALSE. - */ -#define TCPCLIENT(client) (((client)->attributes & NS_CLIENTATTR_TCP) != 0) - -/**************************************************************************/ - -typedef struct rr rr_t; - -struct rr { - /* dns_name_t name; */ - uint32_t ttl; - dns_rdata_t rdata; -}; - -typedef struct update_event update_event_t; - -struct update_event { - ISC_EVENT_COMMON(update_event_t); - dns_zone_t *zone; - isc_result_t result; - dns_message_t *answer; -}; - -/*% - * Prepare an RR for the addition of the new RR 'ctx->update_rr', - * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting - * the RRs if it is replaced by the new RR or has a conflicting TTL. - * The necessary changes are appended to ctx->del_diff and ctx->add_diff; - * we need to do all deletions before any additions so that we don't run - * into transient states with conflicting TTLs. - */ - -typedef struct { - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_name_t *oldname; - dns_rdata_t *update_rr; - dns_ttl_t update_rr_ttl; - bool ignore_add; - dns_diff_t del_diff; - dns_diff_t add_diff; -} add_rr_prepare_ctx_t; - -/**************************************************************************/ -/* - * Forward declarations. - */ - -static void update_action(isc_task_t *task, isc_event_t *event); -static void updatedone_action(isc_task_t *task, isc_event_t *event); -static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone); -static void forward_done(isc_task_t *task, isc_event_t *event); -static isc_result_t add_rr_prepare_action(void *data, rr_t *rr); - -/**************************************************************************/ - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) -{ - va_list ap; - char message[4096]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - if (client == NULL) { - return; - } - - if (isc_log_wouldlog(ns_g_lctx, level) == false) { - return; - } - - va_start(ap, fmt); - vsnprintf(message, sizeof(message), fmt, ap); - va_end(ap); - - if (zone != NULL) { - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, - NS_LOGMODULE_UPDATE, - level, "updating zone '%s/%s': %s", - namebuf, classbuf, message); - } else { - ns_client_log(client, NS_LOGCATEGORY_UPDATE, - NS_LOGMODULE_UPDATE, - level, "%s", message); - } - -} - -static void -update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { - update_log(arg, zone, level, "%s", message); -} - -/*% - * Increment updated-related statistics counters. - */ -static inline void -inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { - isc_stats_increment(ns_g_server->nsstats, counter); - - if (zone != NULL) { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - } -} - -/*% - * Check if we could have queried for the contents of this zone or - * if the zone is potentially updateable. - * If the zone can potentially be updated and the check failed then - * log a error otherwise we log a informational message. - */ -static isc_result_t -checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename, - dns_acl_t *updateacl, dns_ssutable_t *ssutable) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level; - isc_result_t result; - - result = ns_client_checkaclsilent(client, NULL, queryacl, true); - if (result != ISC_R_SUCCESS) { - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - level = (updateacl == NULL && ssutable == NULL) ? - ISC_LOG_INFO : ISC_LOG_ERROR; - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, - "update '%s/%s' denied due to allow-query", - namebuf, classbuf); - } else if (updateacl == NULL && ssutable == NULL) { - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - result = DNS_R_REFUSED; - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, ISC_LOG_INFO, - "update '%s/%s' denied", namebuf, classbuf); - } - return (result); -} - -/*% - * Override the default acl logging when checking whether a client - * can update the zone or whether we can forward the request to the - * master based on IP address. - * - * 'message' contains the type of operation that is being attempted. - * 'slave' indicates if this is a slave zone. If 'acl' is NULL then - * log at debug=3. - * If the zone has no access controls configured ('acl' == NULL && - * 'has_ssutable == ISC_FALS) log the attempt at info, otherwise - * at error. - * - * If the request was signed log that we received it. - */ -static isc_result_t -checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message, - dns_name_t *zonename, bool slave, - bool has_ssutable) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level = ISC_LOG_ERROR; - const char *msg = "denied"; - isc_result_t result; - - if (slave && acl == NULL) { - result = DNS_R_NOTIMP; - level = ISC_LOG_DEBUG(3); - msg = "disabled"; - } else { - result = ns_client_checkaclsilent(client, NULL, acl, false); - if (result == ISC_R_SUCCESS) { - level = ISC_LOG_DEBUG(3); - msg = "approved"; - } else if (acl == NULL && !has_ssutable) { - level = ISC_LOG_INFO; - } - } - - if (client->signer != NULL) { - dns_name_format(client->signer, namebuf, sizeof(namebuf)); - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, ISC_LOG_INFO, - "signer \"%s\" %s", namebuf, msg); - } - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, "%s '%s/%s' %s", - message, namebuf, classbuf, msg); - return (result); -} - -/*% - * Update a single RR in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li '*tuple' == NULL. Either the tuple is freed, or its - * ownership has been transferred to the diff. - */ -static isc_result_t -do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - dns_diff_t temp_diff; - isc_result_t result; - - /* - * Create a singleton diff. - */ - dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); - - /* - * Apply it to the database. - */ - result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); - if (result != ISC_R_SUCCESS) { - dns_difftuple_free(tuple); - return (result); - } - - /* - * Merge it into the current pending journal entry. - */ - dns_diff_appendminimal(diff, tuple); - - /* - * Do not clear temp_diff. - */ - return (ISC_R_SUCCESS); -} - -/*% - * Perform the updates in 'updates' in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li 'updates' is empty. - */ -static isc_result_t -do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - isc_result_t result; - while (! ISC_LIST_EMPTY(updates->tuples)) { - dns_difftuple_t *t = ISC_LIST_HEAD(updates->tuples); - ISC_LIST_UNLINK(updates->tuples, t, link); - CHECK(do_one_tuple(&t, db, ver, diff)); - } - return (ISC_R_SUCCESS); - - failure: - dns_diff_clear(diff); - return (result); -} - -static isc_result_t -update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, - dns_rdata_t *rdata) -{ - dns_difftuple_t *tuple = NULL; - isc_result_t result; - result = dns_difftuple_create(diff->mctx, op, - name, ttl, rdata, &tuple); - if (result != ISC_R_SUCCESS) - return (result); - return (do_one_tuple(&tuple, db, ver, diff)); -} - -/**************************************************************************/ -/* - * Callback-style iteration over rdatasets and rdatas. - * - * foreach_rrset() can be used to iterate over the RRsets - * of a name and call a callback function with each - * one. Similarly, foreach_rr() can be used to iterate - * over the individual RRs at name, optionally restricted - * to RRs of a given type. - * - * The callback functions are called "actions" and take - * two arguments: a void pointer for passing arbitrary - * context information, and a pointer to the current RRset - * or RR. By convention, their names end in "_action". - */ - -/* - * XXXRTH We might want to make this public somewhere in libdns. - */ - -/*% - * Function type for foreach_rrset() iterator actions. - */ -typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); - -/*% - * Function type for foreach_rr() iterator actions. - */ -typedef isc_result_t rr_func(void *data, rr_t *rr); - -/*% - * Internal context struct for foreach_node_rr(). - */ -typedef struct { - rr_func * rr_action; - void * rr_action_data; -} foreach_node_rr_ctx_t; - -/*% - * Internal helper function for foreach_node_rr(). - */ -static isc_result_t -foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { - isc_result_t result; - foreach_node_rr_ctx_t *ctx = data; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - - dns_rdataset_current(rdataset, &rr.rdata); - rr.ttl = rdataset->ttl; - result = (*ctx->rr_action)(ctx->rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - return (result); - } - if (result != ISC_R_NOMORE) - return (result); - return (ISC_R_SUCCESS); -} - -/*% - * For each rdataset of 'name' in 'ver' of 'db', call 'action' - * with the rdataset and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - rrset_func *action, void *action_data) -{ - isc_result_t result; - dns_dbnode_t *node; - dns_rdatasetiter_t *iter; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *oldver = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - - /* - * Only set the clientinfo 'versionp' if the new version is - * different from the current version - */ - dns_db_currentversion(db, &oldver); - dns_clientinfo_init(&ci, NULL, (ver != oldver) ? ver : NULL); - dns_db_closeversion(db, &oldver, false); - - node = NULL; - result = dns_db_findnodeext(db, name, false, &cm, &ci, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - iter = NULL; - result = dns_db_allrdatasets(db, node, ver, - (isc_stdtime_t) 0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(iter, &rdataset); - - result = (*action)(action_data, &rdataset); - - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup_iterator; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup_iterator: - dns_rdatasetiter_destroy(&iter); - - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/*% - * For each RR of 'name' in 'ver' of 'db', call 'action' - * with the RR and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration - * and return the error. - */ -static isc_result_t -foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - rr_func *rr_action, void *rr_action_data) -{ - foreach_node_rr_ctx_t ctx; - ctx.rr_action = rr_action; - ctx.rr_action_data = rr_action_data; - return (foreach_rrset(db, ver, name, - foreach_node_rr_action, &ctx)); -} - - -/*% - * For each of the RRs specified by 'db', 'ver', 'name', 'type', - * (which can be dns_rdatatype_any to match any type), and 'covers', call - * 'action' with the RR and 'action_data' as arguments. If the name - * does not exist, or if no RRset of the given type exists at the name, - * do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action, - void *rr_action_data) -{ - - isc_result_t result; - dns_dbnode_t *node; - dns_rdataset_t rdataset; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *oldver = NULL; - dns_fixedname_t fixed; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - - /* - * Only set the clientinfo 'versionp' if the new version is - * different from the current version - */ - dns_db_currentversion(db, &oldver); - dns_clientinfo_init(&ci, NULL, (ver != oldver) ? ver : NULL); - dns_db_closeversion(db, &oldver, false); - - if (type == dns_rdatatype_any) - return (foreach_node_rr(db, ver, name, - rr_action, rr_action_data)); - - node = NULL; - if (type == dns_rdatatype_nsec3 || - (type == dns_rdatatype_rrsig && covers == dns_rdatatype_nsec3)) - result = dns_db_findnsec3node(db, name, false, &node); - else - result = dns_db_findnodeext(db, name, false, - &cm, &ci, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, covers, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_node; - } - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - if (rr_action == add_rr_prepare_action) { - add_rr_prepare_ctx_t *ctx = rr_action_data; - - ctx->oldname = dns_fixedname_initname(&fixed); - dns_name_copy(name, ctx->oldname, NULL); - dns_rdataset_getownercase(&rdataset, ctx->oldname); - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - dns_rdataset_current(&rdataset, &rr.rdata); - rr.ttl = rdataset.ttl; - result = (*rr_action)(rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - goto cleanup_rdataset; - } - if (result != ISC_R_NOMORE) - goto cleanup_rdataset; - result = ISC_R_SUCCESS; - - cleanup_rdataset: - dns_rdataset_disassociate(&rdataset); - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/**************************************************************************/ -/* - * Various tests on the database contents (for prerequisites, etc). - */ - -/*% - * Function type for predicate functions that compare a database RR 'db_rr' - * against an update RR 'update_rr'. - */ -typedef bool rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); - -/*% - * Helper function for rrset_exists(). - */ -static isc_result_t -rrset_exists_action(void *data, rr_t *rr) { - UNUSED(data); - UNUSED(rr); - return (ISC_R_EXISTS); -} - -/*% - * Utility macro for RR existence checking functions. - * - * If the variable 'result' has the value ISC_R_EXISTS or - * ISC_R_SUCCESS, set *exists to true or false, - * respectively, and return success. - * - * If 'result' has any other value, there was a failure. - * Return the failure result code and do not set *exists. - * - * This would be more readable as "do { if ... } while(0)", - * but that form generates tons of warnings on Solaris 2.6. - */ -#define RETURN_EXISTENCE_FLAG \ - return ((result == ISC_R_EXISTS) ? \ - (*exists = true, ISC_R_SUCCESS) : \ - ((result == ISC_R_SUCCESS) ? \ - (*exists = false, ISC_R_SUCCESS) : \ - result)) - -/*% - * Set '*exists' to true iff an rrset of the given type exists, - * to false otherwise. - */ -static isc_result_t -rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, - bool *exists) -{ - isc_result_t result; - result = foreach_rr(db, ver, name, type, covers, - rrset_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for cname_incompatible_rrset_exists. - */ -static isc_result_t -cname_compatibility_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (rrset->type != dns_rdatatype_cname && - ! dns_rdatatype_atcname(rrset->type)) - { - return (ISC_R_EXISTS); - } - return (ISC_R_SUCCESS); -} - -/*% - * Check whether there is an rrset incompatible with adding a CNAME RR, - * i.e., anything but another CNAME (which can be replaced) or a - * DNSSEC RR (which can coexist). - * - * If such an incompatible rrset exists, set '*exists' to true. - * Otherwise, set it to false. - */ -static isc_result_t -cname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, bool *exists) { - isc_result_t result; - result = foreach_rrset(db, ver, name, - cname_compatibility_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for rr_count(). - */ -static isc_result_t -count_rr_action(void *data, rr_t *rr) { - int *countp = data; - UNUSED(rr); - (*countp)++; - return (ISC_R_SUCCESS); -} - -/*% - * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'. - */ -static isc_result_t -rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, int *countp) -{ - *countp = 0; - return (foreach_rr(db, ver, name, type, covers, - count_rr_action, countp)); -} - -/*% - * Context struct and helper function for name_exists(). - */ - -static isc_result_t -name_exists_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - UNUSED(rrset); - return (ISC_R_EXISTS); -} - -/*% - * Set '*exists' to true iff the given name exists, to false otherwise. - */ -static isc_result_t -name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - bool *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - name_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/* - * 'ssu_check_t' is used to pass the arguments to - * dns_ssutable_checkrules() to the callback function - * ssu_checkrule(). - */ -typedef struct { - /* The ownername of the record to be updated. */ - dns_name_t *name; - - /* The signature's name if the request was signed. */ - dns_name_t *signer; - - /* The address of the client. */ - isc_netaddr_t *addr; - - /* Whether the request was sent via TCP. */ - bool tcp; - - /* The ssu table to check against. */ - dns_ssutable_t *table; - - /* the key used for TKEY requests */ - dst_key_t *key; -} ssu_check_t; - -static isc_result_t -ssu_checkrule(void *data, dns_rdataset_t *rrset) { - ssu_check_t *ssuinfo = data; - bool result; - - /* - * If we're deleting all records, it's ok to delete RRSIG and NSEC even - * if we're normally not allowed to. - */ - if (rrset->type == dns_rdatatype_rrsig || - rrset->type == dns_rdatatype_nsec) - return (ISC_R_SUCCESS); - result = dns_ssutable_checkrules2(ssuinfo->table, ssuinfo->signer, - ssuinfo->name, ssuinfo->addr, - ssuinfo->tcp, &ns_g_server->aclenv, - rrset->type, ssuinfo->key); - return (result == true ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static bool -ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_ssutable_t *ssutable, dns_name_t *signer, - isc_netaddr_t *addr, bool tcp, dst_key_t *key) -{ - isc_result_t result; - ssu_check_t ssuinfo; - - ssuinfo.name = name; - ssuinfo.table = ssutable; - ssuinfo.signer = signer; - ssuinfo.addr = addr; - ssuinfo.tcp = tcp; - ssuinfo.key = key; - result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo); - return (result == ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Checking of "RRset exists (value dependent)" prerequisites. - * - * In the RFC2136 section 3.2.5, this is the pseudocode involving - * a variable called "temp", a mapping of tuples to rrsets. - * - * Here, we represent the "temp" data structure as (non-minimal) "dns_diff_t" - * where each tuple has op==DNS_DIFFOP_EXISTS. - */ - - -/*% - * Append a tuple asserting the existence of the RR with - * 'name' and 'rdata' to 'diff'. - */ -static isc_result_t -temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - REQUIRE(DNS_DIFF_VALID(diff)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, - name, 0, rdata, &tuple)); - ISC_LIST_APPEND(diff->tuples, tuple, link); - failure: - return (result); -} - -/*% - * Compare two rdatasets represented as sorted lists of tuples. - * All list elements must have the same owner name and type. - * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset) - * if not. - */ -static isc_result_t -temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) { - for (;;) { - if (a == NULL || b == NULL) - break; - INSIST(a->op == DNS_DIFFOP_EXISTS && - b->op == DNS_DIFFOP_EXISTS); - INSIST(a->rdata.type == b->rdata.type); - INSIST(dns_name_equal(&a->name, &b->name)); - if (dns_rdata_casecompare(&a->rdata, &b->rdata) != 0) - return (DNS_R_NXRRSET); - a = ISC_LIST_NEXT(a, link); - b = ISC_LIST_NEXT(b, link); - } - if (a != NULL || b != NULL) - return (DNS_R_NXRRSET); - return (ISC_R_SUCCESS); -} - -/*% - * A comparison function defining the sorting order for the entries - * in the "temp" data structure. The major sort key is the owner name, - * followed by the type and rdata. - */ -static int -temp_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - r = dns_name_compare(&a->name, &b->name); - if (r != 0) - return (r); - r = (b->rdata.type - a->rdata.type); - if (r != 0) - return (r); - r = dns_rdata_casecompare(&a->rdata, &b->rdata); - return (r); -} - -/*% - * Check the "RRset exists (value dependent)" prerequisite information - * in 'temp' against the contents of the database 'db'. - * - * Return ISC_R_SUCCESS if the prerequisites are satisfied, - * rcode(dns_rcode_nxrrset) if not. - * - * 'temp' must be pre-sorted. - */ - -static isc_result_t -temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) -{ - isc_result_t result; - dns_name_t *name; - dns_dbnode_t *node; - dns_difftuple_t *t; - dns_diff_t trash; - - dns_diff_init(mctx, &trash); - - /* - * For each name and type in the prerequisites, - * construct a sorted rdata list of the corresponding - * database contents, and compare the lists. - */ - t = ISC_LIST_HEAD(temp->tuples); - while (t != NULL) { - name = &t->name; - (void)dns_name_copy(name, tmpname, NULL); - *typep = t->rdata.type; - - /* A new unique name begins here. */ - node = NULL; - result = dns_db_findnode(db, name, false, &node); - if (result == ISC_R_NOTFOUND) { - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } - if (result != ISC_R_SUCCESS) { - dns_diff_clear(&trash); - return (result); - } - - /* A new unique type begins here. */ - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_rdataset_t rdataset; - dns_diff_t d_rrs; /* Database RRs with - this name and type */ - dns_diff_t u_rrs; /* Update RRs with - this name and type */ - - *typep = type = t->rdata.type; - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&t->rdata); - else if (type == dns_rdatatype_any) { - dns_db_detachnode(db, &node); - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } else - covers = 0; - - /* - * Collect all database RRs for this name and type - * onto d_rrs and sort them. - */ - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, - covers, (isc_stdtime_t) 0, - &rdataset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } - - dns_diff_init(mctx, &d_rrs); - dns_diff_init(mctx, &u_rrs); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = temp_append(&d_rrs, name, &rdata); - if (result != ISC_R_SUCCESS) - goto failure; - } - if (result != ISC_R_NOMORE) - goto failure; - result = dns_diff_sort(&d_rrs, temp_order); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Collect all update RRs for this name and type - * onto u_rrs. No need to sort them here - - * they are already sorted. - */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - dns_difftuple_t *next = - ISC_LIST_NEXT(t, link); - ISC_LIST_UNLINK(temp->tuples, t, link); - ISC_LIST_APPEND(u_rrs.tuples, t, link); - t = next; - } - - /* Compare the two sorted lists. */ - result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples), - ISC_LIST_HEAD(d_rrs.tuples)); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * We are done with the tuples, but we can't free - * them yet because "name" still points into one - * of them. Move them on a temporary list. - */ - ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); - ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); - dns_rdataset_disassociate(&rdataset); - - continue; - - failure: - dns_diff_clear(&d_rrs); - dns_diff_clear(&u_rrs); - dns_diff_clear(&trash); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); - } - - dns_db_detachnode(db, &node); - } - - dns_diff_clear(&trash); - return (ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Conditional deletion of RRs. - */ - -/*% - * Context structure for delete_if(). - */ - -typedef struct { - rr_predicate *predicate; - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; -} conditional_delete_ctx_t; - -/*% - * Predicate functions for delete_if(). - */ - -/*% - * Return true iff 'db_rr' is neither a SOA nor an NS RR nor - * an RRSIG nor an NSEC3PARAM nor a NSEC. - */ -static bool -type_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_soa && - db_rr->type != dns_rdatatype_ns && - db_rr->type != dns_rdatatype_nsec3param && - db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - true : false); -} - -/*% - * Return true iff 'db_rr' is neither a RRSIG nor a NSEC. - */ -static bool -type_not_dnssec(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - true : false); -} - -/*% - * Return true always. - */ -static bool -true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - UNUSED(db_rr); - return (true); -} - -/*% - * Return true iff the two RRs have identical rdata. - */ -static bool -rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - /* - * XXXRTH This is not a problem, but we should consider creating - * dns_rdata_equal() (that used dns_name_equal()), since it - * would be faster. Not a priority. - */ - return (dns_rdata_casecompare(update_rr, db_rr) == 0 ? - true : false); -} - -/*% - * Return true iff 'update_rr' should replace 'db_rr' according - * to the special RFC2136 rules for CNAME, SOA, and WKS records. - * - * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs - * make little sense, so we replace those, too. - * - * Additionally replace RRSIG that have been generated by the same key - * for the same type. This simplifies refreshing a offline KSK by not - * requiring that the old RRSIG be deleted. It also simplifies key - * rollover by only requiring that the new RRSIG be added. - */ -static bool -replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - dns_rdata_rrsig_t updatesig, dbsig; - isc_result_t result; - - if (db_rr->type != update_rr->type) - return (false); - if (db_rr->type == dns_rdatatype_cname) - return (true); - if (db_rr->type == dns_rdatatype_dname) - return (true); - if (db_rr->type == dns_rdatatype_soa) - return (true); - if (db_rr->type == dns_rdatatype_nsec) - return (true); - if (db_rr->type == dns_rdatatype_rrsig) { - /* - * Replace existing RRSIG with the same keyid, - * covered and algorithm. - */ - result = dns_rdata_tostruct(db_rr, &dbsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = dns_rdata_tostruct(update_rr, &updatesig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dbsig.keyid == updatesig.keyid && - dbsig.covered == updatesig.covered && - dbsig.algorithm == updatesig.algorithm) - return (true); - } - if (db_rr->type == dns_rdatatype_wks) { - /* - * Compare the address and protocol fields only. These - * form the first five bytes of the RR data. Do a - * raw binary comparison; unpacking the WKS RRs using - * dns_rdata_tostruct() might be cleaner in some ways. - */ - INSIST(db_rr->length >= 5 && update_rr->length >= 5); - return (memcmp(db_rr->data, update_rr->data, 5) == 0 ? - true : false); - } - - if (db_rr->type == dns_rdatatype_nsec3param) { - if (db_rr->length != update_rr->length) - return (false); - INSIST(db_rr->length >= 4 && update_rr->length >= 4); - /* - * Replace NSEC3PARAM records that only differ by the - * flags field. - */ - if (db_rr->data[0] == update_rr->data[0] && - memcmp(db_rr->data+2, update_rr->data+2, - update_rr->length - 2) == 0) - return (true); - } - return (false); -} - -/*% - * Internal helper function for delete_if(). - */ -static isc_result_t -delete_if_action(void *data, rr_t *rr) { - conditional_delete_ctx_t *ctx = data; - if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { - isc_result_t result; - result = update_one_rr(ctx->db, ctx->ver, ctx->diff, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, &rr->rdata); - return (result); - } else { - return (ISC_R_SUCCESS); - } -} - -/*% - * Conditionally delete RRs. Apply 'predicate' to the RRs - * specified by 'db', 'ver', 'name', and 'type' (which can - * be dns_rdatatype_any to match any type). Delete those - * RRs for which the predicate returns true, and log the - * deletions in 'diff'. - */ -static isc_result_t -delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, - dns_rdata_t *update_rr, dns_diff_t *diff) -{ - conditional_delete_ctx_t ctx; - ctx.predicate = predicate; - ctx.db = db; - ctx.ver = ver; - ctx.diff = diff; - ctx.name = name; - ctx.update_rr = update_rr; - return (foreach_rr(db, ver, name, type, covers, - delete_if_action, &ctx)); -} - -/**************************************************************************/ - -static isc_result_t -add_rr_prepare_action(void *data, rr_t *rr) { - isc_result_t result = ISC_R_SUCCESS; - add_rr_prepare_ctx_t *ctx = data; - dns_difftuple_t *tuple = NULL; - bool equal, case_equal, ttl_equal; - - /* - * Are the new and old cases equal? - */ - case_equal = dns_name_caseequal(ctx->name, ctx->oldname); - - /* - * Are the ttl's equal? - */ - ttl_equal = rr->ttl == ctx->update_rr_ttl; - - /* - * If the update RR is a "duplicate" of a existing RR, - * the update should be silently ignored. - */ - equal = !dns_rdata_casecompare(&rr->rdata, ctx->update_rr); - if (equal && case_equal && ttl_equal) { - ctx->ignore_add = true; - return (ISC_R_SUCCESS); - } - - /* - * If this RR is "equal" to the update RR, it should - * be deleted before the update RR is added. - */ - if (replaces_p(ctx->update_rr, &rr->rdata)) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL, - ctx->oldname, rr->ttl, &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - return (ISC_R_SUCCESS); - } - - /* - * If this RR differs in TTL or case from the update RR, - * its TTL and case must be adjusted. - */ - if (!ttl_equal || !case_equal) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL, - ctx->oldname, rr->ttl, &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - if (!equal) { - CHECK(dns_difftuple_create(ctx->add_diff.mctx, - DNS_DIFFOP_ADD, ctx->name, - ctx->update_rr_ttl, - &rr->rdata, &tuple)); - dns_diff_append(&ctx->add_diff, &tuple); - } - } - failure: - return (result); -} - -/**************************************************************************/ -/* - * Miscellaneous subroutines. - */ - -/*% - * Extract a single update RR from 'section' of dynamic update message - * 'msg', with consistency checking. - * - * Stores the owner name, rdata, and TTL of the update RR at 'name', - * 'rdata', and 'ttl', respectively. - */ -static void -get_current_rr(dns_message_t *msg, dns_section_t section, - dns_rdataclass_t zoneclass, dns_name_t **name, - dns_rdata_t *rdata, dns_rdatatype_t *covers, - dns_ttl_t *ttl, dns_rdataclass_t *update_class) -{ - dns_rdataset_t *rdataset; - isc_result_t result; - dns_message_currentname(msg, section, name); - rdataset = ISC_LIST_HEAD((*name)->list); - INSIST(rdataset != NULL); - INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); - *covers = rdataset->covers; - *ttl = rdataset->ttl; - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, rdata); - INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE); - *update_class = rdata->rdclass; - rdata->rdclass = zoneclass; -} - -/*% - * Increment the SOA serial number of database 'db', version 'ver'. - * Replace the SOA record in the database, and log the - * change in 'diff'. - */ - - /* - * XXXRTH Failures in this routine will be worth logging, when - * we have a logging system. Failure to find the zonename - * or the SOA rdataset warrant at least an UNEXPECTED_ERROR(). - */ - -static isc_result_t -update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - isc_mem_t *mctx, dns_updatemethod_t method) -{ - dns_difftuple_t *deltuple = NULL; - dns_difftuple_t *addtuple = NULL; - uint32_t serial; - isc_result_t result; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); - CHECK(dns_difftuple_copy(deltuple, &addtuple)); - addtuple->op = DNS_DIFFOP_ADD; - - serial = dns_soa_getserial(&addtuple->rdata); - serial = dns_update_soaserial(serial, method); - dns_soa_setserial(serial, &addtuple->rdata); - CHECK(do_one_tuple(&deltuple, db, ver, diff)); - CHECK(do_one_tuple(&addtuple, db, ver, diff)); - result = ISC_R_SUCCESS; - - failure: - if (addtuple != NULL) - dns_difftuple_free(&addtuple); - if (deltuple != NULL) - dns_difftuple_free(&deltuple); - return (result); -} - -/*% - * Check that the new SOA record at 'update_rdata' does not - * illegally cause the SOA serial number to decrease or stay - * unchanged relative to the existing SOA in 'db'. - * - * Sets '*ok' to true if the update is legal, false if not. - * - * William King points out that RFC2136 is inconsistent about - * the case where the serial number stays unchanged: - * - * section 3.4.2.2 requires a server to ignore a SOA update request - * if the serial number on the update SOA is less_than_or_equal to - * the zone SOA serial. - * - * section 3.6 requires a server to ignore a SOA update request if - * the serial is less_than the zone SOA serial. - * - * Paul says 3.4.2.2 is correct. - * - */ -static isc_result_t -check_soa_increment(dns_db_t *db, dns_dbversion_t *ver, - dns_rdata_t *update_rdata, bool *ok) -{ - uint32_t db_serial; - uint32_t update_serial; - isc_result_t result; - - update_serial = dns_soa_getserial(update_rdata); - - result = dns_db_getsoaserial(db, ver, &db_serial); - if (result != ISC_R_SUCCESS) - return (result); - - if (DNS_SERIAL_GE(db_serial, update_serial)) { - *ok = false; - } else { - *ok = true; - } - - return (ISC_R_SUCCESS); - -} - -/**************************************************************************/ -/*% - * The actual update code in all its glory. We try to follow - * the RFC2136 pseudocode as closely as possible. - */ - -static isc_result_t -send_update_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - update_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - isc_result_t msg_result; - - msg_result = dns_message_reply(client->message, true); - if (msg_result != ISC_R_SUCCESS) - goto msg_failure; - client->message->rcode = dns_result_torcode(result); - - ns_client_send(client); - return; - - msg_failure: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - ISC_LOG_ERROR, - "could not create update response message: %s", - isc_result_totext(msg_result)); - ns_client_next(client, msg_result); -} - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL, *raw = NULL; - - /* - * Interpret the zone section. - */ - result = dns_message_firstname(request, DNS_SECTION_ZONE); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, "update zone section empty"); - - /* - * The zone section must contain exactly one "question", and - * it must be of type SOA. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_ZONE, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (zone_rdataset->type != dns_rdatatype_soa) - FAILC(DNS_R_FORMERR, - "update zone section contains non-SOA"); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_NOTAUTH, "not authoritative for update zone"); - - /* - * If there is a raw (unsigned) zone associated with this - * zone then it processes the UPDATE request. - */ - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_dlz: - /* - * We can now fail due to a bad signature as we now know - * that we are the master. - */ - if (sigresult != ISC_R_SUCCESS) - FAIL(sigresult); - CHECK(send_update_event(client, zone)); - break; - case dns_zone_slave: - CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone), - "update forwarding", zonename, true, - false)); - CHECK(send_forward_event(client, zone)); - break; - default: - FAILC(DNS_R_NOTAUTH, "not authoritative for update zone"); - } - return; - - failure: - if (result == DNS_R_REFUSED) { - INSIST(dns_zone_gettype(zone) == dns_zone_slave); - inc_stats(zone, dns_nsstatscounter_updaterej); - } - /* - * We failed without having sent an update event to the zone. - * We are still in the client task context, so we can - * simply give an error response without switching tasks. - */ - respond(client, result); - if (zone != NULL) - dns_zone_detach(&zone); -} - -/*% - * DS records are not allowed to exist without corresponding NS records, - * RFC 3658, 2.2 Protocol Change, - * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". - */ - -static isc_result_t -remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { - isc_result_t result; - bool ns_exists; - dns_difftuple_t *tupple; - dns_diff_t temp_diff; - - dns_diff_init(diff->mctx, &temp_diff); - - for (tupple = ISC_LIST_HEAD(diff->tuples); - tupple != NULL; - tupple = ISC_LIST_NEXT(tupple, link)) { - if (!((tupple->op == DNS_DIFFOP_DEL && - tupple->rdata.type == dns_rdatatype_ns) || - (tupple->op == DNS_DIFFOP_ADD && - tupple->rdata.type == dns_rdatatype_ds))) - continue; - CHECK(rrset_exists(db, newver, &tupple->name, - dns_rdatatype_ns, 0, &ns_exists)); - if (ns_exists && - !dns_name_equal(&tupple->name, dns_db_origin(db))) - continue; - CHECK(delete_if(true_p, db, newver, &tupple->name, - dns_rdatatype_ds, 0, NULL, &temp_diff)); - } - result = ISC_R_SUCCESS; - - failure: - for (tupple = ISC_LIST_HEAD(temp_diff.tuples); - tupple != NULL; - tupple = ISC_LIST_HEAD(temp_diff.tuples)) { - ISC_LIST_UNLINK(temp_diff.tuples, tupple, link); - dns_diff_appendminimal(diff, &tupple); - } - return (result); -} - -/* - * This implements the post load integrity checks for mx records. - */ -static isc_result_t -check_mx(ns_client_t *client, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) -{ - char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char altbuf[DNS_NAME_FORMATSIZE]; - dns_difftuple_t *t; - dns_fixedname_t fixed; - dns_name_t *foundname; - dns_rdata_mx_t mx; - dns_rdata_t rdata; - bool ok = true; - bool isaddress; - isc_result_t result; - struct in6_addr addr6; - struct in_addr addr; - unsigned int options; - - foundname = dns_fixedname_initname(&fixed); - dns_rdata_init(&rdata); - options = dns_zone_getoptions(zone); - - for (t = ISC_LIST_HEAD(diff->tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) { - if (t->op != DNS_DIFFOP_ADD || - t->rdata.type != dns_rdatatype_mx) - continue; - - result = dns_rdata_tostruct(&t->rdata, &mx, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* - * Check if we will error out if we attempt to reload the - * zone. - */ - dns_name_format(&mx.mx, namebuf, sizeof(namebuf)); - dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf)); - isaddress = false; - if ((options & DNS_ZONEOPT_CHECKMX) != 0 && - strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) { - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - isaddress = true; - } - - if (isaddress && (options & DNS_ZONEOPT_CHECKMXFAIL) != 0) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - ok = false; - } else if (isaddress) { - update_log(client, zone, ISC_LOG_WARNING, - "%s/MX: warning: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - } - - /* - * Check zone integrity checks. - */ - if ((options & DNS_ZONEOPT_CHECKINTEGRITY) == 0) - continue; - result = dns_db_find(db, &mx.mx, newver, dns_rdatatype_a, - 0, 0, NULL, foundname, NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - - if (result == DNS_R_NXRRSET) { - result = dns_db_find(db, &mx.mx, newver, - dns_rdatatype_aaaa, - 0, 0, NULL, foundname, - NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - } - - if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' has no address records " - "(A or AAAA)", ownerbuf, namebuf); - ok = false; - } else if (result == DNS_R_CNAME) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is a CNAME (illegal)", - ownerbuf, namebuf); - ok = false; - } else if (result == DNS_R_DNAME) { - dns_name_format(foundname, altbuf, sizeof altbuf); - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is below a DNAME '%s' (illegal)", - ownerbuf, namebuf, altbuf); - ok = false; - } - } - return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED); -} - -static isc_result_t -rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - const dns_rdata_t *rdata, bool *flag) -{ - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - isc_result_t result; - - dns_rdataset_init(&rdataset); - if (rdata->type == dns_rdatatype_nsec3) - CHECK(dns_db_findnsec3node(db, name, false, &node)); - else - CHECK(dns_db_findnode(db, name, false, &node)); - result = dns_db_findrdataset(db, node, ver, rdata->type, 0, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - *flag = false; - result = ISC_R_SUCCESS; - goto failure; - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t myrdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &myrdata); - if (!dns_rdata_casecompare(&myrdata, rdata)) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - *flag = true; - } else if (result == ISC_R_NOMORE) { - *flag = false; - result = ISC_R_SUCCESS; - } - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -get_iterations(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype, - unsigned int *iterationsp) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - dns_rdataset_t rdataset; - isc_result_t result; - unsigned int iterations = 0; - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto try_private; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (nsec3param.iterations > iterations) - iterations = nsec3param.iterations; - } - if (result != ISC_R_NOMORE) - goto failure; - - dns_rdataset_disassociate(&rdataset); - - try_private: - if (privatetype == 0) - goto success; - - result = dns_db_findrdataset(db, node, ver, privatetype, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t private = DNS_RDATA_INIT; - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) - continue; - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (nsec3param.iterations > iterations) - iterations = nsec3param.iterations; - } - if (result != ISC_R_NOMORE) - goto failure; - - success: - *iterationsp = iterations; - result = ISC_R_SUCCESS; - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (result); -} - -/* - * Prevent the zone entering a inconsistent state where - * NSEC only DNSKEYs are present with NSEC3 chains. - */ -static isc_result_t -check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_difftuple_t *tuple; - bool nseconly = false, nsec3 = false; - isc_result_t result; - unsigned int iterations = 0, max; - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - - /* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - if (tuple->op != DNS_DIFFOP_ADD) - continue; - - if (tuple->rdata.type == dns_rdatatype_dnskey) { - uint8_t alg; - alg = tuple->rdata.data[3]; - if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || - alg == DST_ALG_DSA || alg == DST_ALG_ECC) { - nseconly = true; - break; - } - } else if (tuple->rdata.type == dns_rdatatype_nsec3param) { - nsec3 = true; - break; - } - } - - /* Check existing DB for NSEC-only DNSKEY */ - if (!nseconly) { - result = dns_nsec_nseconly(db, ver, &nseconly); - - /* - * An NSEC3PARAM update can proceed without a DNSKEY (it - * will trigger a delayed change), so we can ignore - * ISC_R_NOTFOUND here. - */ - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - - CHECK(result); - } - - /* Check existing DB for NSEC3 */ - if (!nsec3) - CHECK(dns_nsec3_activex(db, ver, false, - privatetype, &nsec3)); - - /* Refuse to allow NSEC3 with NSEC-only keys */ - if (nseconly && nsec3) { - update_log(client, zone, ISC_LOG_ERROR, - "NSEC only DNSKEYs and NSEC3 chains not allowed"); - result = DNS_R_REFUSED; - goto failure; - } - - /* Verify NSEC3 params */ - CHECK(get_iterations(db, ver, privatetype, &iterations)); - CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max)); - if (max != 0 && iterations > max) { - update_log(client, zone, ISC_LOG_ERROR, - "too many NSEC3 iterations (%u) for " - "weakest DNSKEY (%u)", iterations, max); - result = DNS_R_REFUSED; - goto failure; - } - - failure: - return (result); -} - -/* - * Delay NSEC3PARAM changes as they need to be applied to the whole zone. - */ -static isc_result_t -add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1]; - dns_diff_t temp_diff; - dns_diffop_t op; - bool flag; - dns_name_t *name = dns_zone_getorigin(zone); - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - uint32_t ttl = 0; - bool ttl_good = false; - - update_log(client, zone, ISC_LOG_DEBUG(3), - "checking for NSEC3PARAM changes"); - - dns_diff_init(diff->mctx, &temp_diff); - - /* - * Extract NSEC3PARAM tuples from list. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; - tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != dns_rdatatype_nsec3param || - !dns_name_equal(name, &tuple->name)) - continue; - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_APPEND(temp_diff.tuples, tuple, link); - } - - /* - * Extract TTL changes pairs, we don't need to convert these to - * delayed changes. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - if (tuple->op == DNS_DIFFOP_ADD) { - if (!ttl_good) { - /* - * Any adds here will contain the final - * NSEC3PARAM RRset TTL. - */ - ttl = tuple->ttl; - ttl_good = true; - } - /* - * Walk the temp_diff list looking for the - * corresponding delete. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op == DNS_DIFFOP_DEL && - next->rdata.length == tuple->rdata.length && - !memcmp(next_data, tuple_data, - next->rdata.length)) { - ISC_LIST_UNLINK(temp_diff.tuples, next, - link); - ISC_LIST_APPEND(diff->tuples, next, - link); - break; - } - next = ISC_LIST_NEXT(next, link); - } - /* - * If we have not found a pair move onto the next - * tuple. - */ - if (next == NULL) { - next = ISC_LIST_NEXT(tuple, link); - continue; - } - /* - * Find the next tuple to be processed before - * unlinking then complete moving the pair to 'diff'. - */ - next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - /* - * Preserve any ongoing changes from a BIND 9.6.x upgrade. - * - * Any NSEC3PARAM records with flags other than OPTOUT named - * in managing and should not be touched so revert such changes - * taking into account any TTL change of the NSEC3PARAM RRset. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - next = ISC_LIST_NEXT(tuple, link); - if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) { - /* - * If we haven't had any adds then the tuple->ttl must - * be the original ttl and should be used for any - * future changes. - */ - if (!ttl_good) { - ttl = tuple->ttl; - ttl_good = true; - } - op = (tuple->op == DNS_DIFFOP_DEL) ? - DNS_DIFFOP_ADD : DNS_DIFFOP_DEL; - CHECK(dns_difftuple_create(diff->mctx, op, name, - ttl, &tuple->rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - } - } - - /* - * We now have just the actual changes to the NSEC3PARAM RRset. - * Convert the adds to delayed adds and the deletions into delayed - * deletions. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - /* - * If we haven't had any adds then the tuple->ttl must be the - * original ttl and should be used for any future changes. - */ - if (!ttl_good) { - ttl = tuple->ttl; - ttl_good = true; - } - if (tuple->op == DNS_DIFFOP_ADD) { - bool nseconly = false; - - /* - * Look for any deletes which match this ADD ignoring - * flags. We don't need to explicitly remove them as - * they will be removed a side effect of processing - * the add. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op != DNS_DIFFOP_DEL || - next->rdata.length != tuple->rdata.length || - next_data[0] != tuple_data[0] || - next_data[2] != tuple_data[2] || - next_data[3] != tuple_data[3] || - memcmp(next_data + 4, tuple_data + 4, - tuple->rdata.length - 4)) { - next = ISC_LIST_NEXT(next, link); - continue; - } - ISC_LIST_UNLINK(temp_diff.tuples, next, link); - ISC_LIST_APPEND(diff->tuples, next, link); - next = ISC_LIST_HEAD(temp_diff.tuples); - } - - /* - * Create a private-type record to signal that - * we want a delayed NSEC3 chain add/delete - */ - dns_nsec3param_toprivate(&tuple->rdata, &rdata, - privatetype, buf, sizeof(buf)); - buf[2] |= DNS_NSEC3FLAG_CREATE; - - /* - * If the zone is not currently capable of - * supporting an NSEC3 chain, then we set the - * INITIAL flag to indicate that these parameters - * are to be used later. - */ - result = dns_nsec_nseconly(db, ver, &nseconly); - if (result == ISC_R_NOTFOUND || nseconly) - buf[2] |= DNS_NSEC3FLAG_INITIAL; - - /* - * See if this CREATE request already exists. - */ - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, - DNS_DIFFOP_ADD, - name, 0, &rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - - /* - * Remove any existing CREATE request to add an - * otherwise identical chain with a reversed - * OPTOUT state. - */ - buf[2] ^= DNS_NSEC3FLAG_OPTOUT; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - - if (flag) { - CHECK(dns_difftuple_create(diff->mctx, - DNS_DIFFOP_DEL, - name, 0, &rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - - /* - * Find the next tuple to be processed and remove the - * temporary add record. - */ - next = ISC_LIST_NEXT(tuple, link); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, - name, ttl, &tuple->rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - dns_rdata_reset(&rdata); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - - INSIST(ttl_good); - - next = ISC_LIST_NEXT(tuple, link); - /* - * See if we already have a REMOVE request in progress. - */ - dns_nsec3param_toprivate(&tuple->rdata, &rdata, privatetype, - buf, sizeof(buf)); - - buf[2] |= DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC; - - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (!flag) { - buf[2] &= ~DNS_NSEC3FLAG_NONSEC; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - } - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, - ttl, &tuple->rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - dns_rdata_reset(&rdata); - } - - result = ISC_R_SUCCESS; - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -static isc_result_t -rollback_private(dns_db_t *db, dns_rdatatype_t privatetype, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_diff_t temp_diff; - dns_diffop_t op; - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_name_t *name = dns_db_origin(db); - isc_mem_t *mctx = diff->mctx; - isc_result_t result; - - if (privatetype == 0) - return (ISC_R_SUCCESS); - - dns_diff_init(mctx, &temp_diff); - - /* - * Extract the changes to be rolled back. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != privatetype || - !dns_name_equal(name, &tuple->name)) - continue; - - /* - * Allow records which indicate that a zone has been - * signed with a DNSKEY to be removed. - */ - if (tuple->op == DNS_DIFFOP_DEL && - tuple->rdata.length == 5 && - tuple->rdata.data[0] != 0 && - tuple->rdata.data[4] != 0) - continue; - - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_PREPEND(temp_diff.tuples, tuple, link); - } - - /* - * Rollback the changes. - */ - while ((tuple = ISC_LIST_HEAD(temp_diff.tuples)) != NULL) { - op = (tuple->op == DNS_DIFFOP_DEL) ? - DNS_DIFFOP_ADD : DNS_DIFFOP_DEL; - CHECK(dns_difftuple_create(mctx, op, name, tuple->ttl, - &tuple->rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff)); - } - result = ISC_R_SUCCESS; - - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -/* - * Add records to cause the delayed signing of the zone by added DNSKEY - * to remove the RRSIG records generated by a deleted DNSKEY. - */ -static isc_result_t -add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_rdata_dnskey_t dnskey; - dns_rdata_t rdata = DNS_RDATA_INIT; - bool flag; - isc_region_t r; - isc_result_t result = ISC_R_SUCCESS; - uint16_t keyid; - unsigned char buf[5]; - dns_name_t *name = dns_db_origin(db); - dns_diff_t temp_diff; - - dns_diff_init(diff->mctx, &temp_diff); - - /* - * Extract the DNSKEY tuples from the list. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != dns_rdatatype_dnskey) - continue; - - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_APPEND(temp_diff.tuples, tuple, link); - } - - /* - * Extract TTL changes pairs, we don't need signing records for these. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - if (tuple->op == DNS_DIFFOP_ADD) { - /* - * Walk the temp_diff list looking for the - * corresponding delete. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op == DNS_DIFFOP_DEL && - dns_name_equal(&tuple->name, &next->name) && - next->rdata.length == tuple->rdata.length && - !memcmp(next_data, tuple_data, - next->rdata.length)) { - ISC_LIST_UNLINK(temp_diff.tuples, next, - link); - ISC_LIST_APPEND(diff->tuples, next, - link); - break; - } - next = ISC_LIST_NEXT(next, link); - } - /* - * If we have not found a pair move onto the next - * tuple. - */ - if (next == NULL) { - next = ISC_LIST_NEXT(tuple, link); - continue; - } - /* - * Find the next tuple to be processed before - * unlinking then complete moving the pair to 'diff'. - */ - next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - /* - * Process the remaining DNSKEY entries. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; - tuple = ISC_LIST_HEAD(temp_diff.tuples)) { - - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - - result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if ((dnskey.flags & - (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) - != DNS_KEYOWNER_ZONE) - continue; - - dns_rdata_toregion(&tuple->rdata, &r); - - keyid = dst_region_computeid(&r, dnskey.algorithm); - - buf[0] = dnskey.algorithm; - buf[1] = (keyid & 0xff00) >> 8; - buf[2] = (keyid & 0xff); - buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; - buf[4] = 0; - rdata.data = buf; - rdata.length = sizeof(buf); - rdata.type = privatetype; - rdata.rdclass = tuple->rdata.rdclass; - - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (flag) - continue; - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - INSIST(newtuple == NULL); - /* - * Remove any record which says this operation has already - * completed. - */ - buf[4] = 1; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - INSIST(newtuple == NULL); - } - } - - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -static bool -isdnssec(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype) { - isc_result_t result; - bool build_nsec, build_nsec3; - - if (dns_db_issecure(db)) - return (true); - - result = dns_private_chains(db, ver, privatetype, - &build_nsec, &build_nsec3); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - return (build_nsec || build_nsec3); -} - -static void -update_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *oldver = NULL; - dns_dbversion_t *ver = NULL; - dns_diff_t diff; /* Pending updates. */ - dns_diff_t temp; /* Pending RR existence assertions. */ - bool soa_serial_changed = false; - isc_mem_t *mctx = client->mctx; - dns_rdatatype_t covers; - dns_message_t *request = client->message; - dns_rdataclass_t zoneclass; - dns_name_t *zonename; - dns_ssutable_t *ssutable = NULL; - dns_fixedname_t tmpnamefixed; - dns_name_t *tmpname = NULL; - unsigned int options, options2; - dns_difftuple_t *tuple; - dns_rdata_dnskey_t dnskey; - bool had_dnskey; - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - dns_ttl_t maxttl = 0; - uint32_t maxrecords; - uint64_t records; - - INSIST(event->ev_type == DNS_EVENT_UPDATE); - - dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &temp); - - CHECK(dns_zone_getdb(zone, &db)); - zonename = dns_db_origin(db); - zoneclass = dns_db_class(db); - dns_zone_getssutable(zone, &ssutable); - - /* - * Update message processing can leak record existence information - * so check that we are allowed to query this zone. Additionally - * if we would refuse all updates for this zone we bail out here. - */ - CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename, - dns_zone_getupdateacl(zone), ssutable)); - - /* - * Get old and new versions now that queryacl has been checked. - */ - dns_db_currentversion(db, &oldver); - CHECK(dns_db_newversion(db, &ver)); - - /* - * Check prerequisites. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - bool flag; - - get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (ttl != 0) - PREREQFAILC(DNS_R_FORMERR, - "prerequisite TTL is not zero"); - - if (! dns_name_issubdomain(name, zonename)) - PREREQFAILN(DNS_R_NOTZONE, name, - "prerequisite name is out of zone"); - - if (update_class == dns_rdataclass_any) { - if (rdata.length != 0) - PREREQFAILC(DNS_R_FORMERR, - "class ANY prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (! flag) { - PREREQFAILN(DNS_R_NXDOMAIN, name, - "'name in use' " - "prerequisite not " - "satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (! flag) { - /* RRset does not exist. */ - PREREQFAILNT(DNS_R_NXRRSET, name, rdata.type, - "'rrset exists (value independent)' " - "prerequisite not satisfied"); - } - } - } else if (update_class == dns_rdataclass_none) { - if (rdata.length != 0) - PREREQFAILC(DNS_R_FORMERR, - "class NONE prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (flag) { - PREREQFAILN(DNS_R_YXDOMAIN, name, - "'name not in use' " - "prerequisite not " - "satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (flag) { - /* RRset exists. */ - PREREQFAILNT(DNS_R_YXRRSET, name, - rdata.type, - "'rrset does not exist' " - "prerequisite not " - "satisfied"); - } - } - } else if (update_class == zoneclass) { - /* "temp += rr;" */ - result = temp_append(&temp, name, &rdata); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "temp entry creation failed: %s", - dns_result_totext(result)); - FAIL(ISC_R_UNEXPECTED); - } - } else { - PREREQFAILC(DNS_R_FORMERR, "malformed prerequisite"); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * Perform the final check of the "rrset exists (value dependent)" - * prerequisites. - */ - if (ISC_LIST_HEAD(temp.tuples) != NULL) { - dns_rdatatype_t type; - - /* - * Sort the prerequisite records by owner name, - * type, and rdata. - */ - result = dns_diff_sort(&temp, temp_order); - if (result != ISC_R_SUCCESS) - FAILC(result, "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - - tmpname = dns_fixedname_initname(&tmpnamefixed); - result = temp_check(mctx, &temp, db, ver, tmpname, &type); - if (result != ISC_R_SUCCESS) - FAILNT(result, tmpname, type, - "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - } - - update_log(client, zone, LOGLEVEL_DEBUG, - "prerequisites are OK"); - - /* - * Check Requestor's Permissions. It seems a bit silly to do this - * only after prerequisite testing, but that is what RFC2136 says. - */ - if (ssutable == NULL) - CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone), - "update", zonename, false, false)); - else if (client->signer == NULL && !TCPCLIENT(client)) - CHECK(checkupdateacl(client, NULL, "update", zonename, - false, true)); - - if (dns_zone_getupdatedisabled(zone)) - FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled " - "because the zone is frozen. Use " - "'rndc thaw' to re-enable updates."); - - /* - * Perform the Update Section Prescan. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (! dns_name_issubdomain(name, zonename)) - FAILC(DNS_R_NOTZONE, - "update RR is outside zone"); - if (update_class == zoneclass) { - /* - * Check for meta-RRs. The RFC2136 pseudocode says - * check for ANY|AXFR|MAILA|MAILB, but the text adds - * "or any other QUERY metatype" - */ - if (dns_rdatatype_ismeta(rdata.type)) { - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } - result = dns_zone_checknames(zone, name, &rdata); - if (result != ISC_R_SUCCESS) - FAIL(DNS_R_REFUSED); - } else if (update_class == dns_rdataclass_any) { - if (ttl != 0 || rdata.length != 0 || - (dns_rdatatype_ismeta(rdata.type) && - rdata.type != dns_rdatatype_any)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else if (update_class == dns_rdataclass_none) { - if (ttl != 0 || - dns_rdatatype_ismeta(rdata.type)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else { - update_log(client, zone, ISC_LOG_WARNING, - "update RR has incorrect class %d", - update_class); - FAIL(DNS_R_FORMERR); - } - - /* - * draft-ietf-dnsind-simple-secure-update-01 says - * "Unlike traditional dynamic update, the client - * is forbidden from updating NSEC records." - */ - if (rdata.type == dns_rdatatype_nsec3) { - FAILC(DNS_R_REFUSED, - "explicit NSEC3 updates are not allowed " - "in secure zones"); - } else if (rdata.type == dns_rdatatype_nsec) { - FAILC(DNS_R_REFUSED, - "explicit NSEC updates are not allowed " - "in secure zones"); - } else if (rdata.type == dns_rdatatype_rrsig && - !dns_name_equal(name, zonename)) { - FAILC(DNS_R_REFUSED, - "explicit RRSIG updates are currently " - "not supported in secure zones except " - "at the apex"); - } - - if (ssutable != NULL) { - isc_netaddr_t netaddr; - dst_key_t *tsigkey = NULL; - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (client->message->tsigkey != NULL) - tsigkey = client->message->tsigkey->key; - - if (rdata.type != dns_rdatatype_any) { - if (!dns_ssutable_checkrules2 - (ssutable, client->signer, name, &netaddr, - TCPCLIENT(client), - &ns_g_server->aclenv, - rdata.type, tsigkey)) - { - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } else { - if (!ssu_checkall(db, ver, name, ssutable, - client->signer, - &netaddr, - TCPCLIENT(client), - tsigkey)) - { - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - update_log(client, zone, LOGLEVEL_DEBUG, - "update section prescan OK"); - - /* - * Process the Update Section. - */ - - options = dns_zone_getoptions(zone); - options2 = dns_zone_getoptions2(zone); - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - bool flag; - - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (update_class == zoneclass) { - - /* - * RFC1123 doesn't allow MF and MD in master zones. - */ - if (rdata.type == dns_rdatatype_md || - rdata.type == dns_rdatatype_mf) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add %s ignored", - typebuf); - continue; - } - if ((rdata.type == dns_rdatatype_ns || - rdata.type == dns_rdatatype_dname) && - dns_name_iswildcard(name)) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add wildcard %s record " - "ignored", typebuf); - continue; - } - if (rdata.type == dns_rdatatype_cname) { - CHECK(cname_incompatible_rrset_exists(db, ver, - name, - &flag)); - if (flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add CNAME " - "alongside non-CNAME " - "ignored"); - continue; - } - } else { - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_cname, 0, - &flag)); - if (flag && - ! dns_rdatatype_atcname(rdata.type)) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add non-CNAME " - "alongside CNAME ignored"); - continue; - } - } - if (rdata.type == dns_rdatatype_soa) { - bool ok; - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_soa, 0, - &flag)); - if (! flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to create 2nd " - "SOA ignored"); - continue; - } - CHECK(check_soa_increment(db, ver, &rdata, - &ok)); - if (! ok) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "SOA update failed to " - "increment serial, " - "ignoring it"); - continue; - } - soa_serial_changed = true; - } - - if (rdata.type == privatetype) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add a private type " - "(%u) record rejected internal " - "use only", privatetype); - continue; - } - - if (rdata.type == dns_rdatatype_nsec3param) { - /* - * Ignore attempts to add NSEC3PARAM records - * with any flags other than OPTOUT. - */ - if ((rdata.data[1] & - ~DNS_NSEC3FLAG_OPTOUT) != 0) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add NSEC3PARAM " - "record with non OPTOUT " - "flag"); - continue; - } - } - - if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 && - dns_name_internalwildcard(name)) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "warning: ownername '%s' contains " - "a non-terminal wildcard", namestr); - } - - if ((options2 & DNS_ZONEOPT2_CHECKTTL) != 0) { - maxttl = dns_zone_getmaxttl(zone); - if (ttl > maxttl) { - ttl = maxttl; - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "reducing TTL to the " - "configured max-zone-ttl %d", - maxttl); - } - } - - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - char rdstr[2048]; - isc_buffer_t buf; - int len = 0; - const char *truncated = ""; - - dns_name_format(name, namestr, sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - isc_buffer_init(&buf, rdstr, sizeof(rdstr)); - result = dns_rdata_totext(&rdata, NULL, &buf); - if (result == ISC_R_NOSPACE) { - len = (int)isc_buffer_usedlength(&buf); - truncated = " [TRUNCATED]"; - } else if (result != ISC_R_SUCCESS) { - snprintf(rdstr, sizeof(rdstr), "[dns_" - "rdata_totext failed: %s]", - dns_result_totext(result)); - len = strlen(rdstr); - } else - len = (int)isc_buffer_usedlength(&buf); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "adding an RR at '%s' %s %.*s%s", - namestr, typestr, len, rdstr, - truncated); - } - - /* Prepare the affected RRset for the addition. */ - { - add_rr_prepare_ctx_t ctx; - ctx.db = db; - ctx.ver = ver; - ctx.diff = &diff; - ctx.name = name; - ctx.oldname = name; - ctx.update_rr = &rdata; - ctx.update_rr_ttl = ttl; - ctx.ignore_add = false; - dns_diff_init(mctx, &ctx.del_diff); - dns_diff_init(mctx, &ctx.add_diff); - CHECK(foreach_rr(db, ver, name, rdata.type, - covers, add_rr_prepare_action, - &ctx)); - - if (ctx.ignore_add) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - } else { - result = do_diff(&ctx.del_diff, db, ver, - &diff); - if (result == ISC_R_SUCCESS) { - result = do_diff(&ctx.add_diff, - db, ver, - &diff); - } - if (result != ISC_R_SUCCESS) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - goto failure; - } - CHECK(update_one_rr(db, ver, &diff, - DNS_DIFFOP_ADD, - name, ttl, &rdata)); - } - } - } else if (update_class == dns_rdataclass_any) { - if (rdata.type == dns_rdatatype_any) { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "delete all rrsets from " - "name '%s'", namestr); - } - if (dns_name_equal(name, zonename)) { - CHECK(delete_if(type_not_soa_nor_ns_p, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } else { - CHECK(delete_if(type_not_dnssec, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } - } else if (dns_name_equal(name, zonename) && - (rdata.type == dns_rdatatype_soa || - rdata.type == dns_rdatatype_ns)) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to delete all SOA " - "or NS records ignored"); - continue; - } else { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, - typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting rrset at '%s' %s", - namestr, typestr); - } - CHECK(delete_if(true_p, db, ver, name, - rdata.type, covers, &rdata, - &diff)); - } - } else if (update_class == dns_rdataclass_none) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - - /* - * The (name == zonename) condition appears in - * RFC2136 3.4.2.4 but is missing from the pseudocode. - */ - if (dns_name_equal(name, zonename)) { - if (rdata.type == dns_rdatatype_soa) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete SOA " - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_ns) { - int count; - CHECK(rr_count(db, ver, name, - dns_rdatatype_ns, - 0, &count)); - if (count == 1) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to " - "delete last " - "NS ignored"); - continue; - } - } - } - dns_name_format(name, namestr, sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "deleting an RR at %s %s", namestr, typestr); - CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type, - covers, &rdata, &diff)); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * Check that any changes to DNSKEY/NSEC3PARAM records make sense. - * If they don't then back out all changes to DNSKEY/NSEC3PARAM - * records. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) - CHECK(check_dnssec(client, zone, db, ver, &diff)); - - if (! ISC_LIST_EMPTY(diff.tuples)) { - unsigned int errors = 0; - CHECK(dns_zone_nscheck(zone, db, ver, &errors)); - if (errors != 0) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: post update name server " - "sanity check failed"); - result = DNS_R_REFUSED; - goto failure; - } - } - if (! ISC_LIST_EMPTY(diff.tuples)) { - result = dns_zone_cdscheck(zone, db, ver); - if (result == DNS_R_BADCDS || result == DNS_R_BADCDNSKEY) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: bad %s RRset", - result == DNS_R_BADCDS ? "CDS" : "CDNSKEY"); - result = DNS_R_REFUSED; - goto failure; - } - if (result != ISC_R_SUCCESS) - goto failure; - - } - - /* - * If any changes were made, increment the SOA serial number, - * update RRSIGs and NSECs (if zone is secure), and write the update - * to the journal. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) { - char *journalfile; - dns_journal_t *journal; - bool has_dnskey; - - /* - * Increment the SOA serial, but only if it was not - * changed as a result of an update operation. - */ - if (! soa_serial_changed) { - CHECK(update_soa_serial(db, ver, &diff, mctx, - dns_zone_getserialupdatemethod(zone))); - } - - CHECK(check_mx(client, zone, db, ver, &diff)); - - CHECK(remove_orphaned_ds(db, ver, &diff)); - - CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey, - 0, &has_dnskey)); - -#define ALLOW_SECURE_TO_INSECURE(zone) \ - ((dns_zone_getoptions(zone) & DNS_ZONEOPT_SECURETOINSECURE) != 0) - - CHECK(rrset_exists(db, oldver, zonename, dns_rdatatype_dnskey, - 0, &had_dnskey)); - if (!ALLOW_SECURE_TO_INSECURE(zone)) { - if (had_dnskey && !has_dnskey) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: all DNSKEY " - "records removed and " - "'dnssec-secure-to-insecure' " - "not set"); - result = DNS_R_REFUSED; - goto failure; - } - } - - CHECK(rollback_private(db, privatetype, ver, &diff)); - - CHECK(add_signing_records(db, privatetype, ver, &diff)); - - CHECK(add_nsec3param_records(client, zone, db, ver, &diff)); - - if (had_dnskey && !has_dnskey) { - /* - * We are transitioning from secure to insecure. - * Cause all NSEC3 chains to be deleted. When the - * the last signature for the DNSKEY records are - * remove any NSEC chain present will also be removed. - */ - CHECK(dns_nsec3param_deletechains(db, ver, zone, - true, &diff)); - } else if (has_dnskey && isdnssec(db, ver, privatetype)) { - uint32_t interval; - dns_update_log_t log; - - interval = dns_zone_getsigvalidityinterval(zone); - log.func = update_log_cb; - log.arg = client; - result = dns_update_signatures(&log, zone, db, oldver, - ver, &diff, interval); - - if (result != ISC_R_SUCCESS) { - update_log(client, zone, - ISC_LOG_ERROR, - "RRSIG/NSEC/NSEC3 update failed: %s", - isc_result_totext(result)); - goto failure; - } - } - - maxrecords = dns_zone_getmaxrecords(zone); - if (maxrecords != 0U) { - result = dns_db_getsize(db, ver, &records, NULL); - if (result == ISC_R_SUCCESS && records > maxrecords) { - update_log(client, zone, ISC_LOG_ERROR, - "records in zone (%" - PRIu64 - ") exceeds max-records (%u)", - records, maxrecords); - result = DNS_R_TOOMANYRECORDS; - goto failure; - } - } - - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "writing journal %s", journalfile); - - journal = NULL; - result = dns_journal_open(mctx, journalfile, - DNS_JOURNAL_CREATE, &journal); - if (result != ISC_R_SUCCESS) - FAILS(result, "journal open failed"); - - result = dns_journal_write_transaction(journal, &diff); - if (result != ISC_R_SUCCESS) { - dns_journal_destroy(&journal); - FAILS(result, "journal write failed"); - } - - dns_journal_destroy(&journal); - } - - /* - * XXXRTH Just a note that this committing code will have - * to change to handle databases that need two-phase - * commit, but this isn't a priority. - */ - update_log(client, zone, LOGLEVEL_DEBUG, - "committing update transaction"); - - dns_db_closeversion(db, &ver, true); - - /* - * Mark the zone as dirty so that it will be written to disk. - */ - dns_zone_markdirty(zone); - - /* - * Notify slaves of the change we just made. - */ - dns_zone_notify(zone); - - /* - * Cause the zone to be signed with the key that we - * have just added or have the corresponding signatures - * deleted. - * - * Note: we are already committed to this course of action. - */ - for (tuple = ISC_LIST_HEAD(diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - isc_region_t r; - dns_secalg_t algorithm; - uint16_t keyid; - - if (tuple->rdata.type != dns_rdatatype_dnskey) - continue; - - dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); - if ((dnskey.flags & - (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) - != DNS_KEYOWNER_ZONE) - continue; - - dns_rdata_toregion(&tuple->rdata, &r); - algorithm = dnskey.algorithm; - keyid = dst_region_computeid(&r, algorithm); - - result = dns_zone_signwithkey(zone, algorithm, keyid, - (tuple->op == DNS_DIFFOP_DEL)); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "dns_zone_signwithkey failed: %s", - dns_result_totext(result)); - } - } - - /* - * Cause the zone to add/delete NSEC3 chains for the - * deferred NSEC3PARAM changes. - * - * Note: we are already committed to this course of action. - */ - for (tuple = ISC_LIST_HEAD(diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3param_t nsec3param; - - if (tuple->rdata.type != privatetype || - tuple->op != DNS_DIFFOP_ADD) - continue; - - if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, - buf, sizeof(buf))) - continue; - dns_rdata_tostruct(&rdata, &nsec3param, NULL); - if (nsec3param.flags == 0) - continue; - - result = dns_zone_addnsec3chain(zone, &nsec3param); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "dns_zone_addnsec3chain failed: %s", - dns_result_totext(result)); - } - } - } else { - update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); - dns_db_closeversion(db, &ver, true); - } - result = ISC_R_SUCCESS; - goto common; - - failure: - /* - * The reason for failure should have been logged at this point. - */ - if (ver != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "rolling back"); - dns_db_closeversion(db, &ver, false); - } - - common: - dns_diff_clear(&temp); - dns_diff_clear(&diff); - - if (oldver != NULL) - dns_db_closeversion(db, &oldver, false); - - if (db != NULL) - dns_db_detach(&db); - - if (ssutable != NULL) - dns_ssutable_detach(&ssutable); - - isc_task_detach(&task); - uev->result = result; - if (zone != NULL) - INSIST(uev->zone == zone); /* we use this later */ - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = updatedone_action; - isc_task_send(client->task, &event); - - INSIST(ver == NULL); - INSIST(event == NULL); -} - -static void -updatedone_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *) event->ev_arg; - - UNUSED(task); - - INSIST(event->ev_type == DNS_EVENT_UPDATEDONE); - INSIST(task == client->task); - - INSIST(client->nupdates > 0); - switch (uev->result) { - case ISC_R_SUCCESS: - inc_stats(uev->zone, dns_nsstatscounter_updatedone); - break; - case DNS_R_REFUSED: - inc_stats(uev->zone, dns_nsstatscounter_updaterej); - break; - default: - inc_stats(uev->zone, dns_nsstatscounter_updatefail); - break; - } - if (uev->zone != NULL) - dns_zone_detach(&uev->zone); - client->nupdates--; - respond(client, uev->result); - isc_event_free(&event); - ns_client_detach(&client); -} - -/*% - * Update forwarding support. - */ - -static void -forward_fail(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, DNS_R_SERVFAIL); - isc_event_free(&event); - ns_client_detach(&client); -} - - -static void -forward_callback(void *arg, isc_result_t result, dns_message_t *answer) { - update_event_t *uev = arg; - ns_client_t *client = uev->ev_arg; - dns_zone_t *zone = uev->zone; - - if (result != ISC_R_SUCCESS) { - INSIST(answer == NULL); - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - inc_stats(zone, dns_nsstatscounter_updatefwdfail); - } else { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_done; - uev->answer = answer; - inc_stats(zone, dns_nsstatscounter_updaterespfwd); - } - isc_task_send(client->task, ISC_EVENT_PTR(&uev)); - dns_zone_detach(&zone); -} - -static void -forward_done(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - ns_client_sendraw(client, uev->answer); - dns_message_detach(&uev->answer); - isc_event_free(&event); - ns_client_detach(&client); -} - -static void -forward_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - - result = dns_zone_forwardupdate(zone, client->message, - forward_callback, event); - if (result != ISC_R_SUCCESS) { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - isc_task_send(client->task, &event); - inc_stats(zone, dns_nsstatscounter_updatefwdfail); - dns_zone_detach(&zone); - } else - inc_stats(zone, dns_nsstatscounter_updatereqfwd); - isc_task_detach(&task); -} - -static isc_result_t -send_forward_event(ns_client_t *client, dns_zone_t *zone) { - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - /* - * This may take some time so replace this client. - */ - if (!client->mortal && (client->attributes & NS_CLIENTATTR_TCP) == 0) - CHECK(ns_client_replace(client)); - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - forward_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - LOGLEVEL_PROTOCOL, "forwarding update for zone '%s/%s'", - namebuf, classbuf); - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} diff --git a/bin/named-pkcs11/win32/dlz_dlopen_driver.c b/bin/named-pkcs11/win32/dlz_dlopen_driver.c deleted file mode 100644 index 7ba1f0c..0000000 --- a/bin/named-pkcs11/win32/dlz_dlopen_driver.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#ifdef ISC_DLZ_DLOPEN -static dns_sdlzimplementation_t *dlz_dlopen = NULL; - - -typedef struct dlopen_data { - isc_mem_t *mctx; - char *dl_path; - char *dlzname; - HMODULE dl_handle; - void *dbdata; - unsigned int flags; - isc_mutex_t lock; - int version; - bool in_configure; - - dlz_dlopen_version_t *dlz_version; - dlz_dlopen_create_t *dlz_create; - dlz_dlopen_findzonedb_t *dlz_findzonedb; - dlz_dlopen_lookup_t *dlz_lookup; - dlz_dlopen_authority_t *dlz_authority; - dlz_dlopen_allnodes_t *dlz_allnodes; - dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr; - dlz_dlopen_newversion_t *dlz_newversion; - dlz_dlopen_closeversion_t *dlz_closeversion; - dlz_dlopen_configure_t *dlz_configure; - dlz_dlopen_ssumatch_t *dlz_ssumatch; - dlz_dlopen_addrdataset_t *dlz_addrdataset; - dlz_dlopen_subrdataset_t *dlz_subrdataset; - dlz_dlopen_delrdataset_t *dlz_delrdataset; - dlz_dlopen_destroy_t *dlz_destroy; -} dlopen_data_t; - -/* Modules can choose whether they are lock-safe or not. */ -#define MAYBE_LOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - LOCK(&cd->lock); \ - } while (0) - -#define MAYBE_UNLOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - UNLOCK(&cd->lock); \ - } while (0) - -/* - * Log a message at the given level. - */ -static void dlopen_log(int level, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), - fmt, ap); - va_end(ap); -} - -/* - * SDLZ methods - */ - -static isc_result_t -dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata, - dns_sdlzallnodes_t *allnodes) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - - UNUSED(driverarg); - - if (cd->dlz_allnodes == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allnodes(zone, cd->dbdata, allnodes); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, - const char *client) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - - if (cd->dlz_allowzonexfr == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allowzonexfr(cd->dbdata, name, client); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_authority == NULL) { - return (ISC_R_NOTIMPLEMENTED); - } - - MAYBE_LOCK(cd); - result = cd->dlz_authority(zone, cd->dbdata, lookup); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, - methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Load a symbol from the library - */ -static void * -dl_load_symbol(dlopen_data_t *cd, const char *symbol, bool mandatory) { - void *ptr = GetProcAddress(cd->dl_handle, symbol); - if (ptr == NULL && mandatory) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: library '%s' is missing " - "required symbol '%s'", cd->dl_path, symbol); - } - return (ptr); -} - -/* - * Called at startup for each dlopen zone in named.conf - */ -static isc_result_t -dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], - void *driverarg, void **dbdata) -{ - dlopen_data_t *cd; - isc_mem_t *mctx = NULL; - isc_result_t result = ISC_R_FAILURE; - bool triedload = false; - - UNUSED(driverarg); - - if (argc < 2) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen driver for '%s' needs a path to " - "the shared library", dlzname); - return (ISC_R_FAILURE); - } - - isc_mem_create(0, 0, &mctx); - - cd = isc_mem_get(mctx, sizeof(*cd)); - if (cd == NULL) { - isc_mem_destroy(&mctx); - return (ISC_R_NOMEMORY); - } - memset(cd, 0, sizeof(*cd)); - - cd->mctx = mctx; - - cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]); - if (cd->dl_path == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - cd->dlzname = isc_mem_strdup(cd->mctx, dlzname); - if (cd->dlzname == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - triedload = true; - - /* Initialize the lock */ - result = isc_mutex_init(&cd->lock); - if (result != ISC_R_SUCCESS) - goto failed; - - /* Open the library */ - cd->dl_handle = LoadLibraryA(cd->dl_path); - if (cd->dl_handle == NULL) { - unsigned int error = GetLastError(); - - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen failed to open library '%s' - %u", - cd->dl_path, error); - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - /* Find the symbols */ - cd->dlz_version = (dlz_dlopen_version_t *) - dl_load_symbol(cd, "dlz_version", true); - cd->dlz_create = (dlz_dlopen_create_t *) - dl_load_symbol(cd, "dlz_create", true); - cd->dlz_lookup = (dlz_dlopen_lookup_t *) - dl_load_symbol(cd, "dlz_lookup", true); - cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *) - dl_load_symbol(cd, "dlz_findzonedb", true); - - if (cd->dlz_create == NULL || - cd->dlz_version == NULL || - cd->dlz_lookup == NULL || - cd->dlz_findzonedb == NULL) - { - /* We're missing a required symbol */ - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *) - dl_load_symbol(cd, "dlz_allowzonexfr", false); - cd->dlz_allnodes = (dlz_dlopen_allnodes_t *) - dl_load_symbol(cd, "dlz_allnodes", - (cd->dlz_allowzonexfr != NULL)); - cd->dlz_authority = (dlz_dlopen_authority_t *) - dl_load_symbol(cd, "dlz_authority", false); - cd->dlz_newversion = (dlz_dlopen_newversion_t *) - dl_load_symbol(cd, "dlz_newversion", false); - cd->dlz_closeversion = (dlz_dlopen_closeversion_t *) - dl_load_symbol(cd, "dlz_closeversion", - (cd->dlz_newversion != NULL)); - cd->dlz_configure = (dlz_dlopen_configure_t *) - dl_load_symbol(cd, "dlz_configure", false); - cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *) - dl_load_symbol(cd, "dlz_ssumatch", false); - cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *) - dl_load_symbol(cd, "dlz_addrdataset", false); - cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *) - dl_load_symbol(cd, "dlz_subrdataset", false); - cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *) - dl_load_symbol(cd, "dlz_delrdataset", false); - - /* Check the version of the API is the same */ - cd->version = cd->dlz_version(&cd->flags); - if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) || - cd->version > DLZ_DLOPEN_VERSION) - { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: %s: incorrect driver API version %d, " - "requires %d", - cd->dl_path, cd->version, DLZ_DLOPEN_VERSION); - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - /* - * Call the library's create function. Note that this is an - * extended version of dlz create, with the addition of - * named function pointers for helper functions that the - * driver will need. This avoids the need for the backend to - * link the BIND9 libraries - */ - MAYBE_LOCK(cd); - result = cd->dlz_create(dlzname, argc-1, argv+1, - &cd->dbdata, - "log", dlopen_log, - "putrr", dns_sdlz_putrr, - "putnamedrr", dns_sdlz_putnamedrr, - "writeable_zone", dns_dlz_writeablezone, - NULL); - MAYBE_UNLOCK(cd); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - *dbdata = cd; - - return (ISC_R_SUCCESS); - -cleanup_lock: - DESTROYLOCK(&cd->lock); -failed: - dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname); - if (cd->dl_path) - isc_mem_free(mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(mctx, cd->dlzname); - if (triedload) - (void) isc_mutex_destroy(&cd->lock); - if (cd->dl_handle) - FreeLibrary(cd->dl_handle); - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); - return (result); -} - - -/* - * Called when bind is shutting down - */ -static void -dlopen_dlz_destroy(void *driverarg, void *dbdata) { - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_mem_t *mctx; - - UNUSED(driverarg); - - if (cd->dlz_destroy) { - MAYBE_LOCK(cd); - cd->dlz_destroy(cd->dbdata); - MAYBE_UNLOCK(cd); - } - - if (cd->dl_path) - isc_mem_free(cd->mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(cd->mctx, cd->dlzname); - - if (cd->dl_handle) - FreeLibrary(cd->dl_handle); - - DESTROYLOCK(&cd->lock); - - mctx = cd->mctx; - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); -} - -/* - * Called to start a transaction - */ -static isc_result_t -dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata, - void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_newversion(zone, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Called to end a transaction - */ -static void -dlopen_dlz_closeversion(const char *zone, bool commit, - void *driverarg, void *dbdata, void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) { - *versionp = NULL; - return; - } - - MAYBE_LOCK(cd); - cd->dlz_closeversion(zone, commit, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); -} - -/* - * Called on startup to configure any writeable zones - */ -static isc_result_t -dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, - void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_configure == NULL) - return (ISC_R_SUCCESS); - - MAYBE_LOCK(cd); - cd->in_configure = true; - result = cd->dlz_configure(view, dlzdb, cd->dbdata); - cd->in_configure = false; - MAYBE_UNLOCK(cd); - - return (result); -} - - -/* - * Check for authority to change a name - */ -static bool -dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, - const char *type, const char *key, uint32_t keydatalen, - unsigned char *keydata, void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - bool ret; - - UNUSED(driverarg); - - if (cd->dlz_ssumatch == NULL) - return (false); - - MAYBE_LOCK(cd); - ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen, - keydata, cd->dbdata); - MAYBE_UNLOCK(cd); - - return (ret); -} - - -/* - * Add an rdataset - */ -static isc_result_t -dlopen_dlz_addrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_addrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Subtract an rdataset - */ -static isc_result_t -dlopen_dlz_subrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_subrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - delete a rdataset - */ -static isc_result_t -dlopen_dlz_delrdataset(const char *name, const char *type, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_delrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_delrdataset(name, type, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - - -static dns_sdlzmethods_t dlz_dlopen_methods = { - dlopen_dlz_create, - dlopen_dlz_destroy, - dlopen_dlz_findzonedb, - dlopen_dlz_lookup, - dlopen_dlz_authority, - dlopen_dlz_allnodes, - dlopen_dlz_allowzonexfr, - dlopen_dlz_newversion, - dlopen_dlz_closeversion, - dlopen_dlz_configure, - dlopen_dlz_ssumatch, - dlopen_dlz_addrdataset, - dlopen_dlz_subrdataset, - dlopen_dlz_delrdataset -}; -#endif - -/* - * Register driver with BIND - */ -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx) { -#ifndef ISC_DLZ_DLOPEN - UNUSED(mctx); - return (ISC_R_NOTIMPLEMENTED); -#else - isc_result_t result; - - dlopen_log(2, "Registering DLZ_dlopen driver"); - - result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL, - DNS_SDLZFLAG_RELATIVEOWNER | - DNS_SDLZFLAG_RELATIVERDATA | - DNS_SDLZFLAG_THREADSAFE, - mctx, &dlz_dlopen); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_sdlzregister() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - } - - return (result); -#endif -} - - -/* - * Unregister the driver - */ -void -dlz_dlopen_clear(void) { -#ifdef ISC_DLZ_DLOPEN - dlopen_log(2, "Unregistering DLZ_dlopen driver"); - if (dlz_dlopen != NULL) - dns_sdlzunregister(&dlz_dlopen); -#endif -} diff --git a/bin/named-pkcs11/win32/include/named/ntservice.h b/bin/named-pkcs11/win32/include/named/ntservice.h deleted file mode 100644 index 77f4ba5..0000000 --- a/bin/named-pkcs11/win32/include/named/ntservice.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NTSERVICE_H -#define NTSERVICE_H - -#include - -#define BIND_DISPLAY_NAME "ISC BIND" -#define BIND_SERVICE_NAME "named" - -void -ntservice_init(); -void UpdateSCM(DWORD); -void ServiceControl(DWORD dwCtrlCode); -void -ntservice_shutdown(); -BOOL ntservice_isservice(); -#endif diff --git a/bin/named-pkcs11/win32/include/named/os.h b/bin/named-pkcs11/win32/include/named/os.h deleted file mode 100644 index e65a321..0000000 --- a/bin/named-pkcs11/win32/include/named/os.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -#include - -#include - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -unsigned int -ns_os_uid(void); - -void -ns_os_adjustnofile(void); - -void -ns_os_minprivs(void); - -FILE * -ns_os_openfile(const char *filename, int mode, bool switch_user); - -void -ns_os_writepidfile(const char *filename, bool first_time); - -bool -ns_os_issingleton(const char *filename); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -const char * -ns_os_uname(void); - -#endif /* NS_OS_H */ diff --git a/bin/named-pkcs11/win32/named.dsp.in b/bin/named-pkcs11/win32/named.dsp.in deleted file mode 100644 index 354b88b..0000000 --- a/bin/named-pkcs11/win32/named.dsp.in +++ /dev/null @@ -1,341 +0,0 @@ -# Microsoft Developer Studio Project File - Name="named" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=named - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "named.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "named.mak" CFG="named - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "named - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "named - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 @OPENSSL_INC@ @GSSAPI_INC@ @GEOIP_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"old Visual Studio\"" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/lwres/win32/Release/liblwres.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/named.exe" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @OPENSSL_INC@ @GSSAPI_INC@ @GEOIP_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"old Visual Studio\"" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/lwres/win32/Debug/liblwres.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /map /debug @MACHINE@ /out:"../../../Build/Debug/named.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "named - @PLATFORM@ Release" -# Name "named - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\builtin.c -# End Source File -# Begin Source File - -SOURCE=..\client.c -# End Source File -# Begin Source File - -SOURCE=..\config.c -# End Source File -# Begin Source File - -SOURCE=..\control.c -# End Source File -# Begin Source File - -SOURCE=..\controlconf.c -# End Source File -# Begin Source File - -SOURCE=.\dlz_dlopen_driver.c -# End Source File -@IF GEOIP -# Begin Source File - -SOURCE=..\geoip.c -# End Source File -@END GEOIP -# Begin Source File - -SOURCE=..\interfacemgr.c -# End Source File -# Begin Source File - -SOURCE=..\listenlist.c -# End Source File -# Begin Source File - -SOURCE=..\log.c -# End Source File -# Begin Source File - -SOURCE=..\logconf.c -# End Source File -# Begin Source File - -SOURCE=..\lwaddr.c -# End Source File -# Begin Source File - -SOURCE=..\lwdclient.c -# End Source File -# Begin Source File - -SOURCE=..\lwderror.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgabn.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgnba.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgrbn.c -# End Source File -# Begin Source File - -SOURCE=..\lwdnoop.c -# End Source File -# Begin Source File - -SOURCE=..\lwresd.c -# End Source File -# Begin Source File - -SOURCE=..\lwsearch.c -# End Source File -# Begin Source File - -SOURCE=..\main.c -# End Source File -# Begin Source File - -SOURCE=..\notify.c -# End Source File -# Begin Source File - -SOURCE=.\ntservice.c -# End Source File -# Begin Source File - -SOURCE=.\os.c -# End Source File -# Begin Source File - -SOURCE=..\query.c -# End Source File -# Begin Source File - -SOURCE=..\server.c -# End Source File -# Begin Source File - -SOURCE=..\sortlist.c -# End Source File -# Begin Source File - -SOURCE=..\statschannel.c -# End Source File -# Begin Source File - -SOURCE=..\tkeyconf.c -# End Source File -# Begin Source File - -SOURCE=..\tsigconf.c -# End Source File -# Begin Source File - -SOURCE=..\update.c -# End Source File -# Begin Source File - -SOURCE=..\xfrout.c -# End Source File -# Begin Source File - -SOURCE=..\zoneconf.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\include\named\client.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\config.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\globals.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\interfacemgr.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\listenlist.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\log.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\logconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwaddr.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwdclient.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwresd.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwsearch.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\main.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\notify.h -# End Source File -# Begin Source File - -SOURCE=.\include\named\ntservice.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\omapi.h -# End Source File -# Begin Source File - -SOURCE=.\include\named\os.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\query.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\seccomp.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\server.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\sortlist.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\statschannel.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\tkeyconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\tsigconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\types.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\update.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\xfrout.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\zoneconf.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/named-pkcs11/win32/named.dsw b/bin/named-pkcs11/win32/named.dsw deleted file mode 100644 index a1a4f34..0000000 --- a/bin/named-pkcs11/win32/named.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "named"=".\named.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/named-pkcs11/win32/named.mak.in b/bin/named-pkcs11/win32/named.mak.in deleted file mode 100644 index 9e73888..0000000 --- a/bin/named-pkcs11/win32/named.mak.in +++ /dev/null @@ -1,1233 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on named.dsp -!IF "$(CFG)" == "" -CFG=named - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to named - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "named - @PLATFORM@ Release" && "$(CFG)" != "named - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "named.mak" CFG="named - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "named - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "named - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -RSC=rc.exe -LIBXML=@LIBXML2_LIB@ - -!IF "$(CFG)" == "named - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -!IF "$(RECURSE)" == "0" - -ALL : "..\..\..\Build\Release\named.exe" - -!ELSE - -ALL : "libisccfg - @PLATFORM@ Release" "libisccc - @PLATFORM@ Release" "liblwres - @PLATFORM@ Release" "libbind9 - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\named.exe" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libbind9 - @PLATFORM@ ReleaseCLEAN" "liblwres - @PLATFORM@ ReleaseCLEAN" "libisccc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\builtin.obj" - -@erase "$(INTDIR)\client.obj" - -@erase "$(INTDIR)\config.obj" - -@erase "$(INTDIR)\control.obj" - -@erase "$(INTDIR)\controlconf.obj" - -@erase "$(INTDIR)\dlz_dlopen_driver.obj" -@IF GEOIP - -@erase "$(INTDIR)\geoip.obj" -@END GEOIP - -@erase "$(INTDIR)\interfacemgr.obj" - -@erase "$(INTDIR)\listenlist.obj" - -@erase "$(INTDIR)\log.obj" - -@erase "$(INTDIR)\logconf.obj" - -@erase "$(INTDIR)\lwaddr.obj" - -@erase "$(INTDIR)\lwdclient.obj" - -@erase "$(INTDIR)\lwderror.obj" - -@erase "$(INTDIR)\lwdgabn.obj" - -@erase "$(INTDIR)\lwdgnba.obj" - -@erase "$(INTDIR)\lwdgrbn.obj" - -@erase "$(INTDIR)\lwdnoop.obj" - -@erase "$(INTDIR)\lwresd.obj" - -@erase "$(INTDIR)\lwsearch.obj" - -@erase "$(INTDIR)\main.obj" - -@erase "$(INTDIR)\notify.obj" - -@erase "$(INTDIR)\ntservice.obj" - -@erase "$(INTDIR)\os.obj" - -@erase "$(INTDIR)\query.obj" - -@erase "$(INTDIR)\server.obj" - -@erase "$(INTDIR)\sortlist.obj" - -@erase "$(INTDIR)\statschannel.obj" - -@erase "$(INTDIR)\tkeyconf.obj" - -@erase "$(INTDIR)\tsigconf.obj" - -@erase "$(INTDIR)\update.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\xfrout.obj" - -@erase "$(INTDIR)\zoneconf.obj" - -@erase "..\..\..\Build\Release\named.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 @OPENSSL_INC@ @GSSAPI_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"nmake\"" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\named.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\named.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/lwres/win32/Release/liblwres.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib $(LIBXML) @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\named.pdb" @MACHINE@ /out:"../../../Build/Release/named.exe" -LINK32_OBJS= \ - "$(INTDIR)\client.obj" \ - "$(INTDIR)\config.obj" \ - "$(INTDIR)\control.obj" \ - "$(INTDIR)\controlconf.obj" \ - "$(INTDIR)\dlz_dlopen_driver.obj" \ -@IF GEOIP - "$(INTDIR)\geoip.obj" \ -@END GEOIP - "$(INTDIR)\interfacemgr.obj" \ - "$(INTDIR)\listenlist.obj" \ - "$(INTDIR)\log.obj" \ - "$(INTDIR)\logconf.obj" \ - "$(INTDIR)\lwaddr.obj" \ - "$(INTDIR)\lwdclient.obj" \ - "$(INTDIR)\lwderror.obj" \ - "$(INTDIR)\lwdgabn.obj" \ - "$(INTDIR)\lwdgnba.obj" \ - "$(INTDIR)\lwdgrbn.obj" \ - "$(INTDIR)\lwdnoop.obj" \ - "$(INTDIR)\lwresd.obj" \ - "$(INTDIR)\lwsearch.obj" \ - "$(INTDIR)\main.obj" \ - "$(INTDIR)\notify.obj" \ - "$(INTDIR)\ntservice.obj" \ - "$(INTDIR)\os.obj" \ - "$(INTDIR)\query.obj" \ - "$(INTDIR)\server.obj" \ - "$(INTDIR)\sortlist.obj" \ - "$(INTDIR)\statschannel.obj" \ - "$(INTDIR)\tkeyconf.obj" \ - "$(INTDIR)\tsigconf.obj" \ - "$(INTDIR)\update.obj" \ - "$(INTDIR)\xfrout.obj" \ - "$(INTDIR)\zoneconf.obj" \ - "$(INTDIR)\builtin.obj" \ - "..\..\..\lib\dns\win32\Release\libdns.lib" \ - "..\..\..\lib\isc\win32\Release\libisc.lib" \ - "..\..\..\lib\bind9\win32\Release\libbind9.lib" \ - "..\..\..\lib\lwres\win32\Release\liblwres.lib" \ - "..\..\..\lib\isccc\win32\Release\libisccc.lib" \ - "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" - -"..\..\..\Build\Release\named.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "..\..\..\Build\Debug\named.exe" "$(OUTDIR)\named.bsc" - -!ELSE - -ALL : "libisccfg - @PLATFORM@ Debug" "libisccc - @PLATFORM@ Debug" "liblwres - @PLATFORM@ Debug" "libbind9 - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\named.exe" "$(OUTDIR)\named.bsc" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libbind9 - @PLATFORM@ DebugCLEAN" "liblwres - @PLATFORM@ DebugCLEAN" "libisccc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\builtin.obj" - -@erase "$(INTDIR)\builtin.sbr" - -@erase "$(INTDIR)\client.obj" - -@erase "$(INTDIR)\client.sbr" - -@erase "$(INTDIR)\config.obj" - -@erase "$(INTDIR)\config.sbr" - -@erase "$(INTDIR)\control.obj" - -@erase "$(INTDIR)\control.sbr" - -@erase "$(INTDIR)\controlconf.obj" - -@erase "$(INTDIR)\controlconf.sbr" - -@erase "$(INTDIR)\dlz_dlopen_driver.obj" - -@erase "$(INTDIR)\dlz_dlopen_driver.sbr" -@IF GEOIP - -@erase "$(INTDIR)\geoip.obj" - -@erase "$(INTDIR)\geoip.sbr" -@END GEOIP - -@erase "$(INTDIR)\interfacemgr.obj" - -@erase "$(INTDIR)\interfacemgr.sbr" - -@erase "$(INTDIR)\listenlist.obj" - -@erase "$(INTDIR)\listenlist.sbr" - -@erase "$(INTDIR)\log.obj" - -@erase "$(INTDIR)\log.sbr" - -@erase "$(INTDIR)\logconf.obj" - -@erase "$(INTDIR)\logconf.sbr" - -@erase "$(INTDIR)\lwaddr.obj" - -@erase "$(INTDIR)\lwaddr.sbr" - -@erase "$(INTDIR)\lwdclient.obj" - -@erase "$(INTDIR)\lwdclient.sbr" - -@erase "$(INTDIR)\lwderror.obj" - -@erase "$(INTDIR)\lwderror.sbr" - -@erase "$(INTDIR)\lwdgabn.obj" - -@erase "$(INTDIR)\lwdgabn.sbr" - -@erase "$(INTDIR)\lwdgnba.obj" - -@erase "$(INTDIR)\lwdgnba.sbr" - -@erase "$(INTDIR)\lwdgrbn.obj" - -@erase "$(INTDIR)\lwdgrbn.sbr" - -@erase "$(INTDIR)\lwdnoop.obj" - -@erase "$(INTDIR)\lwdnoop.sbr" - -@erase "$(INTDIR)\lwresd.obj" - -@erase "$(INTDIR)\lwresd.sbr" - -@erase "$(INTDIR)\lwsearch.obj" - -@erase "$(INTDIR)\lwsearch.sbr" - -@erase "$(INTDIR)\main.obj" - -@erase "$(INTDIR)\main.sbr" - -@erase "$(INTDIR)\notify.obj" - -@erase "$(INTDIR)\notify.sbr" - -@erase "$(INTDIR)\ntservice.obj" - -@erase "$(INTDIR)\ntservice.sbr" - -@erase "$(INTDIR)\os.obj" - -@erase "$(INTDIR)\os.sbr" - -@erase "$(INTDIR)\query.obj" - -@erase "$(INTDIR)\query.sbr" - -@erase "$(INTDIR)\server.obj" - -@erase "$(INTDIR)\server.sbr" - -@erase "$(INTDIR)\sortlist.obj" - -@erase "$(INTDIR)\sortlist.sbr" - -@erase "$(INTDIR)\statschannel.obj" - -@erase "$(INTDIR)\statschannel.sbr" - -@erase "$(INTDIR)\tkeyconf.obj" - -@erase "$(INTDIR)\tkeyconf.sbr" - -@erase "$(INTDIR)\tsigconf.obj" - -@erase "$(INTDIR)\tsigconf.sbr" - -@erase "$(INTDIR)\update.obj" - -@erase "$(INTDIR)\update.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(INTDIR)\xfrout.obj" - -@erase "$(INTDIR)\xfrout.sbr" - -@erase "$(INTDIR)\zoneconf.obj" - -@erase "$(INTDIR)\zoneconf.sbr" - -@erase "$(OUTDIR)\named.bsc" - -@erase "$(OUTDIR)\named.map" - -@erase "$(OUTDIR)\named.pdb" - -@erase "..\..\..\Build\Debug\named.exe" - -@erase "..\..\..\Build\Debug\named.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @OPENSSL_INC@ @GSSAPI_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"nmake\"" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\named.bsc" -BSC32_SBRS= \ - "$(INTDIR)\client.sbr" \ - "$(INTDIR)\config.sbr" \ - "$(INTDIR)\control.sbr" \ - "$(INTDIR)\controlconf.sbr" \ - "$(INTDIR)\dlz_dlopen_driver.sbr" \ -@IF GEOIP - "$(INTDIR)\geoip.sbr" \ -@END GEOIP - "$(INTDIR)\interfacemgr.sbr" \ - "$(INTDIR)\listenlist.sbr" \ - "$(INTDIR)\log.sbr" \ - "$(INTDIR)\logconf.sbr" \ - "$(INTDIR)\lwaddr.sbr" \ - "$(INTDIR)\lwdclient.sbr" \ - "$(INTDIR)\lwderror.sbr" \ - "$(INTDIR)\lwdgabn.sbr" \ - "$(INTDIR)\lwdgnba.sbr" \ - "$(INTDIR)\lwdgrbn.sbr" \ - "$(INTDIR)\lwdnoop.sbr" \ - "$(INTDIR)\lwresd.sbr" \ - "$(INTDIR)\lwsearch.sbr" \ - "$(INTDIR)\main.sbr" \ - "$(INTDIR)\notify.sbr" \ - "$(INTDIR)\ntservice.sbr" \ - "$(INTDIR)\os.sbr" \ - "$(INTDIR)\query.sbr" \ - "$(INTDIR)\server.sbr" \ - "$(INTDIR)\sortlist.sbr" \ - "$(INTDIR)\statschannel.sbr" \ - "$(INTDIR)\tkeyconf.sbr" \ - "$(INTDIR)\tsigconf.sbr" \ - "$(INTDIR)\update.sbr" \ - "$(INTDIR)\xfrout.sbr" \ - "$(INTDIR)\zoneconf.sbr" \ - "$(INTDIR)\builtin.sbr" - -"$(OUTDIR)\named.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/lwres/win32/Debug/liblwres.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib $(LIBXML) @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\named.pdb" /map:"$(INTDIR)\named.map" /debug @MACHINE@ /out:"../../../Build/Debug/named.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\client.obj" \ - "$(INTDIR)\config.obj" \ - "$(INTDIR)\control.obj" \ - "$(INTDIR)\controlconf.obj" \ - "$(INTDIR)\dlz_dlopen_driver.obj" \ -@IF GEOIP - "$(INTDIR)\geoip.obj" \ -@END GEOIP - "$(INTDIR)\interfacemgr.obj" \ - "$(INTDIR)\listenlist.obj" \ - "$(INTDIR)\log.obj" \ - "$(INTDIR)\logconf.obj" \ - "$(INTDIR)\lwaddr.obj" \ - "$(INTDIR)\lwdclient.obj" \ - "$(INTDIR)\lwderror.obj" \ - "$(INTDIR)\lwdgabn.obj" \ - "$(INTDIR)\lwdgnba.obj" \ - "$(INTDIR)\lwdgrbn.obj" \ - "$(INTDIR)\lwdnoop.obj" \ - "$(INTDIR)\lwresd.obj" \ - "$(INTDIR)\lwsearch.obj" \ - "$(INTDIR)\main.obj" \ - "$(INTDIR)\notify.obj" \ - "$(INTDIR)\ntservice.obj" \ - "$(INTDIR)\os.obj" \ - "$(INTDIR)\query.obj" \ - "$(INTDIR)\server.obj" \ - "$(INTDIR)\sortlist.obj" \ - "$(INTDIR)\statschannel.obj" \ - "$(INTDIR)\tkeyconf.obj" \ - "$(INTDIR)\tsigconf.obj" \ - "$(INTDIR)\update.obj" \ - "$(INTDIR)\xfrout.obj" \ - "$(INTDIR)\zoneconf.obj" \ - "$(INTDIR)\builtin.obj" \ - "..\..\..\lib\dns\win32\Debug\libdns.lib" \ - "..\..\..\lib\isc\win32\Debug\libisc.lib" \ - "..\..\..\lib\bind9\win32\Debug\libbind9.lib" \ - "..\..\..\lib\lwres\win32\Debug\liblwres.lib" \ - "..\..\..\lib\isccc\win32\Debug\libisccc.lib" \ - "..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" - -"..\..\..\Build\Debug\named.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("named.dep") -!INCLUDE "named.dep" -!ELSE -!MESSAGE Warning: cannot find "named.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "named - @PLATFORM@ Release" || "$(CFG)" == "named - @PLATFORM@ Debug" -SOURCE=..\builtin.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\builtin.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\builtin.obj" "$(INTDIR)\builtin.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\client.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\client.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\client.obj" "$(INTDIR)\client.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\config.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\config.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\config.obj" "$(INTDIR)\config.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\control.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\control.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\control.obj" "$(INTDIR)\control.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\controlconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\controlconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\controlconf.obj" "$(INTDIR)\controlconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=.\dlz_dlopen_driver.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\dlz_dlopen_driver.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\dlz_dlopen_driver.obj" "$(INTDIR)\dlz_dlopen_driver.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -@IF GEOIP -SOURCE=..\geoip.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\geoip.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\geoip.obj" "$(INTDIR)\geoip.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF -@END GEOIP - -SOURCE=..\interfacemgr.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\interfacemgr.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\interfacemgr.obj" "$(INTDIR)\interfacemgr.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\listenlist.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\listenlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\listenlist.obj" "$(INTDIR)\listenlist.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\log.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\log.obj" "$(INTDIR)\log.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\logconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\logconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\logconf.obj" "$(INTDIR)\logconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwaddr.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwaddr.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwaddr.obj" "$(INTDIR)\lwaddr.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdclient.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdclient.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdclient.obj" "$(INTDIR)\lwdclient.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwderror.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwderror.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwderror.obj" "$(INTDIR)\lwderror.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgabn.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgabn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgabn.obj" "$(INTDIR)\lwdgabn.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgnba.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgnba.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgnba.obj" "$(INTDIR)\lwdgnba.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgrbn.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgrbn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgrbn.obj" "$(INTDIR)\lwdgrbn.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdnoop.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdnoop.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdnoop.obj" "$(INTDIR)\lwdnoop.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwresd.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwresd.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwresd.obj" "$(INTDIR)\lwresd.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwsearch.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwsearch.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwsearch.obj" "$(INTDIR)\lwsearch.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\main.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\notify.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\notify.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\notify.obj" "$(INTDIR)\notify.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=.\ntservice.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\ntservice.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\ntservice.obj" "$(INTDIR)\ntservice.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -SOURCE=.\os.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\os.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\os.obj" "$(INTDIR)\os.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -SOURCE=..\query.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\query.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\query.obj" "$(INTDIR)\query.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\server.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\server.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\server.obj" "$(INTDIR)\server.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\sortlist.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\sortlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\sortlist.obj" "$(INTDIR)\sortlist.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\statschannel.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\statschannel.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\statschannel.obj" "$(INTDIR)\statschannel.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\tkeyconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\tkeyconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\tkeyconf.obj" "$(INTDIR)\tkeyconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\tsigconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\tsigconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\tsigconf.obj" "$(INTDIR)\tsigconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\update.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\update.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\update.obj" "$(INTDIR)\update.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\xfrout.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\xfrout.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\xfrout.obj" "$(INTDIR)\xfrout.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\zoneconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\zoneconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\zoneconf.obj" "$(INTDIR)\zoneconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libdns - @PLATFORM@ Release" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libdns - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libdns - @PLATFORM@ Debug" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libdns - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisc - @PLATFORM@ Release" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisc - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisc - @PLATFORM@ Debug" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisc - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libbind9 - @PLATFORM@ Release" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libbind9 - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libbind9 - @PLATFORM@ Debug" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libbind9 - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"liblwres - @PLATFORM@ Release" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"liblwres - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"liblwres - @PLATFORM@ Debug" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"liblwres - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisccc - @PLATFORM@ Release" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisccc - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisccc - @PLATFORM@ Debug" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisccc - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisccfg - @PLATFORM@ Release" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisccfg - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisccfg - @PLATFORM@ Debug" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisccfg - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/named-pkcs11/win32/named.vcxproj.filters.in b/bin/named-pkcs11/win32/named.vcxproj.filters.in deleted file mode 100644 index 8a5173e..0000000 --- a/bin/named-pkcs11/win32/named.vcxproj.filters.in +++ /dev/null @@ -1,221 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - -@IF GEOIP - - Source Files - -@END GEOIP -@IF GEOIPLEGACY - - Source Files - -@END GEOIPLEGACY - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - -@IF GEOIP - - Header Files - -@END GEOIP -@IF GEOIPLEGACY - - Header Files - -@END GEOIPLEGACY - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/bin/named-pkcs11/win32/named.vcxproj.in b/bin/named-pkcs11/win32/named.vcxproj.in deleted file mode 100644 index 0487405..0000000 --- a/bin/named-pkcs11/win32/named.vcxproj.in +++ /dev/null @@ -1,190 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {723C65DA-A96C-4BA3-A34E-44F11CA346F9} - Win32Proj - named - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@@USE_GSSAPI@BUILDER="Visual Studio";_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - @OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) - @LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;liblwres.lib;libisccfg.lib;libbind9.lib;version.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@@USE_GSSAPI@BUILDER="Visual Studio";NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - @OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) - @LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;liblwres.lib;libisccfg.lib;libbind9.lib;version.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - -@IF GEOIP - -@END GEOIP -@IF GEOIPLEGACY - -@END GEOIPLEGACY - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@IF GEOIP - -@END GEOIP -@IF GEOIPLEGACY - -@END GEOIPLEGACY - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/named-pkcs11/win32/named.vcxproj.user b/bin/named-pkcs11/win32/named.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/named-pkcs11/win32/named.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/named-pkcs11/win32/ntservice.c b/bin/named-pkcs11/win32/ntservice.c deleted file mode 100644 index 77cafe3..0000000 --- a/bin/named-pkcs11/win32/ntservice.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Handle to SCM for updating service status */ -static SERVICE_STATUS_HANDLE hServiceStatus = 0; -static BOOL foreground = FALSE; -static char ConsoleTitle[128]; - -/* - * Forward declarations - */ -void ServiceControl(DWORD dwCtrlCode); -int bindmain(int, char *[]); /* From main.c */ - -/* - * Initialize the Service by registering it. - */ -void -ntservice_init(void) { - if (!foreground) { - /* Register handler with the SCM */ - hServiceStatus = RegisterServiceCtrlHandler(BIND_SERVICE_NAME, - (LPHANDLER_FUNCTION)ServiceControl); - if (!hServiceStatus) { - ns_main_earlyfatal( - "could not register service control handler"); - } - UpdateSCM(SERVICE_RUNNING); - } else { - strlcpy(ConsoleTitle, "BIND Version ", sizeof(ConsoleTitle)); - strlcat(ConsoleTitle, VERSION, sizeof(ConsoleTitle)); - SetConsoleTitle(ConsoleTitle); - } -} - -void -ntservice_shutdown(void) { - UpdateSCM(SERVICE_STOPPED); -} -/* - * Routine to check if this is a service or a foreground program - */ -BOOL -ntservice_isservice(void) { - return(!foreground); -} -/* - * ServiceControl(): Handles requests from the SCM and passes them on - * to named. - */ -void -ServiceControl(DWORD dwCtrlCode) { - /* Handle the requested control code */ - switch(dwCtrlCode) { - case SERVICE_CONTROL_INTERROGATE: - UpdateSCM(0); - break; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - ns_server_flushonshutdown(ns_g_server, true); - isc_app_shutdown(); - UpdateSCM(SERVICE_STOP_PENDING); - break; - default: - break; - } -} - -/* - * Tell the Service Control Manager the state of the service. - */ -void UpdateSCM(DWORD state) { - SERVICE_STATUS ss; - static DWORD dwState = SERVICE_STOPPED; - - if (hServiceStatus) { - if (state) - dwState = state; - - memset(&ss, 0, sizeof(SERVICE_STATUS)); - ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS; - ss.dwCurrentState = dwState; - ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SHUTDOWN; - ss.dwCheckPoint = 0; - ss.dwServiceSpecificExitCode = 0; - ss.dwWin32ExitCode = NO_ERROR; - ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 10000 : 1000; - - if (!SetServiceStatus(hServiceStatus, &ss)) { - ss.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(hServiceStatus, &ss); - } - } -} - -/* unhook main */ - -#undef main - -/* - * This is the entry point for the executable - * We can now call bindmain() explicitly or via StartServiceCtrlDispatcher() - * as we need to. - */ -int main(int argc, char *argv[]) -{ - int rc, ch; - - /* Command line users should put -f in the options. */ - isc_commandline_errprint = false; - while ((ch = isc_commandline_parse(argc, argv, NS_MAIN_ARGS)) != -1) { - switch (ch) { - case 'f': - case 'g': - case 'v': - case 'V': - foreground = TRUE; - break; - default: - break; - } - } - isc_commandline_reset = true; - - if (foreground) { - /* run in console window */ - exit(bindmain(argc, argv)); - } else { - /* Start up as service */ - char *SERVICE_NAME = BIND_SERVICE_NAME; - - SERVICE_TABLE_ENTRY dispatchTable[] = { - { TEXT(SERVICE_NAME), - (LPSERVICE_MAIN_FUNCTION)bindmain }, - { NULL, NULL } - }; - - rc = StartServiceCtrlDispatcher(dispatchTable); - if (!rc) { - fprintf(stderr, - "Use -f to run from the command line.\n"); - /* will be 1063 when launched as a console app */ - exit(GetLastError()); - } - } - exit(0); -} diff --git a/bin/named-pkcs11/win32/os.c b/bin/named-pkcs11/win32/os.c deleted file mode 100644 index 300e115..0000000 --- a/bin/named-pkcs11/win32/os.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -static char *lockfile = NULL; -static char *pidfile = NULL; -static int devnullfd = -1; -static int lockfilefd = -1; - -static BOOL Initialized = FALSE; - -static char *version_error = - "named requires Windows 2000 Service Pack 2 or later to run correctly"; - -void -ns_paths_init(void) { - if (!Initialized) - isc_ntpaths_init(); - - lwresd_g_conffile = isc_ntpaths_get(LWRES_CONF_PATH); - lwresd_g_resolvconffile = isc_ntpaths_get(RESOLV_CONF_PATH); - ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH); - ns_g_defaultpidfile = isc_ntpaths_get(NAMED_PID_PATH); - lwresd_g_defaultpidfile = isc_ntpaths_get(LWRESD_PID_PATH); - ns_g_defaultlockfile = isc_ntpaths_get(NAMED_LOCK_PATH); - ns_g_keyfile = isc_ntpaths_get(RNDC_KEY_PATH); - ns_g_defaultsessionkeyfile = isc_ntpaths_get(SESSION_KEY_PATH); - - Initialized = TRUE; -} - -/* - * Due to Knowledge base article Q263823 we need to make sure that - * Windows 2000 systems have Service Pack 2 or later installed and - * warn when it isn't. - */ -static void -version_check(const char *progname) { - - if ((isc_win32os_versioncheck(4, 0, 0, 0) >= 0) && - (isc_win32os_versioncheck(5, 0, 0, 0) < 0)) - return; /* No problem with Version 4.0 */ - if (isc_win32os_versioncheck(5, 0, 2, 0) < 0) - if (ntservice_isservice()) - NTReportError(progname, version_error); - else - fprintf(stderr, "%s\n", version_error); -} - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - - openlog(progname, options, LOG_DAEMON); -} - -void -ns_os_init(const char *progname) { - ns_paths_init(); - setup_syslog(progname); - /* - * XXXMPA. We may need to split ntservice_init() in two and - * just mark as running in ns_os_started(). If we do that - * this is where the first part of ntservice_init() should be - * called from. - * - * XXX970 Remove comment if no problems by 9.7.0. - * - * ntservice_init(); - */ - version_check(progname); - /* - * If running in a Cygwin environment, clear the SEM_NOGPFAULTERRORBOX - * bit in the process error mode to prevent Cygwin from concealing - * non-abort() crashes, giving Windows Error Reporting a chance to - * handle such crashes. This is done to ensure all crashes triggered - * by system tests can be detected. - */ - if (getenv("CYGWIN") != NULL) { - SetErrorMode(SetErrorMode(0) & ~SEM_NOGPFAULTERRORBOX); - } -} - -void -ns_os_daemonize(void) { - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - */ - if (devnullfd != -1) { - if (devnullfd != _fileno(stdin)) { - close(_fileno(stdin)); - (void)_dup2(devnullfd, _fileno(stdin)); - } - if (devnullfd != _fileno(stdout)) { - close(_fileno(stdout)); - (void)_dup2(devnullfd, _fileno(stdout)); - } - if (devnullfd != _fileno(stderr)) { - close(_fileno(stderr)); - (void)_dup2(devnullfd, _fileno(stderr)); - } - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("NUL", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != _fileno(stdin) && - devnullfd != _fileno(stdout) && - devnullfd != _fileno(stderr)) { - close(devnullfd); - devnullfd = -1; - } -} - -void -ns_os_chroot(const char *root) { - if (root != NULL) - ns_main_earlyfatal("chroot(): isn't supported by Win32 API"); -} - -void -ns_os_inituserinfo(const char *username) { -} - -void -ns_os_changeuser(void) { -} - -unsigned int -ns_os_uid(void) { - return (0); -} - -void -ns_os_adjustnofile(void) { -} - -void -ns_os_minprivs(void) { -} - -static int -safe_open(const char *filename, int mode, bool append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) - return (-1); - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode); - else { - (void)unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - if (pidfile != NULL) { - (void)unlink(pidfile); - free(pidfile); - } - pidfile = NULL; -} - -static void -cleanup_lockfile(void) { - if (lockfilefd != -1) { - close(lockfilefd); - lockfilefd = -1; - } - - if (lockfile != NULL) { - int n = unlink(lockfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", lockfile); - free(lockfile); - lockfile = NULL; - } -} - -FILE * -ns_os_openfile(const char *filename, int mode, bool switch_user) { - char strbuf[ISC_STRERRORSIZE]; - FILE *fp; - int fd; - - UNUSED(switch_user); - fd = safe_open(filename, mode, false); - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not open file '%s': %s", - filename, strbuf); - return (NULL); - } - - fp = fdopen(fd, "w"); - if (fp == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not fdopen() file '%s': %s", - filename, strbuf); - close(fd); - } - - return (fp); -} - -void -ns_os_writepidfile(const char *filename, bool first_time) { - FILE *pidlockfile; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - pidfile = strdup(filename); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't strdup() '%s': %s", filename, strbuf); - return; - } - - pidlockfile = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, - false); - if (pidlockfile == NULL) { - free(pidfile); - pidfile = NULL; - return; - } - - pid = getpid(); - - if (fprintf(pidlockfile, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(pidlockfile); - cleanup_pidfile(); - return; - } - if (fflush(pidlockfile) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(pidlockfile); - cleanup_pidfile(); - return; - } - (void)fclose(pidlockfile); -} - -bool -ns_os_issingleton(const char *filename) { - char strbuf[ISC_STRERRORSIZE]; - OVERLAPPED o; - - if (lockfilefd != -1) - return (true); - - if (strcasecmp(filename, "none") == 0) - return (true); - - lockfile = strdup(filename); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't allocate memory for '%s': %s", - filename, strbuf); - } - - /* - * ns_os_openfile() uses safeopen() which removes any existing - * files. We can't use that here. - */ - lockfilefd = open(filename, O_WRONLY | O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (lockfilefd == -1) { - cleanup_lockfile(); - return (false); - } - - memset(&o, 0, sizeof(o)); - /* Expect ERROR_LOCK_VIOLATION if already locked */ - if (!LockFileEx((HANDLE) _get_osfhandle(lockfilefd), - LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, - 0, 0, 1, &o)) { - cleanup_lockfile(); - return (false); - } - - return (true); -} - - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); - - if (lockfilefd != -1) { - (void) UnlockFile((HANDLE) _get_osfhandle(lockfilefd), - 0, 0, 0, 1); - } - cleanup_lockfile(); - - ntservice_shutdown(); /* This MUST be the last thing done */ -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, (int)len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - UNUSED(command); - UNUSED(text); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} - -void -ns_os_started(void) { - ntservice_init(); -} - -static char unamebuf[BUFSIZ]; -static const char *unamep = NULL; - -static void -getuname(void) { - DWORD fvilen; - char *fvi; - VS_FIXEDFILEINFO *ffi; - UINT ffilen; - SYSTEM_INFO sysinfo; - char *arch; - - fvi = NULL; - fvilen = GetFileVersionInfoSize("kernel32.dll", 0); - if (fvilen == 0) { - goto err; - } - fvi = (char *)malloc(fvilen); - if (fvi == NULL) { - goto err; - } - memset(fvi, 0, fvilen); - if (GetFileVersionInfo("kernel32.dll", 0, fvilen, fvi) == 0) { - goto err; - } - ffi = NULL; - ffilen = 0; - if ((VerQueryValue(fvi, "\\", &ffi, &ffilen) == 0) || - (ffi == NULL) || (ffilen == 0)) { - goto err; - } - memset(&sysinfo, 0, sizeof(sysinfo)); - GetSystemInfo(&sysinfo); - switch (sysinfo.wProcessorArchitecture) { - case PROCESSOR_ARCHITECTURE_INTEL: - arch = "x86"; - break; - case PROCESSOR_ARCHITECTURE_ARM: - arch = "arm"; - break; - case PROCESSOR_ARCHITECTURE_IA64: - arch = "ia64"; - break; - case PROCESSOR_ARCHITECTURE_AMD64: - arch = "x64"; - break; - default: - arch = "unknown architecture"; - break; - } - - snprintf(unamebuf, sizeof(unamebuf), - "Windows %d %d build %d %d for %s\n", - (ffi->dwProductVersionMS >> 16) & 0xffff, - ffi->dwProductVersionMS & 0xffff, - (ffi->dwProductVersionLS >> 16) & 0xffff, - ffi->dwProductVersionLS & 0xffff, - arch); - - err: - if (fvi != NULL) { - free(fvi); - } - unamep = unamebuf; -} - -/* - * GetVersionEx() returns 6.2 (aka Windows 8.1) since it was obsoleted - * so we had to switch to the recommended way to get the Windows version. - */ -const char * -ns_os_uname(void) { - if (unamep == NULL) { - getuname(); - } - return (unamep); -} diff --git a/bin/named-pkcs11/xfrout.c b/bin/named-pkcs11/xfrout.c deleted file mode 100644 index 7149825..0000000 --- a/bin/named-pkcs11/xfrout.c +++ /dev/null @@ -1,1745 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/*! \file - * \brief - * Outgoing AXFR and IXFR. - */ - -/* - * TODO: - * - IXFR over UDP - */ - -#define XFROUT_COMMON_LOGARGS \ - ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT - -#define XFROUT_PROTOCOL_LOGARGS \ - XFROUT_COMMON_LOGARGS, ISC_LOG_INFO - -#define XFROUT_DEBUG_LOGARGS(n) \ - XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) - -#define XFROUT_RR_LOGARGS \ - XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL - -#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - result = (code); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: %s (%s)", \ - msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILQ(code, msg, question, rdclass) \ - do { \ - char _buf1[DNS_NAME_FORMATSIZE]; \ - char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ - result = (code); \ - dns_name_format(question, _buf1, sizeof(_buf1)); \ - dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: '%s/%s': %s (%s)", \ - _buf1, _buf2, msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ - -static inline void -inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { - isc_stats_increment(ns_g_server->nsstats, counter); - if (zone != NULL) { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - } -} - -/**************************************************************************/ - -/*% Log an RR (for debugging) */ - -static void -log_rr(dns_name_t *name, dns_rdata_t *rdata, uint32_t ttl) { - isc_result_t result; - isc_buffer_t buf; - char mem[2000]; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdata_t rd = DNS_RDATA_INIT; - - dns_rdatalist_init(&rdl); - rdl.type = rdata->type; - rdl.rdclass = rdata->rdclass; - rdl.ttl = ttl; - if (rdata->type == dns_rdatatype_sig || - rdata->type == dns_rdatatype_rrsig) - rdl.covers = dns_rdata_covers(rdata); - else - rdl.covers = dns_rdatatype_none; - dns_rdataset_init(&rds); - dns_rdata_init(&rd); - dns_rdata_clone(rdata, &rd); - ISC_LIST_APPEND(rdl.rdata, &rd, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); - - isc_buffer_init(&buf, mem, sizeof(mem)); - result = dns_rdataset_totext(&rds, name, - false, false, &buf); - - /* - * We could use xfrout_log(), but that would produce - * very long lines with a repetitive prefix. - */ - if (result == ISC_R_SUCCESS) { - /* - * Get rid of final newline. - */ - INSIST(buf.used >= 1 && - ((char *) buf.base)[buf.used - 1] == '\n'); - buf.used--; - - isc_log_write(XFROUT_RR_LOGARGS, "%.*s", - (int)isc_buffer_usedlength(&buf), - (char *)isc_buffer_base(&buf)); - } else { - isc_log_write(XFROUT_RR_LOGARGS, ""); - } -} - -/**************************************************************************/ -/* - * An 'rrstream_t' is a polymorphic iterator that returns - * a stream of resource records. There are multiple implementations, - * e.g. for generating AXFR and IXFR records streams. - */ - -typedef struct rrstream_methods rrstream_methods_t; - -typedef struct rrstream { - isc_mem_t *mctx; - rrstream_methods_t *methods; -} rrstream_t; - -struct rrstream_methods { - isc_result_t (*first)(rrstream_t *); - isc_result_t (*next)(rrstream_t *); - void (*current)(rrstream_t *, - dns_name_t **, - uint32_t *, - dns_rdata_t **); - void (*pause)(rrstream_t *); - void (*destroy)(rrstream_t **); -}; - -static void -rrstream_noop_pause(rrstream_t *rs) { - UNUSED(rs); -} - -/**************************************************************************/ -/* - * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns - * an IXFR-like RR stream from a journal file. - * - * The SOA at the beginning of each sequence of additions - * or deletions are included in the stream, but the extra - * SOAs at the beginning and end of the entire transfer are - * not included. - */ - -typedef struct ixfr_rrstream { - rrstream_t common; - dns_journal_t *journal; -} ixfr_rrstream_t; - -/* Forward declarations. */ -static void -ixfr_rrstream_destroy(rrstream_t **sp); - -static rrstream_methods_t ixfr_rrstream_methods; - -/* - * Returns: anything dns_journal_open() or dns_journal_iter_init() - * may return. - */ - -static isc_result_t -ixfr_rrstream_create(isc_mem_t *mctx, - const char *journal_filename, - uint32_t begin_serial, - uint32_t end_serial, - rrstream_t **sp) -{ - ixfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &ixfr_rrstream_methods; - s->journal = NULL; - - CHECK(dns_journal_open(mctx, journal_filename, - DNS_JOURNAL_READ, &s->journal)); - CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - ixfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -ixfr_rrstream_first(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_first_rr(s->journal)); -} - -static isc_result_t -ixfr_rrstream_next(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_next_rr(s->journal)); -} - -static void -ixfr_rrstream_current(rrstream_t *rs, - dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - dns_journal_current_rr(s->journal, name, ttl, rdata); -} - -static void -ixfr_rrstream_destroy(rrstream_t **rsp) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; - if (s->journal != 0) - dns_journal_destroy(&s->journal); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t ixfr_rrstream_methods = { - ixfr_rrstream_first, - ixfr_rrstream_next, - ixfr_rrstream_current, - rrstream_noop_pause, - ixfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'axfr_rrstream_t' is an 'rrstream_t' that returns - * an AXFR-like RR stream from a database. - * - * The SOAs at the beginning and end of the transfer are - * not included in the stream. - */ - -typedef struct axfr_rrstream { - rrstream_t common; - dns_rriterator_t it; - bool it_valid; -} axfr_rrstream_t; - -/* - * Forward declarations. - */ -static void -axfr_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t axfr_rrstream_methods; - -static isc_result_t -axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - axfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &axfr_rrstream_methods; - s->it_valid = false; - - CHECK(dns_rriterator_init(&s->it, db, ver, 0)); - s->it_valid = true; - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - axfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -axfr_rrstream_first(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - result = dns_rriterator_first(&s->it); - if (result != ISC_R_SUCCESS) - return (result); - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - dns_rriterator_current(&s->it, &name_dummy, - &ttl_dummy, NULL, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - result = dns_rriterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -axfr_rrstream_next(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - result = dns_rriterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - dns_rriterator_current(&s->it, &name_dummy, - &ttl_dummy, NULL, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - } - return (result); -} - -static void -axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - dns_rriterator_current(&s->it, name, ttl, NULL, rdata); -} - -static void -axfr_rrstream_pause(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - dns_rriterator_pause(&s->it); -} - -static void -axfr_rrstream_destroy(rrstream_t **rsp) { - axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; - if (s->it_valid) - dns_rriterator_destroy(&s->it); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t axfr_rrstream_methods = { - axfr_rrstream_first, - axfr_rrstream_next, - axfr_rrstream_current, - axfr_rrstream_pause, - axfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns - * a single SOA record. - */ - -typedef struct soa_rrstream { - rrstream_t common; - dns_difftuple_t *soa_tuple; -} soa_rrstream_t; - -/* - * Forward declarations. - */ -static void -soa_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t soa_rrstream_methods; - -static isc_result_t -soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - soa_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &soa_rrstream_methods; - s->soa_tuple = NULL; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - &s->soa_tuple)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - soa_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -soa_rrstream_first(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_SUCCESS); -} - -static isc_result_t -soa_rrstream_next(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_NOMORE); -} - -static void -soa_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - soa_rrstream_t *s = (soa_rrstream_t *) rs; - *name = &s->soa_tuple->name; - *ttl = s->soa_tuple->ttl; - *rdata = &s->soa_tuple->rdata; -} - -static void -soa_rrstream_destroy(rrstream_t **rsp) { - soa_rrstream_t *s = (soa_rrstream_t *) *rsp; - if (s->soa_tuple != NULL) - dns_difftuple_free(&s->soa_tuple); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t soa_rrstream_methods = { - soa_rrstream_first, - soa_rrstream_next, - soa_rrstream_current, - rrstream_noop_pause, - soa_rrstream_destroy -}; - -/**************************************************************************/ -/* - * A 'compound_rrstream_t' objects owns a soa_rrstream - * and another rrstream, the "data stream". It returns - * a concatenated stream consisting of the soa_rrstream, then - * the data stream, then the soa_rrstream again. - * - * The component streams are owned by the compound_rrstream_t - * and are destroyed with it. - */ - -typedef struct compound_rrstream { - rrstream_t common; - rrstream_t *components[3]; - int state; - isc_result_t result; -} compound_rrstream_t; - -/* - * Forward declarations. - */ -static void -compound_rrstream_destroy(rrstream_t **rsp); - -static isc_result_t -compound_rrstream_next(rrstream_t *rs); - -static rrstream_methods_t compound_rrstream_methods; - -/* - * Requires: - * soa_stream != NULL && *soa_stream != NULL - * data_stream != NULL && *data_stream != NULL - * sp != NULL && *sp == NULL - * - * Ensures: - * *soa_stream == NULL - * *data_stream == NULL - * *sp points to a valid compound_rrstream_t - * The soa and data streams will be destroyed - * when the compound_rrstream_t is destroyed. - */ -static isc_result_t -compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, - rrstream_t **data_stream, rrstream_t **sp) -{ - compound_rrstream_t *s; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &compound_rrstream_methods; - s->components[0] = *soa_stream; - s->components[1] = *data_stream; - s->components[2] = *soa_stream; - s->state = -1; - s->result = ISC_R_FAILURE; - - *soa_stream = NULL; - *data_stream = NULL; - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); -} - -static isc_result_t -compound_rrstream_first(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - s->state = 0; - do { - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } while (s->result == ISC_R_NOMORE && s->state < 2); - return (s->result); -} - -static isc_result_t -compound_rrstream_next(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->next(curstream); - while (s->result == ISC_R_NOMORE) { - /* - * Make sure locks held by the current stream - * are released before we switch streams. - */ - curstream->methods->pause(curstream); - if (s->state == 2) - return (ISC_R_NOMORE); - s->state++; - curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } - return (s->result); -} - -static void -compound_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - INSIST(s->result == ISC_R_SUCCESS); - curstream = s->components[s->state]; - curstream->methods->current(curstream, name, ttl, rdata); -} - -static void -compound_rrstream_pause(rrstream_t *rs) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - curstream = s->components[s->state]; - curstream->methods->pause(curstream); -} - -static void -compound_rrstream_destroy(rrstream_t **rsp) { - compound_rrstream_t *s = (compound_rrstream_t *) *rsp; - s->components[0]->methods->destroy(&s->components[0]); - s->components[1]->methods->destroy(&s->components[1]); - s->components[2] = NULL; /* Copy of components[0]. */ - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t compound_rrstream_methods = { - compound_rrstream_first, - compound_rrstream_next, - compound_rrstream_current, - compound_rrstream_pause, - compound_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR - * in progress. - */ - -typedef struct { - isc_mem_t *mctx; - ns_client_t *client; - unsigned int id; /* ID of request */ - dns_name_t *qname; /* Question name of request */ - dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ - dns_rdataclass_t qclass; - dns_zone_t *zone; /* (necessary for stats) */ - dns_db_t *db; - dns_dbversion_t *ver; - isc_quota_t *quota; - rrstream_t *stream; /* The XFR RR stream */ - bool end_of_stream; /* EOS has been reached */ - isc_buffer_t buf; /* Buffer for message owner - names and rdatas */ - isc_buffer_t txlenbuf; /* Transmit length buffer */ - isc_buffer_t txbuf; /* Transmit message buffer */ - void *txmem; - unsigned int txmemlen; - unsigned int nmsg; /* Number of messages sent */ - dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ - isc_buffer_t *lasttsig; /* the last TSIG */ - bool verified_tsig; /* verified request MAC */ - bool many_answers; - int sends; /* Send in progress */ - bool shuttingdown; - const char *mnemonic; /* Style of transfer */ -} xfrout_ctx_t; - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, - unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, - bool verified_tsig, - unsigned int maxtime, - unsigned int idletime, - bool many_answers, - xfrout_ctx_t **xfrp); - -static void -sendstream(xfrout_ctx_t *xfr); - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event); - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr); - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp); - -static void -xfrout_client_shutdown(void *arg, isc_result_t result); - -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -/**************************************************************************/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { - isc_result_t result; - dns_name_t *question_name; - dns_rdataset_t *question_rdataset; - dns_zone_t *zone = NULL, *raw = NULL, *mayberaw; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rdataclass_t question_class; - rrstream_t *soa_stream = NULL; - rrstream_t *data_stream = NULL; - rrstream_t *stream = NULL; - dns_difftuple_t *current_soa_tuple = NULL; - dns_name_t *soa_name; - dns_rdataset_t *soa_rdataset; - dns_rdata_t soa_rdata = DNS_RDATA_INIT; - bool have_soa = false; - const char *mnemonic = NULL; - isc_mem_t *mctx = client->mctx; - dns_message_t *request = client->message; - xfrout_ctx_t *xfr = NULL; - isc_quota_t *quota = NULL; - dns_transfer_format_t format = client->view->transfer_format; - isc_netaddr_t na; - dns_peer_t *peer = NULL; - isc_buffer_t *tsigbuf = NULL; - char *journalfile; - char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; - char keyname[DNS_NAME_FORMATSIZE]; - bool is_poll = false; - bool is_dlz = false; - bool is_ixfr = false; - uint32_t begin_serial = 0, current_serial; - - switch (reqtype) { - case dns_rdatatype_axfr: - mnemonic = "AXFR"; - break; - case dns_rdatatype_ixfr: - mnemonic = "IXFR"; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - ns_client_log(client, - DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(6), "%s request", mnemonic); - /* - * Apply quota. - */ - result = isc_quota_attach(&ns_g_server->xfroutquota, "a); - if (result != ISC_R_SUCCESS) { - isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, - "%s request denied: %s", mnemonic, - isc_result_totext(result)); - goto failure; - } - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - - /* - * The question section must contain exactly one question, and - * it must be for AXFR/IXFR as appropriate. - */ - question_name = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); - question_rdataset = ISC_LIST_HEAD(question_name->list); - question_class = question_rdataset->rdclass; - INSIST(question_rdataset->type == reqtype); - if (ISC_LIST_NEXT(question_rdataset, link) != NULL) { - FAILC(DNS_R_FORMERR, "multiple questions"); - } - result = dns_message_nextname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) { - FAILC(DNS_R_FORMERR, "multiple questions"); - } - - result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, - &zone); - - if (result != ISC_R_SUCCESS || dns_zone_gettype(zone) == dns_zone_dlz) { - /* - * The normal zone table does not have a match, or this is - * marked in the zone table as a DLZ zone. Check the DLZ - * databases for a match. - */ - if (! ISC_LIST_EMPTY(client->view->dlz_searched)) { - result = dns_dlzallowzonexfr(client->view, - question_name, - &client->peeraddr, - &db); - - if (result == ISC_R_NOPERM) { - char _buf1[DNS_NAME_FORMATSIZE]; - char _buf2[DNS_RDATACLASS_FORMATSIZE]; - - result = DNS_R_REFUSED; - dns_name_format(question_name, _buf1, - sizeof(_buf1)); - dns_rdataclass_format(question_class, - _buf2, sizeof(_buf2)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_ERROR, - "zone transfer '%s/%s' denied", - _buf1, _buf2); - goto failure; - } - if (result != ISC_R_SUCCESS) - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - is_dlz = true; - } else { - /* - * not DLZ and not in normal zone table, we are - * not authoritative - */ - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - } else { - /* zone table has a match */ - switch(dns_zone_gettype(zone)) { - /* Master and slave zones are OK for transfer. */ - case dns_zone_master: - case dns_zone_slave: - case dns_zone_dlz: - break; - default: - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - CHECK(dns_zone_getdb(zone, &db)); - dns_db_currentversion(db, &ver); - } - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s question section OK", mnemonic); - - /* - * Check the authority section. Look for a SOA record with - * the same name and class as the question. - */ - for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) - { - soa_name = NULL; - dns_message_currentname(request, DNS_SECTION_AUTHORITY, - &soa_name); - - /* - * Ignore data whose owner name is not the zone apex. - */ - if (! dns_name_equal(soa_name, question_name)) { - continue; - } - - for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); - soa_rdataset != NULL; - soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) - { - /* - * Ignore non-SOA data. - */ - if (soa_rdataset->type != dns_rdatatype_soa) { - continue; - } - if (soa_rdataset->rdclass != question_class) { - continue; - } - - CHECK(dns_rdataset_first(soa_rdataset)); - dns_rdataset_current(soa_rdataset, &soa_rdata); - result = dns_rdataset_next(soa_rdataset); - if (result == ISC_R_SUCCESS) { - FAILC(DNS_R_FORMERR, - "IXFR authority section " - "has multiple SOAs"); - } - have_soa = true; - goto got_soa; - } - } - got_soa: - if (result != ISC_R_NOMORE) { - CHECK(result); - } - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s authority section OK", mnemonic); - - /* - * If not a DLZ zone, decide whether to allow this transfer. - */ - if (!is_dlz) { - ns_client_aclmsg("zone transfer", question_name, reqtype, - client->view->rdclass, msg, sizeof(msg)); - CHECK(ns_client_checkacl(client, NULL, msg, - dns_zone_getxfracl(zone), - true, ISC_LOG_ERROR)); - } - - /* - * AXFR over UDP is not possible. - */ - if (reqtype == dns_rdatatype_axfr && - (client->attributes & NS_CLIENTATTR_TCP) == 0) { - FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); - } - - /* - * Look up the requesting server in the peer table. - */ - isc_netaddr_fromsockaddr(&na, &client->peeraddr); - (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); - - /* - * Decide on the transfer format (one-answer or many-answers). - */ - if (peer != NULL) { - (void)dns_peer_gettransferformat(peer, &format); - } - - /* - * Get a dynamically allocated copy of the current SOA. - */ - if (is_dlz) - dns_db_currentversion(db, &ver); - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - ¤t_soa_tuple)); - - current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); - if (reqtype == dns_rdatatype_ixfr) { - if (!have_soa) { - FAILC(DNS_R_FORMERR, "IXFR request missing SOA"); - } - - begin_serial = dns_soa_getserial(&soa_rdata); - - /* - * RFC1995 says "If an IXFR query with the same or - * newer version number than that of the server - * is received, it is replied to with a single SOA - * record of the server's current version, just as - * in AXFR". The claim about AXFR is incorrect, - * but other than that, we do as the RFC says. - * - * Sending a single SOA record is also how we refuse - * IXFR over UDP (currently, we always do). - */ - if (DNS_SERIAL_GE(begin_serial, current_serial) || - (client->attributes & NS_CLIENTATTR_TCP) == 0) - { - CHECK(soa_rrstream_create(mctx, db, ver, &stream)); - is_poll = true; - goto have_stream; - } - - /* - * Outgoing IXFR may have been disabled for this peer - * or globally. - */ - if ((client->attributes & NS_CLIENTATTR_TCP) != 0) { - bool provide_ixfr; - - provide_ixfr = client->view->provideixfr; - if (peer != NULL) { - (void)dns_peer_getprovideixfr(peer, - &provide_ixfr); - } - if (!provide_ixfr) { - xfrout_log1(client, question_name, - question_class, ISC_LOG_DEBUG(4), - "IXFR delta response disabled due " - "to 'provide-ixfr no;' being set"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - } - - journalfile = is_dlz ? NULL : dns_zone_getjournal(zone); - if (journalfile != NULL) { - result = ixfr_rrstream_create(mctx, - journalfile, - begin_serial, - current_serial, - &data_stream); - } else { - result = ISC_R_NOTFOUND; - } - if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(4), - "IXFR version not in journal, " - "falling back to AXFR"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - CHECK(result); - is_ixfr = true; - } else { - axfr_fallback: - CHECK(axfr_rrstream_create(mctx, db, ver, &data_stream)); - } - - /* - * Bracket the data stream with SOAs. - */ - CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); - CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, - &stream)); - soa_stream = NULL; - 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. - */ - - - - if (is_dlz) { - CHECK(xfrout_ctx_create(mctx, client, request->id, - question_name, reqtype, question_class, - zone, db, ver, quota, stream, - dns_message_gettsigkey(request), - tsigbuf, - request->verified_sig, - 3600, - 3600, - (format == dns_many_answers) ? - true : false, - &xfr)); - } else { - CHECK(xfrout_ctx_create(mctx, client, request->id, - question_name, reqtype, question_class, - zone, db, ver, quota, stream, - dns_message_gettsigkey(request), - tsigbuf, - request->verified_sig, - dns_zone_getmaxxfrout(zone), - dns_zone_getidleout(zone), - (format == dns_many_answers) ? - true : false, - &xfr)); - } - - xfr->mnemonic = mnemonic; - stream = NULL; - quota = NULL; - - CHECK(xfr->stream->methods->first(xfr->stream)); - - if (xfr->tsigkey != NULL) { - dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); - } else { - keyname[0] = '\0'; - } - if (is_poll) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - } else if (is_ixfr) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s (serial %u -> %u)", - mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", - keyname, begin_serial, current_serial); - } else { - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s (serial %u)", - mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", - keyname, current_serial); - } - - - if (zone != NULL) { - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 && - dns_zone_gettype(mayberaw) == dns_zone_slave) { - isc_time_t expiretime; - uint32_t secs; - dns_zone_getexpiretime(zone, &expiretime); - secs = isc_time_seconds(&expiretime); - if (secs >= client->now && result == ISC_R_SUCCESS) { - client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; - client->expire = secs - client->now; - } - } - if (raw != NULL) { - dns_zone_detach(&raw); - } - } - - /* - * Hand the context over to sendstream(). Set xfr to NULL; - * sendstream() is responsible for either passing the - * context on to a later event handler or destroying it. - */ - sendstream(xfr); - xfr = NULL; - - result = ISC_R_SUCCESS; - - failure: - if (result == DNS_R_REFUSED) { - inc_stats(zone, dns_nsstatscounter_xfrrej); - } - if (quota != NULL) { - isc_quota_detach("a); - } - if (current_soa_tuple != NULL) { - dns_difftuple_free(¤t_soa_tuple); - } - if (stream != NULL) { - stream->methods->destroy(&stream); - } - if (soa_stream != NULL) { - soa_stream->methods->destroy(&soa_stream); - } - if (data_stream != NULL) { - data_stream->methods->destroy(&data_stream); - } - if (ver != NULL) { - dns_db_closeversion(db, &ver, false); - } - if (db != NULL) { - dns_db_detach(&db); - } - if (zone != NULL) { - dns_zone_detach(&zone); - } - /* XXX kludge */ - if (xfr != NULL) { - xfrout_fail(xfr, result, "setting up zone transfer"); - } else if (result != ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(3), "zone transfer setup failed"); - ns_client_error(client, result); - } -} - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, - dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, bool verified_tsig, - unsigned int maxtime, unsigned int idletime, - bool many_answers, xfrout_ctx_t **xfrp) -{ - xfrout_ctx_t *xfr; - isc_result_t result; - unsigned int len; - void *mem; - - INSIST(xfrp != NULL && *xfrp == NULL); - xfr = isc_mem_get(mctx, sizeof(*xfr)); - if (xfr == NULL) - return (ISC_R_NOMEMORY); - xfr->mctx = NULL; - isc_mem_attach(mctx, &xfr->mctx); - xfr->client = NULL; - ns_client_attach(client, &xfr->client); - xfr->id = id; - xfr->qname = qname; - xfr->qtype = qtype; - xfr->qclass = qclass; - xfr->zone = NULL; - xfr->db = NULL; - xfr->ver = NULL; - if (zone != NULL) /* zone will be NULL if it's DLZ */ - dns_zone_attach(zone, &xfr->zone); - dns_db_attach(db, &xfr->db); - dns_db_attachversion(db, ver, &xfr->ver); - xfr->end_of_stream = false; - xfr->tsigkey = tsigkey; - xfr->lasttsig = lasttsig; - xfr->verified_tsig = verified_tsig; - xfr->nmsg = 0; - xfr->many_answers = many_answers; - xfr->sends = 0; - xfr->shuttingdown = false; - xfr->mnemonic = NULL; - xfr->buf.base = NULL; - xfr->buf.length = 0; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->stream = NULL; - xfr->quota = NULL; - - /* - * Allocate a temporary buffer for the uncompressed response - * message data. The size should be no more than 65535 bytes - * so that the compressed data will fit in a TCP message, - * and no less than 65535 bytes so that an almost maximum-sized - * RR will fit. Note that although 65535-byte RRs are allowed - * in principle, they cannot be zone-transferred (at least not - * if uncompressible), because the message and RR headers would - * push the size of the TCP message over the 65536 byte limit. - */ - len = 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->buf, mem, len); - - /* - * Allocate another temporary buffer for the compressed - * response message and its TCP length prefix. - */ - len = 2 + 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->txlenbuf, mem, 2); - isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); - xfr->txmem = mem; - xfr->txmemlen = len; - - CHECK(dns_timer_setidle(xfr->client->timer, - maxtime, idletime, false)); - - /* - * Register a shutdown callback with the client, so that we - * can stop the transfer immediately when the client task - * gets a shutdown event. - */ - xfr->client->shutdown = xfrout_client_shutdown; - xfr->client->shutdown_arg = xfr; - /* - * These MUST be after the last "goto failure;" / CHECK to - * prevent a double free by the caller. - */ - xfr->quota = quota; - xfr->stream = stream; - - *xfrp = xfr; - return (ISC_R_SUCCESS); - -failure: - xfrout_ctx_destroy(&xfr); - return (result); -} - - -/* - * Arrange to send as much as we can of "stream" without blocking. - * - * Requires: - * The stream iterator is initialized and points at an RR, - * or possibly at the end of the stream (that is, the - * _first method of the iterator has been called). - */ -static void -sendstream(xfrout_ctx_t *xfr) { - dns_message_t *tcpmsg = NULL; - dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ - isc_result_t result; - isc_region_t used; - isc_region_t region; - dns_rdataset_t *qrdataset; - dns_name_t *msgname = NULL; - dns_rdata_t *msgrdata = NULL; - dns_rdatalist_t *msgrdl = NULL; - dns_rdataset_t *msgrds = NULL; - dns_compress_t cctx; - bool cleanup_cctx = false; - bool is_tcp; - - int n_rrs; - - isc_buffer_clear(&xfr->buf); - isc_buffer_clear(&xfr->txlenbuf); - isc_buffer_clear(&xfr->txbuf); - - is_tcp = ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0); - if (!is_tcp) { - /* - * In the UDP case, we put the response data directly into - * the client message. - */ - msg = xfr->client->message; - CHECK(dns_message_reply(msg, true)); - } else { - /* - * TCP. Build a response dns_message_t, temporarily storing - * the raw, uncompressed owner names and RR data contiguously - * in xfr->buf. We know that if the uncompressed data fits - * in xfr->buf, the compressed data will surely fit in a TCP - * message. - */ - - CHECK(dns_message_create(xfr->mctx, - DNS_MESSAGE_INTENTRENDER, &tcpmsg)); - msg = tcpmsg; - - msg->id = xfr->id; - msg->rcode = dns_rcode_noerror; - msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; - if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) - msg->flags |= DNS_MESSAGEFLAG_RA; - CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); - CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - msg->verified_sig = xfr->verified_tsig; - - /* - * Add a EDNS option to the message? - */ - if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { - dns_rdataset_t *opt = NULL; - - CHECK(ns_client_addopt(xfr->client, msg, &opt)); - CHECK(dns_message_setopt(msg, opt)); - /* - * Add to first message only. - */ - xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID; - xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE; - } - - /* - * Account for reserved space. - */ - if (xfr->tsigkey != NULL) - INSIST(msg->reserved != 0U); - isc_buffer_add(&xfr->buf, msg->reserved); - - /* - * Include a question section in the first message only. - * BIND 8.2.1 will not recognize an IXFR if it does not - * have a question section. - */ - if (xfr->nmsg == 0) { - dns_name_t *qname = NULL; - isc_region_t r; - - /* - * Reserve space for the 12-byte message header - * and 4 bytes of question. - */ - isc_buffer_add(&xfr->buf, 12 + 4); - - qrdataset = NULL; - result = dns_message_gettemprdataset(msg, &qrdataset); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_makequestion(qrdataset, - xfr->client->message->rdclass, - xfr->qtype); - - result = dns_message_gettempname(msg, &qname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(qname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= xfr->qname->length); - r.length = xfr->qname->length; - isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, - xfr->qname->length); - dns_name_fromregion(qname, &r); - ISC_LIST_INIT(qname->list); - ISC_LIST_APPEND(qname->list, qrdataset, link); - - dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - } else { - /* - * Reserve space for the 12-byte message header - */ - isc_buffer_add(&xfr->buf, 12); - msg->tcp_continuation = 1; - } - } - - /* - * Try to fit in as many RRs as possible, unless "one-answer" - * format has been requested. - */ - for (n_rrs = 0; ; n_rrs++) { - dns_name_t *name = NULL; - uint32_t ttl; - dns_rdata_t *rdata = NULL; - - unsigned int size; - isc_region_t r; - - msgname = NULL; - msgrdata = NULL; - msgrdl = NULL; - msgrds = NULL; - - xfr->stream->methods->current(xfr->stream, - &name, &ttl, &rdata); - size = name->length + 10 + rdata->length; - isc_buffer_availableregion(&xfr->buf, &r); - if (size >= r.length) { - /* - * RR would not fit. If there are other RRs in the - * buffer, send them now and leave this RR to the - * next message. If this RR overflows the buffer - * all by itself, fail. - * - * In theory some RRs might fit in a TCP message - * when compressed even if they do not fit when - * uncompressed, but surely we don't want - * to send such monstrosities to an unsuspecting - * slave. - */ - if (n_rrs == 0) { - xfrout_log(xfr, ISC_LOG_WARNING, - "RR too large for zone transfer " - "(%d bytes)", size); - /* XXX DNS_R_RRTOOLARGE? */ - result = ISC_R_NOSPACE; - goto failure; - } - break; - } - - if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) - log_rr(name, rdata, ttl); /* XXX */ - - result = dns_message_gettempname(msg, &msgname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(msgname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= name->length); - r.length = name->length; - isc_buffer_putmem(&xfr->buf, name->ndata, name->length); - dns_name_fromregion(msgname, &r); - - /* Reserve space for RR header. */ - isc_buffer_add(&xfr->buf, 10); - - result = dns_message_gettemprdata(msg, &msgrdata); - if (result != ISC_R_SUCCESS) - goto failure; - isc_buffer_availableregion(&xfr->buf, &r); - r.length = rdata->length; - isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); - dns_rdata_init(msgrdata); - dns_rdata_fromregion(msgrdata, - rdata->rdclass, rdata->type, &r); - - result = dns_message_gettemprdatalist(msg, &msgrdl); - if (result != ISC_R_SUCCESS) - goto failure; - msgrdl->type = rdata->type; - msgrdl->rdclass = rdata->rdclass; - msgrdl->ttl = ttl; - if (rdata->type == dns_rdatatype_sig || - rdata->type == dns_rdatatype_rrsig) - msgrdl->covers = dns_rdata_covers(rdata); - else - msgrdl->covers = dns_rdatatype_none; - ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); - - result = dns_message_gettemprdataset(msg, &msgrds); - if (result != ISC_R_SUCCESS) - goto failure; - result = dns_rdatalist_tordataset(msgrdl, msgrds); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_APPEND(msgname->list, msgrds, link); - - dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); - msgname = NULL; - - result = xfr->stream->methods->next(xfr->stream); - if (result == ISC_R_NOMORE) { - xfr->end_of_stream = true; - break; - } - CHECK(result); - - if (! xfr->many_answers) - break; - /* - * At this stage, at least 1 RR has been rendered into - * the message. Check if we want to clamp this message - * here (TCP only). - */ - if ((isc_buffer_usedlength(&xfr->buf) >= - ns_g_server->transfer_tcp_message_size) && is_tcp) - break; - } - - if (is_tcp) { - CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); - dns_compress_setsensitive(&cctx, true); - cleanup_cctx = true; - CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); - CHECK(dns_message_renderend(msg)); - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - - isc_buffer_usedregion(&xfr->txbuf, &used); - isc_buffer_putuint16(&xfr->txlenbuf, - (uint16_t)used.length); - region.base = xfr->txlenbuf.base; - region.length = 2 + used.length; - xfrout_log(xfr, ISC_LOG_DEBUG(8), - "sending TCP message of %d bytes", - used.length); - CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ - ®ion, xfr->client->task, - xfrout_senddone, - xfr)); - xfr->sends++; - } else { - xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); - ns_client_send(xfr->client); - xfr->stream->methods->pause(xfr->stream); - xfrout_ctx_destroy(&xfr); - return; - } - - /* Advance lasttsig to be the last TSIG generated */ - CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); - - xfr->nmsg++; - - failure: - if (msgname != NULL) { - if (msgrds != NULL) { - if (dns_rdataset_isassociated(msgrds)) - dns_rdataset_disassociate(msgrds); - dns_message_puttemprdataset(msg, &msgrds); - } - if (msgrdl != NULL) { - ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); - dns_message_puttemprdatalist(msg, &msgrdl); - } - if (msgrdata != NULL) - dns_message_puttemprdata(msg, &msgrdata); - dns_message_puttempname(msg, &msgname); - } - - if (tcpmsg != NULL) - dns_message_detach(&tcpmsg); - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - /* - * Make sure to release any locks held by database - * iterators before returning from the event handler. - */ - xfr->stream->methods->pause(xfr->stream); - - if (result == ISC_R_SUCCESS) - return; - - xfrout_fail(xfr, result, "sending zone data"); -} - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { - xfrout_ctx_t *xfr = *xfrp; - ns_client_t *client = NULL; - - INSIST(xfr->sends == 0); - - xfr->client->shutdown = NULL; - xfr->client->shutdown_arg = NULL; - - if (xfr->stream != NULL) - xfr->stream->methods->destroy(&xfr->stream); - if (xfr->buf.base != NULL) - 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) - isc_buffer_free(&xfr->lasttsig); - if (xfr->quota != NULL) - isc_quota_detach(&xfr->quota); - if (xfr->ver != NULL) - dns_db_closeversion(xfr->db, &xfr->ver, false); - if (xfr->zone != NULL) - dns_zone_detach(&xfr->zone); - if (xfr->db != NULL) - dns_db_detach(&xfr->db); - - /* - * We want to detch the client after we have released the memory - * context as ns_client_detach checks the memory reference count. - */ - ns_client_attach(xfr->client, &client); - ns_client_detach(&xfr->client); - isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); - ns_client_detach(&client); - - *xfrp = NULL; -} - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sev = (isc_socketevent_t *)event; - xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; - isc_result_t evresult = sev->result; - - UNUSED(task); - - INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - isc_event_free(&event); - xfr->sends--; - INSIST(xfr->sends == 0); - - (void)isc_timer_touch(xfr->client->timer); - if (xfr->shuttingdown == true) { - xfrout_maybe_destroy(xfr); - } else if (evresult != ISC_R_SUCCESS) { - xfrout_fail(xfr, evresult, "send"); - } else if (xfr->end_of_stream == false) { - sendstream(xfr); - } else { - /* End of zone transfer stream. */ - inc_stats(xfr->zone, dns_nsstatscounter_xfrdone); - xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); - ns_client_next(xfr->client, ISC_R_SUCCESS); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { - xfr->shuttingdown = true; - xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", - msg, isc_result_totext(result)); - xfrout_maybe_destroy(xfr); -} - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr) { - INSIST(xfr->shuttingdown == true); - if (xfr->sends > 0) { - /* - * If we are currently sending, cancel it and wait for - * cancel event before destroying the context. - */ - isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, - ISC_SOCKCANCEL_SEND); - } else { - ns_client_next(xfr->client, ISC_R_CANCELED); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_client_shutdown(void *arg, isc_result_t result) { - xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; - xfrout_fail(xfr, result, "aborted"); -} - -/* - * Log outgoing zone transfer messages in a format like - * : transfer of : - */ - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) - ISC_FORMAT_PRINTF(5, 0); - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, level, - "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); -} - -/* - * Logging function for use when a xfrout_ctx_t has not yet been created. - */ -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(client, zonename, rdclass, level, fmt, ap); - va_end(ap); -} - -/* - * Logging function for use when there is a xfrout_ctx_t. - */ -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); - va_end(ap); -} diff --git a/bin/named-pkcs11/zoneconf.c b/bin/named-pkcs11/zoneconf.c deleted file mode 100644 index fa6dbf9..0000000 --- a/bin/named-pkcs11/zoneconf.c +++ /dev/null @@ -1,1851 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* ACLs associated with zone */ -typedef enum { - allow_notify, - allow_query, - allow_query_on, - allow_transfer, - allow_update, - allow_update_forwarding -} acl_type_t; - -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -/*% - * Convenience function for configuring a single zone ACL. - */ -static isc_result_t -configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, - const cfg_obj_t *config, acl_type_t acltype, - cfg_aclconfctx_t *actx, dns_zone_t *zone, - void (*setzacl)(dns_zone_t *, dns_acl_t *), - void (*clearzacl)(dns_zone_t *)) -{ - isc_result_t result; - const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL}; - const cfg_obj_t *aclobj = NULL; - int i = 0; - dns_acl_t **aclp = NULL, *acl = NULL; - const char *aclname; - dns_view_t *view; - - view = dns_zone_getview(zone); - - switch (acltype) { - case allow_notify: - if (view != NULL) - aclp = &view->notifyacl; - aclname = "allow-notify"; - break; - case allow_query: - if (view != NULL) - aclp = &view->queryacl; - aclname = "allow-query"; - break; - case allow_query_on: - if (view != NULL) - aclp = &view->queryonacl; - aclname = "allow-query-on"; - break; - case allow_transfer: - if (view != NULL) - aclp = &view->transferacl; - aclname = "allow-transfer"; - break; - case allow_update: - if (view != NULL) - aclp = &view->updateacl; - aclname = "allow-update"; - break; - case allow_update_forwarding: - if (view != NULL) - aclp = &view->upfwdacl; - aclname = "allow-update-forwarding"; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - /* First check to see if ACL is defined within the zone */ - if (zconfig != NULL) { - maps[0] = cfg_tuple_get(zconfig, "options"); - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj != NULL) { - aclp = NULL; - goto parse_acl; - } - } - - /* Failing that, see if there's a default ACL already in the view */ - if (aclp != NULL && *aclp != NULL) { - (*setzacl)(zone, *aclp); - return (ISC_R_SUCCESS); - } - - /* Check for default ACLs that haven't been parsed yet */ - if (vconfig != NULL) { - const cfg_obj_t *options = cfg_tuple_get(vconfig, "options"); - if (options != NULL) - maps[i++] = options; - } - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - (*clearzacl)(zone); - return (ISC_R_SUCCESS); - } - -parse_acl: - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, - dns_zone_getmctx(zone), 0, &acl); - if (result != ISC_R_SUCCESS) - return (result); - (*setzacl)(zone, acl); - - /* Set the view default now */ - if (aclp != NULL) - dns_acl_attach(acl, aclp); - - dns_acl_detach(&acl); - return (ISC_R_SUCCESS); -} - -/*% - * Parse the zone update-policy statement. - */ -static isc_result_t -configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, - const char *zname) -{ - const cfg_obj_t *updatepolicy = NULL; - const cfg_listelt_t *element, *element2; - dns_ssutable_t *table = NULL; - isc_mem_t *mctx = dns_zone_getmctx(zone); - bool autoddns = false; - isc_result_t result; - - (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); - - if (updatepolicy == NULL) { - dns_zone_setssutable(zone, NULL); - return (ISC_R_SUCCESS); - } - - if (cfg_obj_isstring(updatepolicy) && - strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) { - autoddns = true; - updatepolicy = NULL; - } - - result = dns_ssutable_create(mctx, &table); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(updatepolicy); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *stmt = cfg_listelt_value(element); - const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); - const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); - const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); - const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); - const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); - const char *str; - bool grant = false; - bool usezone = false; - dns_ssumatchtype_t mtype = DNS_SSUMATCHTYPE_NAME; - dns_fixedname_t fname, fident; - isc_buffer_t b; - dns_rdatatype_t *types; - unsigned int i, n; - - str = cfg_obj_asstring(mode); - if (strcasecmp(str, "grant") == 0) { - grant = true; - } else if (strcasecmp(str, "deny") == 0) { - grant = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - str = cfg_obj_asstring(matchtype); - CHECK(dns_ssu_mtypefromstring(str, &mtype)); - if (mtype == dns_ssumatchtype_subdomain && - strcasecmp(str, "zonesub") == 0) { - usezone = true; - } - - dns_fixedname_init(&fident); - str = cfg_obj_asstring(identity); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fident), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - dns_fixedname_init(&fname); - if (usezone) { - result = dns_name_copy(dns_zone_getorigin(zone), - dns_fixedname_name(&fname), - NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "error copying origin: %s", - isc_result_totext(result)); - goto cleanup; - } - } else { - str = cfg_obj_asstring(dname); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fname), - &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - } - - n = ns_config_listcount(typelist); - if (n == 0) - types = NULL; - else { - types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); - if (types == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - i = 0; - for (element2 = cfg_list_first(typelist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - const cfg_obj_t *typeobj; - isc_textregion_t r; - - INSIST(i < n); - - typeobj = cfg_listelt_value(element2); - str = cfg_obj_asstring(typeobj); - DE_CONST(str, r.base); - r.length = strlen(str); - - result = dns_rdatatype_fromtext(&types[i++], &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid type", str); - isc_mem_put(mctx, types, - n * sizeof(dns_rdatatype_t)); - goto cleanup; - } - } - INSIST(i == n); - - result = dns_ssutable_addrule(table, grant, - dns_fixedname_name(&fident), - mtype, - dns_fixedname_name(&fname), - n, types); - if (types != NULL) - isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - - /* - * If "update-policy local;" and a session key exists, - * then use the default policy, which is equivalent to: - * update-policy { grant zonesub any; }; - */ - if (autoddns) { - dns_rdatatype_t any = dns_rdatatype_any; - - if (ns_g_server->session_keyname == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to enable auto DDNS policy " - "for zone %s: session key not found", - zname); - result = ISC_R_NOTFOUND; - goto cleanup; - } - - result = dns_ssutable_addrule(table, true, - ns_g_server->session_keyname, - DNS_SSUMATCHTYPE_LOCAL, - dns_zone_getorigin(zone), - 1, &any); - - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - result = ISC_R_SUCCESS; - dns_zone_setssutable(zone, table); - - cleanup: - dns_ssutable_detach(&table); - return (result); -} - -/* - * This is the TTL used for internally generated RRsets for static-stub zones. - * The value doesn't matter because the mapping is static, but needs to be - * defined for the sake of implementation. - */ -#define STATICSTUB_SERVER_TTL 86400 - -/*% - * Configure an apex NS with glues for a static-stub zone. - * For example, for the zone named "example.com", the following RRs will be - * added to the zone DB: - * example.com. NS example.com. - * example.com. A 192.0.2.1 - * example.com. AAAA 2001:db8::1 - */ -static isc_result_t -configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone, - dns_rdatalist_t *rdatalist_ns, - dns_rdatalist_t *rdatalist_a, - dns_rdatalist_t *rdatalist_aaaa) -{ - const cfg_listelt_t *element; - isc_mem_t *mctx = dns_zone_getmctx(zone); - isc_region_t region, sregion; - dns_rdata_t *rdata; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(zconfig); - element != NULL; - element = cfg_list_next(element)) - { - const isc_sockaddr_t* sa; - isc_netaddr_t na; - const cfg_obj_t *address = cfg_listelt_value(element); - dns_rdatalist_t *rdatalist; - - sa = cfg_obj_assockaddr(address); - if (isc_sockaddr_getport(sa) != 0) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "port is not configurable for " - "static stub server-addresses"); - return (ISC_R_FAILURE); - } - isc_netaddr_fromsockaddr(&na, sa); - if (isc_netaddr_getzone(&na) != 0) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "scoped address is not allowed " - "for static stub " - "server-addresses"); - return (ISC_R_FAILURE); - } - - switch (na.family) { - case AF_INET: - region.length = sizeof(na.type.in); - rdatalist = rdatalist_a; - break; - default: - INSIST(na.family == AF_INET6); - region.length = sizeof(na.type.in6); - rdatalist = rdatalist_aaaa; - break; - } - - rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, &na.type, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - rdatalist->type, ®ion); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - } - - /* - * If no address is specified (unlikely in this context, but possible), - * there's nothing to do anymore. - */ - if (ISC_LIST_EMPTY(rdatalist_a->rdata) && - ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) { - return (ISC_R_SUCCESS); - } - - /* Add to the list an apex NS with the ns name being the origin name */ - dns_name_toregion(dns_zone_getorigin(zone), &sregion); - rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); - if (rdata == NULL) { - /* - * Already allocated data will be freed in the caller, so - * we can simply return here. - */ - return (ISC_R_NOMEMORY); - } - region.length = sregion.length; - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, sregion.base, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - dns_rdatatype_ns, ®ion); - ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link); - - return (result); -} - -/*% - * Configure an apex NS with an out-of-zone NS names for a static-stub zone. - * For example, for the zone named "example.com", something like the following - * RRs will be added to the zone DB: - * example.com. NS ns.example.net. - */ -static isc_result_t -configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone, - dns_rdatalist_t *rdatalist, const char *zname) -{ - const cfg_listelt_t *element; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_rdata_t *rdata; - isc_region_t sregion, region; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(zconfig); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed_name; - dns_name_t *nsname; - isc_buffer_t b; - - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - - nsname = dns_fixedname_initname(&fixed_name); - - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "server-name '%s' is not a valid " - "name", str); - return (result); - } - if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "server-name '%s' must not be a " - "subdomain of zone name '%s'", - str, zname); - return (ISC_R_FAILURE); - } - - dns_name_toregion(nsname, &sregion); - rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - region.length = sregion.length; - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, sregion.base, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - dns_rdatatype_ns, ®ion); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - } - - return (result); -} - -/*% - * Configure static-stub zone. - */ -static isc_result_t -configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone, - const char *zname, const char *dbtype) -{ - int i = 0; - const cfg_obj_t *obj; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_db_t *db = NULL; - dns_dbversion_t *dbversion = NULL; - dns_dbnode_t *apexnode = NULL; - dns_name_t apexname; - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa; - dns_rdatalist_t* rdatalists[] = { - &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL - }; - dns_rdata_t *rdata; - isc_region_t region; - - /* Create the DB beforehand */ - RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone), - dns_dbtype_stub, dns_zone_getclass(zone), - 0, NULL, &db)); - - dns_rdataset_init(&rdataset); - - dns_rdatalist_init(&rdatalist_ns); - rdatalist_ns.rdclass = dns_zone_getclass(zone); - rdatalist_ns.type = dns_rdatatype_ns; - rdatalist_ns.ttl = STATICSTUB_SERVER_TTL; - - dns_rdatalist_init(&rdatalist_a); - rdatalist_a.rdclass = dns_zone_getclass(zone); - rdatalist_a.type = dns_rdatatype_a; - rdatalist_a.ttl = STATICSTUB_SERVER_TTL; - - dns_rdatalist_init(&rdatalist_aaaa); - rdatalist_aaaa.rdclass = dns_zone_getclass(zone); - rdatalist_aaaa.type = dns_rdatatype_aaaa; - rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL; - - /* Prepare zone RRs from the configuration */ - obj = NULL; - result = cfg_map_get(zconfig, "server-addresses", &obj); - if (result == ISC_R_SUCCESS) { - INSIST(obj != NULL); - CHECK(configure_staticstub_serveraddrs(obj, zone, - &rdatalist_ns, - &rdatalist_a, - &rdatalist_aaaa)); - } - - obj = NULL; - result = cfg_map_get(zconfig, "server-names", &obj); - if (result == ISC_R_SUCCESS) { - INSIST(obj != NULL); - CHECK(configure_staticstub_servernames(obj, zone, - &rdatalist_ns, - zname)); - } - - /* - * Sanity check: there should be at least one NS RR at the zone apex - * to trigger delegation. - */ - if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "No NS record is configured for a " - "static-stub zone '%s'", zname); - result = ISC_R_FAILURE; - goto cleanup; - } - - /* - * Now add NS and glue A/AAAA RRsets to the zone DB. - * First open a new version for the add operation and get a pointer - * to the apex node (all RRs are of the apex name). - */ - CHECK(dns_db_newversion(db, &dbversion)); - - dns_name_init(&apexname, NULL); - dns_name_clone(dns_zone_getorigin(zone), &apexname); - CHECK(dns_db_findnode(db, &apexname, false, &apexnode)); - - /* Add NS RRset */ - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, - 0, NULL)); - dns_rdataset_disassociate(&rdataset); - - /* Add glue A RRset, if any */ - if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) { - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, - &rdataset, 0, NULL)); - dns_rdataset_disassociate(&rdataset); - } - - /* Add glue AAAA RRset, if any */ - if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) { - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa, - &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, - &rdataset, 0, NULL)); - dns_rdataset_disassociate(&rdataset); - } - - dns_db_closeversion(db, &dbversion, true); - dns_zone_setdb(zone, db); - - result = ISC_R_SUCCESS; - - cleanup: - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_disassociate(&rdataset); - } - if (apexnode != NULL) { - dns_db_detachnode(db, &apexnode); - } - if (dbversion != NULL) { - dns_db_closeversion(db, &dbversion, false); - } - if (db != NULL) { - dns_db_detach(&db); - } - for (i = 0; rdatalists[i] != NULL; i++) { - while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) { - ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link); - dns_rdata_toregion(rdata, ®ion); - isc_mem_put(mctx, rdata, - sizeof(*rdata) + region.length); - } - } - - INSIST(dbversion == NULL); - - return (result); -} - -/*% - * Convert a config file zone type into a server zone type. - */ -static inline dns_zonetype_t -zonetype_fromconfig(const cfg_obj_t *map) { - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = cfg_map_get(map, "type", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - return (ns_config_getzonetype(obj)); -} - -/*% - * Helper function for strtoargv(). Pardon the gratuitous recursion. - */ -static isc_result_t -strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, - char ***argvp, unsigned int n) -{ - isc_result_t result; - - /* Discard leading whitespace. */ - while (*s == ' ' || *s == '\t') - s++; - - if (*s == '\0') { - /* We have reached the end of the string. */ - *argcp = n; - *argvp = isc_mem_get(mctx, n * sizeof(char *)); - if (*argvp == NULL) - return (ISC_R_NOMEMORY); - } else { - char *p = s; - while (*p != ' ' && *p != '\t' && *p != '\0') - p++; - if (*p != '\0') - *p++ = '\0'; - - result = strtoargvsub(mctx, p, argcp, argvp, n + 1); - if (result != ISC_R_SUCCESS) - return (result); - (*argvp)[n] = s; - } - return (ISC_R_SUCCESS); -} - -/*% - * Tokenize the string "s" into whitespace-separated words, - * return the number of words in '*argcp' and an array - * of pointers to the words in '*argvp'. The caller - * must free the array using isc_mem_put(). The string - * is modified in-place. - */ -static isc_result_t -strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { - return (strtoargvsub(mctx, s, argcp, argvp, 0)); -} - -static void -checknames(dns_zonetype_t ztype, const cfg_obj_t **maps, - const cfg_obj_t **objp) -{ - const char *zone = NULL; - isc_result_t result; - - switch (ztype) { - case dns_zone_slave: zone = "slave"; break; - case dns_zone_master: zone = "master"; break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - result = ns_checknames_get(maps, zone, objp); - INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL); -} - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone, dns_zone_t *raw) -{ - isc_result_t result; - const char *zname; - dns_rdataclass_t zclass; - dns_rdataclass_t vclass; - const cfg_obj_t *maps[5]; - const cfg_obj_t *nodefault[4]; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *obj; - const char *filename = NULL; - const char *dupcheck; - dns_notifytype_t notifytype = dns_notifytype_yes; - uint32_t count; - unsigned int dbargc; - char **dbargv; - static char default_dbtype[] = "rbt"; - static char dlz_dbtype[] = "dlz"; - char *cpval = default_dbtype; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_dialuptype_t dialup = dns_dialuptype_no; - dns_zonetype_t ztype; - int i; - int32_t journal_size; - bool multi; - bool alt; - dns_view_t *view; - bool check = false, fail = false; - bool warn = false, ignore = false; - bool ixfrdiff; - dns_masterformat_t masterformat; - const dns_master_style_t *masterstyle = &dns_master_style_default; - isc_stats_t *zoneqrystats; - dns_stats_t *rcvquerystats; - dns_zonestat_level_t statlevel = dns_zonestat_none; - int seconds; - dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; - isc_dscp_t dscp; - - i = 0; - if (zconfig != NULL) { - zoptions = cfg_tuple_get(zconfig, "options"); - nodefault[i] = maps[i] = zoptions; - i++; - } - if (vconfig != NULL) { - nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options"); - i++; - } - if (config != NULL) { - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - nodefault[i] = maps[i] = options; - i++; - } - } - nodefault[i] = NULL; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - if (vconfig != NULL) - RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), - dns_rdataclass_in, &vclass)); - else - vclass = dns_rdataclass_in; - - /* - * Configure values common to all zone types. - */ - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - - RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - vclass, &zclass)); - dns_zone_setclass(zone, zclass); - if (raw != NULL) - dns_zone_setclass(raw, zclass); - - ztype = zonetype_fromconfig(zoptions); - if (raw != NULL) { - dns_zone_settype(raw, ztype); - dns_zone_settype(zone, dns_zone_master); - } else - dns_zone_settype(zone, ztype); - - obj = NULL; - result = cfg_map_get(zoptions, "database", &obj); - if (result == ISC_R_SUCCESS) - cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - if (cpval == NULL) - return(ISC_R_NOMEMORY); - - obj = NULL; - result = cfg_map_get(zoptions, "dlz", &obj); - if (result == ISC_R_SUCCESS) { - const char *dlzname = cfg_obj_asstring(obj); - size_t len; - - if (cpval != default_dbtype) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': both 'database' and 'dlz' " - "specified", zname); - return (ISC_R_FAILURE); - } - - len = strlen(dlzname) + 5; - cpval = isc_mem_allocate(mctx, len); - if (cpval == NULL) - return (ISC_R_NOMEMORY); - snprintf(cpval, len, "dlz %s", dlzname); - } - - result = strtoargv(mctx, cpval, &dbargc, &dbargv); - if (result != ISC_R_SUCCESS && cpval != default_dbtype) { - isc_mem_free(mctx, cpval); - return (result); - } - - /* - * ANSI C is strange here. There is no logical reason why (char **) - * cannot be promoted automatically to (const char * const *) by the - * compiler w/o generating a warning. - */ - result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); - isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); - if (cpval != default_dbtype && cpval != dlz_dbtype) - isc_mem_free(mctx, cpval); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(zoptions, "file", &obj); - if (result == ISC_R_SUCCESS) - filename = cfg_obj_asstring(obj); - - /* - * Unless we're using some alternative database, a master zone - * will be needing a master file. - */ - if (ztype == dns_zone_master && cpval == default_dbtype && - filename == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - return (ISC_R_FAILURE); - } - - if (ztype == dns_zone_slave) - masterformat = dns_masterformat_raw; - else - masterformat = dns_masterformat_text; - obj = NULL; - result = ns_config_get(maps, "masterfile-format", &obj); - if (result == ISC_R_SUCCESS) { - const char *masterformatstr = cfg_obj_asstring(obj); - - if (strcasecmp(masterformatstr, "text") == 0) { - masterformat = dns_masterformat_text; - } else if (strcasecmp(masterformatstr, "raw") == 0) { - masterformat = dns_masterformat_raw; - } else if (strcasecmp(masterformatstr, "map") == 0) { - masterformat = dns_masterformat_map; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "masterfile-style", &obj); - if (result == ISC_R_SUCCESS) { - const char *masterstylestr = cfg_obj_asstring(obj); - - if (masterformat != dns_masterformat_text) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s': 'masterfile-style' " - "can only be used with " - "'masterfile-format text'", zname); - return (ISC_R_FAILURE); - } - - if (strcasecmp(masterstylestr, "full") == 0) { - masterstyle = &dns_master_style_full; - } else if (strcasecmp(masterstylestr, "relative") == 0) { - masterstyle = &dns_master_style_default; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "max-zone-ttl", &obj); - if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'max-zone-ttl' is not compatible " - "with 'masterfile-format map'", zname); - return (ISC_R_FAILURE); - } else if (result == ISC_R_SUCCESS) { - dns_ttl_t maxttl = 0; /* unlimited */ - - if (cfg_obj_isuint32(obj)) - maxttl = cfg_obj_asuint32(obj); - dns_zone_setmaxttl(zone, maxttl); - if (raw != NULL) - dns_zone_setmaxttl(raw, maxttl); - } - - obj = NULL; - result = ns_config_get(maps, "max-records", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxrecords(mayberaw, cfg_obj_asuint32(obj)); - if (zone != mayberaw) - dns_zone_setmaxrecords(zone, 0); - - if (raw != NULL && filename != NULL) { -#define SIGNED ".signed" - size_t signedlen = strlen(filename) + sizeof(SIGNED); - char *signedname; - - RETERR(dns_zone_setfile3(raw, filename, - masterformat, masterstyle)); - signedname = isc_mem_get(mctx, signedlen); - if (signedname == NULL) - return (ISC_R_NOMEMORY); - - (void)snprintf(signedname, signedlen, "%s" SIGNED, filename); - result = dns_zone_setfile3(zone, signedname, - dns_masterformat_raw, NULL); - isc_mem_put(mctx, signedname, signedlen); - if (result != ISC_R_SUCCESS) - return (result); - } else - RETERR(dns_zone_setfile3(zone, filename, - masterformat, masterstyle)); - - obj = NULL; - result = cfg_map_get(zoptions, "journal", &obj); - if (result == ISC_R_SUCCESS) - RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj))); - - /* - * Notify messages are processed by the raw zone if it exists. - */ - if (ztype == dns_zone_slave) - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_notify, ac, mayberaw, - dns_zone_setnotifyacl, - dns_zone_clearnotifyacl)); - - /* - * XXXAG This probably does not make sense for stubs. - */ - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_query, ac, zone, - dns_zone_setqueryacl, - dns_zone_clearqueryacl)); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_query_on, ac, zone, - dns_zone_setqueryonacl, - dns_zone_clearqueryonacl)); - - obj = NULL; - result = ns_config_get(maps, "dialup", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - dialup = dns_dialuptype_yes; - else - dialup = dns_dialuptype_no; - } else { - const char *dialupstr = cfg_obj_asstring(obj); - if (strcasecmp(dialupstr, "notify") == 0) { - dialup = dns_dialuptype_notify; - } else if (strcasecmp(dialupstr, "notify-passive") == 0) { - dialup = dns_dialuptype_notifypassive; - } else if (strcasecmp(dialupstr, "refresh") == 0) { - dialup = dns_dialuptype_refresh; - } else if (strcasecmp(dialupstr, "passive") == 0) { - dialup = dns_dialuptype_passive; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (raw != NULL) - dns_zone_setdialup(raw, dialup); - dns_zone_setdialup(zone, dialup); - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - statlevel = dns_zonestat_full; - else - statlevel = dns_zonestat_none; - } else { - const char *levelstr = cfg_obj_asstring(obj); - if (strcasecmp(levelstr, "full") == 0) { - statlevel = dns_zonestat_full; - } else if (strcasecmp(levelstr, "terse") == 0) { - statlevel = dns_zonestat_terse; - } else if (strcasecmp(levelstr, "none") == 0) { - statlevel = dns_zonestat_none; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - dns_zone_setstatlevel(zone, statlevel); - - zoneqrystats = NULL; - rcvquerystats = NULL; - if (statlevel == dns_zonestat_full) { - RETERR(isc_stats_create(mctx, &zoneqrystats, - dns_nsstatscounter_max)); - RETERR(dns_rdatatypestats_create(mctx, - &rcvquerystats)); - } - dns_zone_setrequeststats(zone, zoneqrystats); - dns_zone_setrcvquerystats(zone, rcvquerystats); - - if (zoneqrystats != NULL) - isc_stats_detach(&zoneqrystats); - - if(rcvquerystats != NULL) - dns_stats_detach(&rcvquerystats); - - /* - * Configure master functionality. This applies - * to primary masters (type "master") and slaves - * acting as masters (type "slave"), but not to stubs. - */ - if (ztype != dns_zone_stub && ztype != dns_zone_staticstub && - ztype != dns_zone_redirect) { - obj = NULL; - result = ns_config_get(maps, "notify", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - notifytype = dns_notifytype_yes; - else - notifytype = dns_notifytype_no; - } else { - const char *notifystr = cfg_obj_asstring(obj); - if (strcasecmp(notifystr, "explicit") == 0) { - notifytype = dns_notifytype_explicit; - } else if (strcasecmp(notifystr, "master-only") == 0) { - notifytype = dns_notifytype_masteronly; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (raw != NULL) - dns_zone_setnotifytype(raw, dns_notifytype_no); - dns_zone_setnotifytype(zone, notifytype); - - obj = NULL; - result = ns_config_get(maps, "also-notify", &obj); - if (result == ISC_R_SUCCESS && - (notifytype == dns_notifytype_yes || - notifytype == dns_notifytype_explicit || - (notifytype == dns_notifytype_masteronly && - ztype == dns_zone_master))) - { - dns_ipkeylist_t ipkl; - dns_ipkeylist_init(&ipkl); - - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &ipkl)); - result = dns_zone_setalsonotifydscpkeys(zone, - ipkl.addrs, - ipkl.dscps, - ipkl.keys, - ipkl.count); - dns_ipkeylist_clear(mctx, &ipkl); - RETERR(result); - } else - RETERR(dns_zone_setalsonotify(zone, NULL, 0)); - - obj = NULL; - result = ns_config_get(maps, "notify-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setnotifysrc4dscp(zone, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setnotifysrc6dscp(zone, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-to-soa", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA, - cfg_obj_asboolean(obj)); - - dns_zone_setisself(zone, ns_client_isself, NULL); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_transfer, ac, zone, - dns_zone_setxfracl, - dns_zone_clearxfracl)); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-out", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-out", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (raw != NULL) - dns_zone_setjournalsize(raw, -1); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" PRId64 "' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (uint32_t)value; - } - if (raw != NULL) - dns_zone_setjournalsize(raw, journal_size); - dns_zone_setjournalsize(zone, journal_size); - - obj = NULL; - result = ns_config_get(maps, "ixfr-from-differences", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) - ixfrdiff = cfg_obj_asboolean(obj); - else if (!strcasecmp(cfg_obj_asstring(obj), "master") && - ztype == dns_zone_master) - ixfrdiff = true; - else if (!strcasecmp(cfg_obj_asstring(obj), "slave") && - ztype == dns_zone_slave) - ixfrdiff = true; - else - ixfrdiff = false; - if (raw != NULL) { - dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS, - true); - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - false); - } else - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - ixfrdiff); - - obj = NULL; - result = ns_config_get(maps, "request-expire", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setrequestexpire(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "request-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - checknames(ztype, maps, &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - if (raw != NULL) { - dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES, - check); - dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL, - fail); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, - false); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, - false); - } else { - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, - check); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, - fail); - } - - obj = NULL; - result = ns_config_get(maps, "notify-delay", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-sibling", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-spf", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check); - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "nsec3-test-zone", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, - cfg_obj_asboolean(obj)); - } else if (ztype == dns_zone_redirect) { - dns_zone_setnotifytype(zone, dns_notifytype_no); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" PRId64 "' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (uint32_t)value; - } - dns_zone_setjournalsize(zone, journal_size); - } - - /* - * Configure update-related options. These apply to - * primary masters only. - */ - if (ztype == dns_zone_master) { - dns_acl_t *updateacl; - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_update, ac, mayberaw, - dns_zone_setupdateacl, - dns_zone_clearupdateacl)); - - updateacl = dns_zone_getupdateacl(mayberaw); - if (updateacl != NULL && dns_acl_isinsecure(updateacl)) - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "zone '%s' allows unsigned updates " - "from remote hosts, which is insecure", - zname); - - RETERR(configure_zone_ssutable(zoptions, mayberaw, zname)); - } - - if (ztype == dns_zone_master || raw != NULL) { - const cfg_obj_t *validity, *resign; - bool allow = false, maint = false; - - obj = NULL; - result = ns_config_get(maps, "sig-validity-interval", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - - validity = cfg_tuple_get(obj, "validity"); - seconds = cfg_obj_asuint32(validity); - if (!ns_g_sigvalinsecs) { - seconds *= 86400; - } - dns_zone_setsigvalidityinterval(zone, seconds); - - resign = cfg_tuple_get(obj, "re-sign"); - if (cfg_obj_isvoid(resign)) { - seconds /= 4; - } else if (!ns_g_sigvalinsecs) { - if (seconds > 7 * 86400) { - seconds = cfg_obj_asuint32(resign) * 86400; - } else { - seconds = cfg_obj_asuint32(resign) * 3600; - } - } else { - seconds = cfg_obj_asuint32(resign); - } - dns_zone_setsigresigninginterval(zone, seconds); - - obj = NULL; - result = ns_config_get(maps, "key-directory", &obj); - if (result == ISC_R_SUCCESS) { - filename = cfg_obj_asstring(obj); - RETERR(dns_zone_setkeydirectory(zone, filename)); - } - - obj = NULL; - result = ns_config_get(maps, "sig-signing-signatures", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setsignatures(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "sig-signing-nodes", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setnodes(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "sig-signing-type", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "update-check-ksk", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setrefreshkeyinterval(zone, - cfg_obj_asuint32(obj))); - - obj = NULL; - result = cfg_map_get(zoptions, "auto-dnssec", &obj); - if (result == ISC_R_SUCCESS) { - const char *arg = cfg_obj_asstring(obj); - if (strcasecmp(arg, "allow") == 0) { - allow = true; - } else if (strcasecmp(arg, "maintain") == 0) { - allow = maint = true; - } else if (strcasecmp(arg, "off") == 0) { - /* Default */ - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow); - dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint); - } - } - - if (ztype == dns_zone_slave) { - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_update_forwarding, ac, - mayberaw, dns_zone_setforwardacl, - dns_zone_clearforwardacl)); - } - - /*% - * Primary master functionality. - */ - if (ztype == dns_zone_master) { - obj = NULL; - result = ns_config_get(maps, "check-wildcard", &obj); - if (result == ISC_R_SUCCESS) - check = cfg_obj_asboolean(obj); - else - check = false; - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check); - - /* - * With map files, the default is ignore duplicate - * records. With other master formats, the default is - * taken from the global configuration. - */ - obj = NULL; - if (masterformat != dns_masterformat_map) { - result = ns_config_get(maps, "check-dup-records", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dupcheck = cfg_obj_asstring(obj); - } else { - result = ns_config_get(nodefault, "check-dup-records", - &obj); - if (result == ISC_R_SUCCESS) - dupcheck = cfg_obj_asstring(obj); - else - dupcheck = "ignore"; - - } - if (strcasecmp(dupcheck, "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(dupcheck, "fail") == 0) { - fail = check = true; - } else if (strcasecmp(dupcheck, "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail); - - obj = NULL; - result = ns_config_get(maps, "check-mx", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail); - - /* - * With map files, the default is *not* to check - * integrity. With other master formats, the default is - * taken from the global configuration. - */ - obj = NULL; - if (masterformat != dns_masterformat_map) { - result = ns_config_get(maps, "check-integrity", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, - cfg_obj_asboolean(obj)); - } else { - check = false; - result = ns_config_get(nodefault, "check-integrity", - &obj); - if (result == ISC_R_SUCCESS) - check = cfg_obj_asboolean(obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, - check); - } - - obj = NULL; - result = ns_config_get(maps, "check-mx-cname", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = true; - ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = true; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore); - - obj = NULL; - result = ns_config_get(maps, "check-srv-cname", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = true; - ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = true; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME, - ignore); - - obj = NULL; - result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = cfg_map_get(zoptions, "dnssec-update-mode", &obj); - if (result == ISC_R_SUCCESS) { - const char *arg = cfg_obj_asstring(obj); - if (strcasecmp(arg, "no-resign") == 0) { - dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN, - true); - } else if (strcasecmp(arg, "maintain") == 0) { - /* Default */ - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "serial-update-method", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0) - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_unixtime); - else if (strcasecmp(cfg_obj_asstring(obj), "date") == 0) - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_date); - else - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_increment); - } - - /* - * Configure slave functionality. - */ - switch (ztype) { - case dns_zone_slave: - case dns_zone_stub: - case dns_zone_redirect: - count = 0; - obj = NULL; - (void)cfg_map_get(zoptions, "masters", &obj); - if (obj != NULL) { - dns_ipkeylist_t ipkl; - dns_ipkeylist_init(&ipkl); - - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &ipkl)); - result = dns_zone_setmasterswithkeys(mayberaw, - ipkl.addrs, - ipkl.keys, - ipkl.count); - count = ipkl.count; - dns_ipkeylist_clear(mctx, &ipkl); - RETERR(result); - } else - result = dns_zone_setmasters(mayberaw, NULL, 0); - RETERR(result); - - multi = false; - if (count > 1) { - obj = NULL; - result = ns_config_get(maps, "multi-master", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - multi = cfg_obj_asboolean(obj); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-in", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-in", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setxfrsource4(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setxfrsource6(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setaltxfrsource4(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setaltxfrsource6(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp)); - - obj = NULL; - (void)ns_config_get(maps, "use-alt-transfer-source", &obj); - if (obj == NULL) { - /* - * Default off when views are in use otherwise - * on for BIND 8 compatibility. - */ - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_default") == 0) - alt = true; - else - alt = false; - } else - alt = cfg_obj_asboolean(obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt); - - obj = NULL; - (void)ns_config_get(maps, "try-tcp-refresh", &obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH, - cfg_obj_asboolean(obj)); - break; - - case dns_zone_staticstub: - RETERR(configure_staticstub(zoptions, zone, zname, - default_dbtype)); - break; - - default: - break; - } - - return (ISC_R_SUCCESS); -} - - -/* - * Set up a DLZ zone as writeable - */ -isc_result_t -ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, - dns_rdataclass_t rdclass, dns_name_t *name) -{ - dns_db_t *db = NULL; - isc_time_t now; - isc_result_t result; - - TIME_NOW(&now); - - dns_zone_settype(zone, dns_zone_dlz); - result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_zone_dlzpostload(zone, db); - dns_db_detach(&db); - return (result); -} - -bool -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *obj = NULL; - const char *cfilename; - const char *zfilename; - dns_zone_t *raw = NULL; - bool has_raw; - dns_zonetype_t ztype; - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * We always reconfigure a static-stub zone for simplicity, assuming - * the amount of data to be loaded is small. - */ - if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: staticstub"); - return (false); - } - - /* If there's a raw zone, use that for filename and type comparison */ - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - zfilename = dns_zone_getfile(raw); - ztype = dns_zone_gettype(raw); - dns_zone_detach(&raw); - has_raw = true; - } else { - zfilename = dns_zone_getfile(zone); - ztype = dns_zone_gettype(zone); - has_raw = false; - } - - obj = NULL; - (void)cfg_map_get(zoptions, "inline-signing", &obj); - if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: old zone was inline-signing"); - return (false); - } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: old zone was not inline-signing"); - return (false); - } - - if (zonetype_fromconfig(zoptions) != ztype) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: type mismatch"); - return (false); - } - - obj = NULL; - (void)cfg_map_get(zoptions, "file", &obj); - if (obj != NULL) - cfilename = cfg_obj_asstring(obj); - else - cfilename = NULL; - if (!((cfilename == NULL && zfilename == NULL) || - (cfilename != NULL && zfilename != NULL && - strcmp(cfilename, zfilename) == 0))) - { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: filename mismatch"); - return (false); - } - - return (true); -} diff --git a/bin/named-sdb/Makefile.in b/bin/named-sdb/Makefile.in deleted file mode 100644 index 9fa3dea..0000000 --- a/bin/named-sdb/Makefile.in +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -# Attempt to disable parallel processing. -.NOTPARALLEL: -.NO_PARALLEL: - -VERSION=@BIND9_VERSION@ - -@BIND9_PRODUCT@ - -@BIND9_DESCRIPTION@ - -@BIND9_SRCID@ - -@BIND9_CONFIGARGS@ - -@BIND9_MAKE_INCLUDES@ - -# -# Add database drivers here. -# -DBDRIVER_OBJS = ldapdb.@O@ pgsqldb.@O@ sqlitedb.@O@ dirdb.@O@ -DBDRIVER_SRCS = ldapdb.c pgsqldb.c sqlitedb.c dirdb.c -DBDRIVER_INCLUDES = -DBDRIVER_LIBS = -lldap -llber -lsqlite3 -lpq - -DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers - -DLZDRIVER_OBJS = @DLZ_DRIVER_OBJS@ -DLZDRIVER_SRCS = @DLZ_DRIVER_SRCS@ -DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@ -DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ - ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ - ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} ${MAXMINDDB_CFLAGS} \ - @DST_OPENSSL_INC@ - -CDEFINES = @CONTRIB_DLZ@ @USE_GSSAPI@ @CRYPTO@ - -CWARNINGS = - -DNSLIBS = ../../lib/dns/libdns.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ - ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ - ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ - -NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ - ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ - -SUBDIRS = unix - -TARGETS = named-sdb@EXEEXT@ - -GEOIPLINKOBJS = geoip.@O@ -GEOIP2LINKOBJS = geoip.@O@ - -OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ fuzz.@O@ \ - @GEOIPLINKOBJS@ @GEOIP2LINKOBJS@ \ - interfacemgr.@O@ listenlist.@O@ log.@O@ logconf.@O@ \ - main.@O@ notify.@O@ \ - query.@O@ server.@O@ sortlist.@O@ statschannel.@O@ \ - tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ - zoneconf.@O@ \ - lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ - lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \ - ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS} - -UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ - -SYMOBJS = symtbl.@O@ - -GEOIPLINKSRCS = geoip.c -GEOIP2LINKSRCS = geoip.c - -SRCS = builtin.c client.c config.c control.c \ - controlconf.c fuzz.c \ - @GEOIPLINKSRCS@ @GEOIP2LINKSRCS@ \ - interfacemgr.c \ listenlist.c log.c logconf.c \ - main.c notify.c \ - query.c server.c sortlist.c statschannel.c \ - tkeyconf.c tsigconf.c update.c xfrout.c \ - zoneconf.c \ - lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ - lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \ - ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS} - -MANPAGES = named.8 lwresd.8 named.conf.5 - -HTMLPAGES = named.html lwresd.html named.conf.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -EXT_CFLAGS = -fpie - -@BIND9_MAKE_RULES@ - -LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack - -main.@O@: main.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DPRODUCT=\"${PRODUCT}\" \ - -DDESCRIPTION=\"${DESCRIPTION}\" \ - -DSRCID=\"${SRCID}\" \ - -DCONFIGARGS="\"${CONFIGARGS}\"" \ - -DBUILDER="\"make\"" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c - -config.@O@: config.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DSRCID=\"${SRCID}\" \ - -DDYNDB_LIBDIR=\"@libdir@/bind\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" \ - -DMAXMINDDB_PREFIX=\"@MAXMINDDB_PREFIX@\" \ - -c ${srcdir}/config.c - -server.@O@: server.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DPRODUCT=\"${PRODUCT}\" \ - -DVERSION=\"${VERSION}\" -c ${srcdir}/server.c - -named-sdb@EXEEXT@: ${OBJS} ${DEPLIBS} - export MAKE_SYMTABLE="yes"; \ - export BASEOBJS="${OBJS} ${UOBJS}"; \ - ${FINALBUILDCMD} - -lwresd@EXEEXT@: named@EXEEXT@ - rm -f lwresd@EXEEXT@ - @LN@ named@EXEEXT@ lwresd@EXEEXT@ - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean maintainer-clean:: - rm -f ${TARGETS} ${OBJS} - -maintainer-clean:: - -bind9.xsl.h: bind9.xsl ${srcdir}/convertxsl.pl - ${PERL} ${srcdir}/convertxsl.pl < ${srcdir}/bind9.xsl > bind9.xsl.h - -depend: bind9.xsl.h -statschannel.@O@: bind9.xsl.h - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - -install-man5: named.conf.5 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man5 - -install-man8: named.8 lwresd.8 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install-man: install-man5 install-man8 - -install:: ${TARGETS} installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-sdb@EXEEXT@ ${DESTDIR}${sbindir} - -uninstall:: - ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/named-sdb@EXEEXT@ - -@DLZ_DRIVER_RULES@ - -named-symtbl.@O@: named-symtbl.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c named-symtbl.c diff --git a/bin/named-sdb/bind9.xsl b/bin/named-sdb/bind9.xsl deleted file mode 100644 index 9a1c6ff..0000000 --- a/bin/named-sdb/bind9.xsl +++ /dev/null @@ -1,1096 +0,0 @@ - - - - - - - - - - - - - - - - - ISC BIND 9 Statistics - - -
-

ISC Bind 9 Configuration and Statistics

-
-

Alternate statistics views: All, - Status, - Server, - Zones, - Network, - Tasks, - Memory and - Traffic Size

-
-

Server Status

- - - - - - - - - - - - - - - - - -
Boot time: - -
Last reconfigured: - -
Current time: - -
Server version: - -
-
- - -

Incoming Requests by DNS Opcode

- -
- [cannot display chart] -
-
- - - - - - even - odd - - - - - - - - - - - -
- - - -
Total: - -
-
-
- - - -

Incoming Queries by Query Type

-
- [cannot display chart] -
-
- - - - - - even - odd - - - - - - - - - - - -
- - - -
Total: - -
-
-
- -

Outgoing Queries per view

- -

View

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
- -

Server Statistics

- - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Zone Maintenance Statistics

- - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
- -

Resolver Statistics (Common)

- - - - - - even - odd - - - - - - - -
- - - -
-
- - -

Resolver Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

ADB Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Cache Statistics for View

- - - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Cache DB RRsets for View

- - - - - even - odd - - - - - - - -
- - - -
-
-
-
- -

Traffic Size Statistics

-
- -

UDP Requests Received

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

UDP Responses Sent

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

TCP Requests Received

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

TCP Responses Sent

- - - - - even - odd - - - - - - - - -
- - - -
-
-
- -

Socket I/O Statistics

- - - - - even - odd - - - - - - - -
- - - -
-
-
- - -

Zones for View

- - - - - - - even - odd - - - - - - - - - -
NameClassTypeSerial
-
-
- -

Received QTYPES per view/zone

- -

View

- - - - - -

Zone

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
-
- -

Response Codes per view/zone

- -

View

- - - - - -

Zone

- - - - - - -
[no data to display]
-
- - - - - - even - odd - - - - - - - -
- - - -
-
-
-
-
- -

Network Status

- - - - - - - - - - - - - - - even - odd - - - - - - - - - - - - -
IDNameTypeReferencesLocalAddressPeerAddressState
- - - - - - - - - - - - - - - -
-
-
- -

Task Manager Configuration

- - - - - - - - - - - - - - - - - - - - - -
Thread-Model - -
Worker Threads - -
Default Quantum - -
Tasks Running - -
Tasks Ready - -
-
-
- -

Tasks

- - - - - - - - - - - - - - even - odd - - - - - - - - - - - -
IDNameReferencesStateQuantumEvents
- - - - - - - - - - - -
-
-
- -

Memory Usage Summary

- - - - - even - odd - - - - - - - -
- - - -
-
-
- -

Memory Contexts

- - - - - - - - - - - - - - - - - - even - odd - - - - - - - - - - - - - - - -
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
- - - - - - - - - - - - - - - - - - - -
-
-
- - - -
-
diff --git a/bin/named-sdb/bind9.xsl.h b/bin/named-sdb/bind9.xsl.h deleted file mode 100644 index 9ce8cd7..0000000 --- a/bin/named-sdb/bind9.xsl.h +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Generated by convertxsl.pl 1.14 2008/07/17 23:43:26 jinmei Exp - * From unknown - */ -static char xslmsg[] = - "\n" - "\n" - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " ISC BIND 9 Statistics\n" - " \n" - " \n" - "
\n" - "

ISC Bind 9 Configuration and Statistics

\n" - "
\n" - "

Alternate statistics views: All,\n" - " Status,\n" - " Server,\n" - " Zones,\n" - " Network,\n" - " Tasks,\n" - " Memory and\n" - " Traffic Size

\n" - "
\n" - "

Server Status

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
Boot time:\n" - " \n" - "
Last reconfigured:\n" - " \n" - "
Current time:\n" - " \n" - "
Server version:\n" - " \n" - "
\n" - "
\n" - " \n" - " \n" - "

Incoming Requests by DNS Opcode

\n" - " \n" - "
\n" - " [cannot display chart]\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
Total:\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - "

Incoming Queries by Query Type

\n" - "
\n" - " [cannot display chart]\n" - "
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
Total:\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Outgoing Queries per view

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Server Statistics

\n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Zone Maintenance Statistics

\n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - " \n" - "

Resolver Statistics (Common)

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - " \n" - " \n" - "

Resolver Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

ADB Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Cache Statistics for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Cache DB RRsets for View

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Traffic Size Statistics

\n" - "
\n" - " \n" - "

UDP Requests Received

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

UDP Responses Sent

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

TCP Requests Received

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

TCP Responses Sent

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Socket I/O Statistics

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - " \n" - "

Zones for View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
NameClassTypeSerial
\n" - "
\n" - "
\n" - " \n" - "

Received QTYPES per view/zone

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "

Zone

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Response Codes per view/zone

\n" - " \n" - "

View

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "

Zone

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
[no data to display]
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - " \n" - "

Network Status

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameTypeReferencesLocalAddressPeerAddressState
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Task Manager Configuration

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
Thread-Model\n" - " \n" - "
Worker Threads\n" - " \n" - "
Default Quantum\n" - " \n" - "
Tasks Running\n" - " \n" - "
Tasks Ready\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Tasks

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameReferencesStateQuantumEvents
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Memory Usage Summary

\n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "

Memory Contexts

\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " even\n" - " odd\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "

Internet Systems Consortium Inc.
http://www.isc.org

\n" - " \n" - " \n" - "
\n" - "
\n"; diff --git a/bin/named-sdb/builtin.c b/bin/named-sdb/builtin.c deleted file mode 100644 index 25a4df1..0000000 --- a/bin/named-sdb/builtin.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file - * \brief - * The built-in "version", "hostname", "id", "authors" and "empty" databases. - */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -typedef struct builtin builtin_t; - -static isc_result_t do_version_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_dns64_lookup(dns_sdblookup_t *lookup); - -/* - * We can't use function pointers as the db_data directly - * because ANSI C does not guarantee that function pointers - * can safely be cast to void pointers and back. - */ - -struct builtin { - isc_result_t (*do_lookup)(dns_sdblookup_t *lookup); - char *server; - char *contact; -}; - -static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; -static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; -static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL }; -static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; -static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; -static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL }; - -static dns_sdbimplementation_t *builtin_impl; -static dns_sdbimplementation_t *dns64_impl; - -/* - * Pre computed HEX * 16 or 1 table. - */ -static const unsigned char hex16[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*00*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*20*/ - 0, 16, 32, 48, 64, 80, 96,112,128,144, 1, 1, 1, 1, 1, 1, /*30*/ - 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*50*/ - 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*60*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/ - 1, 1, 1, 1, 1, 1, 1, 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, /*90*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*A0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*B0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*C0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*D0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*E0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /*F0*/ -}; - -const unsigned char decimal[] = "0123456789"; - -static size_t -dns64_rdata(unsigned char *v, size_t start, unsigned char *rdata) { - size_t i, j = 0; - - for (i = 0; i < 4U; i++) { - unsigned char c = v[start++]; - if (start == 7U) - start++; - if (c > 99) { - rdata[j++] = 3; - rdata[j++] = decimal[c/100]; c = c % 100; - rdata[j++] = decimal[c/10]; c = c % 10; - rdata[j++] = decimal[c]; - } else if (c > 9) { - rdata[j++] = 2; - rdata[j++] = decimal[c/10]; c = c % 10; - rdata[j++] = decimal[c]; - } else { - rdata[j++] = 1; - rdata[j++] = decimal[c]; - } - } - memmove(&rdata[j], "\07in-addr\04arpa", 14); - return (j + 14); -} - -static isc_result_t -dns64_cname(const dns_name_t *zone, const dns_name_t *name, - dns_sdblookup_t *lookup) -{ - size_t zlen, nlen, j, len; - unsigned char v[16], n; - unsigned int i; - unsigned char rdata[sizeof("123.123.123.123.in-addr.arpa.")]; - unsigned char *ndata; - - /* - * The combined length of the zone and name is 74. - * - * The minimum zone length is 10 ((3)ip6(4)arpa(0)). - * - * The length of name should always be even as we are expecting - * a series of nibbles. - */ - zlen = zone->length; - nlen = name->length; - if ((zlen + nlen) > 74U || zlen < 10U || (nlen % 2) != 0U) - return (ISC_R_NOTFOUND); - - /* - * We assume the zone name is well formed. - */ - - /* - * XXXMPA We could check the dns64 suffix here if we need to. - */ - /* - * Check that name is a series of nibbles. - * Compute the byte values that correspond to the nibbles as we go. - * - * Shift the final result 4 bits, by setting 'i' to 1, if we if we - * have a odd number of nibbles so that "must be zero" tests below - * are byte aligned and we correctly return ISC_R_NOTFOUND or - * ISC_R_SUCCESS. We will not generate a CNAME in this case. - */ - ndata = name->ndata; - i = (nlen % 4) == 2U ? 1 : 0; - j = nlen; - memset(v, 0, sizeof(v)); - while (j != 0U) { - INSIST((i/2) < sizeof(v)); - if (ndata[0] != 1) - return (ISC_R_NOTFOUND); - n = hex16[ndata[1]&0xff]; - if (n == 1) - return (ISC_R_NOTFOUND); - v[i/2] = n | (v[i/2]>>4); - j -= 2; - ndata += 2; - i++; - } - - /* - * If we get here then we know name only consisted of nibbles. - * Now we need to determine if the name exists or not and whether - * it corresponds to a empty node in the zone or there should be - * a CNAME. - */ -#define ZLEN(x) (10 + (x)/2) - switch (zlen) { - case ZLEN(32): /* prefix len 32 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 16U && v[(nlen-1)/4 - 4] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 8, rdata); - break; - case ZLEN(40): /* prefix len 40 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 12U && v[(nlen-1)/4 - 3] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 6, rdata); - break; - case ZLEN(48): /* prefix len 48 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 8U && v[(nlen-1)/4 - 2] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 5, rdata); - break; - case ZLEN(56): /* prefix len 56 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (nlen > 4U && v[(nlen-1)/4 - 1] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 4, rdata); - break; - case ZLEN(64): /* prefix len 64 */ - /* - * The nibbles that map to this byte must be zero for 'name' - * to exist in the zone. - */ - if (v[(nlen-1)/4] != 0) - return (ISC_R_NOTFOUND); - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 3, rdata); - break; - case ZLEN(96): /* prefix len 96 */ - /* - * If the total length is not 74 then this is a empty node - * so return success. - */ - if (nlen + zlen != 74U) - return (ISC_R_SUCCESS); - len = dns64_rdata(v, 0, rdata); - break; - default: - /* - * This should never be reached unless someone adds a - * zone declaration with this internal type to named.conf. - */ - return (ISC_R_NOTFOUND); - } - return (dns_sdb_putrdata(lookup, dns_rdatatype_cname, 600, - rdata, (unsigned int)len)); -} - -static isc_result_t -builtin_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - UNUSED(methods); - UNUSED(clientinfo); - - if (strcmp(name, "@") == 0) - return (b->do_lookup(lookup)); - else - return (ISC_R_NOTFOUND); -} - -static isc_result_t -dns64_lookup(const dns_name_t *zone, const dns_name_t *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(methods); - UNUSED(clientinfo); - - if (name->labels == 0 && name->length == 0) - return (b->do_lookup(lookup)); - else - return (dns64_cname(zone, name, lookup)); -} - -static isc_result_t -put_txt(dns_sdblookup_t *lookup, const char *text) { - unsigned char buf[256]; - unsigned int len = strlen(text); - if (len > 255) - len = 255; /* Silently truncate */ - buf[0] = len; - memmove(&buf[1], text, len); - return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1)); -} - -static isc_result_t -do_version_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->version_set) { - if (ns_g_server->version == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->version)); - } else { - return (put_txt(lookup, ns_g_version)); - } -} - -static isc_result_t -do_hostname_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->hostname_set) { - if (ns_g_server->hostname == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->hostname)); - } else { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } -} - -static isc_result_t -do_authors_lookup(dns_sdblookup_t *lookup) { - isc_result_t result; - const char **p; - static const char *authors[] = { - "Mark Andrews", - "Curtis Blackburn", - "James Brister", - "Ben Cottrell", - "John H. DuBois III", - "Francis Dupont", - "Michael Graff", - "Andreas Gustafsson", - "Bob Halley", - "Evan Hunt", - "JINMEI Tatuya", - "Witold Krecicki", - "David Lawrence", - "Scott Mann", - "Danny Mayer", - "Damien Neil", - "Matt Nelson", - "Jeremy C. Reed", - "Michael Sawyer", - "Brian Wellington", - NULL - }; - - /* - * If a version string is specified, disable the authors.bind zone. - */ - if (ns_g_server->version_set) - return (ISC_R_SUCCESS); - - for (p = authors; *p != NULL; p++) { - result = put_txt(lookup, *p); - if (result != ISC_R_SUCCESS) - return (result); - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_id_lookup(dns_sdblookup_t *lookup) { - - if (ns_g_server->server_usehostname) { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } - - if (ns_g_server->server_id == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->server_id)); -} - -static isc_result_t -do_dns64_lookup(dns_sdblookup_t *lookup) { - UNUSED(lookup); - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_empty_lookup(dns_sdblookup_t *lookup) { - - UNUSED(lookup); - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { - isc_result_t result; - const char *contact = "hostmaster"; - const char *server = "@"; - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - UNUSED(dbdata); - - if (b == &empty_builtin) { - server = "."; - contact = "."; - } else { - if (b->server != NULL) - server = b->server; - if (b->contact != NULL) - contact = b->contact; - } - - result = dns_sdb_putsoa(lookup, server, contact, 0); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - result = dns_sdb_putrr(lookup, "ns", 0, server); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - REQUIRE(argc >= 1); - - UNUSED(zone); - UNUSED(driverdata); - - if (strcmp(argv[0], "empty") == 0 || strcmp(argv[0], "dns64") == 0) { - if (argc != 3) - return (DNS_R_SYNTAX); - } else if (argc != 1) - return (DNS_R_SYNTAX); - - if (strcmp(argv[0], "version") == 0) - *dbdata = &version_builtin; - else if (strcmp(argv[0], "hostname") == 0) - *dbdata = &hostname_builtin; - else if (strcmp(argv[0], "authors") == 0) - *dbdata = &authors_builtin; - else if (strcmp(argv[0], "id") == 0) - *dbdata = &id_builtin; - else if (strcmp(argv[0], "empty") == 0 || - strcmp(argv[0], "dns64") == 0) { - builtin_t *empty; - char *server; - char *contact; - /* - * We don't want built-in zones to fail. Fallback to - * the static configuration if memory allocation fails. - */ - empty = isc_mem_get(ns_g_mctx, sizeof(*empty)); - server = isc_mem_strdup(ns_g_mctx, argv[1]); - contact = isc_mem_strdup(ns_g_mctx, argv[2]); - if (empty == NULL || server == NULL || contact == NULL) { - if (strcmp(argv[0], "empty") == 0) - *dbdata = &empty_builtin; - else - *dbdata = &dns64_builtin; - if (server != NULL) - isc_mem_free(ns_g_mctx, server); - if (contact != NULL) - isc_mem_free(ns_g_mctx, contact); - if (empty != NULL) - isc_mem_put(ns_g_mctx, empty, sizeof (*empty)); - } else { - if (strcmp(argv[0], "empty") == 0) - memmove(empty, &empty_builtin, - sizeof (empty_builtin)); - else - memmove(empty, &dns64_builtin, - sizeof (empty_builtin)); - empty->server = server; - empty->contact = contact; - *dbdata = empty; - } - } else - return (ISC_R_NOTIMPLEMENTED); - return (ISC_R_SUCCESS); -} - -static void -builtin_destroy(const char *zone, void *driverdata, void **dbdata) { - builtin_t *b = (builtin_t *) *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - /* - * Don't free the static versions. - */ - if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || - *dbdata == &authors_builtin || *dbdata == &id_builtin || - *dbdata == &empty_builtin || *dbdata == &dns64_builtin) - return; - - isc_mem_free(ns_g_mctx, b->server); - isc_mem_free(ns_g_mctx, b->contact); - isc_mem_put(ns_g_mctx, b, sizeof (*b)); -} - -static dns_sdbmethods_t builtin_methods = { - builtin_lookup, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - builtin_destroy, - NULL -}; - -static dns_sdbmethods_t dns64_methods = { - NULL, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - builtin_destroy, - dns64_lookup, -}; - -isc_result_t -ns_builtin_init(void) { - RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA, - ns_g_mctx, &builtin_impl) - == ISC_R_SUCCESS); - RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_DNS64, - ns_g_mctx, &dns64_impl) - == ISC_R_SUCCESS); - return (ISC_R_SUCCESS); -} - -void -ns_builtin_deinit(void) { - dns_sdb_unregister(&builtin_impl); - dns_sdb_unregister(&dns64_impl); -} diff --git a/bin/named-sdb/client.c b/bin/named-sdb/client.c deleted file mode 100644 index 4d140e8..0000000 --- a/bin/named-sdb/client.c +++ /dev/null @@ -1,4333 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/*** - *** Client - ***/ - -/*! \file - * Client Routines - * - * Important note! - * - * All client state changes, other than that from idle to listening, occur - * as a result of events. This guarantees serialization and avoids the - * need for locking. - * - * If a routine is ever created that allows someone other than the client's - * task to change the client, then the client will have to be locked. - */ - -#define NS_CLIENT_TRACE -#ifdef NS_CLIENT_TRACE -#define CTRACE(m) ns_client_log(client, \ - NS_LOGCATEGORY_CLIENT, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "%s", (m)) -#define MTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "clientmgr @%p: %s", manager, (m)) -#else -#define CTRACE(m) ((void)(m)) -#define MTRACE(m) ((void)(m)) -#endif - -#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -#define TCP_BUFFER_SIZE (65535 + 2) -#define SEND_BUFFER_SIZE 4096 -#define RECV_BUFFER_SIZE 4096 - -#define TCP_CLIENTS_PER_CONN 23 -/*%< - * Number of simultaneous ns_clients_t (queries in flight) for one - * TCP connection. The number was arbitrarily picked and might be - * changed in the future. - */ - -#ifdef ISC_PLATFORM_USETHREADS - -#define NMCTXS 100 -/*%< - * Number of 'mctx pools' for clients. (Should this be configurable?) - * When enabling threads, we use a pool of memory contexts shared by - * client objects, since concurrent access to a shared context would cause - * heavy contentions. The above constant is expected to be enough for - * completely avoiding contentions among threads for an authoritative-only - * server. - */ -#else -#define NMCTXS 0 -/*%< - * If named with built without thread, simply share manager's context. Using - * a separate context in this case would simply waste memory. - */ -#endif - -#define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */ -#define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */ - -#define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0) -#define WANTEXPIRE(x) (((x)->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0) - -/*% nameserver client manager structure */ -struct ns_clientmgr { - /* Unlocked. */ - unsigned int magic; - - /* The queue object has its own locks */ - client_queue_t inactive; /*%< To be recycled */ - - isc_mem_t * mctx; - isc_taskmgr_t * taskmgr; - isc_timermgr_t * timermgr; - - /* Lock covers manager state. */ - isc_mutex_t lock; - bool exiting; - - /* Lock covers the clients list */ - isc_mutex_t listlock; - client_list_t clients; /*%< All active clients */ - - /* Lock covers the recursing list */ - isc_mutex_t reclock; - client_list_t recursing; /*%< Recursing clients */ - -#if NMCTXS > 0 - /*%< mctx pool for clients. */ - unsigned int nextmctx; - isc_mem_t * mctxpool[NMCTXS]; -#endif -}; - -#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) - -/*! - * Client object states. Ordering is significant: higher-numbered - * states are generally "more active", meaning that the client can - * have more dynamically allocated data, outstanding events, etc. - * In the list below, any such properties listed for state N - * also apply to any state > N. - * - * To force the client into a less active state, set client->newstate - * to that state and call exit_check(). This will cause any - * activities defined for higher-numbered states to be aborted. - */ - -#define NS_CLIENTSTATE_FREED 0 -/*%< - * The client object no longer exists. - */ - -#define NS_CLIENTSTATE_INACTIVE 1 -/*%< - * The client object exists and has a task and timer. - * Its "query" struct and sendbuf are initialized. - * It is on the client manager's list of inactive clients. - * It has a message and OPT, both in the reset state. - */ - -#define NS_CLIENTSTATE_READY 2 -/*%< - * The client object is either a TCP or a UDP one, and - * it is associated with a network interface. It is on the - * client manager's list of active clients. - * - * If it is a TCP client object, it has a TCP listener socket - * and an outstanding TCP listen request. - * - * If it is a UDP client object, it has a UDP listener socket - * and an outstanding UDP receive request. - */ - -#define NS_CLIENTSTATE_READING 3 -/*%< - * The client object is a TCP client object that has received - * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an - * outstanding TCP read request. This state is not used for - * UDP client objects. - */ - -#define NS_CLIENTSTATE_WORKING 4 -/*%< - * The client object has received a request and is working - * on it. It has a view, and it may have any of a non-reset OPT, - * recursion quota, and an outstanding write request. - */ - -#define NS_CLIENTSTATE_RECURSING 5 -/*%< - * The client object is recursing. It will be on the 'recursing' - * list. - */ - -#define NS_CLIENTSTATE_MAX 9 -/*%< - * Sentinel value used to indicate "no state". When client->newstate - * has this value, we are not attempting to exit the current state. - * Must be greater than any valid state. - */ - -/* - * Enable ns_client_dropport() by default. - */ -#ifndef NS_CLIENT_DROPPORT -#define NS_CLIENT_DROPPORT 1 -#endif - -#ifdef NS_CLIENT_NCRSTDATOMIC -_Atomic(unsigned int) ns_client_requests; -#else -unsigned int ns_client_requests; -#endif - -static void client_read(ns_client_t *client); -static void client_accept(ns_client_t *client); -static void client_udprecv(ns_client_t *client); -static void clientmgr_destroy(ns_clientmgr_t *manager); -static bool exit_check(ns_client_t *client); -static void ns_client_endrequest(ns_client_t *client); -static void client_start(isc_task_t *task, isc_event_t *event); -static void client_request(isc_task_t *task, isc_event_t *event); -static void ns_client_dumpmessage(ns_client_t *client, const char *reason); -static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, - dns_dispatch_t *disp, bool tcp); -static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, - isc_socket_t *sock, ns_client_t *oldclient); -static inline bool -allowed(isc_netaddr_t *addr, const dns_name_t *signer, - isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, - uint8_t *ecs_scope, dns_acl_t *acl); -static void compute_cookie(ns_client_t *client, uint32_t when, - uint32_t nonce, const unsigned char *secret, - isc_buffer_t *buf); - -void -ns_client_recursing(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING); - - LOCK(&client->manager->reclock); - client->newstate = client->state = NS_CLIENTSTATE_RECURSING; - ISC_LIST_APPEND(client->manager->recursing, client, rlink); - UNLOCK(&client->manager->reclock); -} - -void -ns_client_killoldestquery(ns_client_t *client) { - ns_client_t *oldest; - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->reclock); - oldest = ISC_LIST_HEAD(client->manager->recursing); - if (oldest != NULL) { - ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink); - UNLOCK(&client->manager->reclock); - ns_query_cancel(oldest); - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_reclimitdropped); - } else { - UNLOCK(&client->manager->reclock); - } -} - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds) { - isc_result_t result; - isc_interval_t interval; - - isc_interval_set(&interval, seconds, 0); - result = isc_timer_reset(client->timer, isc_timertype_once, NULL, - &interval, false); - client->timerset = true; - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "setting timeout: %s", - isc_result_totext(result)); - /* Continue anyway. */ - } -} - -/*% - * Allocate a reference-counted object that will maintain a single pointer to - * the (also reference-counted) TCP client quota, shared between all the - * clients processing queries on a single TCP connection, so that all - * clients sharing the one socket will together consume only one slot in - * the 'tcp-clients' quota. - */ -static isc_result_t -tcpconn_init(ns_client_t *client, bool force) { - isc_result_t result; - isc_quota_t *quota = NULL; - ns_tcpconn_t *tconn = NULL; - - REQUIRE(client->tcpconn == NULL); - - /* - * Try to attach to the quota first, so we won't pointlessly - * allocate memory for a tcpconn object if we can't get one. - */ - if (force) { - result = isc_quota_force(&ns_g_server->tcpquota, "a); - } else { - result = isc_quota_attach(&ns_g_server->tcpquota, "a); - } - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * A global memory context is used for the allocation as different - * client structures may have different memory contexts assigned and a - * reference counter allocated here might need to be freed by a - * different client. The performance impact caused by memory context - * contention here is expected to be negligible, given that this code - * is only executed for TCP connections. - */ - tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn)); - if (tconn == NULL) { - isc_quota_detach("a); - return (ISC_R_NOMEMORY); - } - - isc_refcount_init(&tconn->clients, 1); /* Current client */ - tconn->tcpquota = quota; - quota = NULL; - tconn->pipelined = false; - - client->tcpconn = tconn; - - return (ISC_R_SUCCESS); -} - -/*% - * Increase the count of client structures sharing the TCP connection - * that 'source' is associated with; add a pointer to the same tcpconn - * to 'target', thus associating it with the same TCP connection. - */ -static void -tcpconn_attach(ns_client_t *source, ns_client_t *target) { - int old_clients; - - REQUIRE(source->tcpconn != NULL); - REQUIRE(target->tcpconn == NULL); - REQUIRE(source->tcpconn->pipelined); - - isc_refcount_increment(&source->tcpconn->clients, &old_clients); - INSIST(old_clients > 1); - target->tcpconn = source->tcpconn; -} - -/*% - * Decrease the count of client structures sharing the TCP connection that - * 'client' is associated with. If this is the last client using this TCP - * connection, we detach from the TCP quota and free the tcpconn - * object. Either way, client->tcpconn is set to NULL. - */ -static void -tcpconn_detach(ns_client_t *client) { - ns_tcpconn_t *tconn = NULL; - int old_clients; - - REQUIRE(client->tcpconn != NULL); - - tconn = client->tcpconn; - client->tcpconn = NULL; - - isc_refcount_decrement(&tconn->clients, &old_clients); - if (old_clients == 0) { - isc_quota_detach(&tconn->tcpquota); - isc_mem_free(ns_g_mctx, tconn); - } -} - -/*% - * Mark a client as active and increment the interface's 'ntcpactive' - * counter, as a signal that there is at least one client servicing - * TCP queries for the interface. If we reach the TCP client quota at - * some point, this will be used to determine whether a quota overrun - * should be permitted. - * - * Marking the client active with the 'tcpactive' flag ensures proper - * accounting, by preventing us from incrementing or decrementing - * 'ntcpactive' more than once per client. - */ -static void -mark_tcp_active(ns_client_t *client, bool active) { - if (active && !client->tcpactive) { - isc_refcount_increment0(&client->interface->ntcpactive, NULL); - client->tcpactive = active; - } else if (!active && client->tcpactive) { - isc_refcount_decrement(&client->interface->ntcpactive, NULL); - client->tcpactive = active; - } -} - -/*% - * Check for a deactivation or shutdown request and take appropriate - * action. Returns true if either is in progress; in this case - * the caller must no longer use the client object as it may have been - * freed. - */ -static bool -exit_check(ns_client_t *client) { - bool destroy_manager = false; - ns_clientmgr_t *manager = NULL; - - REQUIRE(NS_CLIENT_VALID(client)); - manager = client->manager; - - if (client->state <= client->newstate) - return (false); /* Business as usual. */ - - INSIST(client->newstate < NS_CLIENTSTATE_RECURSING); - - /* - * We need to detach from the view early when shutting down - * the server to break the following vicious circle: - * - * - The resolver will not shut down until the view refcount is zero - * - The view refcount does not go to zero until all clients detach - * - The client does not detach from the view until references is zero - * - references does not go to zero until the resolver has shut down - * - * Keep the view attached until any outstanding updates complete. - */ - if (client->nupdates == 0 && - client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) - dns_view_detach(&client->view); - - if (client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING) - { - INSIST(client->newstate <= NS_CLIENTSTATE_READING); - /* - * Let the update processing complete. - */ - if (client->nupdates > 0) - return (true); - - /* - * We are trying to abort request processing. - */ - if (client->nsends > 0) { - isc_socket_t *sock; - if (TCP_CLIENT(client)) - sock = client->tcpsocket; - else - sock = client->udpsocket; - isc_socket_cancel(sock, client->task, - ISC_SOCKCANCEL_SEND); - } - - if (! (client->nsends == 0 && client->nrecvs == 0 && - client->references == 0)) - { - /* - * Still waiting for I/O cancel completion. - * or lingering references. - */ - return (true); - } - - /* - * I/O cancel is complete. Burn down all state - * related to the current request. Ensure that - * the client is no longer on the recursing list. - * - * We need to check whether the client is still linked, - * because it may already have been removed from the - * recursing list by ns_client_killoldestquery() - */ - if (client->state == NS_CLIENTSTATE_RECURSING) { - LOCK(&manager->reclock); - if (ISC_LINK_LINKED(client, rlink)) - ISC_LIST_UNLINK(manager->recursing, - client, rlink); - UNLOCK(&manager->reclock); - } - ns_client_endrequest(client); - - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - if (NS_CLIENTSTATE_READING == client->newstate) { - INSIST(client->tcpconn != NULL); - if (!client->tcpconn->pipelined) { - client_read(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (true); /* We're done. */ - } else if (client->mortal) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - } else - return (false); - } - } - - if (client->state == NS_CLIENTSTATE_READING) { - /* - * We are trying to abort the current TCP connection, - * if any. - */ - INSIST(client->recursionquota == NULL); - INSIST(client->newstate <= NS_CLIENTSTATE_READY); - - if (client->nreads > 0) { - dns_tcpmsg_cancelread(&client->tcpmsg); - /* Still waiting for read cancel completion? */ - if (client->nreads > 0) { - return (true); - } - } - - if (client->tcpmsg_valid) { - dns_tcpmsg_invalidate(&client->tcpmsg); - client->tcpmsg_valid = false; - } - - /* - * Soon the client will be ready to accept a new TCP - * connection or UDP request, but we may have enough - * clients doing that already. Check whether this client - * needs to remain active and allow it go inactive if - * not. - * - * UDP clients always go inactive at this point, but a TCP - * client may need to stay active and return to READY - * state if no other clients are available to listen - * for TCP requests on this interface. - * - * Regardless, if we're going to FREED state, that means - * the system is shutting down and we don't need to - * retain clients. - */ - if (client->mortal && TCP_CLIENT(client) && - client->newstate != NS_CLIENTSTATE_FREED && - !ns_g_clienttest && - isc_refcount_current(&client->interface->ntcpaccepting) == 0) - { - /* Nobody else is accepting */ - client->mortal = false; - client->newstate = NS_CLIENTSTATE_READY; - } - - /* - * Detach from TCP connection and TCP client quota, - * if appropriate. If this is the last reference to - * the TCP connection in our pipeline group, the - * TCP quota slot will be released. - */ - if (client->tcpconn) { - tcpconn_detach(client); - } - - if (client->tcpsocket != NULL) { - CTRACE("closetcp"); - isc_socket_detach(&client->tcpsocket); - mark_tcp_active(client, false); - } - - if (client->timerset) { - (void)isc_timer_reset(client->timer, - isc_timertype_inactive, - NULL, NULL, true); - client->timerset = false; - } - - client->peeraddr_valid = false; - - client->state = NS_CLIENTSTATE_READY; - - /* - * We don't need the client; send it to the inactive - * queue for recycling. - */ - if (client->mortal) { - if (client->newstate > NS_CLIENTSTATE_INACTIVE) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - } - } - - if (NS_CLIENTSTATE_READY == client->newstate) { - if (TCP_CLIENT(client)) { - client_accept(client); - } else { - client_udprecv(client); - } - client->newstate = NS_CLIENTSTATE_MAX; - return (true); - } - } - - if (client->state == NS_CLIENTSTATE_READY) { - INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); - - /* - * We are trying to enter the inactive state. - */ - if (client->naccepts > 0) { - isc_socket_cancel(client->tcplistener, client->task, - ISC_SOCKCANCEL_ACCEPT); - /* Still waiting for accept cancel completion? */ - if (client->naccepts > 0) { - return (true); - } - } - - /* Accept cancel is complete. */ - if (client->nrecvs > 0) { - isc_socket_cancel(client->udpsocket, client->task, - ISC_SOCKCANCEL_RECV); - /* Still waiting for recv cancel completion? */ - if (client->nrecvs > 0) { - return (true); - } - } - - /* Still waiting for control event to be delivered */ - if (client->nctls > 0) { - return (true); - } - - INSIST(client->naccepts == 0); - INSIST(client->recursionquota == NULL); - if (client->tcplistener != NULL) { - isc_socket_detach(&client->tcplistener); - mark_tcp_active(client, false); - } - if (client->udpsocket != NULL) { - isc_socket_detach(&client->udpsocket); - } - - /* Deactivate the client. */ - if (client->interface != NULL) { - ns_interface_detach(&client->interface); - } - - if (client->dispatch != NULL) { - dns_dispatch_detach(&client->dispatch); - } - - client->attributes = 0; - client->mortal = false; - - if (client->keytag != NULL) { - isc_mem_put(client->mctx, client->keytag, - client->keytag_len); - client->keytag_len = 0; - } - - /* - * Put the client on the inactive list. If we are aiming for - * the "freed" state, it will be removed from the inactive - * list shortly, and we need to keep the manager locked until - * that has been done, lest the manager decide to reactivate - * the dying client in between. - */ - client->state = NS_CLIENTSTATE_INACTIVE; - INSIST(client->recursionquota == NULL); - - if (client->state == client->newstate) { - client->newstate = NS_CLIENTSTATE_MAX; - if (!ns_g_clienttest && manager != NULL && - !manager->exiting) - { - ISC_QUEUE_PUSH(manager->inactive, client, - ilink); - } - if (client->needshutdown) { - isc_task_shutdown(client->task); - } - return (true); - } - } - - if (client->state == NS_CLIENTSTATE_INACTIVE) { - INSIST(client->newstate == NS_CLIENTSTATE_FREED); - /* - * We are trying to free the client. - * - * When "shuttingdown" is true, either the task has received - * its shutdown event or no shutdown event has ever been - * set up. Thus, we have no outstanding shutdown - * event at this point. - */ - REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); - - INSIST(client->recursionquota == NULL); - INSIST(!ISC_QLINK_LINKED(client, ilink)); - - if (manager != NULL) { - LOCK(&manager->listlock); - ISC_LIST_UNLINK(manager->clients, client, link); - LOCK(&manager->lock); - if (manager->exiting && - ISC_LIST_EMPTY(manager->clients)) - destroy_manager = true; - UNLOCK(&manager->lock); - UNLOCK(&manager->listlock); - } - - ns_query_free(client); - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - isc_event_free((isc_event_t **)&client->sendevent); - isc_event_free((isc_event_t **)&client->recvevent); - isc_timer_detach(&client->timer); - if (client->delaytimer != NULL) - isc_timer_detach(&client->delaytimer); - - if (client->tcpbuf != NULL) - isc_mem_put(client->mctx, client->tcpbuf, - TCP_BUFFER_SIZE); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, - &client->opt); - } - if (client->keytag != NULL) { - isc_mem_put(client->mctx, client->keytag, - client->keytag_len); - client->keytag_len = 0; - } - - dns_message_detach(&client->message); - - /* - * Detaching the task must be done after unlinking from - * the manager's lists because the manager accesses - * client->task. - */ - if (client->task != NULL) - isc_task_detach(&client->task); - - CTRACE("free"); - client->magic = 0; - - /* - * Check that there are no other external references to - * the memory context. - */ - if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) { - isc_mem_stats(client->mctx, stderr); - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Destroy the fetchlock mutex that was created in - * ns_query_init(). - */ - DESTROYLOCK(&client->query.fetchlock); - - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - } - - if (destroy_manager && manager != NULL) - clientmgr_destroy(manager); - - return (true); -} - -/*% - * The client's task has received the client's control event - * as part of the startup process. - */ -static void -client_start(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *) event->ev_arg; - - INSIST(task == client->task); - - UNUSED(task); - - INSIST(client->nctls == 1); - client->nctls--; - - if (exit_check(client)) - return; - - if (TCP_CLIENT(client)) { - if (client->tcpconn != NULL) { - client_read(client); - } else { - client_accept(client); - } - } else { - client_udprecv(client); - } -} - -/*% - * The client's task has received a shutdown event. - */ -static void -client_shutdown(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - UNUSED(task); - - CTRACE("shutdown"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - ISC_QUEUE_UNLINKIFLINKED(client->manager->inactive, client, ilink); - - client->newstate = NS_CLIENTSTATE_FREED; - client->needshutdown = false; - (void)exit_check(client); -} - -static void -ns_client_endrequest(ns_client_t *client) { - INSIST(client->naccepts == 0); - INSIST(client->nreads == 0); - INSIST(client->nsends == 0); - INSIST(client->nrecvs == 0); - INSIST(client->nupdates == 0); - INSIST(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING); - - CTRACE("endrequest"); - - if (client->next != NULL) { - (client->next)(client); - client->next = NULL; - } - - if (client->view != NULL) { -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_resolver) { - dns_cache_clean(client->view->cache, INT_MAX); - dns_adb_flush(client->view->adb); - } -#endif - dns_view_detach(&client->view); - } - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - - client->signer = NULL; - client->udpsize = 512; - client->extflags = 0; - client->ednsversion = -1; - dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); - - if (client->recursionquota != NULL) { - isc_quota_detach(&client->recursionquota); - isc_stats_decrement(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - - /* - * Clear all client attributes that are specific to - * the request; that's all except the TCP flag. - */ - client->attributes &= NS_CLIENTATTR_TCP; -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_client || - ns_g_fuzz_type == ns_fuzz_tcpclient || - ns_g_fuzz_type == ns_fuzz_resolver) { - named_fuzz_notify(); - } -#endif /* ENABLE_AFL */ - -} - -void -ns_client_next(ns_client_t *client, isc_result_t result) { - int newstate; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_RECURSING || - client->state == NS_CLIENTSTATE_READING); - - CTRACE("next"); - - if (result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request failed: %s", isc_result_totext(result)); - - /* - * An error processing a TCP request may have left - * the connection out of sync. To be safe, we always - * sever the connection when result != ISC_R_SUCCESS. - */ - if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) - newstate = NS_CLIENTSTATE_READING; - else - newstate = NS_CLIENTSTATE_READY; - - if (client->newstate > newstate) - client->newstate = newstate; - (void)exit_check(client); -} - - -static void -client_senddone(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - - REQUIRE(sevent != NULL); - REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); - client = sevent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(sevent == client->sendevent); - - UNUSED(task); - - CTRACE("senddone"); - - if (sevent->result != ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "error sending response: %s", - isc_result_totext(sevent->result)); - - INSIST(client->nsends > 0); - client->nsends--; - - if (client->tcpbuf != NULL) { - INSIST(TCP_CLIENT(client)); - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - ns_client_next(client, ISC_R_SUCCESS); -} - -/*% - * We only want to fail with ISC_R_NOSPACE when called from - * ns_client_sendraw() and not when called from ns_client_send(), - * tcpbuffer is NULL when called from ns_client_sendraw() and - * length != 0. tcpbuffer != NULL when called from ns_client_send() - * and length == 0. - */ - -static isc_result_t -client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, - isc_buffer_t *tcpbuffer, uint32_t length, - unsigned char *sendbuf, unsigned char **datap) -{ - unsigned char *data; - uint32_t bufsize; - isc_result_t result; - - INSIST(datap != NULL); - INSIST((tcpbuffer == NULL && length != 0) || - (tcpbuffer != NULL && length == 0)); - - if (TCP_CLIENT(client)) { - INSIST(client->tcpbuf == NULL); - if (length + 2 > TCP_BUFFER_SIZE) { - result = ISC_R_NOSPACE; - goto done; - } - client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); - if (client->tcpbuf == NULL) { - result = ISC_R_NOMEMORY; - goto done; - } - data = client->tcpbuf; - if (tcpbuffer != NULL) { - isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); - isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); - } else { - isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); - INSIST(length <= 0xffff); - isc_buffer_putuint16(buffer, (uint16_t)length); - } - } else { - data = sendbuf; - if ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) == 0) { - if (client->view != NULL) - bufsize = client->view->nocookieudp; - else - bufsize = 512; - } else - bufsize = client->udpsize; - if (bufsize > client->udpsize) - bufsize = client->udpsize; - if (bufsize > SEND_BUFFER_SIZE) - bufsize = SEND_BUFFER_SIZE; - if (length > bufsize) { - result = ISC_R_NOSPACE; - goto done; - } - isc_buffer_init(buffer, data, bufsize); - } - *datap = data; - result = ISC_R_SUCCESS; - - done: - return (result); -} - -static isc_result_t -client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { - struct in6_pktinfo *pktinfo; - isc_result_t result; - isc_region_t r; - isc_sockaddr_t *address; - isc_socket_t *sock; - isc_netaddr_t netaddr; - int match; - unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; - - if (TCP_CLIENT(client)) { - sock = client->tcpsocket; - address = NULL; - } else { - sock = client->udpsocket; - address = &client->peeraddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - return (DNS_R_BLACKHOLED); - sockflags |= ISC_SOCKFLAG_NORETRY; - } - - if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && - (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - - if (client->dispatch != NULL) { - isc_dscp_t dscp = dns_dispatch_getdscp(client->dispatch); - if (dscp != -1) { - client->dscp = dscp; - } - } - - if (client->dscp == -1) { - client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; - client->sendevent->dscp = 0; - } else { - client->sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; - client->sendevent->dscp = client->dscp; - } - - isc_buffer_usedregion(buffer, &r); - - /* - * If this is a UDP client and the IPv6 packet can't be - * encapsulated without generating a PTB on a 1500 octet - * MTU link force fragmentation at 1280 if it is a IPv6 - * response. - */ - client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_USEMINMTU; - if (!TCP_CLIENT(client) && r.length > 1432) - client->sendevent->attributes |= ISC_SOCKEVENTATTR_USEMINMTU; - - CTRACE("sendto"); - - result = isc_socket_sendto2(sock, &r, client->task, - address, pktinfo, - client->sendevent, sockflags); - if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { - client->nsends++; - if (result == ISC_R_SUCCESS) - client_senddone(client->task, - (isc_event_t *)client->sendevent); - result = ISC_R_SUCCESS; - } - return (result); -} - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *message) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_region_t r; - isc_region_t *mr; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("sendraw"); - - mr = dns_message_getrawmessage(message); - if (mr == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto done; - } - - result = client_allocsendbuf(client, &buffer, NULL, mr->length, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - /* - * Copy message to buffer and fixup id. - */ - isc_buffer_availableregion(&buffer, &r); - result = isc_buffer_copyregion(&buffer, mr); - if (result != ISC_R_SUCCESS) - goto done; - r.base[0] = (client->message->id >> 8) & 0xff; - r.base[1] = client->message->id & 0xff; - - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - ns_client_next(client, result); -} - -static void -client_send(ns_client_t *client) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_buffer_t tcpbuffer; - isc_region_t r; - dns_compress_t cctx; - bool cleanup_cctx = false; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - unsigned int render_opts; - unsigned int preferred_glue; - bool opt_included = false; - size_t respsize; -#ifdef HAVE_DNSTAP - unsigned char zone[DNS_NAME_MAXWIRE]; - dns_dtmsgtype_t dtmsgtype; - isc_region_t zr; -#endif /* HAVE_DNSTAP */ - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("send"); - - if (client->message->opcode == dns_opcode_query && - (client->attributes & NS_CLIENTATTR_RA) != 0) - client->message->flags |= DNS_MESSAGEFLAG_RA; - - if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) - render_opts = 0; - else - render_opts = DNS_MESSAGERENDER_OMITDNSSEC; - - preferred_glue = 0; - if (client->view != NULL) { - if (client->view->preferred_glue == dns_rdatatype_a) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else if (client->view->preferred_glue == dns_rdatatype_aaaa) - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - if (preferred_glue == 0) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * filter-aaaa-on-v4 yes or break-dnssec option to suppress - * AAAA records. - * - * We already know that request came via IPv4, - * that we have both AAAA and A records, - * and that we either have no signatures that the client wants - * or we are supposed to break DNSSEC. - * - * Override preferred glue if necessary. - */ - if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) { - render_opts |= DNS_MESSAGERENDER_FILTER_AAAA; - if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - } -#endif - - /* - * Create an OPT for our reply. - */ - if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { - result = ns_client_addopt(client, client->message, - &client->opt); - if (result != ISC_R_SUCCESS) - goto done; - } - - /* - * XXXRTH The following doesn't deal with TCP buffer resizing. - */ - result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - result = dns_compress_init(&cctx, -1, client->mctx); - if (result != ISC_R_SUCCESS) - goto done; - if (client->peeraddr_valid && client->view != NULL) { - isc_netaddr_t netaddr; - dns_name_t *name = NULL; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (client->message->tsigkey != NULL) - name = &client->message->tsigkey->name; - - if (client->view->nocasecompress == NULL || - !allowed(&netaddr, name, NULL, 0, NULL, - client->view->nocasecompress)) - { - dns_compress_setsensitive(&cctx, true); - } - - if (client->view->msgcompression == false) { - dns_compress_disable(&cctx); - } - } - cleanup_cctx = true; - - result = dns_message_renderbegin(client->message, &cctx, &buffer); - if (result != ISC_R_SUCCESS) - goto done; - - if (client->opt != NULL) { - result = dns_message_setopt(client->message, client->opt); - opt_included = true; - client->opt = NULL; - if (result != ISC_R_SUCCESS) - goto done; - } - result = dns_message_rendersection(client->message, - DNS_SECTION_QUESTION, 0); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - /* - * Stop after the question if TC was set for rate limiting. - */ - if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) - goto renderend; - result = dns_message_rendersection(client->message, - DNS_SECTION_ANSWER, - DNS_MESSAGERENDER_PARTIAL | - render_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_AUTHORITY, - DNS_MESSAGERENDER_PARTIAL | - render_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ADDITIONAL, - preferred_glue | render_opts); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - goto done; - renderend: - result = dns_message_renderend(client->message); - - if (result != ISC_R_SUCCESS) - goto done; - -#ifdef HAVE_DNSTAP - memset(&zr, 0, sizeof(zr)); - if (((client->message->flags & DNS_MESSAGEFLAG_AA) != 0) && - (client->query.authzone != NULL)) - { - isc_buffer_t b; - dns_name_t *zo = - dns_zone_getorigin(client->query.authzone); - - isc_buffer_init(&b, zone, sizeof(zone)); - dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE); - result = dns_name_towire(zo, &cctx, &b); - if (result == ISC_R_SUCCESS) - isc_buffer_usedregion(&b, &zr); - } - - if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) - dtmsgtype = DNS_DTTYPE_CR; - else - dtmsgtype = DNS_DTTYPE_AR; -#endif /* HAVE_DNSTAP */ - - if (cleanup_cctx) { - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - } - - if (TCP_CLIENT(client)) { - isc_buffer_usedregion(&buffer, &r); - isc_buffer_putuint16(&tcpbuffer, (uint16_t) r.length); - isc_buffer_add(&tcpbuffer, r.length); -#ifdef HAVE_DNSTAP - if (client->view != NULL) { - dns_dt_send(client->view, dtmsgtype, - &client->peeraddr, &client->destsockaddr, - true, &zr, &client->requesttime, NULL, - &buffer); - } -#endif /* HAVE_DNSTAP */ - - /* don't count the 2-octet length header */ - respsize = isc_buffer_usedlength(&tcpbuffer) - 2; - result = client_sendpkg(client, &tcpbuffer); - - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->tcpoutstats4, - ISC_MIN((int)respsize / 16, 256)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->tcpoutstats6, - ISC_MIN((int)respsize / 16, 256)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else { - respsize = isc_buffer_usedlength(&buffer); - result = client_sendpkg(client, &buffer); -#ifdef HAVE_DNSTAP - if (client->view != NULL) { - dns_dt_send(client->view, dtmsgtype, - &client->peeraddr, - &client->destsockaddr, - false, &zr, - &client->requesttime, NULL, &buffer); - } -#endif /* HAVE_DNSTAP */ - - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->udpoutstats4, - ISC_MIN((int)respsize / 16, 256)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->udpoutstats6, - ISC_MIN((int)respsize / 16, 256)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - - /* update statistics (XXXJT: is it okay to access message->xxxkey?) */ - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response); - - dns_rcodestats_increment(ns_g_server->rcodestats, - client->message->rcode); - if (opt_included) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_edns0out); - } - if (client->message->tsigkey != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_tsigout); - } - if (client->message->sig0key != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_sig0out); - } - if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_truncatedresp); - - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - - ns_client_next(client, result); -} - -/* - * Completes the sending of a delayed client response. - */ -static void -client_delay(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->delaytimer != NULL); - - UNUSED(task); - - CTRACE("client_delay"); - - isc_event_free(&event); - isc_timer_detach(&client->delaytimer); - - client_send(client); - ns_client_detach(&client); -} - -void -ns_client_send(ns_client_t *client) { - - /* - * Delay the response by ns_g_delay ms. - */ - if (ns_g_delay != 0) { - ns_client_t *dummy = NULL; - isc_result_t result; - isc_interval_t interval; - - /* - * Replace ourselves if we have not already been replaced. - */ - if (!client->mortal) { - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - goto nodelay; - } - - ns_client_attach(client, &dummy); - if (ns_g_delay >= 1000) - isc_interval_set(&interval, ns_g_delay / 1000, - (ns_g_delay % 1000) * 1000000); - else - isc_interval_set(&interval, 0, ns_g_delay * 1000000); - result = isc_timer_create(client->manager->timermgr, - isc_timertype_once, NULL, &interval, - client->task, client_delay, - client, &client->delaytimer); - if (result == ISC_R_SUCCESS) - return; - - ns_client_detach(&dummy); - } - - nodelay: - client_send(client); -} - -#if NS_CLIENT_DROPPORT -#define DROPPORT_NO 0 -#define DROPPORT_REQUEST 1 -#define DROPPORT_RESPONSE 2 -/*% - * ns_client_dropport determines if certain requests / responses - * should be dropped based on the port number. - * - * Returns: - * \li 0: Don't drop. - * \li 1: Drop request. - * \li 2: Drop (error) response. - */ -static int -ns_client_dropport(in_port_t port) { - switch (port) { - case 7: /* echo */ - case 13: /* daytime */ - case 19: /* chargen */ - case 37: /* time */ - return (DROPPORT_REQUEST); - case 464: /* kpasswd */ - return (DROPPORT_RESPONSE); - } - return (DROPPORT_NO); -} -#endif - -void -ns_client_error(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("error"); - - message = client->message; - rcode = dns_result_torcode(result); - -#if NS_CLIENT_DROPPORT - /* - * Don't send FORMERR to ports on the drop port list. - */ - if (rcode == dns_rcode_formerr && - ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != - DROPPORT_NO) { - char buf[64]; - isc_buffer_t b; - - isc_buffer_init(&b, buf, sizeof(buf) - 1); - if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) - isc_buffer_putstr(&b, "UNKNOWN RCODE"); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped error (%.*s) response: suspicious port", - (int)isc_buffer_usedlength(&b), buf); - ns_client_next(client, ISC_R_SUCCESS); - return; - } -#endif - - /* - * Try to rate limit error responses. - */ - if (client->view != NULL && client->view->rrl != NULL) { - bool wouldlog; - char log_buf[DNS_RRL_LOG_BUF_LEN]; - dns_rrl_result_t rrl_result; - int loglevel; - - INSIST(rcode != dns_rcode_noerror && - rcode != dns_rcode_nxdomain); - if (ns_g_server->log_queries) - loglevel = DNS_RRL_LOG_DROP; - else - loglevel = ISC_LOG_DEBUG(1); - wouldlog = isc_log_wouldlog(ns_g_lctx, loglevel); - rrl_result = dns_rrl(client->view, &client->peeraddr, - TCP_CLIENT(client), - dns_rdataclass_in, dns_rdatatype_none, - NULL, result, client->now, - wouldlog, log_buf, sizeof(log_buf)); - if (rrl_result != DNS_RRL_RESULT_OK) { - /* - * Log dropped errors in the query category - * so that they are not lost in silence. - * Starts of rate-limited bursts are logged in - * NS_LOGCATEGORY_RRL. - */ - if (wouldlog) { - ns_client_log(client, - NS_LOGCATEGORY_QUERY_ERRORS, - NS_LOGMODULE_CLIENT, - loglevel, - "%s", log_buf); - } - /* - * Some error responses cannot be 'slipped', - * so don't try to slip any error responses. - */ - if (!client->view->rrl->log_only) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_ratedropped); - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_dropped); - ns_client_next(client, DNS_R_DROP); - return; - } - } - } - - /* - * Message may be an in-progress reply that we had trouble - * with, in which case QR will be set. We need to clear QR before - * calling dns_message_reply() to avoid triggering an assertion. - */ - message->flags &= ~DNS_MESSAGEFLAG_QR; - /* - * AA and AD shouldn't be set. - */ - message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); - result = dns_message_reply(message, true); - if (result != ISC_R_SUCCESS) { - /* - * It could be that we've got a query with a good header, - * but a bad question section, so we try again with - * want_question_section set to false. - */ - result = dns_message_reply(message, false); - if (result != ISC_R_SUCCESS) { - ns_client_next(client, result); - return; - } - } - message->rcode = rcode; - - if (rcode == dns_rcode_formerr) { - /* - * FORMERR loop avoidance: If we sent a FORMERR message - * with the same ID to the same client less than two - * seconds ago, assume that we are in an infinite error - * packet dialog with a server for some protocol whose - * error responses look enough like DNS queries to - * elicit a FORMERR response. Drop a packet to break - * the loop. - */ - if (isc_sockaddr_equal(&client->peeraddr, - &client->formerrcache.addr) && - message->id == client->formerrcache.id && - (isc_time_seconds(&client->requesttime) - - client->formerrcache.time) < 2) - { - /* Drop packet. */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "possible error packet loop, " - "FORMERR dropped"); - ns_client_next(client, result); - return; - } - client->formerrcache.addr = client->peeraddr; - client->formerrcache.time = - isc_time_seconds(&client->requesttime); - client->formerrcache.id = message->id; - } else if (rcode == dns_rcode_servfail && client->query.qname != NULL && - client->view != NULL && client->view->fail_ttl != 0 && - ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0)) - { - /* - * SERVFAIL caching: store qname/qtype of failed queries - */ - isc_time_t expire; - isc_interval_t i; - uint32_t flags = 0; - - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) - flags = NS_FAILCACHE_CD; - - isc_interval_set(&i, client->view->fail_ttl, 0); - result = isc_time_nowplusinterval(&expire, &i); - if (result == ISC_R_SUCCESS) - dns_badcache_add(client->view->failcache, - client->query.qname, - client->query.qtype, - true, flags, &expire); - } - ns_client_send(client); -} - -isc_result_t -ns_client_addopt(ns_client_t *client, dns_message_t *message, - dns_rdataset_t **opt) -{ - unsigned char ecs[ECS_SIZE]; - char nsid[BUFSIZ], *nsidp; - unsigned char cookie[COOKIE_SIZE]; - isc_result_t result; - dns_view_t *view; - dns_resolver_t *resolver; - uint16_t udpsize; - dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; - int count = 0; - unsigned int flags; - unsigned char expire[4]; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(opt != NULL && *opt == NULL); - REQUIRE(message != NULL); - - view = client->view; - resolver = (view != NULL) ? view->resolver : NULL; - if (resolver != NULL) - udpsize = dns_resolver_getudpsize(resolver); - else - udpsize = ns_g_udpsize; - - flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE; - - /* Set EDNS options if applicable */ - if (WANTNSID(client) && - (ns_g_server->server_id != NULL || - ns_g_server->server_usehostname)) { - if (ns_g_server->server_usehostname) { - result = ns_os_gethostname(nsid, sizeof(nsid)); - if (result != ISC_R_SUCCESS) { - goto no_nsid; - } - nsidp = nsid; - } else - nsidp = ns_g_server->server_id; - - INSIST(count < DNS_EDNSOPTIONS); - ednsopts[count].code = DNS_OPT_NSID; - ednsopts[count].length = (uint16_t)strlen(nsidp); - ednsopts[count].value = (unsigned char *)nsidp; - count++; - } - no_nsid: - if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) { - isc_buffer_t buf; - isc_stdtime_t now; - uint32_t nonce; - - isc_buffer_init(&buf, cookie, sizeof(cookie)); - isc_stdtime_get(&now); - nonce = ((isc_rng_random(ns_g_server->rngctx) << 16) | - isc_rng_random(ns_g_server->rngctx)); - - compute_cookie(client, now, nonce, ns_g_server->secret, &buf); - - INSIST(count < DNS_EDNSOPTIONS); - ednsopts[count].code = DNS_OPT_COOKIE; - ednsopts[count].length = COOKIE_SIZE; - ednsopts[count].value = cookie; - count++; - } - if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) { - isc_buffer_t buf; - - INSIST(count < DNS_EDNSOPTIONS); - - isc_buffer_init(&buf, expire, sizeof(expire)); - isc_buffer_putuint32(&buf, client->expire); - ednsopts[count].code = DNS_OPT_EXPIRE; - ednsopts[count].length = 4; - ednsopts[count].value = expire; - count++; - } - if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) && - (client->ecs_addr.family == AF_INET || - client->ecs_addr.family == AF_INET6 || - client->ecs_addr.family == AF_UNSPEC)) - { - isc_buffer_t buf; - uint8_t addr[16]; - uint32_t plen, addrl; - uint16_t family = 0; - - /* Add CLIENT-SUBNET option. */ - - plen = client->ecs_addrlen; - - /* Round up prefix len to a multiple of 8 */ - addrl = (plen + 7) / 8; - - switch (client->ecs_addr.family) { - case AF_UNSPEC: - INSIST(plen == 0); - family = 0; - break; - case AF_INET: - INSIST(plen <= 32); - family = 1; - memmove(addr, &client->ecs_addr.type, addrl); - break; - case AF_INET6: - INSIST(plen <= 128); - family = 2; - memmove(addr, &client->ecs_addr.type, addrl); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_buffer_init(&buf, ecs, sizeof(ecs)); - /* family */ - isc_buffer_putuint16(&buf, family); - /* source prefix-length */ - isc_buffer_putuint8(&buf, client->ecs_addrlen); - /* scope prefix-length */ - isc_buffer_putuint8(&buf, client->ecs_scope); - - /* address */ - if (addrl > 0) { - /* Mask off last address byte */ - if ((plen % 8) != 0) - addr[addrl - 1] &= - ~0U << (8 - (plen % 8)); - isc_buffer_putmem(&buf, addr, - (unsigned) addrl); - } - - ednsopts[count].code = DNS_OPT_CLIENT_SUBNET; - ednsopts[count].length = addrl + 4; - ednsopts[count].value = ecs; - count++; - } - - result = dns_message_buildopt(message, opt, 0, udpsize, flags, - ednsopts, count); - return (result); -} - -static inline bool -allowed(isc_netaddr_t *addr, const dns_name_t *signer, - isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen, - uint8_t *ecs_scope, dns_acl_t *acl) -{ - int match; - isc_result_t result; - - if (acl == NULL) - return (true); - result = dns_acl_match2(addr, signer, ecs_addr, ecs_addrlen, ecs_scope, - acl, &ns_g_server->aclenv, &match, NULL); - if (result == ISC_R_SUCCESS && match > 0) - return (true); - return (false); -} - -/* - * Callback to see if a non-recursive query coming from 'srcaddr' to - * 'destaddr', with optional key 'mykey' for class 'rdclass' would be - * delivered to 'myview'. - * - * We run this unlocked as both the view list and the interface list - * are updated when the appropriate task has exclusivity. - */ -bool -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr, - dns_rdataclass_t rdclass, void *arg) -{ - dns_view_t *view; - dns_tsigkey_t *key = NULL; - isc_netaddr_t netsrc; - isc_netaddr_t netdst; - - UNUSED(arg); - - /* - * ns_g_server->interfacemgr is task exclusive locked. - */ - if (ns_g_server->interfacemgr == NULL) - return (true); - - if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) - return (false); - - isc_netaddr_fromsockaddr(&netsrc, srcaddr); - isc_netaddr_fromsockaddr(&netdst, dstaddr); - - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - const dns_name_t *tsig = NULL; - - if (view->matchrecursiveonly) - continue; - - if (rdclass != view->rdclass) - continue; - - if (mykey != NULL) { - bool match; - isc_result_t result; - - result = dns_view_gettsig(view, &mykey->name, &key); - if (result != ISC_R_SUCCESS) - continue; - match = dst_key_compare(mykey->key, key->key); - dns_tsigkey_detach(&key); - if (!match) - continue; - tsig = dns_tsigkey_identity(mykey); - } - - if (allowed(&netsrc, tsig, NULL, 0, NULL, - view->matchclients) && - allowed(&netdst, tsig, NULL, 0, NULL, - view->matchdestinations)) - break; - } - return (view == myview); -} - -static void -compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce, - const unsigned char *secret, isc_buffer_t *buf) -{ - switch (ns_g_server->cookiealg) { - case ns_cookiealg_siphash24: { - unsigned char digest[ISC_SIPHASH24_TAG_LENGTH] = { 0 }; - unsigned char input[16 + 16] = { 0 }; - size_t inputlen = 0; - isc_netaddr_t netaddr; - unsigned char *cp; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1); - isc_buffer_putuint24(buf, 0); /* Reserved */ - isc_buffer_putuint32(buf, when); - - memmove(input, cp, 16); - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - memmove(input + 16, cp, 4); - inputlen = 20; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - memmove(input + 16, cp, 16); - inputlen = 32; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_siphash24(secret, input, inputlen, digest); - isc_buffer_putmem(buf, digest, 8); - break; - } -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) - case ns_cookiealg_aes: { - unsigned char digest[ISC_AES_BLOCK_LENGTH]; - unsigned char input[4 + 4 + 16]; - isc_netaddr_t netaddr; - unsigned char *cp; - unsigned int i; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - memmove(input, cp, 16); - isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) { - input[i] = digest[i] ^ digest[i + 8]; - } - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - memmove(input + 8, cp, 4); - memset(input + 12, 0, 4); - isc_aes128_crypt(secret, input, digest); - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - memmove(input + 8, cp, 16); - isc_aes128_crypt(secret, input, digest); - for (i = 0; i < 8; i++) { - input[i + 8] = digest[i] ^ digest[i + 8]; - } - isc_aes128_crypt(ns_g_server->secret, input + 8, - digest); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - for (i = 0; i < 8; i++) { - digest[i] ^= digest[i + 8]; - } - isc_buffer_putmem(buf, digest, 8); - break; - } -#endif - - case ns_cookiealg_sha1: { - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - isc_netaddr_t netaddr; - unsigned char *cp; - isc_hmacsha1_t hmacsha1; - unsigned int length; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - - isc_hmacsha1_init(&hmacsha1, secret, ISC_SHA1_DIGESTLENGTH); - isc_hmacsha1_update(&hmacsha1, cp, 16); - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - length = 4; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - length = 16; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_hmacsha1_update(&hmacsha1, cp, length); - isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest)); - isc_buffer_putmem(buf, digest, 8); - isc_hmacsha1_invalidate(&hmacsha1); - break; - } - - case ns_cookiealg_sha256: { - unsigned char digest[ISC_SHA256_DIGESTLENGTH]; - isc_netaddr_t netaddr; - unsigned char *cp; - isc_hmacsha256_t hmacsha256; - unsigned int length; - - cp = isc_buffer_used(buf); - isc_buffer_putmem(buf, client->cookie, 8); - isc_buffer_putuint32(buf, nonce); - isc_buffer_putuint32(buf, when); - - isc_hmacsha256_init(&hmacsha256, secret, - ISC_SHA256_DIGESTLENGTH); - isc_hmacsha256_update(&hmacsha256, cp, 16); - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (netaddr.family) { - case AF_INET: - cp = (unsigned char *)&netaddr.type.in; - length = 4; - break; - case AF_INET6: - cp = (unsigned char *)&netaddr.type.in6; - length = 16; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_hmacsha256_update(&hmacsha256, cp, length); - isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest)); - isc_buffer_putmem(buf, digest, 8); - isc_hmacsha256_invalidate(&hmacsha256); - break; - } - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void -process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - ns_altsecret_t *altsecret; - unsigned char dbuf[COOKIE_SIZE]; - unsigned char *old; - isc_stdtime_t now; - uint32_t when; - uint32_t nonce; - isc_buffer_t db; - - /* - * If we have already seen a cookie option skip this cookie option. - */ - if ((!ns_g_server->answercookie) || - (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) - { - isc_buffer_forward(buf, (unsigned int)optlen); - return; - } - - client->attributes |= NS_CLIENTATTR_WANTCOOKIE; - - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_cookiein); - - if (optlen != COOKIE_SIZE) { - /* - * Not our token. - */ - INSIST(optlen >= 8U); - memmove(client->cookie, isc_buffer_current(buf), 8); - isc_buffer_forward(buf, (unsigned int)optlen); - - if (optlen == 8U) - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookienew); - else - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiebadsize); - return; - } - - /* - * Process all of the incoming buffer. - */ - old = isc_buffer_current(buf); - memmove(client->cookie, old, 8); - isc_buffer_forward(buf, 8); - nonce = isc_buffer_getuint32(buf); - when = isc_buffer_getuint32(buf); - isc_buffer_forward(buf, 8); - - /* - * Allow for a 5 minute clock skew between servers sharing a secret. - * Only accept COOKIE if we have talked to the client in the last hour. - */ - isc_stdtime_get(&now); - if (isc_serial_gt(when, (now + 300)) || /* In the future. */ - isc_serial_lt(when, (now - 3600))) { /* In the past. */ - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiebadtime); - return; - } - - isc_buffer_init(&db, dbuf, sizeof(dbuf)); - compute_cookie(client, when, nonce, ns_g_server->secret, &db); - - if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiematch); - client->attributes |= NS_CLIENTATTR_HAVECOOKIE; - return; - } - - for (altsecret = ISC_LIST_HEAD(ns_g_server->altsecrets); - altsecret != NULL; - altsecret = ISC_LIST_NEXT(altsecret, link)) - { - isc_buffer_init(&db, dbuf, sizeof(dbuf)); - compute_cookie(client, when, nonce, altsecret->secret, &db); - if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookiematch); - client->attributes |= NS_CLIENTATTR_HAVECOOKIE; - return; - } - } - - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_cookienomatch); -} - -static isc_result_t -process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - uint16_t family; - uint8_t addrlen, addrbytes, scope, *paddr; - isc_netaddr_t caddr; - - /* - * If we have already seen a ECS option skip this ECS option. - */ - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); - } - - /* - * XXXMUKS: Is there any need to repeat these checks here - * (except query's scope length) when they are done in the OPT - * RDATA fromwire code? - */ - - if (optlen < 4U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option too short"); - return (DNS_R_FORMERR); - } - - family = isc_buffer_getuint16(buf); - addrlen = isc_buffer_getuint8(buf); - scope = isc_buffer_getuint8(buf); - optlen -= 4; - - if (scope != 0U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid scope"); - return (DNS_R_OPTERR); - } - - memset(&caddr, 0, sizeof(caddr)); - switch (family) { - case 0: - /* - * XXXMUKS: In queries, if FAMILY is set to 0, SOURCE - * PREFIX-LENGTH must be 0 and ADDRESS should not be - * present as the address and prefix lengths don't make - * sense because the family is unknown. - */ - if (addrlen != 0U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for FAMILY=0", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_UNSPEC; - break; - case 1: - if (addrlen > 32U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for IPv4", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_INET; - break; - case 2: - if (addrlen > 128U) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid " - "address length (%u) for IPv6", - addrlen); - return (DNS_R_OPTERR); - } - caddr.family = AF_INET6; - break; - default: - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: invalid family"); - return (DNS_R_OPTERR); - } - - addrbytes = (addrlen + 7) / 8; - if (isc_buffer_remaininglength(buf) < addrbytes) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "EDNS client-subnet option: address too short"); - return (DNS_R_OPTERR); - } - - paddr = (uint8_t *) &caddr.type; - if (addrbytes != 0U) { - memmove(paddr, isc_buffer_current(buf), addrbytes); - isc_buffer_forward(buf, addrbytes); - optlen -= addrbytes; - - if ((addrlen % 8) != 0) { - uint8_t bits = ~0U << (8 - (addrlen % 8)); - bits &= paddr[addrbytes - 1]; - if (bits != paddr[addrbytes - 1]) - return (DNS_R_OPTERR); - } - } - - memmove(&client->ecs_addr, &caddr, sizeof(caddr)); - client->ecs_addrlen = addrlen; - client->ecs_scope = 0; - client->attributes |= NS_CLIENTATTR_HAVEECS; - - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); -} - -static isc_result_t -process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { - - if (optlen == 0 || (optlen % 2) != 0) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (DNS_R_OPTERR); - } - - /* Silently drop additional keytag options. */ - if (client->keytag != NULL) { - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); - } - - client->keytag = isc_mem_get(client->mctx, optlen); - if (client->keytag != NULL) { - client->keytag_len = (uint16_t)optlen; - memmove(client->keytag, isc_buffer_current(buf), optlen); - } - isc_buffer_forward(buf, (unsigned int)optlen); - return (ISC_R_SUCCESS); -} - -static isc_result_t -process_opt(ns_client_t *client, dns_rdataset_t *opt) { - dns_rdata_t rdata; - isc_buffer_t optbuf; - isc_result_t result; - uint16_t optcode; - uint16_t optlen; - - /* - * Set the client's UDP buffer size. - */ - client->udpsize = opt->rdclass; - - /* - * If the requested UDP buffer size is less than 512, - * ignore it and use 512. - */ - if (client->udpsize < 512) - client->udpsize = 512; - - /* - * Get the flags out of the OPT record. - */ - client->extflags = (uint16_t)(opt->ttl & 0xFFFF); - - /* - * Do we understand this version of EDNS? - * - * XXXRTH need library support for this! - */ - client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; - if (client->ednsversion > DNS_EDNS_VERSION) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_badednsver); - result = ns_client_addopt(client, client->message, - &client->opt); - if (result == ISC_R_SUCCESS) - result = DNS_R_BADVERS; - ns_client_error(client, result); - goto cleanup; - } - - /* Check for NSID request */ - result = dns_rdataset_first(opt); - if (result == ISC_R_SUCCESS) { - dns_rdata_init(&rdata); - dns_rdataset_current(opt, &rdata); - isc_buffer_init(&optbuf, rdata.data, rdata.length); - isc_buffer_add(&optbuf, rdata.length); - while (isc_buffer_remaininglength(&optbuf) >= 4) { - optcode = isc_buffer_getuint16(&optbuf); - optlen = isc_buffer_getuint16(&optbuf); - switch (optcode) { - case DNS_OPT_NSID: - if (!WANTNSID(client)) - isc_stats_increment( - ns_g_server->nsstats, - dns_nsstatscounter_nsidopt); - client->attributes |= NS_CLIENTATTR_WANTNSID; - isc_buffer_forward(&optbuf, optlen); - break; - case DNS_OPT_COOKIE: - process_cookie(client, &optbuf, optlen); - break; - case DNS_OPT_EXPIRE: - if (!WANTEXPIRE(client)) - isc_stats_increment( - ns_g_server->nsstats, - dns_nsstatscounter_expireopt); - client->attributes |= NS_CLIENTATTR_WANTEXPIRE; - isc_buffer_forward(&optbuf, optlen); - break; - case DNS_OPT_CLIENT_SUBNET: - result = process_ecs(client, &optbuf, optlen); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - goto cleanup; - } - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_ecsopt); - break; - case DNS_OPT_KEY_TAG: - result = process_keytag(client, &optbuf, - optlen); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - return (result); - } - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_keytagopt); - break; - default: - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_otheropt); - isc_buffer_forward(&optbuf, optlen); - break; - } - } - } - - isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_edns0in); - client->attributes |= NS_CLIENTATTR_WANTOPT; - - cleanup: - return (result); -} - -/* - * Handle an incoming request event from the socket (UDP case) - * or tcpmsg (TCP case). - */ -static void -client_request(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent; - isc_result_t result; - isc_result_t sigresult = ISC_R_SUCCESS; - isc_buffer_t *buffer; - isc_buffer_t tbuffer; - dns_view_t *view; - dns_rdataset_t *opt; - dns_name_t *signame; - bool ra; /* Recursion available. */ - isc_netaddr_t netaddr; - int match; - dns_messageid_t id; - unsigned int flags; - bool notimp; - size_t reqsize; -#ifdef HAVE_DNSTAP - dns_dtmsgtype_t dtmsgtype; -#endif - - REQUIRE(event != NULL); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - INSIST(client->recursionquota == NULL); - - INSIST(client->state == (TCP_CLIENT(client) ? - NS_CLIENTSTATE_READING : - NS_CLIENTSTATE_READY)); - - ncr_inc(ns_client_requests); - - if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { - INSIST(!TCP_CLIENT(client)); - sevent = (isc_socketevent_t *)event; - REQUIRE(sevent == client->recvevent); - isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); - isc_buffer_add(&tbuffer, sevent->n); - buffer = &tbuffer; - result = sevent->result; - if (result == ISC_R_SUCCESS) { - client->peeraddr = sevent->address; - client->peeraddr_valid = true; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(90), - "received DSCP %d", sevent->dscp); - if (client->dscp == -1) - client->dscp = sevent->dscp; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->attributes |= NS_CLIENTATTR_PKTINFO; - client->pktinfo = sevent->pktinfo; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) - client->attributes |= NS_CLIENTATTR_MULTICAST; - client->nrecvs--; - } else { - INSIST(TCP_CLIENT(client)); - INSIST(client->tcpconn != NULL); - REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); - REQUIRE(event->ev_sender == &client->tcpmsg); - buffer = &client->tcpmsg.buffer; - result = client->tcpmsg.result; - INSIST(client->nreads == 1); - /* - * client->peeraddr was set when the connection was accepted. - */ - client->nreads--; - } - - reqsize = isc_buffer_usedlength(buffer); - /* don't count the length header */ - if (TCP_CLIENT(client)) - reqsize -= 2; - - if (exit_check(client)) - goto cleanup; - client->state = client->newstate = NS_CLIENTSTATE_WORKING; - - isc_task_getcurrenttimex(task, &client->requesttime); - client->tnow = client->requesttime; - client->now = isc_time_seconds(&client->tnow); - - if (result != ISC_R_SUCCESS) { - if (TCP_CLIENT(client)) { - ns_client_next(client, result); - } else { - if (result != ISC_R_CANCELED) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "UDP client handler shutting " - "down due to fatal receive " - "error: %s", - isc_result_totext(result)); - isc_task_shutdown(client->task); - } - goto cleanup; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - -#if NS_CLIENT_DROPPORT - if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == - DROPPORT_REQUEST) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped request: suspicious port"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } -#endif - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s request", - TCP_CLIENT(client) ? "TCP" : "UDP"); - - /* - * Check the blackhole ACL for UDP only, since TCP is done in - * client_newconn. - */ - if (!TCP_CLIENT(client)) { - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed UDP datagram"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Silently drop multicast requests for the present. - * XXXMPA revisit this as mDNS spec was published. - */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "dropping multicast request"); - ns_client_next(client, DNS_R_REFUSED); - goto cleanup; - } - - result = dns_message_peekheader(buffer, &id, &flags); - if (result != ISC_R_SUCCESS) { - /* - * There isn't enough header to determine whether - * this was a request or a response. Drop it. - */ - ns_client_next(client, result); - goto cleanup; - } - - /* - * The client object handles requests, not responses. - * If this is a UDP response, forward it to the dispatcher. - * If it's a TCP response, discard it here. - */ - if ((flags & DNS_MESSAGEFLAG_QR) != 0) { - if (TCP_CLIENT(client)) { - CTRACE("unexpected response"); - ns_client_next(client, DNS_R_FORMERR); - goto cleanup; - } else { - dns_dispatch_importrecv(client->dispatch, event); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Update some statistics counters. Don't count responses. - */ - if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requestv4); - } else { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requestv6); - } - if (TCP_CLIENT(client)) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_requesttcp); - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->tcpinstats4, - ISC_MIN((int)reqsize / 16, 18)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->tcpinstats6, - ISC_MIN((int)reqsize / 16, 18)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else { - switch (isc_sockaddr_pf(&client->peeraddr)) { - case AF_INET: - isc_stats_increment(ns_g_server->udpinstats4, - ISC_MIN((int)reqsize / 16, 18)); - break; - case AF_INET6: - isc_stats_increment(ns_g_server->udpinstats6, - ISC_MIN((int)reqsize / 16, 18)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - - /* - * It's a request. Parse it. - */ - result = dns_message_parse(client->message, buffer, 0); - if (result != ISC_R_SUCCESS) { - /* - * Parsing the request failed. Send a response - * (typically FORMERR or SERVFAIL). - */ - if (result == DNS_R_OPTERR) { - (void)ns_client_addopt(client, client->message, - &client->opt); - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message parsing failed: %s", - isc_result_totext(result)); - if (result == ISC_R_NOSPACE || result == DNS_R_BADTSIG) { - result = DNS_R_FORMERR; - } - ns_client_error(client, result); - goto cleanup; - } - - /* - * Pipeline TCP query processing. - */ - if (TCP_CLIENT(client)) { - if (client->message->opcode != dns_opcode_query) { - client->tcpconn->pipelined = false; - } - - /* - * Limit the maximum number of simultaneous pipelined - * queries on TCP connection to TCP_CLIENTS_PER_CONN. - */ - if ((isc_refcount_current(&client->tcpconn->clients) - > TCP_CLIENTS_PER_CONN)) - { - client->tcpconn->pipelined = false; - } - - if (client->tcpconn->pipelined) { - /* - * We're pipelining. Replace the client; the - * replacement can read the TCP socket looking - * for new messages and this one can process the - * current message asynchronously. - * - * There will now be at least three clients using this - * TCP socket - one accepting new connections, - * one reading an existing connection to get new - * messages, and one answering the message already - * received. - */ - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - client->tcpconn->pipelined = false; - } - } - } - - dns_opcodestats_increment(ns_g_server->opcodestats, - client->message->opcode); - switch (client->message->opcode) { - case dns_opcode_query: - case dns_opcode_update: - case dns_opcode_notify: - notimp = false; - break; - case dns_opcode_iquery: - default: - notimp = true; - break; - } - - client->message->rcode = dns_rcode_noerror; - - /* RFC1123 section 6.1.3.2 */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) - client->message->flags &= ~DNS_MESSAGEFLAG_RD; - - /* - * Deal with EDNS. - */ - if (ns_g_noedns) - opt = NULL; - else - opt = dns_message_getopt(client->message); - - client->ecs_addrlen = 0; - client->ecs_scope = 0; - - if (opt != NULL) { - /* - * Are returning FORMERR to all EDNS queries? - * Simulate a STD13 compliant server. - */ - if (ns_g_ednsformerr) { - ns_client_error(client, DNS_R_FORMERR); - return; - } - - /* - * Are returning NOTIMP to all EDNS queries? - */ - if (ns_g_ednsnotimp) { - ns_client_error(client, DNS_R_NOTIMP); - return; - } - - /* - * Are returning REFUSED to all EDNS queries? - */ - if (ns_g_ednsrefused) { - ns_client_error(client, DNS_R_REFUSED); - return; - } - - /* - * Are we dropping all EDNS queries? - */ - if (ns_g_dropedns) { - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - - result = process_opt(client, opt); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (client->message->rdclass == 0) { - if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 && - client->message->opcode == dns_opcode_query && - client->message->counts[DNS_SECTION_QUESTION] == 0U) - { - result = dns_message_reply(client->message, true); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - return; - } - if (notimp) - client->message->rcode = dns_rcode_notimp; - ns_client_send(client); - return; - } - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message class could not be determined"); - ns_client_dumpmessage(client, - "message class could not be determined"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); - goto cleanup; - } - - /* - * Determine the destination address. If the receiving interface is - * bound to a specific address, we simply use it regardless of the - * address family. All IPv4 queries should fall into this case. - * Otherwise, if this is a TCP query, get the address from the - * receiving socket (this needs a system call and can be heavy). - * For IPv6 UDP queries, we get this from the pktinfo structure (if - * supported). - * If all the attempts fail (this can happen due to memory shortage, - * etc), we regard this as an error for safety. - */ - if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) - isc_netaddr_fromsockaddr(&client->destaddr, - &client->interface->addr); - else { - isc_sockaddr_t sockaddr; - result = ISC_R_FAILURE; - - if (TCP_CLIENT(client)) - result = isc_socket_getsockname(client->tcpsocket, - &sockaddr); - if (result == ISC_R_SUCCESS) - isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr); - if (result != ISC_R_SUCCESS && - client->interface->addr.type.sa.sa_family == AF_INET6 && - (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { - /* - * XXXJT technically, we should convert the receiving - * interface ID to a proper scope zone ID. However, - * due to the fact there is no standard API for this, - * we only handle link-local addresses and use the - * interface index as link ID. Despite the assumption, - * it should cover most typical cases. - */ - isc_netaddr_fromin6(&client->destaddr, - &client->pktinfo.ipi6_addr); - if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) - isc_netaddr_setzone(&client->destaddr, - client->pktinfo.ipi6_ifindex); - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "failed to get request's " - "destination: %s", - isc_result_totext(result)); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - isc_sockaddr_fromnetaddr(&client->destsockaddr, &client->destaddr, 0); - - /* - * Find a view that matches the client's source address. - */ - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (client->message->rdclass == view->rdclass || - client->message->rdclass == dns_rdataclass_any) - { - const dns_name_t *tsig = NULL; - isc_netaddr_t *addr = NULL; - uint8_t *scope = NULL; - - sigresult = dns_message_rechecksig(client->message, - view); - if (sigresult == ISC_R_SUCCESS) { - dns_tsigkey_t *tsigkey; - - tsigkey = client->message->tsigkey; - tsig = dns_tsigkey_identity(tsigkey); - } - - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - addr = &client->ecs_addr; - scope = &client->ecs_scope; - } - - if (allowed(&netaddr, tsig, addr, client->ecs_addrlen, - scope, view->matchclients) && - allowed(&client->destaddr, tsig, NULL, - 0, NULL, view->matchdestinations) && - !(view->matchrecursiveonly && - (client->message->flags & DNS_MESSAGEFLAG_RD) == 0)) - { - dns_view_attach(view, &client->view); - break; - } - } - } - - if (view == NULL) { - char classname[DNS_RDATACLASS_FORMATSIZE]; - - /* - * Do a dummy TSIG verification attempt so that the - * response will have a TSIG if the query did, as - * required by RFC2845. - */ - isc_buffer_t b; - isc_region_t *r; - - dns_message_resetsig(client->message); - - r = dns_message_getrawmessage(client->message); - isc_buffer_init(&b, r->base, r->length); - isc_buffer_add(&b, r->length); - (void)dns_tsig_verify(&b, client->message, NULL, NULL); - - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "no matching view in class '%s'", classname); - ns_client_dumpmessage(client, "no matching view in class"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); - goto cleanup; - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), - "using view '%s'", view->name); - - /* - * Check for a signature. We log bad signatures regardless of - * whether they ultimately cause the request to be rejected or - * not. We do not log the lack of a signature unless we are - * debugging. - */ - client->signer = NULL; - dns_name_init(&client->signername, NULL); - result = dns_message_signer(client->message, &client->signername); - if (result != ISC_R_NOTFOUND) { - signame = NULL; - if (dns_message_gettsig(client->message, &signame) != NULL) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_tsigin); - } else { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_sig0in); - } - - } - if (result == ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(&client->signername, namebuf, sizeof(namebuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request has valid signature: %s", namebuf); - client->signer = &client->signername; - } else if (result == ISC_R_NOTFOUND) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is not signed"); - } else if (result == DNS_R_NOIDENTITY) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is signed by a nonauthoritative key"); - } else { - char tsigrcode[64]; - isc_buffer_t b; - dns_rcode_t status; - isc_result_t tresult; - - /* There is a signature, but it is bad. */ - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_invalidsig); - signame = NULL; - if (dns_message_gettsig(client->message, &signame) != NULL) { - char namebuf[DNS_NAME_FORMATSIZE]; - char cnamebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(signame, namebuf, sizeof(namebuf)); - status = client->message->tsigstatus; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - if (client->message->tsigkey->generated) { - dns_name_format(client->message->tsigkey->creator, - cnamebuf, sizeof(cnamebuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s (%s): %s (%s)", namebuf, - cnamebuf, - isc_result_totext(result), - tsigrcode); - } else { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s: %s (%s)", namebuf, - isc_result_totext(result), - tsigrcode); - } - } else { - status = client->message->sig0status; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: %s (%s)", - isc_result_totext(result), tsigrcode); - } - /* - * Accept update messages signed by unknown keys so that - * update forwarding works transparently through slaves - * that don't have all the same keys as the master. - */ - if (!(client->message->tsigstatus == dns_tsigerror_badkey && - client->message->opcode == dns_opcode_update)) { - ns_client_error(client, sigresult); - goto cleanup; - } - } - - /* - * Decide whether recursive service is available to this client. - * We do this here rather than in the query code so that we can - * set the RA bit correctly on all kinds of responses, not just - * responses to ordinary queries. Note if you can't query the - * cache there is no point in setting RA. - */ - ra = false; - if (client->view->resolver != NULL && - client->view->recursion == true && - ns_client_checkaclsilent(client, NULL, - client->view->recursionacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, NULL, - client->view->cacheacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, &client->destaddr, - client->view->recursiononacl, - true) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, &client->destaddr, - client->view->cacheonacl, - true) == ISC_R_SUCCESS) - ra = true; - - if (ra == true) { - client->attributes |= NS_CLIENTATTR_RA; - } - - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, - ISC_LOG_DEBUG(3), ra ? "recursion available" : - "recursion not available"); - - /* - * Adjust maximum UDP response size for this client. - */ - if (client->udpsize > 512) { - dns_peer_t *peer = NULL; - uint16_t udpsize = view->maxudp; - (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer); - if (peer != NULL) - dns_peer_getmaxudp(peer, &udpsize); - if (client->udpsize > udpsize) - client->udpsize = udpsize; - } - - /* - * Dispatch the request. - */ - switch (client->message->opcode) { - case dns_opcode_query: - CTRACE("query"); -#ifdef HAVE_DNSTAP - if (ra && (client->message->flags & DNS_MESSAGEFLAG_RD) != 0) { - dtmsgtype = DNS_DTTYPE_CQ; - } else { - dtmsgtype = DNS_DTTYPE_AQ; - } - - dns_dt_send(view, dtmsgtype, &client->peeraddr, - &client->destsockaddr, TCP_CLIENT(client), NULL, - &client->requesttime, NULL, buffer); -#endif /* HAVE_DNSTAP */ - - ns_query_start(client); - break; - case dns_opcode_update: - CTRACE("update"); - ns_client_settimeout(client, 60); - ns_update_start(client, sigresult); - break; - case dns_opcode_notify: - CTRACE("notify"); - ns_client_settimeout(client, 60); - ns_notify_start(client); - break; - case dns_opcode_iquery: - CTRACE("iquery"); - ns_client_error(client, DNS_R_NOTIMP); - break; - default: - CTRACE("unknown opcode"); - ns_client_error(client, DNS_R_NOTIMP); - } - - cleanup: - return; -} - -static void -client_timeout(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->timer != NULL); - - UNUSED(task); - - CTRACE("timeout"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - if (client->newstate > NS_CLIENTSTATE_READY) - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); -} - -static isc_result_t -get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { - isc_mem_t *clientmctx; - isc_result_t result; -#if NMCTXS > 0 - unsigned int nextmctx; -#endif - - MTRACE("clientmctx"); - - /* - * Caller must be holding the manager lock. - */ - if (ns_g_clienttest) { - result = isc_mem_create(0, 0, mctxp); - if (result == ISC_R_SUCCESS) - isc_mem_setname(*mctxp, "client", NULL); - return (result); - } -#if NMCTXS > 0 - nextmctx = manager->nextmctx++; - if (manager->nextmctx == NMCTXS) - manager->nextmctx = 0; - - INSIST(nextmctx < NMCTXS); - - clientmctx = manager->mctxpool[nextmctx]; - if (clientmctx == NULL) { - result = isc_mem_create(0, 0, &clientmctx); - if (result != ISC_R_SUCCESS) - return (result); - isc_mem_setname(clientmctx, "client", NULL); - - manager->mctxpool[nextmctx] = clientmctx; - } -#else - clientmctx = manager->mctx; -#endif - - isc_mem_attach(clientmctx, mctxp); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - ns_client_t *client; - isc_result_t result; - isc_mem_t *mctx = NULL; - - /* - * Caller must be holding the manager lock. - * - * Note: creating a client does not add the client to the - * manager's client list or set the client's manager pointer. - * The caller is responsible for that. - */ - - REQUIRE(clientp != NULL && *clientp == NULL); - - result = get_clientmctx(manager, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - - client = isc_mem_get(mctx, sizeof(*client)); - if (client == NULL) { - isc_mem_detach(&mctx); - return (ISC_R_NOMEMORY); - } - client->mctx = mctx; - - client->task = NULL; - result = isc_task_create(manager->taskmgr, 0, &client->task); - if (result != ISC_R_SUCCESS) - goto cleanup_client; - isc_task_setname(client->task, "client", client); - - client->timer = NULL; - result = isc_timer_create(manager->timermgr, isc_timertype_inactive, - NULL, NULL, client->task, client_timeout, - client, &client->timer); - if (result != ISC_R_SUCCESS) - goto cleanup_task; - client->timerset = false; - - client->delaytimer = NULL; - - client->message = NULL; - result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, - &client->message); - if (result != ISC_R_SUCCESS) - goto cleanup_timer; - - /* XXXRTH Hardwired constants */ - - client->sendevent = isc_socket_socketevent(client->mctx, client, - ISC_SOCKEVENT_SENDDONE, - client_senddone, client); - if (client->sendevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_message; - } - - client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE); - if (client->recvbuf == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_sendevent; - } - - client->recvevent = isc_socket_socketevent(client->mctx, client, - ISC_SOCKEVENT_RECVDONE, - client_request, client); - if (client->recvevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_recvbuf; - } - - client->magic = NS_CLIENT_MAGIC; - client->manager = NULL; - client->state = NS_CLIENTSTATE_INACTIVE; - client->newstate = NS_CLIENTSTATE_MAX; - client->naccepts = 0; - client->nreads = 0; - client->nsends = 0; - client->nrecvs = 0; - client->nupdates = 0; - client->nctls = 0; - client->references = 0; - client->attributes = 0; - client->view = NULL; - client->dispatch = NULL; - client->udpsocket = NULL; - client->tcplistener = NULL; - client->tcpsocket = NULL; - client->tcpmsg_valid = false; - client->tcpbuf = NULL; - client->opt = NULL; - client->udpsize = 512; - client->dscp = -1; - client->extflags = 0; - client->ednsversion = -1; - client->next = NULL; - client->shutdown = NULL; - client->shutdown_arg = NULL; - client->signer = NULL; - dns_name_init(&client->signername, NULL); - client->mortal = false; - client->tcpconn = NULL; - client->recursionquota = NULL; - client->interface = NULL; - client->peeraddr_valid = false; - client->ecs_addrlen = 0; - client->ecs_scope = 0; -#ifdef ALLOW_FILTER_AAAA - client->filter_aaaa = dns_aaaa_ok; -#endif - client->needshutdown = ns_g_clienttest; - client->tcpactive = false; - - ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, - NS_EVENT_CLIENTCONTROL, client_start, client, client, - NULL, NULL); - /* - * Initialize FORMERR cache to sentinel value that will not match - * any actual FORMERR response. - */ - isc_sockaddr_any(&client->formerrcache.addr); - client->formerrcache.time = 0; - client->formerrcache.id = 0; - ISC_LINK_INIT(client, link); - ISC_LINK_INIT(client, rlink); - ISC_QLINK_INIT(client, ilink); - client->keytag = NULL; - client->keytag_len = 0; - - /* - * We call the init routines for the various kinds of client here, - * after we have created an otherwise valid client, because some - * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). - */ - result = ns_query_init(client); - if (result != ISC_R_SUCCESS) - goto cleanup_recvevent; - - result = isc_task_onshutdown(client->task, client_shutdown, client); - if (result != ISC_R_SUCCESS) - goto cleanup_query; - - CTRACE("create"); - - *clientp = client; - - return (ISC_R_SUCCESS); - - cleanup_query: - ns_query_free(client); - - cleanup_recvevent: - isc_event_free((isc_event_t **)&client->recvevent); - - cleanup_recvbuf: - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - - cleanup_sendevent: - isc_event_free((isc_event_t **)&client->sendevent); - - client->magic = 0; - - cleanup_message: - dns_message_detach(&client->message); - - cleanup_timer: - isc_timer_detach(&client->timer); - - cleanup_task: - isc_task_detach(&client->task); - - cleanup_client: - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - - return (result); -} - -static void -client_read(ns_client_t *client) { - isc_result_t result; - - CTRACE("read"); - - result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, - client_request, client); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * Set a timeout to limit the amount of time we will wait - * for a request on this TCP connection. - */ - ns_client_settimeout(client, 30); - - client->state = client->newstate = NS_CLIENTSTATE_READING; - INSIST(client->nreads == 0); - INSIST(client->recursionquota == NULL); - client->nreads++; - - return; - fail: - ns_client_next(client, result); -} - -static void -client_newconn(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_client_t *client = event->ev_arg; - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->task == task); - - UNUSED(task); - - INSIST(client->state == NS_CLIENTSTATE_READY); - - /* - * The accept() was successful and we're now establishing a new - * connection. We need to make note of it in the client and - * interface objects so client objects can do the right thing - * when going inactive in exit_check() (see comments in - * client_accept() for details). - */ - INSIST(client->naccepts == 1); - client->naccepts--; - - isc_refcount_decrement(&client->interface->ntcpaccepting, NULL); - - /* - * We must take ownership of the new socket before the exit - * check to make sure it gets destroyed if we decide to exit. - */ - if (nevent->result == ISC_R_SUCCESS) { - client->tcpsocket = nevent->newsocket; - isc_socket_setname(client->tcpsocket, "client-tcp", NULL); - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - (void)isc_socket_getpeername(client->tcpsocket, - &client->peeraddr); - client->peeraddr_valid = true; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "new TCP connection"); - } else { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - * - * Going idle is probably the right thing if the - * I/O was canceled. - */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "accept failed: %s", - isc_result_totext(nevent->result)); - tcpconn_detach(client); - } - - if (exit_check(client)) - goto freeevent; - - if (nevent->result == ISC_R_SUCCESS) { - int match; - isc_netaddr_t netaddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed connection attempt"); - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); - goto freeevent; - } - - INSIST(client->tcpmsg_valid == false); - dns_tcpmsg_init(client->mctx, client->tcpsocket, - &client->tcpmsg); - client->tcpmsg_valid = true; - - /* - * Let a new client take our place immediately, before - * we wait for a request packet. If we don't, - * telnetting to port 53 (once per CPU) will - * deny service to legitimate TCP clients. - */ - result = ns_client_replace(client); - if (result == ISC_R_SUCCESS && - (ns_g_server->keepresporder == NULL || - !allowed(&netaddr, NULL, NULL, 0, NULL, - ns_g_server->keepresporder))) - { - client->tcpconn->pipelined = true; - } - - client_read(client); - } - - freeevent: - isc_event_free(&event); -} - -static void -client_accept(ns_client_t *client) { - isc_result_t result; - - CTRACE("accept"); - /* - * Set up a new TCP connection. This means try to attach to the - * TCP client quota (tcp-clients), but fail if we're over quota. - */ - result = tcpconn_init(client, false); - if (result != ISC_R_SUCCESS) { - bool exit; - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "TCP client quota reached: %s", - isc_result_totext(result)); - - /* - * We have exceeded the system-wide TCP client quota. But, - * we can't just block this accept in all cases, because if - * we did, a heavy TCP load on other interfaces might cause - * this interface to be starved, with no clients able to - * accept new connections. - * - * So, we check here to see if any other clients are - * already servicing TCP queries on this interface (whether - * accepting, reading, or processing). If we find that at - * least one client other than this one is active, then - * it's okay *not* to call accept - we can let this - * client go inactive and another will take over when it's - * done. - * - * If there aren't enough active clients on the interface, - * then we can be a little bit flexible about the quota. - * We'll allow *one* extra client through to ensure we're - * listening on every interface; we do this by setting the - * 'force' option to tcpconn_init(). - * - * (Note: In practice this means that the real TCP client - * quota is tcp-clients plus the number of listening - * interfaces plus 1.) - */ - exit = (isc_refcount_current(&client->interface->ntcpactive) > - (client->tcpactive ? 1U : 0U)); - if (exit) { - client->newstate = NS_CLIENTSTATE_INACTIVE; - (void)exit_check(client); - return; - } - - result = tcpconn_init(client, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - /* TCP high-water stats update. */ - unsigned int curr_tcpquota = isc_quota_getused(&ns_g_server->tcpquota); - isc_stats_update_if_greater(ns_g_server->nsstats, - dns_nsstatscounter_tcphighwater, - curr_tcpquota); - - /* - * If this client was set up using get_client() or get_worker(), - * then TCP is already marked active. However, if it was restarted - * from exit_check(), it might not be, so we take care of it now. - */ - mark_tcp_active(client, true); - - result = isc_socket_accept(client->tcplistener, client->task, - client_newconn, client); - if (result != ISC_R_SUCCESS) { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - */ - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - - tcpconn_detach(client); - mark_tcp_active(client, false); - return; - } - - /* - * The client's 'naccepts' counter indicates that this client has - * called accept() and is waiting for a new connection. It should - * never exceed 1. - */ - INSIST(client->naccepts == 0); - client->naccepts++; - - /* - * The interface's 'ntcpaccepting' counter is incremented when - * any client calls accept(), and decremented in client_newconn() - * once the connection is established. - * - * When the client object is shutting down after handling a TCP - * request (see exit_check()), if this value is at least one, that - * means another client has called accept() and is waiting to - * establish the next connection. That means the client may be - * be free to become inactive; otherwise it may need to start - * listening for connections itself to prevent the interface - * going dead. - */ - isc_refcount_increment0(&client->interface->ntcpaccepting, NULL); -} - -static void -client_udprecv(ns_client_t *client) { - isc_result_t result; - isc_region_t r; - - CTRACE("udprecv"); - - r.base = client->recvbuf; - r.length = RECV_BUFFER_SIZE; - result = isc_socket_recv2(client->udpsocket, &r, 1, - client->task, client->recvevent, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_recv2() failed: %s", - isc_result_totext(result)); - /* - * This cannot happen in the current implementation, since - * isc_socket_recv2() cannot fail if flags == 0. - * - * If this does fail, we just go idle. - */ - return; - } - INSIST(client->nrecvs == 0); - client->nrecvs++; -} - -void -ns_client_attach(ns_client_t *source, ns_client_t **targetp) { - REQUIRE(NS_CLIENT_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - source->references++; - ns_client_log(source, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_attach: ref = %d", source->references); - *targetp = source; -} - -void -ns_client_detach(ns_client_t **clientp) { - ns_client_t *client = *clientp; - - client->references--; - INSIST(client->references >= 0); - *clientp = NULL; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_detach: ref = %d", client->references); - (void)exit_check(client); -} - -bool -ns_client_shuttingdown(ns_client_t *client) { - return (client->newstate == NS_CLIENTSTATE_FREED); -} - -isc_result_t -ns_client_replace(ns_client_t *client) { - isc_result_t result; - bool tcp; - - CTRACE("replace"); - - REQUIRE(client != NULL); - REQUIRE(client->manager != NULL); - - tcp = TCP_CLIENT(client); - if (tcp && client->tcpconn != NULL && client->tcpconn->pipelined) { - result = get_worker(client->manager, client->interface, - client->tcpsocket, client); - } else { - result = get_client(client->manager, client->interface, - client->dispatch, tcp); - - } - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * The responsibility for listening for new requests is hereby - * transferred to the new client. Therefore, the old client - * should refrain from listening for any more requests. - */ - client->mortal = true; - - return (ISC_R_SUCCESS); -} - -/*** - *** Client Manager - ***/ - -static void -clientmgr_destroy(ns_clientmgr_t *manager) { -#if NMCTXS > 0 - int i; -#endif - - REQUIRE(ISC_LIST_EMPTY(manager->clients)); - - MTRACE("clientmgr_destroy"); - -#if NMCTXS > 0 - for (i = 0; i < NMCTXS; i++) { - if (manager->mctxpool[i] != NULL) - isc_mem_detach(&manager->mctxpool[i]); - } -#endif - - ISC_QUEUE_DESTROY(manager->inactive); - DESTROYLOCK(&manager->lock); - DESTROYLOCK(&manager->listlock); - DESTROYLOCK(&manager->reclock); - manager->magic = 0; - isc_mem_put(manager->mctx, manager, sizeof(*manager)); -} - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) -{ - ns_clientmgr_t *manager; - isc_result_t result; -#if NMCTXS > 0 - int i; -#endif - - manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&manager->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_manager; - - result = isc_mutex_init(&manager->listlock); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - result = isc_mutex_init(&manager->reclock); - if (result != ISC_R_SUCCESS) - goto cleanup_listlock; - - manager->mctx = mctx; - manager->taskmgr = taskmgr; - manager->timermgr = timermgr; - manager->exiting = false; - ISC_LIST_INIT(manager->clients); - ISC_LIST_INIT(manager->recursing); - ISC_QUEUE_INIT(manager->inactive, ilink); -#if NMCTXS > 0 - manager->nextmctx = 0; - for (i = 0; i < NMCTXS; i++) - manager->mctxpool[i] = NULL; /* will be created on-demand */ -#endif - manager->magic = MANAGER_MAGIC; - - MTRACE("create"); - - *managerp = manager; - - return (ISC_R_SUCCESS); - - cleanup_listlock: - (void) isc_mutex_destroy(&manager->listlock); - - cleanup_lock: - (void) isc_mutex_destroy(&manager->lock); - - cleanup_manager: - isc_mem_put(manager->mctx, manager, sizeof(*manager)); - - return (result); -} - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp) { - isc_result_t result; - ns_clientmgr_t *manager; - ns_client_t *client; - bool need_destroy = false, unlock = false; - - REQUIRE(managerp != NULL); - manager = *managerp; - REQUIRE(VALID_MANAGER(manager)); - - MTRACE("destroy"); - - /* - * Check for success because we may already be task-exclusive - * at this point. Only if we succeed at obtaining an exclusive - * lock now will we need to relinquish it later. - */ - result = isc_task_beginexclusive(ns_g_server->task); - if (result == ISC_R_SUCCESS) - unlock = true; - - manager->exiting = true; - - for (client = ISC_LIST_HEAD(manager->clients); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - if (ISC_LIST_EMPTY(manager->clients)) - need_destroy = true; - - if (unlock) - isc_task_endexclusive(ns_g_server->task); - - if (need_destroy) - clientmgr_destroy(manager); - - *managerp = NULL; -} - -/* - * ISC_QUEUE_POP is deliberately not tsan safe to avoid aquiring - * the taillock every time ISC_QUEUE_POP is called. - * Isolate ISC_QUEUE_POP from tsan analysis. - */ -ISC_NO_SANITIZE_THREAD static ns_client_t * -queue_pop(ns_clientmgr_t *manager) -{ - ns_client_t *client = NULL; - - if (!ns_g_clienttest) { - ISC_QUEUE_POP(manager->inactive, ilink, client); - } - return (client); -} - -static isc_result_t -get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, - dns_dispatch_t *disp, bool tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - isc_event_t *ev; - ns_client_t *client; - MTRACE("get client"); - - REQUIRE(manager != NULL); - - if (manager->exiting) - return (ISC_R_SHUTTINGDOWN); - - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = NULL; - if (!ns_g_clienttest) { - client = queue_pop(manager); - } - - if (client != NULL) - MTRACE("recycle"); - else { - MTRACE("create new"); - - LOCK(&manager->lock); - result = client_create(manager, &client); - UNLOCK(&manager->lock); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&manager->listlock); - ISC_LIST_APPEND(manager->clients, client, link); - UNLOCK(&manager->listlock); - } - - client->manager = manager; - ns_interface_attach(ifp, &client->interface); - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - client->dscp = ifp->dscp; - - if (tcp) { - mark_tcp_active(client, true); - - client->attributes |= NS_CLIENTATTR_TCP; - isc_socket_attach(ifp->tcpsocket, - &client->tcplistener); - - } else { - isc_socket_t *sock; - - dns_dispatch_attach(disp, &client->dispatch); - sock = dns_dispatch_getsocket(client->dispatch); - isc_socket_attach(sock, &client->udpsocket); - } - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - - return (result); -} - -static isc_result_t -get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock, - ns_client_t *oldclient) -{ - isc_result_t result = ISC_R_SUCCESS; - isc_event_t *ev; - ns_client_t *client; - MTRACE("get worker"); - - REQUIRE(manager != NULL); - REQUIRE(oldclient != NULL); - - if (manager->exiting) - return (ISC_R_SHUTTINGDOWN); - - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = NULL; - if (!ns_g_clienttest) { - client = queue_pop(manager); - } - - if (client != NULL) - MTRACE("recycle"); - else { - MTRACE("create new"); - - LOCK(&manager->lock); - result = client_create(manager, &client); - UNLOCK(&manager->lock); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&manager->listlock); - ISC_LIST_APPEND(manager->clients, client, link); - UNLOCK(&manager->listlock); - } - - client->manager = manager; - ns_interface_attach(ifp, &client->interface); - client->newstate = client->state = NS_CLIENTSTATE_WORKING; - INSIST(client->recursionquota == NULL); - - client->dscp = ifp->dscp; - - client->attributes |= NS_CLIENTATTR_TCP; - client->mortal = true; - - tcpconn_attach(oldclient, client); - mark_tcp_active(client, true); - - isc_socket_attach(ifp->tcpsocket, &client->tcplistener); - isc_socket_attach(sock, &client->tcpsocket); - isc_socket_setname(client->tcpsocket, "worker-tcp", NULL); - (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr); - client->peeraddr_valid = true; - - INSIST(client->tcpmsg_valid == false); - dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg); - client->tcpmsg_valid = true; - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - - return (result); -} - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, bool tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - unsigned int disp; - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(n > 0); - - MTRACE("createclients"); - - for (disp = 0; disp < n; disp++) { - result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); - if (result != ISC_R_SUCCESS) - break; - } - - return (result); -} - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client) { - return (&client->peeraddr); -} - -isc_sockaddr_t * -ns_client_getdestaddr(ns_client_t *client) { - return (&client->destsockaddr); -} - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, - dns_acl_t *acl, bool default_allow) -{ - isc_result_t result; - isc_netaddr_t tmpnetaddr; - isc_netaddr_t *ecs_addr = NULL; - uint8_t ecs_addrlen = 0; - int match; - - if (acl == NULL) { - if (default_allow) - goto allow; - else - goto deny; - } - - if (netaddr == NULL) { - isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr); - netaddr = &tmpnetaddr; - } - - if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) { - ecs_addr = &client->ecs_addr; - ecs_addrlen = client->ecs_addrlen; - } - - result = dns_acl_match2(netaddr, client->signer, - ecs_addr, ecs_addrlen, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS) - goto deny; /* Internal error, already logged. */ - - if (match > 0) - goto allow; - goto deny; /* Negative match or no match. */ - - allow: - return (ISC_R_SUCCESS); - - deny: - return (DNS_R_REFUSED); -} - -isc_result_t -ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr, - const char *opname, dns_acl_t *acl, - bool default_allow, int log_level) -{ - isc_result_t result; - isc_netaddr_t netaddr; - - if (sockaddr != NULL) - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL, - acl, default_allow); - - if (result == ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s approved", opname); - else - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - log_level, "%s denied", opname); - return (result); -} - -static void -ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { - if (client->peeraddr_valid) - isc_sockaddr_format(&client->peeraddr, peerbuf, - (unsigned int)len); - else - snprintf(peerbuf, len, "@%p", client); -} - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) -{ - char msgbuf[4096]; - char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *viewname = ""; - const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = ""; - const char *signer = "", *qname = ""; - dns_name_t *q = NULL; - - REQUIRE(client != NULL); - - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - - if (client->signer != NULL) { - dns_name_format(client->signer, signerbuf, sizeof(signerbuf)); - sep1 = "/key "; - signer = signerbuf; - } - - q = client->query.origqname != NULL - ? client->query.origqname : client->query.qname; - if (q != NULL) { - dns_name_format(q, qnamebuf, sizeof(qnamebuf)); - sep2 = " ("; - sep3 = ")"; - qname = qnamebuf; - } - - if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - sep4 = ": view "; - viewname = client->view->name; - } - - if (client->peeraddr_valid) { - isc_sockaddr_format(&client->peeraddr, - peerbuf, sizeof(peerbuf)); - } else { - snprintf(peerbuf, sizeof(peerbuf), "(no-peer)"); - } - - isc_log_write(ns_g_lctx, category, module, level, - "client @%p %s%s%s%s%s%s%s%s: %s", - client, peerbuf, sep1, signer, sep2, qname, sep3, - sep4, viewname, msgbuf); -} - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, ...) -{ - va_list ap; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - va_start(ap, fmt); - ns_client_logv(client, category, module, level, fmt, ap); - va_end(ap); -} - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, - classbuf); -} - -static void -ns_client_dumpmessage(ns_client_t *client, const char *reason) { - isc_buffer_t buffer; - char *buf = NULL; - int len = 1024; - isc_result_t result; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1))) - return; - - /* - * Note that these are multiline debug messages. We want a newline - * to appear in the log after each message. - */ - - do { - buf = isc_mem_get(client->mctx, len); - if (buf == NULL) - break; - isc_buffer_init(&buffer, buf, len); - result = dns_message_totext(client->message, - &dns_master_style_debug, - 0, &buffer); - if (result == ISC_R_NOSPACE) { - isc_mem_put(client->mctx, buf, len); - len += 1024; - } else if (result == ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "%s\n%.*s", reason, - (int)isc_buffer_usedlength(&buffer), - buf); - } while (result == ISC_R_NOSPACE); - - if (buf != NULL) - isc_mem_put(client->mctx, buf, len); -} - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { - ns_client_t *client; - char namebuf[DNS_NAME_FORMATSIZE]; - char original[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - const char *name; - const char *sep; - const char *origfor; - dns_rdataset_t *rdataset; - - REQUIRE(VALID_MANAGER(manager)); - - LOCK(&manager->reclock); - client = ISC_LIST_HEAD(manager->recursing); - while (client != NULL) { - INSIST(client->state == NS_CLIENTSTATE_RECURSING); - - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && - strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } else { - name = ""; - sep = ""; - } - - LOCK(&client->query.fetchlock); - INSIST(client->query.qname != NULL); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - if (client->query.qname != client->query.origqname && - client->query.origqname != NULL) { - origfor = " for "; - dns_name_format(client->query.origqname, original, - sizeof(original)); - } else { - origfor = ""; - original[0] = '\0'; - } - rdataset = ISC_LIST_HEAD(client->query.qname->list); - if (rdataset == NULL && client->query.origqname != NULL) - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - if (rdataset != NULL) { - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - } else { - strlcpy(typebuf, "-", sizeof(typebuf)); - strlcpy(classbuf, "-", sizeof(classbuf)); - } - UNLOCK(&client->query.fetchlock); - fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s " - "requesttime %u\n", peerbuf, sep, name, - client->message->id, namebuf, typebuf, classbuf, - origfor, original, - isc_time_seconds(&client->requesttime)); - client = ISC_LIST_NEXT(client, rlink); - } - UNLOCK(&manager->reclock); -} - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { - LOCK(&client->query.fetchlock); - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = name; - client->query.attributes &= ~NS_QUERYATTR_REDIRECT; - UNLOCK(&client->query.fetchlock); -} - -isc_result_t -ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) { - ns_client_t *client = (ns_client_t *) ci->data; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(addrp != NULL); - - *addrp = &client->peeraddr; - return (ISC_R_SUCCESS); -} diff --git a/bin/named-sdb/config.c b/bin/named-sdb/config.c deleted file mode 100644 index d2cd3bc..0000000 --- a/bin/named-sdb/config.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -/*% default configuration */ -static char defaultconf[] = "\ -options {\n\ - answer-cookie true;\n\ - automatic-interface-scan yes;\n\ - bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\ -# blackhole {none;};\n" -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) -" cookie-algorithm aes;\n" -#else -" cookie-algorithm sha256;\n" -#endif -#ifndef WIN32 -" coresize default;\n\ - datasize default;\n" -#endif -"\ -# deallocate-on-exit ;\n\ -# directory \n\ - dump-file \"named_dump.db\";\n\ - edns-udp-size 1232;\n\ -# fake-iquery ;\n" -#ifndef WIN32 -" files unlimited;\n" -#endif -#if defined(HAVE_GEOIP2) && !defined(WIN32) -" geoip-directory \"" MAXMINDDB_PREFIX "/share/GeoIP\";\n" -#elif defined(HAVE_GEOIP2) -" geoip-directory \".\";\n" -#endif -"\ -# has-old-clients ;\n\ - heartbeat-interval 60;\n\ -# host-statistics ;\n\ - interface-interval 60;\n\ -# keep-response-order {none;};\n\ - listen-on {any;};\n\ - listen-on-v6 {any;};\n\ -# lock-file \"" NS_LOCALSTATEDIR "/run/named/named.lock\";\n\ - match-mapped-addresses no;\n\ - max-rsa-exponent-size 0; /* no limit */\n\ - max-udp-size 1232;\n\ - memstatistics-file \"named.memstats\";\n\ -# multiple-cnames ;\n\ -# named-xfer ;\n\ - nocookie-udp-size 4096;\n\ - notify-rate 20;\n\ - nta-lifetime 3600;\n\ - nta-recheck 300;\n\ -# pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\ - port 53;\n\ - prefetch 2 9;\n" -#if defined(ISC_PLATFORM_CRYPTORANDOM) -" random-device none;\n" -#elif defined(PATH_RANDOMDEV) -" random-device \"" PATH_RANDOMDEV "\";\n" -#endif -" recursing-file \"named.recursing\";\n\ - recursive-clients 1000;\n\ - request-nsid false;\n\ - reserved-sockets 512;\n\ - resolver-query-timeout 10;\n\ - rrset-order { order random; };\n\ - secroots-file \"named.secroots\";\n\ - send-cookie true;\n\ -# serial-queries ;\n\ - serial-query-rate 20;\n\ - server-id none;\n\ - session-keyalg hmac-sha256;\n\ -# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\ - session-keyname local-ddns;\n" -#ifndef WIN32 -" stacksize default;\n" -#endif -" startup-notify-rate 20;\n\ - statistics-file \"named.stats\";\n\ -# statistics-interval ;\n\ - tcp-clients 150;\n\ - tcp-listen-queue 10;\n\ -# tkey-dhkey \n\ -# tkey-domain \n\ -# tkey-gssapi-credential \n\ - transfer-message-size 20480;\n\ - transfers-in 10;\n\ - transfers-out 10;\n\ - transfers-per-ns 2;\n\ -# treat-cr-as-space ;\n\ - trust-anchor-telemetry yes;\n\ -# use-id-pool ;\n\ -# use-ixfr ;\n\ -\n\ - /* view */\n\ - acache-cleaning-interval 60;\n\ - acache-enable no;\n\ - additional-from-auth true;\n\ - additional-from-cache true;\n\ - allow-new-zones no;\n\ - allow-notify {none;};\n\ - allow-query-cache { localnets; localhost; };\n\ - allow-query-cache-on { any; };\n\ - allow-recursion { localnets; localhost; };\n\ - allow-recursion-on { any; };\n\ - allow-update-forwarding {none;};\n\ -# allow-v6-synthesis ;\n\ - auth-nxdomain false;\n\ - check-dup-records warn;\n\ - check-mx warn;\n\ - check-names master fail;\n\ - check-names response ignore;\n\ - check-names slave warn;\n\ - check-spf warn;\n\ - cleaning-interval 0; /* now meaningless */\n\ - clients-per-query 10;\n\ - dnssec-accept-expired no;\n\ - dnssec-enable yes;\n\ - dnssec-validation yes; \n" -#ifdef HAVE_DNSTAP -" dnstap-identity hostname;\n" -#endif -"\ -# fetch-glue ;\n\ - fetch-quota-params 100 0.1 0.3 0.7;\n\ - fetches-per-server 0;\n\ - fetches-per-zone 0;\n" -#ifdef ALLOW_FILTER_AAAA -" filter-aaaa-on-v4 no;\n\ - filter-aaaa-on-v6 no;\n\ - filter-aaaa { any; };\n" -#endif -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -" geoip-use-ecs yes;\n" -#endif -" lame-ttl 600;\n" -#ifdef HAVE_LMDB -" lmdb-mapsize 32M;\n" -#endif -" max-cache-size 90%;\n\ - max-acache-size 16M;\n\ - max-cache-ttl 604800; /* 1 week */\n\ - max-clients-per-query 100;\n\ - max-ncache-ttl 10800; /* 3 hours */\n\ - max-recursion-depth 7;\n\ - max-recursion-queries 100;\n\ - max-stale-ttl 604800; /* 1 week */\n\ - message-compression yes;\n\ -# min-roots ;\n\ - minimal-any false;\n\ - minimal-responses false;\n\ - notify-source *;\n\ - notify-source-v6 *;\n\ - nsec3-test-zone no;\n\ - provide-ixfr true;\n\ - query-source address *;\n\ - query-source-v6 address *;\n\ - recursion true;\n\ - request-expire true;\n\ - request-ixfr true;\n\ - require-server-cookie no;\n\ - resolver-nonbackoff-tries 3;\n\ - resolver-retry-interval 800; /* in milliseconds */\n\ -# rfc2308-type1 ;\n\ - root-key-sentinel yes;\n\ - servfail-ttl 1;\n\ -# sortlist \n\ - stale-answer-enable false;\n\ - stale-answer-ttl 1; /* 1 second */\n\ -# topology \n\ - transfer-format many-answers;\n\ - v6-bias 50;\n\ - zero-no-soa-ttl-cache no;\n\ -\n\ - /* zone */\n\ - allow-query {any;};\n\ - allow-query-on {any;};\n\ - allow-transfer {any;};\n\ -# also-notify \n\ - alt-transfer-source *;\n\ - alt-transfer-source-v6 *;\n\ - check-integrity yes;\n\ - check-mx-cname warn;\n\ - check-sibling yes;\n\ - check-srv-cname warn;\n\ - check-wildcard yes;\n\ - dialup no;\n\ - dnssec-dnskey-kskonly no;\n\ - dnssec-loadkeys-interval 60;\n\ - dnssec-secure-to-insecure no;\n\ - dnssec-update-mode maintain;\n\ -# forward \n\ -# forwarders \n\ - inline-signing no;\n\ - ixfr-from-differences false;\n\ -# maintain-ixfr-base ;\n\ -# max-ixfr-log-size \n\ - max-journal-size unlimited;\n\ - max-records 0;\n\ - max-refresh-time 2419200; /* 4 weeks */\n\ - max-retry-time 1209600; /* 2 weeks */\n\ - max-transfer-idle-in 60;\n\ - max-transfer-idle-out 60;\n\ - max-transfer-time-in 120;\n\ - max-transfer-time-out 120;\n\ - min-refresh-time 300;\n\ - min-retry-time 500;\n\ - multi-master no;\n\ - notify yes;\n\ - notify-delay 5;\n\ - notify-to-soa no;\n\ - serial-update-method increment;\n\ - sig-signing-nodes 100;\n\ - sig-signing-signatures 10;\n\ - sig-signing-type 65534;\n\ - sig-validity-interval 30; /* days */\n\ - transfer-source *;\n\ - transfer-source-v6 *;\n\ - try-tcp-refresh yes; /* BIND 8 compat */\n\ - update-check-ksk yes;\n\ - zero-no-soa-ttl yes;\n\ - zone-statistics terse;\n\ -};\n\ -" - -"#\n\ -# Zones in the \"_bind\" view are NOT counted in the count of zones.\n\ -#\n\ -view \"_bind\" chaos {\n\ - recursion no;\n\ - notify no;\n\ - allow-new-zones no;\n\ -\n\ - # Prevent use of this zone in DNS amplified reflection DoS attacks\n\ - rate-limit {\n\ - responses-per-second 3;\n\ - slip 0;\n\ - min-table-size 10;\n\ - };\n\ -\n\ - zone \"version.bind\" chaos {\n\ - type master;\n\ - database \"_builtin version\";\n\ - };\n\ -\n\ - zone \"hostname.bind\" chaos {\n\ - type master;\n\ - database \"_builtin hostname\";\n\ - };\n\ -\n\ - zone \"authors.bind\" chaos {\n\ - type master;\n\ - database \"_builtin authors\";\n\ - };\n\ -\n\ - zone \"id.server\" chaos {\n\ - type master;\n\ - database \"_builtin id\";\n\ - };\n\ -};\n\ -" -"#\n\ -# Default trusted key(s), used if \n\ -# \"dnssec-validation auto;\" is set and\n\ -# sysconfdir/bind.keys doesn't exist).\n\ -#\n\ -# BEGIN MANAGED KEYS\n" - -/* Imported from bind.keys.h: */ -MANAGED_KEYS - -"# END MANAGED KEYS\n\ -"; - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { - isc_buffer_t b; - - isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); - isc_buffer_add(&b, sizeof(defaultconf) - 1); - return (cfg_parse_buffer4(parser, &b, __FILE__, 0, - &cfg_type_namedconf, - CFG_PCTX_NODEPRECATED, conf)); -} - -isc_result_t -ns_config_get(cfg_obj_t const * const *maps, const char *name, - const cfg_obj_t **obj) -{ - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - } -} - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char *which, - const cfg_obj_t **obj) -{ - const cfg_listelt_t *element; - const cfg_obj_t *checknames; - const cfg_obj_t *type; - const cfg_obj_t *value; - int i; - - REQUIRE(maps != NULL); - REQUIRE(which != NULL); - REQUIRE(obj != NULL && *obj == NULL); - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - checknames = NULL; - if (cfg_map_get(maps[i], "check-names", - &checknames) == ISC_R_SUCCESS) { - /* - * Zone map entry is not a list. - */ - if (checknames != NULL && !cfg_obj_islist(checknames)) { - *obj = checknames; - return (ISC_R_SUCCESS); - } - for (element = cfg_list_first(checknames); - element != NULL; - element = cfg_list_next(element)) { - value = cfg_listelt_value(element); - type = cfg_tuple_get(value, "type"); - if (strcasecmp(cfg_obj_asstring(type), - which) == 0) { - *obj = cfg_tuple_get(value, "mode"); - return (ISC_R_SUCCESS); - } - } - - } - } -} - -int -ns_config_listcount(const cfg_obj_t *list) { - const cfg_listelt_t *e; - int i = 0; - - for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e)) - i++; - - return (i); -} - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(classobj)) { - *classp = defclass; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(classobj), r.base); - r.length = strlen(r.base); - result = dns_rdataclass_fromtext(classp, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown class '%s'", r.base); - return (result); -} - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(typeobj)) { - *typep = deftype; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(typeobj), r.base); - r.length = strlen(r.base); - result = dns_rdatatype_fromtext(typep, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown type '%s'", r.base); - return (result); -} - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj) { - dns_zonetype_t ztype = dns_zone_none; - const char *str; - - str = cfg_obj_asstring(zonetypeobj); - if (strcasecmp(str, "master") == 0) { - ztype = dns_zone_master; - } else if (strcasecmp(str, "slave") == 0) { - ztype = dns_zone_slave; - } else if (strcasecmp(str, "stub") == 0) { - ztype = dns_zone_stub; - } else if (strcasecmp(str, "static-stub") == 0) { - ztype = dns_zone_staticstub; - } else if (strcasecmp(str, "redirect") == 0) { - ztype = dns_zone_redirect; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - return (ztype); -} - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, - uint32_t *countp) -{ - int count, i = 0; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj, *dscpobj; - const cfg_listelt_t *element; - isc_sockaddr_t *addrs; - in_port_t port; - isc_dscp_t dscp = -1, *dscps = NULL; - isc_result_t result; - - INSIST(addrsp != NULL && *addrsp == NULL); - INSIST(dscpsp == NULL || *dscpsp == NULL); - INSIST(countp != NULL); - - addrlist = cfg_tuple_get(list, "addresses"); - count = ns_config_listcount(addrlist); - - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } else if (defport != 0) - port = defport; - else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - - if (dscpsp != NULL) { - dscpobj = cfg_tuple_get(list, "dscp"); - if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t)); - if (dscps == NULL) - return (ISC_R_NOMEMORY); - } - - addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); - if (addrs == NULL) { - if (dscps != NULL) - isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t)); - return (ISC_R_NOMEMORY); - } - - for (element = cfg_list_first(addrlist); - element != NULL; - element = cfg_list_next(element), i++) - { - const cfg_obj_t *addr; - INSIST(i < count); - addr = cfg_listelt_value(element); - addrs[i] = *cfg_obj_assockaddr(addr); - if (dscpsp != NULL) { - isc_dscp_t innerdscp; - innerdscp = cfg_obj_getdscp(addr); - if (innerdscp == -1) - innerdscp = dscp; - dscps[i] = innerdscp; - } - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - } - INSIST(i == count); - - *addrsp = addrs; - *countp = count; - - if (dscpsp != NULL) - *dscpsp = dscps; - - return (ISC_R_SUCCESS); -} - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_dscp_t **dscpsp, uint32_t count) -{ - INSIST(addrsp != NULL && *addrsp != NULL); - INSIST(dscpsp == NULL || *dscpsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - *addrsp = NULL; - - if (dscpsp != NULL) { - isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t)); - *dscpsp = NULL; - } -} - -static isc_result_t -get_masters_def(const cfg_obj_t *cctx, const char *name, - const cfg_obj_t **ret) -{ - isc_result_t result; - const cfg_obj_t *masters = NULL; - const cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "masters", &masters); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(masters); - elt != NULL; - elt = cfg_list_next(elt)) { - const cfg_obj_t *list; - const char *listname; - - list = cfg_listelt_value(elt); - listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); - - if (strcasecmp(listname, name) == 0) { - *ret = list; - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, dns_ipkeylist_t *ipkl) -{ - uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0; - uint32_t listcount = 0, l = 0, j; - uint32_t stackcount = 0, pushed = 0; - isc_result_t result; - const cfg_listelt_t *element; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj; - const cfg_obj_t *dscpobj; - in_port_t port; - isc_dscp_t dscp = -1; - dns_fixedname_t fname; - isc_sockaddr_t *addrs = NULL; - isc_dscp_t *dscps = NULL; - dns_name_t **keys = NULL; - struct { const char *name; } *lists = NULL; - struct { - const cfg_listelt_t *element; - in_port_t port; - isc_dscp_t dscp; - } *stack = NULL; - - REQUIRE(ipkl != NULL); - REQUIRE(ipkl->count == 0); - REQUIRE(ipkl->addrs == NULL); - REQUIRE(ipkl->keys == NULL); - REQUIRE(ipkl->dscps == NULL); - REQUIRE(ipkl->labels == NULL); - REQUIRE(ipkl->allocated == 0); - - /* - * Get system defaults. - */ - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_config_getdscp(config, &dscp); - if (result != ISC_R_SUCCESS) - goto cleanup; - - newlist: - addrlist = cfg_tuple_get(list, "addresses"); - portobj = cfg_tuple_get(list, "port"); - dscpobj = cfg_tuple_get(list, "dscp"); - - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - result = ISC_R_RANGE; - goto cleanup; - } - port = (in_port_t) val; - } - - if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - result = ISC_R_RANGE; - goto cleanup; - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - result = ISC_R_NOMEMORY; - - element = cfg_list_first(addrlist); - resume: - for ( ; - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *addr; - const cfg_obj_t *key; - const char *keystr; - isc_buffer_t b; - - addr = cfg_tuple_get(cfg_listelt_value(element), - "masterselement"); - key = cfg_tuple_get(cfg_listelt_value(element), "key"); - - if (!cfg_obj_issockaddr(addr)) { - const char *listname = cfg_obj_asstring(addr); - isc_result_t tresult; - - /* Grow lists? */ - if (listcount == l) { - void * tmp; - uint32_t newlen = listcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*lists); - oldsize = listcount * sizeof(*lists); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (listcount != 0) { - memmove(tmp, lists, oldsize); - isc_mem_put(mctx, lists, oldsize); - } - lists = tmp; - listcount = newlen; - } - /* Seen? */ - for (j = 0; j < l; j++) - if (strcasecmp(lists[j].name, listname) == 0) - break; - if (j < l) - continue; - tresult = get_masters_def(config, listname, &list); - if (tresult == ISC_R_NOTFOUND) { - cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, - "masters \"%s\" not found", listname); - - result = tresult; - goto cleanup; - } - if (tresult != ISC_R_SUCCESS) - goto cleanup; - lists[l++].name = listname; - /* Grow stack? */ - if (stackcount == pushed) { - void * tmp; - uint32_t newlen = stackcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*stack); - oldsize = stackcount * sizeof(*stack); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (stackcount != 0) { - memmove(tmp, stack, oldsize); - isc_mem_put(mctx, stack, oldsize); - } - stack = tmp; - stackcount = newlen; - } - /* - * We want to resume processing this list on the - * next element. - */ - stack[pushed].element = cfg_list_next(element); - stack[pushed].port = port; - stack[pushed].dscp = dscp; - pushed++; - goto newlist; - } - - if (i == addrcount) { - void * tmp; - uint32_t newlen = addrcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (addrcount != 0) { - memmove(tmp, addrs, oldsize); - isc_mem_put(mctx, addrs, oldsize); - } - addrs = tmp; - addrcount = newlen; - - newsize = newlen * sizeof(isc_dscp_t); - oldsize = dscpcount * sizeof(isc_dscp_t); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (dscpcount != 0) { - memmove(tmp, dscps, oldsize); - isc_mem_put(mctx, dscps, oldsize); - } - dscps = tmp; - dscpcount = newlen; - - newsize = newlen * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - if (keycount != 0) { - memmove(tmp, keys, oldsize); - isc_mem_put(mctx, keys, oldsize); - } - keys = tmp; - keycount = newlen; - } - - addrs[i] = *cfg_obj_assockaddr(addr); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - dscps[i] = cfg_obj_getdscp(addr); - if (dscps[i] == -1) - dscps[i] = dscp; - keys[i] = NULL; - i++; /* Increment here so that cleanup on error works. */ - if (!cfg_obj_isstring(key)) - continue; - keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t)); - if (keys[i - 1] == NULL) - goto cleanup; - dns_name_init(keys[i - 1], NULL); - - keystr = cfg_obj_asstring(key); - isc_buffer_constinit(&b, keystr, strlen(keystr)); - isc_buffer_add(&b, strlen(keystr)); - dns_fixedname_init(&fname); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_name_dup(dns_fixedname_name(&fname), mctx, - keys[i - 1]); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - if (pushed != 0) { - pushed--; - element = stack[pushed].element; - port = stack[pushed].port; - dscp = stack[pushed].dscp; - goto resume; - } - if (i < addrcount) { - void * tmp; - size_t newsize, oldsize; - - newsize = i * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, addrs, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, addrs, oldsize); - addrs = tmp; - addrcount = i; - - newsize = i * sizeof(isc_dscp_t); - oldsize = dscpcount * sizeof(isc_dscp_t); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, dscps, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, dscps, oldsize); - dscps = tmp; - dscpcount = i; - - newsize = i * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - if (i != 0) { - tmp = isc_mem_get(mctx, newsize); - if (tmp == NULL) - goto cleanup; - memmove(tmp, keys, newsize); - } else - tmp = NULL; - isc_mem_put(mctx, keys, oldsize); - keys = tmp; - keycount = i; - } - - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - - INSIST(dscpcount == addrcount); - INSIST(keycount == addrcount); - INSIST(keycount == dscpcount); - - ipkl->addrs = addrs; - ipkl->dscps = dscps; - ipkl->keys = keys; - ipkl->count = addrcount; - ipkl->allocated = addrcount; - - return (ISC_R_SUCCESS); - - cleanup: - if (addrs != NULL) - isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); - if (dscps != NULL) - isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t)); - if (keys != NULL) { - for (j = 0; j < i; j++) { - if (keys[j] == NULL) - continue; - if (dns_name_dynamic(keys[j])) - dns_name_free(keys[j], mctx); - isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); - } - isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); - } - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - return (result); -} - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp) { - const cfg_obj_t *maps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *portobj = NULL; - isc_result_t result; - int i; - - (void)cfg_map_get(config, "options", &options); - i = 0; - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "port", &portobj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_asuint32(portobj) >= UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - *portp = (in_port_t)cfg_obj_asuint32(portobj); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) { - const cfg_obj_t *options = NULL; - const cfg_obj_t *dscpobj = NULL; - isc_result_t result; - - (void)cfg_map_get(config, "options", &options); - if (options == NULL) - return (ISC_R_SUCCESS); - - result = cfg_map_get(options, "dscp", &dscpobj); - if (result != ISC_R_SUCCESS || dscpobj == NULL) { - *dscpp = -1; - return (ISC_R_SUCCESS); - } - if (cfg_obj_asuint32(dscpobj) >= 64) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp '%u' out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - *dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - return (ISC_R_SUCCESS); -} - -struct keyalgorithms { - const char *str; - enum { hmacnone, hmacmd5, hmacsha1, hmacsha224, - hmacsha256, hmacsha384, hmacsha512 } hmac; - unsigned int type; - uint16_t size; -} algorithms[] = { -#ifndef PK11_MD5_DISABLE - { "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 }, - { "hmac-md5.sig-alg.reg.int", hmacmd5, DST_ALG_HMACMD5, 0 }, - { "hmac-md5.sig-alg.reg.int.", hmacmd5, DST_ALG_HMACMD5, 0 }, -#endif - { "hmac-sha1", hmacsha1, DST_ALG_HMACSHA1, 160 }, - { "hmac-sha224", hmacsha224, DST_ALG_HMACSHA224, 224 }, - { "hmac-sha256", hmacsha256, DST_ALG_HMACSHA256, 256 }, - { "hmac-sha384", hmacsha384, DST_ALG_HMACSHA384, 384 }, - { "hmac-sha512", hmacsha512, DST_ALG_HMACSHA512, 512 }, - { NULL, hmacnone, DST_ALG_UNKNOWN, 0 } -}; - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - uint16_t *digestbits) -{ - return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits)); -} - -static inline int -algorithms_start() { -#ifndef PK11_MD5_DISABLE - if (!isc_md5_available()) { - int i = 0; - while (algorithms[i].str != NULL && - algorithms[i].hmac == hmacmd5) { - i++; - } - return i; - } -#endif - return 0; -} - -isc_result_t -ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, - unsigned int *typep, uint16_t *digestbits) -{ - int i; - size_t len = 0; - uint16_t bits; - isc_result_t result; - - for (i = algorithms_start(); algorithms[i].str != NULL; i++) { - len = strlen(algorithms[i].str); - if (strncasecmp(algorithms[i].str, str, len) == 0 && - (str[len] == '\0' || - (algorithms[i].size != 0 && str[len] == '-'))) - break; - } - if (algorithms[i].str == NULL) - return (ISC_R_NOTFOUND); - if (str[len] == '-') { - result = isc_parse_uint16(&bits, str + len + 1, 10); - if (result != ISC_R_SUCCESS) - return (result); - if (bits > algorithms[i].size) - return (ISC_R_RANGE); - } else if (algorithms[i].size == 0) - bits = 128; - else - bits = algorithms[i].size; - - if (name != NULL) { - switch (algorithms[i].hmac) { -#ifndef PK11_MD5_DISABLE - case hmacmd5: - if (isc_md5_available()) { - *name = dns_tsig_hmacmd5_name; break; - } else { - return (ISC_R_NOTFOUND); - } -#endif - case hmacsha1: *name = dns_tsig_hmacsha1_name; break; - case hmacsha224: *name = dns_tsig_hmacsha224_name; break; - case hmacsha256: *name = dns_tsig_hmacsha256_name; break; - case hmacsha384: *name = dns_tsig_hmacsha384_name; break; - case hmacsha512: *name = dns_tsig_hmacsha512_name; break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (typep != NULL) - *typep = algorithms[i].type; - if (digestbits != NULL) - *digestbits = bits; - return (ISC_R_SUCCESS); -} diff --git a/bin/named-sdb/control.c b/bin/named-sdb/control.c deleted file mode 100644 index 0756c73..0000000 --- a/bin/named-sdb/control.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static isc_result_t -getcommand(isc_lex_t *lex, char **cmdp) { - isc_result_t result; - isc_token_t token; - - REQUIRE(cmdp != NULL && *cmdp == NULL); - - result = isc_lex_gettoken(lex, ISC_LEXOPT_EOF, &token); - if (result != ISC_R_SUCCESS) - return (result); - - isc_lex_ungettoken(lex, &token); - - if (token.type != isc_tokentype_string) - return (ISC_R_FAILURE); - - *cmdp = token.value.as_textregion.base; - - return (ISC_R_SUCCESS); -} - -static inline bool -command_compare(const char *str, const char *command) { - return (strcasecmp(str, command) == 0); -} - -/*% - * This function is called to process the incoming command - * when a control channel message is received. - */ -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, bool readonly, - isc_buffer_t **text) -{ - isccc_sexpr_t *data; - char *cmdline = NULL; - char *command = NULL; - isc_result_t result; - int log_level; - isc_buffer_t src; - isc_lex_t *lex = NULL; -#ifdef HAVE_LIBSCF - ns_smf_want_disable = 0; -#endif - - data = isccc_alist_lookup(message, "_data"); - if (!isccc_alist_alistp(data)) { - /* - * No data section. - */ - return (ISC_R_FAILURE); - } - - result = isccc_cc_lookupstring(data, "type", &cmdline); - if (result != ISC_R_SUCCESS) { - /* - * We have no idea what this is. - */ - return (result); - } - - result = isc_lex_create(ns_g_mctx, strlen(cmdline), &lex); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_init(&src, cmdline, strlen(cmdline)); - isc_buffer_add(&src, strlen(cmdline)); - result = isc_lex_openbuffer(lex, &src); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = getcommand(lex, &command); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Compare the 'command' parameter against all known control commands. - */ - if ((command_compare(command, NS_COMMAND_NULL) && - strlen(cmdline) == 4) || - command_compare(command, NS_COMMAND_STATUS)) - { - log_level = ISC_LOG_DEBUG(1); - } else { - log_level = ISC_LOG_INFO; - } - - /* - * If this listener should have read-only access, reject - * restricted commands here. rndc nta is handled specially - * below. - */ - if (readonly && - !command_compare(command, NS_COMMAND_NTA) && - !command_compare(command, NS_COMMAND_NULL) && - !command_compare(command, NS_COMMAND_STATUS) && - !command_compare(command, NS_COMMAND_SHOWZONE) && - !command_compare(command, NS_COMMAND_TESTGEN) && - !command_compare(command, NS_COMMAND_ZONESTATUS)) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, log_level, - "rejecting restricted control channel " - "command '%s'", cmdline); - result = ISC_R_FAILURE; - goto cleanup; - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, log_level, - "received control channel command '%s'", - cmdline); - - /* - * After the lengthy "halt" and "stop", the commands are - * handled in alphabetical order of the NS_COMMAND_ macros. - */ - if (command_compare(command, NS_COMMAND_HALT)) { -#ifdef HAVE_LIBSCF - /* - * If we are managed by smf(5), AND in chroot, then - * we cannot connect to the smf repository, so just - * return with an appropriate message back to rndc. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - goto cleanup; - } - /* - * If we are managed by smf(5) but not in chroot, - * try to disable ourselves the smf way. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; - /* - * If ns_smf_got_instance = 0, ns_smf_chroot - * is not relevant and we fall through to - * isc_app_shutdown below. - */ -#endif - /* Do not flush master files */ - ns_server_flushonshutdown(ns_g_server, false); - ns_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_STOP)) { - /* - * "stop" is the same as "halt" except it does - * flush master files. - */ -#ifdef HAVE_LIBSCF - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - goto cleanup; - } - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; -#endif - ns_server_flushonshutdown(ns_g_server, true); - ns_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_ADDZONE) || - command_compare(command, NS_COMMAND_MODZONE)) { - result = ns_server_changezone(ns_g_server, cmdline, text); - } else if (command_compare(command, NS_COMMAND_DELZONE)) { - result = ns_server_delzone(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_DNSTAP) || - command_compare(command, NS_COMMAND_DNSTAPREOPEN)) { - result = ns_server_dnstap(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_DUMPDB)) { - ns_server_dumpdb(ns_g_server, lex, text); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) { - result = ns_server_dumpstats(ns_g_server); - } else if (command_compare(command, NS_COMMAND_FLUSH)) { - result = ns_server_flushcache(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { - result = ns_server_flushnode(ns_g_server, lex, false); - } else if (command_compare(command, NS_COMMAND_FLUSHTREE)) { - result = ns_server_flushnode(ns_g_server, lex, true); - } else if (command_compare(command, NS_COMMAND_FREEZE)) { - result = ns_server_freeze(ns_g_server, true, lex, - text); - } else if (command_compare(command, NS_COMMAND_LOADKEYS) || - command_compare(command, NS_COMMAND_SIGN)) { - result = ns_server_rekey(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_MKEYS)) { - result = ns_server_mkeys(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_NOTIFY)) { - result = ns_server_notifycommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_NOTRACE)) { - ns_g_debuglevel = 0; - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_NTA)) { - result = ns_server_nta(ns_g_server, lex, readonly, text); - } else if (command_compare(command, NS_COMMAND_NULL)) { - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_QUERYLOG)) { - result = ns_server_togglequerylog(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_RECONFIG)) { - result = ns_server_reconfigcommand(ns_g_server); - } else if (command_compare(command, NS_COMMAND_RECURSING)) { - result = ns_server_dumprecursing(ns_g_server); - } else if (command_compare(command, NS_COMMAND_REFRESH)) { - result = ns_server_refreshcommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_RELOAD)) { - result = ns_server_reloadcommand(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_RETRANSFER)) { - result = ns_server_retransfercommand(ns_g_server, - lex, text); - } else if (command_compare(command, NS_COMMAND_SCAN)) { - result = ISC_R_SUCCESS; - ns_server_scan_interfaces(ns_g_server); - } else if (command_compare(command, NS_COMMAND_SECROOTS)) { - result = ns_server_dumpsecroots(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SIGNING)) { - result = ns_server_signing(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SHOWZONE)) { - result = ns_server_showzone(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_STATUS)) { - result = ns_server_status(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_SYNC)) { - result = ns_server_sync(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_THAW) || - command_compare(command, NS_COMMAND_UNFREEZE)) { - result = ns_server_freeze(ns_g_server, false, lex, - text); - } else if (command_compare(command, NS_COMMAND_TESTGEN)) { - result = ns_server_testgen(lex, text); - } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) { - result = ISC_R_SUCCESS; - isc_timermgr_poke(ns_g_timermgr); - } else if (command_compare(command, NS_COMMAND_TRACE)) { - result = ns_server_setdebuglevel(ns_g_server, lex); - } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) { - result = ns_server_tsigdelete(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_TSIGLIST)) { - result = ns_server_tsiglist(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_VALIDATION)) { - result = ns_server_validation(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_ZONESTATUS)) { - result = ns_server_zonestatus(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SERVESTALE)) { - result = ns_server_servestale(ns_g_server, lex, text); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "unknown control channel command '%s'", - command); - result = DNS_R_UNKNOWNCOMMAND; - } - - cleanup: - if (lex != NULL) - isc_lex_destroy(&lex); - - return (result); -} diff --git a/bin/named-sdb/controlconf.c b/bin/named-sdb/controlconf.c deleted file mode 100644 index 42128dc..0000000 --- a/bin/named-sdb/controlconf.c +++ /dev/null @@ -1,1556 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -/* - * Note: Listeners and connections are not locked. All event handlers are - * executed by the server task, and all callers of exported routines must - * be running under the server task. - */ - -typedef struct controlkey controlkey_t; -typedef ISC_LIST(controlkey_t) controlkeylist_t; - -typedef struct controlconnection controlconnection_t; -typedef ISC_LIST(controlconnection_t) controlconnectionlist_t; - -typedef struct controllistener controllistener_t; -typedef ISC_LIST(controllistener_t) controllistenerlist_t; - -struct controlkey { - char * keyname; - uint32_t algorithm; - isc_region_t secret; - ISC_LINK(controlkey_t) link; -}; - -struct controlconnection { - isc_socket_t * sock; - isccc_ccmsg_t ccmsg; - bool ccmsg_valid; - bool sending; - isc_timer_t * timer; - isc_buffer_t * buffer; - controllistener_t * listener; - uint32_t nonce; - ISC_LINK(controlconnection_t) link; -}; - -struct controllistener { - ns_controls_t * controls; - isc_mem_t * mctx; - isc_task_t * task; - isc_sockaddr_t address; - isc_socket_t * sock; - dns_acl_t * acl; - bool listening; - bool exiting; - controlkeylist_t keys; - controlconnectionlist_t connections; - isc_sockettype_t type; - uint32_t perm; - uint32_t owner; - uint32_t group; - bool readonly; - ISC_LINK(controllistener_t) link; -}; - -struct ns_controls { - ns_server_t *server; - controllistenerlist_t listeners; - bool shuttingdown; - isc_mutex_t symtab_lock; - isccc_symtab_t *symtab; -}; - -static void control_newconn(isc_task_t *task, isc_event_t *event); -static void control_recvmessage(isc_task_t *task, isc_event_t *event); - -#define CLOCKSKEW 300 - -static void -free_controlkey(controlkey_t *key, isc_mem_t *mctx) { - if (key->keyname != NULL) - isc_mem_free(mctx, key->keyname); - if (key->secret.base != NULL) - isc_mem_put(mctx, key->secret.base, key->secret.length); - isc_mem_put(mctx, key, sizeof(*key)); -} - -static void -free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) { - while (!ISC_LIST_EMPTY(*keylist)) { - controlkey_t *key = ISC_LIST_HEAD(*keylist); - ISC_LIST_UNLINK(*keylist, key, link); - free_controlkey(key, mctx); - } -} - -static void -free_listener(controllistener_t *listener) { - INSIST(listener->exiting); - INSIST(!listener->listening); - INSIST(ISC_LIST_EMPTY(listener->connections)); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - free_controlkeylist(&listener->keys, listener->mctx); - - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - - isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); -} - -static void -maybe_free_listener(controllistener_t *listener) { - if (listener->exiting && - !listener->listening && - ISC_LIST_EMPTY(listener->connections)) - free_listener(listener); -} - -static void -maybe_free_connection(controlconnection_t *conn) { - controllistener_t *listener = conn->listener; - - if (conn->buffer != NULL) - isc_buffer_free(&conn->buffer); - - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - - if (conn->ccmsg_valid) { - isccc_ccmsg_cancelread(&conn->ccmsg); - return; - } - - if (conn->sending) { - isc_socket_cancel(conn->sock, listener->task, - ISC_SOCKCANCEL_SEND); - return; - } - - ISC_LIST_UNLINK(listener->connections, conn, link); -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_rndc) { - named_fuzz_notify(); - } -#endif - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -} - -static void -shutdown_listener(controllistener_t *listener) { - controlconnection_t *conn; - controlconnection_t *next; - - if (!listener->exiting) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_UNLINK(listener->controls->listeners, listener, link); - - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "stopping command channel on %s", socktext); - if (listener->type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, true); - listener->exiting = true; - } - - for (conn = ISC_LIST_HEAD(listener->connections); - conn != NULL; - conn = next) - { - next = ISC_LIST_NEXT(conn, link); - maybe_free_connection(conn); - } - - if (listener->listening) - isc_socket_cancel(listener->sock, listener->task, - ISC_SOCKCANCEL_ACCEPT); - - maybe_free_listener(listener); -} - -static bool -address_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) { - isc_netaddr_t netaddr; - isc_result_t result; - int match; - - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = dns_acl_match(&netaddr, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS || match <= 0) - return (false); - else - return (true); -} - -static isc_result_t -control_accept(controllistener_t *listener) { - isc_result_t result; - result = isc_socket_accept(listener->sock, - listener->task, - control_newconn, listener); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - else - listener->listening = true; - return (result); -} - -static isc_result_t -control_listen(controllistener_t *listener) { - isc_result_t result; - - result = isc_socket_listen(listener->sock, 0); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_listen() failed: %s", - isc_result_totext(result)); - return (result); -} - -static void -control_next(controllistener_t *listener) { - (void)control_accept(listener); -} - -static void -control_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - controlconnection_t *conn = event->ev_arg; - controllistener_t *listener = conn->listener; - isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender; - isc_result_t result; - - REQUIRE(conn->sending); - - UNUSED(task); - - conn->sending = false; - - if (sevent->result != ISC_R_SUCCESS && - sevent->result != ISC_R_CANCELED) - { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "error sending command response to %s: %s", - socktext, isc_result_totext(sevent->result)); - } - isc_event_free(&event); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) { - isc_socket_detach(&conn->sock); - maybe_free_connection(conn); - maybe_free_listener(listener); - } -} - -static inline void -log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(ccmsg->sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_ERROR, - "invalid command from %s: %s", - socktext, isc_result_totext(result)); -} - -static void -control_recvmessage(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = NULL; - controllistener_t *listener = NULL; - ns_server_t *server = NULL; - controlkey_t *key = NULL; - isccc_sexpr_t *request = NULL; - isccc_sexpr_t *response = NULL; - uint32_t algorithm; - isccc_region_t secret; - isc_stdtime_t now; - isc_buffer_t b; - isc_region_t r; - isc_buffer_t *text; - isc_result_t result; - isc_result_t eresult; - isccc_sexpr_t *_ctrl = NULL; - isccc_time_t sent; - isccc_time_t exp; - uint32_t nonce; - isccc_sexpr_t *data = NULL; - - REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); - - conn = event->ev_arg; - listener = conn->listener; - server = listener->controls->server; - algorithm = DST_ALG_UNKNOWN; - secret.rstart = NULL; - text = NULL; - - /* Is the server shutting down? */ - if (listener->controls->shuttingdown) - goto cleanup; - - if (conn->ccmsg.result != ISC_R_SUCCESS) { - if (conn->ccmsg.result != ISC_R_CANCELED && - conn->ccmsg.result != ISC_R_EOF) - log_invalid(&conn->ccmsg, conn->ccmsg.result); - goto cleanup; - } - - request = NULL; - - for (key = ISC_LIST_HEAD(listener->keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - isccc_region_t ccregion; - - ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); - ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); - secret.rstart = isc_mem_get(listener->mctx, key->secret.length); - if (secret.rstart == NULL) - goto cleanup; - memmove(secret.rstart, key->secret.base, key->secret.length); - secret.rend = secret.rstart + key->secret.length; - algorithm = key->algorithm; - result = isccc_cc_fromwire(&ccregion, &request, - algorithm, &secret); - if (result == ISC_R_SUCCESS) - break; - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - if (result != ISCCC_R_BADAUTH) { - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - } - - if (key == NULL) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* We shouldn't be getting a reply. */ - if (isccc_cc_isreply(request)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - isc_stdtime_get(&now); - - /* - * Limit exposure to replay attacks. - */ - _ctrl = isccc_alist_lookup(request, "_ctrl"); - if (!isccc_alist_alistp(_ctrl)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { - if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { - log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); - goto cleanup_request; - } - } else { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup_request; - } - - /* - * Expire messages that are too old. - */ - if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && - now > exp) { - log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); - goto cleanup_request; - } - - /* - * Duplicate suppression (required for UDP). - */ - LOCK(&listener->controls->symtab_lock); - isccc_cc_cleansymtab(listener->controls->symtab, now); - result = isccc_cc_checkdup(listener->controls->symtab, request, now); - UNLOCK(&listener->controls->symtab_lock); - if (result != ISC_R_SUCCESS) { - if (result == ISC_R_EXISTS) - result = ISCCC_R_DUPLICATE; - log_invalid(&conn->ccmsg, result); - goto cleanup_request; - } - - if (conn->nonce != 0 && - (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || - conn->nonce != nonce)) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup_request; - } - - result = isc_buffer_allocate(listener->mctx, &text, 2 * 2048); - if (result != ISC_R_SUCCESS) - goto cleanup_request; - - /* - * Establish nonce. - */ - if (conn->nonce == 0) { - while (conn->nonce == 0) { - uint16_t r1 = isc_rng_random(server->rngctx); - uint16_t r2 = isc_rng_random(server->rngctx); - conn->nonce = (r1 << 16) | r2; - } - eresult = ISC_R_SUCCESS; - } else - eresult = ns_control_docommand(request, listener->readonly, &text); - - result = isccc_cc_createresponse(request, now, now + 60, &response); - if (result != ISC_R_SUCCESS) - goto cleanup_request; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - if (isccc_cc_defineuint32(data, "result", eresult) == NULL) - goto cleanup_response; - } - - if (eresult != ISC_R_SUCCESS) { - if (data != NULL) { - const char *estr = isc_result_totext(eresult); - if (isccc_cc_definestring(data, "err", estr) == NULL) - goto cleanup_response; - } - } - - if (isc_buffer_usedlength(text) > 0) { - if (data != NULL) { - char *str = (char *)isc_buffer_base(text); - if (isccc_cc_definestring(data, "text", str) == NULL) - goto cleanup_response; - } - } - - _ctrl = isccc_alist_lookup(response, "_ctrl"); - if (_ctrl == NULL || - isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) - goto cleanup_response; - - if (conn->buffer == NULL) { - result = isc_buffer_allocate(listener->mctx, - &conn->buffer, 2 * 2048); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - } - - isc_buffer_clear(conn->buffer); - /* Skip the length field (4 bytes) */ - isc_buffer_add(conn->buffer, 4); - - result = isccc_cc_towire(response, &conn->buffer, algorithm, &secret); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - - isc_buffer_init(&b, conn->buffer->base, 4); - isc_buffer_putuint32(&b, conn->buffer->used - 4); - - r.base = conn->buffer->base; - r.length = conn->buffer->used; - - result = isc_socket_send(conn->sock, &r, task, control_senddone, conn); - if (result != ISC_R_SUCCESS) - goto cleanup_response; - conn->sending = true; - - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - isccc_sexpr_free(&request); - isccc_sexpr_free(&response); - isc_buffer_free(&text); - return; - - cleanup_response: - isccc_sexpr_free(&response); - - cleanup_request: - isccc_sexpr_free(&request); - isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret)); - if (text != NULL) - isc_buffer_free(&text); - - cleanup: - isc_socket_detach(&conn->sock); - isccc_ccmsg_invalidate(&conn->ccmsg); - conn->ccmsg_valid = false; - maybe_free_connection(conn); - maybe_free_listener(listener); -} - -static void -control_timeout(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = event->ev_arg; - - UNUSED(task); - - isc_timer_detach(&conn->timer); - maybe_free_connection(conn); - - isc_event_free(&event); -} - -static isc_result_t -newconnection(controllistener_t *listener, isc_socket_t *sock) { - controlconnection_t *conn; - isc_interval_t interval; - isc_result_t result; - - conn = isc_mem_get(listener->mctx, sizeof(*conn)); - if (conn == NULL) - return (ISC_R_NOMEMORY); - - conn->sock = sock; - isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg); - - /* Set a 32 KiB upper limit on incoming message. */ - isccc_ccmsg_setmaxsize(&conn->ccmsg, 32768); - - conn->ccmsg_valid = true; - conn->sending = false; - conn->buffer = NULL; - conn->timer = NULL; - isc_interval_set(&interval, 60, 0); - result = isc_timer_create(ns_g_timermgr, isc_timertype_once, - NULL, &interval, listener->task, - control_timeout, conn, &conn->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - conn->listener = listener; - conn->nonce = 0; - ISC_LINK_INIT(conn, link); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_APPEND(listener->connections, conn, link); - return (ISC_R_SUCCESS); - - cleanup: - if (conn->buffer != NULL) - isc_buffer_free(&conn->buffer); - isccc_ccmsg_invalidate(&conn->ccmsg); - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_rndc) { - named_fuzz_notify(); - } -#endif - return (result); -} - -static void -control_newconn(isc_task_t *task, isc_event_t *event) { - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - controllistener_t *listener = event->ev_arg; - isc_socket_t *sock; - isc_sockaddr_t peeraddr; - isc_result_t result; - - UNUSED(task); - - listener->listening = false; - - if (nevent->result != ISC_R_SUCCESS) { - if (nevent->result == ISC_R_CANCELED) { - shutdown_listener(listener); - goto cleanup; - } - goto restart; - } - - sock = nevent->newsocket; - isc_socket_setname(sock, "control", NULL); - (void)isc_socket_getpeername(sock, &peeraddr); - if (listener->type == isc_sockettype_tcp && - !address_ok(&peeraddr, listener->acl)) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "rejected command channel message from %s", - socktext); - isc_socket_detach(&sock); - goto restart; - } - - result = newconnection(listener, sock); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "dropped command channel from %s: %s", - socktext, isc_result_totext(result)); - isc_socket_detach(&sock); - goto restart; - } - - restart: - control_next(listener); - cleanup: - isc_event_free(&event); -} - -static void -controls_shutdown(ns_controls_t *controls) { - controllistener_t *listener; - controllistener_t *next; - - for (listener = ISC_LIST_HEAD(controls->listeners); - listener != NULL; - listener = next) - { - /* - * This is asynchronous. As listeners shut down, they will - * call their callbacks. - */ - next = ISC_LIST_NEXT(listener, link); - shutdown_listener(listener); - } -} - -void -ns_controls_shutdown(ns_controls_t *controls) { - controls_shutdown(controls); - controls->shuttingdown = true; -} - -static isc_result_t -cfgkeylist_find(const cfg_obj_t *keylist, const char *keyname, - const cfg_obj_t **objp) -{ - const cfg_listelt_t *element; - const char *str; - const cfg_obj_t *obj; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_map_getname(obj)); - if (strcasecmp(str, keyname) == 0) - break; - } - if (element == NULL) - return (ISC_R_NOTFOUND); - obj = cfg_listelt_value(element); - *objp = obj; - return (ISC_R_SUCCESS); -} - -static isc_result_t -controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx, - controlkeylist_t *keyids) -{ - const cfg_listelt_t *element; - char *newstr = NULL; - const char *str; - const cfg_obj_t *obj; - controlkey_t *key; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - newstr = isc_mem_strdup(mctx, str); - if (newstr == NULL) - goto cleanup; - key = isc_mem_get(mctx, sizeof(*key)); - if (key == NULL) - goto cleanup; - key->keyname = newstr; - key->algorithm = DST_ALG_UNKNOWN; - key->secret.base = NULL; - key->secret.length = 0; - ISC_LINK_INIT(key, link); - ISC_LIST_APPEND(*keyids, key, link); - newstr = NULL; - } - return (ISC_R_SUCCESS); - - cleanup: - if (newstr != NULL) - isc_mem_free(mctx, newstr); - free_controlkeylist(keyids, mctx); - return (ISC_R_NOMEMORY); -} - -static void -register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist, - controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) -{ - controlkey_t *keyid, *next; - const cfg_obj_t *keydef; - char secret[1024]; - isc_buffer_t b; - isc_result_t result; - - /* - * Find the keys corresponding to the keyids used by this listener. - */ - for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) { - next = ISC_LIST_NEXT(keyid, link); - - result = cfgkeylist_find(keylist, keyid->keyname, &keydef); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't find key '%s' for use with " - "command channel %s", - keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - } else { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - unsigned int algtype; - - (void)cfg_map_get(keydef, "algorithm", &algobj); - (void)cfg_map_get(keydef, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm2(algstr, NULL, - &algtype, NULL) != ISC_R_SUCCESS) - { - cfg_obj_log(control, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel %s", - algstr, keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->algorithm = algtype; - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on " - "command channel %s: %s", - keyid->keyname, socktext, - isc_result_totext(result)); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - break; - } - memmove(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - } - } -} - -#define CHECK(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static isc_result_t -get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { - isc_result_t result; - cfg_parser_t *pctx = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *key = NULL; - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - controlkey_t *keyid = NULL; - char secret[1024]; - unsigned int algtype; - isc_buffer_t b; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_INFO, - "configuring command channel from '%s'", - ns_g_keyfile); - if (! isc_file_exists(ns_g_keyfile)) - return (ISC_R_FILENOTFOUND); - - CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); - CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); - CHECK(cfg_map_get(config, "key", &key)); - - keyid = isc_mem_get(mctx, sizeof(*keyid)); - if (keyid == NULL) - CHECK(ISC_R_NOMEMORY); - keyid->keyname = isc_mem_strdup(mctx, - cfg_obj_asstring(cfg_map_getname(key))); - keyid->secret.base = NULL; - keyid->secret.length = 0; - keyid->algorithm = DST_ALG_UNKNOWN; - ISC_LINK_INIT(keyid, link); - if (keyid->keyname == NULL) - CHECK(ISC_R_NOMEMORY); - - CHECK(bind9_check_key(key, ns_g_lctx)); - - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm2(algstr, NULL, - &algtype, NULL) != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel", - algstr, keyid->keyname); - goto cleanup; - } - - keyid->algorithm = algtype; - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on command channel: %s", - keyid->keyname, isc_result_totext(result)); - goto cleanup; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - CHECK(ISC_R_NOMEMORY); - } - memmove(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - ISC_LIST_APPEND(*keyids, keyid, link); - keyid = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (keyid != NULL) - free_controlkey(keyid, mctx); - if (config != NULL) - cfg_obj_destroy(pctx, &config); - if (pctx != NULL) - cfg_parser_destroy(&pctx); - return (result); -} - -/* - * Ensures that both '*global_keylistp' and '*control_keylistp' are - * valid or both are NULL. - */ -static void -get_key_info(const cfg_obj_t *config, const cfg_obj_t *control, - const cfg_obj_t **global_keylistp, - const cfg_obj_t **control_keylistp) -{ - isc_result_t result; - const cfg_obj_t *control_keylist = NULL; - const cfg_obj_t *global_keylist = NULL; - - REQUIRE(global_keylistp != NULL && *global_keylistp == NULL); - REQUIRE(control_keylistp != NULL && *control_keylistp == NULL); - - control_keylist = cfg_tuple_get(control, "keys"); - - if (!cfg_obj_isvoid(control_keylist) && - cfg_list_first(control_keylist) != NULL) { - result = cfg_map_get(config, "key", &global_keylist); - - if (result == ISC_R_SUCCESS) { - *global_keylistp = global_keylist; - *control_keylistp = control_keylist; - } - } -} - -static void -update_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - controlkeylist_t keys; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(cp->listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * There is already a listener for this sockaddr. - * Update the access list and key information. - * - * First try to deal with the key situation. There are a few - * possibilities: - * (a) It had an explicit keylist and still has an explicit keylist. - * (b) It had an automagic key and now has an explicit keylist. - * (c) It had an explicit keylist and now needs an automagic key. - * (d) It has an automagic key and still needs the automagic key. - * - * (c) and (d) are the annoying ones. The caller needs to know - * that it should use the automagic configuration for key information - * in place of the named.conf configuration. - * - * XXXDCL There is one other hazard that has not been dealt with, - * the problem that if a key change is being caused by a control - * channel reload, then the response will be with the new key - * and not able to be decrypted by the client. - */ - if (control != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - INSIST(global_keylist != NULL); - - ISC_LIST_INIT(keys); - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, &keys); - if (result == ISC_R_SUCCESS) { - free_controlkeylist(&listener->keys, listener->mctx); - listener->keys = keys; - register_keys(control, global_keylist, &listener->keys, - listener->mctx, socktext); - } - } else { - free_controlkeylist(&listener->keys, listener->mctx); - result = get_rndckey(listener->mctx, &listener->keys); - } - - if (result != ISC_R_SUCCESS && global_keylist != NULL) { - /* - * This message might be a little misleading since the - * "new keys" might in fact be identical to the old ones, - * but tracking whether they are identical just for the - * sake of avoiding this message would be too much trouble. - */ - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - /* - * Now, keep the old access list unless a new one can be made. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else { - result = dns_acl_any(listener->mctx, &new_acl); - } - - if (control != NULL) { - const cfg_obj_t *readonly; - - readonly = cfg_tuple_get(control, "read-only"); - if (!cfg_obj_isvoid(readonly)) - listener->readonly = cfg_obj_asboolean(readonly); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - /* XXXDCL say the old acl is still used? */ - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - uint32_t perm, owner, group; - perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); - owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); - group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); - result = ISC_R_SUCCESS; - if (listener->perm != perm || listener->owner != owner || - listener->group != group) - result = isc_socket_permunix(&listener->address, perm, - owner, group); - if (result == ISC_R_SUCCESS) { - listener->perm = perm; - listener->owner = owner; - listener->group = group; - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't update ownership/permission for " - "command channel %s", socktext); - } - - *listenerp = listener; -} - -static void -add_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - isc_mem_t *mctx = cp->server->mctx; - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - listener = isc_mem_get(mctx, sizeof(*listener)); - if (listener == NULL) - result = ISC_R_NOMEMORY; - - if (result == ISC_R_SUCCESS) { - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - listener->controls = cp; - listener->task = cp->server->task; - listener->address = *addr; - listener->sock = NULL; - listener->listening = false; - listener->exiting = false; - listener->acl = NULL; - listener->type = type; - listener->perm = 0; - listener->owner = 0; - listener->group = 0; - listener->readonly = false; - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->keys); - ISC_LIST_INIT(listener->connections); - - /* - * Make the acl. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, mctx, 0, - &new_acl); - } else { - result = dns_acl_any(mctx, &new_acl); - } - } - - if ((result == ISC_R_SUCCESS) && (control != NULL)) { - const cfg_obj_t *readonly; - - readonly = cfg_tuple_get(control, "read-only"); - if (!cfg_obj_isvoid(readonly)) - listener->readonly = cfg_obj_asboolean(readonly); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - if (config != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, - &listener->keys); - if (result == ISC_R_SUCCESS) - register_keys(control, global_keylist, - &listener->keys, - listener->mctx, socktext); - } else - result = get_rndckey(mctx, &listener->keys); - - if (result != ISC_R_SUCCESS && control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - if (result == ISC_R_SUCCESS) { - int pf = isc_sockaddr_pf(&listener->address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || -#ifdef ISC_PLATFORM_HAVESYSUNH - (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) || -#endif - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - result = ISC_R_FAMILYNOSUPPORT; - } - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, false); - - if (result == ISC_R_SUCCESS) - result = isc_socket_create(ns_g_socketmgr, - isc_sockaddr_pf(&listener->address), - type, &listener->sock); - if (result == ISC_R_SUCCESS) - isc_socket_setname(listener->sock, "control", NULL); - -#ifndef ISC_ALLOW_MAPPED - if (result == ISC_R_SUCCESS) - isc_socket_ipv6only(listener->sock, true); -#endif - - if (result == ISC_R_SUCCESS) - result = isc_socket_bind(listener->sock, &listener->address, - ISC_SOCKET_REUSEADDRESS); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, - "perm")); - listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, - "owner")); - listener->group = cfg_obj_asuint32(cfg_tuple_get(control, - "group")); - result = isc_socket_permunix(&listener->address, listener->perm, - listener->owner, listener->group); - } - if (result == ISC_R_SUCCESS) - result = control_listen(listener); - - if (result == ISC_R_SUCCESS) - result = control_accept(listener); - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "command channel listening on %s", socktext); - *listenerp = listener; - - } else { - if (listener != NULL) { - listener->exiting = true; - free_listener(listener); - } - - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - - *listenerp = NULL; - } - - /* XXXDCL return error results? fail hard? */ -} - -isc_result_t -ns_controls_configure(ns_controls_t *cp, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx) -{ - controllistener_t *listener; - controllistenerlist_t new_listeners; - const cfg_obj_t *controlslist = NULL; - const cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'controls' statements. - */ - (void)cfg_map_get(config, "controls", &controlslist); - - /* - * Run through the new control channel list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (controlslist != NULL) { - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *inetcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "inet", &inetcontrols); - if (inetcontrols == NULL) - continue; - - for (element2 = cfg_list_first(inetcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *obj; - isc_sockaddr_t addr; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - obj = cfg_tuple_get(control, "address"); - addr = *cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, - NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel %s", - socktext); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *unixcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "unix", &unixcontrols); - if (unixcontrols == NULL) - continue; - - for (element2 = cfg_list_first(unixcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *path; - isc_sockaddr_t addr; - isc_result_t result; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - path = cfg_tuple_get(control, "path"); - result = isc_sockaddr_frompath(&addr, - cfg_obj_asstring(path)); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "control channel '%s': %s", - cfg_obj_asstring(path), - isc_result_totext(result)); - continue; - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel '%s'", - cfg_obj_asstring(path)); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - } else { - int i; - - for (i = 0; i < 2; i++) { - isc_sockaddr_t addr; - - if (i == 0) { - struct in_addr localhost; - - if (isc_net_probeipv4() != ISC_R_SUCCESS) - continue; - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&addr, &localhost, 0); - } else { - if (isc_net_probeipv6() != ISC_R_SUCCESS) - continue; - isc_sockaddr_fromin6(&addr, - &in6addr_loopback, 0); - } - isc_sockaddr_setport(&addr, NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - - update_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - - /* - * ns_control_shutdown() will stop whatever is on the global - * listeners list, which currently only has whatever sockaddrs - * were in the previous configuration (if any) that do not - * remain in the current configuration. - */ - controls_shutdown(cp); - - /* - * Put all of the valid listeners on the listeners list. - * Anything already on listeners in the process of shutting - * down will be taken care of by listen_done(). - */ - ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { - isc_mem_t *mctx = server->mctx; - isc_result_t result; - ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); - - if (controls == NULL) { - return (ISC_R_NOMEMORY); - } - - *controls = (ns_controls_t){ - .server = server, - }; - - ISC_LIST_INIT(controls->listeners); - - result = isc_mutex_init(&controls->symtab_lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - - LOCK(&controls->symtab_lock); - result = isccc_cc_createsymtab(&controls->symtab); - UNLOCK(&controls->symtab_lock); - - if (result != ISC_R_SUCCESS) { - isc_mutex_destroy(&controls->symtab_lock); - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - *ctrlsp = controls; - return (ISC_R_SUCCESS); -} - -void -ns_controls_destroy(ns_controls_t **ctrlsp) { - ns_controls_t *controls = *ctrlsp; - - REQUIRE(ISC_LIST_EMPTY(controls->listeners)); - - LOCK(&controls->symtab_lock); - isccc_symtab_destroy(&controls->symtab); - UNLOCK(&controls->symtab_lock); - isc_mutex_destroy(&controls->symtab_lock); - isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); - *ctrlsp = NULL; -} diff --git a/bin/named-sdb/convertxsl.pl b/bin/named-sdb/convertxsl.pl deleted file mode 100755 index 092bc01..0000000 --- a/bin/named-sdb/convertxsl.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -use strict; -use warnings; - -my $rev = '$Id: convertxsl.pl,v 1.14 2008/07/17 23:43:26 jinmei Exp $'; -$rev =~ s/\$//g; -$rev =~ s/,v//g; -$rev =~ s/Id: //; - -my $xsl = "unknown"; -my $lines = ''; - -while (<>) { - chomp; - # pickout the id for comment. - $xsl = $_ if (//); - # convert Id string to a form not recognisable by cvs. - $_ =~ s///; - s/[\ \t]+/ /g; - s/\>\ \\.*//; -$xsl =~ s/,v//; - -print "/*\n * Generated by $rev \n * From $xsl\n */\n"; -print 'static char xslmsg[] =',"\n"; -print $lines; - -print ';', "\n"; diff --git a/bin/named-sdb/dirdb.c b/bin/named-sdb/dirdb.c deleted file mode 100644 index 9a23e09..0000000 --- a/bin/named-sdb/dirdb.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* - * A simple database driver that returns basic information about - * files and directories in the Unix file system as DNS data. - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#include "dirdb.h" - -static dns_sdbimplementation_t *dirdb = NULL; - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) return (result); \ - } while (0) - -#define CHECKN(op) \ - do { n = (op); \ - if (n < 0) return (ISC_R_FAILURE); \ - } while (0) - - -/* - * This database operates on relative names. - * - * Any name will be interpreted as a pathname offset from the directory - * specified in the configuration file. - */ -#ifdef DNS_CLIENTINFO_VERSION -static isc_result_t -dirdb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -#else -static isc_result_t -dirdb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -#endif /* DNS_CLIENTINFO_VERSION */ -{ - char filename[255]; - char filename2[255]; - char buf[1024]; - struct stat statbuf; - isc_result_t result; - int n; - - UNUSED(zone); - UNUSED(dbdata); -#ifdef DNS_CLIENTINFO_VERSION - UNUSED(methods); - UNUSED(clientinfo); -#endif /* DNS_CLIENTINFO_VERSION */ - - if (strcmp(name, "@") == 0) - snprintf(filename, sizeof(filename), "%s", (char *)dbdata); - else - snprintf(filename, sizeof(filename), "%s/%s", - (char *)dbdata, name); - CHECKN(lstat(filename, &statbuf)); - - if (S_ISDIR(statbuf.st_mode)) - CHECK(dns_sdb_putrr(lookup, "txt", 3600, "dir")); - else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) { - CHECKN(snprintf(buf, sizeof(buf), - "\"%sdev\" \"major %d\" \"minor %d\"", - S_ISCHR(statbuf.st_mode) ? "chr" : "blk", - major(statbuf.st_rdev), - minor(statbuf.st_rdev))); - CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); - } else if (S_ISFIFO(statbuf.st_mode)) - CHECK(dns_sdb_putrr(lookup, "txt", 3600, "pipe")); - else if (S_ISSOCK(statbuf.st_mode)) - CHECK(dns_sdb_putrr(lookup, "txt", 3600, "socket")); - else if (S_ISLNK(statbuf.st_mode)) { - CHECKN(readlink(filename, filename2, sizeof(filename2) - 1)); - buf[n] = 0; - CHECKN(snprintf(buf, sizeof(buf), "\"symlink\" \"%s\"", - filename2)); - CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); - } else if (!S_ISREG(statbuf.st_mode)) - CHECK(dns_sdb_putrr(lookup, "txt", 3600, "unknown")); - else { - CHECKN(snprintf(buf, sizeof(buf), "\"file\" \"size = %u\"", - (unsigned int)statbuf.st_size)); - CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); - } - - return (ISC_R_SUCCESS); -} - -/* - * lookup () does not return SOA or NS records, so authority() must be defined. - */ -static isc_result_t -dirdb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { - isc_result_t result; - - UNUSED(zone); - UNUSED(dbdata); - - result = dns_sdb_putsoa(lookup, "ns", "hostmaster", 0); - INSIST(result == ISC_R_SUCCESS); - result = dns_sdb_putrr(lookup, "ns", 86400, "ns1"); - INSIST(result == ISC_R_SUCCESS); - result = dns_sdb_putrr(lookup, "ns", 86400, "ns2"); - INSIST(result == ISC_R_SUCCESS); - return (ISC_R_SUCCESS); -} - -/* - * Each database stores the top-level directory as the dbdata opaque - * object. The create() function allocates it. argv[0] holds the top - * level directory. - */ -static isc_result_t -dirdb_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - UNUSED(zone); - UNUSED(driverdata); - - if (argc < 1) - return (ISC_R_FAILURE); - *dbdata = isc_mem_strdup((isc_mem_t *)driverdata, argv[0]); - if (*dbdata == NULL) - return (ISC_R_NOMEMORY); - return (ISC_R_SUCCESS); -} - -/* - * The destroy() function frees the memory allocated by create(). - */ -static void -dirdb_destroy(const char *zone, void *driverdata, void **dbdata) { - UNUSED(zone); - UNUSED(driverdata); - isc_mem_free((isc_mem_t *)driverdata, *dbdata); -} - -/* - * This zone does not support zone transfer, so allnodes() is NULL. - */ -static dns_sdbmethods_t dirdb_methods = { - dirdb_lookup, - dirdb_authority, - NULL, /* allnodes */ - dirdb_create, - dirdb_destroy, - NULL /* lookup2 */ -}; - -/* - * Wrapper around dns_sdb_register(). Note that the first ns_g_mctx is - * being passed as the "driverdata" parameter, so that will it will be - * passed to create() and destroy(). - */ -isc_result_t -dirdb_init(void) { - unsigned int flags; - flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_THREADSAFE; - return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags, - ns_g_mctx, &dirdb)); -} - -/* - * Wrapper around dns_sdb_unregister(). - */ -void -dirdb_clear(void) { - if (dirdb != NULL) - dns_sdb_unregister(&dirdb); -} diff --git a/bin/named-sdb/dirdb.h b/bin/named-sdb/dirdb.h deleted file mode 100644 index 3f0421f..0000000 --- a/bin/named-sdb/dirdb.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -isc_result_t dirdb_init(void); - -void dirdb_clear(void); - diff --git a/bin/named-sdb/fuzz.c b/bin/named-sdb/fuzz.c deleted file mode 100644 index 0d6165f..0000000 --- a/bin/named-sdb/fuzz.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include "config.h" - -#include -#include - -#include - -#ifdef ENABLE_AFL -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifndef __AFL_LOOP -#error To use American Fuzzy Lop you have to set CC to afl-clang-fast!!! -#endif - -/* - * We are using pthreads directly because we might be using it with unthreaded - * version of BIND, where all thread functions are mocks. Since AFL for now only - * works on Linux it's not a problem. - */ -static pthread_cond_t cond; -static pthread_mutex_t mutex; -static bool ready; - - -static void * -fuzz_main_client(void *arg) { - char *host; - char *port; - struct sockaddr_in servaddr; - int sockfd; - int loop; - void *buf; - - UNUSED(arg); - - /* - * Parse named -A argument in the "address:port" syntax. Due to - * the syntax used, this only supports IPv4 addresses. - */ - - host = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(host != NULL); - port = strchr(host, ':'); - RUNTIME_CHECK(port != NULL); - *port = 0; - ++port; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, host, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(port)); - - free(host); - - /* Wait for named to start. */ - while (!ns_g_run_done) { - usleep(10000); - } - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(sockfd != -1); - - buf = malloc(65536); - RUNTIME_CHECK(buf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - - length = read(0, buf, 65536); - if (length <= 0) { - usleep(1000000); - continue; - } - - if (length > 4096) { - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, - false); - isc_app_shutdown(); - return (NULL); - } - raise(SIGSTOP); - continue; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - - sent = sendto(sockfd, buf, length, 0, - (struct sockaddr *) &servaddr, sizeof(servaddr)); - RUNTIME_CHECK(sent == length); - - /* unclog */ - recvfrom(sockfd, buf, 65536, MSG_DONTWAIT, NULL, NULL); - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == ISC_R_SUCCESS); - } - - free(buf); - close(sockfd); - - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - return (NULL); -} - -static void * -fuzz_main_resolver(void *arg) { - char *shost, *sport, *rhost, *rport; - /* Query for A? aaaaaaaaaa.example. */ - char respacket[] = - "\0\0\1 \0\1\0\0\0\0\0\0\naaaaaaaaaa\7example\0\0\1\0\1"; - struct sockaddr_in servaddr, recaddr, recvaddr; - int sockfd; - int listenfd; - int loop; - char *buf, *rbuf; - - UNUSED(arg); - - /* - * Parse named -A argument in the "laddress:sport:raddress:rport" - * syntax. Due to the syntax used, this only supports IPv4 addresses. - */ - - shost = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(shost != NULL); - sport = strchr(shost, ':'); - RUNTIME_CHECK(sport != NULL); - *sport = 0; - sport++; - rhost = strchr(sport, ':'); - RUNTIME_CHECK(rhost != NULL); - *rhost = 0; - rhost++; - rport = strchr(rhost, ':'); - RUNTIME_CHECK(rport != NULL); - *rport = 0; - rport++; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, shost, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(sport)); - - memset(&recaddr, 0, sizeof (recaddr)); - recaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, rhost, &recaddr.sin_addr) == 1); - recaddr.sin_port = htons(atoi(rport)); - - free(shost); - - /* Wait for named to start */ - while (!ns_g_run_done) { - usleep(10000); - } - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(sockfd != -1); - - listenfd = socket(AF_INET, SOCK_DGRAM, 0); - RUNTIME_CHECK(listenfd != -1); - RUNTIME_CHECK(bind(listenfd, (struct sockaddr *)&recaddr, - sizeof(struct sockaddr_in)) == 0); - - buf = malloc(65536); - rbuf = malloc(65536); - RUNTIME_CHECK(buf != NULL); - RUNTIME_CHECK(rbuf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - memset(buf, 0, 16); - length = read(0, buf, 65536); - if (length <= 0) { - usleep(1000000); - continue; - } - - if (length > 4096) { - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, - false); - isc_app_shutdown(); - return (NULL); - } - raise(SIGSTOP); - continue; - } - - if (length < 16) { - length = 16; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - /* Randomize query ID. */ - int id = random(); - respacket[0] = id >> 8; - respacket[1] = id & 0xff; - - /* flush */ - socklen_t socklen = sizeof(recvaddr); - sent = recvfrom(listenfd, rbuf, 65536, MSG_DONTWAIT, - (struct sockaddr *) &recvaddr, &socklen); - - sent = sendto(sockfd, respacket, sizeof(respacket), 0, - (struct sockaddr *) &servaddr, sizeof(servaddr)); - RUNTIME_CHECK(sent == sizeof(respacket)); - - socklen = sizeof(recvaddr); - sent = recvfrom(listenfd, rbuf, 65536, 0, - (struct sockaddr *) &recvaddr, &socklen); - RUNTIME_CHECK(sent > 0); - - /* Copy QID and set QR so that response is always processed. */ - buf[0] = rbuf[0]; - buf[1] = rbuf[1]; - buf[2] |= 0x80; - - sent = sendto(listenfd, buf, length, 0, - (struct sockaddr *) &recvaddr, sizeof(recvaddr)); - RUNTIME_CHECK(sent == length); - - /* We might get additional questions here (e.g. for CNAME). */ - for (;;) { - fd_set fds; - struct timeval tv; - int rv; - int max; - - FD_ZERO(&fds); - FD_SET(listenfd, &fds); - FD_SET(sockfd, &fds); - tv.tv_sec = 10; - tv.tv_usec = 0; - max = (listenfd > sockfd ? listenfd : sockfd)+1; - - rv = select(max, &fds, NULL, NULL, &tv); - RUNTIME_CHECK(rv > 0); - - if (FD_ISSET(sockfd, &fds)) { - /* It's the reply, we're done. */ - recvfrom(sockfd, buf, 65536, 0, NULL, NULL); - break; - } - - /* - * We've got additional question (eg. cname chain) - * We are bouncing it - setting QR flag and NOERROR - * rcode and sending it back. - */ - - length = recvfrom(listenfd, buf, 65536, 0, - (struct sockaddr *) &recvaddr, &socklen); - buf[2] |= 0x80; - buf[3] &= 0xF0; - sent = sendto(listenfd, buf, length, 0, - (struct sockaddr *) &recvaddr, - sizeof(recvaddr)); - RUNTIME_CHECK(sent == length); - } - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == 0); - } - - free(buf); - free(rbuf); - close(sockfd); - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - /* - * It's here just for the signature, that's how AFL detects if it's - * a 'persistent mode' binary. - */ - __AFL_LOOP(0); - - return (NULL); -} - -static void * -fuzz_main_tcp(void *arg) { - char *host; - char *port; - struct sockaddr_in servaddr; - int sockfd; - char *buf; - int loop; - - UNUSED(arg); - - /* - * Parse named -A argument in the "address:port" syntax. Due to - * the syntax used, this only supports IPv4 addresses. - */ - - host = strdup(ns_g_fuzz_named_addr); - RUNTIME_CHECK(host != NULL); - port = strchr(host, ':'); - RUNTIME_CHECK(port != NULL); - *port = 0; - ++port; - - memset(&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - RUNTIME_CHECK(inet_pton(AF_INET, host, &servaddr.sin_addr) == 1); - servaddr.sin_port = htons(atoi(port)); - - free(host); - - /* Wait for named to start */ - while (!ns_g_run_done) { - usleep(10000); - } - - buf = malloc(65539); - RUNTIME_CHECK(buf != NULL); - - loop = 100000; - while (loop--) { - ssize_t length; - - if (ns_g_fuzz_type == ns_fuzz_tcpclient) { - /* - * To fuzz TCP client we have to put length at - * the start of packet. - */ - length = read(0, buf+2, 65535); - buf[0] = length >> 8; - buf[1] = length & 0xff; - length += 2; - } else { - length = read(0, buf, 65535); - } - if (length <= 0) { - usleep(1000000); - continue; - } - if (ns_g_fuzz_type == ns_fuzz_http) { - /* - * This guarantees that the request will be processed. - */ - buf[length++]='\r'; - buf[length++]='\n'; - buf[length++]='\r'; - buf[length++]='\n'; - } - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == ISC_R_SUCCESS); - - ready = false; - - ssize_t sent; - int yes = 1; - int r; - sockfd = socket(AF_INET, SOCK_STREAM, 0); - - RUNTIME_CHECK(sockfd != -1); - RUNTIME_CHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - &yes, sizeof(int)) == 0); - - do { - r = connect(sockfd, (struct sockaddr*)&servaddr, - sizeof(servaddr)); - } while (r != 0); - - sent = write(sockfd, buf, length); - RUNTIME_CHECK(sent == length); - close(sockfd); - - /* unclog */ - recvfrom(sockfd, buf, 65537, MSG_DONTWAIT, NULL, NULL); - - while (!ready) - pthread_cond_wait(&cond, &mutex); - - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == ISC_R_SUCCESS); - } - - free(buf); - close(sockfd); - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - - return (NULL); -} - -#endif /* ENABLE_AFL */ - -void -named_fuzz_notify(void) { -#ifdef ENABLE_AFL - if (getenv("AFL_CMIN")) { - ns_server_flushonshutdown(ns_g_server, false); - isc_app_shutdown(); - return; - } - - raise(SIGSTOP); - - RUNTIME_CHECK(pthread_mutex_lock(&mutex) == 0); - - ready = true; - - RUNTIME_CHECK(pthread_cond_signal(&cond) == 0); - RUNTIME_CHECK(pthread_mutex_unlock(&mutex) == 0); -#endif /* ENABLE_AFL */ -} - -void -named_fuzz_setup(void) { -#ifdef ENABLE_AFL - if (getenv("__AFL_PERSISTENT") || getenv("AFL_CMIN")) { - pthread_t thread; - void *(fn) = NULL; - - switch (ns_g_fuzz_type) { - case ns_fuzz_client: - fn = fuzz_main_client; - break; - - case ns_fuzz_http: - case ns_fuzz_tcpclient: - case ns_fuzz_rndc: - fn = fuzz_main_tcp; - break; - case ns_fuzz_resolver: - fn = fuzz_main_resolver; - break; - default: - RUNTIME_CHECK(fn != NULL); - } - - RUNTIME_CHECK(pthread_mutex_init(&mutex, NULL) == 0); - RUNTIME_CHECK(pthread_cond_init(&cond, NULL) == 0); - RUNTIME_CHECK(pthread_create(&thread, NULL, fn, NULL) == 0); - } -#endif /* ENABLE_AFL */ -} diff --git a/bin/named-sdb/geoip.c b/bin/named-sdb/geoip.c deleted file mode 100644 index 02db0de..0000000 --- a/bin/named-sdb/geoip.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#if defined(HAVE_GEOIP2) -#include -#elif defined(HAVE_GEOIP) -#include -#include -#endif - -#include -#include -#include - -#include - -#include -#include - -static dns_geoip_databases_t geoip_table; - -#if defined(HAVE_GEOIP) -static void -init_geoip_db(void **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, - GeoIPOptions method, const char *name) -{ - char *info; - GeoIP *db; - - REQUIRE(dbp != NULL); - - db = (GeoIP *)*dbp; - - if (db != NULL) { - GeoIP_delete(db); - db = *dbp = NULL; - } - - if (! GeoIP_db_avail(edition)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "GeoIP %s (type %d) DB not available", name, edition); - goto fail; - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "initializing GeoIP %s (type %d) DB", name, edition); - - db = GeoIP_open_type(edition, method); - if (db == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to initialize GeoIP %s (type %d) DB%s", - name, edition, fallback == 0 - ? "geoip matches using this database will fail" : ""); - goto fail; - } - - info = GeoIP_database_info(db); - if (info != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s", info); - free(info); - } - - *dbp = db; - return; - - fail: - if (fallback != 0) { - init_geoip_db(dbp, fallback, 0, method, name); - } - -} -#elif defined(HAVE_GEOIP2) -static MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain; - -static MMDB_s * -open_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) { - char pathbuf[PATH_MAX]; - unsigned int n; - int ret; - - n = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile); - if (n >= sizeof(pathbuf)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "GeoIP2 database '%s/%s': path too long", - dir, dbfile); - return (NULL); - } - - ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb); - if (ret == MMDB_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "opened GeoIP2 database '%s'", pathbuf); - return (mmdb); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "unable to open GeoIP2 database '%s' (status %d)", - pathbuf, ret); - - return (NULL); -} -#endif /* HAVE_GEOIP2 */ - - -void -ns_geoip_init(void) { -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - if (ns_g_geoip == NULL) { - ns_g_geoip = &geoip_table; - } -#if defined(HAVE_GEOIP) - GeoIP_cleanup(); -#endif -#else - return; -#endif -} - -void -ns_geoip_load(char *dir) { -#if defined(HAVE_GEOIP2) - REQUIRE(dir != NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "looking for GeoIP2 databases in '%s'", dir); - - ns_g_geoip->country = open_geoip2(dir, "GeoIP2-Country.mmdb", - &geoip_country); - if (ns_g_geoip->country == NULL) { - ns_g_geoip->country = open_geoip2(dir, - "GeoLite2-Country.mmdb", - &geoip_country); - } - - ns_g_geoip->city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city); - if (ns_g_geoip->city == NULL) { - ns_g_geoip->city = open_geoip2(dir, "GeoLite2-City.mmdb", - &geoip_city); - } - - ns_g_geoip->as = open_geoip2(dir, "GeoIP2-ASN.mmdb", &geoip_as); - if (ns_g_geoip->as == NULL) { - ns_g_geoip->as = open_geoip2(dir, "GeoLite2-ASN.mmdb", - &geoip_as); - } - - ns_g_geoip->isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp); - ns_g_geoip->domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", - &geoip_domain); -#elif defined(HAVE_GEOIP) - GeoIPOptions method; - -#ifdef _WIN32 - method = GEOIP_STANDARD; -#else - method = GEOIP_MMAP_CACHE; -#endif - - ns_geoip_init(); - if (dir != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using \"%s\" as GeoIP directory", dir); - GeoIP_setup_custom_directory(dir); - } - - init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION, 0, - method, "Country (IPv4)"); -#ifdef HAVE_GEOIP_V6 - init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6, 0, - method, "Country (IPv6)"); -#endif - - init_geoip_db(&ns_g_geoip->city_v4, GEOIP_CITY_EDITION_REV1, - GEOIP_CITY_EDITION_REV0, method, "City (IPv4)"); -#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6) - init_geoip_db(&ns_g_geoip->city_v6, GEOIP_CITY_EDITION_REV1_V6, - GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)"); -#endif - - init_geoip_db(&ns_g_geoip->region, GEOIP_REGION_EDITION_REV1, - GEOIP_REGION_EDITION_REV0, method, "Region"); - - init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION, 0, - method, "ISP"); - init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION, 0, - method, "Org"); - init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION, 0, - method, "AS"); - init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION, 0, - method, "Domain"); - init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION, 0, - method, "NetSpeed"); -#else - UNUSED(dir); - - return; -#endif -} - -void -ns_geoip_shutdown(void) { -#ifdef HAVE_GEOIP2 - if (ns_g_geoip->country != NULL) { - MMDB_close(ns_g_geoip->country); - ns_g_geoip->country = NULL; - } - if (ns_g_geoip->city != NULL) { - MMDB_close(ns_g_geoip->city); - ns_g_geoip->city = NULL; - } - if (ns_g_geoip->as != NULL) { - MMDB_close(ns_g_geoip->as); - ns_g_geoip->as = NULL; - } - if (ns_g_geoip->isp != NULL) { - MMDB_close(ns_g_geoip->isp); - ns_g_geoip->isp = NULL; - } - if (ns_g_geoip->domain != NULL) { - MMDB_close(ns_g_geoip->domain); - ns_g_geoip->domain = NULL; - } -#endif /* HAVE_GEOIP2 */ -} diff --git a/bin/named-sdb/include/dlz/dlz_dlopen_driver.h b/bin/named-sdb/include/dlz/dlz_dlopen_driver.h deleted file mode 100644 index 8dcc4b4..0000000 --- a/bin/named-sdb/include/dlz/dlz_dlopen_driver.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DLZ_DLOPEN_DRIVER_H -#define DLZ_DLOPEN_DRIVER_H - -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx); - -void -dlz_dlopen_clear(void); -#endif diff --git a/bin/named-sdb/include/named/builtin.h b/bin/named-sdb/include/named/builtin.h deleted file mode 100644 index 240132f..0000000 --- a/bin/named-sdb/include/named/builtin.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_BUILTIN_H -#define NAMED_BUILTIN_H 1 - -/*! \file */ - -#include - -isc_result_t ns_builtin_init(void); - -void ns_builtin_deinit(void); - -#endif /* NAMED_BUILTIN_H */ diff --git a/bin/named-sdb/include/named/client.h b/bin/named-sdb/include/named/client.h deleted file mode 100644 index 09839bc..0000000 --- a/bin/named-sdb/include/named/client.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_CLIENT_H -#define NAMED_CLIENT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * This module defines two objects, ns_client_t and ns_clientmgr_t. - * - * An ns_client_t object handles incoming DNS requests from clients - * on a given network interface. - * - * Each ns_client_t object can handle only one TCP connection or UDP - * request at a time. Therefore, several ns_client_t objects are - * typically created to serve each network interface, e.g., one - * for handling TCP requests and a few (one per CPU) for handling - * UDP requests. - * - * Incoming requests are classified as queries, zone transfer - * requests, update requests, notify requests, etc, and handed off - * to the appropriate request handler. When the request has been - * fully handled (which can be much later), the ns_client_t must be - * notified of this by calling one of the following functions - * exactly once in the context of its task: - * \code - * ns_client_send() (sending a non-error response) - * ns_client_sendraw() (sending a raw response) - * ns_client_error() (sending an error response) - * ns_client_next() (sending no response) - *\endcode - * This will release any resources used by the request and - * and allow the ns_client_t to listen for the next request. - * - * A ns_clientmgr_t manages a number of ns_client_t objects. - * New ns_client_t objects are created by calling - * ns_clientmgr_createclients(). They are destroyed by - * destroying their manager. - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*** - *** Types - ***/ - -/*% reference-counted TCP connection object */ -typedef struct ns_tcpconn { - isc_refcount_t clients; /* Number of clients using - * this connection. Conn can - * be freed if goes to 0 - */ - isc_quota_t *tcpquota; - bool pipelined; -} ns_tcpconn_t; - -/*% nameserver client structure */ -struct ns_client { - unsigned int magic; - isc_mem_t * mctx; - ns_clientmgr_t * manager; - int state; - int newstate; - int naccepts; - int nreads; - int nsends; - int nrecvs; - int nupdates; - int nctls; - int references; - bool tcpactive; - bool needshutdown; /* - * Used by clienttest to get - * the client to go from - * inactive to free state - * by shutting down the - * client's task. - */ - unsigned int attributes; - isc_task_t * task; - dns_view_t * view; - dns_dispatch_t * dispatch; - isc_socket_t * udpsocket; - isc_socket_t * tcplistener; - isc_socket_t * tcpsocket; - unsigned char * tcpbuf; - dns_tcpmsg_t tcpmsg; - bool tcpmsg_valid; - isc_timer_t * timer; - isc_timer_t * delaytimer; - bool timerset; - dns_message_t * message; - isc_socketevent_t * sendevent; - isc_socketevent_t * recvevent; - unsigned char * recvbuf; - dns_rdataset_t * opt; - uint16_t udpsize; - uint16_t extflags; - int16_t ednsversion; /* -1 noedns */ - void (*next)(ns_client_t *); - void (*shutdown)(void *arg, isc_result_t result); - void *shutdown_arg; - ns_query_t query; - isc_time_t requesttime; - isc_stdtime_t now; - isc_time_t tnow; - dns_name_t signername; /*%< [T]SIG key name */ - dns_name_t *signer; /*%< NULL if not valid sig */ - bool mortal; /*%< Die after handling request */ - ns_tcpconn_t *tcpconn; - isc_quota_t *recursionquota; - ns_interface_t *interface; - - isc_sockaddr_t peeraddr; - bool peeraddr_valid; - isc_netaddr_t destaddr; - isc_sockaddr_t destsockaddr; - - isc_netaddr_t ecs_addr; /*%< EDNS client subnet */ - uint8_t ecs_addrlen; - uint8_t ecs_scope; - - struct in6_pktinfo pktinfo; - isc_dscp_t dscp; - isc_event_t ctlevent; -#ifdef ALLOW_FILTER_AAAA - dns_aaaa_t filter_aaaa; -#endif - /*% - * Information about recent FORMERR response(s), for - * FORMERR loop avoidance. This is separate for each - * client object rather than global only to avoid - * the need for locking. - */ - struct { - isc_sockaddr_t addr; - isc_stdtime_t time; - dns_messageid_t id; - } formerrcache; - - ISC_LINK(ns_client_t) link; - ISC_LINK(ns_client_t) rlink; - ISC_QLINK(ns_client_t) ilink; - unsigned char cookie[8]; - uint32_t expire; - unsigned char *keytag; - uint16_t keytag_len; -}; - -typedef ISC_QUEUE(ns_client_t) client_queue_t; -typedef ISC_LIST(ns_client_t) client_list_t; - -#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') -#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) - -#define NS_CLIENTATTR_TCP 0x0001 -#define NS_CLIENTATTR_RA 0x0002 /*%< Client gets recursive service */ -#define NS_CLIENTATTR_PKTINFO 0x0004 /*%< pktinfo is valid */ -#define NS_CLIENTATTR_MULTICAST 0x0008 /*%< recv'd from multicast */ -#define NS_CLIENTATTR_WANTDNSSEC 0x0010 /*%< include dnssec records */ -#define NS_CLIENTATTR_WANTNSID 0x0020 /*%< include nameserver ID */ -#ifdef ALLOW_FILTER_AAAA -#define NS_CLIENTATTR_FILTER_AAAA 0x0040 /*%< suppress AAAAs */ -#define NS_CLIENTATTR_FILTER_AAAA_RC 0x0080 /*%< recursing for A against AAAA */ -#endif -#define NS_CLIENTATTR_WANTAD 0x0100 /*%< want AD in response if possible */ -#define NS_CLIENTATTR_WANTCOOKIE 0x0200 /*%< return a COOKIE */ -#define NS_CLIENTATTR_HAVECOOKIE 0x0400 /*%< has a valid COOKIE */ -#define NS_CLIENTATTR_WANTEXPIRE 0x0800 /*%< return seconds to expire */ -#define NS_CLIENTATTR_HAVEEXPIRE 0x1000 /*%< return seconds to expire */ -#define NS_CLIENTATTR_WANTOPT 0x2000 /*%< add opt to reply */ -#define NS_CLIENTATTR_HAVEECS 0x4000 /*%< received an ECS option */ - -#define NS_CLIENTATTR_NOSETFC 0x8000 /*%< don't set servfail cache */ - -/* - * Flag to use with the SERVFAIL cache to indicate - * that a query had the CD bit set. - */ -#define NS_FAILCACHE_CD 0x01 - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#define ncr_inc(x) atomic_fetch_add(&(x), (1)) -#define ncr_load(x) atomic_load(&(x)) -#define NS_CLIENT_NCRSTDATOMIC 1 -extern _Atomic(unsigned int) ns_client_requests; -#elif defined(ISC_PLATFORM_HAVEXADD) -#define ncr_inc(x) isc_atomic_xadd((int *)&(x), 1); -#define ncr_load(x) isc_atomic_xadd((int *)&(x), 0); -extern unsigned int ns_client_requests; -#else -#define ncr_inc(x) ((x)++) -#define ncr_load(x) (x) -extern unsigned int ns_client_requests; -#endif - -/*** - *** Functions - ***/ - -/*% - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_send(ns_client_t *client); -/*% - * Finish processing the current client request and - * send client->message as a response. - * \brief - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *msg); -/*% - * Finish processing the current client request and - * send msg as a response using client->message->id for the id. - */ - -void -ns_client_error(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request and return - * an error response to the client. The error response - * will have an RCODE determined by 'result'. - */ - -void -ns_client_next(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request, - * return no response to the client. - */ - -bool -ns_client_shuttingdown(ns_client_t *client); -/*% - * Return true iff the client is currently shutting down. - */ - -void -ns_client_attach(ns_client_t *source, ns_client_t **target); -/*% - * Attach '*targetp' to 'source'. - */ - -void -ns_client_detach(ns_client_t **clientp); -/*% - * Detach '*clientp' from its client. - */ - -isc_result_t -ns_client_replace(ns_client_t *client); -/*% - * Try to replace the current client with a new one, so that the - * current one can go off and do some lengthy work without - * leaving the dispatch/socket without service. - */ - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds); -/*% - * Set a timer in the client to go off in the specified amount of time. - */ - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); -/*% - * Create a client manager. - */ - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp); -/*% - * Destroy a client manager and all ns_client_t objects - * managed by it. - */ - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, bool tcp); -/*% - * Create up to 'n' clients listening on interface 'ifp'. - * If 'tcp' is true, the clients will listen for TCP connections, - * otherwise for UDP requests. - */ - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client); -/*% - * Get the socket address of the client whose request is - * currently being processed. - */ - -isc_sockaddr_t * -ns_client_getdestaddr(ns_client_t *client); -/*%< - * Get the destination address (server) for the request that is - * currently being processed. - */ - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, - dns_acl_t *acl, bool default_allow); - -/*% - * Convenience function for client request ACL checking. - * - * Check the current client request against 'acl'. If 'acl' - * is NULL, allow the request iff 'default_allow' is true. - * If netaddr is NULL, check the ACL against client->peeraddr; - * otherwise check it against netaddr. - * - * Notes: - *\li This is appropriate for checking allow-update, - * allow-query, allow-transfer, etc. It is not appropriate - * for checking the blackhole list because we treat positive - * matches as "allow" and negative matches as "deny"; in - * the case of the blackhole list this would be backwards. - * - * Requires: - *\li 'client' points to a valid client. - *\li 'netaddr' points to a valid address, or is NULL. - *\li 'acl' points to a valid ACL, or is NULL. - * - * Returns: - *\li ISC_R_SUCCESS if the request should be allowed - * \li DNS_R_REFUSED if the request should be denied - *\li No other return values are possible. - */ - -isc_result_t -ns_client_checkacl(ns_client_t *client, - isc_sockaddr_t *sockaddr, - const char *opname, dns_acl_t *acl, - bool default_allow, - int log_level); -/*% - * Like ns_client_checkaclsilent, except the outcome of the check is - * logged at log level 'log_level' if denied, and at debug 3 if approved. - * Log messages will refer to the request as an 'opname' request. - * - * Requires: - *\li 'client' points to a valid client. - *\li 'sockaddr' points to a valid address, or is NULL. - *\li 'acl' points to a valid ACL, or is NULL. - *\li 'opname' points to a null-terminated string. - */ - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len); - -#define NS_CLIENT_ACLMSGSIZE(x) \ - (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ - DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) - -void -ns_client_recursing(ns_client_t *client); -/*% - * Add client to end of th recursing list. - */ - -void -ns_client_killoldestquery(ns_client_t *client); -/*% - * Kill the oldest recursive query (recursing list head). - */ - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); -/*% - * Dump the outstanding recursive queries to 'f'. - */ - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); -/*% - * Replace the qname. - */ - -bool -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - dns_rdataclass_t rdclass, void *arg); -/*% - * Isself callback. - */ - -isc_result_t -ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); - -isc_result_t -ns_client_addopt(ns_client_t *client, dns_message_t *message, - dns_rdataset_t **opt); - -#endif /* NAMED_CLIENT_H */ diff --git a/bin/named-sdb/include/named/config.h b/bin/named-sdb/include/named/config.h deleted file mode 100644 index 656336b..0000000 --- a/bin/named-sdb/include/named/config.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NAMED_CONFIG_H -#define NAMED_CONFIG_H 1 - -/*! \file */ - -#include - -#include - -#include -#include - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); - -isc_result_t -ns_config_get(cfg_obj_t const * const *maps, const char *name, - const cfg_obj_t **obj); - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char *name, - const cfg_obj_t **obj); - -int -ns_config_listcount(const cfg_obj_t *list); - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp); - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep); - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj); - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, - uint32_t *countp); - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_dscp_t **dscpsp, uint32_t count); - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, dns_ipkeylist_t *ipkl); - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp); - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - uint16_t *digestbits); -isc_result_t -ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, - unsigned int *typep, uint16_t *digestbits); - -isc_result_t -ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp); - -#endif /* NAMED_CONFIG_H */ diff --git a/bin/named-sdb/include/named/control.h b/bin/named-sdb/include/named/control.h deleted file mode 100644 index 37403f1..0000000 --- a/bin/named-sdb/include/named/control.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_CONTROL_H -#define NAMED_CONTROL_H 1 - -/*! \file - * \brief - * The name server command channel. - */ - -#include -#include - -#include - -#include - -#define NS_CONTROL_PORT 953 - -#define NS_COMMAND_STOP "stop" -#define NS_COMMAND_HALT "halt" -#define NS_COMMAND_RELOAD "reload" -#define NS_COMMAND_RECONFIG "reconfig" -#define NS_COMMAND_REFRESH "refresh" -#define NS_COMMAND_RETRANSFER "retransfer" -#define NS_COMMAND_DUMPSTATS "stats" -#define NS_COMMAND_QUERYLOG "querylog" -#define NS_COMMAND_DUMPDB "dumpdb" -#define NS_COMMAND_SECROOTS "secroots" -#define NS_COMMAND_TRACE "trace" -#define NS_COMMAND_NOTRACE "notrace" -#define NS_COMMAND_FLUSH "flush" -#define NS_COMMAND_FLUSHNAME "flushname" -#define NS_COMMAND_FLUSHTREE "flushtree" -#define NS_COMMAND_STATUS "status" -#define NS_COMMAND_TSIGLIST "tsig-list" -#define NS_COMMAND_TSIGDELETE "tsig-delete" -#define NS_COMMAND_FREEZE "freeze" -#define NS_COMMAND_UNFREEZE "unfreeze" -#define NS_COMMAND_THAW "thaw" -#define NS_COMMAND_TIMERPOKE "timerpoke" -#define NS_COMMAND_RECURSING "recursing" -#define NS_COMMAND_NULL "null" -#define NS_COMMAND_NOTIFY "notify" -#define NS_COMMAND_VALIDATION "validation" -#define NS_COMMAND_SCAN "scan" -#define NS_COMMAND_SIGN "sign" -#define NS_COMMAND_LOADKEYS "loadkeys" -#define NS_COMMAND_ADDZONE "addzone" -#define NS_COMMAND_MODZONE "modzone" -#define NS_COMMAND_DELZONE "delzone" -#define NS_COMMAND_SHOWZONE "showzone" -#define NS_COMMAND_SYNC "sync" -#define NS_COMMAND_SIGNING "signing" -#define NS_COMMAND_ZONESTATUS "zonestatus" -#define NS_COMMAND_NTA "nta" -#define NS_COMMAND_TESTGEN "testgen" -#define NS_COMMAND_MKEYS "managed-keys" -#define NS_COMMAND_DNSTAPREOPEN "dnstap-reopen" -#define NS_COMMAND_DNSTAP "dnstap" -#define NS_COMMAND_SERVESTALE "serve-stale" - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); -/*%< - * Create an initial, empty set of command channels for 'server'. - */ - -void -ns_controls_destroy(ns_controls_t **ctrlsp); -/*%< - * Destroy a set of command channels. - * - * Requires: - * Shutdown of the channels has completed. - */ - -isc_result_t -ns_controls_configure(ns_controls_t *controls, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx); -/*%< - * Configure zero or more command channels into 'controls' - * as defined in the configuration parse tree 'config'. - * The channels will evaluate ACLs in the context of - * 'aclconfctx'. - */ - -void -ns_controls_shutdown(ns_controls_t *controls); -/*%< - * Initiate shutdown of all the command channels in 'controls'. - */ - -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, bool readonly, - isc_buffer_t **text); - -#endif /* NAMED_CONTROL_H */ diff --git a/bin/named-sdb/include/named/fuzz.h b/bin/named-sdb/include/named/fuzz.h deleted file mode 100644 index c05f112..0000000 --- a/bin/named-sdb/include/named/fuzz.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_FUZZ_H -#define NAMED_FUZZ_H - -void -named_fuzz_notify(void); - -void -named_fuzz_setup(void); - -typedef enum { - ns_fuzz_none, - ns_fuzz_client, - ns_fuzz_tcpclient, - ns_fuzz_resolver, - ns_fuzz_http, - ns_fuzz_rndc -} ns_fuzz_t; - -#endif /* NAMED_FUZZ_H */ diff --git a/bin/named-sdb/include/named/geoip.h b/bin/named-sdb/include/named/geoip.h deleted file mode 100644 index c293f1a..0000000 --- a/bin/named-sdb/include/named/geoip.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef _GEOIP_H -#define _GEOIP_H - -extern dns_geoip_databases_t *ns_g_geoip; - -void -ns_geoip_init(void); - -void -ns_geoip_load(char *dir); - -void -ns_geoip_shutdown(void); -#endif diff --git a/bin/named-sdb/include/named/globals.h b/bin/named-sdb/include/named/globals.h deleted file mode 100644 index b1756af..0000000 --- a/bin/named-sdb/include/named/globals.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_GLOBALS_H -#define NAMED_GLOBALS_H 1 - -/*! \file */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -#ifndef NS_RUN_PID_DIR -#define NS_RUN_PID_DIR 1 -#endif - -EXTERN isc_mem_t * ns_g_mctx INIT(NULL); -EXTERN unsigned int ns_g_cpus INIT(0); -EXTERN unsigned int ns_g_udpdisp INIT(0); -EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL); -EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL); -EXTERN isc_entropy_t * ns_g_entropy INIT(NULL); -EXTERN isc_entropy_t * ns_g_fallbackentropy INIT(NULL); -EXTERN unsigned int ns_g_cpus_detected INIT(1); - -#ifdef ENABLE_AFL -EXTERN bool ns_g_run_done INIT(false); -#endif -/* - * XXXRTH We're going to want multiple timer managers eventually. One - * for really short timers, another for client timers, and one - * for zone timers. - */ -EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL); -EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL); -EXTERN cfg_parser_t * ns_g_parser INIT(NULL); -EXTERN cfg_parser_t * ns_g_addparser INIT(NULL); -EXTERN const char * ns_g_version INIT(VERSION); -EXTERN const char * ns_g_product INIT(PRODUCT); -EXTERN const char * ns_g_description INIT(DESCRIPTION); -EXTERN const char * ns_g_srcid INIT(SRCID); -EXTERN const char * ns_g_configargs INIT(CONFIGARGS); -EXTERN const char * ns_g_builder INIT(BUILDER); -EXTERN in_port_t ns_g_port INIT(0); -EXTERN isc_dscp_t ns_g_dscp INIT(-1); -EXTERN in_port_t lwresd_g_listenport INIT(0); - -EXTERN ns_server_t * ns_g_server INIT(NULL); - -EXTERN bool ns_g_lwresdonly INIT(false); - -/* - * Logging. - */ -EXTERN isc_log_t * ns_g_lctx INIT(NULL); -EXTERN isc_logcategory_t * ns_g_categories INIT(NULL); -EXTERN isc_logmodule_t * ns_g_modules INIT(NULL); -EXTERN unsigned int ns_g_debuglevel INIT(0); - -/* - * Current configuration information. - */ -EXTERN cfg_obj_t * ns_g_config INIT(NULL); -EXTERN const cfg_obj_t * ns_g_defaults INIT(NULL); -EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR - "/named.conf"); -EXTERN cfg_obj_t * ns_g_bindkeys INIT(NULL); -EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR - "/rndc.key"); - -EXTERN dns_tsigkey_t * ns_g_sessionkey INIT(NULL); -EXTERN dns_name_t ns_g_sessionkeyname; - -EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR - "/lwresd.conf"); -EXTERN const char * lwresd_g_resolvconffile INIT("/etc" - "/resolv.conf"); -EXTERN bool ns_g_conffileset INIT(false); -EXTERN bool lwresd_g_useresolvconf INIT(false); -EXTERN uint16_t ns_g_udpsize INIT(4096); -EXTERN cfg_aclconfctx_t * ns_g_aclconfctx INIT(NULL); - -/* - * Initial resource limits. - */ -EXTERN isc_resourcevalue_t ns_g_initstacksize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initdatasize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initcoresize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initopenfiles INIT(0); - -/* - * Misc. - */ -EXTERN bool ns_g_coreok INIT(true); -EXTERN const char * ns_g_chrootdir INIT(NULL); -EXTERN bool ns_g_foreground INIT(false); -EXTERN bool ns_g_logstderr INIT(false); -EXTERN bool ns_g_nosyslog INIT(false); -EXTERN const char * ns_g_logfile INIT(NULL); - -EXTERN const char * ns_g_defaultsessionkeyfile - INIT(NS_LOCALSTATEDIR "/run/named/" - "session.key"); -EXTERN const char * ns_g_defaultlockfile INIT(NS_LOCALSTATEDIR - "/run/named/" - "named.lock"); -EXTERN bool ns_g_forcelock INIT(false); - -#if NS_RUN_PID_DIR -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named/" - "named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd/" - "lwresd.pid"); -#else -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd.pid"); -#endif - -EXTERN const char * ns_g_username INIT(NULL); - -#if defined(USE_PKCS11) && !defined(PKCS11CRYPTO) -EXTERN const char * ns_g_engine INIT(PKCS11_ENGINE); -#else -EXTERN const char * ns_g_engine INIT(NULL); -#endif - -EXTERN int ns_g_listen INIT(3); -EXTERN isc_time_t ns_g_boottime; -EXTERN isc_time_t ns_g_configtime; -EXTERN bool ns_g_memstatistics INIT(false); -EXTERN bool ns_g_clienttest INIT(false); -EXTERN bool ns_g_dropedns INIT(false); -EXTERN bool ns_g_ednsformerr INIT(false); -EXTERN bool ns_g_ednsnotimp INIT(false); -EXTERN bool ns_g_ednsrefused INIT(false); -EXTERN bool ns_g_noedns INIT(false); -EXTERN bool ns_g_nosoa INIT(false); -EXTERN bool ns_g_noaa INIT(false); -EXTERN bool ns_g_keepstderr INIT(false); -EXTERN unsigned int ns_g_delay INIT(0); -EXTERN bool ns_g_nonearest INIT(false); -EXTERN bool ns_g_notcp INIT(false); -EXTERN bool ns_g_disable6 INIT(false); -EXTERN bool ns_g_disable4 INIT(false); -EXTERN unsigned int ns_g_tat_interval INIT(24*3600); -EXTERN bool ns_g_fixedlocal INIT(false); -EXTERN bool ns_g_sigvalinsecs INIT(false); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL); -#endif - -EXTERN const char * ns_g_fuzz_named_addr INIT(NULL); -EXTERN ns_fuzz_t ns_g_fuzz_type INIT(ns_fuzz_none); - -EXTERN dns_acl_t * ns_g_mapped INIT(NULL); - -#undef EXTERN -#undef INIT - -#endif /* NAMED_GLOBALS_H */ diff --git a/bin/named-sdb/include/named/interfacemgr.h b/bin/named-sdb/include/named/interfacemgr.h deleted file mode 100644 index 2170693..0000000 --- a/bin/named-sdb/include/named/interfacemgr.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_INTERFACEMGR_H -#define NAMED_INTERFACEMGR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The interface manager monitors the operating system's list - * of network interfaces, creating and destroying listeners - * as needed. - * - * Reliability: - *\li No impact expected. - * - * Resources: - * - * Security: - * \li The server will only be able to bind to the DNS port on - * newly discovered interfaces if it is running as root. - * - * Standards: - *\li The API for scanning varies greatly among operating systems. - * This module attempts to hide the differences. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -/*** - *** Types - ***/ - -#define IFACE_MAGIC ISC_MAGIC('I',':','-',')') -#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) - -#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ -#define MAX_UDP_DISPATCH 128 /*%< Maximum number of UDP dispatchers - to start per interface */ -/*% The nameserver interface structure */ -struct ns_interface { - unsigned int magic; /*%< Magic number. */ - ns_interfacemgr_t * mgr; /*%< Interface manager. */ - isc_mutex_t lock; - int references; /*%< Locked */ - unsigned int generation; /*%< Generation number. */ - isc_sockaddr_t addr; /*%< Address and port. */ - unsigned int flags; /*%< Interface characteristics */ - char name[32]; /*%< Null terminated. */ - dns_dispatch_t * udpdispatch[MAX_UDP_DISPATCH]; - /*%< UDP dispatchers. */ - isc_socket_t * tcpsocket; /*%< TCP socket. */ - isc_dscp_t dscp; /*%< "listen-on" DSCP value */ - isc_refcount_t ntcpaccepting; /*%< Number of clients - ready to accept new - TCP connections on this - interface */ - isc_refcount_t ntcpactive; /*%< Number of clients - servicing TCP queries - (whether accepting or - connected) */ - int nudpdispatch; /*%< Number of UDP dispatches */ - ns_clientmgr_t * clientmgr; /*%< Client manager. */ - ISC_LINK(ns_interface_t) link; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - isc_task_t *task, ns_interfacemgr_t **mgrp); -/*% - * Create a new interface manager. - * - * Initially, the new manager will not listen on any interfaces. - * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() - * to set nonempty listen-on lists. - */ - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp); - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); - -bool -ns_interfacemgr_islistening(ns_interfacemgr_t *mgr); -/*% - * Return if the manager is listening on any interface. It can be called - * after a scan or adjust. - */ - -isc_result_t -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose); -/*% - * Scan the operatings system's list of network interfaces - * and create listeners when new interfaces are discovered. - * Shut down the sockets for interfaces that go away. - * - * This should be called once on server startup and then - * periodically according to the 'interface-interval' option - * in named.conf. - */ - -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose); -/*% - * Similar to ns_interfacemgr_scan(), but this function also tries to see the - * need for an explicit listen-on when a list element in 'list' is going to - * override an already-listening a wildcard interface. - * - * This function does not update localhost and localnets ACLs. - * - * This should be called once on server startup, after configuring views and - * zones. - */ - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv4 "listen-on" list of 'mgr' to 'value'. - * The previous IPv4 listen-on list is freed. - */ - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv6 "listen-on" list of 'mgr' to 'value'. - * The previous IPv6 listen-on list is freed. - */ - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target); - -void -ns_interface_detach(ns_interface_t **targetp); - -void -ns_interface_shutdown(ns_interface_t *ifp); -/*% - * Stop listening for queries on interface 'ifp'. - * May safely be called multiple times. - */ - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); - -bool -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr); - -#endif /* NAMED_INTERFACEMGR_H */ diff --git a/bin/named-sdb/include/named/listenlist.h b/bin/named-sdb/include/named/listenlist.h deleted file mode 100644 index 04525c0..0000000 --- a/bin/named-sdb/include/named/listenlist.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LISTENLIST_H -#define NAMED_LISTENLIST_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * "Listen lists", as in the "listen-on" configuration statement. - */ - -/*** - *** Imports - ***/ - - -#include -#include - -#include - -/*** - *** Types - ***/ - -typedef struct ns_listenelt ns_listenelt_t; -typedef struct ns_listenlist ns_listenlist_t; - -struct ns_listenelt { - isc_mem_t * mctx; - in_port_t port; - isc_dscp_t dscp; /* -1 = not set, 0..63 */ - dns_acl_t * acl; - ISC_LINK(ns_listenelt_t) link; -}; - -struct ns_listenlist { - isc_mem_t * mctx; - int refcount; - ISC_LIST(ns_listenelt_t) elts; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - dns_acl_t *acl, ns_listenelt_t **target); -/*% - * Create a listen-on list element. - */ - -void -ns_listenelt_destroy(ns_listenelt_t *elt); -/*% - * Destroy a listen-on list element. - */ - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); -/*% - * Create a new, empty listen-on list. - */ - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); -/*% - * Attach '*target' to '*source'. - */ - -void -ns_listenlist_detach(ns_listenlist_t **listp); -/*% - * Detach 'listp'. - */ - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - bool enabled, ns_listenlist_t **target); -/*% - * Create a listen-on list with default contents, matching - * all addresses with port 'port' (if 'enabled' is true), - * or no addresses (if 'enabled' is false). - */ - -#endif /* NAMED_LISTENLIST_H */ diff --git a/bin/named-sdb/include/named/log.h b/bin/named-sdb/include/named/log.h deleted file mode 100644 index 0d1d985..0000000 --- a/bin/named-sdb/include/named/log.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LOG_H -#define NAMED_LOG_H 1 - -/*! \file */ - -#include -#include - -#include - -#include /* Required for ns_g_(categories|modules). */ - -/* Unused slot 0. */ -#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1]) -#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2]) -#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3]) -#define NS_LOGCATEGORY_QUERIES (&ns_g_categories[4]) -#define NS_LOGCATEGORY_UNMATCHED (&ns_g_categories[5]) -#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) -#define NS_LOGCATEGORY_QUERY_ERRORS (&ns_g_categories[7]) -#define NS_LOGCATEGORY_TAT (&ns_g_categories[8]) -#define NS_LOGCATEGORY_SERVE_STALE (&ns_g_categories[9]) - -/* - * Backwards compatibility. - */ -#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL - -#define NS_LOGMODULE_MAIN (&ns_g_modules[0]) -#define NS_LOGMODULE_CLIENT (&ns_g_modules[1]) -#define NS_LOGMODULE_SERVER (&ns_g_modules[2]) -#define NS_LOGMODULE_QUERY (&ns_g_modules[3]) -#define NS_LOGMODULE_INTERFACEMGR (&ns_g_modules[4]) -#define NS_LOGMODULE_UPDATE (&ns_g_modules[5]) -#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6]) -#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7]) -#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8]) -#define NS_LOGMODULE_CONTROL (&ns_g_modules[9]) -#define NS_LOGMODULE_LWRESD (&ns_g_modules[10]) - -isc_result_t -ns_log_init(bool safe); -/*% - * Initialize the logging system and set up an initial default - * logging default configuration that will be used until the - * config file has been read. - * - * If 'safe' is true, use a default configuration that refrains - * from opening files. This is to avoid creating log files - * as root. - */ - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg); -/*% - * Set up logging channels according to the named defaults, which - * may differ from the logging library defaults. Currently, - * this just means setting up default_debug. - */ - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg); -/*% - * Like ns_log_setdefaultchannels(), but omits any logging to files. - */ - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category default" to go to the right places. - */ - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category unmatched" to go to the right places. - */ - -void -ns_log_shutdown(void); - -#endif /* NAMED_LOG_H */ diff --git a/bin/named-sdb/include/named/logconf.h b/bin/named-sdb/include/named/logconf.h deleted file mode 100644 index 8438b67..0000000 --- a/bin/named-sdb/include/named/logconf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NAMED_LOGCONF_H -#define NAMED_LOGCONF_H 1 - -/*! \file */ - -#include - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt); -/*%< - * Set up the logging configuration in '*logconf' according to - * the named.conf data in 'logstmt'. - */ - -#endif /* NAMED_LOGCONF_H */ diff --git a/bin/named-sdb/include/named/lwaddr.h b/bin/named-sdb/include/named/lwaddr.h deleted file mode 100644 index 3e5eed2..0000000 --- a/bin/named-sdb/include/named/lwaddr.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include - -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la); - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port); - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na); - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa); diff --git a/bin/named-sdb/include/named/lwdclient.h b/bin/named-sdb/include/named/lwdclient.h deleted file mode 100644 index 389abc7..0000000 --- a/bin/named-sdb/include/named/lwdclient.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWDCLIENT_H -#define NAMED_LWDCLIENT_H 1 - -/*! \file */ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) - -#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) - -/*% Lightweight Resolver Daemon Client */ -struct ns_lwdclient { - isc_sockaddr_t address; /*%< where to reply */ - struct in6_pktinfo pktinfo; - bool pktinfo_valid; - ns_lwdclientmgr_t *clientmgr; /*%< our parent */ - ISC_LINK(ns_lwdclient_t) link; - unsigned int state; - void *arg; /*%< packet processing state */ - - /* - * Received data info. - */ - unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */ - uint32_t recvlength; /*%< length recv'd */ - lwres_lwpacket_t pkt; - - /*% - * Send data state. If sendbuf != buffer (that is, the send buffer - * isn't our receive buffer) it will be freed to the lwres_context_t. - */ - unsigned char *sendbuf; - uint32_t sendlength; - isc_buffer_t recv_buffer; - - /*% - * gabn (get address by name) state info. - */ - dns_adbfind_t *find; - dns_adbfind_t *v4find; - dns_adbfind_t *v6find; - unsigned int find_wanted; /*%< Addresses we want */ - dns_fixedname_t query_name; - dns_fixedname_t target_name; - ns_lwsearchctx_t searchctx; - lwres_gabnresponse_t gabn; - - /*% - * gnba (get name by address) state info. - */ - lwres_gnbaresponse_t gnba; - dns_byaddr_t *byaddr; - unsigned int options; - isc_netaddr_t na; - - /*% - * grbn (get rrset by name) state info. - * - * Note: this also uses target_name and searchctx. - */ - lwres_grbnresponse_t grbn; - dns_lookup_t *lookup; - dns_rdatatype_t rdtype; - - /*% - * Alias and address info. This is copied up to the gabn/gnba - * structures eventually. - * - * XXXMLG We can keep all of this in a client since we only service - * three packet types right now. If we started handling more, - * we'd need to use "arg" above and allocate/destroy things. - */ - char *aliases[LWRES_MAX_ALIASES]; - uint16_t aliaslen[LWRES_MAX_ALIASES]; - lwres_addr_t addrs[LWRES_MAX_ADDRS]; -}; - -/*% - * Client states. - * - * _IDLE The client is not doing anything at all. - * - * _RECV The client is waiting for data after issuing a socket recv(). - * - * _RECVDONE Data has been received, and is being processed. - * - * _FINDWAIT An adb (or other) request was made that cannot be satisfied - * immediately. An event will wake the client up. - * - * _SEND All data for a response has completed, and a reply was - * sent via a socket send() call. - * - * Badly formatted state table: - * - * IDLE -> RECV when client has a recv() queued. - * - * RECV -> RECVDONE when recvdone event received. - * - * RECVDONE -> SEND if the data for a reply is at hand. - * RECVDONE -> FINDWAIT if more searching is needed, and events will - * eventually wake us up again. - * - * FINDWAIT -> SEND when enough data was received to reply. - * - * SEND -> IDLE when a senddone event was received. - * - * At any time -> IDLE on error. Sometimes this will be -> SEND - * instead, if enough data is on hand to reply with a meaningful - * error. - * - * Packets which are badly formatted may or may not get error returns. - */ -#define NS_LWDCLIENT_STATEIDLE 1 -#define NS_LWDCLIENT_STATERECV 2 -#define NS_LWDCLIENT_STATERECVDONE 3 -#define NS_LWDCLIENT_STATEFINDWAIT 4 -#define NS_LWDCLIENT_STATESEND 5 -#define NS_LWDCLIENT_STATESENDDONE 6 - -#define NS_LWDCLIENT_ISIDLE(c) \ - ((c)->state == NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_ISRECV(c) \ - ((c)->state == NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_ISRECVDONE(c) \ - ((c)->state == NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_ISFINDWAIT(c) \ - ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_ISSEND(c) \ - ((c)->state == NS_LWDCLIENT_STATESEND) - -/*% - * Overall magic test that means we're not idle. - */ -#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) - -#define NS_LWDCLIENT_SETIDLE(c) \ - ((c)->state = NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_SETRECV(c) \ - ((c)->state = NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_SETRECVDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_SETFINDWAIT(c) \ - ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_SETSEND(c) \ - ((c)->state = NS_LWDCLIENT_STATESEND) -#define NS_LWDCLIENT_SETSENDDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATESENDDONE) - -/*% lightweight daemon client manager */ -struct ns_lwdclientmgr { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_socket_t *sock; /*%< socket to use */ - dns_view_t *view; - lwres_context_t *lwctx; /*%< lightweight proto context */ - isc_task_t *task; /*%< owning task */ - unsigned int flags; - isc_mutex_t lock; - ISC_LINK(ns_lwdclientmgr_t) link; - ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */ - ISC_LIST(ns_lwdclient_t) running; /*%< running clients */ -}; - -#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 -#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); - -void -ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); - -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *); - -void -ns_lwdclient_stateidle(ns_lwdclient_t *); - -void -ns_lwdclient_recv(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_send(isc_task_t *, isc_event_t *); - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); - -/* - * Processing functions of various types. - */ -void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); - -void ns_lwdclient_errorpktsend(ns_lwdclient_t *, uint32_t); - -void ns_lwdclient_log(int level, const char *format, ...) - ISC_FORMAT_PRINTF(2, 3); - -#endif /* NAMED_LWDCLIENT_H */ diff --git a/bin/named-sdb/include/named/lwresd.h b/bin/named-sdb/include/named/lwresd.h deleted file mode 100644 index fff9f11..0000000 --- a/bin/named-sdb/include/named/lwresd.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWRESD_H -#define NAMED_LWRESD_H 1 - -/*! \file */ - -#include -#include - -#include - -#include - -struct ns_lwresd { - unsigned int magic; - - isc_mutex_t lock; - dns_view_t *view; - ns_lwsearchlist_t *search; - unsigned int ndots; - unsigned int ntasks; - unsigned int nclients; - isc_mem_t *mctx; - bool shutting_down; - unsigned int refs; -}; - -struct ns_lwreslistener { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - isc_sockaddr_t address; - ns_lwresd_t *manager; - isc_socket_t *sock; - unsigned int refs; - ISC_LIST(ns_lwdclientmgr_t) cmgrs; - ISC_LINK(ns_lwreslistener_t) link; -}; - -/*% - * Configure lwresd. - */ -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config); - -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp); - -/*% - * Trigger shutdown. - */ -void -ns_lwresd_shutdown(void); - -/* - * Manager functions - */ -/*% create manager */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp); - -/*% attach to manager */ -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); - -/*% detach from manager */ -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp); - -/* - * Listener functions - */ -/*% attach to listener */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp); - -/*% detach from lister */ -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); - -/*% link client manager */ -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - -/*% unlink client manager */ -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - - - - -/* - * INTERNAL FUNCTIONS. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size); - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size); - -#endif /* NAMED_LWRESD_H */ diff --git a/bin/named-sdb/include/named/lwsearch.h b/bin/named-sdb/include/named/lwsearch.h deleted file mode 100644 index a256f33..0000000 --- a/bin/named-sdb/include/named/lwsearch.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_LWSEARCH_H -#define NAMED_LWSEARCH_H 1 - -#include -#include -#include - -#include - -#include - -/*! \file - * \brief - * Lightweight resolver search list types and routines. - * - * An ns_lwsearchlist_t holds a list of search path elements. - * - * An ns_lwsearchctx stores the state of search list during a lookup - * operation. - */ - -/*% An ns_lwsearchlist_t holds a list of search path elements. */ -struct ns_lwsearchlist { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - unsigned int refs; - dns_namelist_t names; -}; -/*% An ns_lwsearchctx stores the state of search list during a lookup operation. */ -struct ns_lwsearchctx { - dns_name_t *relname; - dns_name_t *searchname; - unsigned int ndots; - ns_lwsearchlist_t *list; - bool doneexact; - bool exactfirst; -}; - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp); -/*%< - * Create an empty search list object. - */ - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target); -/*%< - * Attach to a search list object. - */ - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp); -/*%< - * Detach from a search list object. - */ - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name); -/*%< - * Append an element to a search list. This creates a copy of the name. - */ - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots); -/*%< - * Creates a search list context structure. - */ - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the first element, which - * is usually the exact name. - */ - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the next element. - */ - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname); -/*%< - * Obtains the current name to be looked up. This involves either - * concatenating the name with a search path element, making an - * exact name absolute, or doing nothing. - */ - -#endif /* NAMED_LWSEARCH_H */ diff --git a/bin/named-sdb/include/named/main.h b/bin/named-sdb/include/named/main.h deleted file mode 100644 index 5e5738f..0000000 --- a/bin/named-sdb/include/named/main.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_MAIN_H -#define NAMED_MAIN_H 1 - -/*! \file */ - -#ifdef ISC_MAIN_HOOK -#define main(argc, argv) bindmain(argc, argv) -#endif - -/* - * Commandline arguments for named; also referenced in win32/ntservice.c - */ -#define NS_MAIN_ARGS "46A:c:C:d:D:E:fFgi:lL:M:m:n:N:p:P:sS:t:T:U:u:vVx:X:" - -ISC_PLATFORM_NORETURN_PRE void -ns_main_earlyfatal(const char *format, ...) -ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; - -void -ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_setmemstats(const char *); - -#endif /* NAMED_MAIN_H */ diff --git a/bin/named-sdb/include/named/notify.h b/bin/named-sdb/include/named/notify.h deleted file mode 100644 index 52895e5..0000000 --- a/bin/named-sdb/include/named/notify.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_NOTIFY_H -#define NAMED_NOTIFY_H 1 - -#include -#include - -/*** - *** Module Info - ***/ - -/*! \file - * \brief - * RFC1996 - * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) - */ - -/*** - *** Functions. - ***/ - -void -ns_notify_start(ns_client_t *client); - -/*%< - * Examines the incoming message to determine appropriate zone. - * Returns FORMERR if there is not exactly one question. - * Returns REFUSED if we do not serve the listed zone. - * Pass the message to the zone module for processing - * and returns the return status. - * - * Requires - *\li client to be valid. - */ - -#endif /* NAMED_NOTIFY_H */ - diff --git a/bin/named-sdb/include/named/ns_smf_globals.h b/bin/named-sdb/include/named/ns_smf_globals.h deleted file mode 100644 index d2b695c..0000000 --- a/bin/named-sdb/include/named/ns_smf_globals.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_SMF_GLOBALS_H -#define NS_SMF_GLOBALS_H 1 - -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN unsigned int ns_smf_got_instance INIT(0); -EXTERN unsigned int ns_smf_chroot INIT(0); -EXTERN unsigned int ns_smf_want_disable INIT(0); - -isc_result_t ns_smf_add_message(isc_buffer_t **text); -isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx); - -#undef EXTERN -#undef INIT - -#endif /* NS_SMF_GLOBALS_H */ diff --git a/bin/named-sdb/include/named/query.h b/bin/named-sdb/include/named/query.h deleted file mode 100644 index 53c052b..0000000 --- a/bin/named-sdb/include/named/query.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_QUERY_H -#define NAMED_QUERY_H 1 - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include - -#include - -/*% nameserver database version structure */ -typedef struct ns_dbversion { - dns_db_t *db; - dns_dbversion_t *version; - bool acl_checked; - bool queryok; - ISC_LINK(struct ns_dbversion) link; -} ns_dbversion_t; - -/*% - * nameserver recursion parameters, to uniquely identify a recursion - * query; this is used to detect a recursion loop - */ -typedef struct ns_query_recparam { - dns_rdatatype_t qtype; - dns_name_t * qname; - dns_fixedname_t fqname; - dns_name_t * qdomain; - dns_fixedname_t fqdomain; -} ns_query_recparam_t; - -/*% nameserver query structure */ -struct ns_query { - unsigned int attributes; - unsigned int restarts; - bool timerset; - dns_name_t * qname; - dns_name_t * origqname; - dns_rdatatype_t qtype; - unsigned int dboptions; - unsigned int fetchoptions; - dns_db_t * gluedb; - dns_db_t * authdb; - dns_zone_t * authzone; - bool authdbset; - bool isreferral; - isc_mutex_t fetchlock; - dns_fetch_t * fetch; - dns_fetch_t * prefetch; - dns_rpz_st_t * rpz_st; - isc_bufferlist_t namebufs; - ISC_LIST(ns_dbversion_t) activeversions; - ISC_LIST(ns_dbversion_t) freeversions; - dns_rdataset_t * dns64_aaaa; - dns_rdataset_t * dns64_sigaaaa; - bool * dns64_aaaaok; - unsigned int dns64_aaaaoklen; - unsigned int dns64_options; - unsigned int dns64_ttl; - - struct { - dns_db_t * db; - dns_zone_t * zone; - dns_dbnode_t * node; - dns_rdatatype_t qtype; - dns_name_t * fname; - dns_fixedname_t fixed; - isc_result_t result; - dns_rdataset_t * rdataset; - dns_rdataset_t * sigrdataset; - bool authoritative; - bool is_zone; - } redirect; - - ns_query_recparam_t recparam; - dns_keytag_t root_key_sentinel_keyid; - bool root_key_sentinel_is_ta; - bool root_key_sentinel_not_ta; -}; - -#define NS_QUERYATTR_RECURSIONOK 0x0001 -#define NS_QUERYATTR_CACHEOK 0x0002 -#define NS_QUERYATTR_PARTIALANSWER 0x0004 -#define NS_QUERYATTR_NAMEBUFUSED 0x0008 -#define NS_QUERYATTR_RECURSING 0x0010 -#define NS_QUERYATTR_CACHEGLUEOK 0x0020 -#define NS_QUERYATTR_QUERYOKVALID 0x0040 -#define NS_QUERYATTR_QUERYOK 0x0080 -#define NS_QUERYATTR_WANTRECURSION 0x0100 -#define NS_QUERYATTR_SECURE 0x0200 -#define NS_QUERYATTR_NOAUTHORITY 0x0400 -#define NS_QUERYATTR_NOADDITIONAL 0x0800 -#define NS_QUERYATTR_CACHEACLOKVALID 0x1000 -#define NS_QUERYATTR_CACHEACLOK 0x2000 -#define NS_QUERYATTR_DNS64 0x4000 -#define NS_QUERYATTR_DNS64EXCLUDE 0x8000 -#define NS_QUERYATTR_RRL_CHECKED 0x10000 -#define NS_QUERYATTR_REDIRECT 0x20000 - -isc_result_t -ns_query_init(ns_client_t *client); - -void -ns_query_free(ns_client_t *client); - -void -ns_query_start(ns_client_t *client); - -void -ns_query_cancel(ns_client_t *client); - -#endif /* NAMED_QUERY_H */ diff --git a/bin/named-sdb/include/named/seccomp.h b/bin/named-sdb/include/named/seccomp.h deleted file mode 100644 index 970ce28..0000000 --- a/bin/named-sdb/include/named/seccomp.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SECCOMP_H -#define NAMED_SECCOMP_H 1 - -/*! \file */ - -#ifdef HAVE_LIBSECCOMP -#include -#include -#include -#include -#include - -/*% - * For each architecture, the scmp_syscalls and - * scmp_syscall_names arrays MUST be kept in sync. - */ -#ifdef __x86_64__ -int scmp_syscalls[] = { - SCMP_SYS(access), - SCMP_SYS(open), - SCMP_SYS(openat), - SCMP_SYS(lseek), - SCMP_SYS(clock_gettime), - SCMP_SYS(time), - SCMP_SYS(read), - SCMP_SYS(write), - SCMP_SYS(close), - SCMP_SYS(brk), - SCMP_SYS(poll), - SCMP_SYS(select), - SCMP_SYS(madvise), - SCMP_SYS(mmap), - SCMP_SYS(munmap), - SCMP_SYS(exit_group), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(rt_sigaction), - SCMP_SYS(fsync), - SCMP_SYS(rt_sigreturn), - SCMP_SYS(setsid), - SCMP_SYS(chdir), - SCMP_SYS(futex), - SCMP_SYS(stat), - SCMP_SYS(rt_sigsuspend), - SCMP_SYS(fstat), - SCMP_SYS(epoll_ctl), - SCMP_SYS(gettimeofday), - SCMP_SYS(getpid), -#ifdef HAVE_GETRANDOM - SCMP_SYS(getrandom), -#endif - SCMP_SYS(rename), - SCMP_SYS(unlink), - SCMP_SYS(socket), - SCMP_SYS(sendto), -#ifndef ISC_PLATFORM_USETHREADS - SCMP_SYS(bind), - SCMP_SYS(accept), - SCMP_SYS(connect), - SCMP_SYS(listen), - SCMP_SYS(fcntl), - SCMP_SYS(sendmsg), - SCMP_SYS(recvmsg), - SCMP_SYS(uname), - SCMP_SYS(setrlimit), - SCMP_SYS(getrlimit), - SCMP_SYS(setsockopt), - SCMP_SYS(getsockopt), - SCMP_SYS(getsockname), - SCMP_SYS(lstat), - SCMP_SYS(getgid), - SCMP_SYS(getegid), - SCMP_SYS(getuid), - SCMP_SYS(geteuid), - SCMP_SYS(setresgid), - SCMP_SYS(setresuid), - SCMP_SYS(setgid), - SCMP_SYS(setuid), - SCMP_SYS(prctl), - SCMP_SYS(epoll_wait), - SCMP_SYS(getdents), - SCMP_SYS(utimes), - SCMP_SYS(dup), -#endif -}; -const char *scmp_syscall_names[] = { - "access", - "open", - "openat", - "lseek", - "clock_gettime", - "time", - "read", - "write", - "close", - "brk", - "poll", - "select", - "madvise", - "mmap", - "munmap", - "exit_group", - "rt_sigprocmask", - "rt_sigaction", - "fsync", - "rt_sigreturn", - "setsid", - "chdir", - "futex", - "stat", - "rt_sigsuspend", - "fstat", - "epoll_ctl", - "gettimeofday", - "getpid", -#ifdef HAVE_GETRANDOM - "getrandom", -#endif - "rename", - "unlink", - "socket", - "sendto", -#ifndef ISC_PLATFORM_USETHREADS - "bind", - "accept", - "connect", - "listen", - "fcntl", - "sendmsg", - "recvmsg", - "uname", - "setrlimit", - "getrlimit", - "setsockopt", - "getsockopt", - "getsockname", - "lstat", - "getgid", - "getegid", - "getuid", - "geteuid", - "setresgid", - "setresuid", - "setgid", - "setuid", - "prctl", - "epoll_wait", - "getdents", - "utimes", - "dup", -#endif -}; -#endif /* __x86_64__ */ -#ifdef __i386__ -int scmp_syscalls[] = { - SCMP_SYS(access), - SCMP_SYS(open), - SCMP_SYS(clock_gettime), - SCMP_SYS(time), - SCMP_SYS(read), - SCMP_SYS(write), - SCMP_SYS(close), - SCMP_SYS(brk), - SCMP_SYS(poll), - SCMP_SYS(_newselect), - SCMP_SYS(select), - SCMP_SYS(madvise), - SCMP_SYS(mmap2), - SCMP_SYS(mmap), - SCMP_SYS(munmap), - SCMP_SYS(exit_group), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(sigprocmask), - SCMP_SYS(rt_sigaction), - SCMP_SYS(socketcall), - SCMP_SYS(fsync), - SCMP_SYS(sigreturn), - SCMP_SYS(setsid), - SCMP_SYS(chdir), - SCMP_SYS(futex), - SCMP_SYS(stat64), - SCMP_SYS(rt_sigsuspend), - SCMP_SYS(fstat64), - SCMP_SYS(epoll_ctl), - SCMP_SYS(gettimeofday), - SCMP_SYS(getpid), -#ifdef HAVE_GETRANDOM - SCMP_SYS(getrandom), -#endif - SCMP_SYS(unlink), -#ifndef ISC_PLATFORM_USETHREADS - SCMP_SYS(fcntl64), -#endif -}; -const char *scmp_syscall_names[] = { - "access", - "open", - "clock_gettime", - "time", - "read", - "write", - "close", - "brk", - "poll", - "_newselect", - "select", - "madvise", - "mmap2", - "mmap", - "munmap", - "exit_group", - "rt_sigprocmask", - "sigprocmask", - "rt_sigaction", - "socketcall", - "fsync", - "sigreturn", - "setsid", - "chdir", - "futex", - "stat64", - "rt_sigsuspend", - "fstat64", - "epoll_ctl", - "gettimeofday", - "getpid", -#ifdef HAVE_GETRANDOM - "getrandom", -#endif - "unlink", -#ifndef ISC_PLATFORM_USETHREADS - "fcntl64", -#endif -}; -#endif /* __i386__ */ -#endif /* HAVE_LIBSECCOMP */ - -#endif /* NAMED_SECCOMP_H */ diff --git a/bin/named-sdb/include/named/server.h b/bin/named-sdb/include/named/server.h deleted file mode 100644 index 08a02dc..0000000 --- a/bin/named-sdb/include/named/server.h +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SERVER_H -#define NAMED_SERVER_H 1 - -/*! \file */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) -#define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) -#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) -#define NS_EVENT_DELZONE (NS_EVENTCLASS + 2) -#define NS_EVENT_TATSEND (NS_EVENTCLASS + 3) - -/*% - * Name server state. Better here than in lots of separate global variables. - */ -struct ns_server { - unsigned int magic; - isc_mem_t * mctx; - - isc_task_t * task; - - /* Configurable data. */ - isc_quota_t xfroutquota; - isc_quota_t tcpquota; - isc_quota_t recursionquota; - - dns_acl_t *blackholeacl; - dns_acl_t *keepresporder; - char * statsfile; /*%< Statistics file name */ - char * dumpfile; /*%< Dump file name */ - char * secrootsfile; /*%< Secroots file name */ - char * bindkeysfile; /*%< bind.keys file name */ - char * recfile; /*%< Recursive file name */ - bool version_set; /*%< User has set version */ - char * version; /*%< User-specified version */ - bool hostname_set; /*%< User has set hostname */ - char * hostname; /*%< User-specified hostname */ - /*% Use hostname for server id */ - bool server_usehostname; - char * server_id; /*%< User-specified server id */ - - /*% - * Current ACL environment. This defines the - * current values of the localhost and localnets - * ACLs. - */ - dns_aclenv_t aclenv; - - /* Server data structures. */ - dns_loadmgr_t * loadmgr; - dns_zonemgr_t * zonemgr; - dns_viewlist_t viewlist; - ns_interfacemgr_t * interfacemgr; - dns_db_t * in_roothints; - dns_tkeyctx_t * tkeyctx; - - isc_timer_t * interface_timer; - isc_timer_t * heartbeat_timer; - isc_timer_t * pps_timer; - isc_timer_t * tat_timer; - - uint32_t interface_interval; - uint32_t heartbeat_interval; - - isc_mutex_t reload_event_lock; - isc_event_t * reload_event; - - bool flushonshutdown; - bool log_queries; /*%< For BIND 8 compatibility */ - - ns_cachelist_t cachelist; /*%< Possibly shared caches */ - isc_stats_t * nsstats; /*%< Server stats */ - dns_stats_t * rcvquerystats; /*% Incoming query stats */ - dns_stats_t * opcodestats; /*%< Incoming message stats */ - isc_stats_t * zonestats; /*% Zone management stats */ - isc_stats_t * resolverstats; /*% Resolver stats */ - isc_stats_t * sockstats; /*%< Socket stats */ - isc_stats_t * udpinstats4; /*%< Traffic size: UDPv4 in */ - isc_stats_t * udpoutstats4; /*%< Traffic size: UDPv4 out */ - isc_stats_t * udpinstats6; /*%< Traffic size: UDPv6 in */ - isc_stats_t * udpoutstats6; /*%< Traffic size: UDPv6 out */ - isc_stats_t * tcpinstats4; /*%< Traffic size: TCPv4 in */ - isc_stats_t * tcpoutstats4; /*%< Traffic size: TCPv4 out */ - isc_stats_t * tcpinstats6; /*%< Traffic size: TCPv6 in */ - isc_stats_t * tcpoutstats6; /*%< Traffic size: TCPv6 out */ - dns_stats_t * rcodestats; /*%< Sent Response code stats */ - - ns_controls_t * controls; /*%< Control channels */ - unsigned int dispatchgen; - ns_dispatchlist_t dispatches; - - dns_acache_t *acache; - - ns_statschannellist_t statschannels; - - dns_tsigkey_t *sessionkey; - char *session_keyfile; - dns_name_t *session_keyname; - unsigned int session_keyalg; - uint16_t session_keybits; - bool interface_auto; - unsigned char secret[32]; /*%< Server Cookie Secret */ - ns_altsecretlist_t altsecrets; - ns_cookiealg_t cookiealg; - bool answercookie; - - dns_dtenv_t *dtenv; /*%< Dnstap environment */ - - char * lockfile; - - uint16_t transfer_tcp_message_size; - isc_rng_t * rngctx; -}; - -struct ns_altsecret { - ISC_LINK(ns_altsecret_t) link; - unsigned char secret[32]; -}; - -#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') -#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC) - -/*% - * Server statistics counters. Used as isc_statscounter_t values. - */ -enum { - dns_nsstatscounter_requestv4 = 0, - dns_nsstatscounter_requestv6 = 1, - dns_nsstatscounter_edns0in = 2, - dns_nsstatscounter_badednsver = 3, - dns_nsstatscounter_tsigin = 4, - dns_nsstatscounter_sig0in = 5, - dns_nsstatscounter_invalidsig = 6, - dns_nsstatscounter_requesttcp = 7, - - dns_nsstatscounter_authrej = 8, - dns_nsstatscounter_recurserej = 9, - dns_nsstatscounter_xfrrej = 10, - dns_nsstatscounter_updaterej = 11, - - dns_nsstatscounter_response = 12, - dns_nsstatscounter_truncatedresp = 13, - dns_nsstatscounter_edns0out = 14, - dns_nsstatscounter_tsigout = 15, - dns_nsstatscounter_sig0out = 16, - - dns_nsstatscounter_success = 17, - dns_nsstatscounter_authans = 18, - dns_nsstatscounter_nonauthans = 19, - dns_nsstatscounter_referral = 20, - dns_nsstatscounter_nxrrset = 21, - dns_nsstatscounter_servfail = 22, - dns_nsstatscounter_formerr = 23, - dns_nsstatscounter_nxdomain = 24, - dns_nsstatscounter_recursion = 25, - dns_nsstatscounter_duplicate = 26, - dns_nsstatscounter_dropped = 27, - dns_nsstatscounter_failure = 28, - - dns_nsstatscounter_xfrdone = 29, - - dns_nsstatscounter_updatereqfwd = 30, - dns_nsstatscounter_updaterespfwd = 31, - dns_nsstatscounter_updatefwdfail = 32, - dns_nsstatscounter_updatedone = 33, - dns_nsstatscounter_updatefail = 34, - dns_nsstatscounter_updatebadprereq = 35, - - dns_nsstatscounter_recursclients = 36, - - dns_nsstatscounter_dns64 = 37, - - dns_nsstatscounter_ratedropped = 38, - dns_nsstatscounter_rateslipped = 39, - - dns_nsstatscounter_rpz_rewrites = 40, - - dns_nsstatscounter_udp = 41, - dns_nsstatscounter_tcp = 42, - - dns_nsstatscounter_nsidopt = 43, - dns_nsstatscounter_expireopt = 44, - dns_nsstatscounter_otheropt = 45, - dns_nsstatscounter_ecsopt = 46, - - dns_nsstatscounter_nxdomainredirect = 47, - dns_nsstatscounter_nxdomainredirect_rlookup = 48, - - dns_nsstatscounter_cookiein = 49, - dns_nsstatscounter_cookiebadsize = 50, - dns_nsstatscounter_cookiebadtime = 51, - dns_nsstatscounter_cookienomatch = 52, - dns_nsstatscounter_cookiematch = 53, - dns_nsstatscounter_cookienew = 54, - dns_nsstatscounter_badcookie = 55, - - dns_nsstatscounter_keytagopt = 56, - - dns_nsstatscounter_tcphighwater = 57, - - dns_nsstatscounter_reclimitdropped = 58, - - dns_nsstatscounter_trystale = 59, - dns_nsstatscounter_usedstale = 60, - - dns_nsstatscounter_max = 61 -}; - -/*% - * Traffic size statistics counters. Used as isc_statscounter_t values. - */ -enum { - dns_sizecounter_in_0 = 0, - dns_sizecounter_in_16 = 1, - dns_sizecounter_in_32 = 2, - dns_sizecounter_in_48 = 3, - dns_sizecounter_in_64 = 4, - dns_sizecounter_in_80 = 5, - dns_sizecounter_in_96 = 6, - dns_sizecounter_in_112 = 7, - dns_sizecounter_in_128 = 8, - dns_sizecounter_in_144 = 9, - dns_sizecounter_in_160 = 10, - dns_sizecounter_in_176 = 11, - dns_sizecounter_in_192 = 12, - dns_sizecounter_in_208 = 13, - dns_sizecounter_in_224 = 14, - dns_sizecounter_in_240 = 15, - dns_sizecounter_in_256 = 16, - dns_sizecounter_in_272 = 17, - dns_sizecounter_in_288 = 18, - - dns_sizecounter_in_max = 19, -}; - -enum { - dns_sizecounter_out_0 = 0, - dns_sizecounter_out_16 = 1, - dns_sizecounter_out_32 = 2, - dns_sizecounter_out_48 = 3, - dns_sizecounter_out_64 = 4, - dns_sizecounter_out_80 = 5, - dns_sizecounter_out_96 = 6, - dns_sizecounter_out_112 = 7, - dns_sizecounter_out_128 = 8, - dns_sizecounter_out_144 = 9, - dns_sizecounter_out_160 = 10, - dns_sizecounter_out_176 = 11, - dns_sizecounter_out_192 = 12, - dns_sizecounter_out_208 = 13, - dns_sizecounter_out_224 = 14, - dns_sizecounter_out_240 = 15, - dns_sizecounter_out_256 = 16, - dns_sizecounter_out_272 = 17, - dns_sizecounter_out_288 = 18, - dns_sizecounter_out_304 = 19, - dns_sizecounter_out_320 = 20, - dns_sizecounter_out_336 = 21, - dns_sizecounter_out_352 = 22, - dns_sizecounter_out_368 = 23, - dns_sizecounter_out_384 = 24, - dns_sizecounter_out_400 = 25, - dns_sizecounter_out_416 = 26, - dns_sizecounter_out_432 = 27, - dns_sizecounter_out_448 = 28, - dns_sizecounter_out_464 = 29, - dns_sizecounter_out_480 = 30, - dns_sizecounter_out_496 = 31, - dns_sizecounter_out_512 = 32, - dns_sizecounter_out_528 = 33, - dns_sizecounter_out_544 = 34, - dns_sizecounter_out_560 = 35, - dns_sizecounter_out_576 = 36, - dns_sizecounter_out_592 = 37, - dns_sizecounter_out_608 = 38, - dns_sizecounter_out_624 = 39, - dns_sizecounter_out_640 = 40, - dns_sizecounter_out_656 = 41, - dns_sizecounter_out_672 = 42, - dns_sizecounter_out_688 = 43, - dns_sizecounter_out_704 = 44, - dns_sizecounter_out_720 = 45, - dns_sizecounter_out_736 = 46, - dns_sizecounter_out_752 = 47, - dns_sizecounter_out_768 = 48, - dns_sizecounter_out_784 = 49, - dns_sizecounter_out_800 = 50, - dns_sizecounter_out_816 = 51, - dns_sizecounter_out_832 = 52, - dns_sizecounter_out_848 = 53, - dns_sizecounter_out_864 = 54, - dns_sizecounter_out_880 = 55, - dns_sizecounter_out_896 = 56, - dns_sizecounter_out_912 = 57, - dns_sizecounter_out_928 = 58, - dns_sizecounter_out_944 = 59, - dns_sizecounter_out_960 = 60, - dns_sizecounter_out_976 = 61, - dns_sizecounter_out_992 = 62, - dns_sizecounter_out_1008 = 63, - dns_sizecounter_out_1024 = 64, - dns_sizecounter_out_1040 = 65, - dns_sizecounter_out_1056 = 66, - dns_sizecounter_out_1072 = 67, - dns_sizecounter_out_1088 = 68, - dns_sizecounter_out_1104 = 69, - dns_sizecounter_out_1120 = 70, - dns_sizecounter_out_1136 = 71, - dns_sizecounter_out_1152 = 72, - dns_sizecounter_out_1168 = 73, - dns_sizecounter_out_1184 = 74, - dns_sizecounter_out_1200 = 75, - dns_sizecounter_out_1216 = 76, - dns_sizecounter_out_1232 = 77, - dns_sizecounter_out_1248 = 78, - dns_sizecounter_out_1264 = 79, - dns_sizecounter_out_1280 = 80, - dns_sizecounter_out_1296 = 81, - dns_sizecounter_out_1312 = 82, - dns_sizecounter_out_1328 = 83, - dns_sizecounter_out_1344 = 84, - dns_sizecounter_out_1360 = 85, - dns_sizecounter_out_1376 = 86, - dns_sizecounter_out_1392 = 87, - dns_sizecounter_out_1408 = 88, - dns_sizecounter_out_1424 = 89, - dns_sizecounter_out_1440 = 90, - dns_sizecounter_out_1456 = 91, - dns_sizecounter_out_1472 = 92, - dns_sizecounter_out_1488 = 93, - dns_sizecounter_out_1504 = 94, - dns_sizecounter_out_1520 = 95, - dns_sizecounter_out_1536 = 96, - dns_sizecounter_out_1552 = 97, - dns_sizecounter_out_1568 = 98, - dns_sizecounter_out_1584 = 99, - dns_sizecounter_out_1600 = 100, - dns_sizecounter_out_1616 = 101, - dns_sizecounter_out_1632 = 102, - dns_sizecounter_out_1648 = 103, - dns_sizecounter_out_1664 = 104, - dns_sizecounter_out_1680 = 105, - dns_sizecounter_out_1696 = 106, - dns_sizecounter_out_1712 = 107, - dns_sizecounter_out_1728 = 108, - dns_sizecounter_out_1744 = 109, - dns_sizecounter_out_1760 = 110, - dns_sizecounter_out_1776 = 111, - dns_sizecounter_out_1792 = 112, - dns_sizecounter_out_1808 = 113, - dns_sizecounter_out_1824 = 114, - dns_sizecounter_out_1840 = 115, - dns_sizecounter_out_1856 = 116, - dns_sizecounter_out_1872 = 117, - dns_sizecounter_out_1888 = 118, - dns_sizecounter_out_1904 = 119, - dns_sizecounter_out_1920 = 120, - dns_sizecounter_out_1936 = 121, - dns_sizecounter_out_1952 = 122, - dns_sizecounter_out_1968 = 123, - dns_sizecounter_out_1984 = 124, - dns_sizecounter_out_2000 = 125, - dns_sizecounter_out_2016 = 126, - dns_sizecounter_out_2032 = 127, - dns_sizecounter_out_2048 = 128, - dns_sizecounter_out_2064 = 129, - dns_sizecounter_out_2080 = 130, - dns_sizecounter_out_2096 = 131, - dns_sizecounter_out_2112 = 132, - dns_sizecounter_out_2128 = 133, - dns_sizecounter_out_2144 = 134, - dns_sizecounter_out_2160 = 135, - dns_sizecounter_out_2176 = 136, - dns_sizecounter_out_2192 = 137, - dns_sizecounter_out_2208 = 138, - dns_sizecounter_out_2224 = 139, - dns_sizecounter_out_2240 = 140, - dns_sizecounter_out_2256 = 141, - dns_sizecounter_out_2272 = 142, - dns_sizecounter_out_2288 = 143, - dns_sizecounter_out_2304 = 144, - dns_sizecounter_out_2320 = 145, - dns_sizecounter_out_2336 = 146, - dns_sizecounter_out_2352 = 147, - dns_sizecounter_out_2368 = 148, - dns_sizecounter_out_2384 = 149, - dns_sizecounter_out_2400 = 150, - dns_sizecounter_out_2416 = 151, - dns_sizecounter_out_2432 = 152, - dns_sizecounter_out_2448 = 153, - dns_sizecounter_out_2464 = 154, - dns_sizecounter_out_2480 = 155, - dns_sizecounter_out_2496 = 156, - dns_sizecounter_out_2512 = 157, - dns_sizecounter_out_2528 = 158, - dns_sizecounter_out_2544 = 159, - dns_sizecounter_out_2560 = 160, - dns_sizecounter_out_2576 = 161, - dns_sizecounter_out_2592 = 162, - dns_sizecounter_out_2608 = 163, - dns_sizecounter_out_2624 = 164, - dns_sizecounter_out_2640 = 165, - dns_sizecounter_out_2656 = 166, - dns_sizecounter_out_2672 = 167, - dns_sizecounter_out_2688 = 168, - dns_sizecounter_out_2704 = 169, - dns_sizecounter_out_2720 = 170, - dns_sizecounter_out_2736 = 171, - dns_sizecounter_out_2752 = 172, - dns_sizecounter_out_2768 = 173, - dns_sizecounter_out_2784 = 174, - dns_sizecounter_out_2800 = 175, - dns_sizecounter_out_2816 = 176, - dns_sizecounter_out_2832 = 177, - dns_sizecounter_out_2848 = 178, - dns_sizecounter_out_2864 = 179, - dns_sizecounter_out_2880 = 180, - dns_sizecounter_out_2896 = 181, - dns_sizecounter_out_2912 = 182, - dns_sizecounter_out_2928 = 183, - dns_sizecounter_out_2944 = 184, - dns_sizecounter_out_2960 = 185, - dns_sizecounter_out_2976 = 186, - dns_sizecounter_out_2992 = 187, - dns_sizecounter_out_3008 = 188, - dns_sizecounter_out_3024 = 189, - dns_sizecounter_out_3040 = 190, - dns_sizecounter_out_3056 = 191, - dns_sizecounter_out_3072 = 192, - dns_sizecounter_out_3088 = 193, - dns_sizecounter_out_3104 = 194, - dns_sizecounter_out_3120 = 195, - dns_sizecounter_out_3136 = 196, - dns_sizecounter_out_3152 = 197, - dns_sizecounter_out_3168 = 198, - dns_sizecounter_out_3184 = 199, - dns_sizecounter_out_3200 = 200, - dns_sizecounter_out_3216 = 201, - dns_sizecounter_out_3232 = 202, - dns_sizecounter_out_3248 = 203, - dns_sizecounter_out_3264 = 204, - dns_sizecounter_out_3280 = 205, - dns_sizecounter_out_3296 = 206, - dns_sizecounter_out_3312 = 207, - dns_sizecounter_out_3328 = 208, - dns_sizecounter_out_3344 = 209, - dns_sizecounter_out_3360 = 210, - dns_sizecounter_out_3376 = 211, - dns_sizecounter_out_3392 = 212, - dns_sizecounter_out_3408 = 213, - dns_sizecounter_out_3424 = 214, - dns_sizecounter_out_3440 = 215, - dns_sizecounter_out_3456 = 216, - dns_sizecounter_out_3472 = 217, - dns_sizecounter_out_3488 = 218, - dns_sizecounter_out_3504 = 219, - dns_sizecounter_out_3520 = 220, - dns_sizecounter_out_3536 = 221, - dns_sizecounter_out_3552 = 222, - dns_sizecounter_out_3568 = 223, - dns_sizecounter_out_3584 = 224, - dns_sizecounter_out_3600 = 225, - dns_sizecounter_out_3616 = 226, - dns_sizecounter_out_3632 = 227, - dns_sizecounter_out_3648 = 228, - dns_sizecounter_out_3664 = 229, - dns_sizecounter_out_3680 = 230, - dns_sizecounter_out_3696 = 231, - dns_sizecounter_out_3712 = 232, - dns_sizecounter_out_3728 = 233, - dns_sizecounter_out_3744 = 234, - dns_sizecounter_out_3760 = 235, - dns_sizecounter_out_3776 = 236, - dns_sizecounter_out_3792 = 237, - dns_sizecounter_out_3808 = 238, - dns_sizecounter_out_3824 = 239, - dns_sizecounter_out_3840 = 240, - dns_sizecounter_out_3856 = 241, - dns_sizecounter_out_3872 = 242, - dns_sizecounter_out_3888 = 243, - dns_sizecounter_out_3904 = 244, - dns_sizecounter_out_3920 = 245, - dns_sizecounter_out_3936 = 246, - dns_sizecounter_out_3952 = 247, - dns_sizecounter_out_3968 = 248, - dns_sizecounter_out_3984 = 249, - dns_sizecounter_out_4000 = 250, - dns_sizecounter_out_4016 = 251, - dns_sizecounter_out_4032 = 252, - dns_sizecounter_out_4048 = 253, - dns_sizecounter_out_4064 = 254, - dns_sizecounter_out_4080 = 255, - dns_sizecounter_out_4096 = 256, - - dns_sizecounter_out_max = 257 -}; - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); -/*%< - * Create a server object with default settings. - * This function either succeeds or causes the program to exit - * with a fatal error. - */ - -void -ns_server_destroy(ns_server_t **serverp); -/*%< - * Destroy a server object, freeing its memory. - */ - -void -ns_server_reloadwanted(ns_server_t *server); -/*%< - * Inform a server that a reload is wanted. This function - * may be called asynchronously, from outside the server's task. - * If a reload is already scheduled or in progress, the call - * is ignored. - */ - -void -ns_server_scan_interfaces(ns_server_t *server); -/*%< - * Trigger a interface scan. - * Must only be called when running under server->task. - */ - -void -ns_server_flushonshutdown(ns_server_t *server, bool flush); -/*%< - * Inform the server that the zones should be flushed to disk on shutdown. - */ - -isc_result_t -ns_server_reloadcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "reload" command from the command channel. - */ - -isc_result_t -ns_server_reconfigcommand(ns_server_t *server); -/*%< - * Act on a "reconfig" command from the command channel. - */ - -isc_result_t -ns_server_notifycommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "notify" command from the command channel. - */ - -isc_result_t -ns_server_refreshcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "refresh" command from the command channel. - */ - -isc_result_t -ns_server_retransfercommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -/*%< - * Act on a "retransfer" command from the command channel. - */ - -isc_result_t -ns_server_togglequerylog(ns_server_t *server, isc_lex_t *lex); -/*%< - * Enable/disable logging of queries. (Takes "yes" or "no" argument, - * but can also be used as a toggle for backward comptibility.) - */ - -/*% - * Save the current NTAs for all views to files. - */ -isc_result_t -ns_server_saventa(ns_server_t *server); - -/*% - * Load NTAs for all views from files. - */ -isc_result_t -ns_server_loadnta(ns_server_t *server); - -/*% - * Dump the current statistics to the statistics file. - */ -isc_result_t -ns_server_dumpstats(ns_server_t *server); - -/*% - * Dump the current cache to the dump file. - */ -isc_result_t -ns_server_dumpdb(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump the current security roots to the secroots file. - */ -isc_result_t -ns_server_dumpsecroots(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); - -/*% - * Change or increment the server debug level. - */ -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, isc_lex_t *lex); - -/*% - * Flush the server's cache(s) - */ -isc_result_t -ns_server_flushcache(ns_server_t *server, isc_lex_t *lex); - -/*% - * Flush a particular name from the server's cache. If 'tree' is false, - * also flush the name from the ADB and badcache. If 'tree' is true, also - * flush all the names under the specified name. - */ -isc_result_t -ns_server_flushnode(ns_server_t *server, isc_lex_t *lex, - bool tree); - -/*% - * Report the server's status. - */ -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t **text); - -/*% - * Report a list of dynamic and static tsig keys, per view. - */ -isc_result_t -ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text); - -/*% - * Delete a specific key (with optional view). - */ -isc_result_t -ns_server_tsigdelete(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); - -/*% - * Enable or disable updates for a zone. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, bool freeze, - isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump zone updates to disk, optionally removing the journal file - */ -isc_result_t -ns_server_sync(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Update a zone's DNSKEY set from the key repository. If - * the command that triggered the call to this function was "sign", - * then force a full signing of the zone. If it was "loadkeys", - * then don't sign the zone; any needed changes to signatures can - * take place incrementally. - */ -isc_result_t -ns_server_rekey(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Dump the current recursive queries. - */ -isc_result_t -ns_server_dumprecursing(ns_server_t *server); - -/*% - * Maintain a list of dispatches that require reserved ports. - */ -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr); - -/*% - * Enable or disable dnssec validation. - */ -isc_result_t -ns_server_validation(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Add a zone to a running process, or modify an existing zone - */ -isc_result_t -ns_server_changezone(ns_server_t *server, char *command, isc_buffer_t **text); - -/*% - * Deletes a zone from a running process - */ -isc_result_t -ns_server_delzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Show current configuration for a given zone - */ -isc_result_t -ns_server_showzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Lists the status of the signing records for a given zone. - */ -isc_result_t -ns_server_signing(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Lists status information for a given zone (e.g., name, type, files, - * load time, expiry, etc). - */ -isc_result_t -ns_server_zonestatus(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Adds/updates a Negative Trust Anchor (NTA) for a specified name and - * duration, in a particular view if specified, or in all views. - */ -isc_result_t -ns_server_nta(ns_server_t *server, isc_lex_t *lex, bool readonly, - isc_buffer_t **text); - -/*% - * Generates a test sequence that is only for use in system tests. The - * argument is the size of required output in bytes. - */ -isc_result_t -ns_server_testgen(isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Force fefresh or print status for managed keys zones. - */ -isc_result_t -ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Close and reopen DNSTAP output file. - */ -isc_result_t -ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - - -/*% - * Control whether stale answers are served or not when configured in - * named.conf. - */ -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); -#endif /* NAMED_SERVER_H */ diff --git a/bin/named-sdb/include/named/sortlist.h b/bin/named-sdb/include/named/sortlist.h deleted file mode 100644 index 0c4e17d..0000000 --- a/bin/named-sdb/include/named/sortlist.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_SORTLIST_H -#define NAMED_SORTLIST_H 1 - -/*! \file */ - -#include - -#include - -/*% - * Type for callback functions that rank addresses. - */ -typedef int -(*dns_addressorderfunc_t)(const isc_netaddr_t *address, const void *arg); - -/*% - * Return value type for setup_sortlist. - */ -typedef enum { - NS_SORTLISTTYPE_NONE, - NS_SORTLISTTYPE_1ELEMENT, - NS_SORTLISTTYPE_2ELEMENT -} ns_sortlisttype_t; - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * - * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and - * make '*argp' point to the matching subelement. - * - * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and - * make '*argp' point to ACL that forms the second element. - * - * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' - * to NULL. - */ - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', the matching element - * of a 1-element top-level sortlist statement. - */ - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', a topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * If a sortlist statement applies, return in '*orderp' a pointer to a function - * for ranking network addresses based on that sortlist statement, and in - * '*argp' an argument to pass to said function. If no sortlist statement - * applies, set '*orderp' and '*argp' to NULL. - */ - -#endif /* NAMED_SORTLIST_H */ diff --git a/bin/named-sdb/include/named/statschannel.h b/bin/named-sdb/include/named/statschannel.h deleted file mode 100644 index c107c29..0000000 --- a/bin/named-sdb/include/named/statschannel.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_STATSCHANNEL_H -#define NAMED_STATSCHANNEL_H 1 - -/*! \file - * \brief - * The statistics channels built-in the name server. - */ - -#include - -#include - -#include - -#define NS_STATSCHANNEL_HTTPPORT 80 - -isc_result_t -ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx); -/*%< - * [Re]configure the statistics channels. - * - * If it is no longer there but was previously configured, destroy - * it here. - * - * If the IP address or port has changed, destroy the old server - * and create a new one. - */ - - -void -ns_statschannels_shutdown(ns_server_t *server); -/*%< - * Initiate shutdown of all the statistics channel listeners. - */ - -isc_result_t -ns_stats_dump(ns_server_t *server, FILE *fp); -/*%< - * Dump statistics counters managed by the server to the file fp. - */ - -#endif /* NAMED_STATSCHANNEL_H */ diff --git a/bin/named-sdb/include/named/tkeyconf.h b/bin/named-sdb/include/named/tkeyconf.h deleted file mode 100644 index 7c2d8a8..0000000 --- a/bin/named-sdb/include/named/tkeyconf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_TKEYCONF_H -#define NS_TKEYCONF_H 1 - -/*! \file */ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); -/*%< - * Create a TKEY context and configure it, including the default DH key - * and default domain, according to 'options'. - * - * Requires: - *\li 'cfg' is a valid configuration options object. - *\li 'mctx' is not NULL - *\li 'ectx' is not NULL - *\li 'tctx' is not NULL - *\li '*tctx' is NULL - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TKEYCONF_H */ diff --git a/bin/named-sdb/include/named/tsigconf.h b/bin/named-sdb/include/named/tsigconf.h deleted file mode 100644 index 87ddc5e..0000000 --- a/bin/named-sdb/include/named/tsigconf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_TSIGCONF_H -#define NS_TSIGCONF_H 1 - -/*! \file */ - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/*%< - * Create a TSIG key ring and configure it according to the 'key' - * statements in the global and view configuration objects. - * - * Requires: - * \li 'config' is not NULL. - * \li 'vconfig' is not NULL. - * \li 'mctx' is not NULL - * \li 'ringp' is not NULL, and '*ringp' is NULL - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TSIGCONF_H */ diff --git a/bin/named-sdb/include/named/types.h b/bin/named-sdb/include/named/types.h deleted file mode 100644 index 8a045e0..0000000 --- a/bin/named-sdb/include/named/types.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_TYPES_H -#define NAMED_TYPES_H 1 - -/*! \file */ - -#include - -typedef struct ns_cache ns_cache_t; -typedef ISC_LIST(ns_cache_t) ns_cachelist_t; -typedef struct ns_client ns_client_t; -typedef struct ns_clientmgr ns_clientmgr_t; -typedef struct ns_query ns_query_t; -typedef struct ns_server ns_server_t; -typedef struct ns_xmld ns_xmld_t; -typedef struct ns_xmldmgr ns_xmldmgr_t; -typedef struct ns_interface ns_interface_t; -typedef struct ns_interfacemgr ns_interfacemgr_t; -typedef struct ns_lwresd ns_lwresd_t; -typedef struct ns_lwreslistener ns_lwreslistener_t; -typedef struct ns_lwdclient ns_lwdclient_t; -typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; -typedef struct ns_lwsearchlist ns_lwsearchlist_t; -typedef struct ns_lwsearchctx ns_lwsearchctx_t; -typedef struct ns_controls ns_controls_t; -typedef struct ns_dispatch ns_dispatch_t; -typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; -typedef struct ns_statschannel ns_statschannel_t; -typedef ISC_LIST(ns_statschannel_t) ns_statschannellist_t; -typedef struct ns_altsecret ns_altsecret_t; -typedef ISC_LIST(ns_altsecret_t) ns_altsecretlist_t; - -typedef enum { - ns_cookiealg_aes, - ns_cookiealg_sha1, - ns_cookiealg_sha256, - ns_cookiealg_siphash24 -} ns_cookiealg_t; - -#define NS_COOKIE_VERSION_1 1 - -#endif /* NAMED_TYPES_H */ diff --git a/bin/named-sdb/include/named/update.h b/bin/named-sdb/include/named/update.h deleted file mode 100644 index 484ad95..0000000 --- a/bin/named-sdb/include/named/update.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_UPDATE_H -#define NAMED_UPDATE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * RFC2136 Dynamic Update - */ - -/*** - *** Imports - ***/ - -#include -#include - -/*** - *** Types. - ***/ - -/*** - *** Functions - ***/ - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult); - -#endif /* NAMED_UPDATE_H */ diff --git a/bin/named-sdb/include/named/xfrout.h b/bin/named-sdb/include/named/xfrout.h deleted file mode 100644 index a0fc886..0000000 --- a/bin/named-sdb/include/named/xfrout.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NAMED_XFROUT_H -#define NAMED_XFROUT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * Outgoing zone transfers (AXFR + IXFR). - */ - -/*** - *** Functions - ***/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); - -#endif /* NAMED_XFROUT_H */ diff --git a/bin/named-sdb/include/named/zoneconf.h b/bin/named-sdb/include/named/zoneconf.h deleted file mode 100644 index a5d367b..0000000 --- a/bin/named-sdb/include/named/zoneconf.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_ZONECONF_H -#define NS_ZONECONF_H 1 - -/*! \file */ - -#include -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone, dns_zone_t *raw); -/*%< - * Configure or reconfigure a zone according to the named.conf - * data in 'cctx' and 'czone'. - * - * The zone origin is not configured, it is assumed to have been set - * at zone creation time. - * - * Require: - * \li 'lctx' to be initialized or NULL. - * \li 'cctx' to be initialized or NULL. - * \li 'ac' to point to an initialized ns_aclconfctx_t. - * \li 'czone' to be initialized. - * \li 'zone' to be initialized. - */ - -bool -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig); -/*%< - * If 'zone' can be safely reconfigured according to the configuration - * data in 'zconfig', return true. If the configuration data is so - * different from the current zone state that the zone needs to be destroyed - * and recreated, return false. - */ - -isc_result_t -ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, - dns_rdataclass_t rdclass, dns_name_t *name); -/*%> - * configure a DLZ zone, setting up the database methods and calling - * postload to load the origin values - * - * Require: - * \li 'dlzdatabase' to be a valid dlz database - * \li 'zone' to be initialized. - * \li 'rdclass' to be a valid rdataclass - * \li 'name' to be a valid zone origin name - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_ZONECONF_H */ diff --git a/bin/named-sdb/interfacemgr.c b/bin/named-sdb/interfacemgr.c deleted file mode 100644 index e12fad9..0000000 --- a/bin/named-sdb/interfacemgr.c +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_NET_ROUTE_H -#include -#if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR) -#define USE_ROUTE_SOCKET 1 -#define ROUTE_SOCKET_PROTOCOL PF_ROUTE -#define MSGHDR rt_msghdr -#define MSGTYPE rtm_type -#endif -#endif - -#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) -#include -#include -#if defined(RTM_NEWADDR) && defined(RTM_DELADDR) -#define USE_ROUTE_SOCKET 1 -#define ROUTE_SOCKET_PROTOCOL PF_NETLINK -#define MSGHDR nlmsghdr -#define MSGTYPE nlmsg_type -#endif -#endif - -#ifdef TUNE_LARGE -#define UDPBUFFERS 32768 -#else -#define UDPBUFFERS 1000 -#endif /* TUNE_LARGE */ - -#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') -#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) - -#define IFMGR_COMMON_LOGARGS \ - ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR - -/*% nameserver interface manager structure */ -struct ns_interfacemgr { - unsigned int magic; /*%< Magic number. */ - int references; - isc_mutex_t lock; - isc_mem_t * mctx; /*%< Memory context. */ - isc_taskmgr_t * taskmgr; /*%< Task manager. */ - isc_socketmgr_t * socketmgr; /*%< Socket manager. */ - dns_dispatchmgr_t * dispatchmgr; - unsigned int generation; /*%< Current generation no. */ - ns_listenlist_t * listenon4; - ns_listenlist_t * listenon6; - dns_aclenv_t aclenv; /*%< Localhost/localnets ACLs */ - ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces. */ - ISC_LIST(isc_sockaddr_t) listenon; -#ifdef USE_ROUTE_SOCKET - isc_task_t * task; - isc_socket_t * route; - unsigned char buf[2048]; -#endif -}; - -static void -purge_old_interfaces(ns_interfacemgr_t *mgr); - -static void -clearlistenon(ns_interfacemgr_t *mgr); - -#ifdef USE_ROUTE_SOCKET -static void -route_event(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = NULL; - ns_interfacemgr_t *mgr = NULL; - isc_region_t r; - isc_result_t result; - struct MSGHDR *rtm; - bool done = true; - - UNUSED(task); - - REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); - mgr = event->ev_arg; - sevent = (isc_socketevent_t *)event; - - if (sevent->result != ISC_R_SUCCESS) { - if (sevent->result != ISC_R_CANCELED) - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "automatic interface scanning " - "terminated: %s", - isc_result_totext(sevent->result)); - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; - } - - rtm = (struct MSGHDR *)mgr->buf; -#ifdef RTM_VERSION - if (rtm->rtm_version != RTM_VERSION) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "automatic interface rescanning disabled: " - "rtm->rtm_version mismatch (%u != %u) " - "recompile required", rtm->rtm_version, - RTM_VERSION); - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; - } -#endif - - switch (rtm->MSGTYPE) { - case RTM_NEWADDR: - case RTM_DELADDR: - if (mgr->route != NULL && ns_g_server->interface_auto) - ns_server_scan_interfaces(ns_g_server); - break; - default: - break; - } - - LOCK(&mgr->lock); - if (mgr->route != NULL) { - /* - * Look for next route event. - */ - r.base = mgr->buf; - r.length = sizeof(mgr->buf); - result = isc_socket_recv(mgr->route, &r, 1, mgr->task, - route_event, mgr); - if (result == ISC_R_SUCCESS) - done = false; - } - UNLOCK(&mgr->lock); - - if (done) - ns_interfacemgr_detach(&mgr); - isc_event_free(&event); - return; -} -#endif - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - isc_task_t *task, ns_interfacemgr_t **mgrp) -{ - isc_result_t result; - ns_interfacemgr_t *mgr; - -#ifndef USE_ROUTE_SOCKET - UNUSED(task); -#endif - - REQUIRE(mctx != NULL); - REQUIRE(mgrp != NULL); - REQUIRE(*mgrp == NULL); - - mgr = isc_mem_get(mctx, sizeof(*mgr)); - if (mgr == NULL) - return (ISC_R_NOMEMORY); - - mgr->mctx = NULL; - isc_mem_attach(mctx, &mgr->mctx); - - result = isc_mutex_init(&mgr->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - - mgr->taskmgr = taskmgr; - mgr->socketmgr = socketmgr; - mgr->dispatchmgr = dispatchmgr; - mgr->generation = 1; - mgr->listenon4 = NULL; - mgr->listenon6 = NULL; - - ISC_LIST_INIT(mgr->interfaces); - ISC_LIST_INIT(mgr->listenon); - - /* - * The listen-on lists are initially empty. - */ - result = ns_listenlist_create(mctx, &mgr->listenon4); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); - - result = dns_aclenv_init(mctx, &mgr->aclenv); - if (result != ISC_R_SUCCESS) - goto cleanup_listenon; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - mgr->aclenv.geoip = ns_g_geoip; -#endif - -#ifdef USE_ROUTE_SOCKET - mgr->route = NULL; - result = isc_socket_create(mgr->socketmgr, ROUTE_SOCKET_PROTOCOL, - isc_sockettype_raw, &mgr->route); - switch (result) { - case ISC_R_NOPERM: - case ISC_R_SUCCESS: - case ISC_R_NOTIMPLEMENTED: - case ISC_R_FAMILYNOSUPPORT: - break; - default: - goto cleanup_aclenv; - } - - mgr->task = NULL; - if (mgr->route != NULL) - isc_task_attach(task, &mgr->task); - mgr->references = (mgr->route != NULL) ? 2 : 1; -#else - mgr->references = 1; -#endif - mgr->magic = IFMGR_MAGIC; - *mgrp = mgr; - -#ifdef USE_ROUTE_SOCKET - if (mgr->route != NULL) { - isc_region_t r = { mgr->buf, sizeof(mgr->buf) }; - - result = isc_socket_recv(mgr->route, &r, 1, mgr->task, - route_event, mgr); - if (result != ISC_R_SUCCESS) { - isc_task_detach(&mgr->task); - isc_socket_detach(&mgr->route); - ns_interfacemgr_detach(&mgr); - } - } -#endif - return (ISC_R_SUCCESS); - -#ifdef USE_ROUTE_SOCKET - cleanup_aclenv: - dns_aclenv_destroy(&mgr->aclenv); -#endif - cleanup_listenon: - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - cleanup_mem: - isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); - return (result); -} - -static void -ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - -#ifdef USE_ROUTE_SOCKET - if (mgr->route != NULL) - isc_socket_detach(&mgr->route); - if (mgr->task != NULL) - isc_task_detach(&mgr->task); -#endif - dns_aclenv_destroy(&mgr->aclenv); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - clearlistenon(mgr); - DESTROYLOCK(&mgr->lock); - mgr->magic = 0; - isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); -} - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { - return (&mgr->aclenv); -} - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { - REQUIRE(NS_INTERFACEMGR_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp) { - isc_result_t need_destroy = false; - ns_interfacemgr_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACEMGR_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = true; - UNLOCK(&target->lock); - if (need_destroy) - ns_interfacemgr_destroy(target); - *targetp = NULL; -} - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - /*% - * Shut down and detach all interfaces. - * By incrementing the generation count, we make purge_old_interfaces() - * consider all interfaces "old". - */ - mgr->generation++; -#ifdef USE_ROUTE_SOCKET - LOCK(&mgr->lock); - if (mgr->route != NULL) { - isc_socket_cancel(mgr->route, mgr->task, ISC_SOCKCANCEL_RECV); - isc_socket_detach(&mgr->route); - isc_task_detach(&mgr->task); - } - UNLOCK(&mgr->lock); -#endif - purge_old_interfaces(mgr); -} - - -static isc_result_t -ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret) -{ - ns_interface_t *ifp; - isc_result_t result; - int disp; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); - if (ifp == NULL) - return (ISC_R_NOMEMORY); - - ifp->mgr = NULL; - ifp->generation = mgr->generation; - ifp->addr = *addr; - ifp->flags = 0; - strlcpy(ifp->name, name, sizeof(ifp->name)); - ifp->clientmgr = NULL; - - result = isc_mutex_init(&ifp->lock); - if (result != ISC_R_SUCCESS) - goto lock_create_failure; - - result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, - ns_g_timermgr, - &ifp->clientmgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "ns_clientmgr_create() failed: %s", - isc_result_totext(result)); - goto clientmgr_create_failure; - } - - for (disp = 0; disp < MAX_UDP_DISPATCH; disp++) - ifp->udpdispatch[disp] = NULL; - - ifp->tcpsocket = NULL; - - /* - * Create a single TCP client object. It will replace itself - * with a new one as soon as it gets a connection, so the actual - * connections will be handled in parallel even though there is - * only one client initially. - */ - isc_refcount_init(&ifp->ntcpaccepting, 0); - isc_refcount_init(&ifp->ntcpactive, 0); - - ifp->nudpdispatch = 0; - - ifp->dscp = -1; - - ISC_LINK_INIT(ifp, link); - - ns_interfacemgr_attach(mgr, &ifp->mgr); - ISC_LIST_APPEND(mgr->interfaces, ifp, link); - - ifp->references = 1; - ifp->magic = IFACE_MAGIC; - *ifpret = ifp; - - return (ISC_R_SUCCESS); - - clientmgr_create_failure: - DESTROYLOCK(&ifp->lock); - - lock_create_failure: - ifp->magic = 0; - isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); - - return (ISC_R_UNEXPECTED); -} - -static isc_result_t -ns_interface_listenudp(ns_interface_t *ifp) { - isc_result_t result; - unsigned int attrs; - unsigned int attrmask; - int disp, i; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - if (isc_sockaddr_pf(&ifp->addr) == AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_NOLISTEN; - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - - ifp->nudpdispatch = ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH); - for (disp = 0; disp < ifp->nudpdispatch; disp++) { - result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr, - ns_g_socketmgr, - ns_g_taskmgr, &ifp->addr, - 4096, UDPBUFFERS, - 32768, 8219, 8237, - attrs, attrmask, - &ifp->udpdispatch[disp], - disp == 0 - ? NULL - : ifp->udpdispatch[0]); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "could not listen on UDP socket: %s", - isc_result_totext(result)); - goto udp_dispatch_failure; - } - - } - - result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch, - ifp, false); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "UDP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto addtodispatch_failure; - } - - return (ISC_R_SUCCESS); - - addtodispatch_failure: - for (i = disp - 1; i >= 0; i--) { - dns_dispatch_changeattributes(ifp->udpdispatch[i], 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&(ifp->udpdispatch[i])); - } - ifp->nudpdispatch = 0; - - udp_dispatch_failure: - return (result); -} - -static isc_result_t -ns_interface_accepttcp(ns_interface_t *ifp) { - isc_result_t result; - - /* - * Open a TCP socket. - */ - result = isc_socket_create(ifp->mgr->socketmgr, - isc_sockaddr_pf(&ifp->addr), - isc_sockettype_tcp, - &ifp->tcpsocket); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "creating TCP socket: %s", - isc_result_totext(result)); - goto tcp_socket_failure; - } - isc_socket_setname(ifp->tcpsocket, "dispatcher", NULL); -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(ifp->tcpsocket, true); -#endif - result = isc_socket_bind(ifp->tcpsocket, &ifp->addr, - ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "binding TCP socket: %s", - isc_result_totext(result)); - goto tcp_bind_failure; - } - - if (ifp->dscp != -1) - isc_socket_dscp(ifp->tcpsocket, ifp->dscp); - - result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "listening on TCP socket: %s", - isc_result_totext(result)); - goto tcp_listen_failure; - } - - /* - * If/when there a multiple filters listen to the - * result. - */ - (void)isc_socket_filter(ifp->tcpsocket, "dataready"); - - result = ns_clientmgr_createclients(ifp->clientmgr, 1, ifp, true); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "TCP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto accepttcp_failure; - } - return (ISC_R_SUCCESS); - - accepttcp_failure: - tcp_listen_failure: - tcp_bind_failure: - isc_socket_detach(&ifp->tcpsocket); - tcp_socket_failure: - return (result); -} - -static isc_result_t -ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret, - bool accept_tcp, isc_dscp_t dscp, - bool *addr_in_use) -{ - isc_result_t result; - ns_interface_t *ifp = NULL; - REQUIRE(ifpret != NULL && *ifpret == NULL); - REQUIRE(addr_in_use == NULL || *addr_in_use == false); - - result = ns_interface_create(mgr, addr, name, &ifp); - if (result != ISC_R_SUCCESS) - return (result); - - ifp->dscp = dscp; - - result = ns_interface_listenudp(ifp); - if (result != ISC_R_SUCCESS) { - if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) - *addr_in_use = true; - goto cleanup_interface; - } - - if (!ns_g_notcp && accept_tcp == true) { - result = ns_interface_accepttcp(ifp); - if (result != ISC_R_SUCCESS) { - if ((result == ISC_R_ADDRINUSE) && - (addr_in_use != NULL)) - *addr_in_use = true; - - /* - * XXXRTH We don't currently have a way to easily stop - * dispatch service, so we currently return - * ISC_R_SUCCESS (the UDP stuff will work even if TCP - * creation failed). This will be fixed later. - */ - result = ISC_R_SUCCESS; - } - } - *ifpret = ifp; - return (result); - - cleanup_interface: - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - ns_interface_detach(&ifp); - return (result); -} - -void -ns_interface_shutdown(ns_interface_t *ifp) { - if (ifp->clientmgr != NULL) - ns_clientmgr_destroy(&ifp->clientmgr); -} - -static void -ns_interface_destroy(ns_interface_t *ifp) { - isc_mem_t *mctx; - int disp; - - REQUIRE(NS_INTERFACE_VALID(ifp)); - - mctx = ifp->mgr->mctx; - - ns_interface_shutdown(ifp); - - for (disp = 0; disp < ifp->nudpdispatch; disp++) - if (ifp->udpdispatch[disp] != NULL) { - dns_dispatch_changeattributes(ifp->udpdispatch[disp], 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&(ifp->udpdispatch[disp])); - } - - if (ifp->tcpsocket != NULL) - isc_socket_detach(&ifp->tcpsocket); - - DESTROYLOCK(&ifp->lock); - - ns_interfacemgr_detach(&ifp->mgr); - - isc_refcount_destroy(&ifp->ntcpactive); - isc_refcount_destroy(&ifp->ntcpaccepting); - - ifp->magic = 0; - isc_mem_put(mctx, ifp, sizeof(*ifp)); -} - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target) { - REQUIRE(NS_INTERFACE_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interface_detach(ns_interface_t **targetp) { - isc_result_t need_destroy = false; - ns_interface_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACE_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = true; - UNLOCK(&target->lock); - if (need_destroy) - ns_interface_destroy(target); - *targetp = NULL; -} - -/*% - * Search the interface list for an interface whose address and port - * both match those of 'addr'. Return a pointer to it, or NULL if not found. - */ -static ns_interface_t * -find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - ns_interface_t *ifp; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; - ifp = ISC_LIST_NEXT(ifp, link)) { - if (isc_sockaddr_equal(&ifp->addr, addr)) - break; - } - return (ifp); -} - -/*% - * Remove any interfaces whose generation number is not the current one. - */ -static void -purge_old_interfaces(ns_interfacemgr_t *mgr) { - ns_interface_t *ifp, *next; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { - INSIST(NS_INTERFACE_VALID(ifp)); - next = ISC_LIST_NEXT(ifp, link); - if (ifp->generation != mgr->generation) { - char sabuf[256]; - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "no longer listening on %s", sabuf); - ns_interface_shutdown(ifp); - ns_interface_detach(&ifp); - } - } -} - -static isc_result_t -clearacl(isc_mem_t *mctx, dns_acl_t **aclp) { - dns_acl_t *newacl = NULL; - isc_result_t result; - result = dns_acl_create(mctx, 0, &newacl); - if (result != ISC_R_SUCCESS) - return (result); - dns_acl_detach(aclp); - dns_acl_attach(newacl, aclp); - dns_acl_detach(&newacl); - return (ISC_R_SUCCESS); -} - -static bool -listenon_is_ip6_any(ns_listenelt_t *elt) { - REQUIRE(elt && elt->acl); - return dns_acl_isany(elt->acl); -} - -static isc_result_t -setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) { - isc_result_t result; - unsigned int prefixlen; - isc_netaddr_t *netaddr; - - netaddr = &interface->address; - - /* First add localhost address */ - prefixlen = (netaddr->family == AF_INET) ? 32 : 128; - result = dns_iptable_addprefix(mgr->aclenv.localhost->iptable, - netaddr, prefixlen, true); - if (result != ISC_R_SUCCESS) - return (result); - - /* Then add localnets prefix */ - result = isc_netaddr_masktoprefixlen(&interface->netmask, - &prefixlen); - - /* Non contiguous netmasks not allowed by IPv6 arch. */ - if (result != ISC_R_SUCCESS && netaddr->family == AF_INET6) - return (result); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "omitting IPv4 interface %s from " - "localnets ACL: %s", interface->name, - isc_result_totext(result)); - return (ISC_R_SUCCESS); - } - - if (prefixlen == 0U) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "omitting %s interface %s from localnets ACL: " - "zero prefix length detected", - (netaddr->family == AF_INET) ? "IPv4" : "IPv6", - interface->name); - return (ISC_R_SUCCESS); - } - - result = dns_iptable_addprefix(mgr->aclenv.localnets->iptable, - netaddr, prefixlen, true); - if (result != ISC_R_SUCCESS) - return (result); - - return (ISC_R_SUCCESS); -} - -static void -setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, - in_port_t port) -{ - isc_sockaddr_t *addr; - isc_sockaddr_t *old; - - addr = isc_mem_get(mgr->mctx, sizeof(*addr)); - if (addr == NULL) - return; - - isc_sockaddr_fromnetaddr(addr, &interface->address, port); - - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(addr, old)) - break; - - if (old != NULL) - isc_mem_put(mgr->mctx, addr, sizeof(*addr)); - else - ISC_LIST_APPEND(mgr->listenon, addr, link); -} - -static void -clearlistenon(ns_interfacemgr_t *mgr) { - isc_sockaddr_t *old; - - old = ISC_LIST_HEAD(mgr->listenon); - while (old != NULL) { - ISC_LIST_UNLINK(mgr->listenon, old, link); - isc_mem_put(mgr->mctx, old, sizeof(*old)); - old = ISC_LIST_HEAD(mgr->listenon); - } -} - -static isc_result_t -do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - bool verbose) -{ - isc_interfaceiter_t *iter = NULL; - bool scan_ipv4 = false; - bool scan_ipv6 = false; - bool adjusting = false; - bool ipv6only = true; - bool ipv6pktinfo = true; - isc_result_t result; - isc_netaddr_t zero_address, zero_address6; - ns_listenelt_t *le; - isc_sockaddr_t listen_addr; - ns_interface_t *ifp; - bool log_explicit = false; - bool dolistenon; - char sabuf[ISC_SOCKADDR_FORMATSIZE]; - bool tried_listening; - bool all_addresses_in_use; - - if (ext_listen != NULL) - adjusting = true; - - if (isc_net_probeipv6() == ISC_R_SUCCESS) - scan_ipv6 = true; -#ifdef WANT_IPV6 - else if (!ns_g_disable6) - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv6 interfaces found"); -#endif - - if (isc_net_probeipv4() == ISC_R_SUCCESS) - scan_ipv4 = true; - else if (!ns_g_disable4) - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv4 interfaces found"); - - /* - * A special, but typical case; listen-on-v6 { any; }. - * When we can make the socket IPv6-only, open a single wildcard - * socket for IPv6 communication. Otherwise, make separate socket - * for each IPv6 address in order to avoid accepting IPv4 packets - * as the form of mapped addresses unintentionally unless explicitly - * allowed. - */ -#ifndef ISC_ALLOW_MAPPED - if (scan_ipv6 == true && - isc_net_probe_ipv6only() != ISC_R_SUCCESS) { - ipv6only = false; - log_explicit = true; - } -#endif - if (scan_ipv6 == true && - isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { - ipv6pktinfo = false; - log_explicit = true; - } - if (scan_ipv6 == true && ipv6only && ipv6pktinfo) { - for (le = ISC_LIST_HEAD(mgr->listenon6->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) { - struct in6_addr in6a; - - if (!listenon_is_ip6_any(le)) - continue; - - in6a = in6addr_any; - isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); - - ifp = find_matching_interface(mgr, &listen_addr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - if (le->dscp != -1 && ifp->dscp == -1) - ifp->dscp = le->dscp; - else if (le->dscp != ifp->dscp) { - isc_sockaddr_format(&listen_addr, - sabuf, - sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "%s: conflicting DSCP " - "values, using %d", - sabuf, ifp->dscp); - } - } else { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "listening on IPv6 " - "interfaces, port %u", - le->port); - result = ns_interface_setup(mgr, &listen_addr, - "", &ifp, - true, - le->dscp, - NULL); - if (result == ISC_R_SUCCESS) - ifp->flags |= NS_INTERFACEFLAG_ANYADDR; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "listening on all IPv6 " - "interfaces failed"); - /* Continue. */ - } - } - } - - isc_netaddr_any(&zero_address); - isc_netaddr_any6(&zero_address6); - - result = isc_interfaceiter_create(mgr->mctx, &iter); - if (result != ISC_R_SUCCESS) - return (result); - - if (adjusting == false) { - result = clearacl(mgr->mctx, &mgr->aclenv.localhost); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - result = clearacl(mgr->mctx, &mgr->aclenv.localnets); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - clearlistenon(mgr); - } - - tried_listening = false; - all_addresses_in_use = true; - for (result = isc_interfaceiter_first(iter); - result == ISC_R_SUCCESS; - result = isc_interfaceiter_next(iter)) - { - isc_interface_t interface; - ns_listenlist_t *ll; - unsigned int family; - - result = isc_interfaceiter_current(iter, &interface); - if (result != ISC_R_SUCCESS) - break; - - family = interface.address.family; - if (family != AF_INET && family != AF_INET6) - continue; - if (scan_ipv4 == false && family == AF_INET) - continue; - if (scan_ipv6 == false && family == AF_INET6) - continue; - - /* - * Test for the address being nonzero rather than testing - * INTERFACE_F_UP, because on some systems the latter - * follows the media state and we could end up ignoring - * the interface for an entire rescan interval due to - * a temporary media glitch at rescan time. - */ - if (family == AF_INET && - isc_netaddr_equal(&interface.address, &zero_address)) { - continue; - } - if (family == AF_INET6 && - isc_netaddr_equal(&interface.address, &zero_address6)) { - continue; - } - - if (adjusting == false) { - /* - * If running with -T fixedlocal, then we only - * want 127.0.0.1 and ::1 in the localhost ACL. - */ - if (ns_g_fixedlocal && - !isc_netaddr_isloopback(&interface.address)) - { - goto listenon; - } - - result = setup_locals(mgr, &interface); - if (result != ISC_R_SUCCESS) - goto ignore_interface; - } - - listenon: - ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; - dolistenon = true; - for (le = ISC_LIST_HEAD(ll->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) - { - int match; - bool ipv6_wildcard = false; - isc_netaddr_t listen_netaddr; - isc_sockaddr_t listen_sockaddr; - - /* - * Construct a socket address for this IP/port - * combination. - */ - if (family == AF_INET) { - isc_netaddr_fromin(&listen_netaddr, - &interface.address.type.in); - } else { - isc_netaddr_fromin6(&listen_netaddr, - &interface.address.type.in6); - isc_netaddr_setzone(&listen_netaddr, - interface.address.zone); - } - isc_sockaddr_fromnetaddr(&listen_sockaddr, - &listen_netaddr, - le->port); - - /* - * See if the address matches the listen-on statement; - * if not, ignore the interface. - */ - (void)dns_acl_match(&listen_netaddr, NULL, le->acl, - &mgr->aclenv, &match, NULL); - if (match <= 0) - continue; - - if (adjusting == false && dolistenon == true) { - setup_listenon(mgr, &interface, le->port); - dolistenon = false; - } - - /* - * The case of "any" IPv6 address will require - * special considerations later, so remember it. - */ - if (family == AF_INET6 && ipv6only && ipv6pktinfo && - listenon_is_ip6_any(le)) - ipv6_wildcard = true; - - /* - * When adjusting interfaces with extra a listening - * list, see if the address matches the extra list. - * If it does, and is also covered by a wildcard - * interface, we need to listen on the address - * explicitly. - */ - if (adjusting == true) { - ns_listenelt_t *ele; - - match = 0; - for (ele = ISC_LIST_HEAD(ext_listen->elts); - ele != NULL; - ele = ISC_LIST_NEXT(ele, link)) { - (void)dns_acl_match(&listen_netaddr, - NULL, ele->acl, - NULL, &match, NULL); - if (match > 0 && - (ele->port == le->port || - ele->port == 0)) - break; - else - match = 0; - } - if (ipv6_wildcard == true && match == 0) - continue; - } - - ifp = find_matching_interface(mgr, &listen_sockaddr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - if (le->dscp != -1 && ifp->dscp == -1) - ifp->dscp = le->dscp; - else if (le->dscp != ifp->dscp) { - isc_sockaddr_format(&listen_sockaddr, - sabuf, - sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "%s: conflicting DSCP " - "values, using %d", - sabuf, ifp->dscp); - } - } else { - bool addr_in_use = false; - - if (adjusting == false && - ipv6_wildcard == true) - continue; - - if (log_explicit && family == AF_INET6 && - !adjusting && listenon_is_ip6_any(le)) { - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : - ISC_LOG_DEBUG(1), - "IPv6 socket API is " - "incomplete; explicitly " - "binding to each IPv6 " - "address separately"); - log_explicit = false; - } - isc_sockaddr_format(&listen_sockaddr, - sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "%s" - "listening on %s interface " - "%s, %s", - (adjusting == true) ? - "additionally " : "", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name, sabuf); - - result = ns_interface_setup(mgr, - &listen_sockaddr, - interface.name, - &ifp, - (adjusting == true) ? - false : true, - le->dscp, - &addr_in_use); - - tried_listening = true; - if (!addr_in_use) - all_addresses_in_use = false; - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "creating %s interface " - "%s failed; interface " - "ignored", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name); - } - /* Continue. */ - } - - } - continue; - - ignore_interface: - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "ignoring %s interface %s: %s", - (family == AF_INET) ? "IPv4" : "IPv6", - interface.name, isc_result_totext(result)); - continue; - } - if (result != ISC_R_NOMORE) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "interface iteration failed: %s", - isc_result_totext(result)); - else - result = ((tried_listening && all_addresses_in_use) ? - ISC_R_ADDRINUSE : ISC_R_SUCCESS); - cleanup_iter: - isc_interfaceiter_destroy(&iter); - return (result); -} - -static isc_result_t -ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - bool verbose) -{ - isc_result_t result; - bool purge = true; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - mgr->generation++; /* Increment the generation count. */ - - result = do_scan(mgr, ext_listen, verbose); - if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) - purge = false; - - /* - * Now go through the interface list and delete anything that - * does not have the current generation number. This is - * how we catch interfaces that go away or change their - * addresses. - */ - if (purge) - purge_old_interfaces(mgr); - - /* - * Warn if we are not listening on any interface, unless - * we're in lwresd-only mode, in which case that is to - * be expected. - */ - if (ext_listen == NULL && - ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "not listening on any interfaces"); - } - - return (result); -} - -bool -ns_interfacemgr_islistening(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - return (ISC_LIST_EMPTY(mgr->interfaces) ? false : true); -} - -isc_result_t -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { - return (ns_interfacemgr_scan0(mgr, NULL, verbose)); -} - -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose) -{ - return (ns_interfacemgr_scan0(mgr, list, verbose)); -} - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_attach(value, &mgr->listenon4); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon6); - ns_listenlist_attach(value, &mgr->listenon6); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { - ns_interface_t *interface; - - LOCK(&mgr->lock); - interface = ISC_LIST_HEAD(mgr->interfaces); - while (interface != NULL) { - if (interface->clientmgr != NULL) - ns_client_dumprecursing(f, interface->clientmgr); - interface = ISC_LIST_NEXT(interface, link); - } - UNLOCK(&mgr->lock); -} - -bool -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - isc_sockaddr_t *old; - - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(old, addr)) - return (true); - return (false); -} diff --git a/bin/named-sdb/ldapdb.c b/bin/named-sdb/ldapdb.c deleted file mode 100644 index 62d3fb4..0000000 --- a/bin/named-sdb/ldapdb.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * ldapdb.c version 1.0-beta - * - * Copyright (C) 2002, 2004 Stig Venaas - * - * 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. - * - * Contributors: Jeremy C. McDermond - */ - -/* - * If you want to use TLS, uncomment the define below - */ -/* #define LDAPDB_TLS */ - -/* - * If you are using an old LDAP API uncomment the define below. Only do this - * if you know what you're doing or get compilation errors on ldap_memfree(). - * This also forces LDAPv2. - */ -/* #define LDAPDB_RFC1823API */ - -/* Using LDAPv3 by default, change this if you want v2 */ -#ifndef LDAPDB_LDAP_VERSION -#define LDAPDB_LDAP_VERSION 3 -#define LDAP_DEPRECATED 1 -#endif - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include "ldapdb.h" - -/* - * A simple database driver for LDAP - */ - -/* enough for name with 8 labels of max length */ -#define MAXNAMELEN 519 - -static dns_sdbimplementation_t *ldapdb = NULL; - -struct ldapdb_data { - char *hostport; - char *hostname; - int portno; - char *base; - int defaultttl; - char *filterall; - int filteralllen; - char *filterone; - int filteronelen; - char *filtername; - char *bindname; - char *bindpw; -#ifdef LDAPDB_TLS - int tls; -#endif -}; - -/* used by ldapdb_getconn */ - -struct ldapdb_entry { - void *index; - size_t size; - void *data; - struct ldapdb_entry *next; -}; - -static struct ldapdb_entry *ldapdb_find(struct ldapdb_entry *stack, - const void *index, size_t size) { - while (stack != NULL) { - if (stack->size == size && !memcmp(stack->index, index, size)) - return stack; - stack = stack->next; - } - return NULL; -} - -static void ldapdb_insert(struct ldapdb_entry **stack, - struct ldapdb_entry *item) { - item->next = *stack; - *stack = item; -} - -static void ldapdb_lock(int what) { - static isc_mutex_t lock; - - switch (what) { - case 0: - isc_mutex_init(&lock); - break; - case 1: - LOCK(&lock); - break; - case -1: - UNLOCK(&lock); - break; - } -} - -/* data == NULL means cleanup */ -static LDAP ** -ldapdb_getconn(struct ldapdb_data *data) -{ - static struct ldapdb_entry *allthreadsdata = NULL; - struct ldapdb_entry *threaddata, *conndata; - unsigned long threadid; - - if (data == NULL) { - /* cleanup */ - /* lock out other threads */ - ldapdb_lock(1); - while (allthreadsdata != NULL) { - threaddata = allthreadsdata; - free(threaddata->index); - while (threaddata->data != NULL) { - conndata = threaddata->data; - if (conndata->data != NULL) - ldap_unbind((LDAP *)conndata->data); - threaddata->data = conndata->next; - free(conndata); - } - allthreadsdata = threaddata->next; - free(threaddata); - } - ldapdb_lock(-1); - return (NULL); - } - - /* look for connection data for current thread */ - threadid = isc_thread_self(); - threaddata = ldapdb_find(allthreadsdata, &threadid, sizeof(threadid)); - if (threaddata == NULL) { - /* no data for this thread, create empty connection list */ - threaddata = malloc(sizeof(*threaddata)); - if (threaddata == NULL) - return (NULL); - threaddata->index = malloc(sizeof(threadid)); - if (threaddata->index == NULL) { - free(threaddata); - return (NULL); - } - *(unsigned long *)threaddata->index = threadid; - threaddata->size = sizeof(threadid); - threaddata->data = NULL; - - /* need to lock out other threads here */ - ldapdb_lock(1); - ldapdb_insert(&allthreadsdata, threaddata); - ldapdb_lock(-1); - } - - /* threaddata points at the connection list for current thread */ - /* look for existing connection to our server */ - conndata = ldapdb_find((struct ldapdb_entry *)threaddata->data, - data->hostport, strlen(data->hostport)); - if (conndata == NULL) { - /* no connection data structure for this server, create one */ - conndata = malloc(sizeof(*conndata)); - if (conndata == NULL) - return (NULL); - conndata->index = data->hostport; - conndata->size = strlen(data->hostport); - conndata->data = NULL; - ldapdb_insert((struct ldapdb_entry **)&threaddata->data, - conndata); - } - - return (LDAP **)&conndata->data; -} - -static void -ldapdb_bind(struct ldapdb_data *data, LDAP **ldp) -{ -#ifndef LDAPDB_RFC1823API - const int ver = LDAPDB_LDAP_VERSION; -#endif - - if (*ldp != NULL) - ldap_unbind(*ldp); - *ldp = ldap_open(data->hostname, data->portno); - if (*ldp == NULL) - return; - -#ifndef LDAPDB_RFC1823API - ldap_set_option(*ldp, LDAP_OPT_PROTOCOL_VERSION, &ver); -#endif - -#ifdef LDAPDB_TLS - if (data->tls) { - ldap_start_tls_s(*ldp, NULL, NULL); - } -#endif - - if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) { - ldap_unbind(*ldp); - *ldp = NULL; - } -} - -#ifdef DNS_CLIENTINFO_VERSION -static isc_result_t -ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) -#else -static isc_result_t -ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata, - void *methods, void *clientinfo) -#endif /* DNS_CLIENTINFO_VERSION */ -{ - struct ldapdb_data *data = dbdata; - isc_result_t result = ISC_R_NOTFOUND; - LDAP **ldp; - LDAPMessage *res, *e; - char *fltr, *a, **vals = NULL, **names = NULL; - char type[64]; -#ifdef LDAPDB_RFC1823API - void *ptr; -#else - BerElement *ptr; -#endif - int i, j, errno, msgid; - - UNUSED(methods); - UNUSED(clientinfo); - - ldp = ldapdb_getconn(data); - if (ldp == NULL) - return (ISC_R_FAILURE); - if (*ldp == NULL) { - ldapdb_bind(data, ldp); - if (*ldp == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': bind failed", zone); - return (ISC_R_FAILURE); - } - } - - if (name == NULL) { - fltr = data->filterall; - } else { - if (strlen(name) > MAXNAMELEN) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': name %s too long", zone, name); - return (ISC_R_FAILURE); - } - sprintf(data->filtername, "%s))", name); - fltr = data->filterone; - } - - msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - if (msgid == -1) { - ldapdb_bind(data, ldp); - if (*ldp != NULL) - msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - } - - if (*ldp == NULL || msgid == -1) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': search failed, filter %s", zone, fltr); - return (ISC_R_FAILURE); - } - - /* Get the records one by one as they arrive and return them to bind */ - while ((errno = ldap_result(*ldp, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { - LDAP *ld = *ldp; - int ttl = data->defaultttl; - - /* not supporting continuation references at present */ - if (errno != LDAP_RES_SEARCH_ENTRY) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': ldap_result returned %d", zone, errno); - ldap_msgfree(res); - return (ISC_R_FAILURE); - } - - /* only one entry per result message */ - e = ldap_first_entry(ld, res); - if (e == NULL) { - ldap_msgfree(res); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': ldap_first_entry failed", zone); - return (ISC_R_FAILURE); - } - - if (name == NULL) { - names = ldap_get_values(ld, e, "relativeDomainName"); - if (names == NULL) - continue; - } - - vals = ldap_get_values(ld, e, "dNSTTL"); - if (vals != NULL) { - ttl = atoi(vals[0]); - ldap_value_free(vals); - } - - for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) { - char *s; - - for (s = a; *s; s++) - *s = toupper(*s); - s = strstr(a, "RECORD"); - if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) { -#ifndef LDAPDB_RFC1823API - ldap_memfree(a); -#endif - continue; - } - - strncpy(type, a, s - a); - type[s - a] = '\0'; - vals = ldap_get_values(ld, e, a); - if (vals != NULL) { - for (i = 0; vals[i] != NULL; i++) { - if (name != NULL) { - result = dns_sdb_putrr(retdata, type, ttl, vals[i]); - } else { - for (j = 0; names[j] != NULL; j++) { - result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]); - if (result != ISC_R_SUCCESS) - break; - } - } -; if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]); - ldap_value_free(vals); -#ifndef LDAPDB_RFC1823API - ldap_memfree(a); - if (ptr != NULL) - ber_free(ptr, 0); -#endif - if (name == NULL) - ldap_value_free(names); - ldap_msgfree(res); - return (ISC_R_FAILURE); - } - } - ldap_value_free(vals); - } -#ifndef LDAPDB_RFC1823API - ldap_memfree(a); -#endif - } -#ifndef LDAPDB_RFC1823API - if (ptr != NULL) - ber_free(ptr, 0); -#endif - if (name == NULL) - ldap_value_free(names); - - /* free this result */ - ldap_msgfree(res); - } - - /* free final result */ - ldap_msgfree(res); - return (result); -} - - -/* callback routines */ -#ifdef DNS_CLIENTINFO_VERSION -static isc_result_t -ldapdb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - UNUSED(methods); - UNUSED(clientinfo); - return (ldapdb_search(zone, name, dbdata, lookup, NULL, NULL)); -} -#else -static isc_result_t -ldapdb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -{ - return (ldapdb_search(zone, name, dbdata, lookup, methods, - clientinfo)); -} -#endif /* DNS_CLIENTINFO_VERSION */ - -static isc_result_t -ldapdb_allnodes(const char *zone, void *dbdata, - dns_sdballnodes_t *allnodes) -{ - return (ldapdb_search(zone, NULL, dbdata, allnodes, NULL, NULL)); -} - -static char * -unhex(char *in) -{ - static const char hexdigits[] = "0123456789abcdef"; - char *p, *s = in; - int d1, d2; - - while ((s = strchr(s, '%'))) { - if (!(s[1] && s[2])) - return NULL; - if ((p = strchr(hexdigits, tolower(s[1]))) == NULL) - return NULL; - d1 = p - hexdigits; - if ((p = strchr(hexdigits, tolower(s[2]))) == NULL) - return NULL; - d2 = p - hexdigits; - *s++ = d1 << 4 | d2; - memmove(s, s + 2, strlen(s) - 1); - } - return in; -} - -/* returns 0 for ok, -1 for bad syntax, -2 for unknown critical extension */ -static int -parseextensions(char *extensions, struct ldapdb_data *data) -{ - char *s, *next, *name, *value; - int critical; - - while (extensions != NULL) { - s = strchr(extensions, ','); - if (s != NULL) { - *s++ = '\0'; - next = s; - } else { - next = NULL; - } - - if (*extensions != '\0') { - s = strchr(extensions, '='); - if (s != NULL) { - *s++ = '\0'; - value = *s != '\0' ? s : NULL; - } else { - value = NULL; - } - name = extensions; - - critical = *name == '!'; - if (critical) { - name++; - } - if (*name == '\0') { - return -1; - } - - if (!strcasecmp(name, "bindname")) { - data->bindname = value; - } else if (!strcasecmp(name, "x-bindpw")) { - data->bindpw = value; -#ifdef LDAPDB_TLS - } else if (!strcasecmp(name, "x-tls")) { - data->tls = value == NULL || !strcasecmp(value, "true"); -#endif - } else if (critical) { - return -2; - } - } - extensions = next; - } - return 0; -} - -static void -free_data(struct ldapdb_data *data) -{ - if (data->hostport != NULL) - isc_mem_free(ns_g_mctx, data->hostport); - if (data->hostname != NULL) - isc_mem_free(ns_g_mctx, data->hostname); - if (data->filterall != NULL) - isc_mem_put(ns_g_mctx, data->filterall, data->filteralllen); - if (data->filterone != NULL) - isc_mem_put(ns_g_mctx, data->filterone, data->filteronelen); - isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data)); -} - - -static isc_result_t -ldapdb_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - struct ldapdb_data *data; - char *s, *filter = NULL, *extensions = NULL; - int defaultttl; - - UNUSED(driverdata); - - /* we assume that only one thread will call create at a time */ - /* want to do this only once for all instances */ - - if ((argc < 2) - || (argv[0] != strstr( argv[0], "ldap://")) - || ((defaultttl = atoi(argv[1])) < 1)) - return (ISC_R_FAILURE); - data = isc_mem_get(ns_g_mctx, sizeof(struct ldapdb_data)); - if (data == NULL) - return (ISC_R_NOMEMORY); - - memset(data, 0, sizeof(struct ldapdb_data)); - data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://")); - if (data->hostport == NULL) { - free_data(data); - return (ISC_R_NOMEMORY); - } - - data->defaultttl = defaultttl; - - s = strchr(data->hostport, '/'); - if (s != NULL) { - *s++ = '\0'; - data->base = s; - /* attrs, scope, filter etc? */ - s = strchr(s, '?'); - if (s != NULL) { - *s++ = '\0'; - /* ignore attributes */ - s = strchr(s, '?'); - if (s != NULL) { - *s++ = '\0'; - /* ignore scope */ - s = strchr(s, '?'); - if (s != NULL) { - *s++ = '\0'; - /* filter */ - filter = s; - s = strchr(s, '?'); - if (s != NULL) { - *s++ = '\0'; - /* extensions */ - extensions = s; - s = strchr(s, '?'); - if (s != NULL) { - *s++ = '\0'; - } - if (*extensions == '\0') { - extensions = NULL; - } - } - if (*filter == '\0') { - filter = NULL; - } - } - } - } - if (*data->base == '\0') { - data->base = NULL; - } - } - - /* parse extensions */ - if (extensions != NULL) { - int err; - - err = parseextensions(extensions, data); - if (err < 0) { - /* err should be -1 or -2 */ - free_data(data); - if (err == -1) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': URL: extension syntax error", zone); - } else if (err == -2) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': URL: unknown critical extension", zone); - } - return (ISC_R_FAILURE); - } - } - - if ((data->base != NULL && unhex(data->base) == NULL) || - (filter != NULL && unhex(filter) == NULL) || - (data->bindname != NULL && unhex(data->bindname) == NULL) || - (data->bindpw != NULL && unhex(data->bindpw) == NULL)) { - free_data(data); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "LDAP sdb zone '%s': URL: bad hex values", zone); - return (ISC_R_FAILURE); - } - - /* compute filterall and filterone once and for all */ - if (filter == NULL) { - data->filteralllen = strlen(zone) + strlen("(zoneName=)") + 1; - data->filteronelen = strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1; - } else { - data->filteralllen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=))") + 1; - data->filteronelen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1; - } - - data->filterall = isc_mem_get(ns_g_mctx, data->filteralllen); - if (data->filterall == NULL) { - free_data(data); - return (ISC_R_NOMEMORY); - } - data->filterone = isc_mem_get(ns_g_mctx, data->filteronelen); - if (data->filterone == NULL) { - free_data(data); - return (ISC_R_NOMEMORY); - } - - if (filter == NULL) { - sprintf(data->filterall, "(zoneName=%s)", zone); - sprintf(data->filterone, "(&(zoneName=%s)(relativeDomainName=", zone); - } else { - sprintf(data->filterall, "(&%s(zoneName=%s))", filter, zone); - sprintf(data->filterone, "(&%s(zoneName=%s)(relativeDomainName=", filter, zone); - } - data->filtername = data->filterone + strlen(data->filterone); - - /* support URLs with literal IPv6 addresses */ - data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport + (*data->hostport == '[' ? 1 : 0)); - if (data->hostname == NULL) { - free_data(data); - return (ISC_R_NOMEMORY); - } - - if (*data->hostport == '[' && - (s = strchr(data->hostname, ']')) != NULL ) - *s++ = '\0'; - else - s = data->hostname; - s = strchr(s, ':'); - if (s != NULL) { - *s++ = '\0'; - data->portno = atoi(s); - } else - data->portno = LDAP_PORT; - - *dbdata = data; - return (ISC_R_SUCCESS); -} - -static void -ldapdb_destroy(const char *zone, void *driverdata, void **dbdata) { - struct ldapdb_data *data = *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - free_data(data); -} - -static dns_sdbmethods_t ldapdb_methods = { - ldapdb_lookup, - NULL, /* authority */ - ldapdb_allnodes, - ldapdb_create, - ldapdb_destroy, - NULL /* lookup2 */ -}; - -/* Wrapper around dns_sdb_register() */ -isc_result_t -ldapdb_init(void) { - unsigned int flags = - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_THREADSAFE; - - ldapdb_lock(0); - return (dns_sdb_register("ldap", &ldapdb_methods, NULL, flags, - ns_g_mctx, &ldapdb)); -} - -/* Wrapper around dns_sdb_unregister() */ -void -ldapdb_clear(void) { - if (ldapdb != NULL) { - /* clean up thread data */ - ldapdb_getconn(NULL); - dns_sdb_unregister(&ldapdb); - } -} diff --git a/bin/named-sdb/ldapdb.h b/bin/named-sdb/ldapdb.h deleted file mode 100644 index a08eb20..0000000 --- a/bin/named-sdb/ldapdb.h +++ /dev/null @@ -1,6 +0,0 @@ -#include - -isc_result_t ldapdb_init(void); - -void ldapdb_clear(void); - diff --git a/bin/named-sdb/listenlist.c b/bin/named-sdb/listenlist.c deleted file mode 100644 index 289e2d5..0000000 --- a/bin/named-sdb/listenlist.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include - -#include - -#include - -static void -destroy(ns_listenlist_t *list); - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - dns_acl_t *acl, ns_listenelt_t **target) -{ - ns_listenelt_t *elt = NULL; - REQUIRE(target != NULL && *target == NULL); - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - elt->port = port; - elt->dscp = dscp; - elt->acl = acl; - *target = elt; - return (ISC_R_SUCCESS); -} - -void -ns_listenelt_destroy(ns_listenelt_t *elt) { - if (elt->acl != NULL) - dns_acl_detach(&elt->acl); - isc_mem_put(elt->mctx, elt, sizeof(*elt)); -} - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) { - ns_listenlist_t *list = NULL; - REQUIRE(target != NULL && *target == NULL); - list = isc_mem_get(mctx, sizeof(*list)); - if (list == NULL) - return (ISC_R_NOMEMORY); - list->mctx = mctx; - list->refcount = 1; - ISC_LIST_INIT(list->elts); - *target = list; - return (ISC_R_SUCCESS); -} - -static void -destroy(ns_listenlist_t *list) { - ns_listenelt_t *elt, *next; - for (elt = ISC_LIST_HEAD(list->elts); - elt != NULL; - elt = next) - { - next = ISC_LIST_NEXT(elt, link); - ns_listenelt_destroy(elt); - } - isc_mem_put(list->mctx, list, sizeof(*list)); -} - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) { - INSIST(source->refcount > 0); - source->refcount++; - *target = source; -} - -void -ns_listenlist_detach(ns_listenlist_t **listp) { - ns_listenlist_t *list = *listp; - INSIST(list->refcount > 0); - list->refcount--; - if (list->refcount == 0) - destroy(list); - *listp = NULL; -} - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, - bool enabled, ns_listenlist_t **target) -{ - isc_result_t result; - dns_acl_t *acl = NULL; - ns_listenelt_t *elt = NULL; - ns_listenlist_t *list = NULL; - - REQUIRE(target != NULL && *target == NULL); - if (enabled) - result = dns_acl_any(mctx, &acl); - else - result = dns_acl_none(mctx, &acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_listenelt_create(mctx, port, dscp, acl, &elt); - if (result != ISC_R_SUCCESS) - goto cleanup_acl; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - goto cleanup_listenelt; - - ISC_LIST_APPEND(list->elts, elt, link); - - *target = list; - return (ISC_R_SUCCESS); - - cleanup_listenelt: - ns_listenelt_destroy(elt); - cleanup_acl: - dns_acl_detach(&acl); - cleanup: - return (result); -} diff --git a/bin/named-sdb/log.c b/bin/named-sdb/log.c deleted file mode 100644 index ea6f114..0000000 --- a/bin/named-sdb/log.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include - -#include - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/*% - * When adding a new category, be sure to add the appropriate - * \#define to and to update the list in - * bin/check/check-tool.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { "query-errors", 0 }, - { "trust-anchor-telemetry", 0 }, - { "serve-stale", 0 }, - { NULL, 0 } -}; - -/*% - * When adding a new module, be sure to add the appropriate - * \#define to . - */ -static isc_logmodule_t modules[] = { - { "main", 0 }, - { "client", 0 }, - { "server", 0 }, - { "query", 0 }, - { "interfacemgr", 0 }, - { "update", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "notify", 0 }, - { "control", 0 }, - { "lwresd", 0 }, - { NULL, 0 } -}; - -isc_result_t -ns_log_init(bool safe) { - isc_result_t result; - isc_logconfig_t *lcfg = NULL; - - ns_g_categories = categories; - ns_g_modules = modules; - - /* - * Setup a logging context. - */ - result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * named-checktool.c:setup_logging() needs to be kept in sync. - */ - isc_log_registercategories(ns_g_lctx, ns_g_categories); - isc_log_registermodules(ns_g_lctx, ns_g_modules); - isc_log_setcontext(ns_g_lctx); - dns_log_init(ns_g_lctx); - dns_log_setcontext(ns_g_lctx); - cfg_log_init(ns_g_lctx); - - if (safe) - result = ns_log_setsafechannels(lcfg); - else - result = ns_log_setdefaultchannels(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_log_setdefaultcategory(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); - - return (result); -} - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - /* - * By default, the logging library makes "default_debug" log to - * stderr. In BIND, we want to override this and log to named.run - * instead, unless the -g option was given. - */ - if (! ns_g_logstderr) { - destination.file.stream = NULL; - destination.file.name = "named.run"; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_DEBUGONLY); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (ns_g_logfile != NULL) { - destination.file.stream = NULL; - destination.file.name = ns_g_logfile; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_logfile", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_PRINTCATEGORY| - ISC_LOG_PRINTLEVEL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Set the initial debug level. - */ - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - if (! ns_g_logstderr) { - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TONULL, - ISC_LOG_DYNAMIC, - NULL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Setting the debug level to zero should get the output - * discarded a bit faster. - */ - isc_log_setdebuglevel(ns_g_lctx, 0); - } else { - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - } - - if (ns_g_logfile != NULL) { - destination.file.stream = NULL; - destination.file.name = ns_g_logfile; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_logfile", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_PRINTCATEGORY| - ISC_LOG_PRINTLEVEL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg) { - isc_result_t result = ISC_R_SUCCESS; - - result = isc_log_usechannel(lcfg, "default_debug", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (! ns_g_logstderr) { - if (ns_g_logfile != NULL) - result = isc_log_usechannel(lcfg, "default_logfile", - ISC_LOGCATEGORY_DEFAULT, - NULL); - else if (! ns_g_nosyslog) - result = isc_log_usechannel(lcfg, "default_syslog", - ISC_LOGCATEGORY_DEFAULT, - NULL); - } - - cleanup: - return (result); -} - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - result = isc_log_usechannel(lcfg, "null", - NS_LOGCATEGORY_UNMATCHED, NULL); - return (result); -} - -void -ns_log_shutdown(void) { - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); -} diff --git a/bin/named-sdb/logconf.c b/bin/named-sdb/logconf.c deleted file mode 100644 index c51e4ca..0000000 --- a/bin/named-sdb/logconf.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/*% - * Set up a logging category according to the named.conf data - * in 'ccat' and add it to 'logconfig'. - */ -static isc_result_t -category_fromconf(const cfg_obj_t *ccat, isc_logconfig_t *logconfig) { - isc_result_t result; - const char *catname; - isc_logcategory_t *category; - isc_logmodule_t *module; - const cfg_obj_t *destinations = NULL; - const cfg_listelt_t *element = NULL; - - catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name")); - category = isc_log_categorybyname(ns_g_lctx, catname); - if (category == NULL) { - cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR, - "unknown logging category '%s' ignored", - catname); - /* - * Allow further processing by returning success. - */ - return (ISC_R_SUCCESS); - } - - if (logconfig == NULL) - return (ISC_R_SUCCESS); - - module = NULL; - - destinations = cfg_tuple_get(ccat, "destinations"); - for (element = cfg_list_first(destinations); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - const char *channelname = cfg_obj_asstring(channel); - - result = isc_log_usechannel(logconfig, channelname, category, - module); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s': %s", channelname, - isc_result_totext(result)); - return (result); - } - } - return (ISC_R_SUCCESS); -} - -/*% - * Set up a logging channel according to the named.conf data - * in 'cchan' and add it to 'logconfig'. - */ -static isc_result_t -channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *logconfig) -{ - isc_result_t result; - isc_logdestination_t dest; - unsigned int type; - unsigned int flags = 0; - int level; - const char *channelname; - const cfg_obj_t *fileobj = NULL; - const cfg_obj_t *syslogobj = NULL; - const cfg_obj_t *nullobj = NULL; - const cfg_obj_t *stderrobj = NULL; - const cfg_obj_t *severity = NULL; - int i; - - channelname = cfg_obj_asstring(cfg_map_getname(channel)); - - (void)cfg_map_get(channel, "file", &fileobj); - (void)cfg_map_get(channel, "syslog", &syslogobj); - (void)cfg_map_get(channel, "null", &nullobj); - (void)cfg_map_get(channel, "stderr", &stderrobj); - - i = 0; - if (fileobj != NULL) - i++; - if (syslogobj != NULL) - i++; - if (nullobj != NULL) - i++; - if (stderrobj != NULL) - i++; - - if (i != 1) { - cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, - "channel '%s': exactly one of file, syslog, " - "null, and stderr must be present", channelname); - return (ISC_R_FAILURE); - } - - type = ISC_LOG_TONULL; - - if (fileobj != NULL) { - const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); - const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); - const cfg_obj_t *versionsobj = - cfg_tuple_get(fileobj, "versions"); - int32_t versions = ISC_LOG_ROLLNEVER; - isc_offset_t size = 0; - uint64_t maxoffset; - - /* - * isc_offset_t is a signed integer type, so the maximum - * value is all 1s except for the MSB. - */ - switch (sizeof(isc_offset_t)) { - case 4: - maxoffset = 0x7fffffffULL; - break; - case 8: - maxoffset = 0x7fffffffffffffffULL; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - type = ISC_LOG_TOFILE; - - if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) - versions = cfg_obj_asuint32(versionsobj); - if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && - strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) - versions = ISC_LOG_ROLLINFINITE; - if (sizeobj != NULL && - cfg_obj_isuint64(sizeobj) && - cfg_obj_asuint64(sizeobj) < maxoffset) - size = (isc_offset_t)cfg_obj_asuint64(sizeobj); - dest.file.stream = NULL; - dest.file.name = cfg_obj_asstring(pathobj); - dest.file.versions = versions; - dest.file.maximum_size = size; - } else if (syslogobj != NULL) { - int facility = LOG_DAEMON; - - type = ISC_LOG_TOSYSLOG; - - if (cfg_obj_isstring(syslogobj)) { - const char *facilitystr = cfg_obj_asstring(syslogobj); - (void)isc_syslog_facilityfromstring(facilitystr, - &facility); - } - dest.facility = facility; - } else if (stderrobj != NULL) { - type = ISC_LOG_TOFILEDESC; - dest.file.stream = stderr; - dest.file.name = NULL; - dest.file.versions = ISC_LOG_ROLLNEVER; - dest.file.maximum_size = 0; - } - - /* - * Munge flags. - */ - { - const cfg_obj_t *printcat = NULL; - const cfg_obj_t *printsev = NULL; - const cfg_obj_t *printtime = NULL; - const cfg_obj_t *buffered = NULL; - - (void)cfg_map_get(channel, "print-category", &printcat); - (void)cfg_map_get(channel, "print-severity", &printsev); - (void)cfg_map_get(channel, "print-time", &printtime); - (void)cfg_map_get(channel, "buffered", &buffered); - - if (printcat != NULL && cfg_obj_asboolean(printcat)) - flags |= ISC_LOG_PRINTCATEGORY; - if (printtime != NULL && cfg_obj_asboolean(printtime)) - flags |= ISC_LOG_PRINTTIME; - if (printsev != NULL && cfg_obj_asboolean(printsev)) - flags |= ISC_LOG_PRINTLEVEL; - if (buffered != NULL && cfg_obj_asboolean(buffered)) - flags |= ISC_LOG_BUFFERED; - } - - level = ISC_LOG_INFO; - if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { - if (cfg_obj_isstring(severity)) { - const char *str = cfg_obj_asstring(severity); - if (strcasecmp(str, "critical") == 0) - level = ISC_LOG_CRITICAL; - else if (strcasecmp(str, "error") == 0) - level = ISC_LOG_ERROR; - else if (strcasecmp(str, "warning") == 0) - level = ISC_LOG_WARNING; - else if (strcasecmp(str, "notice") == 0) - level = ISC_LOG_NOTICE; - else if (strcasecmp(str, "info") == 0) - level = ISC_LOG_INFO; - else if (strcasecmp(str, "dynamic") == 0) - level = ISC_LOG_DYNAMIC; - } else - /* debug */ - level = cfg_obj_asuint32(severity); - } - - if (logconfig == NULL) - result = ISC_R_SUCCESS; - else - result = isc_log_createchannel(logconfig, channelname, - type, level, &dest, flags); - - if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { - FILE *fp; - - /* - * Test to make sure that file is a plain file. - * Fix defect #22771 - */ - result = isc_file_isplainfile(dest.file.name); - if (result == ISC_R_SUCCESS || result == ISC_R_FILENOTFOUND) { - /* - * Test that the file can be opened, since - * isc_log_open() can't effectively report - * failures when called in isc_log_doit(). - */ - result = isc_stdio_open(dest.file.name, "a", &fp); - if (result != ISC_R_SUCCESS) { - if (logconfig != NULL && !ns_g_nosyslog) - syslog(LOG_ERR, - "isc_stdio_open '%s' failed: " - "%s", dest.file.name, - isc_result_totext(result)); - fprintf(stderr, - "isc_stdio_open '%s' failed: %s\n", - dest.file.name, - isc_result_totext(result)); - } else - (void)isc_stdio_close(fp); - goto done; - } - if (logconfig != NULL && !ns_g_nosyslog) - syslog(LOG_ERR, "isc_file_isplainfile '%s' failed: %s", - dest.file.name, isc_result_totext(result)); - fprintf(stderr, "isc_file_isplainfile '%s' failed: %s\n", - dest.file.name, isc_result_totext(result)); - } - - done: - return (result); -} - -isc_result_t -ns_log_configure(isc_logconfig_t *logconfig, const cfg_obj_t *logstmt) { - isc_result_t result; - const cfg_obj_t *channels = NULL; - const cfg_obj_t *categories = NULL; - const cfg_listelt_t *element; - bool default_set = false; - bool unmatched_set = false; - const cfg_obj_t *catname; - - if (logconfig != NULL) - CHECK(ns_log_setdefaultchannels(logconfig)); - - (void)cfg_map_get(logstmt, "channel", &channels); - for (element = cfg_list_first(channels); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - CHECK(channel_fromconf(channel, logconfig)); - } - - (void)cfg_map_get(logstmt, "category", &categories); - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *category = cfg_listelt_value(element); - CHECK(category_fromconf(category, logconfig)); - if (!default_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "default") == 0) - default_set = true; - } - if (!unmatched_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0) - unmatched_set = true; - } - } - - if (logconfig != NULL && !default_set) - CHECK(ns_log_setdefaultcategory(logconfig)); - - if (logconfig != NULL && !unmatched_set) - CHECK(ns_log_setunmatchedcategory(logconfig)); - - return (ISC_R_SUCCESS); - - cleanup: - return (result); -} diff --git a/bin/named-sdb/lwaddr.c b/bin/named-sdb/lwaddr.c deleted file mode 100644 index 50c43af..0000000 --- a/bin/named-sdb/lwaddr.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include - -#include - -#include - -/*% - * Convert addresses from lwres to isc format. - */ -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la) { - if (la->family != LWRES_ADDRTYPE_V4 && la->family != LWRES_ADDRTYPE_V6) - return (ISC_R_FAMILYNOSUPPORT); - - if (la->family == LWRES_ADDRTYPE_V4) { - struct in_addr ina; - memmove(&ina.s_addr, la->address, 4); - isc_netaddr_fromin(na, &ina); - } else { - struct in6_addr ina6; - memmove(&ina6.s6_addr, la->address, 16); - isc_netaddr_fromin6(na, &ina6); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port) -{ - isc_netaddr_t na; - isc_result_t result; - - result = lwaddr_netaddr_fromlwresaddr(&na, la); - if (result != ISC_R_SUCCESS) - return (result); - isc_sockaddr_fromnetaddr(sa, &na, port); - return (ISC_R_SUCCESS); -} - -/*% - * Convert addresses from isc to lwres format. - */ - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na) { - if (na->family != AF_INET && na->family != AF_INET6) - return (ISC_R_FAMILYNOSUPPORT); - - if (na->family == AF_INET) { - la->family = LWRES_ADDRTYPE_V4; - la->length = 4; - memmove(la->address, &na->type.in, 4); - } else { - la->family = LWRES_ADDRTYPE_V6; - la->length = 16; - memmove(la->address, &na->type.in6, 16); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa) { - isc_netaddr_t na; - isc_netaddr_fromsockaddr(&na, sa); - return (lwaddr_lwresaddr_fromnetaddr(la, &na)); -} diff --git a/bin/named-sdb/lwdclient.c b/bin/named-sdb/lwdclient.c deleted file mode 100644 index 13b8148..0000000 --- a/bin/named-sdb/lwdclient.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); - -void -ns_lwdclient_log(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_DEBUG(level), format, args); - va_end(args); -} - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, - isc_taskmgr_t *taskmgr) -{ - ns_lwresd_t *lwresd = listener->manager; - ns_lwdclientmgr_t *cm; - ns_lwdclient_t *client; - unsigned int i; - isc_result_t result; - - cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); - if (cm == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&cm->lock); - if (result != ISC_R_SUCCESS) - goto freecm; - - cm->listener = NULL; - ns_lwreslistener_attach(listener, &cm->listener); - cm->mctx = lwresd->mctx; - cm->sock = NULL; - isc_socket_attach(listener->sock, &cm->sock); - cm->view = lwresd->view; - cm->lwctx = NULL; - cm->task = NULL; - cm->flags = 0; - ISC_LINK_INIT(cm, link); - ISC_LIST_INIT(cm->idle); - ISC_LIST_INIT(cm->running); - - result = lwres_context_create(&cm->lwctx, cm->mctx, - ns__lwresd_memalloc, ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (result != ISC_R_SUCCESS) - goto errout; - - for (i = 0; i < nclients; i++) { - client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); - if (client != NULL) { - ns_lwdclient_log(50, "created client %p, manager %p", - client, cm); - ns_lwdclient_initialize(client, cm); - } - } - - /* - * If we could create no clients, clean up and return. - */ - if (ISC_LIST_EMPTY(cm->idle)) { - result = ISC_R_NOMEMORY; - goto errout; - } - - result = isc_task_create(taskmgr, 0, &cm->task); - if (result != ISC_R_SUCCESS) - goto errout; - isc_task_setname(cm->task, "lwdclient", NULL); - - /* - * This MUST be last, since there is no way to cancel an onshutdown... - */ - result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, - cm); - if (result != ISC_R_SUCCESS) - goto errout; - - ns_lwreslistener_linkcm(listener, cm); - - return (ISC_R_SUCCESS); - - errout: - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(lwresd->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (cm->task != NULL) - isc_task_detach(&cm->task); - - if (cm->lwctx != NULL) - lwres_context_destroy(&cm->lwctx); - - DESTROYLOCK(&cm->lock); - - freecm: - isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); - return (result); -} - -static void -lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - ns_lwreslistener_t *listener; - - LOCK(&cm->lock); - if (!SHUTTINGDOWN(cm)) { - UNLOCK(&cm->lock); - return; - } - - /* - * Run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (!ISC_LIST_EMPTY(cm->running)) { - UNLOCK(&cm->lock); - return; - } - - UNLOCK(&cm->lock); - - lwres_context_destroy(&cm->lwctx); - cm->view = NULL; - isc_socket_detach(&cm->sock); - isc_task_detach(&cm->task); - - DESTROYLOCK(&cm->lock); - - listener = cm->listener; - ns_lwreslistener_unlinkcm(listener, cm); - ns_lwdclient_log(50, "destroying manager %p", cm); - isc_mem_put(cm->mctx, cm, sizeof(*cm)); - ns_lwreslistener_detach(&listener); -} - -static void -process_request(ns_lwdclient_t *client) { - lwres_buffer_t b; - isc_result_t result; - - lwres_buffer_init(&b, client->buffer, client->recvlength); - lwres_buffer_add(&b, client->recvlength); - - result = lwres_lwpacket_parseheader(&b, &client->pkt); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, "invalid packet header received"); - goto restart; - } - - ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); - - switch (client->pkt.opcode) { - case LWRES_OPCODE_GETADDRSBYNAME: - ns_lwdclient_processgabn(client, &b); - return; - case LWRES_OPCODE_GETNAMEBYADDR: - ns_lwdclient_processgnba(client, &b); - return; - case LWRES_OPCODE_GETRDATABYNAME: - ns_lwdclient_processgrbn(client, &b); - return; - case LWRES_OPCODE_NOOP: - ns_lwdclient_processnoop(client, &b); - return; - default: - ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); - goto restart; - } - - /* - * Drop the packet. - */ - restart: - ns_lwdclient_log(50, "restarting client %p...", client); - ns_lwdclient_stateidle(client); -} - -void -ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - INSIST(dev->region.base == client->buffer); - INSIST(NS_LWDCLIENT_ISRECV(client)); - - NS_LWDCLIENT_SETRECVDONE(client); - - LOCK(&cm->lock); - INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - UNLOCK(&cm->lock); - - ns_lwdclient_log(50, - "event received: task %p, length %u, result %u (%s)", - task, dev->n, dev->result, - isc_result_totext(dev->result)); - - if (dev->result != ISC_R_SUCCESS) { - isc_event_free(&ev); - dev = NULL; - - /* - * Go idle. - */ - ns_lwdclient_stateidle(client); - - return; - } - - client->recvlength = dev->n; - client->address = dev->address; - if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->pktinfo = dev->pktinfo; - client->pktinfo_valid = true; - } else - client->pktinfo_valid = false; - isc_event_free(&ev); - dev = NULL; - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - - process_request(client); -} - -/* - * This function will start a new recv() on a socket for this client manager. - */ -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - isc_result_t result; - isc_region_t r; - bool destroy = false; - - - LOCK(&cm->lock); - if (SHUTTINGDOWN(cm)) { - destroy = true; - result = ISC_R_SUCCESS; - goto unlock; - } - - /* - * If a recv is already running, don't bother. - */ - if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) { - result = ISC_R_SUCCESS; - goto unlock; - } - - /* - * If we have no idle slots, just return success. - */ - client = ISC_LIST_HEAD(cm->idle); - if (client == NULL) { - result = ISC_R_SUCCESS; - goto unlock; - } - - INSIST(NS_LWDCLIENT_ISIDLE(client)); - - /* - * Set the flag to say there is a recv pending. If isc_socket_recv - * fails we will clear the flag otherwise it will be cleared by - * ns_lwdclient_recv. - */ - cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; - - /* - * Issue the recv. If it fails, return that it did. - */ - r.base = client->buffer; - r.length = LWRES_RECVLENGTH; - result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, - client); - if (result != ISC_R_SUCCESS) { - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - goto unlock; - } - - /* - * Remove the client from the idle list, and put it on the running - * list. - */ - NS_LWDCLIENT_SETRECV(client); - ISC_LIST_UNLINK(cm->idle, client, link); - ISC_LIST_APPEND(cm->running, client, link); - - unlock: - UNLOCK(&cm->lock); - - if (destroy) - lwdclientmgr_destroy(cm); - - return (result); -} - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { - ns_lwdclientmgr_t *cm = ev->ev_arg; - ns_lwdclient_t *client; - - REQUIRE(!SHUTTINGDOWN(cm)); - - ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", - task, cm); - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - LOCK(&cm->lock); - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - UNLOCK(&cm->lock); - - /* - * Cancel any pending I/O. - */ - isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); - - /* - * Run through the running client list and kill off any finds - * in progress. - */ - LOCK(&cm->lock); - client = ISC_LIST_HEAD(cm->running); - while (client != NULL) { - if (client->find != client->v4find - && client->find != client->v6find) - dns_adb_cancelfind(client->find); - if (client->v4find != NULL) - dns_adb_cancelfind(client->v4find); - if (client->v6find != NULL) - dns_adb_cancelfind(client->v6find); - client = ISC_LIST_NEXT(client, link); - } - - cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; - - UNLOCK(&cm->lock); - - isc_event_free(&ev); -} - -/* - * Do all the crap needed to move a client from the run queue to the idle - * queue. - */ -void -ns_lwdclient_stateidle(ns_lwdclient_t *client) { - ns_lwdclientmgr_t *cm; - isc_result_t result; - - cm = client->clientmgr; - - INSIST(client->sendbuf == NULL); - INSIST(client->sendlength == 0); - INSIST(client->arg == NULL); - INSIST(client->v4find == NULL); - INSIST(client->v6find == NULL); - - LOCK(&cm->lock); - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_PREPEND(cm->idle, client, link); - UNLOCK(&cm->lock); - - NS_LWDCLIENT_SETIDLE(client); - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); -} - -void -ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - UNUSED(task); - UNUSED(dev); - - INSIST(NS_LWDCLIENT_ISSEND(client)); - INSIST(client->sendbuf == dev->region.base); - - ns_lwdclient_log(50, "task %p for client %p got send-done event", - task, client); - - if (client->sendbuf != client->buffer) - lwres_context_freemem(cm->lwctx, client->sendbuf, - client->sendlength); - client->sendbuf = NULL; - client->sendlength = 0; - - ns_lwdclient_stateidle(client); - - isc_event_free(&ev); -} - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { - struct in6_pktinfo *pktinfo; - ns_lwdclientmgr_t *cm = client->clientmgr; - - if (client->pktinfo_valid) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, - client, &client->address, pktinfo)); -} - -void -ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { - client->clientmgr = cmgr; - ISC_LINK_INIT(client, link); - NS_LWDCLIENT_SETIDLE(client); - client->arg = NULL; - - client->recvlength = 0; - - client->sendbuf = NULL; - client->sendlength = 0; - - client->find = NULL; - client->v4find = NULL; - client->v6find = NULL; - client->find_wanted = 0; - - client->options = 0; - client->byaddr = NULL; - - client->lookup = NULL; - - client->pktinfo_valid = false; - - LOCK(&cmgr->lock); - ISC_LIST_APPEND(cmgr->idle, client, link); - UNLOCK(&cmgr->lock); -} diff --git a/bin/named-sdb/lwderror.c b/bin/named-sdb/lwderror.c deleted file mode 100644 index e219450..0000000 --- a/bin/named-sdb/lwderror.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -/*% - * Generate an error packet for the client, schedule a send, and put us in - * the SEND state. - * - * The client->pkt structure will be modified to form an error return. - * The receiver needs to verify that it is in fact an error, and do the - * right thing with it. The opcode will be unchanged. The result needs - * to be set before calling this function. - * - * The only change this code makes is to set the receive buffer size to the - * size we use, set the reply bit, and recompute any security information. - */ -void -ns_lwdclient_errorpktsend(ns_lwdclient_t *client, uint32_t _result) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t b; - - REQUIRE(NS_LWDCLIENT_ISRUNNING(client)); - - /* - * Since we are only sending the packet header, we can safely toss - * the receive buffer. This means we won't need to allocate space - * for sending an error reply. This is a Good Thing. - */ - client->pkt.length = LWRES_LWPACKET_LENGTH; - client->pkt.pktflags |= LWRES_LWPACKETFLAG_RESPONSE; - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = _result; - - lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH); - lwres = lwres_lwpacket_renderheader(&b, &client->pkt); - if (lwres != LWRES_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - r.base = client->buffer; - r.length = b.used; - client->sendbuf = client->buffer; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - NS_LWDCLIENT_SETSEND(client); -} diff --git a/bin/named-sdb/lwdgabn.c b/bin/named-sdb/lwdgabn.c deleted file mode 100644 index a999740..0000000 --- a/bin/named-sdb/lwdgabn.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define NEED_V4(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \ - && ((c)->v4find == NULL)) -#define NEED_V6(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \ - && ((c)->v6find == NULL)) - -static isc_result_t start_find(ns_lwdclient_t *); -static void restart_find(ns_lwdclient_t *); -static void init_gabn(ns_lwdclient_t *); - -/*% - * Destroy any finds. This can be used to "start over from scratch" and - * should only be called when events are _not_ being generated by the finds. - */ -static void -cleanup_gabn(ns_lwdclient_t *client) { - ns_lwdclient_log(50, "cleaning up client %p", client); - - if (client->v6find != NULL) { - if (client->v6find == client->v4find) - client->v6find = NULL; - else - dns_adb_destroyfind(&client->v6find); - } - if (client->v4find != NULL) - dns_adb_destroyfind(&client->v4find); -} - -static void -setup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) { - dns_adbaddrinfo_t *ai; - lwres_addr_t *addr; - int af; - const struct sockaddr *sa; - isc_result_t result; - - if (at == DNS_ADBFIND_INET) - af = AF_INET; - else - af = AF_INET6; - - ai = ISC_LIST_HEAD(find->list); - while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { - sa = &ai->sockaddr.type.sa; - if (sa->sa_family != af) - goto next; - - addr = &client->addrs[client->gabn.naddrs]; - - result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr); - if (result != ISC_R_SUCCESS) - goto next; - - ns_lwdclient_log(50, "adding address %p, family %d, length %d", - addr->address, addr->family, addr->length); - - client->gabn.naddrs++; - REQUIRE(!LWRES_LINK_LINKED(addr, link)); - LWRES_LIST_APPEND(client->gabn.addrs, addr, link); - - next: - ai = ISC_LIST_NEXT(ai, publink); - } -} - -typedef struct { - isc_netaddr_t address; - int rank; -} rankedaddress; - -static int -addr_compare(const void *av, const void *bv) { - const rankedaddress *a = (const rankedaddress *) av; - const rankedaddress *b = (const rankedaddress *) bv; - return (a->rank - b->rank); -} - -static void -sort_addresses(ns_lwdclient_t *client) { - unsigned int naddrs; - rankedaddress *addrs; - isc_netaddr_t remote; - dns_addressorderfunc_t order; - const void *arg; - ns_lwresd_t *lwresd = client->clientmgr->listener->manager; - unsigned int i; - isc_result_t result; - - naddrs = client->gabn.naddrs; - - if (naddrs <= 1 || lwresd->view->sortlist == NULL) - return; - - addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs); - if (addrs == NULL) - return; - - isc_netaddr_fromsockaddr(&remote, &client->address); - ns_sortlist_byaddrsetup(lwresd->view->sortlist, - &remote, &order, &arg); - if (order == NULL) { - isc_mem_put(lwresd->mctx, addrs, - sizeof(rankedaddress) * naddrs); - return; - } - for (i = 0; i < naddrs; i++) { - result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address, - &client->addrs[i]); - INSIST(result == ISC_R_SUCCESS); - addrs[i].rank = (*order)(&addrs[i].address, arg); - } - qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare); - for (i = 0; i < naddrs; i++) { - result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i], - &addrs[i].address); - INSIST(result == ISC_R_SUCCESS); - } - - isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs); -} - -static void -generate_reply(ns_lwdclient_t *client) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t lwb; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - lwb.base = NULL; - - ns_lwdclient_log(50, "generating gabn reply for client %p", client); - - /* - * We must make certain the client->find is not still active. - * If it is either the v4 or v6 answer, just set it to NULL and - * let the cleanup code destroy it. Otherwise, destroy it now. - */ - if (client->find == client->v4find || client->find == client->v6find) - client->find = NULL; - else - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - - /* - * perhaps there are some here? - */ - if (NEED_V6(client) && client->v4find != NULL) - client->v6find = client->v4find; - - /* - * Run through the finds we have and wire them up to the gabn - * structure. - */ - LWRES_LIST_INIT(client->gabn.addrs); - if (client->v4find != NULL) - setup_addresses(client, client->v4find, DNS_ADBFIND_INET); - if (client->v6find != NULL) - setup_addresses(client, client->v6find, DNS_ADBFIND_INET6); - - /* - * If there are no addresses, try the next element in the search - * path, if there are any more. Otherwise, fall through into - * the error handling code below. - */ - if (client->gabn.naddrs == 0) { - do { - result = ns_lwsearchctx_next(&client->searchctx); - if (result == ISC_R_SUCCESS) { - cleanup_gabn(client); - result = start_find(client); - if (result == ISC_R_SUCCESS) - return; - } - } while (result == ISC_R_SUCCESS); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - - /* - * If there are no addresses, return failure. - */ - if (client->gabn.naddrs != 0) - client->pkt.result = LWRES_R_SUCCESS; - else - client->pkt.result = LWRES_R_NOTFOUND; - - sort_addresses(client); - - lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - /* - * All done! - */ - cleanup_gabn(client); - - return; - - out: - cleanup_gabn(client); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -/* - * Take the current real name, move it to an alias slot (if any are - * open) then put this new name in as the real name for the target. - * - * Return success if it can be rendered, otherwise failure. Note that - * not having enough alias slots open is NOT a failure. - */ -static isc_result_t -add_alias(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - uint16_t naliases; - - b = client->recv_buffer; - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(dns_fixedname_name(&client->target_name), - true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Are there any open slots? - */ - naliases = client->gabn.naliases; - if (naliases < LWRES_MAX_ALIASES) { - client->gabn.aliases[naliases] = client->gabn.realname; - client->gabn.aliaslen[naliases] = client->gabn.realnamelen; - client->gabn.naliases++; - } - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *)(b.base) + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -store_realname(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - dns_name_t *tname; - - b = client->recv_buffer; - - tname = dns_fixedname_name(&client->target_name); - result = ns_lwsearchctx_current(&client->searchctx, tname); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(tname, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *) b.base + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static void -process_gabn_finddone(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - isc_eventtype_t evtype; - bool claimed; - - ns_lwdclient_log(50, "find done for task %p, client %p", task, client); - - evtype = ev->ev_type; - isc_event_free(&ev); - - /* - * No more info to be had? If so, we have all the good stuff - * right now, so we can render things. - */ - claimed = false; - if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { - if (NEED_V4(client)) { - client->v4find = client->find; - claimed = true; - } - if (NEED_V6(client)) { - client->v6find = client->find; - claimed = true; - } - if (client->find != NULL) { - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - } - generate_reply(client); - return; - } - - /* - * We probably don't need this find anymore. We're either going to - * reissue it, or an error occurred. Either way, we're done with - * it. - */ - if ((client->find != client->v4find) - && (client->find != client->v6find)) { - dns_adb_destroyfind(&client->find); - } else { - client->find = NULL; - } - - /* - * We have some new information we can gather. Run off and fetch - * it. - */ - if (evtype == DNS_EVENT_ADBMOREADDRESSES) { - restart_find(client); - return; - } - - /* - * An error or other strangeness happened. Drop this query. - */ - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -restart_find(ns_lwdclient_t *client) { - unsigned int options; - isc_result_t result; - bool claimed; - - ns_lwdclient_log(50, "starting find for client %p", client); - - /* - * Issue a find for the name contained in the request. We won't - * set the bit that says "anything is good enough" -- we want it - * all. - */ - options = 0; - options |= DNS_ADBFIND_WANTEVENT; - options |= DNS_ADBFIND_RETURNLAME; - - /* - * Set the bits up here to mark that we want this address family - * and that we do not currently have a find pending. We will - * set that bit again below if it turns out we will get an event. - */ - if (NEED_V4(client)) - options |= DNS_ADBFIND_INET; - if (NEED_V6(client)) - options |= DNS_ADBFIND_INET6; - - find_again: - INSIST(client->find == NULL); - result = dns_adb_createfind(client->clientmgr->view->adb, - client->clientmgr->task, - process_gabn_finddone, client, - dns_fixedname_name(&client->target_name), - dns_rootname, 0, options, 0, - dns_fixedname_name(&client->target_name), - client->clientmgr->view->dstport, - &client->find); - - /* - * Did we get an alias? If so, save it and re-issue the query. - */ - if (result == DNS_R_ALIAS) { - ns_lwdclient_log(50, "found alias, restarting query"); - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - result = add_alias(client); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, - "out of buffer space adding alias"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - goto find_again; - } - - ns_lwdclient_log(50, "find returned %d (%s)", result, - isc_result_totext(result)); - - /* - * Did we get an error? - */ - if (result != ISC_R_SUCCESS) { - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - - claimed = false; - - /* - * Did we get our answer to V4 addresses? - */ - if (NEED_V4(client) - && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { - ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", - client, client->find); - claimed = true; - client->v4find = client->find; - } - - /* - * Did we get our answer to V6 addresses? - */ - if (NEED_V6(client) - && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { - ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", - client, client->find); - claimed = true; - client->v6find = client->find; - } - - /* - * If we're going to get an event, set our internal pending flag - * and return. When we get an event back we'll do the right - * thing, basically by calling this function again, perhaps with a - * new target name. - * - * If we have both v4 and v6, and we are still getting an event, - * we have a programming error, so die hard. - */ - if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { - ns_lwdclient_log(50, "event will be sent"); - INSIST(client->v4find == NULL || client->v6find == NULL); - return; - } - ns_lwdclient_log(50, "no event will be sent"); - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - /* - * We seem to have everything we asked for, or at least we are - * able to respond with things we've learned. - */ - - generate_reply(client); -} - -static isc_result_t -start_find(ns_lwdclient_t *client) { - isc_result_t result; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gabn(client); - - result = store_realname(client); - if (result != ISC_R_SUCCESS) - return (result); - restart_find(client); - return (ISC_R_SUCCESS); - -} - -static void -init_gabn(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gabn.naliases = 0; - client->gabn.naddrs = 0; - client->gabn.realname = NULL; - client->gabn.aliases = client->aliases; - client->gabn.realnamelen = 0; - client->gabn.aliaslen = client->aliaslen; - LWRES_LIST_INIT(client->gabn.addrs); - client->gabn.base = NULL; - client->gabn.baselen = 0; - - /* - * Set up the internal buffer to point to the receive region. - */ - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -/* - * When we are called, we can be assured that: - * - * client->sockaddr contains the address we need to reply to, - * - * client->pkt contains the packet header data, - * - * the packet "checks out" overall -- any MD5 hashes or crypto - * bits have been verified, - * - * "b" points to the remaining data after the packet header - * was parsed off. - * - * We are in a the RECVDONE state. - * - * From this state we will enter the SEND state if we happen to have - * everything we need or we need to return an error packet, or to the - * FINDWAIT state if we need to look things up. - */ -void -ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { - isc_result_t result; - lwres_gabnrequest_t *req; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gabnrequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->target_name); - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, 0, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - client->find_wanted = req->addrtypes; - ns_lwdclient_log(50, "client %p looking for addrtypes %08x", - client, client->find_wanted); - - /* - * We no longer need to keep this around. - */ - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - /* - * Start the find. - */ - result = start_find(client); - if (result != ISC_R_SUCCESS) - goto out; - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-sdb/lwdgnba.c b/bin/named-sdb/lwdgnba.c deleted file mode 100644 index e827289..0000000 --- a/bin/named-sdb/lwdgnba.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include - -static void start_byaddr(ns_lwdclient_t *); - -static void -byaddr_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_byaddrevent_t *bevent; - int lwres; - lwres_buffer_t lwb; - dns_name_t *name; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_gnbaresponse_t *gnba; - uint16_t naliases; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); - - bevent = (dns_byaddrevent_t *)event; - gnba = &client->gnba; - - ns_lwdclient_log(50, "byaddr event result = %s", - isc_result_totext(bevent->result)); - - result = bevent->result; - if (result != ISC_R_SUCCESS) { - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - bevent = NULL; - - if (client->na.family != AF_INET6 || - (client->options & DNS_BYADDROPT_IPV6INT) != 0) { - if (result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET || - result == DNS_R_NXDOMAIN || - result == DNS_R_NXRRSET) - lwresult = LWRES_R_NOTFOUND; - else - lwresult = LWRES_R_FAILURE; - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - /* - * Fall back to ip6.int reverse if the default ip6.arpa - * fails. - */ - client->options |= DNS_BYADDROPT_IPV6INT; - - start_byaddr(client); - return; - } - - for (name = ISC_LIST_HEAD(bevent->names); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - { - b = client->recv_buffer; - - result = dns_name_totext(name, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwdclient_log(50, "found name '%.*s'", - (int)(client->recv_buffer.used - b.used), - (char *)(b.base) + b.used); - if (gnba->realname == NULL) { - gnba->realname = (char *)(b.base) + b.used; - gnba->realnamelen = client->recv_buffer.used - b.used; - } else { - naliases = gnba->naliases; - if (naliases >= LWRES_MAX_ALIASES) - break; - gnba->aliases[naliases] = (char *)(b.base) + b.used; - gnba->aliaslen[naliases] = - client->recv_buffer.used - b.used; - gnba->naliases++; - } - } - - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwres = lwres_gnbaresponse_render(cm->lwctx, - gnba, &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (client->byaddr != NULL) - dns_byaddr_destroy(&client->byaddr); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, - lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); -} - -static void -start_byaddr(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - - INSIST(client->byaddr == NULL); - - result = dns_byaddr_create(cm->mctx, &client->na, cm->view, - client->options, cm->task, byaddr_done, - client, &client->byaddr); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_gnba(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gnba.naliases = 0; - client->gnba.realname = NULL; - client->gnba.aliases = client->aliases; - client->gnba.realnamelen = 0; - client->gnba.aliaslen = client->aliaslen; - client->gnba.base = NULL; - client->gnba.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_gnbarequest_t *req; - isc_result_t result; - isc_sockaddr_t sa; - ns_lwdclientmgr_t *cm; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gnbarequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - - client->options = 0; - if (req->addr.family == LWRES_ADDRTYPE_V4) { - client->na.family = AF_INET; - if (req->addr.length != 4) - goto out; - memmove(&client->na.type.in, req->addr.address, 4); - } else if (req->addr.family == LWRES_ADDRTYPE_V6) { - client->na.family = AF_INET6; - if (req->addr.length != 16) - goto out; - memmove(&client->na.type.in6, req->addr.address, 16); - } else { - goto out; - } - isc_sockaddr_fromnetaddr(&sa, &client->na, 53); - - ns_lwdclient_log(50, "client %p looking for addrtype %08x", - client, req->addr.family); - - /* - * We no longer need to keep this around. - */ - lwres_gnbarequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gnba(client); - client->options = 0; - - /* - * Start the find. - */ - start_byaddr(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gnbarequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-sdb/lwdgrbn.c b/bin/named-sdb/lwdgrbn.c deleted file mode 100644 index 2295558..0000000 --- a/bin/named-sdb/lwdgrbn.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static void start_lookup(ns_lwdclient_t *); - -static isc_result_t -fill_array(int *pos, dns_rdataset_t *rdataset, - int size, unsigned char **rdatas, uint16_t *rdatalen) -{ - dns_rdata_t rdata; - isc_result_t result; - isc_region_t r; - - UNUSED(size); - - dns_rdata_init(&rdata); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - INSIST(*pos < size); - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - rdatas[*pos] = r.base; - rdatalen[*pos] = r.length; - dns_rdata_reset(&rdata); - (*pos)++; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - return (result); -} - -static isc_result_t -iterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, - isc_mem_t *mctx) -{ - int used = 0, count; - int size = 8, oldsize = 0; - unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; - uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; - dns_rdatasetiter_t *iter = NULL; - dns_rdataset_t set; - dns_ttl_t ttl = INT32_MAX; - uint32_t flags = LWRDATA_VALIDATED; - isc_result_t result = ISC_R_NOMEMORY; - - result = dns_db_allrdatasets(db, node, NULL, 0, &iter); - if (result != ISC_R_SUCCESS) - goto out; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - result = ISC_R_NOMEMORY; - dns_rdataset_init(&set); - dns_rdatasetiter_current(iter, &set); - - if (set.type != dns_rdatatype_rrsig) { - dns_rdataset_disassociate(&set); - continue; - } - - count = dns_rdataset_count(&set); - if (used + count > size) { - /* copy & reallocate */ - oldsize = size; - oldrdatas = rdatas; - oldlens = lens; - rdatas = NULL; - lens = NULL; - - size *= 2; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - memmove(rdatas, oldrdatas, used * sizeof(*rdatas)); - memmove(lens, oldlens, used * sizeof(*lens)); - isc_mem_put(mctx, oldrdatas, - oldsize * sizeof(*oldrdatas)); - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - oldrdatas = NULL; - oldlens = NULL; - } - if (set.ttl < ttl) - ttl = set.ttl; - if (set.trust != dns_trust_secure) - flags &= (~LWRDATA_VALIDATED); - result = fill_array(&used, &set, size, rdatas, lens); - dns_rdataset_disassociate(&set); - if (result != ISC_R_SUCCESS) - goto out; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - goto out; - dns_rdatasetiter_destroy(&iter); - - /* - * If necessary, shrink and copy the arrays. - */ - if (size != used) { - result = ISC_R_NOMEMORY; - newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); - if (newrdatas == NULL) - goto out; - newlens = isc_mem_get(mctx, used * sizeof(*lens)); - if (newlens == NULL) - goto out; - memmove(newrdatas, rdatas, used * sizeof(*rdatas)); - memmove(newlens, lens, used * sizeof(*lens)); - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - isc_mem_put(mctx, lens, size * sizeof(*lens)); - grbn->rdatas = newrdatas; - grbn->rdatalen = newlens; - } else { - grbn->rdatas = rdatas; - grbn->rdatalen = lens; - } - grbn->nrdatas = used; - grbn->ttl = ttl; - grbn->flags = flags; - return (ISC_R_SUCCESS); - - out: - dns_rdatasetiter_destroy(&iter); - if (rdatas != NULL) - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - if (lens != NULL) - isc_mem_put(mctx, lens, size * sizeof(*lens)); - if (oldrdatas != NULL) - isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); - if (oldlens != NULL) - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - if (newrdatas != NULL) - isc_mem_put(mctx, newrdatas, used * sizeof(*newrdatas)); - return (result); -} - -static void -lookup_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_lookupevent_t *levent; - lwres_buffer_t lwb; - dns_name_t *name; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_grbnresponse_t *grbn; - int i; - - REQUIRE(event != NULL); - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); - - levent = (dns_lookupevent_t *)event; - grbn = &client->grbn; - - ns_lwdclient_log(50, "lookup event result = %s", - isc_result_totext(levent->result)); - - result = levent->result; - if (result != ISC_R_SUCCESS) { - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - levent = NULL; - - switch (result) { - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - result = ns_lwsearchctx_next(&client->searchctx); - if (result != ISC_R_SUCCESS) - lwresult = LWRES_R_NOTFOUND; - else { - start_lookup(client); - return; - } - break; - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - lwresult = LWRES_R_TYPENOTFOUND; - break; - default: - lwresult = LWRES_R_FAILURE; - } - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - name = levent->name; - b = client->recv_buffer; - - grbn->flags = 0; - - grbn->nrdatas = 0; - grbn->rdatas = NULL; - grbn->rdatalen = NULL; - - grbn->nsigs = 0; - grbn->sigs = NULL; - grbn->siglen = NULL; - - result = dns_name_totext(name, true, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - grbn->realname = (char *)isc_buffer_used(&b); - grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - - isc_buffer_usedlength(&b); - ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, - grbn->realname); - - grbn->rdclass = cm->view->rdclass; - grbn->rdtype = client->rdtype; - - rdataset = levent->rdataset; - if (rdataset != NULL) { - /* The normal case */ - grbn->nrdatas = dns_rdataset_count(rdataset); - grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(unsigned char *)); - if (grbn->rdatas == NULL) - goto out; - grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(uint16_t)); - if (grbn->rdatalen == NULL) - goto out; - - i = 0; - result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, - grbn->rdatalen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nrdatas); - grbn->ttl = rdataset->ttl; - if (rdataset->trust == dns_trust_secure) - grbn->flags |= LWRDATA_VALIDATED; - } else { - /* The SIG query case */ - result = iterate_node(grbn, levent->db, levent->node, - cm->mctx); - if (result != ISC_R_SUCCESS) - goto out; - } - ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, - (grbn->nrdatas == 1) ? "" : "s"); - - sigrdataset = levent->sigrdataset; - if (sigrdataset != NULL) { - grbn->nsigs = dns_rdataset_count(sigrdataset); - grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(unsigned char *)); - if (grbn->sigs == NULL) - goto out; - grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(uint16_t)); - if (grbn->siglen == NULL) - goto out; - - i = 0; - result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, - grbn->siglen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nsigs); - ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, - (grbn->nsigs == 1) ? "" : "s"); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwresult = lwres_grbnresponse_render(cm->lwctx, - grbn, &client->pkt, &lwb); - if (lwresult != LWRES_R_SUCCESS) - goto out; - - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(uint16_t)); - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out2; - - NS_LWDCLIENT_SETSEND(client); - - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - - return; - - out: - if (grbn->rdatas != NULL) - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - if (grbn->rdatalen != NULL) - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(uint16_t)); - out2: - if (client->lookup != NULL) - dns_lookup_destroy(&client->lookup); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); - - isc_event_free(&event); - - ns_lwdclient_log(50, "error constructing getrrsetbyname response"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -start_lookup(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - dns_fixedname_t absname; - - cm = client->clientmgr; - - INSIST(client->lookup == NULL); - - dns_fixedname_init(&absname); - - /* - * Perform search across all search domains until success - * is returned. Return in case of failure. - */ - while (ns_lwsearchctx_current(&client->searchctx, - dns_fixedname_name(&absname)) != ISC_R_SUCCESS) { - if (ns_lwsearchctx_next(&client->searchctx) != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - } - - result = dns_lookup_create(cm->mctx, - dns_fixedname_name(&absname), - client->rdtype, cm->view, - client->options, cm->task, lookup_done, - client, &client->lookup); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_grbn(ns_lwdclient_t *client) { - client->grbn.rdclass = 0; - client->grbn.rdtype = 0; - client->grbn.ttl = 0; - client->grbn.nrdatas = 0; - client->grbn.realname = NULL; - client->grbn.realnamelen = 0; - client->grbn.rdatas = 0; - client->grbn.rdatalen = 0; - client->grbn.base = NULL; - client->grbn.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_grbnrequest_t *req; - isc_result_t result; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_grbnrequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - client->options = 0; - if (req->rdclass != cm->view->rdclass) - goto out; - - if (req->rdclass == dns_rdataclass_any || - req->rdtype == dns_rdatatype_any) - goto out; - - client->rdtype = req->rdtype; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, 0, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - ns_lwdclient_log(50, "client %p looking for type %d", - client, client->rdtype); - - /* - * We no longer need to keep this around. - */ - lwres_grbnrequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_grbn(client); - - /* - * Start the find. - */ - start_lookup(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_grbnrequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-sdb/lwdnoop.c b/bin/named-sdb/lwdnoop.c deleted file mode 100644 index 7d4de0d..0000000 --- a/bin/named-sdb/lwdnoop.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -void -ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_nooprequest_t *req; - lwres_noopresponse_t resp; - isc_result_t result; - lwres_result_t lwres; - isc_region_t r; - lwres_buffer_t lwb; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - req = NULL; - - result = lwres_nooprequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto send_error; - - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - resp.datalength = req->datalength; - resp.data = req->data; - - lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto cleanup_req; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto cleanup_lwb; - - /* - * We can now destroy request. - */ - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - NS_LWDCLIENT_SETSEND(client); - - return; - - cleanup_lwb: - lwres_context_freemem(client->clientmgr->lwctx, lwb.base, lwb.length); - - cleanup_req: - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - send_error: - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/bin/named-sdb/lwresd.8 b/bin/named-sdb/lwresd.8 deleted file mode 100644 index aa2c33b..0000000 --- a/bin/named-sdb/lwresd.8 +++ /dev/null @@ -1,250 +0,0 @@ -.\" Copyright (C) 2000, 2001, 2004, 2005, 2007-2009, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: lwresd -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2009-01-20 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "LWRESD" "8" "2009\-01\-20" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -lwresd \- lightweight resolver daemon -.SH "SYNOPSIS" -.HP \w'\fBlwresd\fR\ 'u -\fBlwresd\fR [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-C\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-i\ \fR\fB\fIpid\-file\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-P\ \fR\fB\fIport\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [[\fB\-4\fR] | [\fB\-6\fR]] -.SH "DESCRIPTION" -.PP -\fBlwresd\fR -is the daemon providing name lookup services to clients that use the BIND 9 lightweight resolver library\&. It is essentially a stripped\-down, caching\-only name server that answers queries using the BIND 9 lightweight resolver protocol rather than the DNS protocol\&. -.PP -\fBlwresd\fR -listens for resolver queries on a UDP port on the IPv4 loopback interface, 127\&.0\&.0\&.1\&. This means that -\fBlwresd\fR -can only be used by processes running on the local machine\&. By default, UDP port number 921 is used for lightweight resolver requests and responses\&. -.PP -Incoming lightweight resolver requests are decoded by the server which then resolves them using the DNS protocol\&. When the DNS lookup completes, -\fBlwresd\fR -encodes the answers in the lightweight resolver format and returns them to the client that made the request\&. -.PP -If -/etc/resolv\&.conf -contains any -\fBnameserver\fR -entries, -\fBlwresd\fR -sends recursive DNS queries to those servers\&. This is similar to the use of forwarders in a caching name server\&. If no -\fBnameserver\fR -entries are present, or if forwarding fails, -\fBlwresd\fR -resolves the queries autonomously starting at the root name servers, using a built\-in list of root server hints\&. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/lwresd\&.conf\&. -\fB\-c\fR -can not be used with -\fB\-C\fR\&. -.RE -.PP -\-C \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/resolv\&.conf\&. -\fB\-C\fR -can not be used with -\fB\-c\fR\&. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon\*(Aqs debug level to -\fIdebug\-level\fR\&. Debugging traces from -\fBlwresd\fR -become more verbose as the debug level increases\&. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i\&.e\&. do not daemonize)\&. -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -stderr\&. -.RE -.PP -\-i \fIpid\-file\fR -.RS 4 -Use -\fIpid\-file\fR -as the PID file instead of the default, -/var/run/lwresd/lwresd\&.pid\&. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags\&. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR\&. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\&. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs\&. If not specified, -\fBlwresd\fR -will try to determine the number of CPUs present and create one thread per CPU\&. If it is unable to determine the number of CPUs, a single worker thread will be created\&. -.RE -.PP -\-P \fIport\fR -.RS 4 -Listen for lightweight resolver queries on port -\fIport\fR\&. If not specified, the default is port 921\&. -.RE -.PP -\-p \fIport\fR -.RS 4 -Send DNS lookups to port -\fIport\fR\&. If not specified, the default is port 53\&. This provides a way of testing the lightweight resolver daemon with a name server that listens for queries on a non\-standard port number\&. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -stdout -on exit\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn\*(Aqt enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail\&. -.sp .5v -.RE -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports\&. -.RE -.PP -\-v -.RS 4 -Report the version number and exit\&. -.RE -.SH "FILES" -.PP -/etc/resolv\&.conf -.RS 4 -The default configuration file\&. -.RE -.PP -/var/run/lwresd\&.pid -.RS 4 -The default process\-id file\&. -.RE -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBlwres\fR(3), -\fBresolver\fR(5)\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000, 2001, 2004, 2005, 2007-2009, 2014-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-sdb/lwresd.c b/bin/named-sdb/lwresd.c deleted file mode 100644 index f2e480e..0000000 --- a/bin/named-sdb/lwresd.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file - * \brief - * Main program for the Lightweight Resolver Daemon. - * - * To paraphrase the old saying about X11, "It's not a lightweight daemon - * for resolvers, it's a daemon for lightweight resolvers". - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D') -#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC) - -#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L') -#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC) - -#define LWRESD_NCLIENTS_MAX 32768 /*%< max clients per task */ - -typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t; - -static ns_lwreslistenerlist_t listeners; -static isc_mutex_t listeners_lock; -static isc_once_t once = ISC_ONCE_INIT; - - -static void -initialize_mutex(void) { - RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); -} - - -/*% - * Wrappers around our memory management stuff, for the lwres functions. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -static isc_result_t -buffer_putstr(isc_buffer_t *b, const char *s) { - unsigned int len = strlen(s); - if (isc_buffer_availablelength(b) <= len) - return (ISC_R_NOSPACE); - isc_buffer_putmem(b, (const unsigned char *)s, len); - return (ISC_R_SUCCESS); -} - -/* - * Convert a resolv.conf file into a config structure. - */ -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp) -{ - char text[4096]; - char str[16]; - isc_buffer_t b; - lwres_context_t *lwctx = NULL; - lwres_conf_t *lwc = NULL; - isc_sockaddr_t sa; - isc_netaddr_t na; - int i; - isc_result_t result; - lwres_result_t lwresult; - - lwctx = NULL; - lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, - ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (lwresult != LWRES_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); - if (lwresult != LWRES_R_SUCCESS) { - result = DNS_R_SYNTAX; - goto cleanup; - } - - lwc = lwres_conf_get(lwctx); - INSIST(lwc != NULL); - - isc_buffer_init(&b, text, sizeof(text)); - - CHECK(buffer_putstr(&b, "options {\n")); - - /* - * Build the list of forwarders. - */ - if (lwc->nsnext > 0) { - CHECK(buffer_putstr(&b, "\tforwarders {\n")); - - for (i = 0; i < lwc->nsnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr( - &sa, - &lwc->nameservers[i], - ns_g_port)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the sortlist - */ - if (lwc->sortlistnxt > 0) { - CHECK(buffer_putstr(&b, "\tsortlist {\n")); - CHECK(buffer_putstr(&b, "\t\t{\n")); - CHECK(buffer_putstr(&b, "\t\t\tany;\n")); - CHECK(buffer_putstr(&b, "\t\t\t{\n")); - for (i = 0; i < lwc->sortlistnxt; i++) { - lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; - lwres_addr_t *lwmask = &lwc->sortlist[i].mask; - unsigned int mask; - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - result = isc_netaddr_masktoprefixlen(&na, &mask); - if (result != ISC_R_SUCCESS) { - char addrtext[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_format(&na, addrtext, - sizeof(addrtext)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_ERROR, - "processing sortlist: '%s' is " - "not a valid netmask", - addrtext); - goto cleanup; - } - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - - CHECK(buffer_putstr(&b, "\t\t\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - snprintf(str, sizeof(str), "%u", mask); - CHECK(buffer_putstr(&b, "/")); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t\t\t};\n")); - CHECK(buffer_putstr(&b, "\t\t};\n")); - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n\n")); - - CHECK(buffer_putstr(&b, "lwres {\n")); - - /* - * Build the search path - */ - if (lwc->searchnxt > 0) { - CHECK(buffer_putstr(&b, "\tsearch {\n")); - for (i = 0; i < lwc->searchnxt; i++) { - CHECK(buffer_putstr(&b, "\t\t\"")); - CHECK(buffer_putstr(&b, lwc->search[i])); - CHECK(buffer_putstr(&b, "\";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the ndots line - */ - if (lwc->ndots != 1) { - CHECK(buffer_putstr(&b, "\tndots ")); - snprintf(str, sizeof(str), "%u", lwc->ndots); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - - /* - * Build the listen-on line - */ - if (lwc->lwnext > 0) { - CHECK(buffer_putstr(&b, "\tlisten-on {\n")); - - for (i = 0; i < lwc->lwnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, - &lwc->lwservers[i], - 0)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n")); - -#if 0 - printf("%.*s\n", - (int)isc_buffer_usedlength(&b), - (char *)isc_buffer_base(&b)); -#endif - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); - - cleanup: - - if (lwctx != NULL) { - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - } - - return (result); -} - - -/* - * Handle lwresd manager objects - */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp) -{ - ns_lwresd_t *lwresd; - const char *vname; - dns_rdataclass_t vclass; - const cfg_obj_t *obj, *viewobj, *searchobj; - const cfg_listelt_t *element; - isc_result_t result; - - INSIST(lwresdp != NULL && *lwresdp == NULL); - - lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); - if (lwresd == NULL) - return (ISC_R_NOMEMORY); - - lwresd->mctx = NULL; - isc_mem_attach(mctx, &lwresd->mctx); - lwresd->view = NULL; - lwresd->search = NULL; - lwresd->refs = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "ndots", &obj); - if (obj != NULL) - lwresd->ndots = cfg_obj_asuint32(obj); - else - lwresd->ndots = 1; - - RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); - - lwresd->shutting_down = false; - - viewobj = NULL; - (void)cfg_map_get(lwres, "view", &viewobj); - if (viewobj != NULL) { - vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); - obj = cfg_tuple_get(viewobj, "class"); - result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); - if (result != ISC_R_SUCCESS) - goto fail; - } else { - vname = "_default"; - vclass = dns_rdataclass_in; - } - - result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, - &lwresd->view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't find view %s", vname); - goto fail; - } - - searchobj = NULL; - (void)cfg_map_get(lwres, "search", &searchobj); - if (searchobj != NULL) { - lwresd->search = NULL; - result = ns_lwsearchlist_create(lwresd->mctx, - &lwresd->search); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't create searchlist"); - goto fail; - } - for (element = cfg_list_first(searchobj); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *search; - const char *searchstr; - isc_buffer_t namebuf; - dns_fixedname_t fname; - dns_name_t *name; - - search = cfg_listelt_value(element); - searchstr = cfg_obj_asstring(search); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - isc_buffer_constinit(&namebuf, searchstr, - strlen(searchstr)); - isc_buffer_add(&namebuf, strlen(searchstr)); - result = dns_name_fromtext(name, &namebuf, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "invalid name %s in searchlist", - searchstr); - continue; - } - - result = ns_lwsearchlist_append(lwresd->search, name); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "couldn't update searchlist"); - goto fail; - } - } - } - - obj = NULL; - (void)cfg_map_get(lwres, "lwres-tasks", &obj); - if (obj != NULL) - lwresd->ntasks = cfg_obj_asuint32(obj); - else - lwresd->ntasks = ns_g_cpus; - - if (lwresd->ntasks == 0) - lwresd->ntasks = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "lwres-clients", &obj); - if (obj != NULL) { - lwresd->nclients = cfg_obj_asuint32(obj); - if (lwresd->nclients > LWRESD_NCLIENTS_MAX) - lwresd->nclients = LWRESD_NCLIENTS_MAX; - } else if (ns_g_lwresdonly) - lwresd->nclients = 1024; - else - lwresd->nclients = 256; - - lwresd->magic = LWRESD_MAGIC; - - *lwresdp = lwresd; - return (ISC_R_SUCCESS); - - fail: - if (lwresd->view != NULL) - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - if (lwresd->mctx != NULL) - isc_mem_detach(&lwresd->mctx); - isc_mem_put(mctx, lwresd, sizeof(ns_lwresd_t)); - return (result); -} - -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { - INSIST(VALID_LWRESD(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp) { - ns_lwresd_t *lwresd; - isc_mem_t *mctx; - bool done = false; - - INSIST(lwresdp != NULL && *lwresdp != NULL); - INSIST(VALID_LWRESD(*lwresdp)); - - lwresd = *lwresdp; - *lwresdp = NULL; - - LOCK(&lwresd->lock); - INSIST(lwresd->refs > 0); - lwresd->refs--; - if (lwresd->refs == 0) - done = true; - UNLOCK(&lwresd->lock); - - if (!done) - return; - - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - mctx = lwresd->mctx; - lwresd->magic = 0; - isc_mem_put(mctx, lwresd, sizeof(*lwresd)); - isc_mem_detach(&mctx); -} - - -/* - * Handle listener objects - */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp) -{ - INSIST(VALID_LWRESLISTENER(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - bool done = false; - - INSIST(listenerp != NULL && *listenerp != NULL); - INSIST(VALID_LWRESLISTENER(*listenerp)); - - listener = *listenerp; - *listenerp = NULL; - - LOCK(&listener->lock); - INSIST(listener->refs > 0); - listener->refs--; - if (listener->refs == 0) - done = true; - UNLOCK(&listener->lock); - - if (!done) - return; - - if (listener->manager != NULL) - ns_lwdmanager_detach(&listener->manager); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - listener->magic = 0; - mctx = listener->mctx; - isc_mem_put(mctx, listener, sizeof(*listener)); - isc_mem_detach(&mctx); -} - -static isc_result_t -listener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd, - ns_lwreslistener_t **listenerp) -{ - ns_lwreslistener_t *listener; - isc_result_t result; - - REQUIRE(listenerp != NULL && *listenerp == NULL); - - listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&listener->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, listener, sizeof(ns_lwreslistener_t)); - return (result); - } - - listener->magic = LWRESLISTENER_MAGIC; - listener->refs = 1; - - listener->sock = NULL; - - listener->manager = NULL; - ns_lwdmanager_attach(lwresd, &listener->manager); - - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->cmgrs); - - *listenerp = listener; - return (ISC_R_SUCCESS); -} - -static isc_result_t -listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - int pf; - - pf = isc_sockaddr_pf(address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - return (ISC_R_FAMILYNOSUPPORT); - - listener->address = *address; - - if (isc_sockaddr_getport(&listener->address) == 0) { - in_port_t port; - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - isc_sockaddr_setport(&listener->address, port); - } - - sock = NULL; - result = isc_socket_create(ns_g_socketmgr, pf, - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to create lwres socket: %s", - isc_result_totext(result)); - return (result); - } - - result = isc_socket_bind(sock, &listener->address, - ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_socket_detach(&sock); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to add lwres socket: %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - listener->sock = sock; - return (ISC_R_SUCCESS); -} - -static void -listener_copysock(ns_lwreslistener_t *oldlistener, - ns_lwreslistener_t *newlistener) -{ - newlistener->address = oldlistener->address; - isc_socket_attach(oldlistener->sock, &newlistener->sock); -} - -static isc_result_t -listener_startclients(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm, *next; - unsigned int i; - isc_result_t result = ISC_R_SUCCESS; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_DEBUG(6), - "listener_startclients: creating %d " - "managers with %d clients each", - listener->manager->ntasks, listener->manager->nclients); - - /* - * Create the client managers. - */ - for (i = 0; i < listener->manager->ntasks; i++) { - result = ns_lwdclientmgr_create(listener, - listener->manager->nclients, - ns_g_taskmgr); - if (result != ISC_R_SUCCESS) - break; - } - - /* - * If the list is empty return now with the previous - * ns_lwdclientmgr_create() result. - */ - if (ISC_LIST_EMPTY(listener->cmgrs)) - return (result); - - /* - * Walk the list of clients and start each one up. - */ - LOCK(&listener->lock); - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - next = ISC_LIST_NEXT(cm, link); - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - cm = next; - } - UNLOCK(&listener->lock); - - return (ISC_R_SUCCESS); -} - -static void -listener_shutdown(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - isc_task_shutdown(cm->task); - cm = ISC_LIST_NEXT(cm, link); - } -} - -static isc_result_t -find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - - INSIST(listenerp != NULL && *listenerp == NULL); - - for (listener = ISC_LIST_HEAD(listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - { - if (!isc_sockaddr_equal(address, &listener->address)) - continue; - *listenerp = listener; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) -{ - REQUIRE(VALID_LWRESLISTENER(listener)); - - LOCK(&listener->lock); - ISC_LIST_UNLINK(listener->cmgrs, cm, link); - UNLOCK(&listener->lock); -} - -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) { - REQUIRE(VALID_LWRESLISTENER(listener)); - - /* - * This does no locking, since it's called early enough that locking - * isn't needed. - */ - ISC_LIST_APPEND(listener->cmgrs, cm, link); -} - -static isc_result_t -configure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd, - isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners) -{ - ns_lwreslistener_t *listener, *oldlistener = NULL; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - - (void)find_listener(address, &oldlistener); - listener = NULL; - result = listener_create(mctx, lwresd, &listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres failed to configure %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - - /* - * If there's already a listener, don't rebind the socket. - */ - if (oldlistener == NULL) { - result = listener_bind(listener, address); - if (result != ISC_R_SUCCESS) { - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - } else - listener_copysock(oldlistener, listener); - - result = listener_startclients(listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres: failed to start %s: %s", socktext, - isc_result_totext(result)); - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - - if (oldlistener != NULL) { - /* - * Remove the old listener from the old list and shut it down. - */ - ISC_LIST_UNLINK(listeners, oldlistener, link); - listener_shutdown(oldlistener); - ns_lwreslistener_detach(&oldlistener); - } else { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres listening on %s", socktext); - } - - ISC_LIST_APPEND(*newlisteners, listener, link); - return (result); -} - -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) { - const cfg_obj_t *lwreslist = NULL; - const cfg_obj_t *lwres = NULL; - const cfg_obj_t *listenerslist = NULL; - const cfg_listelt_t *element = NULL; - ns_lwreslistener_t *listener; - ns_lwreslistenerlist_t newlisteners; - isc_result_t result; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t *addrs = NULL; - ns_lwresd_t *lwresd = NULL; - uint32_t count = 0; - - REQUIRE(mctx != NULL); - REQUIRE(config != NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - ISC_LIST_INIT(newlisteners); - - result = cfg_map_get(config, "lwres", &lwreslist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - LOCK(&listeners_lock); - /* - * Run through the new lwres address list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicates addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - for (element = cfg_list_first(lwreslist); - element != NULL; - element = cfg_list_next(element)) - { - in_port_t port; - - lwres = cfg_listelt_value(element); - CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd)); - - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - - listenerslist = NULL; - (void)cfg_map_get(lwres, "listen-on", &listenerslist); - if (listenerslist == NULL) { - struct in_addr localhost; - isc_sockaddr_t address; - - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&address, &localhost, port); - CHECK(configure_listener(&address, lwresd, mctx, - &newlisteners)); - } else { - uint32_t i; - - CHECK(ns_config_getiplist(config, listenerslist, - port, mctx, &addrs, NULL, - &count)); - for (i = 0; i < count; i++) - CHECK(configure_listener(&addrs[i], lwresd, - mctx, &newlisteners)); - ns_config_putiplist(mctx, &addrs, NULL, count); - } - ns_lwdmanager_detach(&lwresd); - } - - /* - * Shutdown everything on the listeners list, and remove them from - * the list. Then put all of the new listeners on it. - */ - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - - isc_sockaddr_format(&listener->address, - socktext, sizeof(socktext)); - - listener_shutdown(listener); - ns_lwreslistener_detach(&listener); - - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres no longer listening on %s", socktext); - } - - cleanup: - ISC_LIST_APPENDLIST(listeners, newlisteners, link); - - if (addrs != NULL) - ns_config_putiplist(mctx, &addrs, NULL, count); - - if (lwresd != NULL) - ns_lwdmanager_detach(&lwresd); - - UNLOCK(&listeners_lock); - - return (result); -} - -void -ns_lwresd_shutdown(void) { - ns_lwreslistener_t *listener; - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - LOCK(&listeners_lock); - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - UNLOCK(&listeners_lock); - ns_lwreslistener_detach(&listener); - LOCK(&listeners_lock); - } - UNLOCK(&listeners_lock); -} diff --git a/bin/named-sdb/lwresd.docbook b/bin/named-sdb/lwresd.docbook deleted file mode 100644 index d1c3cdc..0000000 --- a/bin/named-sdb/lwresd.docbook +++ /dev/null @@ -1,365 +0,0 @@ - - - - - - 2009-01-20 - - - ISC - Internet Systems Consortium, Inc. - - - - lwresd - 8 - BIND9 - - - - lwresd - lightweight resolver daemon - - - - - 2000 - 2001 - 2004 - 2005 - 2007 - 2008 - 2009 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - lwresd - - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - - lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. - - - lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default, UDP port - number 921 is used for lightweight resolver requests and - responses. - - - Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. - - - If /etc/resolv.conf contains any - entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. - - - - OPTIONS - - - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - can not be used with . - - - - - - -C config-file - - - Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - can not be used with . - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -i pid-file - - - Use pid-file as the - PID file instead of the default, - /var/run/lwresd/lwresd.pid. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -P port - - - Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. - - - - - - -p port - - - Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. - - - - - - -s - - - Write memory usage statistics to stdout - on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - - - -v - - - Report the version number and exit. - - - - - - - - - FILES - - - - - - /etc/resolv.conf - - - The default configuration file. - - - - - - /var/run/lwresd.pid - - - The default process-id file. - - - - - - - - - SEE ALSO - - - named8 - , - - lwres3 - , - - resolver5 - . - - - - diff --git a/bin/named-sdb/lwresd.html b/bin/named-sdb/lwresd.html deleted file mode 100644 index ad4bf61..0000000 --- a/bin/named-sdb/lwresd.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - -lwresd - - -
-
-
-

Name

-

lwresd — lightweight resolver daemon

-
-
-

Synopsis

-

lwresd [-c config-file] [-C config-file] [-d debug-level] [-f] [-g] [-i pid-file] [-m flag] [-n #cpus] [-P port] [-p port] [-s] [-t directory] [-u user] [-v] [[-4] | [-6]]

-
-
-

DESCRIPTION

-

lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. -

-

lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default, UDP port - number 921 is used for lightweight resolver requests and - responses. -

-

- Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. -

-

- If /etc/resolv.conf contains any - nameserver entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - nameserver entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - -c can not be used with -C. -

-
-C config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - -C can not be used with -c. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. -

-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-i pid-file
-

- Use pid-file as the - PID file instead of the default, - /var/run/lwresd/lwresd.pid. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-P port
-

- Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. -

-
-p port
-

- Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. -

-
-s
-
-

- Write memory usage statistics to stdout - on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-u user
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-v
-

- Report the version number and exit. -

-
-
-
-

FILES

-
-
/etc/resolv.conf
-

- The default configuration file. -

-
/var/run/lwresd.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

named(8), - lwres(3), - resolver(5). -

-
-
- diff --git a/bin/named-sdb/lwsearch.c b/bin/named-sdb/lwsearch.c deleted file mode 100644 index f56dc7b..0000000 --- a/bin/named-sdb/lwsearch.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L') -#define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC) - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(listp != NULL && *listp == NULL); - - list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); - if (list == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&list->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - return (result); - } - list->mctx = NULL; - isc_mem_attach(mctx, &list->mctx); - list->refs = 1; - ISC_LIST_INIT(list->names); - list->magic = LWSEARCHLIST_MAGIC; - - *listp = list; - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) { - REQUIRE(VALID_LWSEARCHLIST(source)); - REQUIRE(target != NULL && *target == NULL); - - LOCK(&source->lock); - INSIST(source->refs > 0); - source->refs++; - INSIST(source->refs != 0); - UNLOCK(&source->lock); - - *target = source; -} - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_mem_t *mctx; - - REQUIRE(listp != NULL); - list = *listp; - REQUIRE(VALID_LWSEARCHLIST(list)); - - LOCK(&list->lock); - INSIST(list->refs > 0); - list->refs--; - UNLOCK(&list->lock); - - *listp = NULL; - if (list->refs != 0) - return; - - mctx = list->mctx; - while (!ISC_LIST_EMPTY(list->names)) { - dns_name_t *name = ISC_LIST_HEAD(list->names); - ISC_LIST_UNLINK(list->names, name, link); - dns_name_free(name, list->mctx); - isc_mem_put(list->mctx, name, sizeof(dns_name_t)); - } - list->magic = 0; - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - isc_mem_detach(&mctx); -} - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { - dns_name_t *newname; - isc_result_t result; - - REQUIRE(VALID_LWSEARCHLIST(list)); - REQUIRE(name != NULL); - - newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); - if (newname == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(newname, NULL); - result = dns_name_dup(name, list->mctx, newname); - if (result != ISC_R_SUCCESS) { - isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); - return (result); - } - ISC_LINK_INIT(newname, link); - ISC_LIST_APPEND(list->names, newname, link); - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots) -{ - INSIST(sctx != NULL); - sctx->relname = name; - sctx->searchname = NULL; - sctx->doneexact = false; - sctx->exactfirst = false; - sctx->ndots = ndots; - if (dns_name_isabsolute(name) || list == NULL) { - sctx->list = NULL; - return; - } - sctx->list = list; - sctx->searchname = ISC_LIST_HEAD(sctx->list->names); - if (dns_name_countlabels(name) > ndots) - sctx->exactfirst = true; -} - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - UNUSED(sctx); -} - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - - if (sctx->list == NULL) - return (ISC_R_NOMORE); - - if (sctx->searchname == NULL) { - if (sctx->exactfirst || sctx->doneexact) - return (ISC_R_NOMORE); - sctx->doneexact = true; - } else { - if (sctx->exactfirst && !sctx->doneexact) - sctx->doneexact = true; - else { - sctx->searchname = ISC_LIST_NEXT(sctx->searchname, - link); - if (sctx->searchname == NULL && sctx->doneexact) - return (ISC_R_NOMORE); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) { - dns_name_t *tname; - bool useexact = false; - - REQUIRE(sctx != NULL); - - if (sctx->list == NULL || - sctx->searchname == NULL || - (sctx->exactfirst && !sctx->doneexact)) - useexact = true; - - if (useexact) { - if (dns_name_isabsolute(sctx->relname)) - tname = NULL; - else - tname = dns_rootname; - } else - tname = sctx->searchname; - - return (dns_name_concatenate(sctx->relname, tname, absname, NULL)); -} diff --git a/bin/named-sdb/main.c b/bin/named-sdb/main.c deleted file mode 100644 index 28c50d3..0000000 --- a/bin/named-sdb/main.c +++ /dev/null @@ -1,1713 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#ifdef PKCS11CRYPTO -#include -#endif - -#include - -#ifdef HAVE_GPERFTOOLS_PROFILER -#include -#endif - -#ifdef HAVE_GEOIP2 -#include -#endif - -/* - * Defining NS_MAIN provides storage declarations (rather than extern) - * for variables in named/globals.h. - */ -#define NS_MAIN 1 - -#include -#include -#include -#include -#include /* Explicit, though named/log.h includes it. */ -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -#ifdef OPENSSL -#include -#include -#endif -#ifdef HAVE_LIBXML2 -#include -#endif -#ifdef HAVE_ZLIB -#include -#endif -/* - * Include header files for database drivers here. - */ -/* #include "xxdb.h" */ -#include "ldapdb.h" -#include "pgsqldb.h" -#include "sqlitedb.h" -#include "dirdb.h" - -#ifdef CONTRIB_DLZ -/* - * Include contributed DLZ drivers if appropriate. - */ -#include -#endif - -/* - * The maximum number of stack frames to dump on assertion failure. - */ -#ifndef BACKTRACE_MAXFRAME -#define BACKTRACE_MAXFRAME 128 -#endif - -LIBISC_EXTERNAL_DATA extern int isc_dscp_check_value; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_hour; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_day; -LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_month; - -static bool want_stats = false; -static char program_name[NAME_MAX] = "named"; -static char absolute_conffile[PATH_MAX]; -static char saved_command_line[512]; -static char version[512]; -static unsigned int maxsocks = 0; -static int maxudp = 0; - -void -ns_main_earlywarning(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - format, args); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); -} - -void -ns_main_earlyfatal(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to early fatal error)"); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); - - exit(1); -} - -ISC_PLATFORM_NORETURN_PRE static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) ISC_PLATFORM_NORETURN_POST; - -static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ - void *tracebuf[BACKTRACE_MAXFRAME]; - int i, nframes; - isc_result_t result; - const char *logsuffix = ""; - const char *fname; - - /* - * Handle assertion failures. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the assertion callback in case it is the log - * routines causing the assertion. - */ - isc_assertion_setcallback(NULL); - - result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, - &nframes); - if (result == ISC_R_SUCCESS && nframes > 0) - logsuffix = ", back trace"; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: %s(%s) failed%s", file, line, - isc_assertion_typetotext(type), cond, logsuffix); - if (result == ISC_R_SUCCESS) { - for (i = 0; i < nframes; i++) { - unsigned long offset; - - fname = NULL; - result = isc_backtrace_getsymbol(tracebuf[i], - &fname, - &offset); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, - ISC_LOG_CRITICAL, - "#%d %p in %s()+0x%lx", i, - tracebuf[i], fname, - offset); - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, - ISC_LOG_CRITICAL, - "#%d %p in ??", i, - tracebuf[i]); - } - } - } - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to assertion failure)"); - } else { - fprintf(stderr, "%s:%d: %s(%s) failed\n", - file, line, isc_assertion_typetotext(type), cond); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -ISC_PLATFORM_NORETURN_PRE static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -ISC_FORMAT_PRINTF(3, 0) ISC_PLATFORM_NORETURN_POST; - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_fatal() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the error callback in case it is the log - * routines causing the assertion. - */ - isc_error_setfatal(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: fatal error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to fatal error in library)"); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_unexpected() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - "%s:%d: unexpected error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - format, args); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } -} - -static void -lwresd_usage(void) { - fprintf(stderr, - "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] " - "[-d debuglevel] [-f|-g]\n" - " [-i pidfile] [-n number_of_cpus] " - "[-p port] [-P listen-port]\n" - " [-s] [-S sockets] [-t chrootdir] [-u username] " - "[-U listeners]\n" - " [-m {usage|trace|record|size|mctx}]\n" - "usage: lwresd [-v|-V]\n"); -} - -static void -usage(void) { - if (ns_g_lwresdonly) { - lwresd_usage(); - return; - } - fprintf(stderr, - "usage: named [-4|-6] [-c conffile] [-d debuglevel] " - "[-E engine] [-f|-g]\n" - " [-n number_of_cpus] [-p port] [-s] " - "[-S sockets] [-t chrootdir]\n" - " [-u username] [-U listeners] " - "[-m {usage|trace|record|size|mctx}]\n" - "usage: named [-v|-V]\n"); -} - -static void -save_command_line(int argc, char *argv[]) { - int i; - char *src; - char *dst; - char *eob; - const char truncated[] = "..."; - bool quoted = false; - - dst = saved_command_line; - eob = saved_command_line + sizeof(saved_command_line); - - for (i = 1; i < argc && dst < eob; i++) { - *dst++ = ' '; - - src = argv[i]; - while (*src != '\0' && dst < eob) { - /* - * This won't perfectly produce a shell-independent - * pastable command line in all circumstances, but - * comes close, and for practical purposes will - * nearly always be fine. - */ - if (quoted || isalnum(*src & 0xff) || - *src == ',' || *src == '-' || *src == '_' || - *src == '.' || *src == '/') { - *dst++ = *src++; - quoted = false; - } else { - *dst++ = '\\'; - quoted = true; - } - } - } - - INSIST(sizeof(saved_command_line) >= sizeof(truncated)); - - if (dst == eob) - strcpy(eob - sizeof(truncated), truncated); - else - *dst = '\0'; -} - -static int -parse_int(char *arg, const char *desc) { - char *endp; - int tmp; - long int ltmp; - - ltmp = strtol(arg, &endp, 10); - tmp = (int) ltmp; - if (*endp != '\0') - ns_main_earlyfatal("%s '%s' must be numeric", desc, arg); - if (tmp < 0 || tmp != ltmp) - ns_main_earlyfatal("%s '%s' out of range", desc, arg); - return (tmp); -} - -static struct flag_def { - const char *name; - unsigned int value; -} mem_debug_flags[] = { - { "none", 0}, - { "trace", ISC_MEM_DEBUGTRACE }, - { "record", ISC_MEM_DEBUGRECORD }, - { "usage", ISC_MEM_DEBUGUSAGE }, - { "size", ISC_MEM_DEBUGSIZE }, - { "mctx", ISC_MEM_DEBUGCTX }, - { NULL, 0 } -}; - -static void -set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) { - bool clear = false; - - for (;;) { - const struct flag_def *def; - const char *end = strchr(arg, ','); - int arglen; - if (end == NULL) - end = arg + strlen(arg); - arglen = (int)(end - arg); - for (def = defs; def->name != NULL; def++) { - if (arglen == (int)strlen(def->name) && - memcmp(arg, def->name, arglen) == 0) { - if (def->value == 0) - clear = true; - *ret |= def->value; - goto found; - } - } - ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg); - found: - if (clear || (*end == '\0')) - break; - arg = end + 1; - } - - if (clear) - *ret = 0; -} - -static void -printversion(bool verbose) { - char rndcconf[PATH_MAX], *dot = NULL; - isc_mem_t *mctx = NULL; - cfg_parser_t *parser = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *defaults = NULL, *obj = NULL; - - printf("%s %s%s%s \n", - ns_g_product, ns_g_version, - (*ns_g_description != '\0') ? " " : "", - ns_g_description, ns_g_srcid); - - if (!verbose) { - return; - } - printf("running on %s\n", ns_os_uname()); - printf("built by %s with %s\n", ns_g_builder, ns_g_configargs); -#ifdef __clang__ - printf("compiled by CLANG %s\n", __VERSION__); -#else -#if defined(__ICC) || defined(__INTEL_COMPILER) - printf("compiled by ICC %s\n", __VERSION__); -#else -#ifdef __GNUC__ - printf("compiled by GCC %s\n", __VERSION__); -#endif -#endif -#endif -#ifdef _MSC_VER - printf("compiled by MSVC %d\n", _MSC_VER); -#endif -#ifdef __SUNPRO_C - printf("compiled by Solaris Studio %x\n", __SUNPRO_C); -#endif -#ifdef OPENSSL - printf("compiled with OpenSSL version: %s\n", OPENSSL_VERSION_TEXT); -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 or higher */ - printf("linked to OpenSSL version: %s\n", - OpenSSL_version(OPENSSL_VERSION)); -#else - printf("linked to OpenSSL version: %s\n", - SSLeay_version(SSLEAY_VERSION)); -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -#endif -#ifdef HAVE_LIBXML2 - printf("compiled with libxml2 version: %s\n", LIBXML_DOTTED_VERSION); - printf("linked to libxml2 version: %s\n", xmlParserVersion); -#endif -#if defined(HAVE_JSON) && defined(JSON_C_VERSION) - printf("compiled with libjson-c version: %s\n", JSON_C_VERSION); - printf("linked to libjson-c version: %s\n", json_c_version()); -#endif -#if defined(HAVE_ZLIB) && defined(ZLIB_VERSION) - printf("compiled with zlib version: %s\n", ZLIB_VERSION); - printf("linked to zlib version: %s\n", zlibVersion()); -#endif -#if defined(HAVE_GEOIP2) - /* Unfortunately, no version define on link time */ - printf("linked to maxminddb version: %s\n", - MMDB_lib_version()); -#endif -#if defined(HAVE_DNSTAP) - printf("compiled with protobuf-c version: %s\n", - PROTOBUF_C_VERSION); - printf("linked to protobuf-c version: %s\n", - protobuf_c_version()); -#endif -#ifdef ISC_PLATFORM_USETHREADS - printf("threads support is enabled\n"); -#else - printf("threads support is disabled\n"); -#endif - - /* - * The default rndc.conf and rndc.key paths are in the same - * directory, but named only has rndc.key defined internally. - * We construct the rndc.conf path from it. (We could use - * NAMED_SYSCONFDIR here but the result would look wrong on - * Windows.) - */ - strlcpy(rndcconf, ns_g_keyfile, sizeof(rndcconf)); - dot = strrchr(rndcconf, '.'); - if (dot != NULL) { - size_t len = dot - rndcconf + 1; - snprintf(dot + 1, PATH_MAX - len, "conf"); - } - -#define RTC(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS) - RTC(isc_mem_create(0, 0, &mctx)); - RTC(cfg_parser_create(mctx, ns_g_lctx, &parser)); - RTC(ns_config_parsedefaults(parser, &config)); - RTC(cfg_map_get(config, "options", &defaults)); - - /* - * Print default configuration paths. - */ - printf("\n"); - printf("default paths:\n"); - printf(" named configuration: %s\n", ns_g_conffile); - printf(" rndc configuration: %s\n", rndcconf); - RTC(cfg_map_get(defaults, "bindkeys-file", &obj)); - printf(" DNSSEC root key: %s\n", cfg_obj_asstring(obj)); - printf(" nsupdate session key: %s\n", ns_g_defaultsessionkeyfile); - printf(" named PID file: %s\n", ns_g_defaultpidfile); - printf(" named lock file: %s\n", ns_g_defaultlockfile); -#if defined(HAVE_GEOIP2) - obj = NULL; - RTC(cfg_map_get(defaults, "geoip-directory", &obj)); - if (cfg_obj_isstring(obj)) { - printf(" geoip-directory: %s\n", cfg_obj_asstring(obj)); - } -#endif /* HAVE_GEOIP2 */ - cfg_obj_destroy(parser, &config); - cfg_parser_destroy(&parser); - isc_mem_detach(&mctx); -} - -static void -parse_fuzz_arg(void) { - if (!strncmp(isc_commandline_argument, "client:", 7)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 7; - ns_g_fuzz_type = ns_fuzz_client; - } else if (!strncmp(isc_commandline_argument, "tcp:", 4)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 4; - ns_g_fuzz_type = ns_fuzz_tcpclient; - } else if (!strncmp(isc_commandline_argument, "resolver:", 9)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 9; - ns_g_fuzz_type = ns_fuzz_resolver; - } else if (!strncmp(isc_commandline_argument, "http:", 5)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 5; - ns_g_fuzz_type = ns_fuzz_http; - } else if (!strncmp(isc_commandline_argument, "rndc:", 5)) { - ns_g_fuzz_named_addr = isc_commandline_argument + 5; - ns_g_fuzz_type = ns_fuzz_rndc; - } else { - ns_main_earlyfatal("unknown fuzzing type '%s'", - isc_commandline_argument); - } -} - -static void -parse_T_opt(char *option) { - const char *p; - /* - * force the server to behave (or misbehave) in - * specified ways for testing purposes. - * - * clienttest: make clients single shot with their - * own memory context. - * delay=xxxx: delay client responses by xxxx ms to - * simulate remote servers. - * dscp=x: check that dscp values are as - * expected and assert otherwise. - */ - if (!strcmp(option, "clienttest")) { - ns_g_clienttest = true; - } else if (!strncmp(option, "delay=", 6)) { - ns_g_delay = atoi(option + 6); - } else if (!strcmp(option, "dropedns")) { - ns_g_dropedns = true; - } else if (!strncmp(option, "dscp=", 5)) { - isc_dscp_check_value = atoi(option + 5); - } else if (!strcmp(option, "ednsformerr")) { - ns_g_ednsformerr = true; - } else if (!strcmp(option, "ednsnotimp")) { - ns_g_ednsnotimp = true; - } else if (!strcmp(option, "ednsrefused")) { - ns_g_ednsrefused = true; - } else if (!strcmp(option, "fixedlocal")) { - ns_g_fixedlocal = true; - } else if (!strcmp(option, "keepstderr")) { - ns_g_keepstderr = true; - } else if (!strcmp(option, "noaa")) { - ns_g_noaa = true; - } else if (!strcmp(option, "noedns")) { - ns_g_noedns = true; - } else if (!strcmp(option, "nonearest")) { - ns_g_nonearest = true; - } else if (!strcmp(option, "nosoa")) { - ns_g_nosoa = true; - } else if (!strcmp(option, "nosyslog")) { - ns_g_nosyslog = true; - } else if (!strcmp(option, "notcp")) { - ns_g_notcp = true; - } else if (!strcmp(option, "maxudp512")) { - maxudp = 512; - } else if (!strcmp(option, "maxudp1460")) { - maxudp = 1460; - } else if (!strncmp(option, "maxudp=", 7)) { - maxudp = atoi(option + 7); - if (maxudp <= 0) { - ns_main_earlyfatal("bad maxudp"); - } - } else if (!strncmp(option, "mkeytimers=", 11)) { - p = strtok(option + 11, "/"); - if (p == NULL) { - ns_main_earlyfatal("bad mkeytimer"); - } - - dns_zone_mkey_hour = atoi(p); - if (dns_zone_mkey_hour == 0) { - ns_main_earlyfatal("bad mkeytimer"); - } - - p = strtok(NULL, "/"); - if (p == NULL) { - dns_zone_mkey_day = (24 * dns_zone_mkey_hour); - dns_zone_mkey_month = (30 * dns_zone_mkey_day); - return; - } - - dns_zone_mkey_day = atoi(p); - if (dns_zone_mkey_day < dns_zone_mkey_hour) - ns_main_earlyfatal("bad mkeytimer"); - - p = strtok(NULL, "/"); - if (p == NULL) { - dns_zone_mkey_month = (30 * dns_zone_mkey_day); - return; - } - - dns_zone_mkey_month = atoi(p); - if (dns_zone_mkey_month < dns_zone_mkey_day) { - ns_main_earlyfatal("bad mkeytimer"); - } - } else if (!strcmp(option, "sigvalinsecs")) { - ns_g_sigvalinsecs = true; - } else if (!strncmp(option, "tat=", 4)) { - ns_g_tat_interval = atoi(option + 4); - } else { - fprintf(stderr, "unknown -T flag '%s'\n", option); - } -} - -static void -parse_command_line(int argc, char *argv[]) { - int ch; - int port; - const char *p; - - save_command_line(argc, argv); - - /* - * NS_MAIN_ARGS is defined in main.h, so that it can be used - * both by named and by ntservice hooks. - */ - isc_commandline_errprint = false; - while ((ch = isc_commandline_parse(argc, argv, NS_MAIN_ARGS)) != -1) { - switch (ch) { - case '4': - if (ns_g_disable4) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv4() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv4 not supported by OS"); - isc_net_disableipv6(); - ns_g_disable6 = true; - break; - case '6': - if (ns_g_disable6) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv6() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv6 not supported by OS"); - isc_net_disableipv4(); - ns_g_disable4 = true; - break; - case 'A': - parse_fuzz_arg(); - break; - case 'c': - ns_g_conffile = isc_commandline_argument; - lwresd_g_conffile = isc_commandline_argument; - if (lwresd_g_useresolvconf) - ns_main_earlyfatal("cannot specify -c and -C"); - ns_g_conffileset = true; - break; - case 'C': - lwresd_g_resolvconffile = isc_commandline_argument; - if (ns_g_conffileset) - ns_main_earlyfatal("cannot specify -c and -C"); - lwresd_g_useresolvconf = true; - break; - case 'd': - ns_g_debuglevel = parse_int(isc_commandline_argument, - "debug level"); - break; - case 'D': - /* Descriptive comment for 'ps'. */ - break; - case 'E': - ns_g_engine = isc_commandline_argument; - break; - case 'f': - ns_g_foreground = true; - break; - case 'g': - ns_g_foreground = true; - ns_g_logstderr = true; - break; - /* XXXBEW -i should be removed */ - case 'i': - lwresd_g_defaultpidfile = isc_commandline_argument; - break; - case 'l': - ns_g_lwresdonly = true; - break; - case 'L': - ns_g_logfile = isc_commandline_argument; - break; - case 'M': - if (strcmp(isc_commandline_argument, "external") == 0) - isc_mem_defaultflags = 0; - break; - case 'm': - set_flags(isc_commandline_argument, mem_debug_flags, - &isc_mem_debugging); - break; - case 'N': /* Deprecated. */ - case 'n': - ns_g_cpus = parse_int(isc_commandline_argument, - "number of cpus"); - if (ns_g_cpus == 0) - ns_g_cpus = 1; - break; - case 'p': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - ns_g_port = port; - break; - /* XXXBEW Should -P be removed? */ - case 'P': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - lwresd_g_listenport = port; - break; - case 's': - /* XXXRTH temporary syntax */ - want_stats = true; - break; - case 'S': - maxsocks = parse_int(isc_commandline_argument, - "max number of sockets"); - break; - case 't': - /* XXXJAB should we make a copy? */ - ns_g_chrootdir = isc_commandline_argument; - break; - case 'T': /* NOT DOCUMENTED */ - parse_T_opt(isc_commandline_argument); - break; - case 'U': - ns_g_udpdisp = parse_int(isc_commandline_argument, - "number of UDP listeners " - "per interface"); - break; - case 'u': - ns_g_username = isc_commandline_argument; - break; - case 'v': - printversion(false); - exit(0); - case 'V': - printversion(true); - exit(0); - case 'x': - /* Obsolete. No longer in use. Ignore. */ - break; - case 'X': - ns_g_forcelock = true; - if (strcasecmp(isc_commandline_argument, "none") != 0) - ns_g_defaultlockfile = isc_commandline_argument; - else - ns_g_defaultlockfile = NULL; - break; - case 'F': - /* Reserved for FIPS mode */ - /* FALLTHROUGH */ - case '?': - usage(); - if (isc_commandline_option == '?') - exit(0); - p = strchr(NS_MAIN_ARGS, isc_commandline_option); - if (p == NULL || *++p != ':') - ns_main_earlyfatal("unknown option '-%c'", - isc_commandline_option); - else - ns_main_earlyfatal("option '-%c' requires " - "an argument", - isc_commandline_option); - /* FALLTHROUGH */ - default: - ns_main_earlyfatal("parsing options returned %d", ch); - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - POST(argv); - - if (argc > 0) { - usage(); - ns_main_earlyfatal("extra command line arguments"); - } -} - -static isc_result_t -create_managers(void) { - isc_result_t result; - unsigned int socks; - - INSIST(ns_g_cpus_detected > 0); - -#ifdef ISC_PLATFORM_USETHREADS - if (ns_g_cpus == 0) - ns_g_cpus = ns_g_cpus_detected; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", - ns_g_cpus_detected, ns_g_cpus_detected == 1 ? "" : "s", - ns_g_cpus, ns_g_cpus == 1 ? "" : "s"); -#else - ns_g_cpus = 1; -#endif -#ifdef WIN32 - ns_g_udpdisp = 1; -#else - if (ns_g_udpdisp == 0) { - if (ns_g_cpus_detected == 1) - ns_g_udpdisp = 1; - else - ns_g_udpdisp = ns_g_cpus_detected - 1; - } - if (ns_g_udpdisp > ns_g_cpus) - ns_g_udpdisp = ns_g_cpus; -#endif -#ifdef ISC_PLATFORM_USETHREADS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "using %u UDP listener%s per interface", - ns_g_udpdisp, ns_g_udpdisp == 1 ? "" : "s"); -#endif - - result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_taskmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timermgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_socketmgr_create2(ns_g_mctx, &ns_g_socketmgr, maxsocks); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socketmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - isc__socketmgr_maxudp(ns_g_socketmgr, maxudp); - result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &socks); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "using up to %u sockets", socks); - } - - result = isc_entropy_create(ns_g_mctx, &ns_g_entropy); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_entropy_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_hash_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -static void -destroy_managers(void) { - ns_lwresd_shutdown(); - - /* - * isc_taskmgr_destroy() will block until all tasks have exited, - */ - isc_taskmgr_destroy(&ns_g_taskmgr); - isc_timermgr_destroy(&ns_g_timermgr); - isc_socketmgr_destroy(&ns_g_socketmgr); - - /* - * isc_hash_destroy() cannot be called as long as a resolver may be - * running. Calling this after isc_taskmgr_destroy() ensures the - * call is safe. - */ - isc_hash_destroy(); -} - -static void -dump_symboltable(void) { - int i; - isc_result_t result; - const char *fname; - const void *addr; - - if (isc__backtrace_nsymbols == 0) - return; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99))) - return; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_DEBUG(99), "Symbol table:"); - - for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) { - addr = NULL; - fname = NULL; - result = isc_backtrace_getsymbolfromindex(i, &addr, &fname); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99), - "[%d] %p %s", i, addr, fname); - } - } -} - -#ifdef HAVE_LIBSECCOMP -static void -setup_seccomp() { - scmp_filter_ctx ctx; - unsigned int i; - int ret; - - /* Make sure the lists are in sync */ - INSIST((sizeof(scmp_syscalls) / sizeof(int)) == - (sizeof(scmp_syscall_names) / sizeof(const char *))); - - ctx = seccomp_init(SCMP_ACT_KILL); - if (ctx == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp activation failed"); - return; - } - - for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) { - ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, - scmp_syscalls[i], 0); - if (ret < 0) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp rule failed: %s", - scmp_syscall_names[i]); - - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(9), - "added libseccomp rule: %s", - scmp_syscall_names[i]); - } - - ret = seccomp_load(ctx); - if (ret < 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - "libseccomp unable to load filter"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "libseccomp sandboxing active"); - } - - /* - * Release filter in ctx. Filters already loaded are not - * affected. - */ - seccomp_release(ctx); -} -#endif /* HAVE_LIBSECCOMP */ - -static void -setup(void) { - isc_result_t result; - isc_resourcevalue_t old_openfiles; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Get the user and group information before changing the root - * directory, so the administrator does not need to keep a copy - * of the user and group databases in the chroot'ed environment. - */ - ns_os_inituserinfo(ns_g_username); - - /* - * Initialize time conversion information - */ - ns_os_tzset(); - - ns_os_opendevnull(); - -#ifdef HAVE_LIBSCF - /* Check if named is under smf control, before chroot. */ - result = ns_smf_get_instance(&instance, 0, ns_g_mctx); - /* We don't care about instance, just check if we got one. */ - if (result == ISC_R_SUCCESS) - ns_smf_got_instance = 1; - else - ns_smf_got_instance = 0; - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); -#endif /* HAVE_LIBSCF */ - -#ifdef PATH_RANDOMDEV - /* - * Initialize system's random device as fallback entropy source - * if running chroot'ed. - */ - if (ns_g_chrootdir != NULL) { - result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_entropy_create() failed: %s", - isc_result_totext(result)); - - result = isc_entropy_createfilesource(ns_g_fallbackentropy, - PATH_RANDOMDEV); - if (result != ISC_R_SUCCESS) { - ns_main_earlywarning("could not open pre-chroot " - "entropy source %s: %s", - PATH_RANDOMDEV, - isc_result_totext(result)); - isc_entropy_detach(&ns_g_fallbackentropy); - } - } -#endif - -#ifdef ISC_PLATFORM_USETHREADS - /* - * Check for the number of cpu's before ns_os_chroot(). - */ - ns_g_cpus_detected = isc_os_ncpus(); -#endif - - ns_os_chroot(ns_g_chrootdir); - - /* - * For operating systems which have a capability mechanism, now - * is the time to switch to minimal privs and change our user id. - * On traditional UNIX systems, this call will be a no-op, and we - * will change the user ID after reading the config file the first - * time. (We need to read the config file to know which possibly - * privileged ports to bind() to.) - */ - ns_os_minprivs(); - - result = ns_log_init((ns_g_username != NULL)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("ns_log_init() failed: %s", - isc_result_totext(result)); - - /* - * Now is the time to daemonize (if we're not running in the - * foreground). We waited until now because we wanted to get - * a valid logging context setup. We cannot daemonize any later, - * because calling create_managers() will create threads, which - * would be lost after fork(). - */ - if (!ns_g_foreground) - ns_os_daemonize(); - - /* - * We call isc_app_start() here as some versions of FreeBSD's fork() - * destroys all the signal handling it sets up. - */ - result = isc_app_start(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_app_start() failed: %s", - isc_result_totext(result)); - - ldapdb_clear(); - pgsqldb_clear(); - dirdb_clear(); - sqlitedb_clear(); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "starting %s %s%s%s ", - ns_g_product, ns_g_version, - *ns_g_description ? " " : "", ns_g_description, - ns_g_srcid); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "running on %s", ns_os_uname()); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "built with %s", ns_g_configargs); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "running as: %s%s", - program_name, saved_command_line); -#ifdef __clang__ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by CLANG %s", __VERSION__); -#else -#if defined(__ICC) || defined(__INTEL_COMPILER) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by ICC %s", __VERSION__); -#else -#ifdef __GNUC__ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by GCC %s", __VERSION__); -#endif -#endif -#endif -#ifdef _MSC_VER - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by MSVC %d", _MSC_VER); -#endif -#ifdef __SUNPRO_C - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled by Solaris Studio %x", __SUNPRO_C); -#endif -#ifdef OPENSSL - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with OpenSSL version: %s", - OPENSSL_VERSION_TEXT); -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 or higher */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to OpenSSL version: %s", - OpenSSL_version(OPENSSL_VERSION)); -#else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to OpenSSL version: %s", - SSLeay_version(SSLEAY_VERSION)); -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -#endif -#ifdef HAVE_LIBXML2 - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with libxml2 version: %s", - LIBXML_DOTTED_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to libxml2 version: %s", xmlParserVersion); -#endif -#if defined(HAVE_JSON) && defined(JSON_C_VERSION) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with libjson-c version: %s", JSON_C_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to libjson-c version: %s", json_c_version()); -#endif -#if defined(HAVE_ZLIB) && defined(ZLIB_VERSION) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "compiled with zlib version: %s", ZLIB_VERSION); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "linked to zlib version: %s", zlibVersion()); -#endif -#ifdef ISC_PLATFORM_USETHREADS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "threads support is enabled"); -#else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "threads support is disabled"); -#endif - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "----------------------------------------------------"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "BIND 9 is maintained by Internet Systems Consortium,"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "Inc. (ISC), a non-profit 501(c)(3) public-benefit "); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "corporation. Support and training for BIND 9 are "); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "available at https://www.isc.org/support"); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, - "----------------------------------------------------"); - - dump_symboltable(); - - /* - * Get the initial resource limits. - */ - (void)isc_resource_getlimit(isc_resource_stacksize, - &ns_g_initstacksize); - (void)isc_resource_getlimit(isc_resource_datasize, - &ns_g_initdatasize); - (void)isc_resource_getlimit(isc_resource_coresize, - &ns_g_initcoresize); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - - /* - * System resources cannot effectively be tuned on some systems. - * Raise the limit in such cases for safety. - */ - old_openfiles = ns_g_initopenfiles; - ns_os_adjustnofile(); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - if (old_openfiles != ns_g_initopenfiles) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "adjusted limit on open files from " - "%" PRIu64 " to " - "%" PRIu64, - old_openfiles, ns_g_initopenfiles); - } - - /* - * If the named configuration filename is relative, prepend the current - * directory's name before possibly changing to another directory. - */ - if (! isc_file_isabsolute(ns_g_conffile)) { - result = isc_file_absolutepath(ns_g_conffile, - absolute_conffile, - sizeof(absolute_conffile)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("could not construct absolute path " - "of configuration file: %s", - isc_result_totext(result)); - ns_g_conffile = absolute_conffile; - } - - /* - * Record the server's startup time. - */ - result = isc_time_now(&ns_g_boottime); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_time_now() failed: %s", - isc_result_totext(result)); - - result = create_managers(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("create_managers() failed: %s", - isc_result_totext(result)); - - ns_builtin_init(); - - /* - * Add calls to register sdb drivers here. - */ - /* xxdb_init(); */ - -#ifdef ISC_DLZ_DLOPEN - /* - * Register the DLZ "dlopen" driver. - */ - result = dlz_dlopen_init(ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("dlz_dlopen_init() failed: %s", - isc_result_totext(result)); -#endif - -#if CONTRIB_DLZ - /* - * Register any other contributed DLZ drivers. - */ - result = dlz_drivers_init(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("dlz_drivers_init() failed: %s", - isc_result_totext(result)); -#endif - - result = ldapdb_init(); - if (result != ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB ldap module initialisation failed: %s.", - isc_result_totext(result) - ); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB ldap zone database will be unavailable." - ); - }else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "SDB ldap zone database module loaded." - ); - - result = pgsqldb_init(); - if (result != ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB pgsql module initialisation failed: %s.", - isc_result_totext(result) - ); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB pgsql zone database will be unavailable." - ); - }else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "SDB postgreSQL DB zone database module loaded." - ); - - result = sqlitedb_init(); - if (result != ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB sqlite3 module initialisation failed: %s.", - isc_result_totext(result) - ); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB sqlite3 zone database will be unavailable." - ); - }else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "SDB sqlite3 DB zone database module loaded." - ); - - result = dirdb_init(); - if (result != ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB directory DB module initialisation failed: %s.", - isc_result_totext(result) - ); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_ERROR, - "SDB directory DB zone database will be unavailable." - ); - }else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "SDB directory DB zone database module loaded." - ); - - - ns_server_create(ns_g_mctx, &ns_g_server); - -#ifdef HAVE_LIBSECCOMP - setup_seccomp(); -#endif /* HAVE_LIBSECCOMP */ -} - -static void -cleanup(void) { - destroy_managers(); - - if (ns_g_mapped != NULL) - dns_acl_detach(&ns_g_mapped); - - ns_server_destroy(&ns_g_server); - - isc_entropy_detach(&ns_g_entropy); - if (ns_g_fallbackentropy != NULL) - isc_entropy_detach(&ns_g_fallbackentropy); - - ns_builtin_deinit(); - - /* - * Add calls to unregister sdb drivers here. - */ - /* xxdb_clear(); */ - -#ifdef CONTRIB_DLZ - /* - * Unregister contributed DLZ drivers. - */ - dlz_drivers_clear(); -#endif -#ifdef ISC_DLZ_DLOPEN - /* - * Unregister "dlopen" DLZ driver. - */ - dlz_dlopen_clear(); -#endif - - dns_name_destroy(); - - ldapdb_clear(); - pgsqldb_clear(); - sqlitedb_clear(); - dirdb_clear(); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "exiting"); - ns_log_shutdown(); -} - -static char *memstats = NULL; - -void -ns_main_setmemstats(const char *filename) { - /* - * Caller has to ensure locking. - */ - - if (memstats != NULL) { - free(memstats); - memstats = NULL; - } - - if (filename == NULL) - return; - - memstats = strdup(filename); -} - -#ifdef HAVE_LIBSCF -/* - * Get FMRI for the named process. - */ -isc_result_t -ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { - scf_handle_t *h = NULL; - int namelen; - char *instance; - - REQUIRE(ins_name != NULL && *ins_name == NULL); - - if ((h = scf_handle_create(SCF_VERSION)) == NULL) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_create() failed: %s", - scf_strerror(scf_error())); - return (ISC_R_FAILURE); - } - - if (scf_handle_bind(h) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_bind() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((namelen = scf_myname(h, NULL, 0)) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_smf_get_instance memory " - "allocation failed: %s", - isc_result_totext(ISC_R_NOMEMORY)); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if (scf_myname(h, instance, namelen + 1) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - isc_mem_free(mctx, instance); - return (ISC_R_FAILURE); - } - - scf_handle_destroy(h); - *ins_name = instance; - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ - -/* main entry point, possibly hooked */ - -int -main(int argc, char *argv[]) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - -#ifdef HAVE_GPERFTOOLS_PROFILER - (void) ProfilerStart(NULL); -#endif - -#ifdef WIN32 - /* - * Prevent unbuffered I/O from crippling named performance on Windows - * when it is logging to stderr (e.g. in system tests). Use full - * buffering (_IOFBF) as line buffering (_IOLBF) is unavailable on - * Windows and fflush() is called anyway after each log message gets - * written to the default stderr logging channels created by libisc. - */ - setvbuf(stderr, NULL, _IOFBF, BUFSIZ); -#endif - -#ifdef HAVE_LIBXML2 - xmlInitThreads(); -#endif /* HAVE_LIBXML2 */ - - /* - * Record version in core image. - * strings named.core | grep "named version:" - */ - strlcat(version, -#if defined(NO_VERSION_DATE) || !defined(__DATE__) - "named version: BIND " VERSION " <" SRCID ">", -#else - "named version: BIND " VERSION " <" SRCID "> (" __DATE__ ")", -#endif - sizeof(version)); - result = isc_file_progname(*argv, program_name, sizeof(program_name)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("program name too long"); - - if (strcmp(program_name, "lwresd") == 0) - ns_g_lwresdonly = true; - - isc_assertion_setcallback(assertion_failed); - isc_error_setfatal(library_fatal_error); - isc_error_setunexpected(library_unexpected_error); - - ns_os_init(program_name); - - dns_result_register(); - dst_result_register(); - isccc_result_register(); -#ifdef PKCS11CRYPTO - pk11_result_register(); -#endif - - parse_command_line(argc, argv); - -#ifdef ENABLE_AFL - if (ns_g_fuzz_type != ns_fuzz_none) { - named_fuzz_setup(); - } - - if (ns_g_fuzz_type == ns_fuzz_resolver) { - dns_resolver_setfuzzing(); - } else if (ns_g_fuzz_type == ns_fuzz_http) { - isc_httpd_setfinishhook(named_fuzz_notify); - } -#endif - /* - * Warn about common configuration error. - */ - if (ns_g_chrootdir != NULL) { - int len = strlen(ns_g_chrootdir); - if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 && - (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\')) - ns_main_earlywarning("config filename (-c %s) contains " - "chroot path (-t %s)", - ns_g_conffile, ns_g_chrootdir); - } - - result = isc_mem_create(0, 0, &ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_mem_create() failed: %s", - isc_result_totext(result)); - isc_mem_setname(ns_g_mctx, "main", NULL); - - setup(); - - /* - * Start things running and then wait for a shutdown request - * or reload. - */ - do { - result = isc_app_run(); - - if (result == ISC_R_RELOAD) { - ns_server_reloadwanted(ns_g_server); - } else if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run(): %s", - isc_result_totext(result)); - /* - * Force exit. - */ - result = ISC_R_SUCCESS; - } - } while (result != ISC_R_SUCCESS); - -#ifdef HAVE_LIBSCF - if (ns_smf_want_disable == 1) { - result = ns_smf_get_instance(&instance, 1, ns_g_mctx); - if (result == ISC_R_SUCCESS && instance != NULL) { - if (smf_disable_instance(instance, 0) != 0) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "smf_disable_instance() " - "failed for %s : %s", - instance, - scf_strerror(scf_error())); - } - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); - } -#endif /* HAVE_LIBSCF */ - - cleanup(); - - if (want_stats) { - isc_mem_stats(ns_g_mctx, stdout); - isc_mutex_stats(stdout); - } - - if (ns_g_memstatistics && memstats != NULL) { - FILE *fp = NULL; - result = isc_stdio_open(memstats, "w", &fp); - if (result == ISC_R_SUCCESS) { - isc_mem_stats(ns_g_mctx, fp); - isc_mutex_stats(fp); - (void) isc_stdio_close(fp); - } - } - isc_mem_destroy(&ns_g_mctx); - isc_mem_checkdestroyed(stderr); - - ns_main_setmemstats(NULL); - - isc_app_finish(); - - ns_os_closedevnull(); - - ns_os_shutdown(); - -#ifdef HAVE_LIBXML2 - xmlCleanupThreads(); -#endif /* HAVE_LIBXML2 */ - -#ifdef HAVE_GPERFTOOLS_PROFILER - ProfilerStop(); -#endif - - return (0); -} diff --git a/bin/named-sdb/named.8 b/bin/named-sdb/named.8 deleted file mode 100644 index 0acd6b5..0000000 --- a/bin/named-sdb/named.8 +++ /dev/null @@ -1,379 +0,0 @@ -.\" Copyright (C) 2000, 2001, 2003-2009, 2011, 2013-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: named -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2014-02-19 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "NAMED" "8" "2014\-02\-19" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -named \- Internet domain name server -.SH "SYNOPSIS" -.HP \w'\fBnamed\fR\ 'u -\fBnamed\fR [[\fB\-4\fR] | [\fB\-6\fR]] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-D\ \fR\fB\fIstring\fR\fR] [\fB\-E\ \fR\fB\fIengine\-name\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-L\ \fR\fB\fIlogfile\fR\fR] [\fB\-M\ \fR\fB\fIoption\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-U\ \fR\fB\fI#listeners\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-X\ \fR\fB\fIlock\-file\fR\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR] -.SH "DESCRIPTION" -.PP -\fBnamed\fR -is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC\&. For more information on the DNS, see RFCs 1033, 1034, and 1035\&. -.PP -When invoked without arguments, -\fBnamed\fR -will read the default configuration file -/etc/named\&.conf, read any initial data, and listen for queries\&. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4\&. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive\&. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -/etc/named\&.conf\&. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible -\fBdirectory\fR -option in the configuration file, -\fIconfig\-file\fR -should be an absolute pathname\&. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon\*(Aqs debug level to -\fIdebug\-level\fR\&. Debugging traces from -\fBnamed\fR -become more verbose as the debug level increases\&. -.RE -.PP -\-D \fIstring\fR -.RS 4 -Specifies a string that is used to identify a instance of -\fBnamed\fR -in a process listing\&. The contents of -\fIstring\fR -are not examined\&. -.RE -.PP -\-E \fIengine\-name\fR -.RS 4 -When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing\&. -.sp -When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module\&. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11"\&. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i\&.e\&. do not daemonize)\&. -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -stderr\&. -.RE -.PP -\-L \fIlogfile\fR -.RS 4 -Log to the file -\fBlogfile\fR -by default instead of the system log\&. -.RE -.PP -\-M \fIoption\fR -.RS 4 -Sets the default memory context options\&. Currently the only supported option is -\fIexternal\fR, which causes the internal memory manager to be bypassed in favor of system\-provided memory allocation functions\&. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags\&. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR\&. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\&. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs\&. If not specified, -\fBnamed\fR -will try to determine the number of CPUs present and create one thread per CPU\&. If it is unable to determine the number of CPUs, a single worker thread will be created\&. -.RE -.PP -\-p \fIport\fR -.RS 4 -Listen for queries on port -\fIport\fR\&. If not specified, the default is port 53\&. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -stdout -on exit\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.PP -\-S \fI#max\-socks\fR -.RS 4 -Allow -\fBnamed\fR -to use up to -\fI#max\-socks\fR -sockets\&. The default value is 4096 on systems built with default configuration options, and 21000 on systems built with "configure \-\-with\-tuning=large"\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be unnecessary for the vast majority of users\&. The use of this option could even be harmful because the specified value may exceed the limitation of the underlying system API\&. It is therefore set only when the default configuration causes exhaustion of file descriptors and the operational environment is known to support the specified number of sockets\&. Note also that the actual maximum number is normally a little fewer than the specified value because -\fBnamed\fR -reserves some file descriptors for its internal use\&. -.sp .5v -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn\*(Aqt enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail\&. -.sp .5v -.RE -.RE -.PP -\-U \fI#listeners\fR -.RS 4 -Use -\fI#listeners\fR -worker threads to listen for incoming UDP packets on each address\&. If not specified, -\fBnamed\fR -will calculate a default value based on the number of detected CPUs: 1 for 1 CPU, and the number of detected CPUs minus one for machines with more than 1 CPU\&. This cannot be increased to a value higher than the number of CPUs\&. If -\fB\-n\fR -has been set to a higher value than the number of detected CPUs, then -\fB\-U\fR -may be increased as high as that value, but no higher\&. On Windows, the number of UDP listeners is hardwired to 1 and this option has no effect\&. -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -On Linux, -\fBnamed\fR -uses the kernel\*(Aqs capability mechanism to drop all root privileges except the ability to -\fBbind(2)\fR -to a privileged port and set process resource limits\&. Unfortunately, this means that the -\fB\-u\fR -option only works when -\fBnamed\fR -is run on kernel 2\&.2\&.18 or later, or kernel 2\&.3\&.99\-pre3 or later, since previous kernels did not allow privileges to be retained after -\fBsetuid(2)\fR\&. -.sp .5v -.RE -.RE -.PP -\-v -.RS 4 -Report the version number and exit\&. -.RE -.PP -\-V -.RS 4 -Report the version number and build options, and exit\&. -.RE -.PP -\-X \fIlock\-file\fR -.RS 4 -Acquire a lock on the specified file at runtime; this helps to prevent duplicate -\fBnamed\fR -instances from running simultaneously\&. Use of this option overrides the -\fBlock\-file\fR -option in -named\&.conf\&. If set to -none, the lock file check is disabled\&. -.RE -.PP -\-x \fIcache\-file\fR -.RS 4 -Load data from -\fIcache\-file\fR -into the cache of the default view\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBWarning\fR -.ps -1 -.br -This option must not be used\&. It is only of interest to BIND 9 developers and may be removed or changed in a future release\&. -.sp .5v -.RE -.RE -.SH "SIGNALS" -.PP -In routine operation, signals should not be used to control the nameserver; -\fBrndc\fR -should be used instead\&. -.PP -SIGHUP -.RS 4 -Force a reload of the server\&. -.RE -.PP -SIGINT, SIGTERM -.RS 4 -Shut down the server\&. -.RE -.PP -The result of sending any other signals to the server is undefined\&. -.SH "CONFIGURATION" -.PP -The -\fBnamed\fR -configuration file is too complex to describe in detail here\&. A complete description is provided in the -BIND 9 Administrator Reference Manual\&. -.PP -\fBnamed\fR -inherits the -\fBumask\fR -(file creation mode mask) from the parent process\&. If files created by -\fBnamed\fR, such as journal files, need to have custom permissions, the -\fBumask\fR -should be set explicitly in the script used to start the -\fBnamed\fR -process\&. -.SH "FILES" -.PP -/etc/named\&.conf -.RS 4 -The default configuration file\&. -.RE -.PP -/var/run/named/named\&.pid -.RS 4 -The default process\-id file\&. -.RE -.SH "SEE ALSO" -.PP -RFC 1033, -RFC 1034, -RFC 1035, -\fBnamed-checkconf\fR(8), -\fBnamed-checkzone\fR(8), -\fBrndc\fR(8), -\fBlwresd\fR(8), -\fBnamed.conf\fR(5), -BIND 9 Administrator Reference Manual\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2000, 2001, 2003-2009, 2011, 2013-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-sdb/named.conf.5 b/bin/named-sdb/named.conf.5 deleted file mode 100644 index 7d5b3ca..0000000 --- a/bin/named-sdb/named.conf.5 +++ /dev/null @@ -1,1026 +0,0 @@ -.\" Copyright (C) 2004-2020 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" This Source Code Form is subject to the terms of the Mozilla Public -.\" License, v. 2.0. If a copy of the MPL was not distributed with this -.\" file, You can obtain one at http://mozilla.org/MPL/2.0/. -.\" -.hy 0 -.ad l -'\" t -.\" Title: named.conf -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 2020-03-12 -.\" Manual: BIND9 -.\" Source: ISC -.\" Language: English -.\" -.TH "NAMED\&.CONF" "5" "2020\-03\-12" "ISC" "BIND9" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -named.conf \- configuration file for \fBnamed\fR -.SH "SYNOPSIS" -.HP \w'\fBnamed\&.conf\fR\ 'u -\fBnamed\&.conf\fR -.SH "DESCRIPTION" -.PP -named\&.conf -is the configuration file for -\fBnamed\fR\&. Statements are enclosed in braces and terminated with a semi\-colon\&. Clauses in the statements are also semi\-colon terminated\&. The usual comment styles are supported: -.PP -C style: /* */ -.PP -C++ style: // to end of line -.PP -Unix style: # to end of line -.SH "ACL" -.sp -.if n \{\ -.RS 4 -.\} -.nf -acl \fIstring\fR { \fIaddress_match_element\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "CONTROLS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -controls { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | - * ) [ port ( \fIinteger\fR | * ) ] allow - { \fIaddress_match_element\fR; \&.\&.\&. } [ - keys { \fIstring\fR; \&.\&.\&. } ] [ read\-only - \fIboolean\fR ]; - unix \fIquoted_string\fR perm \fIinteger\fR - owner \fIinteger\fR group \fIinteger\fR [ - keys { \fIstring\fR; \&.\&.\&. } ] [ read\-only - \fIboolean\fR ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "DLZ" -.sp -.if n \{\ -.RS 4 -.\} -.nf -dlz \fIstring\fR { - database \fIstring\fR; - search \fIboolean\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "DYNDB" -.sp -.if n \{\ -.RS 4 -.\} -.nf -dyndb \fIstring\fR \fIquoted_string\fR { - \fIunspecified\-text\fR }; -.fi -.if n \{\ -.RE -.\} -.SH "KEY" -.sp -.if n \{\ -.RS 4 -.\} -.nf -key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "LOGGING" -.sp -.if n \{\ -.RS 4 -.\} -.nf -logging { - category \fIstring\fR { \fIstring\fR; \&.\&.\&. }; - channel \fIstring\fR { - buffered \fIboolean\fR; - file \fIquoted_string\fR [ versions ( "unlimited" | \fIinteger\fR ) - ] [ size \fIsize\fR ]; - null; - print\-category \fIboolean\fR; - print\-severity \fIboolean\fR; - print\-time \fIboolean\fR; - severity \fIlog_severity\fR; - stderr; - syslog [ \fIsyslog_facility\fR ]; - }; -}; -.fi -.if n \{\ -.RE -.\} -.SH "LWRES" -.sp -.if n \{\ -.RS 4 -.\} -.nf -lwres { - listen\-on [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - lwres\-clients \fIinteger\fR; - lwres\-tasks \fIinteger\fR; - ndots \fIinteger\fR; - search { \fIstring\fR; \&.\&.\&. }; - view \fIstring\fR [ \fIclass\fR ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "MANAGED\-KEYS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -managed\-keys { \fIstring\fR \fIstring\fR \fIinteger\fR - \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "MASTERS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -masters \fIstring\fR [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ - port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "OPTIONS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -options { - acache\-cleaning\-interval \fIinteger\fR; - acache\-enable \fIboolean\fR; - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - allow\-new\-zones \fIboolean\fR; - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - answer\-cookie \fIboolean\fR; - attach\-cache \fIstring\fR; - auth\-nxdomain \fIboolean\fR; // default changed - auto\-dnssec ( allow | maintain | off ); - automatic\-interface\-scan \fIboolean\fR; - avoid\-v4\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - avoid\-v6\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - bindkeys\-file \fIquoted_string\fR; - blackhole { \fIaddress_match_element\fR; \&.\&.\&. }; - cache\-file \fIquoted_string\fR; - catalog\-zones { zone \fIstring\fR [ default\-masters [ port \fIinteger\fR ] - [ dscp \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ port - \fIinteger\fR ] | \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key - \fIstring\fR ]; \&.\&.\&. } ] [ zone\-directory \fIquoted_string\fR ] [ - in\-memory \fIboolean\fR ] [ min\-update\-interval \fIinteger\fR ]; \&.\&.\&. }; - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( master | slave | response - ) ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - cleaning\-interval \fIinteger\fR; - clients\-per\-query \fIinteger\fR; - cookie\-algorithm ( aes | sha1 | sha256 | siphash24 ); - cookie\-secret \fIstring\fR; - coresize ( default | unlimited | \fIsizeval\fR ); - datasize ( default | unlimited | \fIsizeval\fR ); - deny\-answer\-addresses { \fIaddress_match_element\fR; \&.\&.\&. } [ - except\-from { \fIquoted_string\fR; \&.\&.\&. } ]; - deny\-answer\-aliases { \fIquoted_string\fR; \&.\&.\&. } [ except\-from { - \fIquoted_string\fR; \&.\&.\&. } ]; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - directory \fIquoted_string\fR; - disable\-algorithms \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-ds\-digests \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-empty\-zone \fIstring\fR; - dns64 \fInetprefix\fR { - break\-dnssec \fIboolean\fR; - clients { \fIaddress_match_element\fR; \&.\&.\&. }; - exclude { \fIaddress_match_element\fR; \&.\&.\&. }; - mapped { \fIaddress_match_element\fR; \&.\&.\&. }; - recursive\-only \fIboolean\fR; - suffix \fIipv6_address\fR; - }; - dns64\-contact \fIstring\fR; - dns64\-server \fIstring\fR; - dnssec\-accept\-expired \fIboolean\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-enable \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-lookaside ( \fIstring\fR trust\-anchor - \fIstring\fR | auto | no ); - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - dnssec\-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; \&.\&.\&. }; - dnstap\-identity ( \fIquoted_string\fR | none | - hostname ); - dnstap\-output ( file | unix ) \fIquoted_string\fR; - dnstap\-version ( \fIquoted_string\fR | none ); - dscp \fIinteger\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { ( \fIquoted_string\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv4_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] ); \&.\&.\&. }; - dump\-file \fIquoted_string\fR; - edns\-udp\-size \fIinteger\fR; - empty\-contact \fIstring\fR; - empty\-server \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - fetch\-quota\-params \fIinteger\fR \fIfixedpoint\fR \fIfixedpoint\fR \fIfixedpoint\fR; - fetches\-per\-server \fIinteger\fR [ ( drop | fail ) ]; - fetches\-per\-zone \fIinteger\fR [ ( drop | fail ) ]; - files ( default | unlimited | \fIsizeval\fR ); - filter\-aaaa { \fIaddress_match_element\fR; \&.\&.\&. }; - filter\-aaaa\-on\-v4 ( break\-dnssec | \fIboolean\fR ); - filter\-aaaa\-on\-v6 ( break\-dnssec | \fIboolean\fR ); - flush\-zones\-on\-shutdown \fIboolean\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - fstrm\-set\-buffer\-hint \fIinteger\fR; - fstrm\-set\-flush\-timeout \fIinteger\fR; - fstrm\-set\-input\-queue\-size \fIinteger\fR; - fstrm\-set\-output\-notify\-threshold \fIinteger\fR; - fstrm\-set\-output\-queue\-model ( mpsc | spsc ); - fstrm\-set\-output\-queue\-size \fIinteger\fR; - fstrm\-set\-reopen\-interval \fIinteger\fR; - geoip\-directory ( \fIquoted_string\fR | none ); - geoip\-use\-ecs \fIboolean\fR; - heartbeat\-interval \fIinteger\fR; - hostname ( \fIquoted_string\fR | none ); - inline\-signing \fIboolean\fR; - interface\-interval \fIinteger\fR; - ixfr\-from\-differences ( master | slave | \fIboolean\fR ); - keep\-response\-order { \fIaddress_match_element\fR; \&.\&.\&. }; - key\-directory \fIquoted_string\fR; - lame\-ttl \fIttlval\fR; - listen\-on [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { - \fIaddress_match_element\fR; \&.\&.\&. }; - listen\-on\-v6 [ port \fIinteger\fR ] [ dscp - \fIinteger\fR ] { - \fIaddress_match_element\fR; \&.\&.\&. }; - lmdb\-mapsize \fIsizeval\fR; - lock\-file ( \fIquoted_string\fR | none ); - managed\-keys\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - match\-mapped\-addresses \fIboolean\fR; - max\-acache\-size ( unlimited | \fIsizeval\fR ); - max\-cache\-size ( default | unlimited | \fIsizeval\fR | \fIpercentage\fR ); - max\-cache\-ttl \fIinteger\fR; - max\-clients\-per\-query \fIinteger\fR; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-ncache\-ttl \fIinteger\fR; - max\-records \fIinteger\fR; - max\-recursion\-depth \fIinteger\fR; - max\-recursion\-queries \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-rsa\-exponent\-size \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - memstatistics \fIboolean\fR; - memstatistics\-file \fIquoted_string\fR; - message\-compression \fIboolean\fR; - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - minimal\-any \fIboolean\fR; - minimal\-responses ( no\-auth | no\-auth\-recursive | \fIboolean\fR ); - multi\-master \fIboolean\fR; - no\-case\-compress { \fIaddress_match_element\fR; \&.\&.\&. }; - nocookie\-udp\-size \fIinteger\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-rate \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - nta\-lifetime \fIttlval\fR; - nta\-recheck \fIttlval\fR; - nxdomain\-redirect \fIstring\fR; - pid\-file ( \fIquoted_string\fR | none ); - port \fIinteger\fR; - preferred\-glue \fIstring\fR; - prefetch \fIinteger\fR [ \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - querylog \fIboolean\fR; - random\-device \fIquoted_string\fR; - rate\-limit { - all\-per\-second \fIinteger\fR; - errors\-per\-second \fIinteger\fR; - exempt\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - ipv4\-prefix\-length \fIinteger\fR; - ipv6\-prefix\-length \fIinteger\fR; - log\-only \fIboolean\fR; - max\-table\-size \fIinteger\fR; - min\-table\-size \fIinteger\fR; - nodata\-per\-second \fIinteger\fR; - nxdomains\-per\-second \fIinteger\fR; - qps\-scale \fIinteger\fR; - referrals\-per\-second \fIinteger\fR; - responses\-per\-second \fIinteger\fR; - slip \fIinteger\fR; - window \fIinteger\fR; - }; - recursing\-file \fIquoted_string\fR; - recursion \fIboolean\fR; - recursive\-clients \fIinteger\fR; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - require\-server\-cookie \fIboolean\fR; - reserved\-sockets \fIinteger\fR; - resolver\-query\-timeout \fIinteger\fR; - response\-policy { zone \fIstring\fR [ log \fIboolean\fR ] [ max\-policy\-ttl - \fIinteger\fR ] [ policy ( cname | disabled | drop | given | no\-op - | nodata | nxdomain | passthru | tcp\-only \fIquoted_string\fR ) ] [ - recursive\-only \fIboolean\fR ]; \&.\&.\&. } [ break\-dnssec \fIboolean\fR ] [ - max\-policy\-ttl \fIinteger\fR ] [ min\-ns\-dots \fIinteger\fR ] [ - nsip\-wait\-recurse \fIboolean\fR ] [ qname\-wait\-recurse \fIboolean\fR ] - [ recursive\-only \fIboolean\fR ]; - root\-delegation\-only [ exclude { \fIquoted_string\fR; \&.\&.\&. } ]; - root\-key\-sentinel \fIboolean\fR; - rrset\-order { [ class \fIstring\fR ] [ type \fIstring\fR ] [ name - \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; \&.\&.\&. }; - secroots\-file \fIquoted_string\fR; - send\-cookie \fIboolean\fR; - serial\-query\-rate \fIinteger\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-id ( \fIquoted_string\fR | none | hostname ); - servfail\-ttl \fIttlval\fR; - session\-keyalg \fIstring\fR; - session\-keyfile ( \fIquoted_string\fR | none ); - session\-keyname \fIstring\fR; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - sortlist { \fIaddress_match_element\fR; \&.\&.\&. }; - stacksize ( default | unlimited | \fIsizeval\fR ); - startup\-notify\-rate \fIinteger\fR; - statistics\-file \fIquoted_string\fR; - tcp\-clients \fIinteger\fR; - tcp\-listen\-queue \fIinteger\fR; - tkey\-dhkey \fIquoted_string\fR \fIinteger\fR; - tkey\-domain \fIquoted_string\fR; - tkey\-gssapi\-credential \fIquoted_string\fR; - tkey\-gssapi\-keytab \fIquoted_string\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-message\-size \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - transfers\-in \fIinteger\fR; - transfers\-out \fIinteger\fR; - transfers\-per\-ns \fIinteger\fR; - trust\-anchor\-telemetry \fIboolean\fR; // experimental - try\-tcp\-refresh \fIboolean\fR; - update\-check\-ksk \fIboolean\fR; - use\-alt\-transfer\-source \fIboolean\fR; - use\-v4\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - use\-v6\-udp\-ports { \fIportrange\fR; \&.\&.\&. }; - v6\-bias \fIinteger\fR; - version ( \fIquoted_string\fR | none ); - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "SERVER" -.sp -.if n \{\ -.RS 4 -.\} -.nf -server \fInetprefix\fR { - bogus \fIboolean\fR; - edns \fIboolean\fR; - edns\-udp\-size \fIinteger\fR; - edns\-version \fIinteger\fR; - keys \fIserver_key\fR; - max\-udp\-size \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - send\-cookie \fIboolean\fR; - tcp\-only \fIboolean\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - transfers \fIinteger\fR; -}; -.fi -.if n \{\ -.RE -.\} -.SH "STATISTICS\-CHANNELS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -statistics\-channels { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | - * ) [ port ( \fIinteger\fR | * ) ] [ - allow { \fIaddress_match_element\fR; \&.\&.\&. - } ]; -}; -.fi -.if n \{\ -.RE -.\} -.SH "TRUSTED\-KEYS" -.sp -.if n \{\ -.RS 4 -.\} -.nf -trusted\-keys { \fIstring\fR \fIinteger\fR \fIinteger\fR - \fIinteger\fR \fIquoted_string\fR; \&.\&.\&. }; -.fi -.if n \{\ -.RE -.\} -.SH "VIEW" -.sp -.if n \{\ -.RS 4 -.\} -.nf -view \fIstring\fR [ \fIclass\fR ] { - acache\-cleaning\-interval \fIinteger\fR; - acache\-enable \fIboolean\fR; - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - allow\-new\-zones \fIboolean\fR; - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-cache\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-recursion\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - attach\-cache \fIstring\fR; - auth\-nxdomain \fIboolean\fR; // default changed - auto\-dnssec ( allow | maintain | off ); - cache\-file \fIquoted_string\fR; - catalog\-zones { zone \fIstring\fR [ default\-masters [ port \fIinteger\fR ] - [ dscp \fIinteger\fR ] { ( \fImasters\fR | \fIipv4_address\fR [ port - \fIinteger\fR ] | \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key - \fIstring\fR ]; \&.\&.\&. } ] [ zone\-directory \fIquoted_string\fR ] [ - in\-memory \fIboolean\fR ] [ min\-update\-interval \fIinteger\fR ]; \&.\&.\&. }; - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( master | slave | response - ) ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - cleaning\-interval \fIinteger\fR; - clients\-per\-query \fIinteger\fR; - deny\-answer\-addresses { \fIaddress_match_element\fR; \&.\&.\&. } [ - except\-from { \fIquoted_string\fR; \&.\&.\&. } ]; - deny\-answer\-aliases { \fIquoted_string\fR; \&.\&.\&. } [ except\-from { - \fIquoted_string\fR; \&.\&.\&. } ]; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - disable\-algorithms \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-ds\-digests \fIstring\fR { \fIstring\fR; - \&.\&.\&. }; - disable\-empty\-zone \fIstring\fR; - dlz \fIstring\fR { - database \fIstring\fR; - search \fIboolean\fR; - }; - dns64 \fInetprefix\fR { - break\-dnssec \fIboolean\fR; - clients { \fIaddress_match_element\fR; \&.\&.\&. }; - exclude { \fIaddress_match_element\fR; \&.\&.\&. }; - mapped { \fIaddress_match_element\fR; \&.\&.\&. }; - recursive\-only \fIboolean\fR; - suffix \fIipv6_address\fR; - }; - dns64\-contact \fIstring\fR; - dns64\-server \fIstring\fR; - dnssec\-accept\-expired \fIboolean\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-enable \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-lookaside ( \fIstring\fR trust\-anchor - \fIstring\fR | auto | no ); - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - dnssec\-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; \&.\&.\&. }; - dual\-stack\-servers [ port \fIinteger\fR ] { ( \fIquoted_string\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv4_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] [ dscp \fIinteger\fR ] ); \&.\&.\&. }; - dyndb \fIstring\fR \fIquoted_string\fR { - \fIunspecified\-text\fR }; - edns\-udp\-size \fIinteger\fR; - empty\-contact \fIstring\fR; - empty\-server \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - fetch\-quota\-params \fIinteger\fR \fIfixedpoint\fR \fIfixedpoint\fR \fIfixedpoint\fR; - fetches\-per\-server \fIinteger\fR [ ( drop | fail ) ]; - fetches\-per\-zone \fIinteger\fR [ ( drop | fail ) ]; - filter\-aaaa { \fIaddress_match_element\fR; \&.\&.\&. }; - filter\-aaaa\-on\-v4 ( break\-dnssec | \fIboolean\fR ); - filter\-aaaa\-on\-v6 ( break\-dnssec | \fIboolean\fR ); - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences ( master | slave | \fIboolean\fR ); - key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; - }; - key\-directory \fIquoted_string\fR; - lame\-ttl \fIttlval\fR; - lmdb\-mapsize \fIsizeval\fR; - managed\-keys { \fIstring\fR \fIstring\fR - \fIinteger\fR \fIinteger\fR \fIinteger\fR - \fIquoted_string\fR; \&.\&.\&. }; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - match\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - match\-destinations { \fIaddress_match_element\fR; \&.\&.\&. }; - match\-recursive\-only \fIboolean\fR; - max\-acache\-size ( unlimited | \fIsizeval\fR ); - max\-cache\-size ( default | unlimited | \fIsizeval\fR | \fIpercentage\fR ); - max\-cache\-ttl \fIinteger\fR; - max\-clients\-per\-query \fIinteger\fR; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-ncache\-ttl \fIinteger\fR; - max\-records \fIinteger\fR; - max\-recursion\-depth \fIinteger\fR; - max\-recursion\-queries \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - message\-compression \fIboolean\fR; - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - minimal\-any \fIboolean\fR; - minimal\-responses ( no\-auth | no\-auth\-recursive | \fIboolean\fR ); - multi\-master \fIboolean\fR; - no\-case\-compress { \fIaddress_match_element\fR; \&.\&.\&. }; - nocookie\-udp\-size \fIinteger\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - nta\-lifetime \fIttlval\fR; - nta\-recheck \fIttlval\fR; - nxdomain\-redirect \fIstring\fR; - preferred\-glue \fIstring\fR; - prefetch \fIinteger\fR [ \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv4_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] ) | ( [ [ address ] ( \fIipv6_address\fR | * ) ] - port ( \fIinteger\fR | * ) ) ) [ dscp \fIinteger\fR ]; - rate\-limit { - all\-per\-second \fIinteger\fR; - errors\-per\-second \fIinteger\fR; - exempt\-clients { \fIaddress_match_element\fR; \&.\&.\&. }; - ipv4\-prefix\-length \fIinteger\fR; - ipv6\-prefix\-length \fIinteger\fR; - log\-only \fIboolean\fR; - max\-table\-size \fIinteger\fR; - min\-table\-size \fIinteger\fR; - nodata\-per\-second \fIinteger\fR; - nxdomains\-per\-second \fIinteger\fR; - qps\-scale \fIinteger\fR; - referrals\-per\-second \fIinteger\fR; - responses\-per\-second \fIinteger\fR; - slip \fIinteger\fR; - window \fIinteger\fR; - }; - recursion \fIboolean\fR; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - require\-server\-cookie \fIboolean\fR; - resolver\-query\-timeout \fIinteger\fR; - response\-policy { zone \fIstring\fR [ log \fIboolean\fR ] [ max\-policy\-ttl - \fIinteger\fR ] [ policy ( cname | disabled | drop | given | no\-op - | nodata | nxdomain | passthru | tcp\-only \fIquoted_string\fR ) ] [ - recursive\-only \fIboolean\fR ]; \&.\&.\&. } [ break\-dnssec \fIboolean\fR ] [ - max\-policy\-ttl \fIinteger\fR ] [ min\-ns\-dots \fIinteger\fR ] [ - nsip\-wait\-recurse \fIboolean\fR ] [ qname\-wait\-recurse \fIboolean\fR ] - [ recursive\-only \fIboolean\fR ]; - root\-delegation\-only [ exclude { \fIquoted_string\fR; \&.\&.\&. } ]; - root\-key\-sentinel \fIboolean\fR; - rrset\-order { [ class \fIstring\fR ] [ type \fIstring\fR ] [ name - \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; \&.\&.\&. }; - send\-cookie \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server \fInetprefix\fR { - bogus \fIboolean\fR; - edns \fIboolean\fR; - edns\-udp\-size \fIinteger\fR; - edns\-version \fIinteger\fR; - keys \fIserver_key\fR; - max\-udp\-size \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * - ) ] [ dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR - | * ) ] [ dscp \fIinteger\fR ]; - provide\-ixfr \fIboolean\fR; - query\-source ( ( [ address ] ( \fIipv4_address\fR | * ) [ port - ( \fIinteger\fR | * ) ] ) | ( [ [ address ] ( - \fIipv4_address\fR | * ) ] port ( \fIinteger\fR | * ) ) ) [ - dscp \fIinteger\fR ]; - query\-source\-v6 ( ( [ address ] ( \fIipv6_address\fR | * ) [ - port ( \fIinteger\fR | * ) ] ) | ( [ [ address ] ( - \fIipv6_address\fR | * ) ] port ( \fIinteger\fR | * ) ) ) [ - dscp \fIinteger\fR ]; - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - request\-nsid \fIboolean\fR; - send\-cookie \fIboolean\fR; - tcp\-only \fIboolean\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - transfers \fIinteger\fR; - }; - servfail\-ttl \fIttlval\fR; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - sortlist { \fIaddress_match_element\fR; \&.\&.\&. }; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - trust\-anchor\-telemetry \fIboolean\fR; // experimental - trusted\-keys { \fIstring\fR \fIinteger\fR - \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; - \&.\&.\&. }; - try\-tcp\-refresh \fIboolean\fR; - update\-check\-ksk \fIboolean\fR; - use\-alt\-transfer\-source \fIboolean\fR; - v6\-bias \fIinteger\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - zone \fIstring\fR [ \fIclass\fR ] { - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( - \fImasters\fR | \fIipv4_address\fR [ port \fIinteger\fR ] | - \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key \fIstring\fR ]; - \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - auto\-dnssec ( allow | maintain | off ); - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - dialup ( notify | notify\-passive | passive | refresh | - \fIboolean\fR ); - dlz \fIstring\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - file \fIquoted_string\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( - \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ - dscp \fIinteger\fR ]; \&.\&.\&. }; - in\-view \fIstring\fR; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences \fIboolean\fR; - journal \fIquoted_string\fR; - key\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - masters [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR - | \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ - port \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - max\-ixfr\-log\-size ( default | unlimited | - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-records \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * - ) ] [ dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR - | * ) ] [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - pubkey \fIinteger\fR - \fIinteger\fR - \fIinteger\fR - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-addresses { ( \fIipv4_address\fR | \fIipv6_address\fR ); \&.\&.\&. }; - server\-names { \fIquoted_string\fR; \&.\&.\&. }; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( - \fIinteger\fR | * ) ] [ dscp \fIinteger\fR ]; - try\-tcp\-refresh \fIboolean\fR; - type ( delegation\-only | forward | hint | master | redirect - | slave | static\-stub | stub ); - update\-check\-ksk \fIboolean\fR; - update\-policy ( local | { ( deny | grant ) \fIstring\fR ( - 6to4\-self | external | krb5\-self | krb5\-selfsub | - krb5\-subdomain | ms\-self | ms\-selfsub | ms\-subdomain | - name | self | selfsub | selfwild | subdomain | tcp\-self - | wildcard | zonesub ) [ \fIstring\fR ] \fIrrtypelist\fR; \&.\&.\&. }; - use\-alt\-transfer\-source \fIboolean\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); - }; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "ZONE" -.sp -.if n \{\ -.RS 4 -.\} -.nf -zone \fIstring\fR [ \fIclass\fR ] { - allow\-notify { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-query\-on { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-transfer { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update { \fIaddress_match_element\fR; \&.\&.\&. }; - allow\-update\-forwarding { \fIaddress_match_element\fR; \&.\&.\&. }; - also\-notify [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - alt\-transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | - * ) ] [ dscp \fIinteger\fR ]; - auto\-dnssec ( allow | maintain | off ); - check\-dup\-records ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx ( fail | warn | ignore ); - check\-mx\-cname ( fail | warn | ignore ); - check\-names ( fail | warn | ignore ); - check\-sibling \fIboolean\fR; - check\-spf ( warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - check\-wildcard \fIboolean\fR; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - dialup ( notify | notify\-passive | passive | refresh | \fIboolean\fR ); - dlz \fIstring\fR; - dnssec\-dnskey\-kskonly \fIboolean\fR; - dnssec\-loadkeys\-interval \fIinteger\fR; - dnssec\-secure\-to\-insecure \fIboolean\fR; - dnssec\-update\-mode ( maintain | no\-resign ); - file \fIquoted_string\fR; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fIipv4_address\fR - | \fIipv6_address\fR ) [ port \fIinteger\fR ] [ dscp \fIinteger\fR ]; \&.\&.\&. }; - in\-view \fIstring\fR; - inline\-signing \fIboolean\fR; - ixfr\-from\-differences \fIboolean\fR; - journal \fIquoted_string\fR; - key\-directory \fIquoted_string\fR; - masterfile\-format ( map | raw | text ); - masterfile\-style ( full | relative ); - masters [ port \fIinteger\fR ] [ dscp \fIinteger\fR ] { ( \fImasters\fR | - \fIipv4_address\fR [ port \fIinteger\fR ] | \fIipv6_address\fR [ port - \fIinteger\fR ] ) [ key \fIstring\fR ]; \&.\&.\&. }; - max\-journal\-size ( unlimited | \fIsizeval\fR ); - max\-records \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-zone\-ttl ( unlimited | \fIttlval\fR ); - min\-refresh\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - notify ( explicit | master\-only | \fIboolean\fR ); - notify\-delay \fIinteger\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ] - [ dscp \fIinteger\fR ]; - notify\-to\-soa \fIboolean\fR; - pubkey \fIinteger\fR \fIinteger\fR - request\-expire \fIboolean\fR; - request\-ixfr \fIboolean\fR; - serial\-update\-method ( date | increment | unixtime ); - server\-addresses { ( \fIipv4_address\fR | \fIipv6_address\fR ); \&.\&.\&. }; - server\-names { \fIquoted_string\fR; \&.\&.\&. }; - sig\-signing\-nodes \fIinteger\fR; - sig\-signing\-signatures \fIinteger\fR; - sig\-signing\-type \fIinteger\fR; - sig\-validity\-interval \fIinteger\fR [ \fIinteger\fR ]; - transfer\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ] [ - dscp \fIinteger\fR ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) - ] [ dscp \fIinteger\fR ]; - try\-tcp\-refresh \fIboolean\fR; - type ( delegation\-only | forward | hint | master | redirect | slave - | static\-stub | stub ); - update\-check\-ksk \fIboolean\fR; - update\-policy ( local | { ( deny | grant ) \fIstring\fR ( 6to4\-self | - external | krb5\-self | krb5\-selfsub | krb5\-subdomain | ms\-self - | ms\-selfsub | ms\-subdomain | name | self | selfsub | selfwild - | subdomain | tcp\-self | wildcard | zonesub ) [ \fIstring\fR ] - \fIrrtypelist\fR; \&.\&.\&. }; - use\-alt\-transfer\-source \fIboolean\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zone\-statistics ( full | terse | none | \fIboolean\fR ); -}; -.fi -.if n \{\ -.RE -.\} -.SH "FILES" -.PP -/etc/named\&.conf -.SH "SEE ALSO" -.PP -\fBddns-confgen\fR(8), -\fBnamed\fR(8), -\fBnamed-checkconf\fR(8), -\fBrndc\fR(8), -\fBrndc-confgen\fR(8), -BIND 9 Administrator Reference Manual\&. -.SH "AUTHOR" -.PP -\fBInternet Systems Consortium, Inc\&.\fR -.SH "COPYRIGHT" -.br -Copyright \(co 2004-2020 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/bin/named-sdb/named.conf.docbook b/bin/named-sdb/named.conf.docbook deleted file mode 100644 index ed137f2..0000000 --- a/bin/named-sdb/named.conf.docbook +++ /dev/null @@ -1,1005 +0,0 @@ - - - - - - - 2020-03-12 - - - ISC - Internet Systems Consortium, Inc. - - - - named.conf - 5 - BIND9 - - - - named.conf - configuration file for named - - - - - 2004 - 2005 - 2006 - 2007 - 2008 - 2009 - 2010 - 2011 - 2012 - 2013 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - named.conf - - - - DESCRIPTION - - named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - - - C style: /* */ - - - C++ style: // to end of line - - - Unix style: # to end of line - - - - ACL - - -acl string { address_match_element; ... }; - - - - CONTROLS - - -controls { - inet ( ipv4_address | ipv6_address | - * ) [ port ( integer | * ) ] allow - { address_match_element; ... } [ - keys { string; ... } ] [ read-only - boolean ]; - unix quoted_string perm integer - owner integer group integer [ - keys { string; ... } ] [ read-only - boolean ]; -}; - - - - DLZ - - -dlz string { - database string; - search boolean; -}; - - - - DYNDB - - -dyndb string quoted_string { - unspecified-text }; - - - - KEY - - -key string { - algorithm string; - secret string; -}; - - - - LOGGING - - -logging { - category string { string; ... }; - channel string { - buffered boolean; - file quoted_string [ versions ( "unlimited" | integer ) - ] [ size size ]; - null; - print-category boolean; - print-severity boolean; - print-time boolean; - severity log_severity; - stderr; - syslog [ syslog_facility ]; - }; -}; - - - - LWRES - - -lwres { - listen-on [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - lwres-clients integer; - lwres-tasks integer; - ndots integer; - search { string; ... }; - view string [ class ]; -}; - - - - MANAGED-KEYS - - -managed-keys { string string integer - integer integer quoted_string; ... }; - - - - MASTERS - - -masters string [ port integer ] [ dscp - integer ] { ( masters | ipv4_address [ - port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - - - - OPTIONS - - -options { - acache-cleaning-interval integer; - acache-enable boolean; - additional-from-auth boolean; - additional-from-cache boolean; - allow-new-zones boolean; - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-query-cache-on { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-recursion { address_match_element; ... }; - allow-recursion-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - answer-cookie boolean; - attach-cache string; - auth-nxdomain boolean; // default changed - auto-dnssec ( allow | maintain | off ); - automatic-interface-scan boolean; - avoid-v4-udp-ports { portrange; ... }; - avoid-v6-udp-ports { portrange; ... }; - bindkeys-file quoted_string; - blackhole { address_match_element; ... }; - cache-file quoted_string; - catalog-zones { zone string [ default-masters [ port integer ] - [ dscp integer ] { ( masters | ipv4_address [ port - integer ] | ipv6_address [ port integer ] ) [ key - string ]; ... } ] [ zone-directory quoted_string ] [ - in-memory boolean ] [ min-update-interval integer ]; ... }; - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( master | slave | response - ) ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - cleaning-interval integer; - clients-per-query integer; - cookie-algorithm ( aes | sha1 | sha256 | siphash24 ); - cookie-secret string; - coresize ( default | unlimited | sizeval ); - datasize ( default | unlimited | sizeval ); - deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; - dialup ( notify | notify-passive | passive | refresh | boolean ); - directory quoted_string; - disable-algorithms string { string; - ... }; - disable-ds-digests string { string; - ... }; - disable-empty-zone string; - dns64 netprefix { - break-dnssec boolean; - clients { address_match_element; ... }; - exclude { address_match_element; ... }; - mapped { address_match_element; ... }; - recursive-only boolean; - suffix ipv6_address; - }; - dns64-contact string; - dns64-server string; - dnssec-accept-expired boolean; - dnssec-dnskey-kskonly boolean; - dnssec-enable boolean; - dnssec-loadkeys-interval integer; - dnssec-lookaside ( string trust-anchor - string | auto | no ); - dnssec-must-be-secure string boolean; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dnstap-identity ( quoted_string | none | - hostname ); - dnstap-output ( file | unix ) quoted_string; - dnstap-version ( quoted_string | none ); - dscp integer; - dual-stack-servers [ port integer ] { ( quoted_string [ port - integer ] [ dscp integer ] | ipv4_address [ port - integer ] [ dscp integer ] | ipv6_address [ port - integer ] [ dscp integer ] ); ... }; - dump-file quoted_string; - edns-udp-size integer; - empty-contact string; - empty-server string; - empty-zones-enable boolean; - fetch-quota-params integer fixedpoint fixedpoint fixedpoint; - fetches-per-server integer [ ( drop | fail ) ]; - fetches-per-zone integer [ ( drop | fail ) ]; - files ( default | unlimited | sizeval ); - filter-aaaa { address_match_element; ... }; - filter-aaaa-on-v4 ( break-dnssec | boolean ); - filter-aaaa-on-v6 ( break-dnssec | boolean ); - flush-zones-on-shutdown boolean; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - fstrm-set-buffer-hint integer; - fstrm-set-flush-timeout integer; - fstrm-set-input-queue-size integer; - fstrm-set-output-notify-threshold integer; - fstrm-set-output-queue-model ( mpsc | spsc ); - fstrm-set-output-queue-size integer; - fstrm-set-reopen-interval integer; - geoip-directory ( quoted_string | none ); - geoip-use-ecs boolean; - heartbeat-interval integer; - hostname ( quoted_string | none ); - inline-signing boolean; - interface-interval integer; - ixfr-from-differences ( master | slave | boolean ); - keep-response-order { address_match_element; ... }; - key-directory quoted_string; - lame-ttl ttlval; - listen-on [ port integer ] [ dscp - integer ] { - address_match_element; ... }; - listen-on-v6 [ port integer ] [ dscp - integer ] { - address_match_element; ... }; - lmdb-mapsize sizeval; - lock-file ( quoted_string | none ); - managed-keys-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - match-mapped-addresses boolean; - max-acache-size ( unlimited | sizeval ); - max-cache-size ( default | unlimited | sizeval | percentage ); - max-cache-ttl integer; - max-clients-per-query integer; - max-journal-size ( unlimited | sizeval ); - max-ncache-ttl integer; - max-records integer; - max-recursion-depth integer; - max-recursion-queries integer; - max-refresh-time integer; - max-retry-time integer; - max-rsa-exponent-size integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-udp-size integer; - max-zone-ttl ( unlimited | ttlval ); - memstatistics boolean; - memstatistics-file quoted_string; - message-compression boolean; - min-refresh-time integer; - min-retry-time integer; - minimal-any boolean; - minimal-responses ( no-auth | no-auth-recursive | boolean ); - multi-master boolean; - no-case-compress { address_match_element; ... }; - nocookie-udp-size integer; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-rate integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - nta-lifetime ttlval; - nta-recheck ttlval; - nxdomain-redirect string; - pid-file ( quoted_string | none ); - port integer; - preferred-glue string; - prefetch integer [ integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - querylog boolean; - random-device quoted_string; - rate-limit { - all-per-second integer; - errors-per-second integer; - exempt-clients { address_match_element; ... }; - ipv4-prefix-length integer; - ipv6-prefix-length integer; - log-only boolean; - max-table-size integer; - min-table-size integer; - nodata-per-second integer; - nxdomains-per-second integer; - qps-scale integer; - referrals-per-second integer; - responses-per-second integer; - slip integer; - window integer; - }; - recursing-file quoted_string; - recursion boolean; - recursive-clients integer; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - require-server-cookie boolean; - reserved-sockets integer; - resolver-query-timeout integer; - response-policy { zone string [ log boolean ] [ max-policy-ttl - integer ] [ policy ( cname | disabled | drop | given | no-op - | nodata | nxdomain | passthru | tcp-only quoted_string ) ] [ - recursive-only boolean ]; ... } [ break-dnssec boolean ] [ - max-policy-ttl integer ] [ min-ns-dots integer ] [ - nsip-wait-recurse boolean ] [ qname-wait-recurse boolean ] - [ recursive-only boolean ]; - root-delegation-only [ exclude { quoted_string; ... } ]; - root-key-sentinel boolean; - rrset-order { [ class string ] [ type string ] [ name - quoted_string ] string string; ... }; - secroots-file quoted_string; - send-cookie boolean; - serial-query-rate integer; - serial-update-method ( date | increment | unixtime ); - server-id ( quoted_string | none | hostname ); - servfail-ttl ttlval; - session-keyalg string; - session-keyfile ( quoted_string | none ); - session-keyname string; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - sortlist { address_match_element; ... }; - stacksize ( default | unlimited | sizeval ); - startup-notify-rate integer; - statistics-file quoted_string; - tcp-clients integer; - tcp-listen-queue integer; - tkey-dhkey quoted_string integer; - tkey-domain quoted_string; - tkey-gssapi-credential quoted_string; - tkey-gssapi-keytab quoted_string; - transfer-format ( many-answers | one-answer ); - transfer-message-size integer; - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - transfers-in integer; - transfers-out integer; - transfers-per-ns integer; - trust-anchor-telemetry boolean; // experimental - try-tcp-refresh boolean; - update-check-ksk boolean; - use-alt-transfer-source boolean; - use-v4-udp-ports { portrange; ... }; - use-v6-udp-ports { portrange; ... }; - v6-bias integer; - version ( quoted_string | none ); - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - zone-statistics ( full | terse | none | boolean ); -}; - - - - SERVER - - -server netprefix { - bogus boolean; - edns boolean; - edns-udp-size integer; - edns-version integer; - keys server_key; - max-udp-size integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - send-cookie boolean; - tcp-only boolean; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - transfers integer; -}; - - - - STATISTICS-CHANNELS - - -statistics-channels { - inet ( ipv4_address | ipv6_address | - * ) [ port ( integer | * ) ] [ - allow { address_match_element; ... - } ]; -}; - - - - TRUSTED-KEYS - - -trusted-keys { string integer integer - integer quoted_string; ... }; - - - - VIEW - - -view string [ class ] { - acache-cleaning-interval integer; - acache-enable boolean; - additional-from-auth boolean; - additional-from-cache boolean; - allow-new-zones boolean; - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-query-cache-on { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-recursion { address_match_element; ... }; - allow-recursion-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - attach-cache string; - auth-nxdomain boolean; // default changed - auto-dnssec ( allow | maintain | off ); - cache-file quoted_string; - catalog-zones { zone string [ default-masters [ port integer ] - [ dscp integer ] { ( masters | ipv4_address [ port - integer ] | ipv6_address [ port integer ] ) [ key - string ]; ... } ] [ zone-directory quoted_string ] [ - in-memory boolean ] [ min-update-interval integer ]; ... }; - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( master | slave | response - ) ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - cleaning-interval integer; - clients-per-query integer; - deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; - dialup ( notify | notify-passive | passive | refresh | boolean ); - disable-algorithms string { string; - ... }; - disable-ds-digests string { string; - ... }; - disable-empty-zone string; - dlz string { - database string; - search boolean; - }; - dns64 netprefix { - break-dnssec boolean; - clients { address_match_element; ... }; - exclude { address_match_element; ... }; - mapped { address_match_element; ... }; - recursive-only boolean; - suffix ipv6_address; - }; - dns64-contact string; - dns64-server string; - dnssec-accept-expired boolean; - dnssec-dnskey-kskonly boolean; - dnssec-enable boolean; - dnssec-loadkeys-interval integer; - dnssec-lookaside ( string trust-anchor - string | auto | no ); - dnssec-must-be-secure string boolean; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dual-stack-servers [ port integer ] { ( quoted_string [ port - integer ] [ dscp integer ] | ipv4_address [ port - integer ] [ dscp integer ] | ipv6_address [ port - integer ] [ dscp integer ] ); ... }; - dyndb string quoted_string { - unspecified-text }; - edns-udp-size integer; - empty-contact string; - empty-server string; - empty-zones-enable boolean; - fetch-quota-params integer fixedpoint fixedpoint fixedpoint; - fetches-per-server integer [ ( drop | fail ) ]; - fetches-per-zone integer [ ( drop | fail ) ]; - filter-aaaa { address_match_element; ... }; - filter-aaaa-on-v4 ( break-dnssec | boolean ); - filter-aaaa-on-v6 ( break-dnssec | boolean ); - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - inline-signing boolean; - ixfr-from-differences ( master | slave | boolean ); - key string { - algorithm string; - secret string; - }; - key-directory quoted_string; - lame-ttl ttlval; - lmdb-mapsize sizeval; - managed-keys { string string - integer integer integer - quoted_string; ... }; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - match-clients { address_match_element; ... }; - match-destinations { address_match_element; ... }; - match-recursive-only boolean; - max-acache-size ( unlimited | sizeval ); - max-cache-size ( default | unlimited | sizeval | percentage ); - max-cache-ttl integer; - max-clients-per-query integer; - max-journal-size ( unlimited | sizeval ); - max-ncache-ttl integer; - max-records integer; - max-recursion-depth integer; - max-recursion-queries integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-udp-size integer; - max-zone-ttl ( unlimited | ttlval ); - message-compression boolean; - min-refresh-time integer; - min-retry-time integer; - minimal-any boolean; - minimal-responses ( no-auth | no-auth-recursive | boolean ); - multi-master boolean; - no-case-compress { address_match_element; ... }; - nocookie-udp-size integer; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - nta-lifetime ttlval; - nta-recheck ttlval; - nxdomain-redirect string; - preferred-glue string; - prefetch integer [ integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port ( - integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ] - port ( integer | * ) ) ) [ dscp integer ]; - rate-limit { - all-per-second integer; - errors-per-second integer; - exempt-clients { address_match_element; ... }; - ipv4-prefix-length integer; - ipv6-prefix-length integer; - log-only boolean; - max-table-size integer; - min-table-size integer; - nodata-per-second integer; - nxdomains-per-second integer; - qps-scale integer; - referrals-per-second integer; - responses-per-second integer; - slip integer; - window integer; - }; - recursion boolean; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - require-server-cookie boolean; - resolver-query-timeout integer; - response-policy { zone string [ log boolean ] [ max-policy-ttl - integer ] [ policy ( cname | disabled | drop | given | no-op - | nodata | nxdomain | passthru | tcp-only quoted_string ) ] [ - recursive-only boolean ]; ... } [ break-dnssec boolean ] [ - max-policy-ttl integer ] [ min-ns-dots integer ] [ - nsip-wait-recurse boolean ] [ qname-wait-recurse boolean ] - [ recursive-only boolean ]; - root-delegation-only [ exclude { quoted_string; ... } ]; - root-key-sentinel boolean; - rrset-order { [ class string ] [ type string ] [ name - quoted_string ] string string; ... }; - send-cookie boolean; - serial-update-method ( date | increment | unixtime ); - server netprefix { - bogus boolean; - edns boolean; - edns-udp-size integer; - edns-version integer; - keys server_key; - max-udp-size integer; - notify-source ( ipv4_address | * ) [ port ( integer | * - ) ] [ dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer - | * ) ] [ dscp integer ]; - provide-ixfr boolean; - query-source ( ( [ address ] ( ipv4_address | * ) [ port - ( integer | * ) ] ) | ( [ [ address ] ( - ipv4_address | * ) ] port ( integer | * ) ) ) [ - dscp integer ]; - query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ - port ( integer | * ) ] ) | ( [ [ address ] ( - ipv6_address | * ) ] port ( integer | * ) ) ) [ - dscp integer ]; - request-expire boolean; - request-ixfr boolean; - request-nsid boolean; - send-cookie boolean; - tcp-only boolean; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - transfers integer; - }; - servfail-ttl ttlval; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - sortlist { address_match_element; ... }; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - trust-anchor-telemetry boolean; // experimental - trusted-keys { string integer - integer integer quoted_string; - ... }; - try-tcp-refresh boolean; - update-check-ksk boolean; - use-alt-transfer-source boolean; - v6-bias integer; - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - zone string [ class ] { - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( - masters | ipv4_address [ port integer ] | - ipv6_address [ port integer ] ) [ key string ]; - ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - auto-dnssec ( allow | maintain | off ); - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - database string; - delegation-only boolean; - dialup ( notify | notify-passive | passive | refresh | - boolean ); - dlz string; - dnssec-dnskey-kskonly boolean; - dnssec-loadkeys-interval integer; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - file quoted_string; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( - ipv4_address | ipv6_address ) [ port integer ] [ - dscp integer ]; ... }; - in-view string; - inline-signing boolean; - ixfr-from-differences boolean; - journal quoted_string; - key-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - masters [ port integer ] [ dscp integer ] { ( masters - | ipv4_address [ port integer ] | ipv6_address [ - port integer ] ) [ key string ]; ... }; - max-ixfr-log-size ( default | unlimited | - max-journal-size ( unlimited | sizeval ); - max-records integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-zone-ttl ( unlimited | ttlval ); - min-refresh-time integer; - min-retry-time integer; - multi-master boolean; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * - ) ] [ dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer - | * ) ] [ dscp integer ]; - notify-to-soa boolean; - pubkey integer - integer - integer - request-expire boolean; - request-ixfr boolean; - serial-update-method ( date | increment | unixtime ); - server-addresses { ( ipv4_address | ipv6_address ); ... }; - server-names { quoted_string; ... }; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - transfer-source ( ipv4_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( - integer | * ) ] [ dscp integer ]; - try-tcp-refresh boolean; - type ( delegation-only | forward | hint | master | redirect - | slave | static-stub | stub ); - update-check-ksk boolean; - update-policy ( local | { ( deny | grant ) string ( - 6to4-self | external | krb5-self | krb5-selfsub | - krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | - name | self | selfsub | selfwild | subdomain | tcp-self - | wildcard | zonesub ) [ string ] rrtypelist; ... }; - use-alt-transfer-source boolean; - zero-no-soa-ttl boolean; - zone-statistics ( full | terse | none | boolean ); - }; - zone-statistics ( full | terse | none | boolean ); -}; - - - - ZONE - - -zone string [ class ] { - allow-notify { address_match_element; ... }; - allow-query { address_match_element; ... }; - allow-query-on { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - also-notify [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - alt-transfer-source ( ipv4_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | - * ) ] [ dscp integer ]; - auto-dnssec ( allow | maintain | off ); - check-dup-records ( fail | warn | ignore ); - check-integrity boolean; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-names ( fail | warn | ignore ); - check-sibling boolean; - check-spf ( warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-wildcard boolean; - database string; - delegation-only boolean; - dialup ( notify | notify-passive | passive | refresh | boolean ); - dlz string; - dnssec-dnskey-kskonly boolean; - dnssec-loadkeys-interval integer; - dnssec-secure-to-insecure boolean; - dnssec-update-mode ( maintain | no-resign ); - file quoted_string; - forward ( first | only ); - forwarders [ port integer ] [ dscp integer ] { ( ipv4_address - | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; - in-view string; - inline-signing boolean; - ixfr-from-differences boolean; - journal quoted_string; - key-directory quoted_string; - masterfile-format ( map | raw | text ); - masterfile-style ( full | relative ); - masters [ port integer ] [ dscp integer ] { ( masters | - ipv4_address [ port integer ] | ipv6_address [ port - integer ] ) [ key string ]; ... }; - max-journal-size ( unlimited | sizeval ); - max-records integer; - max-refresh-time integer; - max-retry-time integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-zone-ttl ( unlimited | ttlval ); - min-refresh-time integer; - min-retry-time integer; - multi-master boolean; - notify ( explicit | master-only | boolean ); - notify-delay integer; - notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] - [ dscp integer ]; - notify-to-soa boolean; - pubkey integer integer - request-expire boolean; - request-ixfr boolean; - serial-update-method ( date | increment | unixtime ); - server-addresses { ( ipv4_address | ipv6_address ); ... }; - server-names { quoted_string; ... }; - sig-signing-nodes integer; - sig-signing-signatures integer; - sig-signing-type integer; - sig-validity-interval integer [ integer ]; - transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [ - dscp integer ]; - transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) - ] [ dscp integer ]; - try-tcp-refresh boolean; - type ( delegation-only | forward | hint | master | redirect | slave - | static-stub | stub ); - update-check-ksk boolean; - update-policy ( local | { ( deny | grant ) string ( 6to4-self | - external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self - | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild - | subdomain | tcp-self | wildcard | zonesub ) [ string ] - rrtypelist; ... }; - use-alt-transfer-source boolean; - zero-no-soa-ttl boolean; - zone-statistics ( full | terse | none | boolean ); -}; - - - - FILES - - /etc/named.conf - - - - SEE ALSO - - - ddns-confgen8 - , - - named8 - , - - named-checkconf8 - , - - rndc8 - , - - rndc-confgen8 - , - BIND 9 Administrator Reference Manual. - - - - diff --git a/bin/named-sdb/named.conf.html b/bin/named-sdb/named.conf.html deleted file mode 100644 index e0bcac8..0000000 --- a/bin/named-sdb/named.conf.html +++ /dev/null @@ -1,940 +0,0 @@ - - - - - -named.conf - - -
-
-
-

Name

-

named.conf — configuration file for named

-
-
-

Synopsis

-

named.conf

-
-
-

DESCRIPTION

-

named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: -

-

- C style: /* */ -

-

- C++ style: // to end of line -

-

- Unix style: # to end of line -

-
-
-

ACL

-


-acl�string�{�address_match_element;�...�};
-

-
-
-

CONTROLS

-


-controls�{
- inet�(�ipv4_address�|�ipv6_address�|
- ����*�)�[�port�(�integer�|�*�)�]�allow
- ����{�address_match_element;�...�}�[
- ����keys�{�string;�...�}�]�[�read-only
- ����boolean�];
- unix�quoted_string�perm�integer
- ����owner�integer�group�integer�[
- ����keys�{�string;�...�}�]�[�read-only
- ����boolean�];
-};
-

-
-
-

DLZ

-


-dlz�string�{
- database�string;
- search�boolean;
-};
-

-
-
-

DYNDB

-


-dyndb�string�quoted_string�{
-����unspecified-text�};
-

-
-
-

KEY

-


-key�string�{
- algorithm�string;
- secret�string;
-};
-

-
-
-

LOGGING

-


-logging�{
- category�string�{�string;�...�};
- channel�string�{
- buffered�boolean;
- file�quoted_string�[�versions�(�"unlimited"�|�integer�)
- ����]�[�size�size�];
- null;
- print-category�boolean;
- print-severity�boolean;
- print-time�boolean;
- severity�log_severity;
- stderr;
- syslog�[�syslog_facility�];
- };
-};
-

-
-
-

LWRES

-


-lwres�{
- listen-on�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- lwres-clients�integer;
- lwres-tasks�integer;
- ndots�integer;
- search�{�string;�...�};
- view�string�[�class�];
-};
-

-
-
-

MANAGED-KEYS

-


-managed-keys�{�string�string�integer
-����integer�integer�quoted_string;�...�};
-

-
-
-

MASTERS

-


-masters�string�[�port�integer�]�[�dscp
-����integer�]�{�(�masters�|�ipv4_address�[
-����port�integer�]�|�ipv6_address�[�port
-����integer�]�)�[�key�string�];�...�};
-

-
-
-

OPTIONS

-


-options�{
- acache-cleaning-interval�integer;
- acache-enable�boolean;
- additional-from-auth�boolean;
- additional-from-cache�boolean;
- allow-new-zones�boolean;
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-cache�{�address_match_element;�...�};
- allow-query-cache-on�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-recursion�{�address_match_element;�...�};
- allow-recursion-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- answer-cookie�boolean;
- attach-cache�string;
- auth-nxdomain�boolean;�//�default�changed
- auto-dnssec�(�allow�|�maintain�|�off�);
- automatic-interface-scan�boolean;
- avoid-v4-udp-ports�{�portrange;�...�};
- avoid-v6-udp-ports�{�portrange;�...�};
- bindkeys-file�quoted_string;
- blackhole�{�address_match_element;�...�};
- cache-file�quoted_string;
- catalog-zones�{�zone�string�[�default-masters�[�port�integer�]
- ����[�dscp�integer�]�{�(�masters�|�ipv4_address�[�port
- ����integer�]�|�ipv6_address�[�port�integer�]�)�[�key
- ����string�];�...�}�]�[�zone-directory�quoted_string�]�[
- ����in-memory�boolean�]�[�min-update-interval�integer�];�...�};
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�master�|�slave�|�response
- ����)�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- cleaning-interval�integer;
- clients-per-query�integer;
- cookie-algorithm�(�aes�|�sha1�|�sha256�|�siphash24�);
- cookie-secret�string;
- coresize�(�default�|�unlimited�|�sizeval�);
- datasize�(�default�|�unlimited�|�sizeval�);
- deny-answer-addresses�{�address_match_element;�...�}�[
- ����except-from�{�quoted_string;�...�}�];
- deny-answer-aliases�{�quoted_string;�...�}�[�except-from�{
- ����quoted_string;�...�}�];
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- directory�quoted_string;
- disable-algorithms�string�{�string;
- ����...�};
- disable-ds-digests�string�{�string;
- ����...�};
- disable-empty-zone�string;
- dns64�netprefix�{
- break-dnssec�boolean;
- clients�{�address_match_element;�...�};
- exclude�{�address_match_element;�...�};
- mapped�{�address_match_element;�...�};
- recursive-only�boolean;
- suffix�ipv6_address;
- };
- dns64-contact�string;
- dns64-server�string;
- dnssec-accept-expired�boolean;
- dnssec-dnskey-kskonly�boolean;
- dnssec-enable�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-lookaside�(�string�trust-anchor
- ����string�|�auto�|�no�);
- dnssec-must-be-secure�string�boolean;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- dnssec-validation�(�yes�|�no�|�auto�);
- dnstap�{�(�all�|�auth�|�client�|�forwarder�|
- ����resolver�)�[�(�query�|�response�)�];�...�};
- dnstap-identity�(�quoted_string�|�none�|
- ����hostname�);
- dnstap-output�(�file�|�unix�)�quoted_string;
- dnstap-version�(�quoted_string�|�none�);
- dscp�integer;
- dual-stack-servers�[�port�integer�]�{�(�quoted_string�[�port
- ����integer�]�[�dscp�integer�]�|�ipv4_address�[�port
- ����integer�]�[�dscp�integer�]�|�ipv6_address�[�port
- ����integer�]�[�dscp�integer�]�);�...�};
- dump-file�quoted_string;
- edns-udp-size�integer;
- empty-contact�string;
- empty-server�string;
- empty-zones-enable�boolean;
- fetch-quota-params�integer�fixedpoint�fixedpoint�fixedpoint;
- fetches-per-server�integer�[�(�drop�|�fail�)�];
- fetches-per-zone�integer�[�(�drop�|�fail�)�];
- files�(�default�|�unlimited�|�sizeval�);
- filter-aaaa�{�address_match_element;�...�};
- filter-aaaa-on-v4�(�break-dnssec�|�boolean�);
- filter-aaaa-on-v6�(�break-dnssec�|�boolean�);
- flush-zones-on-shutdown�boolean;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- fstrm-set-buffer-hint�integer;
- fstrm-set-flush-timeout�integer;
- fstrm-set-input-queue-size�integer;
- fstrm-set-output-notify-threshold�integer;
- fstrm-set-output-queue-model�(�mpsc�|�spsc�);
- fstrm-set-output-queue-size�integer;
- fstrm-set-reopen-interval�integer;
- geoip-directory�(�quoted_string�|�none�);
- geoip-use-ecs�boolean;
- heartbeat-interval�integer;
- hostname�(�quoted_string�|�none�);
- inline-signing�boolean;
- interface-interval�integer;
- ixfr-from-differences�(�master�|�slave�|�boolean�);
- keep-response-order�{�address_match_element;�...�};
- key-directory�quoted_string;
- lame-ttl�ttlval;
- listen-on�[�port�integer�]�[�dscp
- ����integer�]�{
- ����address_match_element;�...�};
- listen-on-v6�[�port�integer�]�[�dscp
- ����integer�]�{
- ����address_match_element;�...�};
- lmdb-mapsize�sizeval;
- lock-file�(�quoted_string�|�none�);
- managed-keys-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- match-mapped-addresses�boolean;
- max-acache-size�(�unlimited�|�sizeval�);
- max-cache-size�(�default�|�unlimited�|�sizeval�|�percentage�);
- max-cache-ttl�integer;
- max-clients-per-query�integer;
- max-journal-size�(�unlimited�|�sizeval�);
- max-ncache-ttl�integer;
- max-records�integer;
- max-recursion-depth�integer;
- max-recursion-queries�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-rsa-exponent-size�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-udp-size�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- memstatistics�boolean;
- memstatistics-file�quoted_string;
- message-compression�boolean;
- min-refresh-time�integer;
- min-retry-time�integer;
- minimal-any�boolean;
- minimal-responses�(�no-auth�|�no-auth-recursive�|�boolean�);
- multi-master�boolean;
- no-case-compress�{�address_match_element;�...�};
- nocookie-udp-size�integer;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-rate�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- nta-lifetime�ttlval;
- nta-recheck�ttlval;
- nxdomain-redirect�string;
- pid-file�(�quoted_string�|�none�);
- port�integer;
- preferred-glue�string;
- prefetch�integer�[�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- querylog�boolean;
- random-device�quoted_string;
- rate-limit�{
- all-per-second�integer;
- errors-per-second�integer;
- exempt-clients�{�address_match_element;�...�};
- ipv4-prefix-length�integer;
- ipv6-prefix-length�integer;
- log-only�boolean;
- max-table-size�integer;
- min-table-size�integer;
- nodata-per-second�integer;
- nxdomains-per-second�integer;
- qps-scale�integer;
- referrals-per-second�integer;
- responses-per-second�integer;
- slip�integer;
- window�integer;
- };
- recursing-file�quoted_string;
- recursion�boolean;
- recursive-clients�integer;
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- require-server-cookie�boolean;
- reserved-sockets�integer;
- resolver-query-timeout�integer;
- response-policy�{�zone�string�[�log�boolean�]�[�max-policy-ttl
- ����integer�]�[�policy�(�cname�|�disabled�|�drop�|�given�|�no-op
- ����|�nodata�|�nxdomain�|�passthru�|�tcp-only�quoted_string�)�]�[
- ����recursive-only�boolean�];�...�}�[�break-dnssec�boolean�]�[
- ����max-policy-ttl�integer�]�[�min-ns-dots�integer�]�[
- ����nsip-wait-recurse�boolean�]�[�qname-wait-recurse�boolean�]
- ����[�recursive-only�boolean�];
- root-delegation-only�[�exclude�{�quoted_string;�...�}�];
- root-key-sentinel�boolean;
- rrset-order�{�[�class�string�]�[�type�string�]�[�name
- ����quoted_string�]�string�string;�...�};
- secroots-file�quoted_string;
- send-cookie�boolean;
- serial-query-rate�integer;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-id�(�quoted_string�|�none�|�hostname�);
- servfail-ttl�ttlval;
- session-keyalg�string;
- session-keyfile�(�quoted_string�|�none�);
- session-keyname�string;
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- sortlist�{�address_match_element;�...�};
- stacksize�(�default�|�unlimited�|�sizeval�);
- startup-notify-rate�integer;
- statistics-file�quoted_string;
- tcp-clients�integer;
- tcp-listen-queue�integer;
- tkey-dhkey�quoted_string�integer;
- tkey-domain�quoted_string;
- tkey-gssapi-credential�quoted_string;
- tkey-gssapi-keytab�quoted_string;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-message-size�integer;
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- transfers-in�integer;
- transfers-out�integer;
- transfers-per-ns�integer;
- trust-anchor-telemetry�boolean;�//�experimental
- try-tcp-refresh�boolean;
- update-check-ksk�boolean;
- use-alt-transfer-source�boolean;
- use-v4-udp-ports�{�portrange;�...�};
- use-v6-udp-ports�{�portrange;�...�};
- v6-bias�integer;
- version�(�quoted_string�|�none�);
- zero-no-soa-ttl�boolean;
- zero-no-soa-ttl-cache�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

SERVER

-


-server�netprefix�{
- bogus�boolean;
- edns�boolean;
- edns-udp-size�integer;
- edns-version�integer;
- keys�server_key;
- max-udp-size�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- send-cookie�boolean;
- tcp-only�boolean;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- transfers�integer;
-};
-

-
-
-

STATISTICS-CHANNELS

-


-statistics-channels�{
- inet�(�ipv4_address�|�ipv6_address�|
- ����*�)�[�port�(�integer�|�*�)�]�[
- ����allow�{�address_match_element;�...
- ����}�];
-};
-

-
-
-

TRUSTED-KEYS

-


-trusted-keys�{�string�integer�integer
-����integer�quoted_string;�...�};
-

-
-
-

VIEW

-


-view�string�[�class�]�{
- acache-cleaning-interval�integer;
- acache-enable�boolean;
- additional-from-auth�boolean;
- additional-from-cache�boolean;
- allow-new-zones�boolean;
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-cache�{�address_match_element;�...�};
- allow-query-cache-on�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-recursion�{�address_match_element;�...�};
- allow-recursion-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- attach-cache�string;
- auth-nxdomain�boolean;�//�default�changed
- auto-dnssec�(�allow�|�maintain�|�off�);
- cache-file�quoted_string;
- catalog-zones�{�zone�string�[�default-masters�[�port�integer�]
- ����[�dscp�integer�]�{�(�masters�|�ipv4_address�[�port
- ����integer�]�|�ipv6_address�[�port�integer�]�)�[�key
- ����string�];�...�}�]�[�zone-directory�quoted_string�]�[
- ����in-memory�boolean�]�[�min-update-interval�integer�];�...�};
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�master�|�slave�|�response
- ����)�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- cleaning-interval�integer;
- clients-per-query�integer;
- deny-answer-addresses�{�address_match_element;�...�}�[
- ����except-from�{�quoted_string;�...�}�];
- deny-answer-aliases�{�quoted_string;�...�}�[�except-from�{
- ����quoted_string;�...�}�];
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- disable-algorithms�string�{�string;
- ����...�};
- disable-ds-digests�string�{�string;
- ����...�};
- disable-empty-zone�string;
- dlz�string�{
- database�string;
- search�boolean;
- };
- dns64�netprefix�{
- break-dnssec�boolean;
- clients�{�address_match_element;�...�};
- exclude�{�address_match_element;�...�};
- mapped�{�address_match_element;�...�};
- recursive-only�boolean;
- suffix�ipv6_address;
- };
- dns64-contact�string;
- dns64-server�string;
- dnssec-accept-expired�boolean;
- dnssec-dnskey-kskonly�boolean;
- dnssec-enable�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-lookaside�(�string�trust-anchor
- ����string�|�auto�|�no�);
- dnssec-must-be-secure�string�boolean;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- dnssec-validation�(�yes�|�no�|�auto�);
- dnstap�{�(�all�|�auth�|�client�|�forwarder�|
- ����resolver�)�[�(�query�|�response�)�];�...�};
- dual-stack-servers�[�port�integer�]�{�(�quoted_string�[�port
- ����integer�]�[�dscp�integer�]�|�ipv4_address�[�port
- ����integer�]�[�dscp�integer�]�|�ipv6_address�[�port
- ����integer�]�[�dscp�integer�]�);�...�};
- dyndb�string�quoted_string�{
- ����unspecified-text�};
- edns-udp-size�integer;
- empty-contact�string;
- empty-server�string;
- empty-zones-enable�boolean;
- fetch-quota-params�integer�fixedpoint�fixedpoint�fixedpoint;
- fetches-per-server�integer�[�(�drop�|�fail�)�];
- fetches-per-zone�integer�[�(�drop�|�fail�)�];
- filter-aaaa�{�address_match_element;�...�};
- filter-aaaa-on-v4�(�break-dnssec�|�boolean�);
- filter-aaaa-on-v6�(�break-dnssec�|�boolean�);
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- inline-signing�boolean;
- ixfr-from-differences�(�master�|�slave�|�boolean�);
- key�string�{
- algorithm�string;
- secret�string;
- };
- key-directory�quoted_string;
- lame-ttl�ttlval;
- lmdb-mapsize�sizeval;
- managed-keys�{�string�string
- ����integer�integer�integer
- ����quoted_string;�...�};
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- match-clients�{�address_match_element;�...�};
- match-destinations�{�address_match_element;�...�};
- match-recursive-only�boolean;
- max-acache-size�(�unlimited�|�sizeval�);
- max-cache-size�(�default�|�unlimited�|�sizeval�|�percentage�);
- max-cache-ttl�integer;
- max-clients-per-query�integer;
- max-journal-size�(�unlimited�|�sizeval�);
- max-ncache-ttl�integer;
- max-records�integer;
- max-recursion-depth�integer;
- max-recursion-queries�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-udp-size�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- message-compression�boolean;
- min-refresh-time�integer;
- min-retry-time�integer;
- minimal-any�boolean;
- minimal-responses�(�no-auth�|�no-auth-recursive�|�boolean�);
- multi-master�boolean;
- no-case-compress�{�address_match_element;�...�};
- nocookie-udp-size�integer;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- nta-lifetime�ttlval;
- nta-recheck�ttlval;
- nxdomain-redirect�string;
- preferred-glue�string;
- prefetch�integer�[�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv4_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�)�|�(�[�[�address�]�(�ipv6_address�|�*�)�]
- ����port�(�integer�|�*�)�)�)�[�dscp�integer�];
- rate-limit�{
- all-per-second�integer;
- errors-per-second�integer;
- exempt-clients�{�address_match_element;�...�};
- ipv4-prefix-length�integer;
- ipv6-prefix-length�integer;
- log-only�boolean;
- max-table-size�integer;
- min-table-size�integer;
- nodata-per-second�integer;
- nxdomains-per-second�integer;
- qps-scale�integer;
- referrals-per-second�integer;
- responses-per-second�integer;
- slip�integer;
- window�integer;
- };
- recursion�boolean;
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- require-server-cookie�boolean;
- resolver-query-timeout�integer;
- response-policy�{�zone�string�[�log�boolean�]�[�max-policy-ttl
- ����integer�]�[�policy�(�cname�|�disabled�|�drop�|�given�|�no-op
- ����|�nodata�|�nxdomain�|�passthru�|�tcp-only�quoted_string�)�]�[
- ����recursive-only�boolean�];�...�}�[�break-dnssec�boolean�]�[
- ����max-policy-ttl�integer�]�[�min-ns-dots�integer�]�[
- ����nsip-wait-recurse�boolean�]�[�qname-wait-recurse�boolean�]
- ����[�recursive-only�boolean�];
- root-delegation-only�[�exclude�{�quoted_string;�...�}�];
- root-key-sentinel�boolean;
- rrset-order�{�[�class�string�]�[�type�string�]�[�name
- ����quoted_string�]�string�string;�...�};
- send-cookie�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server�netprefix�{
- bogus�boolean;
- edns�boolean;
- edns-udp-size�integer;
- edns-version�integer;
- keys�server_key;
- max-udp-size�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*
- ����)�]�[�dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer
- ����|�*�)�]�[�dscp�integer�];
- provide-ixfr�boolean;
- query-source�(�(�[�address�]�(�ipv4_address�|�*�)�[�port
- ����(�integer�|�*�)�]�)�|�(�[�[�address�]�(
- ����ipv4_address�|�*�)�]�port�(�integer�|�*�)�)�)�[
- ����dscp�integer�];
- query-source-v6�(�(�[�address�]�(�ipv6_address�|�*�)�[
- ����port�(�integer�|�*�)�]�)�|�(�[�[�address�]�(
- ����ipv6_address�|�*�)�]�port�(�integer�|�*�)�)�)�[
- ����dscp�integer�];
- request-expire�boolean;
- request-ixfr�boolean;
- request-nsid�boolean;
- send-cookie�boolean;
- tcp-only�boolean;
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- transfers�integer;
- };
- servfail-ttl�ttlval;
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- sortlist�{�address_match_element;�...�};
- transfer-format�(�many-answers�|�one-answer�);
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- trust-anchor-telemetry�boolean;�//�experimental
- trusted-keys�{�string�integer
- ����integer�integer�quoted_string;
- ����...�};
- try-tcp-refresh�boolean;
- update-check-ksk�boolean;
- use-alt-transfer-source�boolean;
- v6-bias�integer;
- zero-no-soa-ttl�boolean;
- zero-no-soa-ttl-cache�boolean;
- zone�string�[�class�]�{
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(
- ����masters�|�ipv4_address�[�port�integer�]�|
- ����ipv6_address�[�port�integer�]�)�[�key�string�];
- ����...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- auto-dnssec�(�allow�|�maintain�|�off�);
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- database�string;
- delegation-only�boolean;
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|
- ����boolean�);
- dlz�string;
- dnssec-dnskey-kskonly�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- file�quoted_string;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(
- ����ipv4_address�|�ipv6_address�)�[�port�integer�]�[
- ����dscp�integer�];�...�};
- in-view�string;
- inline-signing�boolean;
- ixfr-from-differences�boolean;
- journal�quoted_string;
- key-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- masters�[�port�integer�]�[�dscp�integer�]�{�(�masters
- ����|�ipv4_address�[�port�integer�]�|�ipv6_address�[
- ����port�integer�]�)�[�key�string�];�...�};
- max-ixfr-log-size�(�default�|�unlimited�|
- max-journal-size�(�unlimited�|�sizeval�);
- max-records�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- min-refresh-time�integer;
- min-retry-time�integer;
- multi-master�boolean;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*
- ����)�]�[�dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer
- ����|�*�)�]�[�dscp�integer�];
- notify-to-soa�boolean;
- pubkey�integer
- ����integer
- ����integer
- request-expire�boolean;
- request-ixfr�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-addresses�{�(�ipv4_address�|�ipv6_address�);�...�};
- server-names�{�quoted_string;�...�};
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(
- ����integer�|�*�)�]�[�dscp�integer�];
- try-tcp-refresh�boolean;
- type�(�delegation-only�|�forward�|�hint�|�master�|�redirect
- ����|�slave�|�static-stub�|�stub�);
- update-check-ksk�boolean;
- update-policy�(�local�|�{�(�deny�|�grant�)�string�(
- ����6to4-self�|�external�|�krb5-self�|�krb5-selfsub�|
- ����krb5-subdomain�|�ms-self�|�ms-selfsub�|�ms-subdomain�|
- ����name�|�self�|�selfsub�|�selfwild�|�subdomain�|�tcp-self
- ����|�wildcard�|�zonesub�)�[�string�]�rrtypelist;�...�};
- use-alt-transfer-source�boolean;
- zero-no-soa-ttl�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
- };
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

ZONE

-


-zone�string�[�class�]�{
- allow-notify�{�address_match_element;�...�};
- allow-query�{�address_match_element;�...�};
- allow-query-on�{�address_match_element;�...�};
- allow-transfer�{�address_match_element;�...�};
- allow-update�{�address_match_element;�...�};
- allow-update-forwarding�{�address_match_element;�...�};
- also-notify�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- alt-transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- alt-transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|
- ����*�)�]�[�dscp�integer�];
- auto-dnssec�(�allow�|�maintain�|�off�);
- check-dup-records�(�fail�|�warn�|�ignore�);
- check-integrity�boolean;
- check-mx�(�fail�|�warn�|�ignore�);
- check-mx-cname�(�fail�|�warn�|�ignore�);
- check-names�(�fail�|�warn�|�ignore�);
- check-sibling�boolean;
- check-spf�(�warn�|�ignore�);
- check-srv-cname�(�fail�|�warn�|�ignore�);
- check-wildcard�boolean;
- database�string;
- delegation-only�boolean;
- dialup�(�notify�|�notify-passive�|�passive�|�refresh�|�boolean�);
- dlz�string;
- dnssec-dnskey-kskonly�boolean;
- dnssec-loadkeys-interval�integer;
- dnssec-secure-to-insecure�boolean;
- dnssec-update-mode�(�maintain�|�no-resign�);
- file�quoted_string;
- forward�(�first�|�only�);
- forwarders�[�port�integer�]�[�dscp�integer�]�{�(�ipv4_address
- ����|�ipv6_address�)�[�port�integer�]�[�dscp�integer�];�...�};
- in-view�string;
- inline-signing�boolean;
- ixfr-from-differences�boolean;
- journal�quoted_string;
- key-directory�quoted_string;
- masterfile-format�(�map�|�raw�|�text�);
- masterfile-style�(�full�|�relative�);
- masters�[�port�integer�]�[�dscp�integer�]�{�(�masters�|
- ����ipv4_address�[�port�integer�]�|�ipv6_address�[�port
- ����integer�]�)�[�key�string�];�...�};
- max-journal-size�(�unlimited�|�sizeval�);
- max-records�integer;
- max-refresh-time�integer;
- max-retry-time�integer;
- max-transfer-idle-in�integer;
- max-transfer-idle-out�integer;
- max-transfer-time-in�integer;
- max-transfer-time-out�integer;
- max-zone-ttl�(�unlimited�|�ttlval�);
- min-refresh-time�integer;
- min-retry-time�integer;
- multi-master�boolean;
- notify�(�explicit�|�master-only�|�boolean�);
- notify-delay�integer;
- notify-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- notify-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)�]
- ����[�dscp�integer�];
- notify-to-soa�boolean;
- pubkey�integer�integer
- request-expire�boolean;
- request-ixfr�boolean;
- serial-update-method�(�date�|�increment�|�unixtime�);
- server-addresses�{�(�ipv4_address�|�ipv6_address�);�...�};
- server-names�{�quoted_string;�...�};
- sig-signing-nodes�integer;
- sig-signing-signatures�integer;
- sig-signing-type�integer;
- sig-validity-interval�integer�[�integer�];
- transfer-source�(�ipv4_address�|�*�)�[�port�(�integer�|�*�)�]�[
- ����dscp�integer�];
- transfer-source-v6�(�ipv6_address�|�*�)�[�port�(�integer�|�*�)
- ����]�[�dscp�integer�];
- try-tcp-refresh�boolean;
- type�(�delegation-only�|�forward�|�hint�|�master�|�redirect�|�slave
- ����|�static-stub�|�stub�);
- update-check-ksk�boolean;
- update-policy�(�local�|�{�(�deny�|�grant�)�string�(�6to4-self�|
- ����external�|�krb5-self�|�krb5-selfsub�|�krb5-subdomain�|�ms-self
- ����|�ms-selfsub�|�ms-subdomain�|�name�|�self�|�selfsub�|�selfwild
- ����|�subdomain�|�tcp-self�|�wildcard�|�zonesub�)�[�string�]
- ����rrtypelist;�...�};
- use-alt-transfer-source�boolean;
- zero-no-soa-ttl�boolean;
- zone-statistics�(�full�|�terse�|�none�|�boolean�);
-};
-

-
-
-

FILES

-

/etc/named.conf -

-
-
-

SEE ALSO

-

ddns-confgen(8), - named(8), - named-checkconf(8), - rndc(8), - rndc-confgen(8), - BIND 9 Administrator Reference Manual. -

-
-
- diff --git a/bin/named-sdb/named.docbook b/bin/named-sdb/named.docbook deleted file mode 100644 index b95a26f..0000000 --- a/bin/named-sdb/named.docbook +++ /dev/null @@ -1,621 +0,0 @@ - - - - - - 2014-02-19 - - - ISC - Internet Systems Consortium, Inc. - - - - named - 8 - BIND9 - - - - named - Internet domain name server - - - - - 2000 - 2001 - 2003 - 2004 - 2005 - 2006 - 2007 - 2008 - 2009 - 2011 - 2013 - 2014 - 2015 - 2016 - 2017 - 2018 - 2019 - 2020 - Internet Systems Consortium, Inc. ("ISC") - - - - - - named - - - - - - - - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. - - - When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. - - - - OPTIONS - - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - option in the configuration - file, config-file should be - an absolute pathname. - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. - - - - - - -D string - - - Specifies a string that is used to identify a instance of - named in a process listing. The contents - of string are - not examined. - - - - - - -E engine-name - - - When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. - - - When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -L logfile - - - Log to the file by default - instead of the system log. - - - - - - -M option - - - Sets the default memory context options. Currently - the only supported option is - external, - which causes the internal memory manager to be bypassed - in favor of system-provided memory allocation functions. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -p port - - - Listen for queries on port port. If not - specified, the default is port 53. - - - - - - -s - - - Write memory usage statistics to stdout on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -S #max-socks - - - Allow named to use up to - #max-socks sockets. - The default value is 4096 on systems built with default - configuration options, and 21000 on systems built with - "configure --with-tuning=large". - - - - This option should be unnecessary for the vast majority - of users. - The use of this option could even be harmful because the - specified value may exceed the limitation of the - underlying system API. - It is therefore set only when the default configuration - causes exhaustion of file descriptors and the - operational environment is known to support the - specified number of sockets. - Note also that the actual maximum number is normally a little - fewer than the specified value because - named reserves some file descriptors - for its internal use. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -U #listeners - - - Use #listeners - worker threads to listen for incoming UDP packets on each - address. If not specified, named will - calculate a default value based on the number of detected - CPUs: 1 for 1 CPU, and the number of detected CPUs - minus one for machines with more than 1 CPU. This cannot - be increased to a value higher than the number of CPUs. - If has been set to a higher value than - the number of detected CPUs, then may - be increased as high as that value, but no higher. - On Windows, the number of UDP listeners is hardwired to 1 - and this option has no effect. - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). - - - - - - - -v - - - Report the version number and exit. - - - - - - -V - - - Report the version number and build options, and exit. - - - - - - -X lock-file - - - Acquire a lock on the specified file at runtime; this - helps to prevent duplicate named instances - from running simultaneously. - Use of this option overrides the lock-file - option in named.conf. - If set to none, the lock file check - is disabled. - - - - - - -x cache-file - - - Load data from cache-file into the - cache of the default view. - - - - This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. - - - - - - - - - - SIGNALS - - - In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. - - - - - - SIGHUP - - - Force a reload of the server. - - - - - - SIGINT, SIGTERM - - - Shut down the server. - - - - - - - - The result of sending any other signals to the server is undefined. - - - - - CONFIGURATION - - - The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. - - - - named inherits the umask - (file creation mode mask) from the parent process. If files - created by named, such as journal files, - need to have custom permissions, the umask - should be set explicitly in the script used to start the - named process. - - - - - FILES - - - - - - /etc/named.conf - - - The default configuration file. - - - - - - /var/run/named/named.pid - - - The default process-id file. - - - - - - - - - NOTES - Red Hat SELinux BIND Security Profile - - - By default, Red Hat ships BIND with the most secure SELinux policy - that will not prevent normal BIND operation and will prevent exploitation - of all known BIND security vulnerabilities . See the selinux(8) man page - for information about SElinux. - - - - It is not necessary to run named in a chroot environment if the Red Hat - SELinux policy for named is enabled. When enabled, this policy is far - more secure than a chroot environment. Users are recommended to enable - SELinux and remove the bind-chroot package. - - - - With this extra security comes some restrictions: - - - - By default, the SELinux policy allows named to write any master - zone database files. Only the root user may create files in the $ROOTDIR/var/named - zone database file directory (the options { "directory" } option), where - $ROOTDIR is set in /etc/sysconfig/named. - - - - The "named" group must be granted read privelege to - these files in order for named to be enabled to read them. - - - - Any file created in the zone database file directory is automatically assigned - the SELinux file context named_zone_t . - - - - By default, SELinux prevents any role from modifying named_zone_t files; this - means that files in the zone database directory cannot be modified by dynamic - DNS (DDNS) updates or zone transfers. - - - - The Red Hat BIND distribution and SELinux policy creates three directories where - named is allowed to create and modify files: /var/named/slaves, /var/named/dynamic - /var/named/data. By placing files you want named to modify, such as - slave or DDNS updateable zone files and database / statistics dump files in - these directories, named will work normally and no further operator action is - required. Files in these directories are automatically assigned the 'named_cache_t' - file context, which SELinux allows named to write. - - - - Red Hat BIND SDB support - - - Red Hat ships named with compiled in Simplified Database Backend modules that ISC - provides in the "contrib/sdb" directory. Install bind-sdb package if you want use them. - - - - The SDB modules for LDAP, PostGreSQL, DirDB and SQLite are compiled into named-sdb. - - - - See the documentation for the various SDB modules in /usr/share/doc/bind-sdb-*/ . - - - - - - SEE ALSO - - RFC 1033, - RFC 1034, - RFC 1035, - - named-checkconf - 8 - , - - named-checkzone - 8 - , - - rndc - 8 - , - - lwresd - 8 - , - - named.conf - 5 - , - BIND 9 Administrator Reference Manual. - - - - diff --git a/bin/named-sdb/named.html b/bin/named-sdb/named.html deleted file mode 100644 index 8637ed8..0000000 --- a/bin/named-sdb/named.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - - -named - - -
-
-
-

Name

-

named — Internet domain name server

-
-
-

Synopsis

-

named [[-4] | [-6]] [-c config-file] [-d debug-level] [-D string] [-E engine-name] [-f] [-g] [-L logfile] [-M option] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-U #listeners] [-u user] [-v] [-V] [-X lock-file] [-x cache-file]

-
-
-

DESCRIPTION

-

named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. -

-

- When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - directory option in the configuration - file, config-file should be - an absolute pathname. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. -

-
-D string
-

- Specifies a string that is used to identify a instance of - named in a process listing. The contents - of string are - not examined. -

-
-E engine-name
-
-

- When applicable, specifies the hardware to use for - cryptographic operations, such as a secure key store used - for signing. -

-

- When BIND is built with OpenSSL PKCS#11 support, this defaults - to the string "pkcs11", which identifies an OpenSSL engine - that can drive a cryptographic accelerator or hardware service - module. When BIND is built with native PKCS#11 cryptography - (--enable-native-pkcs11), it defaults to the path of the PKCS#11 - provider library specified via "--with-pkcs11". -

-
-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-L logfile
-

- Log to the file logfile by default - instead of the system log. -

-
-M option
-

- Sets the default memory context options. Currently - the only supported option is - external, - which causes the internal memory manager to be bypassed - in favor of system-provided memory allocation functions. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-p port
-

- Listen for queries on port port. If not - specified, the default is port 53. -

-
-s
-
-

- Write memory usage statistics to stdout on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-S #max-socks
-
-

- Allow named to use up to - #max-socks sockets. - The default value is 4096 on systems built with default - configuration options, and 21000 on systems built with - "configure --with-tuning=large". -

-
-

Warning

-

- This option should be unnecessary for the vast majority - of users. - The use of this option could even be harmful because the - specified value may exceed the limitation of the - underlying system API. - It is therefore set only when the default configuration - causes exhaustion of file descriptors and the - operational environment is known to support the - specified number of sockets. - Note also that the actual maximum number is normally a little - fewer than the specified value because - named reserves some file descriptors - for its internal use. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-U #listeners
-

- Use #listeners - worker threads to listen for incoming UDP packets on each - address. If not specified, named will - calculate a default value based on the number of detected - CPUs: 1 for 1 CPU, and the number of detected CPUs - minus one for machines with more than 1 CPU. This cannot - be increased to a value higher than the number of CPUs. - If -n has been set to a higher value than - the number of detected CPUs, then -U may - be increased as high as that value, but no higher. - On Windows, the number of UDP listeners is hardwired to 1 - and this option has no effect. -

-
-u user
-
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-

Note

-

- On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the -u - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). -

-
-
-
-v
-

- Report the version number and exit. -

-
-V
-

- Report the version number and build options, and exit. -

-
-X lock-file
-

- Acquire a lock on the specified file at runtime; this - helps to prevent duplicate named instances - from running simultaneously. - Use of this option overrides the lock-file - option in named.conf. - If set to none, the lock file check - is disabled. -

-
-x cache-file
-
-

- Load data from cache-file into the - cache of the default view. -

-
-

Warning

-

- This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. -

-
-
-
-
-
-

SIGNALS

-

- In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. -

-
-
SIGHUP
-

- Force a reload of the server. -

-
SIGINT, SIGTERM
-

- Shut down the server. -

-
-

- The result of sending any other signals to the server is undefined. -

-
-
-

CONFIGURATION

-

- The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. -

-

- named inherits the umask - (file creation mode mask) from the parent process. If files - created by named, such as journal files, - need to have custom permissions, the umask - should be set explicitly in the script used to start the - named process. -

-
-
-

FILES

-
-
/etc/named.conf
-

- The default configuration file. -

-
/var/run/named/named.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

RFC 1033, - RFC 1034, - RFC 1035, - named-checkconf(8), - named-checkzone(8), - rndc(8), - lwresd(8), - named.conf(5), - BIND 9 Administrator Reference Manual. -

-
-
- diff --git a/bin/named-sdb/notify.c b/bin/named-sdb/notify.c deleted file mode 100644 index de4ca09..0000000 --- a/bin/named-sdb/notify.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*! \file - * \brief - * This module implements notify as in RFC1996. - */ - -static void -notify_log(ns_client_t *client, int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY, - level, fmt, ap); - va_end(ap); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - isc_result_t msg_result; - - message = client->message; - rcode = dns_result_torcode(result); - - msg_result = dns_message_reply(message, true); - if (msg_result != ISC_R_SUCCESS) - msg_result = dns_message_reply(message, false); - if (msg_result != ISC_R_SUCCESS) { - ns_client_next(client, msg_result); - return; - } - message->rcode = rcode; - if (rcode == dns_rcode_noerror) - message->flags |= DNS_MESSAGEFLAG_AA; - else - message->flags &= ~DNS_MESSAGEFLAG_AA; - ns_client_send(client); -} - -void -ns_notify_start(ns_client_t *client) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - char tsigbuf[DNS_NAME_FORMATSIZE * 2 + sizeof(": TSIG '' ()")]; - dns_tsigkey_t *tsigkey; - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section empty"); - result = DNS_R_FORMERR; - goto done; - } - - /* - * The question section must contain exactly one question. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - result = DNS_R_FORMERR; - goto done; - } - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - result = DNS_R_FORMERR; - goto done; - } - - /* The one rdataset must be an SOA. */ - if (zone_rdataset->type != dns_rdatatype_soa) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains no SOA"); - result = DNS_R_FORMERR; - goto done; - } - - tsigkey = dns_message_gettsigkey(request); - if (tsigkey != NULL) { - dns_name_format(&tsigkey->name, namebuf, sizeof(namebuf)); - - if (tsigkey->generated) { - char cnamebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(tsigkey->creator, cnamebuf, - sizeof(cnamebuf)); - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s' (%s)", - namebuf, cnamebuf); - } else { - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", - namebuf); - } - } else - tsigbuf[0] = '\0'; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, &zone); - if (result == ISC_R_SUCCESS) { - dns_zonetype_t zonetype = dns_zone_gettype(zone); - - if ((zonetype == dns_zone_master) || - (zonetype == dns_zone_slave) || - (zonetype == dns_zone_stub)) - { - isc_sockaddr_t *from = ns_client_getsockaddr(client); - isc_sockaddr_t *to = ns_client_getdestaddr(client); - notify_log(client, ISC_LOG_INFO, - "received notify for zone '%s'%s", - namebuf, tsigbuf); - result = dns_zone_notifyreceive2(zone, from, to, - request); - goto done; - } - } - - notify_log(client, ISC_LOG_NOTICE, - "received notify for zone '%s'%s: not authoritative", - namebuf, tsigbuf); - result = DNS_R_NOTAUTH; - - done: - if (zone != NULL) - dns_zone_detach(&zone); - respond(client, result); -} diff --git a/bin/named-sdb/pgsqldb.c b/bin/named-sdb/pgsqldb.c deleted file mode 100644 index e276912..0000000 --- a/bin/named-sdb/pgsqldb.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include "pgsqldb.h" - -/* - * A simple database driver that interfaces to a PostgreSQL database. This - * is not complete, and not designed for general use. It opens one - * connection to the database per zone, which is inefficient. It also may - * not handle quoting correctly. - * - * The table must contain the fields "name", "rdtype", and "rdata", and - * is expected to contain a properly constructed zone. The program "zonetodb" - * creates such a table. - */ - -static dns_sdbimplementation_t *pgsqldb = NULL; - -struct dbinfo { - PGconn *conn; - char *database; - char *table; - char *host; - char *user; - char *passwd; -}; - -static void -pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata); - -/* - * Canonicalize a string before writing it to the database. - * "dest" must be an array of at least size 2*strlen(source) + 1. - */ -static void -quotestring(const char *source, char *dest) { - while (*source != 0) { - if (*source == '\'') - *dest++ = '\''; - /* SQL doesn't treat \ as special, but PostgreSQL does */ - else if (*source == '\\') - *dest++ = '\\'; - *dest++ = *source++; - } - *dest++ = 0; -} - -/* - * Connect to the database. - */ -static isc_result_t -db_connect(struct dbinfo *dbi) { - dbi->conn = PQsetdbLogin(dbi->host, NULL, NULL, NULL, dbi->database, - dbi->user, dbi->passwd); - - if (PQstatus(dbi->conn) == CONNECTION_OK) - return (ISC_R_SUCCESS); - else - return (ISC_R_FAILURE); -} - -/* - * Check to see if the connection is still valid. If not, attempt to - * reconnect. - */ -static isc_result_t -maybe_reconnect(struct dbinfo *dbi) { - if (PQstatus(dbi->conn) == CONNECTION_OK) - return (ISC_R_SUCCESS); - - return (db_connect(dbi)); -} - -/* - * This database operates on absolute names. - * - * Queries are converted into SQL queries and issued synchronously. Errors - * are handled really badly. - */ -#ifdef DNS_CLIENTINFO_VERSION -static isc_result_t -pgsqldb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -#else -static isc_result_t -pgsqldb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -#endif /* DNS_CLIENTINFO_VERSION */ -{ - isc_result_t result; - struct dbinfo *dbi = dbdata; - PGresult *res; - char str[1500]; - char *canonname; - int i; - - UNUSED(zone); -#ifdef DNS_CLIENTINFO_VERSION - UNUSED(methods); - UNUSED(clientinfo); -#endif /* DNS_CLIENTINFO_VERSION */ - - canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1); - if (canonname == NULL) - return (ISC_R_NOMEMORY); - quotestring(name, canonname); - snprintf(str, sizeof(str), - "SELECT TTL,RDTYPE,RDATA FROM \"%s\" WHERE " - "lower(NAME) = lower('%s')", dbi->table, canonname); - isc_mem_put(ns_g_mctx, canonname, strlen(name) * 2 + 1); - - result = maybe_reconnect(dbi); - if (result != ISC_R_SUCCESS) - return (result); - - res = PQexec(dbi->conn, str); - if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { - PQclear(res); - return (ISC_R_FAILURE); - } - if (PQntuples(res) == 0) { - PQclear(res); - return (ISC_R_NOTFOUND); - } - - for (i = 0; i < PQntuples(res); i++) { - char *ttlstr = PQgetvalue(res, i, 0); - char *type = PQgetvalue(res, i, 1); - char *data = PQgetvalue(res, i, 2); - dns_ttl_t ttl; - char *endp; - ttl = strtol(ttlstr, &endp, 10); - if (*endp != '\0') { - PQclear(res); - return (DNS_R_BADTTL); - } - result = dns_sdb_putrr(lookup, type, ttl, data); - if (result != ISC_R_SUCCESS) { - PQclear(res); - return (ISC_R_FAILURE); - } - } - - PQclear(res); - return (ISC_R_SUCCESS); -} - -/* - * Issue an SQL query to return all nodes in the database and fill the - * allnodes structure. - */ -static isc_result_t -pgsqldb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) { - struct dbinfo *dbi = dbdata; - PGresult *res; - isc_result_t result; - char str[1500]; - int i; - - UNUSED(zone); - - snprintf(str, sizeof(str), - "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%s\" ORDER BY NAME", - dbi->table); - - result = maybe_reconnect(dbi); - if (result != ISC_R_SUCCESS) - return (result); - - res = PQexec(dbi->conn, str); - if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ) { - PQclear(res); - return (ISC_R_FAILURE); - } - if (PQntuples(res) == 0) { - PQclear(res); - return (ISC_R_NOTFOUND); - } - - for (i = 0; i < PQntuples(res); i++) { - char *ttlstr = PQgetvalue(res, i, 0); - char *name = PQgetvalue(res, i, 1); - char *type = PQgetvalue(res, i, 2); - char *data = PQgetvalue(res, i, 3); - dns_ttl_t ttl; - char *endp; - ttl = strtol(ttlstr, &endp, 10); - if (*endp != '\0') { - PQclear(res); - return (DNS_R_BADTTL); - } - result = dns_sdb_putnamedrr(allnodes, name, type, ttl, data); - if (result != ISC_R_SUCCESS) { - PQclear(res); - return (ISC_R_FAILURE); - } - } - - PQclear(res); - return (ISC_R_SUCCESS); -} - -/* - * Create a connection to the database and save any necessary information - * in dbdata. - * - * argv[0] is the name of the database - * argv[1] is the name of the table - * argv[2] (if present) is the name of the host to connect to - * argv[3] (if present) is the name of the user to connect as - * argv[4] (if present) is the name of the password to connect with - */ -static isc_result_t -pgsqldb_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - struct dbinfo *dbi; - isc_result_t result; - - UNUSED(zone); - UNUSED(driverdata); - - if (argc < 2) - return (ISC_R_FAILURE); - - dbi = isc_mem_get(ns_g_mctx, sizeof(struct dbinfo)); - if (dbi == NULL) - return (ISC_R_NOMEMORY); - dbi->conn = NULL; - dbi->database = NULL; - dbi->table = NULL; - dbi->host = NULL; - dbi->user = NULL; - dbi->passwd = NULL; - -#define STRDUP_OR_FAIL(target, source) \ - do { \ - target = isc_mem_strdup(ns_g_mctx, source); \ - if (target == NULL) { \ - result = ISC_R_NOMEMORY; \ - goto cleanup; \ - } \ - } while (0); - - STRDUP_OR_FAIL(dbi->database, argv[0]); - STRDUP_OR_FAIL(dbi->table, argv[1]); - if (argc > 2) - STRDUP_OR_FAIL(dbi->host, argv[2]); - if (argc > 3) - STRDUP_OR_FAIL(dbi->user, argv[3]); - if (argc > 4) - STRDUP_OR_FAIL(dbi->passwd, argv[4]); - - result = db_connect(dbi); - if (result != ISC_R_SUCCESS) - goto cleanup; - - *dbdata = dbi; - return (ISC_R_SUCCESS); - - cleanup: - pgsqldb_destroy(zone, driverdata, (void **)&dbi); - return (result); -} - -/* - * Close the connection to the database. - */ -static void -pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata) { - struct dbinfo *dbi = *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - if (dbi->conn != NULL) - PQfinish(dbi->conn); - if (dbi->database != NULL) - isc_mem_free(ns_g_mctx, dbi->database); - if (dbi->table != NULL) - isc_mem_free(ns_g_mctx, dbi->table); - if (dbi->host != NULL) - isc_mem_free(ns_g_mctx, dbi->host); - if (dbi->user != NULL) - isc_mem_free(ns_g_mctx, dbi->user); - if (dbi->passwd != NULL) - isc_mem_free(ns_g_mctx, dbi->passwd); - if (dbi->database != NULL) - isc_mem_free(ns_g_mctx, dbi->database); - isc_mem_put(ns_g_mctx, dbi, sizeof(struct dbinfo)); -} - -/* - * Since the SQL database corresponds to a zone, the authority data should - * be returned by the lookup() function. Therefore the authority() function - * is NULL. - */ -static dns_sdbmethods_t pgsqldb_methods = { - pgsqldb_lookup, - NULL, /* authority */ - pgsqldb_allnodes, - pgsqldb_create, - pgsqldb_destroy, - NULL /* lookup2 */ -}; - -/* - * Wrapper around dns_sdb_register(). - */ -isc_result_t -pgsqldb_init(void) { - unsigned int flags; - flags = 0; - return (dns_sdb_register("pgsql", &pgsqldb_methods, NULL, flags, - ns_g_mctx, &pgsqldb)); -} - -/* - * Wrapper around dns_sdb_unregister(). - */ -void -pgsqldb_clear(void) { - if (pgsqldb != NULL) - dns_sdb_unregister(&pgsqldb); -} diff --git a/bin/named-sdb/pgsqldb.h b/bin/named-sdb/pgsqldb.h deleted file mode 100644 index 1916723..0000000 --- a/bin/named-sdb/pgsqldb.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -isc_result_t pgsqldb_init(void); - -void pgsqldb_clear(void); - diff --git a/bin/named-sdb/query.c b/bin/named-sdb/query.c deleted file mode 100644 index a95f5ad..0000000 --- a/bin/named-sdb/query.c +++ /dev/null @@ -1,9888 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#define last_load(x) atomic_load((x)) -#define last_cmpxchg(x, e, r) atomic_compare_exchange_strong((x), (e), r) -#elif defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) -#define last_load(x) (isc_stdtime_t)isc_atomic_xadd((int32_t*)(x), 0) -#define last_cmpxchg(x, e, r) isc_atomic_cmpxchg((int32_t*)x, (*(int32_t*)(e)), (int32_t)(r)) -#else -#define last_load(x) (*(x)) -static inline bool -last_cmpxchg(isc_stdtime_t *x, isc_stdtime_t *e, isc_stdtime_t r) { - if (*x == *e) { - *x = r; - return (true); - } - return (false); -} -#endif - -#if 0 -/* - * It has been recommended that DNS64 be changed to return excluded - * AAAA addresses if DNS64 synthesis does not occur. This minimises - * the impact on the lookup results. While most DNS AAAA lookups are - * done to send IP packets to a host, not all of them are and filtering - * excluded addresses has a negative impact on those uses. - */ -#define dns64_bis_return_excluded_addresses 1 -#endif - -/*% Partial answer? */ -#define PARTIALANSWER(c) (((c)->query.attributes & \ - NS_QUERYATTR_PARTIALANSWER) != 0) -/*% Use Cache? */ -#define USECACHE(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEOK) != 0) -/*% Recursion OK? */ -#define RECURSIONOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSIONOK) != 0) -/*% Recursing? */ -#define RECURSING(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSING) != 0) -/*% Cache glue ok? */ -#define CACHEGLUEOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEGLUEOK) != 0) -/*% Want Recursion? */ -#define WANTRECURSION(c) (((c)->query.attributes & \ - NS_QUERYATTR_WANTRECURSION) != 0) -/*% Is TCP? */ -#define TCP(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -/*% Want DNSSEC? */ -#define WANTDNSSEC(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTDNSSEC) != 0) -/*% Want WANTAD? */ -#define WANTAD(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTAD) != 0) -/*% Client presented a valid COOKIE. */ -#define HAVECOOKIE(c) (((c)->attributes & \ - NS_CLIENTATTR_HAVECOOKIE) != 0) -/*% Client presented a COOKIE. */ -#define WANTCOOKIE(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTCOOKIE) != 0) -/*% No authority? */ -#define NOAUTHORITY(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOAUTHORITY) != 0) -/*% No additional? */ -#define NOADDITIONAL(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOADDITIONAL) != 0) -/*% Secure? */ -#define SECURE(c) (((c)->query.attributes & \ - NS_QUERYATTR_SECURE) != 0) -/*% DNS64 A lookup? */ -#define DNS64(c) (((c)->query.attributes & \ - NS_QUERYATTR_DNS64) != 0) - -#define DNS64EXCLUDE(c) (((c)->query.attributes & \ - NS_QUERYATTR_DNS64EXCLUDE) != 0) - -#define REDIRECT(c) (((c)->query.attributes & \ - NS_QUERYATTR_REDIRECT) != 0) - -/*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */ -#define NOQNAME(r) (((r)->attributes & \ - DNS_RDATASETATTR_NOQNAME) != 0) - -/*% Does the rdataset 'r' contain a stale answer? */ -#define STALE(r) (((r)->attributes & \ - DNS_RDATASETATTR_STALE) != 0) - -#ifdef WANT_QUERYTRACE -static inline void -client_trace(ns_client_t *client, int level, const char *message) { - if (client != NULL && client->query.qname != NULL) { - if (isc_log_wouldlog(ns_g_lctx, level)) { - char qbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(client->query.qname, - qbuf, sizeof(qbuf)); - dns_rdatatype_format(client->query.qtype, - tbuf, sizeof(tbuf)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, level, - "query client=%p thread=0x%lx " - "(%s/%s): %s", - client, - (unsigned long) isc_thread_self(), - qbuf, tbuf, message); - } - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, level, - "query client=%p thread=0x%lx " - "(): %s", - client, - (unsigned long) isc_thread_self(), - message); - } -} -#define CTRACE(l,m) client_trace(client, l, m) -#else -#define CTRACE(l,m) ((void)m) -#endif /* WANT_QUERYTRACE */ - - -#define DNS_GETDB_NOEXACT 0x01U -#define DNS_GETDB_NOLOG 0x02U -#define DNS_GETDB_PARTIAL 0x04U -#define DNS_GETDB_IGNOREACL 0x08U - -#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0) - -#define SFCACHE_CDFLAG 0x1 - -/* - * These have the same semantics as: - * - * foo_attach(b, a); - * foo_detach(&a); - * - * without the locking and magic testing. - * - * We use SAVE and RESTORE as that shows the operation being performed. - */ -#define SAVE(a, b) do { INSIST(a == NULL); a = b; b = NULL; } while (0) -#define RESTORE(a, b) SAVE(a, b) - -typedef struct client_additionalctx { - ns_client_t *client; - dns_rdataset_t *rdataset; -} client_additionalctx_t; - -static isc_result_t -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); - -static bool -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -static void -query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, - dns_dbversion_t *version, ns_client_t *client, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_name_t *fname, bool exact, - dns_name_t *found); - -static inline void -log_queryerror(ns_client_t *client, isc_result_t result, int line, int level); - -static void -rpz_st_clear(ns_client_t *client); - -static bool -rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain); - -/*% - * Increment query statistics counters. - */ -static inline void -inc_stats(ns_client_t *client, isc_statscounter_t counter) { - dns_zone_t *zone = client->query.authzone; - dns_rdatatype_t qtype; - dns_rdataset_t *rdataset; - isc_stats_t *zonestats; - dns_stats_t *querystats = NULL; - - isc_stats_increment(ns_g_server->nsstats, counter); - - if (zone == NULL) - return; - - /* Do regular response type stats */ - zonestats = dns_zone_getrequeststats(zone); - - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - - /* Do query type statistics - * - * We only increment per-type if we're using the authoritative - * answer counter, preventing double-counting. - */ - if (counter == dns_nsstatscounter_authans) { - querystats = dns_zone_getrcvquerystats(zone); - if (querystats != NULL) { - rdataset = ISC_LIST_HEAD(client->query.qname->list); - if (rdataset != NULL) { - qtype = rdataset->type; - dns_rdatatypestats_increment(querystats, qtype); - } - } - } -} - -static void -query_send(ns_client_t *client) { - isc_statscounter_t counter; - - if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) - inc_stats(client, dns_nsstatscounter_nonauthans); - else - inc_stats(client, dns_nsstatscounter_authans); - - if (client->message->rcode == dns_rcode_noerror) { - dns_section_t answer = DNS_SECTION_ANSWER; - if (ISC_LIST_EMPTY(client->message->sections[answer])) { - if (client->query.isreferral) - counter = dns_nsstatscounter_referral; - else - counter = dns_nsstatscounter_nxrrset; - } else - counter = dns_nsstatscounter_success; - } else if (client->message->rcode == dns_rcode_nxdomain) - counter = dns_nsstatscounter_nxdomain; - else if (client->message->rcode == dns_rcode_badcookie) - counter = dns_nsstatscounter_badcookie; - else /* We end up here in case of YXDOMAIN, and maybe others */ - counter = dns_nsstatscounter_failure; - - inc_stats(client, counter); - ns_client_send(client); -} - -static void -query_error(ns_client_t *client, isc_result_t result, int line) { - int loglevel = ISC_LOG_DEBUG(3); - - switch (result) { - case DNS_R_SERVFAIL: - loglevel = ISC_LOG_DEBUG(1); - inc_stats(client, dns_nsstatscounter_servfail); - break; - case DNS_R_FORMERR: - inc_stats(client, dns_nsstatscounter_formerr); - break; - default: - inc_stats(client, dns_nsstatscounter_failure); - break; - } - - if (ns_g_server->log_queries) - loglevel = ISC_LOG_INFO; - - log_queryerror(client, result, line, loglevel); - - ns_client_error(client, result); -} - -static void -query_next(ns_client_t *client, isc_result_t result) { - if (result == DNS_R_DUPLICATE) - inc_stats(client, dns_nsstatscounter_duplicate); - else if (result == DNS_R_DROP) - inc_stats(client, dns_nsstatscounter_dropped); - else - inc_stats(client, dns_nsstatscounter_failure); - ns_client_next(client, result); -} - -static inline void -query_freefreeversions(ns_client_t *client, bool everything) { - ns_dbversion_t *dbversion, *dbversion_next; - unsigned int i; - - for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; - dbversion != NULL; - dbversion = dbversion_next, i++) - { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - /* - * If we're not freeing everything, we keep the first three - * dbversions structures around. - */ - if (i > 3 || everything) { - ISC_LIST_UNLINK(client->query.freeversions, dbversion, - link); - isc_mem_put(client->mctx, dbversion, - sizeof(*dbversion)); - } - } -} - -void -ns_query_cancel(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - dns_resolver_cancelfetch(client->query.fetch); - - client->query.fetch = NULL; - } - UNLOCK(&client->query.fetchlock); -} - -static inline void -query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { - dns_rdataset_t *rdataset = *rdatasetp; - - CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset"); - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, rdatasetp); - } - CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset: done"); -} - -static inline void -query_reset(ns_client_t *client, bool everything) { - isc_buffer_t *dbuf, *dbuf_next; - ns_dbversion_t *dbversion, *dbversion_next; - - CTRACE(ISC_LOG_DEBUG(3), "query_reset"); - - /*% - * Reset the query state of a client to its default state. - */ - - /* - * Cancel the fetch if it's running. - */ - ns_query_cancel(client); - - /* - * Cleanup any active versions. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = dbversion_next) { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - dns_db_closeversion(dbversion->db, &dbversion->version, - false); - dns_db_detach(&dbversion->db); - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } - ISC_LIST_INIT(client->query.activeversions); - - if (client->query.authdb != NULL) - dns_db_detach(&client->query.authdb); - if (client->query.authzone != NULL) - dns_zone_detach(&client->query.authzone); - - if (client->query.dns64_aaaa != NULL) - query_putrdataset(client, &client->query.dns64_aaaa); - if (client->query.dns64_sigaaaa != NULL) - query_putrdataset(client, &client->query.dns64_sigaaaa); - if (client->query.dns64_aaaaok != NULL) { - isc_mem_put(client->mctx, client->query.dns64_aaaaok, - client->query.dns64_aaaaoklen * - sizeof(bool)); - client->query.dns64_aaaaok = NULL; - client->query.dns64_aaaaoklen = 0; - } - - query_putrdataset(client, &client->query.redirect.rdataset); - query_putrdataset(client, &client->query.redirect.sigrdataset); - if (client->query.redirect.db != NULL) { - if (client->query.redirect.node != NULL) - dns_db_detachnode(client->query.redirect.db, - &client->query.redirect.node); - dns_db_detach(&client->query.redirect.db); - } - if (client->query.redirect.zone != NULL) - dns_zone_detach(&client->query.redirect.zone); - - query_freefreeversions(client, everything); - - for (dbuf = ISC_LIST_HEAD(client->query.namebufs); - dbuf != NULL; - dbuf = dbuf_next) { - dbuf_next = ISC_LIST_NEXT(dbuf, link); - if (dbuf_next != NULL || everything) { - ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); - isc_buffer_free(&dbuf); - } - } - - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = NULL; - client->query.attributes = (NS_QUERYATTR_RECURSIONOK | - NS_QUERYATTR_CACHEOK | - NS_QUERYATTR_SECURE); - client->query.restarts = 0; - client->query.timerset = false; - if (client->query.rpz_st != NULL) { - rpz_st_clear(client); - if (everything) { - isc_mem_put(client->mctx, client->query.rpz_st, - sizeof(*client->query.rpz_st)); - client->query.rpz_st = NULL; - } - } - client->query.origqname = NULL; - client->query.dboptions = 0; - client->query.fetchoptions = 0; - client->query.gluedb = NULL; - client->query.authdbset = false; - client->query.isreferral = false; - client->query.dns64_options = 0; - client->query.dns64_ttl = UINT32_MAX; - recparam_update(&client->query.recparam, 0, NULL, NULL); - client->query.root_key_sentinel_keyid = 0; - client->query.root_key_sentinel_is_ta = false; - client->query.root_key_sentinel_not_ta = false; -} - -static void -query_next_callback(ns_client_t *client) { - query_reset(client, false); -} - -void -ns_query_free(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - query_reset(client, true); -} - -static inline isc_result_t -query_newnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf"); - /*% - * Allocate a name buffer. - */ - - dbuf = NULL; - result = isc_buffer_allocate(client->mctx, &dbuf, 1024); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newnamebuf: isc_buffer_allocate failed: done"); - return (result); - } - ISC_LIST_APPEND(client->query.namebufs, dbuf, link); - - CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf: done"); - return (ISC_R_SUCCESS); -} - -static inline isc_buffer_t * -query_getnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - isc_region_t r; - - CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf"); - /*% - * Return a name buffer with space for a maximal name, allocating - * a new one if necessary. - */ - - if (ISC_LIST_EMPTY(client->query.namebufs)) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - } - } - - dbuf = ISC_LIST_TAIL(client->query.namebufs); - INSIST(dbuf != NULL); - isc_buffer_availableregion(dbuf, &r); - if (r.length < DNS_NAME_MAXWIRE) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - - } - dbuf = ISC_LIST_TAIL(client->query.namebufs); - isc_buffer_availableregion(dbuf, &r); - INSIST(r.length >= 255); - } - CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf: done"); - return (dbuf); -} - -static inline void -query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { - isc_region_t r; - - CTRACE(ISC_LOG_DEBUG(3), "query_keepname"); - /*% - * 'name' is using space in 'dbuf', but 'dbuf' has not yet been - * adjusted to take account of that. We do the adjustment. - */ - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0); - - dns_name_toregion(name, &r); - isc_buffer_add(dbuf, r.length); - dns_name_setbuffer(name, NULL); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; -} - -static inline void -query_releasename(ns_client_t *client, dns_name_t **namep) { - dns_name_t *name = *namep; - - /*% - * 'name' is no longer needed. Return it to our pool of temporary - * names. If it is using a name buffer, relinquish its exclusive - * rights on the buffer. - */ - - CTRACE(ISC_LOG_DEBUG(3), "query_releasename"); - if (dns_name_hasbuffer(name)) { - INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) - != 0); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; - } - dns_message_puttempname(client->message, namep); - CTRACE(ISC_LOG_DEBUG(3), "query_releasename: done"); -} - -static inline dns_name_t * -query_newname(ns_client_t *client, isc_buffer_t *dbuf, - isc_buffer_t *nbuf) -{ - dns_name_t *name; - isc_region_t r; - isc_result_t result; - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); - - CTRACE(ISC_LOG_DEBUG(3), "query_newname"); - name = NULL; - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newname: dns_message_gettempname failed: done"); - return (NULL); - } - isc_buffer_availableregion(dbuf, &r); - isc_buffer_init(nbuf, r.base, r.length); - dns_name_init(name, NULL); - dns_name_setbuffer(name, nbuf); - client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; - - CTRACE(ISC_LOG_DEBUG(3), "query_newname: done"); - return (name); -} - -static inline dns_rdataset_t * -query_newrdataset(ns_client_t *client) { - dns_rdataset_t *rdataset; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset"); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_newrdataset: " - "dns_message_gettemprdataset failed: done"); - return (NULL); - } - - CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: done"); - return (rdataset); -} - -static inline isc_result_t -query_newdbversion(ns_client_t *client, unsigned int n) { - unsigned int i; - ns_dbversion_t *dbversion; - - for (i = 0; i < n; i++) { - dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); - if (dbversion != NULL) { - dbversion->db = NULL; - dbversion->version = NULL; - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } else { - /* - * We only return ISC_R_NOMEMORY if we couldn't - * allocate anything. - */ - if (i == 0) - return (ISC_R_NOMEMORY); - else - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_SUCCESS); -} - -static inline ns_dbversion_t * -query_getdbversion(ns_client_t *client) { - isc_result_t result; - ns_dbversion_t *dbversion; - - if (ISC_LIST_EMPTY(client->query.freeversions)) { - result = query_newdbversion(client, 1); - if (result != ISC_R_SUCCESS) - return (NULL); - } - dbversion = ISC_LIST_HEAD(client->query.freeversions); - INSIST(dbversion != NULL); - ISC_LIST_UNLINK(client->query.freeversions, dbversion, link); - - return (dbversion); -} - -isc_result_t -ns_query_init(ns_client_t *client) { - isc_result_t result; - - REQUIRE(NS_CLIENT_VALID(client)); - - ISC_LIST_INIT(client->query.namebufs); - ISC_LIST_INIT(client->query.activeversions); - ISC_LIST_INIT(client->query.freeversions); - client->query.restarts = 0; - client->query.timerset = false; - client->query.rpz_st = NULL; - client->query.qname = NULL; - /* - * This mutex is destroyed when the client is destroyed in - * exit_check(). - */ - result = isc_mutex_init(&client->query.fetchlock); - if (result != ISC_R_SUCCESS) - return (result); - client->query.fetch = NULL; - client->query.prefetch = NULL; - client->query.authdb = NULL; - client->query.authzone = NULL; - client->query.authdbset = false; - client->query.isreferral = false; - client->query.dns64_aaaa = NULL; - client->query.dns64_sigaaaa = NULL; - client->query.dns64_aaaaok = NULL; - client->query.dns64_aaaaoklen = 0; - client->query.redirect.db = NULL; - client->query.redirect.node = NULL; - client->query.redirect.zone = NULL; - client->query.redirect.qtype = dns_rdatatype_none; - client->query.redirect.result = ISC_R_SUCCESS; - client->query.redirect.rdataset = NULL; - client->query.redirect.sigrdataset = NULL; - client->query.redirect.authoritative = false; - client->query.redirect.is_zone = false; - client->query.redirect.fname = - dns_fixedname_initname(&client->query.redirect.fixed); - query_reset(client, false); - result = query_newdbversion(client, 3); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&client->query.fetchlock); - return (result); - } - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - query_freefreeversions(client, true); - DESTROYLOCK(&client->query.fetchlock); - } - - return (result); -} - -static ns_dbversion_t * -query_findversion(ns_client_t *client, dns_db_t *db) { - ns_dbversion_t *dbversion; - - /*% - * We may already have done a query related to this - * database. If so, we must be sure to make subsequent - * queries from the same version. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = ISC_LIST_NEXT(dbversion, link)) { - if (dbversion->db == db) - break; - } - - if (dbversion == NULL) { - /* - * This is a new zone for this query. Add it to - * the active list. - */ - dbversion = query_getdbversion(client); - if (dbversion == NULL) - return (NULL); - dns_db_attach(db, &dbversion->db); - dns_db_currentversion(db, &dbversion->version); - dbversion->acl_checked = false; - dbversion->queryok = false; - ISC_LIST_APPEND(client->query.activeversions, - dbversion, link); - } - - return (dbversion); -} - -static inline isc_result_t -query_validatezonedb(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t qtype, unsigned int options, - dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t **versionp) -{ - isc_result_t result; - dns_acl_t *queryacl, *queryonacl; - ns_dbversion_t *dbversion; - - REQUIRE(zone != NULL); - REQUIRE(db != NULL); - - /* - * This limits our searching to the zone where the first name - * (the query target) was looked for. This prevents following - * CNAMES or DNAMES into other zones and prevents returning - * additional data from other zones. - */ - if (!client->view->additionalfromauth && - client->query.authdbset && - db != client->query.authdb) - return (DNS_R_REFUSED); - - /* - * Non recursive query to a static-stub zone is prohibited; its - * zone content is not public data, but a part of local configuration - * and should not be disclosed. - */ - if (dns_zone_gettype(zone) == dns_zone_staticstub && - !RECURSIONOK(client)) { - return (DNS_R_REFUSED); - } - - /* - * If the zone has an ACL, we'll check it, otherwise - * we use the view's "allow-query" ACL. Each ACL is only checked - * once per query. - * - * Also, get the database version to use. - */ - - /* - * Get the current version of this database. - */ - dbversion = query_findversion(client, db); - if (dbversion == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to get db version"); - return (DNS_R_SERVFAIL); - } - - if ((options & DNS_GETDB_IGNOREACL) != 0) - goto approved; - if (dbversion->acl_checked) { - if (!dbversion->queryok) - return (DNS_R_REFUSED); - goto approved; - } - - queryacl = dns_zone_getqueryacl(zone); - if (queryacl == NULL) { - queryacl = client->view->queryacl; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOKVALID) != 0) { - /* - * We've evaluated the view's queryacl already. If - * NS_QUERYATTR_QUERYOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - dbversion->acl_checked = true; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOK) == 0) { - dbversion->queryok = false; - return (DNS_R_REFUSED); - } - dbversion->queryok = true; - goto approved; - } - } - - result = ns_client_checkaclsilent(client, NULL, queryacl, true); - if ((options & DNS_GETDB_NOLOG) == 0) { - char msg[NS_CLIENT_ACLMSGSIZE("query")]; - if (result == ISC_R_SUCCESS) { - if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - } - - if (queryacl == client->view->queryacl) { - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the default - * "allow-query" ACL. Remember this so we - * don't have to check again. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOK; - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_QUERYOK attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; - } - - /* If and only if we've gotten this far, check allow-query-on too */ - if (result == ISC_R_SUCCESS) { - queryonacl = dns_zone_getqueryonacl(zone); - if (queryonacl == NULL) - queryonacl = client->view->queryonacl; - - result = ns_client_checkaclsilent(client, &client->destaddr, - queryonacl, true); - if ((options & DNS_GETDB_NOLOG) == 0 && - result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "query-on denied"); - } - - dbversion->acl_checked = true; - if (result != ISC_R_SUCCESS) { - dbversion->queryok = false; - return (DNS_R_REFUSED); - } - dbversion->queryok = true; - - approved: - /* Transfer ownership, if necessary. */ - if (versionp != NULL) - *versionp = dbversion->version; - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp) -{ - isc_result_t result; - unsigned int ztoptions; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - bool partial = false; - - REQUIRE(zonep != NULL && *zonep == NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a zone database to answer the query. - */ - ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ? - DNS_ZTFIND_NOEXACT : 0; - - result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, - &zone); - - if (result == DNS_R_PARTIALMATCH) - partial = true; - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - result = dns_zone_getdb(zone, &db); - - if (result != ISC_R_SUCCESS) - goto fail; - - result = query_validatezonedb(client, name, qtype, options, zone, db, - versionp); - - if (result != ISC_R_SUCCESS) - goto fail; - - /* Transfer ownership. */ - *zonep = zone; - *dbp = db; - - if (partial && (options & DNS_GETDB_PARTIAL) != 0) - return (DNS_R_PARTIALMATCH); - return (ISC_R_SUCCESS); - - fail: - if (zone != NULL) - dns_zone_detach(&zone); - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static void -rpz_log_rewrite(ns_client_t *client, bool disabled, - dns_rpz_policy_t policy, dns_rpz_type_t type, - dns_zone_t *p_zone, dns_name_t *p_name, - dns_name_t *cname, dns_rpz_num_t rpz_num) -{ - char cname_buf[DNS_NAME_FORMATSIZE] = { 0 }; - char p_name_buf[DNS_NAME_FORMATSIZE]; - char qname_buf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - const char *s1 = cname_buf, *s2 = cname_buf; - dns_rdataset_t *rdataset; - dns_rpz_st_t *st; - isc_stats_t *zonestats; - - /* - * Count enabled rewrites in the global counter. - * Count both enabled and disabled rewrites for each zone. - */ - if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_rpz_rewrites); - } - if (p_zone != NULL) { - zonestats = dns_zone_getrequeststats(p_zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, - dns_nsstatscounter_rpz_rewrites); - } - - if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) - return; - - st = client->query.rpz_st; - if ((st->popt.no_log & DNS_RPZ_ZBIT(rpz_num)) != 0) - return; - - dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf)); - dns_name_format(p_name, p_name_buf, sizeof(p_name_buf)); - if (cname != NULL) { - s1 = " (CNAME to: "; - dns_name_format(cname, cname_buf, sizeof(cname_buf)); - s2 = ")"; - } - - /* - * Log Qclass and Qtype in addition to existing - * fields. - */ - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - INSIST(rdataset != NULL); - dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - - ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, -#ifdef RPZ_LOG_QTYPE_QCLASS - "%srpz %s %s rewrite %s/%s/%s via %s%s%s%s", -#else /* RPZ_LOG_QTYPE_QCLASS */ - "%srpz %s %s rewrite %s via %s%s%s%s", -#endif /* RPZ_LOG_QTYPE_QCLASS */ - disabled ? "disabled " : "", - dns_rpz_type2str(type), dns_rpz_policy2str(policy), - qname_buf, -#ifdef RPZ_LOG_QTYPE_QCLASS - typebuf, classbuf, -#endif /* RPZ_LOG_QTYPE_QCLASS */ - p_name_buf, s1, cname_buf, s2); -} - -static void -rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name, - dns_rpz_type_t rpz_type1, dns_rpz_type_t rpz_type2, - const char *str, isc_result_t result) -{ - char qnamebuf[DNS_NAME_FORMATSIZE]; - char p_namebuf[DNS_NAME_FORMATSIZE]; - const char *failed; - const char *slash; - const char *via; - const char *str_blank; - const char *rpztypestr1; - const char *rpztypestr2; - - if (!isc_log_wouldlog(ns_g_lctx, level)) - return; - - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems. - */ - if (level <= DNS_RPZ_DEBUG_LEVEL1) - failed = "failed: "; - else - failed = ": "; - - rpztypestr1 = dns_rpz_type2str(rpz_type1); - if (rpz_type2 != DNS_RPZ_TYPE_BAD) { - slash = "/"; - rpztypestr2 = dns_rpz_type2str(rpz_type2); - } else { - slash = ""; - rpztypestr2 = ""; - } - - str_blank = (*str != ' ' && *str != '\0') ? " " : ""; - dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf)); - if (p_name != NULL) { - via = " via "; - dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); - } else { - via = ""; - p_namebuf[0] = '\0'; - } - - ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, - NS_LOGMODULE_QUERY, level, - "rpz %s%s%s rewrite %s%s%s%s%s%s : %s", - rpztypestr1, slash, rpztypestr2, - qnamebuf, via, p_namebuf, str_blank, - str, failed, isc_result_totext(result)); -} - -static void -rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name, - dns_rpz_type_t rpz_type, const char *str, isc_result_t result) -{ - rpz_log_fail_helper(client, level, p_name, - rpz_type, DNS_RPZ_TYPE_BAD, str, result); -} - -/* - * Get a policy rewrite zone database. - */ -static isc_result_t -rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type, - dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) -{ - char qnamebuf[DNS_NAME_FORMATSIZE]; - char p_namebuf[DNS_NAME_FORMATSIZE]; - dns_dbversion_t *rpz_version = NULL; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_getdb"); - - result = query_getzonedb(client, p_name, dns_rdatatype_any, - DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version); - if (result == ISC_R_SUCCESS) { - dns_rpz_st_t *st = client->query.rpz_st; - - /* - * It isn't meaningful to log this message when - * logging is disabled for some policy zones. - */ - if (st->popt.no_log == 0 && - isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) - { - dns_name_format(client->query.qname, qnamebuf, - sizeof(qnamebuf)); - dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); - ns_client_log(client, DNS_LOGCATEGORY_RPZ, - NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2, - "try rpz %s rewrite %s via %s", - dns_rpz_type2str(rpz_type), - qnamebuf, p_namebuf); - } - *versionp = rpz_version; - return (ISC_R_SUCCESS); - } - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, - " query_getzonedb()", result); - return (result); -} - -static inline isc_result_t -query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - dns_db_t **dbp, unsigned int options) -{ - isc_result_t result; - bool check_acl; - dns_db_t *db = NULL; - - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a cache database to answer the query. - * This may fail with DNS_R_REFUSED if the client - * is not allowed to use the cache. - */ - - if (!USECACHE(client)) - return (DNS_R_REFUSED); - dns_db_attach(client->view->cachedb, &db); - - if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) { - /* - * We've evaluated the view's cacheacl already. If - * NS_QUERYATTR_CACHEACLOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - check_acl = false; - if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0) - goto refuse; - } else { - /* - * We haven't evaluated the view's queryacl yet. - */ - check_acl = true; - } - - if (check_acl) { - bool log = !(options & DNS_GETDB_NOLOG); - char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; - - result = ns_client_checkaclsilent(client, NULL, - client->view->cacheacl, - true); - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the "allow-query-cache" ACL. - * Remember this so we don't have to check again. - */ - client->query.attributes |= - NS_QUERYATTR_CACHEACLOK; - if (log && isc_log_wouldlog(ns_g_lctx, - ISC_LOG_DEBUG(3))) - { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else if (log) { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, msg, - sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID; - - if (result != ISC_R_SUCCESS) - goto refuse; - } - - /* Approved. */ - - /* Transfer ownership. */ - *dbp = db; - - return (ISC_R_SUCCESS); - - refuse: - result = DNS_R_REFUSED; - - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static inline isc_result_t -query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, bool *is_zonep) -{ - isc_result_t result; - - isc_result_t tresult; - unsigned int namelabels; - unsigned int zonelabels; - dns_zone_t *zone = NULL; - - REQUIRE(zonep != NULL && *zonep == NULL); - - /* Calculate how many labels are in name. */ - namelabels = dns_name_countlabels(name); - zonelabels = 0; - - /* Try to find name in bind's standard database. */ - result = query_getzonedb(client, name, qtype, options, &zone, - dbp, versionp); - - /* See how many labels are in the zone's name. */ - if (result == ISC_R_SUCCESS && zone != NULL) - zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); - - /* - * If # zone labels < # name labels, try to find an even better match - * Only try if DLZ drivers are loaded for this view - */ - if (ISC_UNLIKELY(zonelabels < namelabels && - !ISC_LIST_EMPTY(client->view->dlz_searched))) - { - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_db_t *tdbp; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - tdbp = NULL; - tresult = dns_view_searchdlz(client->view, name, - zonelabels, &cm, &ci, &tdbp); - /* If we successful, we found a better match. */ - if (tresult == ISC_R_SUCCESS) { - ns_dbversion_t *dbversion; - - /* - * If the previous search returned a zone, detach it. - */ - if (zone != NULL) - dns_zone_detach(&zone); - - /* - * If the previous search returned a database, - * detach it. - */ - if (*dbp != NULL) - dns_db_detach(dbp); - - /* - * If the previous search returned a version, clear it. - */ - *versionp = NULL; - - dbversion = query_findversion(client, tdbp); - if (dbversion == NULL) { - tresult = ISC_R_NOMEMORY; - } else { - /* - * Be sure to return our database. - */ - *dbp = tdbp; - *versionp = dbversion->version; - } - - /* - * We return a null zone, No stats for DLZ zones. - */ - zone = NULL; - result = tresult; - } - } - - /* If successful, Transfer ownership of zone. */ - if (result == ISC_R_SUCCESS) { - *zonep = zone; - /* - * If neither attempt above succeeded, return the cache instead - */ - *is_zonep = true; - } else if (result == ISC_R_NOTFOUND) { - result = query_getcachedb(client, name, qtype, dbp, options); - *is_zonep = false; - } - return (result); -} - -static inline bool -query_isduplicate(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t type, dns_name_t **mnamep) -{ - dns_section_t section; - dns_name_t *mname = NULL; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate"); - - for (section = DNS_SECTION_ANSWER; - section <= DNS_SECTION_ADDITIONAL; - section++) { - result = dns_message_findname(client->message, section, - name, type, 0, &mname, NULL); - if (result == ISC_R_SUCCESS) { - /* - * We've already got this RRset in the response. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_isduplicate: true: done"); - return (true); - } else if (result == DNS_R_NXRRSET) { - /* - * The name exists, but the rdataset does not. - */ - if (section == DNS_SECTION_ADDITIONAL) - break; - } else - RUNTIME_CHECK(result == DNS_R_NXDOMAIN); - mname = NULL; - } - - if (mnamep != NULL) - *mnamep = mname; - - CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done"); - return (false); -} - -static isc_result_t -query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - ns_client_t *client = arg; - isc_result_t result, eresult; - dns_dbnode_t *node; - dns_db_t *db; - dns_name_t *fname, *mname; - dns_rdataset_t *rdataset, *sigrdataset, *trdataset; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version; - bool added_something, need_addname; - dns_zone_t *zone; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_rdatasetadditional_t additionaltype; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(qtype != dns_rdatatype_any); - - if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) - return (ISC_R_SUCCESS); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional"); - - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - trdataset = NULL; - db = NULL; - version = NULL; - node = NULL; - added_something = false; - need_addname = false; - zone = NULL; - additionaltype = dns_rdatasetadditional_fromauth; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - */ - if (qtype == dns_rdatatype_a) - type = dns_rdatatype_any; - else - type = qtype; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) - goto try_cache; - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - result = dns_db_findext(db, name, version, type, - client->query.dboptions, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (sigrdataset != NULL && !dns_db_issecure(db) && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - goto found; - } - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - additionaltype = dns_rdatasetadditional_fromcache; - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - /* - * Attempt to validate glue. - */ - if (sigrdataset == NULL) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - result = dns_db_findext(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - - dns_cache_updatestats(client->view->cache, result); - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - if (result == ISC_R_SUCCESS) - goto found; - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poison caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - dns_db_attach(client->query.gluedb, &db); - - additionaltype = dns_rdatasetadditional_fromglue; - result = dns_db_findext(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) - goto cleanup; - - found: - /* - * We have found a potential additional data rdataset, or - * at least a node to iterate over. - */ - query_keepname(client, fname, dbuf); - - /* - * If we have an rdataset, add it to the additional data - * section. - */ - mname = NULL; - if (dns_rdataset_isassociated(rdataset) && - !query_isduplicate(client, fname, type, &mname)) { - if (mname != NULL) { - INSIST(mname != fname); - query_releasename(client, &fname); - fname = mname; - } else - need_addname = true; - ISC_LIST_APPEND(fname->list, rdataset, link); - trdataset = rdataset; - rdataset = NULL; - added_something = true; - /* - * Note: we only add SIGs if we've added the type they cover, - * so we do not need to check if the SIG rdataset is already - * in the response. - */ - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, sigrdataset, link); - sigrdataset = NULL; - } - } - - if (qtype == dns_rdatatype_a) { -#ifdef ALLOW_FILTER_AAAA - bool have_a = false; -#endif - - /* - * We now go looking for A and AAAA records, along with - * their signatures. - * - * XXXRTH This code could be more efficient. - */ - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - } else { - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - } - if (sigrdataset != NULL) { - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto addname; - } - if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) - goto aaaa_lookup; - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - rdataset, sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - bool invalid = false; - mname = NULL; -#ifdef ALLOW_FILTER_AAAA - have_a = true; -#endif - if (additionaltype == - dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - /* validate() may change rdataset->trust */ - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (!query_isduplicate(client, fname, - dns_rdatatype_a, &mname)) - { - if (mname != fname) { - if (mname != NULL) { - query_releasename(client, - &fname); - fname = mname; - } else - need_addname = true; - } - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = true; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = - query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - if (WANTDNSSEC(client) && sigrdataset == NULL) - goto addname; - } else { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - } - aaaa_lookup: - if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) - goto addname; - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_aaaa, 0, - client->now, - rdataset, sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - bool invalid = false; - mname = NULL; - /* - * There's an A; check whether we're filtering AAAA - */ -#ifdef ALLOW_FILTER_AAAA - if (have_a && - (client->filter_aaaa == dns_aaaa_break_dnssec || - (client->filter_aaaa == dns_aaaa_filter && - (!WANTDNSSEC(client) || sigrdataset == NULL || - !dns_rdataset_isassociated(sigrdataset))))) - goto addname; -#endif - if (additionaltype == - dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - /* validate() may change rdataset->trust */ - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (!query_isduplicate(client, fname, - dns_rdatatype_aaaa, &mname)) - { - if (mname != fname) { - if (mname != NULL) { - query_releasename(client, - &fname); - fname = mname; - } else - need_addname = true; - } - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = true; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = NULL; - } - rdataset = NULL; - } - } - } - - addname: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: addname"); - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be false. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - /* - * In a few cases, we want to add additional data for additional - * data. It's simpler to just deal with special cases here than - * to try to create a general purpose mechanism and allow the - * rdata implementations to do it themselves. - * - * This involves recursion, but the depth is limited. The - * most complex case is adding a SRV rdataset, which involves - * recursing to add address records, which in turn can cause - * recursion to add KEYs. - */ - if (type == dns_rdatatype_srv && trdataset != NULL) { - /* - * If we're adding SRV records to the additional data - * section, it's helpful if we add the SRV additional data - * as well. - */ - eresult = dns_rdataset_additionaldata(trdataset, - query_addadditional, - client); - } - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done"); - return (eresult); -} - -static inline void -query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base, - dns_rdatasetadditional_t additionaltype, - dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, dns_dbnode_t **nodep, - dns_name_t *fname) -{ - dns_rdataset_t *rdataset; - - while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) { - ISC_LIST_UNLINK(fname->list, rdataset, link); - query_putrdataset(client, &rdataset); - } - if (*versionp != NULL) - dns_db_closeversion(*dbp, versionp, false); - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - if (*dbp != NULL) - dns_db_detach(dbp); - if (*zonep != NULL) - dns_zone_detach(zonep); - (void)dns_rdataset_putadditional(client->view->acache, rdataset_base, - additionaltype, type); -} - -static inline isc_result_t -query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0, - dns_dbversion_t *version) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_dbversion_t *version_current = NULL; - dns_db_t *db_current = db0; - - if (db_current == NULL) { - result = dns_zone_getdb(zone, &db_current); - if (result != ISC_R_SUCCESS) - return (result); - } - dns_db_currentversion(db_current, &version_current); - if (db_current != db || version_current != version) { - result = ISC_R_FAILURE; - goto cleanup; - } - - cleanup: - dns_db_closeversion(db_current, &version_current, false); - if (db0 == NULL && db_current != NULL) - dns_db_detach(&db_current); - - return (result); -} - -static isc_result_t -query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - client_additionalctx_t *additionalctx = arg; - dns_rdataset_t *rdataset_base; - ns_client_t *client; - isc_result_t result, eresult; - dns_dbnode_t *node, *cnode; - dns_db_t *db, *cdb; - dns_name_t *fname, *mname0, cfname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_rdataset_t *crdataset, *crdataset_next; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version, *cversion; - bool added_something, need_addname, needadditionalcache; - bool need_sigrrset; - dns_zone_t *zone; - dns_rdatatype_t type; - dns_rdatasetadditional_t additionaltype; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - bool invalid; - - /* - * If we don't have an additional cache call query_addadditional. - */ - client = additionalctx->client; - REQUIRE(NS_CLIENT_VALID(client)); - - if (qtype != dns_rdatatype_a || client->view->acache == NULL) { - /* - * This function is optimized for "address" types. For other - * types, use a generic routine. - * XXX: ideally, this function should be generic enough. - */ - return (query_addadditional(additionalctx->client, - name, qtype)); - } - - /* - * Initialization. - */ - rdataset_base = additionalctx->rdataset; - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - db = NULL; - cdb = NULL; - version = NULL; - cversion = NULL; - node = NULL; - cnode = NULL; - added_something = false; - need_addname = false; - zone = NULL; - needadditionalcache = false; - POST(needadditionalcache); - additionaltype = dns_rdatasetadditional_fromauth; - dns_name_init(&cfname, NULL); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2"); - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - * XXXJT: this approach can cause a suboptimal result when the cache - * DB only has partial address types and the glue DB has remaining - * ones. - */ - type = dns_rdatatype_any; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - goto cleanup; - dns_name_setbuffer(&cfname, &b); /* share the buffer */ - - /* Check additional cache */ - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, &zone, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findauthdb; - if (zone == NULL) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: auth zone not found"); - goto try_cache; - } - - /* Is the cached DB up-to-date? */ - result = query_iscachevalid(zone, cdb, NULL, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: old auth additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findauthdb; - } - - if (cnode == NULL) { - /* - * We have a negative cache. We don't have to check the zone - * ACL, since the result (not using this zone) would be same - * regardless of the result. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: negative auth additional cache"); - dns_db_closeversion(cdb, &cversion, false); - dns_db_detach(&cdb); - dns_zone_detach(&zone); - goto try_cache; - } - - result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG, - zone, cdb, NULL); - if (result != ISC_R_SUCCESS) { - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto try_cache; - } - - /* We've got an active cache. */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: auth additional cache"); - dns_db_closeversion(cdb, &cversion, false); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - findauthdb: - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) { - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, NULL, NULL, NULL, - NULL); - goto try_cache; - } - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - node = NULL; - result = dns_db_findext(db, name, version, type, - client->query.dboptions, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, zone, db, - version, NULL, fname); - - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - additionaltype = dns_rdatasetadditional_fromcache; - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - - result = dns_db_findext(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poison caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - /* Check additional cache */ - additionaltype = dns_rdatasetadditional_fromglue; - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, NULL, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findglue; - - result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: old glue additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findglue; - } - - if (cnode == NULL) { - /* We have a negative cache. */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addadditional2: negative glue additional cache"); - dns_db_closeversion(cdb, &cversion, false); - dns_db_detach(&cdb); - goto cleanup; - } - - /* Cache hit. */ - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: glue additional cache"); - dns_db_closeversion(cdb, &cversion, false); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - findglue: - dns_db_attach(client->query.gluedb, &db); - result = dns_db_findext(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, &cm, &ci, - NULL, NULL); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) { - /* cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, db, version, NULL, - fname); - goto cleanup; - } - - found: - /* - * We have found a DB node to iterate over from a DB. - * We are going to look for address RRsets (i.e., A and AAAA) in the DB - * node we've just found. We'll then store the complete information - * in the additional data cache. - */ - dns_name_clone(fname, &cfname); - query_keepname(client, fname, dbuf); - needadditionalcache = true; - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto cleanup; - - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - - if (additionaltype == dns_rdatasetadditional_fromcache && - query_isduplicate(client, fname, dns_rdatatype_a, NULL)) - goto aaaa_lookup; - /* - * Find A RRset with sig RRset. Even if we don't find a sig RRset - * for a client using DNSSEC, we'll continue the process to make a - * complete list to be cached. However, we need to cancel the - * caching when something unexpected happens, in order to avoid - * caching incomplete information. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, - client->now, rdataset, sigrdataset); - - /* - * Try to promote pending/glue from the cache to secure. - * If unable to do so, drop it from the response unless - * it's glue, in which case it may still be needed. - */ - invalid = false; - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == DNS_R_NCACHENXDOMAIN) - goto setcache; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - if (result == ISC_R_SUCCESS) { - /* Remember the result as a cache */ - ISC_LIST_APPEND(cfname.list, rdataset, link); - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (sigrdataset == NULL || rdataset == NULL) { - /* do not cache incomplete information */ - goto foundcache; - } - } - - aaaa_lookup: - if (additionaltype == dns_rdatasetadditional_fromcache && - query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) - goto foundcache; - /* Find AAAA RRset with sig RRset */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, - 0, client->now, rdataset, sigrdataset); - /* - * Try to promote pending/glue from the cache to secure. - * If unable to do so, drop it from the response unless - * it's glue, in which case it may still be needed. - */ - invalid = false; - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (DNS_TRUST_PENDING(rdataset->trust) || - DNS_TRUST_GLUE(rdataset->trust))) - { - invalid = !validate(client, db, fname, - rdataset, sigrdataset); - } - if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == ISC_R_SUCCESS) { - ISC_LIST_APPEND(cfname.list, rdataset, link); - rdataset = NULL; - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = NULL; - } - } - - setcache: - /* - * Set the new result in the cache if required. We do not support - * caching additional data from a cache DB. - */ - if (needadditionalcache == true && - (additionaltype == dns_rdatasetadditional_fromauth || - additionaltype == dns_rdatasetadditional_fromglue)) { - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - zone, db, version, node, - &cfname); - } - - foundcache: - need_sigrrset = false; - mname0 = NULL; - for (crdataset = ISC_LIST_HEAD(cfname.list); - crdataset != NULL; - crdataset = crdataset_next) { - dns_name_t *mname; - - crdataset_next = ISC_LIST_NEXT(crdataset, link); - - mname = NULL; - if (crdataset->type == dns_rdatatype_a || - crdataset->type == dns_rdatatype_aaaa) { - if (!query_isduplicate(client, fname, crdataset->type, - &mname)) { - if (mname != fname) { - if (mname != NULL) { - /* - * A different type of this name is - * already stored in the additional - * section. We'll reuse the name. - * Note that this should happen at most - * once. Otherwise, fname->link could - * leak below. - */ - INSIST(mname0 == NULL); - - query_releasename(client, &fname); - fname = mname; - mname0 = mname; - } else - need_addname = true; - } - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = true; - need_sigrrset = true; - } else - need_sigrrset = false; - } else if (crdataset->type == dns_rdatatype_rrsig && - need_sigrrset && WANTDNSSEC(client)) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = true; /* just in case */ - need_sigrrset = false; - } - } - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: addname"); - - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be false. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: cleanup"); - - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - query_putrdataset(client, &crdataset); - } - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: done"); - return (eresult); -} - -static inline void -query_addrdataset(ns_client_t *client, dns_name_t *fname, - dns_rdataset_t *rdataset) -{ - client_additionalctx_t additionalctx; - - /* - * Add 'rdataset' and any pertinent additional data to - * 'fname', a name in the response message for 'client'. - */ - - CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset"); - - ISC_LIST_APPEND(fname->list, rdataset, link); - - if (client->view->order != NULL) - rdataset->attributes |= dns_order_find(client->view->order, - fname, rdataset->type, - rdataset->rdclass); - rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; - - if (NOADDITIONAL(client)) - return; - - /* - * Add additional data. - * - * We don't care if dns_rdataset_additionaldata() fails. - */ - additionalctx.client = client; - additionalctx.rdataset = rdataset; - (void)dns_rdataset_additionaldata(rdataset, query_addadditional2, - &additionalctx); - CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done"); -} - -static isc_result_t -query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf, - dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdata_t *dns64_rdata; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t *dns64_rdatalist; - dns_rdataset_t *dns64_rdataset; - dns_rdataset_t *mrdataset; - isc_buffer_t *buffer; - isc_region_t r; - isc_result_t result; - dns_view_t *view = client->view; - isc_netaddr_t netaddr; - dns_dns64_t *dns64; - unsigned int flags = 0; - - /*% - * To the current response for 'client', add the answer RRset - * '*rdatasetp' and an optional signature set '*sigrdatasetp', with - * owner name '*namep', to section 'section', unless they are - * already there. Also add any pertinent additional data. - * - * If 'dbuf' is not NULL, then '*namep' is the name whose data is - * stored in 'dbuf'. In this case, query_addrrset() guarantees that - * when it returns the name will either have been kept or released. - */ - CTRACE(ISC_LOG_DEBUG(3), "query_dns64"); - name = *namep; - mname = NULL; - mrdataset = NULL; - buffer = NULL; - dns64_rdata = NULL; - dns64_rdataset = NULL; - dns64_rdatalist = NULL; - result = dns_message_findname(client->message, section, - name, dns_rdatatype_aaaa, - rdataset->covers, - &mname, &mrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - * There's nothing else to do; - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_dns64: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - return (ISC_R_SUCCESS); - } else if (result == DNS_R_NXDOMAIN) { - /* - * The name doesn't exist. - */ - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - *namep = NULL; - mname = name; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt * - 16 * dns_rdataset_count(rdataset)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(client->message, &dns64_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdatalist(client->message, - &dns64_rdatalist); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdatalist_init(dns64_rdatalist); - dns64_rdatalist->rdclass = dns_rdataclass_in; - dns64_rdatalist->type = dns_rdatatype_aaaa; - if (client->query.dns64_ttl != UINT32_MAX) - dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, - client->query.dns64_ttl); - else - dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600); - - if (RECURSIONOK(client)) - flags |= DNS_DNS64_RECURSIVE; - - /* - * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC - * as this provides a easy way to see if the answer was signed. - */ - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - flags |= DNS_DNS64_DNSSEC; - - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - for (dns64 = ISC_LIST_HEAD(client->view->dns64); - dns64 != NULL; dns64 = dns_dns64_next(dns64)) { - - dns_rdataset_current(rdataset, &rdata); - isc_buffer_availableregion(buffer, &r); - INSIST(r.length >= 16); - result = dns_dns64_aaaafroma(dns64, &netaddr, - client->signer, - &ns_g_server->aclenv, - flags, rdata.data, r.base); - if (result != ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - continue; - } - isc_buffer_add(buffer, 16); - isc_buffer_remainingregion(buffer, &r); - isc_buffer_forward(buffer, 16); - result = dns_message_gettemprdata(client->message, - &dns64_rdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdata_init(dns64_rdata); - dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in, - dns_rdatatype_aaaa, &r); - ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata, - link); - dns64_rdata = NULL; - dns_rdata_reset(&rdata); - } - } - if (result != ISC_R_NOMORE) - goto cleanup; - - if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) - goto cleanup; - - result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_setownercase(dns64_rdataset, mname); - client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; - dns64_rdataset->trust = rdataset->trust; - query_addrdataset(client, mname, dns64_rdataset); - dns64_rdataset = NULL; - dns64_rdatalist = NULL; - dns_message_takebuffer(client->message, &buffer); - inc_stats(client, dns_nsstatscounter_dns64); - result = ISC_R_SUCCESS; - - cleanup: - if (buffer != NULL) - isc_buffer_free(&buffer); - - if (dns64_rdata != NULL) - dns_message_puttemprdata(client->message, &dns64_rdata); - - if (dns64_rdataset != NULL) - dns_message_puttemprdataset(client->message, &dns64_rdataset); - - if (dns64_rdatalist != NULL) { - for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata); - dns64_rdata != NULL; - dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata)) - { - ISC_LIST_UNLINK(dns64_rdatalist->rdata, - dns64_rdata, link); - dns_message_puttemprdata(client->message, &dns64_rdata); - } - dns_message_puttemprdatalist(client->message, &dns64_rdatalist); - } - - CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done"); - return (result); -} - -static void -query_filter64(ns_client_t *client, dns_name_t **namep, - dns_rdataset_t *rdataset, isc_buffer_t *dbuf, - dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdata_t *myrdata; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t *myrdatalist; - dns_rdataset_t *myrdataset; - isc_buffer_t *buffer; - isc_region_t r; - isc_result_t result; - unsigned int i; - - CTRACE(ISC_LOG_DEBUG(3), "query_filter64"); - - INSIST(client->query.dns64_aaaaok != NULL); - INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset)); - - name = *namep; - mname = NULL; - buffer = NULL; - myrdata = NULL; - myrdataset = NULL; - myrdatalist = NULL; - result = dns_message_findname(client->message, section, - name, dns_rdatatype_aaaa, - rdataset->covers, - &mname, &myrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - * There's nothing else to do; - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_filter64: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - return; - } else if (result == DNS_R_NXDOMAIN) { - mname = name; - *namep = NULL; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - dbuf = NULL; - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - - result = isc_buffer_allocate(client->mctx, &buffer, - 16 * dns_rdataset_count(rdataset)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(client->message, &myrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdatalist(client->message, &myrdatalist); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdatalist_init(myrdatalist); - myrdatalist->rdclass = dns_rdataclass_in; - myrdatalist->type = dns_rdatatype_aaaa; - myrdatalist->ttl = rdataset->ttl; - - i = 0; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - if (!client->query.dns64_aaaaok[i++]) - continue; - dns_rdataset_current(rdataset, &rdata); - INSIST(rdata.length == 16); - isc_buffer_putmem(buffer, rdata.data, rdata.length); - isc_buffer_remainingregion(buffer, &r); - isc_buffer_forward(buffer, rdata.length); - result = dns_message_gettemprdata(client->message, &myrdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdata_init(myrdata); - dns_rdata_fromregion(myrdata, dns_rdataclass_in, - dns_rdatatype_aaaa, &r); - ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link); - myrdata = NULL; - dns_rdata_reset(&rdata); - } - if (result != ISC_R_NOMORE) - goto cleanup; - - result = dns_rdatalist_tordataset(myrdatalist, myrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_setownercase(myrdataset, name); - client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; - if (mname == name) { - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - dbuf = NULL; - } - myrdataset->trust = rdataset->trust; - query_addrdataset(client, mname, myrdataset); - myrdataset = NULL; - myrdatalist = NULL; - dns_message_takebuffer(client->message, &buffer); - - cleanup: - if (buffer != NULL) - isc_buffer_free(&buffer); - - if (myrdata != NULL) - dns_message_puttemprdata(client->message, &myrdata); - - if (myrdataset != NULL) - dns_message_puttemprdataset(client->message, &myrdataset); - - if (myrdatalist != NULL) { - for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata); - myrdata != NULL; - myrdata = ISC_LIST_HEAD(myrdatalist->rdata)) - { - ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link); - dns_message_puttemprdata(client->message, &myrdata); - } - dns_message_puttemprdatalist(client->message, &myrdatalist); - } - if (dbuf != NULL) - query_releasename(client, &name); - - CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done"); -} - -static void -query_addrrset(ns_client_t *client, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, - isc_buffer_t *dbuf, dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdataset_t *rdataset, *mrdataset, *sigrdataset; - isc_result_t result; - - /*% - * To the current response for 'client', add the answer RRset - * '*rdatasetp' and an optional signature set '*sigrdatasetp', with - * owner name '*namep', to section 'section', unless they are - * already there. Also add any pertinent additional data. - * - * If 'dbuf' is not NULL, then '*namep' is the name whose data is - * stored in 'dbuf'. In this case, query_addrrset() guarantees that - * when it returns the name will either have been kept or released. - */ - CTRACE(ISC_LOG_DEBUG(3), "query_addrrset"); - name = *namep; - rdataset = *rdatasetp; - if (sigrdatasetp != NULL) - sigrdataset = *sigrdatasetp; - else - sigrdataset = NULL; - mname = NULL; - mrdataset = NULL; - result = dns_message_findname(client->message, section, - name, rdataset->type, rdataset->covers, - &mname, &mrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - */ - CTRACE(ISC_LOG_DEBUG(3), - "query_addrrset: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) - mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - return; - } else if (result == DNS_R_NXDOMAIN) { - /* - * The name doesn't exist. - */ - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - *namep = NULL; - mname = name; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - /* - * Note: we only add SIGs if we've added the type they cover, so - * we do not need to check if the SIG rdataset is already in the - * response. - */ - query_addrdataset(client, mname, rdataset); - *rdatasetp = NULL; - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { - /* - * We have a signature. Add it to the response. - */ - ISC_LIST_APPEND(mname->list, sigrdataset, link); - *sigrdatasetp = NULL; - } - CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done"); -} - -static inline isc_result_t -query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, - unsigned int override_ttl, bool isassociated, - dns_section_t section) -{ - dns_name_t *name; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addsoa"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Don't add the SOA record for test which set "-T nosoa". - */ - if (ns_g_nosoa && (!WANTDNSSEC(client) || !isassociated)) - return (ISC_R_SUCCESS); - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client) && dns_db_issecure(db)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the SOA. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_soa, 0, client->now, - rdataset, sigrdataset); - } else { - dns_fixedname_t foundname; - dns_name_t *fname; - - fname = dns_fixedname_initname(&foundname); - - result = dns_db_findext(db, name, version, dns_rdatatype_soa, - client->query.dboptions, 0, &node, - fname, &cm, &ci, rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * This is bad. We tried to get the SOA RR at the zone top - * and it didn't work! - */ - CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex"); - eresult = DNS_R_SERVFAIL; - } else { - /* - * Extract the SOA MINIMUM. - */ - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (override_ttl != UINT32_MAX && - override_ttl < rdataset->ttl) { - rdataset->ttl = override_ttl; - if (sigrdataset != NULL) - sigrdataset->ttl = override_ttl; - } - - /* - * Add the SOA and its SIG to the response, with the - * TTLs adjusted per RFC2308 section 3. - */ - if (rdataset->ttl > soa.minimum) - rdataset->ttl = soa.minimum; - if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) - sigrdataset->ttl = soa.minimum; - - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - - if (section == DNS_SECTION_ADDITIONAL) - rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - section); - } - - cleanup: - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (eresult); -} - -static inline isc_result_t -query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { - dns_name_t *name, *fname; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_fixedname_t foundname; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addns"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - fname = dns_fixedname_initname(&foundname); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_DEBUG(3), - "query_addns: dns_message_gettempname failed: done"); - return (result); - } - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client) && dns_db_issecure(db)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the NS rdataset. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_ns, 0, client->now, - rdataset, sigrdataset); - } else { - CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find"); - result = dns_db_findext(db, name, NULL, dns_rdatatype_ns, - client->query.dboptions, 0, &node, - fname, &cm, &ci, rdataset, sigrdataset); - CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete"); - } - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_addns: " - "dns_db_findrdataset or dns_db_find failed"); - /* - * This is bad. We tried to get the NS rdataset at the zone - * top and it didn't work! - */ - eresult = DNS_R_SERVFAIL; - } else { - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - DNS_SECTION_AUTHORITY); - } - - cleanup: - CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - CTRACE(ISC_LOG_DEBUG(3), "query_addns: done"); - return (eresult); -} -static isc_result_t -query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, - dns_trust_t trust, dns_ttl_t ttl) -{ - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_region_t r; - dns_name_t *aname; - isc_result_t result; - - /* - * We assume the name data referred to by tname won't go away. - */ - - aname = NULL; - result = dns_message_gettempname(client->message, &aname); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_name_dup(qname, client->mctx, aname); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - return (result); - } - - rdatalist = NULL; - result = dns_message_gettemprdatalist(client->message, &rdatalist); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - return (result); - } - rdata = NULL; - result = dns_message_gettemprdata(client->message, &rdata); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - dns_message_puttemprdatalist(client->message, &rdatalist); - return (result); - } - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &aname); - dns_message_puttemprdatalist(client->message, &rdatalist); - dns_message_puttemprdata(client->message, &rdata); - return (result); - } - rdatalist->type = dns_rdatatype_cname; - rdatalist->rdclass = client->message->rdclass; - rdatalist->ttl = ttl; - - dns_name_toregion(tname, &r); - rdata->data = r.base; - rdata->length = r.length; - rdata->rdclass = client->message->rdclass; - rdata->type = dns_rdatatype_cname; - - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); - rdataset->trust = trust; - dns_rdataset_setownercase(rdataset, aname); - - query_addrrset(client, &aname, &rdataset, NULL, NULL, - DNS_SECTION_ANSWER); - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, &rdataset); - } - if (aname != NULL) - dns_message_puttempname(client->message, &aname); - - return (ISC_R_SUCCESS); -} - -static bool -get_root_key_sentinel_id(ns_client_t *client, const char *ndata) { - unsigned int v = 0; - int i; - - for (i = 0; i < 5; i++) { - if (ndata[i] < '0' || ndata[i] > '9') { - return (false); - } - v *= 10; - v += ndata[i] - '0'; - } - if (v > 65535U) { - return (false); - } - client->query.root_key_sentinel_keyid = v; - return (true); -} - -/*% - * Find out if the query is for a root key sentinel and if so, record the type - * of root key sentinel query and the key id that is being checked for. - * - * The code is assuming a zero padded decimal field of width 5. - */ -static void -root_key_sentinel_detect(ns_client_t *client) { - const char *ndata = (const char *)client->query.qname->ndata; - - if (client->query.qname->length > 30 && ndata[0] == 29 && - strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0) - { - if (!get_root_key_sentinel_id(client, ndata + 25)) { - return; - } - client->query.root_key_sentinel_is_ta = true; - ns_client_log(client, NS_LOGCATEGORY_TAT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "root-key-sentinel-is-ta query label found"); - } else if (client->query.qname->length > 31 && ndata[0] == 30 && - strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0) - { - if (!get_root_key_sentinel_id(client, ndata + 26)) { - return; - } - client->query.root_key_sentinel_not_ta = true; - ns_client_log(client, NS_LOGCATEGORY_TAT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "root-key-sentinel-not-ta query label found"); - } -} - -/* - * Mark the RRsets as secure. Update the cache (db) to reflect the - * change in trust level. - */ -static void -mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - isc_stdtime_t now; - - rdataset->trust = dns_trust_secure; - sigrdataset->trust = dns_trust_secure; - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Save the updated secure state. Ignore failures. - */ - result = dns_db_findnodeext(db, name, true, &cm, &ci, &node); - if (result != ISC_R_SUCCESS) - return; - - isc_stdtime_get(&now); - dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now, - client->view->acceptexpired); - - (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, - 0, NULL); - (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, - 0, NULL); - dns_db_detachnode(db, &node); -} - -/* - * Find the secure key that corresponds to rrsig. - * Note: 'keyrdataset' maintains state between successive calls, - * there may be multiple keys with the same keyid. - * Return false if we have exhausted all the possible keys. - */ -static bool -get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, - dns_rdataset_t *keyrdataset, dst_key_t **keyp) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - bool secure = false; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (!dns_rdataset_isassociated(keyrdataset)) { - result = dns_db_findnodeext(db, &rrsig->signer, false, - &cm, &ci, &node); - if (result != ISC_R_SUCCESS) - return (false); - - result = dns_db_findrdataset(db, node, NULL, - dns_rdatatype_dnskey, 0, - client->now, keyrdataset, NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - return (false); - - if (keyrdataset->trust != dns_trust_secure) - return (false); - - result = dns_rdataset_first(keyrdataset); - } else - result = dns_rdataset_next(keyrdataset); - - for ( ; result == ISC_R_SUCCESS; - result = dns_rdataset_next(keyrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t b; - - dns_rdataset_current(keyrdataset, &rdata); - isc_buffer_init(&b, rdata.data, rdata.length); - isc_buffer_add(&b, rdata.length); - result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, - client->mctx, keyp); - if (result != ISC_R_SUCCESS) - continue; - if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && - rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && - dst_key_iszonekey(*keyp)) { - secure = true; - break; - } - dst_key_free(keyp); - } - return (secure); -} - -static bool -verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, - dns_rdata_t *rdata, ns_client_t *client) -{ - isc_result_t result; - dns_fixedname_t fixed; - bool ignore = false; - - dns_fixedname_init(&fixed); - -again: - result = dns_dnssec_verify3(name, rdataset, key, ignore, - client->view->maxbits, client->mctx, - rdata, NULL); - if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) { - ignore = true; - goto again; - } - if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) - return (true); - return (false); -} - -/* - * Validate the rdataset if possible with available records. - */ -static bool -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t rrsig; - dst_key_t *key = NULL; - dns_rdataset_t keyrdataset; - - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return (false); - - for (result = dns_rdataset_first(sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(sigrdataset)) { - - dns_rdata_reset(&rdata); - dns_rdataset_current(sigrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rrsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (!dns_resolver_algorithm_supported(client->view->resolver, - name, rrsig.algorithm)) - continue; - if (!dns_name_issubdomain(name, &rrsig.signer)) - continue; - dns_rdataset_init(&keyrdataset); - do { - if (!get_key(client, db, &rrsig, &keyrdataset, &key)) - break; - if (verify(key, name, rdataset, &rdata, client)) { - dst_key_free(&key); - dns_rdataset_disassociate(&keyrdataset); - mark_secure(client, db, name, &rrsig, - rdataset, sigrdataset); - return (true); - } - dst_key_free(&key); - } while (1); - if (dns_rdataset_isassociated(&keyrdataset)) - dns_rdataset_disassociate(&keyrdataset); - } - return (false); -} - -static void -query_addbestns(ns_client_t *client) { - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_name_t *fname, *zfname; - dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; - bool is_zone, use_zone; - isc_buffer_t *dbuf; - isc_result_t result; - dns_dbversion_t *version; - dns_zone_t *zone; - isc_buffer_t b; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addbestns"); - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - is_zone = false; - use_zone = false; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Find the right database. - */ - result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, - &zone, &db, &version, &is_zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - db_find: - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - /* - * Get the RRSIGs if the client requested them or if we may - * need to validate answers from the cache. - */ - if (WANTDNSSEC(client) || !is_zone) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Now look for the zonecut. - */ - if (is_zone) { - result = dns_db_findext(db, client->query.qname, version, - dns_rdatatype_ns, - client->query.dboptions, - client->now, &node, fname, - &cm, &ci, rdataset, sigrdataset); - if (result != DNS_R_DELEGATION) - goto cleanup; - if (USECACHE(client)) { - query_keepname(client, fname, dbuf); - dns_db_detachnode(db, &node); - SAVE(zdb, db); - SAVE(zfname, fname); - SAVE(zrdataset, rdataset); - SAVE(zsigrdataset, sigrdataset); - version = NULL; - dns_db_attach(client->view->cachedb, &db); - is_zone = false; - goto db_find; - } - } else { - result = dns_db_findzonecut(db, client->query.qname, - client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (zfname != NULL && - !dns_name_issubdomain(fname, zfname)) { - /* - * We found a zonecut in the cache, but our - * zone delegation is better. - */ - use_zone = true; - } - } else if (result == ISC_R_NOTFOUND && zfname != NULL) { - /* - * We didn't find anything in the cache, but we - * have a zone delegation, so use it. - */ - use_zone = true; - } else - goto cleanup; - } - - if (use_zone) { - query_releasename(client, &fname); - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - RESTORE(db, zdb); - RESTORE(fname, zfname); - RESTORE(rdataset, zrdataset); - RESTORE(sigrdataset, zsigrdataset); - } - - /* - * Attempt to validate RRsets that are pending or that are glue. - */ - if ((DNS_TRUST_PENDING(rdataset->trust) || - (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) - && !validate(client, db, fname, rdataset, sigrdataset) && - !PENDINGOK(client->query.dboptions)) - goto cleanup; - - if ((DNS_TRUST_GLUE(rdataset->trust) || - (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) && - !validate(client, db, fname, rdataset, sigrdataset) && - SECURE(client) && WANTDNSSEC(client)) - goto cleanup; - - /* - * If the answer is secure only add NS records if they are secure - * when the client may be looking for AD in the response. - */ - if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) && - ((rdataset->trust != dns_trust_secure) || - (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure))) - goto cleanup; - - /* - * If the client doesn't want DNSSEC we can discard the sigrdataset - * now. - */ - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } -} - -static void -fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) { - if (*rdataset == NULL) - *rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(*rdataset)) - dns_rdataset_disassociate(*rdataset); -} - -static void -fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf, - isc_buffer_t *nbuf) -{ - if (*fname == NULL) { - *dbuf = query_getnamebuf(client); - if (*dbuf == NULL) - return; - *fname = query_newname(client, *dbuf, nbuf); - } -} - -static void -query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_name_t *name) -{ - dns_fixedname_t fixed; - dns_name_t *fname = NULL; - dns_name_t *rname; - dns_rdataset_t *rdataset, *sigrdataset; - isc_buffer_t *dbuf, b; - isc_result_t result; - unsigned int count; - - CTRACE(ISC_LOG_DEBUG(3), "query_addds"); - rname = NULL; - rdataset = NULL; - sigrdataset = NULL; - - /* - * We'll need some resources... - */ - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - /* - * Look for the DS record, which may or may not be present. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0, - client->now, rdataset, sigrdataset); - /* - * If we didn't find it, look for an NSEC. - */ - if (result == ISC_R_NOTFOUND) - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec, 0, client->now, - rdataset, sigrdataset); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto addnsec3; - if (!dns_rdataset_isassociated(rdataset) || - !dns_rdataset_isassociated(sigrdataset)) - goto addnsec3; - - /* - * We've already added the NS record, so if the name's not there, - * we have other problems. Use this name rather than calling - * query_addrrset(). - */ - result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rname = NULL; - dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, - &rname); - result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_APPEND(rname->list, rdataset, link); - ISC_LIST_APPEND(rname->list, sigrdataset, link); - rdataset = NULL; - sigrdataset = NULL; - return; - - addnsec3: - if (!dns_db_iszone(db)) - goto cleanup; - /* - * Add the NSEC3 which proves the DS does not exist. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - dns_fixedname_init(&fixed); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - query_findclosestnsec3(name, db, version, client, rdataset, - sigrdataset, fname, true, - dns_fixedname_name(&fixed)); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - /* - * Did we find the closest provable encloser instead? - * If so add the nearest to the closest provable encloser. - */ - if (!dns_name_equal(name, dns_fixedname_name(&fixed))) { - count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1; - dns_name_getlabelsequence(name, - dns_name_countlabels(name) - count, - count, dns_fixedname_name(&fixed)); - fixfname(client, &fname, &dbuf, &b); - fixrdataset(client, &rdataset); - fixrdataset(client, &sigrdataset); - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - query_findclosestnsec3(dns_fixedname_name(&fixed), db, version, - client, rdataset, sigrdataset, fname, - false, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - } - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); -} - -static void -query_addwildcardproof(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t *name, - bool ispositive, bool nodata) -{ - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_fixedname_t wfixed; - dns_name_t *wname; - dns_dbnode_t *node; - unsigned int options; - unsigned int olabels, nlabels, labels; - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec_t nsec; - bool have_wname; - int order; - dns_fixedname_t cfixed; - dns_name_t *cname; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof"); - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - node = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Get the NOQNAME proof then if !ispositive - * get the NOWILDCARD proof. - * - * DNS_DBFIND_NOWILD finds the NSEC records that covers the - * name ignoring any wildcard. From the owner and next names - * of this record you can compute which wildcard (if it exists) - * will match by finding the longest common suffix of the - * owner name and next names with the qname and prefixing that - * with the wildcard label. - * - * e.g. - * Given: - * example SOA - * example NSEC b.example - * b.example A - * b.example NSEC a.d.example - * a.d.example A - * a.d.example NSEC g.f.example - * g.f.example A - * g.f.example NSEC z.i.example - * z.i.example A - * z.i.example NSEC example - * - * QNAME: - * a.example -> example NSEC b.example - * owner common example - * next common example - * wild *.example - * d.b.example -> b.example NSEC a.d.example - * owner common b.example - * next common example - * wild *.b.example - * a.f.example -> a.d.example NSEC g.f.example - * owner common example - * next common f.example - * wild *.f.example - * j.example -> z.i.example NSEC example - * owner common example - * next common example - * wild *.example - */ - options = client->query.dboptions | DNS_DBFIND_NOWILD; - wname = dns_fixedname_initname(&wfixed); - again: - have_wname = false; - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - result = dns_db_findext(db, name, version, dns_rdatatype_nsec, - options, 0, &node, fname, &cm, &ci, - rdataset, sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - if (!dns_rdataset_isassociated(rdataset)) { - /* - * No NSEC proof available, return NSEC3 proofs instead. - */ - cname = dns_fixedname_initname(&cfixed); - /* - * Find the closest encloser. - */ - dns_name_copy(name, cname, NULL); - while (result == DNS_R_NXDOMAIN) { - labels = dns_name_countlabels(cname) - 1; - /* - * Sanity check. - */ - if (labels == 0U) - goto cleanup; - dns_name_split(cname, labels, NULL, cname); - result = dns_db_findext(db, cname, version, - dns_rdatatype_nsec, - options, 0, NULL, fname, - &cm, &ci, NULL, NULL); - } - /* - * Add closest (provable) encloser NSEC3. - */ - query_findclosestnsec3(cname, db, version, client, rdataset, - sigrdataset, fname, true, cname); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - if (!ispositive) - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - /* - * Replace resources which were consumed by query_addrrset. - */ - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - - if (rdataset == NULL) - rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (sigrdataset == NULL) - sigrdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - /* - * Add no qname proof. - */ - labels = dns_name_countlabels(cname) + 1; - if (dns_name_countlabels(name) == labels) - dns_name_copy(name, wname, NULL); - else - dns_name_split(name, labels, NULL, wname); - - query_findclosestnsec3(wname, db, version, client, rdataset, - sigrdataset, fname, false, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - if (ispositive) - goto cleanup; - - /* - * Replace resources which were consumed by query_addrrset. - */ - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - - if (rdataset == NULL) - rdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (sigrdataset == NULL) - sigrdataset = query_newrdataset(client); - else if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - /* - * Add the no wildcard proof. - */ - result = dns_name_concatenate(dns_wildcardname, - cname, wname, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - query_findclosestnsec3(wname, db, version, client, rdataset, - sigrdataset, fname, nodata, NULL); - if (!dns_rdataset_isassociated(rdataset)) - goto cleanup; - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - - goto cleanup; - } else if (result == DNS_R_NXDOMAIN) { - if (!ispositive) - result = dns_rdataset_first(rdataset); - if (result == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - (void)dns_name_fullcompare(name, fname, &order, - &olabels); - (void)dns_name_fullcompare(name, &nsec.next, &order, - &nlabels); - /* - * Check for a pathological condition created when - * serving some malformed signed zones and bail out. - */ - if (dns_name_countlabels(name) == nlabels) - goto cleanup; - - if (olabels > nlabels) - dns_name_split(name, olabels, NULL, wname); - else - dns_name_split(name, nlabels, NULL, wname); - result = dns_name_concatenate(dns_wildcardname, - wname, wname, NULL); - if (result == ISC_R_SUCCESS) - have_wname = true; - dns_rdata_freestruct(&nsec); - } - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (have_wname) { - ispositive = true; /* prevent loop */ - if (!dns_name_equal(name, wname)) { - name = wname; - goto again; - } - } - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); -} - -static void -query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp) -{ - dns_name_t *name; - dns_rdataset_t *sigrdataset; - dns_rdata_t sigrdata; - dns_rdata_rrsig_t sig; - unsigned int labels; - isc_buffer_t *dbuf, b; - dns_name_t *fname; - isc_result_t result; - - name = *namep; - if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) { - query_addrrset(client, namep, rdatasetp, sigrdatasetp, - NULL, DNS_SECTION_AUTHORITY); - return; - } - - if (sigrdatasetp == NULL) - return; - - sigrdataset = *sigrdatasetp; - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return; - result = dns_rdataset_first(sigrdataset); - if (result != ISC_R_SUCCESS) - return; - dns_rdata_init(&sigrdata); - dns_rdataset_current(sigrdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &sig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - labels = dns_name_countlabels(name); - if ((unsigned int)sig.labels + 1 >= labels) - return; - - /* XXX */ - query_addwildcardproof(client, db, version, client->query.qname, - true, false); - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - return; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - return; - dns_name_split(name, sig.labels + 1, NULL, fname); - /* This will succeed, since we've stripped labels. */ - RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, - NULL) == ISC_R_SUCCESS); - query_addrrset(client, &fname, rdatasetp, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); -} - -static void -free_devent(ns_client_t *client, isc_event_t **eventp, - dns_fetchevent_t **deventp) -{ - dns_fetchevent_t *devent = *deventp; - - REQUIRE((void*)(*eventp) == (void *)(*deventp)); - - if (devent->fetch != NULL) - dns_resolver_destroyfetch(&devent->fetch); - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - if (devent->rdataset != NULL) - query_putrdataset(client, &devent->rdataset); - if (devent->sigrdataset != NULL) - query_putrdataset(client, &devent->sigrdataset); - /* - * If the two pointers are the same then leave the setting of - * (*deventp) to NULL to isc_event_free. - */ - if ((void *)eventp != (void *)deventp) - (*deventp) = NULL; - isc_event_free(eventp); -} - -/*% - * Check the configured trust anchors for a root zone trust anchor - * with a key id that matches client->query.root_key_sentinel_keyid. - * - * Return true when found, otherwise return false. - */ -static bool -has_ta(ns_client_t *client) { - dns_keytable_t *keytable = NULL; - dns_keynode_t *keynode = NULL; - isc_result_t result; - - result = dns_view_getsecroots(client->view, &keytable); - if (result != ISC_R_SUCCESS) { - return (false); - } - - result = dns_keytable_find(keytable, dns_rootname, &keynode); - while (result == ISC_R_SUCCESS) { - dns_keynode_t *nextnode = NULL; - dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode)); - if (keyid == client->query.root_key_sentinel_keyid) { - dns_keytable_detachkeynode(keytable, &keynode); - dns_keytable_detach(&keytable); - return (true); - } - result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); - dns_keytable_detachkeynode(keytable, &keynode); - keynode = nextnode; - } - dns_keytable_detach(&keytable); - - return (false); -} - -/*% - * Check if a root key sentinel SERVFAIL should be returned. - */ -static bool -root_key_sentinel_return_servfail(ns_client_t *client, bool is_zone, - dns_rdataset_t *rdataset, isc_result_t result) -{ - /* - * Are we looking at a "root-key-sentinel" query? - */ - if (!client->query.root_key_sentinel_is_ta && - !client->query.root_key_sentinel_not_ta) - { - return (false); - } - - /* - * We only care about the query if 'result' indicates we have a cached - * answer. - */ - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_CNAME: - case DNS_R_DNAME: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - break; - default: - return (false); - } - - /* - * Do we meet the specified conditions to return SERVFAIL? - */ - if (!is_zone && rdataset->trust == dns_trust_secure && - ((client->query.root_key_sentinel_is_ta && !has_ta(client)) || - (client->query.root_key_sentinel_not_ta && has_ta(client)))) - { - return (true); - } - - /* - * As special processing may only be triggered by the original QNAME, - * disable it after following a CNAME/DNAME. - */ - client->query.root_key_sentinel_is_ta = false; - client->query.root_key_sentinel_not_ta = false; - - return (false); -} - -static void -query_resume(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - dns_fetch_t *fetch = NULL; - ns_client_t *client; - bool fetch_canceled, client_shuttingdown; - isc_result_t result; - isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_ERRORS; - int errorloglevel; - - /* - * Resume a query after recursion. - */ - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - client = devent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(RECURSING(client)); - - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - /* - * This is the fetch we've been waiting for. - */ - INSIST(devent->fetch == client->query.fetch); - client->query.fetch = NULL; - fetch_canceled = false; - /* - * Update client->now. - */ - isc_stdtime_get(&client->now); - } else { - /* - * This is a fetch completion event for a canceled fetch. - * Clean up and don't resume the find. - */ - fetch_canceled = true; - } - UNLOCK(&client->query.fetchlock); - INSIST(client->query.fetch == NULL); - - client->query.attributes &= ~NS_QUERYATTR_RECURSING; - SAVE(fetch, devent->fetch); - - /* - * If this client is shutting down, or this transaction - * has timed out, do not resume the find. - */ - client_shuttingdown = ns_client_shuttingdown(client); - if (fetch_canceled || client_shuttingdown) { - free_devent(client, &event, &devent); - if (fetch_canceled) { - CTRACE(ISC_LOG_ERROR, "fetch cancelled"); - query_error(client, DNS_R_SERVFAIL, __LINE__); - } else - query_next(client, ISC_R_CANCELED); - /* - * This may destroy the client. - */ - ns_client_detach(&client); - } else { - result = query_find(client, devent, 0); - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_SERVFAIL) - errorloglevel = ISC_LOG_DEBUG(2); - else - errorloglevel = ISC_LOG_DEBUG(4); - if (isc_log_wouldlog(ns_g_lctx, errorloglevel)) { - dns_resolver_logfetch(fetch, ns_g_lctx, - logcategory, - NS_LOGMODULE_QUERY, - errorloglevel, false); - } - } - } - - dns_resolver_destroyfetch(&fetch); -} - -static void -prefetch_done(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - ns_client_t *client; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - client = devent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - LOCK(&client->query.fetchlock); - if (client->query.prefetch != NULL) { - INSIST(devent->fetch == client->query.prefetch); - client->query.prefetch = NULL; - } - UNLOCK(&client->query.fetchlock); - free_devent(client, &event, &devent); - ns_client_detach(&client); -} - -static void -query_prefetch(ns_client_t *client, dns_name_t *qname, - dns_rdataset_t *rdataset) -{ - isc_result_t result; - isc_sockaddr_t *peeraddr; - dns_rdataset_t *tmprdataset; - ns_client_t *dummy = NULL; - unsigned int options; - - if (client->query.prefetch != NULL || - client->view->prefetch_trigger == 0U || - rdataset->ttl > client->view->prefetch_trigger || - (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) - return; - - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client)) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - return; - } - - tmprdataset = query_newrdataset(client); - if (tmprdataset == NULL) - return; - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - ns_client_attach(client, &dummy); - options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH; - result = dns_resolver_createfetch3(client->view->resolver, - qname, rdataset->type, NULL, NULL, - NULL, peeraddr, client->message->id, - options, 0, NULL, client->task, - prefetch_done, client, - tmprdataset, NULL, - &client->query.prefetch); - if (result != ISC_R_SUCCESS) { - query_putrdataset(client, &tmprdataset); - ns_client_detach(&dummy); - } - dns_rdataset_clearprefetch(rdataset); -} - - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -static void -log_quota(ns_client_t *client, _Atomic(isc_stdtime_t) *last, isc_stdtime_t now, - const char *fmt, const char *tail) -#else -static void -log_quota(ns_client_t *client, isc_stdtime_t *last, isc_stdtime_t now, - const char *fmt, const char *tail) -#endif -{ - isc_stdtime_t old = last_load(last); - if (now > old || (old + 1) > now) { - if (last_cmpxchg(last, &old, now)) { - LOCK(&ns_g_server->recursionquota.lock); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, fmt, - ns_g_server->recursionquota.used, - ns_g_server->recursionquota.soft, - ns_g_server->recursionquota.max, - tail); - UNLOCK(&ns_g_server->recursionquota.lock); - } - } -} - -/*% - * Check whether the recursion parameters in 'param' match the current query's - * recursion parameters provided in 'qtype', 'qname', and 'qdomain'. - */ -static bool -recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - REQUIRE(param != NULL); - - return (param->qtype == qtype && - param->qname != NULL && qname != NULL && - param->qdomain != NULL && qdomain != NULL && - dns_name_equal(param->qname, qname) && - dns_name_equal(param->qdomain, qdomain)); -} - -/*% - * Update 'param' with current query's recursion parameters provided in - * 'qtype', 'qname', and 'qdomain'. - */ -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - isc_result_t result; - - REQUIRE(param != NULL); - - param->qtype = qtype; - - if (qname == NULL) { - param->qname = NULL; - } else { - param->qname = dns_fixedname_initname(¶m->fqname); - result = dns_name_copy(qname, param->qname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - if (qdomain == NULL) { - param->qdomain = NULL; - } else { - param->qdomain = dns_fixedname_initname(¶m->fqdomain); - result = dns_name_copy(qdomain, param->qdomain, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } -} - -static isc_result_t -query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, - dns_name_t *qdomain, dns_rdataset_t *nameservers, - bool resuming) -{ - isc_result_t result; - dns_rdataset_t *rdataset, *sigrdataset; - isc_sockaddr_t *peeraddr; - - /* - * Check recursion parameters from the previous query to see if they - * match. If not, update recursion parameters and proceed. - */ - if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "recursion loop detected"); - return (ISC_R_FAILURE); - } - - recparam_update(&client->query.recparam, qtype, qname, qdomain); - - if (!resuming) - inc_stats(client, dns_nsstatscounter_recursion); - - /* - * We are about to recurse, which means that this client will - * be unavailable for serving new requests for an indeterminate - * amount of time. If this client is currently responsible - * for handling incoming queries, set up a new client - * object to handle them while we are waiting for a - * response. There is no need to replace TCP clients - * because those have already been replaced when the - * connection was accepted (if allowed by the TCP quota). - */ - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - - if (result == ISC_R_SOFTQUOTA) { -#ifdef ISC_PLATFORM_HAVESTDATOMIC - static _Atomic(isc_stdtime_t) last = 0; -#else - static isc_stdtime_t last = 0; -#endif - isc_stdtime_t now; - isc_stdtime_get(&now); - log_quota(client, &last, now, - "recursive-clients soft limit exceeded " - "(%d/%d/%d) %s", "aborting oldest query"); - ns_client_killoldestquery(client); - result = ISC_R_SUCCESS; - } else if (result == ISC_R_QUOTA) { -#ifdef ISC_PLATFORM_HAVESTDATOMIC - static _Atomic(isc_stdtime_t) last = 0; -#else - static isc_stdtime_t last = 0; -#endif - isc_stdtime_t now; - isc_stdtime_get(&now); - log_quota(client, &last, now, - "no more recursive clients (%d/%d/%d): %s", - isc_result_totext(result)); - ns_client_killoldestquery(client); - } - if (result == ISC_R_SUCCESS && !client->mortal && - !TCP(client)) { - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "ns_client_replace() failed: %s", - isc_result_totext(result)); - isc_quota_detach(&client->recursionquota); - isc_stats_decrement(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - } - if (result != ISC_R_SUCCESS) - return (result); - ns_client_recursing(client); - } - - /* - * Invoke the resolver. - */ - REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); - REQUIRE(client->query.fetch == NULL); - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - return (ISC_R_NOMEMORY); - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - query_putrdataset(client, &rdataset); - return (ISC_R_NOMEMORY); - } - } else - sigrdataset = NULL; - - if (client->query.timerset == false) - ns_client_settimeout(client, 60); - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - result = dns_resolver_createfetch3(client->view->resolver, - qname, qtype, qdomain, nameservers, - NULL, peeraddr, client->message->id, - client->query.fetchoptions, 0, NULL, - client->task, query_resume, client, - rdataset, sigrdataset, - &client->query.fetch); - - if (result == ISC_R_SUCCESS) { - /* - * Record that we're waiting for an event. A client which - * is shutting down will not be destroyed until all the - * events have been received. - */ - } else { - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - } - - return (result); -} - -static inline void -rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep, - dns_rdataset_t **rdatasetp) -{ - if (nodep != NULL && *nodep != NULL) { - REQUIRE(dbp != NULL && *dbp != NULL); - dns_db_detachnode(*dbp, nodep); - } - if (dbp != NULL && *dbp != NULL) - dns_db_detach(dbp); - if (zonep != NULL && *zonep != NULL) - dns_zone_detach(zonep); - if (rdatasetp != NULL && *rdatasetp != NULL && - dns_rdataset_isassociated(*rdatasetp)) - dns_rdataset_disassociate(*rdatasetp); -} - -static inline void -rpz_match_clear(dns_rpz_st_t *st) { - rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); - st->m.version = NULL; -} - -static inline isc_result_t -rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) { - REQUIRE(rdatasetp != NULL); - - CTRACE(ISC_LOG_DEBUG(3), "rpz_ready"); - - if (*rdatasetp == NULL) { - *rdatasetp = query_newrdataset(client); - if (*rdatasetp == NULL) { - CTRACE(ISC_LOG_ERROR, - "rpz_ready: query_newrdataset failed"); - return (DNS_R_SERVFAIL); - } - } else if (dns_rdataset_isassociated(*rdatasetp)) { - dns_rdataset_disassociate(*rdatasetp); - } - return (ISC_R_SUCCESS); -} - -static void -rpz_st_clear(ns_client_t *client) { - dns_rpz_st_t *st = client->query.rpz_st; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_st_clear"); - - if (st->m.rdataset != NULL) - query_putrdataset(client, &st->m.rdataset); - rpz_match_clear(st); - - rpz_clean(NULL, &st->r.db, NULL, NULL); - if (st->r.ns_rdataset != NULL) - query_putrdataset(client, &st->r.ns_rdataset); - if (st->r.r_rdataset != NULL) - query_putrdataset(client, &st->r.r_rdataset); - - rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL); - if (st->q.rdataset != NULL) - query_putrdataset(client, &st->q.rdataset); - if (st->q.sigrdataset != NULL) - query_putrdataset(client, &st->q.sigrdataset); - st->state = 0; - st->m.type = DNS_RPZ_TYPE_BAD; - st->m.policy = DNS_RPZ_POLICY_MISS; -} - -static dns_rpz_zbits_t -rpz_get_zbits(ns_client_t *client, - dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type) -{ - dns_rpz_st_t *st; - dns_rpz_zbits_t zbits; - - REQUIRE(client != NULL); - REQUIRE(client->query.rpz_st != NULL); - - st = client->query.rpz_st; - - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - zbits = st->have.client_ip; - break; - case DNS_RPZ_TYPE_QNAME: - zbits = st->have.qname; - break; - case DNS_RPZ_TYPE_IP: - if (ip_type == dns_rdatatype_a) { - zbits = st->have.ipv4; - } else if (ip_type == dns_rdatatype_aaaa) { - zbits = st->have.ipv6; - } else { - zbits = st->have.ip; - } - break; - case DNS_RPZ_TYPE_NSDNAME: - zbits = st->have.nsdname; - break; - case DNS_RPZ_TYPE_NSIP: - if (ip_type == dns_rdatatype_a) { - zbits = st->have.nsipv4; - } else if (ip_type == dns_rdatatype_aaaa) { - zbits = st->have.nsipv6; - } else { - zbits = st->have.nsip; - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - break; - } - - /* - * Choose - * the earliest configured policy zone (rpz->num) - * QNAME over IP over NSDNAME over NSIP (rpz_type) - * the smallest name, - * the longest IP address prefix, - * the lexically smallest address. - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.type >= rpz_type) { - zbits &= DNS_RPZ_ZMASK(st->m.rpz->num); - } else{ - zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1; - } - } - - /* - * If the client wants recursion, allow only compatible policies. - */ - if (!RECURSIONOK(client)) - zbits &= st->popt.no_rd_ok; - - return (zbits); -} - -static void -query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) { - isc_result_t result; - isc_sockaddr_t *peeraddr; - dns_rdataset_t *tmprdataset; - ns_client_t *dummy = NULL; - unsigned int options; - - if (client->query.prefetch != NULL) - return; - - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - isc_stats_increment(ns_g_server->nsstats, - dns_nsstatscounter_recursclients); - } - if (result == ISC_R_SUCCESS && !client->mortal && !TCP(client)) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) - return; - } - - tmprdataset = query_newrdataset(client); - if (tmprdataset == NULL) - return; - if (!TCP(client)) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - ns_client_attach(client, &dummy); - options = client->query.fetchoptions; - result = dns_resolver_createfetch3(client->view->resolver, qname, type, - NULL, NULL, NULL, peeraddr, - client->message->id, options, 0, - NULL, client->task, prefetch_done, - client, tmprdataset, NULL, - &client->query.prefetch); - if (result != ISC_R_SUCCESS) { - query_putrdataset(client, &tmprdataset); - ns_client_detach(&dummy); - } -} - -/* - * Get an NS, A, or AAAA rrset related to the response for the client - * to check the contents of that rrset for hits by eligible policy zones. - */ -static isc_result_t -rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, - dns_rpz_type_t rpz_type, dns_db_t **dbp, - dns_dbversion_t *version, dns_rdataset_t **rdatasetp, - bool resuming) -{ - dns_rpz_st_t *st; - bool is_zone; - dns_dbnode_t *node; - dns_fixedname_t fixed; - dns_name_t *found; - isc_result_t result; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find"); - - st = client->query.rpz_st; - if ((st->state & DNS_RPZ_RECURSING) != 0) { - INSIST(st->r.r_type == type); - INSIST(dns_name_equal(name, st->r_name)); - INSIST(*rdatasetp == NULL || - !dns_rdataset_isassociated(*rdatasetp)); - st->state &= ~DNS_RPZ_RECURSING; - RESTORE(*dbp, st->r.db); - if (*rdatasetp != NULL) - query_putrdataset(client, rdatasetp); - RESTORE(*rdatasetp, st->r.r_rdataset); - result = st->r.r_result; - if (result == DNS_R_DELEGATION) { - CTRACE(ISC_LOG_ERROR, "RPZ recursing"); - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " rpz_rrset_find(1)", result); - st->m.policy = DNS_RPZ_POLICY_ERROR; - result = DNS_R_SERVFAIL; - } - return (result); - } - - result = rpz_ready(client, rdatasetp); - if (result != ISC_R_SUCCESS) { - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (result); - } - if (*dbp != NULL) { - is_zone = false; - } else { - dns_zone_t *zone; - - version = NULL; - zone = NULL; - result = query_getdb(client, name, type, 0, &zone, dbp, - &version, &is_zone); - if (result != ISC_R_SUCCESS) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " rpz_rrset_find(2)", result); - st->m.policy = DNS_RPZ_POLICY_ERROR; - if (zone != NULL) - dns_zone_detach(&zone); - return (result); - } - if (zone != NULL) - dns_zone_detach(&zone); - } - - node = NULL; - found = dns_fixedname_initname(&fixed); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK, - client->now, &node, found, - &cm, &ci, *rdatasetp, NULL); - if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { - /* - * Try the cache if we're authoritative for an - * ancestor but not the domain itself. - */ - rpz_clean(NULL, dbp, &node, rdatasetp); - version = NULL; - dns_db_attach(client->view->cachedb, dbp); - result = dns_db_findext(*dbp, name, version, type, - 0, client->now, &node, found, - &cm, &ci, *rdatasetp, NULL); - } - rpz_clean(NULL, dbp, &node, NULL); - if (result == DNS_R_DELEGATION) { - rpz_clean(NULL, NULL, NULL, rdatasetp); - /* - * Recurse for NS rrset or A or AAAA rrset for an NS. - * Do not recurse for addresses for the query name. - */ - if (rpz_type == DNS_RPZ_TYPE_IP) { - result = DNS_R_NXRRSET; - } else if (!client->view->rpzs->p.nsip_wait_recurse) { - query_rpzfetch(client, name, type); - result = DNS_R_NXRRSET; - } else { - dns_name_copy(name, st->r_name, NULL); - result = query_recurse(client, type, st->r_name, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - st->state |= DNS_RPZ_RECURSING; - result = DNS_R_DELEGATION; - } - } - } - return (result); -} - -/* - * Compute a policy owner name, p_name, in a policy zone given the needed - * policy type and the trigger name. - */ -static isc_result_t -rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, - dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_name_t *trig_name) -{ - dns_offsets_t prefix_offsets; - dns_name_t prefix, *suffix; - unsigned int first, labels; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_get_p_name"); - - /* - * The policy owner name consists of a suffix depending on the type - * and policy zone and a prefix that is the longest possible string - * from the trigger name that keesp the resulting policy owner name - * from being too long. - */ - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - suffix = &rpz->client_ip; - break; - case DNS_RPZ_TYPE_QNAME: - suffix = &rpz->origin; - break; - case DNS_RPZ_TYPE_IP: - suffix = &rpz->ip; - break; - case DNS_RPZ_TYPE_NSDNAME: - suffix = &rpz->nsdname; - break; - case DNS_RPZ_TYPE_NSIP: - suffix = &rpz->nsip; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Start with relative version of the full trigger name, - * and trim enough allow the addition of the suffix. - */ - dns_name_init(&prefix, prefix_offsets); - labels = dns_name_countlabels(trig_name); - first = 0; - for (;;) { - dns_name_getlabelsequence(trig_name, first, labels-first-1, - &prefix); - result = dns_name_concatenate(&prefix, suffix, p_name, NULL); - if (result == ISC_R_SUCCESS) - break; - INSIST(result == DNS_R_NAMETOOLONG); - /* - * Trim the trigger name until the combination is not too long. - */ - if (labels-first < 2) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix, - rpz_type, " concatenate()", result); - return (ISC_R_FAILURE); - } - /* - * Complain once about trimming the trigger name. - */ - if (first == 0) { - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix, - rpz_type, " concatenate()", result); - } - ++first; - } - return (ISC_R_SUCCESS); -} - -/* - * Look in policy zone rpz for a policy of rpz_type by p_name. - * The self-name (usually the client qname or an NS name) is compared with - * the target of a CNAME policy for the old style passthru encoding. - * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep, - * *rdatasetp, and *policyp. - * The target DNS type, qtype, chooses the best rdataset for *rdatasetp. - * The caller must decide if the found policy is most suitable, including - * better than a previously found policy. - * If it is best, the caller records it in client->query.rpz_st->m. - */ -static isc_result_t -rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype, - dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, - dns_rpz_policy_t *policyp) -{ - dns_fixedname_t foundf; - dns_name_t *found; - isc_result_t result; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - bool found_a = false; - - REQUIRE(nodep != NULL); - - CTRACE(ISC_LOG_DEBUG(3), "rpz_find_p"); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Try to find either a CNAME or the type of record demanded by the - * request from the policy zone. - */ - rpz_clean(zonep, dbp, nodep, rdatasetp); - result = rpz_ready(client, rdatasetp); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, "rpz_ready() failed"); - return (DNS_R_SERVFAIL); - } - *versionp = NULL; - result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp); - if (result != ISC_R_SUCCESS) - return (DNS_R_NXDOMAIN); - found = dns_fixedname_initname(&foundf); - - result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0, - client->now, nodep, found, &cm, &ci, - *rdatasetp, NULL); - /* - * Choose the best rdataset if we found something. - */ - if (result == ISC_R_SUCCESS) { - dns_rdatasetiter_t *rdsiter; - - rdsiter = NULL; - result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0, - &rdsiter); - if (result != ISC_R_SUCCESS) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, - rpz_type, " allrdatasets()", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: allrdatasets failed"); - return (DNS_R_SERVFAIL); - } - if (qtype == dns_rdatatype_aaaa && - !ISC_LIST_EMPTY(client->view->dns64)) { - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, *rdatasetp); - if ((*rdatasetp)->type == dns_rdatatype_a) { - found_a = true; - } - dns_rdataset_disassociate(*rdatasetp); - } - } - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, *rdatasetp); - if ((*rdatasetp)->type == dns_rdatatype_cname || - (*rdatasetp)->type == qtype) - break; - dns_rdataset_disassociate(*rdatasetp); - } - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_SUCCESS) { - if (result != ISC_R_NOMORE) { - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, - p_name, rpz_type, - " rdatasetiter", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: rdatasetiter failed"); - return (DNS_R_SERVFAIL); - } - /* - * Ask again to get the right DNS_R_DNAME/NXRRSET/... - * result if there is neither a CNAME nor target type. - */ - if (dns_rdataset_isassociated(*rdatasetp)) - dns_rdataset_disassociate(*rdatasetp); - dns_db_detachnode(*dbp, nodep); - - if (qtype == dns_rdatatype_rrsig || - qtype == dns_rdatatype_sig) - result = DNS_R_NXRRSET; - else - result = dns_db_findext(*dbp, p_name, *versionp, - qtype, 0, client->now, - nodep, found, &cm, &ci, - *rdatasetp, NULL); - } - } - switch (result) { - case ISC_R_SUCCESS: - if ((*rdatasetp)->type != dns_rdatatype_cname) { - *policyp = DNS_RPZ_POLICY_RECORD; - } else { - *policyp = dns_rpz_decode_cname(rpz, *rdatasetp, - self_name); - if ((*policyp == DNS_RPZ_POLICY_RECORD || - *policyp == DNS_RPZ_POLICY_WILDCNAME) && - qtype != dns_rdatatype_cname && - qtype != dns_rdatatype_any) - return (DNS_R_CNAME); - } - return (ISC_R_SUCCESS); - case DNS_R_NXRRSET: - if (found_a) { - *policyp = DNS_RPZ_POLICY_DNS64; - } else { - *policyp = DNS_RPZ_POLICY_NODATA; - } - return (result); - case DNS_R_DNAME: - /* - * DNAME policy RRs have very few if any uses that are not - * better served with simple wildcards. Making them work would - * require complications to get the number of labels matched - * in the name or the found name to the main DNS_R_DNAME case - * in query_find(). The domain also does not appear in the - * summary database at the right level, so this happens only - * with a single policy zone when we have no summary database. - * Treat it as a miss. - */ - case DNS_R_NXDOMAIN: - case DNS_R_EMPTYNAME: - return (DNS_R_NXDOMAIN); - default: - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, - "", result); - CTRACE(ISC_LOG_ERROR, - "rpz_find_p: unexpected result"); - return (DNS_R_SERVFAIL); - } -} - -static void -rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, - dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix, - isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, - dns_dbversion_t *version) -{ - dns_rdataset_t *trdataset = NULL; - - rpz_match_clear(st); - st->m.rpz = rpz; - st->m.type = rpz_type; - st->m.policy = policy; - dns_name_copy(p_name, st->p_name, NULL); - st->m.prefix = prefix; - st->m.result = result; - SAVE(st->m.zone, *zonep); - SAVE(st->m.db, *dbp); - SAVE(st->m.node, *nodep); - if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) { - /* - * Save the replacement rdataset from the policy - * and make the previous replacement rdataset scratch. - */ - SAVE(trdataset, st->m.rdataset); - SAVE(st->m.rdataset, *rdatasetp); - SAVE(*rdatasetp, trdataset); - st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl); - } else { - st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl); - } - SAVE(st->m.version, version); -} - -/* - * Check this address in every eligible policy zone. - */ -static isc_result_t -rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_st_t *st; - dns_rpz_zone_t *rpz; - dns_rpz_prefix_t prefix; - dns_rpz_num_t rpz_num; - dns_fixedname_t ip_namef, p_namef; - dns_name_t *ip_name, *p_name; - dns_zone_t *p_zone; - dns_db_t *p_db; - dns_dbversion_t *p_version; - dns_dbnode_t *p_node; - dns_rpz_policy_t policy; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip"); - - ip_name = dns_fixedname_initname(&ip_namef); - - p_zone = NULL; - p_db = NULL; - p_node = NULL; - - rpzs = client->view->rpzs; - st = client->query.rpz_st; - while (zbits != 0) { - rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr, - ip_name, &prefix); - if (rpz_num == DNS_RPZ_INVALID_NUM) - break; - zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1); - - /* - * Do not try applying policy zones that cannot replace a - * previously found policy zone. - * Stop looking if the next best choice cannot - * replace what we already have. - */ - rpz = rpzs->zones[rpz_num]; - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.rpz->num < rpz->num) - break; - if (st->m.rpz->num == rpz->num && - (st->m.type < rpz_type || - st->m.prefix > prefix)) - break; - } - - /* - * Get the policy for a prefix at least as long - * as the prefix of the entry we had before. - */ - p_name = dns_fixedname_initname(&p_namef); - result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name); - if (result != ISC_R_SUCCESS) - continue; - result = rpz_find_p(client, ip_name, qtype, - p_name, rpz, rpz_type, - &p_zone, &p_db, &p_version, &p_node, - p_rdatasetp, &policy); - switch (result) { - case DNS_R_NXDOMAIN: - /* - * Continue after a policy record that is missing - * contrary to the summary data. The summary - * data can out of date during races with and among - * policy zone updates. - */ - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_ip: mismatched summary data; " - "continuing"); - continue; - case DNS_R_SERVFAIL: - rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (DNS_R_SERVFAIL); - default: - /* - * Forget this policy if it is not preferable - * to the previously found policy. - * If this policy is not good, then stop looking - * because none of the later policy zones would work. - * - * With more than one applicable policy, prefer - * the earliest configured policy, - * client-IP over QNAME over IP over NSDNAME over NSIP, - * the longest prefix - * the lexically smallest address. - * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num. - * We can compare new and current p_name because - * both are of the same type and in the same zone. - * The tests above eliminate other reasons to - * reject this policy. If this policy can't work, - * then neither can later zones. - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS && - rpz->num == st->m.rpz->num && - (st->m.type == rpz_type && - st->m.prefix == prefix && - 0 > dns_name_rdatacompare(st->p_name, p_name))) - break; - - /* - * Stop checking after saving an enabled hit in this - * policy zone. The radix tree in the policy zone - * ensures that we found the longest match. - */ - if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { - CTRACE(ISC_LOG_DEBUG(3), - "rpz_rewrite_ip: rpz_save_p"); - rpz_save_p(st, rpz, rpz_type, - policy, p_name, prefix, result, - &p_zone, &p_db, &p_node, - p_rdatasetp, p_version); - break; - } - - /* - * Log DNS_RPZ_POLICY_DISABLED zones - * and try the next eligible policy zone. - */ - rpz_log_rewrite(client, true, policy, rpz_type, - p_zone, p_name, NULL, rpz_num); - } - } - - rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); - return (ISC_R_SUCCESS); -} - -/* - * Check the IP addresses in the A or AAAA rrsets for name against - * all eligible rpz_type (IP or NSIP) response policy rewrite rules. - */ -static isc_result_t -rpz_rewrite_ip_rrset(ns_client_t *client, - dns_name_t *name, dns_rdatatype_t qtype, - dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type, - dns_db_t **ip_dbp, dns_dbversion_t *ip_version, - dns_rdataset_t **ip_rdatasetp, - dns_rdataset_t **p_rdatasetp, bool resuming) -{ - dns_rpz_zbits_t zbits; - isc_netaddr_t netaddr; - struct in_addr ina; - struct in6_addr in6a; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrset"); - - zbits = rpz_get_zbits(client, ip_type, rpz_type); - if (zbits == 0) - return (ISC_R_SUCCESS); - - /* - * Get the A or AAAA rdataset. - */ - result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp, - ip_version, ip_rdatasetp, resuming); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_GLUE: - case DNS_R_ZONECUT: - break; - case DNS_R_EMPTYNAME: - case DNS_R_EMPTYWILD: - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - case ISC_R_NOTFOUND: - return (ISC_R_SUCCESS); - case DNS_R_DELEGATION: - case DNS_R_DUPLICATE: - case DNS_R_DROP: - return (result); - case DNS_R_CNAME: - case DNS_R_DNAME: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type, - " NS address rewrite rrset", result); - return (ISC_R_SUCCESS); - default: - if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { - client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR; - rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, - rpz_type, " NS address rewrite rrset", - result); - } - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_ip_rrset: unexpected result"); - return (DNS_R_SERVFAIL); - } - - /* - * Check all of the IP addresses in the rdataset. - */ - for (result = dns_rdataset_first(*ip_rdatasetp); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(*ip_rdatasetp)) { - - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(*ip_rdatasetp, &rdata); - switch (rdata.type) { - case dns_rdatatype_a: - INSIST(rdata.length == 4); - memmove(&ina.s_addr, rdata.data, 4); - isc_netaddr_fromin(&netaddr, &ina); - break; - case dns_rdatatype_aaaa: - INSIST(rdata.length == 16); - memmove(in6a.s6_addr, rdata.data, 16); - isc_netaddr_fromin6(&netaddr, &in6a); - break; - default: - continue; - } - - result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type, - zbits, p_rdatasetp); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (ISC_R_SUCCESS); -} - -/* - * Look for IP addresses in A and AAAA rdatasets - * that trigger all eligible IP or NSIP policy rules. - */ -static isc_result_t -rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rdataset_t **ip_rdatasetp, bool resuming) -{ - dns_rpz_st_t *st; - dns_dbversion_t *ip_version; - dns_db_t *ip_db; - dns_rdataset_t *p_rdataset; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrsets"); - - st = client->query.rpz_st; - ip_version = NULL; - ip_db = NULL; - p_rdataset = NULL; - if ((st->state & DNS_RPZ_DONE_IPv4) == 0 && - (qtype == dns_rdatatype_a || - qtype == dns_rdatatype_any || - rpz_type == DNS_RPZ_TYPE_NSIP)) { - /* - * Rewrite based on an IPv4 address that will appear - * in the ANSWER section or if we are checking IP addresses. - */ - result = rpz_rewrite_ip_rrset(client, name, qtype, - rpz_type, dns_rdatatype_a, - &ip_db, ip_version, ip_rdatasetp, - &p_rdataset, resuming); - if (result == ISC_R_SUCCESS) - st->state |= DNS_RPZ_DONE_IPv4; - } else { - result = ISC_R_SUCCESS; - } - if (result == ISC_R_SUCCESS && - (qtype == dns_rdatatype_aaaa || - qtype == dns_rdatatype_any || - rpz_type == DNS_RPZ_TYPE_NSIP)) { - /* - * Rewrite based on IPv6 addresses that will appear - * in the ANSWER section or if we are checking IP addresses. - */ - result = rpz_rewrite_ip_rrset(client, name, qtype, - rpz_type, dns_rdatatype_aaaa, - &ip_db, ip_version, ip_rdatasetp, - &p_rdataset, resuming); - } - if (ip_db != NULL) - dns_db_detach(&ip_db); - query_putrdataset(client, &p_rdataset); - return (result); -} - -/* - * Try to rewrite a request for a qtype rdataset based on the trigger name - * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME). - * Record the results including the replacement rdataset if any - * in client->query.rpz_st. - * *rdatasetp is a scratch rdataset. - */ -static isc_result_t -rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name, - dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t allowed_zbits, dns_rdataset_t **rdatasetp) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_zone_t *rpz; - dns_rpz_st_t *st; - dns_fixedname_t p_namef; - dns_name_t *p_name; - dns_rpz_zbits_t zbits; - dns_rpz_num_t rpz_num; - dns_zone_t *p_zone; - dns_db_t *p_db; - dns_dbversion_t *p_version; - dns_dbnode_t *p_node; - dns_rpz_policy_t policy; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name"); - - zbits = rpz_get_zbits(client, qtype, rpz_type); - zbits &= allowed_zbits; - if (zbits == 0) - return (ISC_R_SUCCESS); - - rpzs = client->view->rpzs; - - /* - * Use the summary database to find the bit mask of policy zones - * with policies for this trigger name. We do this even if there - * is only one eligible policy zone so that wildcard triggers - * are matched correctly, and not into their parent. - */ - zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name); - if (zbits == 0) - return (ISC_R_SUCCESS); - - p_name = dns_fixedname_initname(&p_namef); - - p_zone = NULL; - p_db = NULL; - p_node = NULL; - - st = client->query.rpz_st; - - /* - * Check the trigger name in every policy zone that the summary data - * says has a hit for the trigger name. - * Most of the time there are no eligible zones and the summary data - * keeps us from getting this far. - * We check the most eligible zone first and so usually check only - * one policy zone. - */ - for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) { - if ((zbits & 1) == 0) - continue; - - /* - * Do not check policy zones that cannot replace a previously - * found policy. - */ - rpz = rpzs->zones[rpz_num]; - if (st->m.policy != DNS_RPZ_POLICY_MISS) { - if (st->m.rpz->num < rpz->num) - break; - if (st->m.rpz->num == rpz->num && - st->m.type < rpz_type) - break; - } - - /* - * Get the next policy zone's record for this trigger name. - */ - result = rpz_get_p_name(client, p_name, rpz, rpz_type, - trig_name); - if (result != ISC_R_SUCCESS) - continue; - result = rpz_find_p(client, trig_name, qtype, p_name, - rpz, rpz_type, - &p_zone, &p_db, &p_version, &p_node, - rdatasetp, &policy); - switch (result) { - case DNS_R_NXDOMAIN: - /* - * Continue after a missing policy record - * contrary to the summary data. The summary - * data can out of date during races with and among - * policy zone updates. - */ - CTRACE(ISC_LOG_ERROR, - "rpz_rewrite_name: mismatched summary data; " - "continuing"); - continue; - case DNS_R_SERVFAIL: - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - st->m.policy = DNS_RPZ_POLICY_ERROR; - return (DNS_R_SERVFAIL); - default: - /* - * With more than one applicable policy, prefer - * the earliest configured policy, - * client-IP over QNAME over IP over NSDNAME over NSIP, - * and the smallest name. - * We known st->m.rpz->num >= rpz->num and either - * st->m.rpz->num > rpz->num or st->m.type >= rpz_type - */ - if (st->m.policy != DNS_RPZ_POLICY_MISS && - rpz->num == st->m.rpz->num && - (st->m.type < rpz_type || - (st->m.type == rpz_type && - 0 >= dns_name_compare(p_name, st->p_name)))) - continue; -#if 0 - /* - * This code would block a customer reported information - * leak of rpz rules by rewriting requests in the - * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs. - * Without this code, a bad guy could request - * 24.0.3.2.10.rpz-ip. to find the policy rule for - * 10.2.3.0/14. It is an insignificant leak and this - * code is not worth its cost, because the bad guy - * could publish "evil.com A 10.2.3.4" and request - * evil.com to get the same information. - * Keep code with "#if 0" in case customer demand - * is irresistible. - * - * We have the less frequent case of a triggered - * policy. Check that we have not trigger on one - * of the pretend RPZ TLDs. - * This test would make it impossible to rewrite - * names in TLDs that start with "rpz-" should - * ICANN ever allow such TLDs. - */ - unsigned int labels; - labels = dns_name_countlabels(trig_name); - if (labels >= 2) { - dns_label_t label; - - dns_name_getlabel(trig_name, labels-2, &label); - if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 && - strncasecmp((const char *)label.base+1, - DNS_RPZ_PREFIX, - sizeof(DNS_RPZ_PREFIX)-1) == 0) - continue; - } -#endif - if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { - CTRACE(ISC_LOG_DEBUG(3), - "rpz_rewrite_name: rpz_save_p"); - rpz_save_p(st, rpz, rpz_type, - policy, p_name, 0, result, - &p_zone, &p_db, &p_node, - rdatasetp, p_version); - /* - * After a hit, higher numbered policy zones - * are irrelevant - */ - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - return (ISC_R_SUCCESS); - } - /* - * Log DNS_RPZ_POLICY_DISABLED zones - * and try the next eligible policy zone. - */ - rpz_log_rewrite(client, true, policy, rpz_type, - p_zone, p_name, NULL, rpz_num); - break; - } - } - - rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); - return (ISC_R_SUCCESS); -} - -static void -rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname, - isc_result_t result, int level, const char *str) -{ - dns_rpz_st_t *st; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ns_skip"); - - st = client->query.rpz_st; - - if (str != NULL) - rpz_log_fail_helper(client, level, nsname, - DNS_RPZ_TYPE_NSIP, DNS_RPZ_TYPE_NSDNAME, - str, result); - if (st->r.ns_rdataset != NULL && - dns_rdataset_isassociated(st->r.ns_rdataset)) - dns_rdataset_disassociate(st->r.ns_rdataset); - - st->r.label--; -} - -/* - * RPZ query result types - */ -typedef enum { - RPZ_QRESULT_TYPE_DONE, - RPZ_QRESULT_TYPE_RESTART, - RPZ_QRESULT_TYPE_RECURSE, -} rpz_qresult_type_t; - -/* - * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting. - */ -static isc_result_t -rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, - isc_result_t qresult, bool resuming, - dns_rdataset_t *ordataset, dns_rdataset_t *osigset) -{ - dns_rpz_zones_t *rpzs; - dns_rpz_st_t *st; - dns_rdataset_t *rdataset; - dns_fixedname_t nsnamef; - dns_name_t *nsname; - rpz_qresult_type_t qresult_type; - dns_rpz_zbits_t zbits; - isc_result_t result = ISC_R_SUCCESS; - dns_rpz_have_t have; - dns_rpz_popt_t popt; - int rpz_ver; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite"); - - rpzs = client->view->rpzs; - st = client->query.rpz_st; - - if (rpzs == NULL || - (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0)) - return (DNS_R_DISALLOWED); - - RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); - if (rpzs->p.num_zones == 0 || - (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) || - !rpz_ck_dnssec(client, qresult, ordataset, osigset)) - { - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - return (DNS_R_DISALLOWED); - } - have = rpzs->have; - popt = rpzs->p; - rpz_ver = rpzs->rpz_ver; - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - - if (st == NULL) { - st = isc_mem_get(client->mctx, sizeof(*st)); - if (st == NULL) - return (ISC_R_NOMEMORY); - st->state = 0; - } - if (st->state == 0) { - st->state |= DNS_RPZ_ACTIVE; - memset(&st->m, 0, sizeof(st->m)); - st->m.type = DNS_RPZ_TYPE_BAD; - st->m.policy = DNS_RPZ_POLICY_MISS; - st->m.ttl = ~0; - memset(&st->r, 0, sizeof(st->r)); - memset(&st->q, 0, sizeof(st->q)); - st->p_name = dns_fixedname_initname(&st->_p_namef); - st->r_name = dns_fixedname_initname(&st->_r_namef); - st->fname = dns_fixedname_initname(&st->_fnamef); - st->have = have; - st->popt = popt; - st->rpz_ver = rpz_ver; - client->query.rpz_st = st; - } - - /* - * There is nothing to rewrite if the main query failed. - */ - switch (qresult) { - case ISC_R_SUCCESS: - case DNS_R_GLUE: - case DNS_R_ZONECUT: - qresult_type = RPZ_QRESULT_TYPE_DONE; - break; - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - case DNS_R_NXDOMAIN: - case DNS_R_EMPTYWILD: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - case DNS_R_CNAME: - case DNS_R_DNAME: - qresult_type = RPZ_QRESULT_TYPE_RESTART; - break; - case DNS_R_DELEGATION: - case ISC_R_NOTFOUND: - /* - * If recursion is on, do only tentative rewriting. - * If recursion is off, this the normal and only time we - * can rewrite. - */ - if (RECURSIONOK(client)) - qresult_type = RPZ_QRESULT_TYPE_RECURSE; - else - qresult_type = RPZ_QRESULT_TYPE_RESTART; - break; - case ISC_R_FAILURE: - case ISC_R_TIMEDOUT: - case DNS_R_BROKENCHAIN: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, client->query.qname, - DNS_RPZ_TYPE_QNAME, - " stop on qresult in rpz_rewrite()", qresult); - return (ISC_R_SUCCESS); - default: - rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, client->query.qname, - DNS_RPZ_TYPE_QNAME, - " stop on unrecognized qresult in rpz_rewrite()", - qresult); - return (ISC_R_SUCCESS); - } - - rdataset = NULL; - - if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) != - (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) { - isc_netaddr_t netaddr; - dns_rpz_zbits_t allowed; - - if (qresult_type == RPZ_QRESULT_TYPE_RECURSE) { - /* - * This request needs recursion that has not been done. - * Get bits for the policy zones that do not need - * to wait for the results of recursion. - */ - allowed = st->have.qname_skip_recurse; - if (allowed == 0) - return (ISC_R_SUCCESS); - } else { - allowed = DNS_RPZ_ALL_ZBITS; - } - - /* - * Check once for triggers for the client IP address. - */ - if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) { - zbits = rpz_get_zbits(client, dns_rdatatype_none, - DNS_RPZ_TYPE_CLIENT_IP); - zbits &= allowed; - if (zbits != 0) { - isc_netaddr_fromsockaddr(&netaddr, - &client->peeraddr); - result = rpz_rewrite_ip(client, &netaddr, qtype, - DNS_RPZ_TYPE_CLIENT_IP, - zbits, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - - /* - * Check triggers for the query name if this is the first time - * for the current qname. - * There is a first time for each name in a CNAME chain - */ - if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { - result = rpz_rewrite_name(client, client->query.qname, - qtype, DNS_RPZ_TYPE_QNAME, - allowed, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Check IPv4 addresses in A RRs next. - * Reset to the start of the NS names. - */ - st->r.label = dns_name_countlabels(client->query.qname); - st->state &= ~(DNS_RPZ_DONE_QNAME_IP | - DNS_RPZ_DONE_IPv4); - - } - - /* - * Quit if this was an attempt to find a qname or - * client-IP trigger before recursion. - * We will be back if no pre-recursion triggers hit. - * For example, consider 2 policy zones, both with qname and - * IP address triggers. If the qname misses the 1st zone, - * then we cannot know whether a hit for the qname in the - * 2nd zone matters until after recursing to get the A RRs and - * testing them in the first zone. - * Do not bother saving the work from this attempt, - * because recursion is so slow. - */ - if (qresult_type == RPZ_QRESULT_TYPE_RECURSE) - goto cleanup; - - /* - * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP - * is reset at the end of dealing with each CNAME. - */ - st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME); - } - - /* - * Check known IP addresses for the query name if the database - * lookup resulted in some addresses (qresult_type == - * RPZ_QRESULT_TYPE_DONE) and if we have not already checked them. - * Any recursion required for the query has already happened. - * Do not check addresses that will not be in the ANSWER section. - */ - if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && - qresult_type == RPZ_QRESULT_TYPE_DONE && - rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) { - result = rpz_rewrite_ip_rrsets(client, - client->query.qname, qtype, - DNS_RPZ_TYPE_IP, - &rdataset, resuming); - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * We are finished checking the IP addresses for the qname. - * Start with IPv4 if we will check NS IP addresses. - */ - st->state |= DNS_RPZ_DONE_QNAME_IP; - st->state &= ~DNS_RPZ_DONE_IPv4; - } - - /* - * Stop looking for rules if there are none of the other kinds - * that could override what we already have. - */ - if (rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSDNAME) == 0 && - rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSIP) == 0) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - dns_fixedname_init(&nsnamef); - dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); - while (st->r.label > st->popt.min_ns_labels) { - /* - * Get NS rrset for each domain in the current qname. - */ - if (st->r.label == dns_name_countlabels(client->query.qname)) { - nsname = client->query.qname; - } else { - nsname = dns_fixedname_name(&nsnamef); - dns_name_split(client->query.qname, st->r.label, - NULL, nsname); - } - if (st->r.ns_rdataset == NULL || - !dns_rdataset_isassociated(st->r.ns_rdataset)) - { - dns_db_t *db = NULL; - result = rpz_rrset_find(client, nsname, - dns_rdatatype_ns, - DNS_RPZ_TYPE_NSDNAME, - &db, NULL, &st->r.ns_rdataset, - resuming); - if (db != NULL) - dns_db_detach(&db); - if (st->m.policy == DNS_RPZ_POLICY_ERROR) - goto cleanup; - switch (result) { - case ISC_R_SUCCESS: - result = dns_rdataset_first(st->r.ns_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - st->state &= ~(DNS_RPZ_DONE_NSDNAME | - DNS_RPZ_DONE_IPv4); - break; - case DNS_R_DELEGATION: - case DNS_R_DUPLICATE: - case DNS_R_DROP: - goto cleanup; - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - case DNS_R_EMPTYWILD: - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - case ISC_R_NOTFOUND: - case DNS_R_CNAME: - case DNS_R_DNAME: - rpz_rewrite_ns_skip(client, nsname, result, - 0, NULL); - continue; - case ISC_R_TIMEDOUT: - case DNS_R_BROKENCHAIN: - case ISC_R_FAILURE: - rpz_rewrite_ns_skip(client, nsname, result, - DNS_RPZ_DEBUG_LEVEL3, - " NS rpz_rrset_find()"); - continue; - default: - rpz_rewrite_ns_skip(client, nsname, result, - DNS_RPZ_INFO_LEVEL, - " unrecognized NS" - " rpz_rrset_find()"); - continue; - } - } - /* - * Check all NS names. - */ - do { - dns_rdata_ns_t ns; - dns_rdata_t nsrdata = DNS_RDATA_INIT; - - dns_rdataset_current(st->r.ns_rdataset, &nsrdata); - result = dns_rdata_tostruct(&nsrdata, &ns, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&nsrdata); - /* - * Do nothing about "NS ." - */ - if (dns_name_equal(&ns.name, dns_rootname)) { - dns_rdata_freestruct(&ns); - result = dns_rdataset_next(st->r.ns_rdataset); - continue; - } - /* - * Check this NS name if we did not handle it - * during a previous recursion. - */ - if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) { - result = rpz_rewrite_name(client, &ns.name, - qtype, - DNS_RPZ_TYPE_NSDNAME, - DNS_RPZ_ALL_ZBITS, - &rdataset); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ns); - goto cleanup; - } - st->state |= DNS_RPZ_DONE_NSDNAME; - } - /* - * Check all IP addresses for this NS name. - */ - result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype, - DNS_RPZ_TYPE_NSIP, - &rdataset, resuming); - dns_rdata_freestruct(&ns); - if (result != ISC_R_SUCCESS) - goto cleanup; - st->state &= ~(DNS_RPZ_DONE_NSDNAME | - DNS_RPZ_DONE_IPv4); - result = dns_rdataset_next(st->r.ns_rdataset); - } while (result == ISC_R_SUCCESS); - dns_rdataset_disassociate(st->r.ns_rdataset); - st->r.label--; - - if (rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSDNAME) == 0 && - rpz_get_zbits(client, dns_rdatatype_any, - DNS_RPZ_TYPE_NSIP) == 0) - break; - } - - /* - * Use the best hit, if any. - */ - result = ISC_R_SUCCESS; - -cleanup: - if (st->m.policy != DNS_RPZ_POLICY_MISS && - st->m.policy != DNS_RPZ_POLICY_ERROR && - st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN) - st->m.policy = st->m.rpz->policy; - if (st->m.policy == DNS_RPZ_POLICY_MISS || - st->m.policy == DNS_RPZ_POLICY_PASSTHRU || - st->m.policy == DNS_RPZ_POLICY_ERROR) { - if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU && - result != DNS_R_DELEGATION) - rpz_log_rewrite(client, false, st->m.policy, - st->m.type, st->m.zone, st->p_name, - NULL, st->m.rpz->num); - rpz_match_clear(st); - } - if (st->m.policy == DNS_RPZ_POLICY_ERROR) { - CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy"); - st->m.type = DNS_RPZ_TYPE_BAD; - result = DNS_R_SERVFAIL; - } - query_putrdataset(client, &rdataset); - if ((st->state & DNS_RPZ_RECURSING) == 0) - rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset); - - return (result); -} - -/* - * See if response policy zone rewriting is allowed by a lack of interest - * by the client in DNSSEC or a lack of signatures. - */ -static bool -rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_fixedname_t fixed; - dns_name_t *found; - dns_rdataset_t trdataset; - dns_rdatatype_t type; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_ck_dnssec"); - - if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) - return (true); - - /* - * We do not know if there are signatures if we have not recursed - * for them. - */ - if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND) - return (false); - - if (sigrdataset == NULL) - return (true); - if (dns_rdataset_isassociated(sigrdataset)) - return (false); - - /* - * We are happy to rewrite nothing. - */ - if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) - return (true); - /* - * Do not rewrite if there is any sign of signatures. - */ - if (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3 || - rdataset->type == dns_rdatatype_rrsig) - return (false); - - /* - * Look for a signature in a negative cache rdataset. - */ - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0) - return (true); - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (false); - } - return (true); -} - -/* - * Add a CNAME to the query response, including translating foo.evil.com and - * *.evil.com CNAME *.example.com - * to - * foo.evil.com CNAME foo.evil.com.example.com - */ -static isc_result_t -rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st, - dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf) -{ - dns_fixedname_t prefix, suffix; - unsigned int labels; - isc_result_t result; - - CTRACE(ISC_LOG_DEBUG(3), "rpz_add_cname"); - - labels = dns_name_countlabels(cname); - if (labels > 2 && dns_name_iswildcard(cname)) { - dns_fixedname_init(&prefix); - dns_name_split(client->query.qname, 1, - dns_fixedname_name(&prefix), NULL); - dns_fixedname_init(&suffix); - dns_name_split(cname, labels-1, - NULL, dns_fixedname_name(&suffix)); - result = dns_name_concatenate(dns_fixedname_name(&prefix), - dns_fixedname_name(&suffix), - fname, NULL); - if (result == DNS_R_NAMETOOLONG) - client->message->rcode = dns_rcode_yxdomain; - } else { - result = dns_name_copy(cname, fname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) - return (result); - query_keepname(client, fname, dbuf); - result = query_add_cname(client, client->query.qname, - fname, dns_trust_authanswer, st->m.ttl); - if (result != ISC_R_SUCCESS) - return (result); - rpz_log_rewrite(client, false, st->m.policy, - st->m.type, st->m.zone, st->p_name, fname, - st->m.rpz->num); - ns_client_qnamereplace(client, fname); - /* - * Turn off DNSSEC because the results of a - * response policy zone cannot verify. - */ - client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | - NS_CLIENTATTR_WANTAD); - return (ISC_R_SUCCESS); -} - -#define MAX_RESTARTS 16 - -#define QUERY_ERROR(r) \ -do { \ - eresult = r; \ - want_restart = false; \ - line = __LINE__; \ -} while (0) - -#define RECURSE_ERROR(r) \ -do { \ - if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \ - QUERY_ERROR(r); \ - else \ - QUERY_ERROR(DNS_R_SERVFAIL); \ -} while (0) - -/* - * Extract a network address from the RDATA of an A or AAAA - * record. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. - */ -static isc_result_t -rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { - struct in_addr ina; - struct in6_addr in6a; - - switch (rdata->type) { - case dns_rdatatype_a: - INSIST(rdata->length == 4); - memmove(&ina.s_addr, rdata->data, 4); - isc_netaddr_fromin(netaddr, &ina); - return (ISC_R_SUCCESS); - case dns_rdatatype_aaaa: - INSIST(rdata->length == 16); - memmove(in6a.s6_addr, rdata->data, 16); - isc_netaddr_fromin6(netaddr, &in6a); - return (ISC_R_SUCCESS); - default: - return (ISC_R_NOTIMPLEMENTED); - } -} - -/* - * Find the sort order of 'rdata' in the topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ -static int -query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder2(&netaddr, arg)); -} - -/* - * Find the sort order of 'rdata' in the matching element - * of a 1-element top-level sortlist statement. - */ -static int -query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder1(&netaddr, arg)); -} - -/* - * Find the sortlist statement that applies to 'client' and set up - * the sortlist info in in client->message appropriately. - */ -static void -setup_query_sortlist(ns_client_t *client) { - isc_netaddr_t netaddr; - dns_rdatasetorderfunc_t order = NULL; - const void *order_arg = NULL; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (ns_sortlist_setup(client->view->sortlist, - &netaddr, &order_arg)) { - case NS_SORTLISTTYPE_1ELEMENT: - order = query_sortlist_order_1element; - break; - case NS_SORTLISTTYPE_2ELEMENT: - order = query_sortlist_order_2element; - break; - case NS_SORTLISTTYPE_NONE: - order = NULL; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - break; - } - dns_message_setsortorder(client->message, order, order_arg); -} - -static void -query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) { - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *neg, *negsig; - isc_result_t result = ISC_R_NOMEMORY; - - CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof"); - - fname = NULL; - neg = NULL; - negsig = NULL; - - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - neg = query_newrdataset(client); - negsig = query_newrdataset(client); - if (fname == NULL || neg == NULL || negsig == NULL) - goto cleanup; - - result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - query_addrrset(client, &fname, &neg, &negsig, dbuf, - DNS_SECTION_AUTHORITY); - - if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) == 0) - goto cleanup; - - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - } - if (neg == NULL) - neg = query_newrdataset(client); - else if (dns_rdataset_isassociated(neg)) - dns_rdataset_disassociate(neg); - if (negsig == NULL) - negsig = query_newrdataset(client); - else if (dns_rdataset_isassociated(negsig)) - dns_rdataset_disassociate(negsig); - if (fname == NULL || neg == NULL || negsig == NULL) - goto cleanup; - result = dns_rdataset_getclosest(rdataset, fname, neg, negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - query_addrrset(client, &fname, &neg, &negsig, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (neg != NULL) - query_putrdataset(client, &neg); - if (negsig != NULL) - query_putrdataset(client, &negsig); - if (fname != NULL) - query_releasename(client, &fname); -} - -static inline void -answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { - dns_name_t *name; - dns_message_t *msg; - dns_section_t section = DNS_SECTION_ADDITIONAL; - dns_rdataset_t *rdataset = NULL; - - msg = client->message; - for (name = ISC_LIST_HEAD(msg->sections[section]); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - if (dns_name_equal(name, client->query.qname)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - if (rdataset->type == qtype) - break; - break; - } - if (rdataset != NULL) { - ISC_LIST_UNLINK(msg->sections[section], name, link); - ISC_LIST_PREPEND(msg->sections[section], name, link); - ISC_LIST_UNLINK(name->list, rdataset, link); - ISC_LIST_PREPEND(name->list, rdataset, link); - rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; - } -} - -static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; -static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; -static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; - -static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; - -static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; - -static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; - -static dns_name_t rfc1918names[] = { - DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets), - DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets) -}; - - -static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; -static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org"; - -static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; -static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; - -static dns_name_t prisoner = - DNS_NAME_INITABSOLUTE(prisoner_data, prisoner_offsets); -static dns_name_t hostmaster = - DNS_NAME_INITABSOLUTE(hostmaster_data, hostmaster_offsets); - -static void -warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { - unsigned int i; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - dns_rdataset_t found; - isc_result_t result; - - for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) { - if (dns_name_issubdomain(fname, &rfc1918names[i])) { - dns_rdataset_init(&found); - result = dns_ncache_getrdataset(rdataset, - &rfc1918names[i], - dns_rdatatype_soa, - &found); - if (result != ISC_R_SUCCESS) - return; - - result = dns_rdataset_first(&found); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(&found, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dns_name_equal(&soa.origin, &prisoner) && - dns_name_equal(&soa.contact, &hostmaster)) { - char buf[DNS_NAME_FORMATSIZE]; - dns_name_format(fname, buf, sizeof(buf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "RFC 1918 response from " - "Internet for %s", buf); - } - dns_rdataset_disassociate(&found); - return; - } - } -} - -static void -query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, - dns_dbversion_t *version, ns_client_t *client, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_name_t *fname, bool exact, - dns_name_t *found) -{ - unsigned char salt[256]; - size_t salt_length; - uint16_t iterations; - isc_result_t result; - unsigned int dboptions; - dns_fixedname_t fixed; - dns_hash_t hash; - dns_name_t name; - unsigned int skip = 0, labels; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - bool optout; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - - salt_length = sizeof(salt); - result = dns_db_getnsec3parameters(db, version, &hash, NULL, - &iterations, salt, &salt_length); - if (result != ISC_R_SUCCESS) - return; - - dns_name_init(&name, NULL); - dns_name_clone(qname, &name); - labels = dns_name_countlabels(&name); - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - /* - * Map unknown algorithm to known value. - */ - if (hash == DNS_NSEC3_UNKNOWNALG) - hash = 1; - - again: - dns_fixedname_init(&fixed); - result = dns_nsec3_hashname(&fixed, NULL, NULL, &name, - dns_db_origin(db), hash, - iterations, salt, salt_length); - if (result != ISC_R_SUCCESS) - return; - - dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; - result = dns_db_findext(db, dns_fixedname_name(&fixed), version, - dns_rdatatype_nsec3, dboptions, client->now, - NULL, fname, &cm, &ci, rdataset, sigrdataset); - - if (result == DNS_R_NXDOMAIN) { - if (!dns_rdataset_isassociated(rdataset)) { - return; - } - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - optout = (nsec3.flags & DNS_NSEC3FLAG_OPTOUT); - if (found != NULL && optout && - dns_name_issubdomain(&name, dns_db_origin(db))) - { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - skip++; - dns_name_getlabelsequence(qname, skip, labels - skip, - &name); - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3), - "looking for closest provable encloser"); - goto again; - } - if (exact) - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_WARNING, - "expected a exact match NSEC3, got " - "a covering record"); - - } else if (result != ISC_R_SUCCESS) { - return; - } else if (!exact) - ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, ISC_LOG_WARNING, - "expected covering NSEC3, got an exact match"); - if (found == qname) { - if (skip != 0U) - dns_name_getlabelsequence(qname, skip, labels - skip, - found); - } else if (found != NULL) - dns_name_copy(&name, found, NULL); - return; -} - -#ifdef ALLOW_FILTER_AAAA -static bool -is_v4_client(ns_client_t *client) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) - return (true); - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) - return (true); - return (false); -} - -static bool -is_v6_client(ns_client_t *client) { - if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && - !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) - return (true); - return (false); -} -#endif - -static uint32_t -dns64_ttl(dns_db_t *db, dns_dbversion_t *version) { - dns_dbnode_t *node = NULL; - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - isc_result_t result; - uint32_t ttl = UINT32_MAX; - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, - 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - ttl = ISC_MIN(rdataset.ttl, soa.minimum); - -cleanup: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (ttl); -} - -static bool -dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - isc_netaddr_t netaddr; - dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64); - unsigned int flags = 0; - unsigned int i, count; - bool *aaaaok; - - INSIST(client->query.dns64_aaaaok == NULL); - INSIST(client->query.dns64_aaaaoklen == 0); - INSIST(client->query.dns64_aaaa == NULL); - INSIST(client->query.dns64_sigaaaa == NULL); - - if (dns64 == NULL) - return (true); - - if (RECURSIONOK(client)) - flags |= DNS_DNS64_RECURSIVE; - - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - flags |= DNS_DNS64_DNSSEC; - - count = dns_rdataset_count(rdataset); - aaaaok = isc_mem_get(client->mctx, sizeof(bool) * count); - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, - &ns_g_server->aclenv, flags, rdataset, - aaaaok, count)) { - for (i = 0; i < count; i++) { - if (aaaaok != NULL && !aaaaok[i]) { - SAVE(client->query.dns64_aaaaok, aaaaok); - client->query.dns64_aaaaoklen = count; - break; - } - } - if (aaaaok != NULL) - isc_mem_put(client->mctx, aaaaok, - sizeof(bool) * count); - return (true); - } - if (aaaaok != NULL) - isc_mem_put(client->mctx, aaaaok, - sizeof(bool) * count); - return (false); -} - -/* - * Look for the name and type in the redirection zone. If found update - * the arguments as appropriate. Return true if a update was - * performed. - * - * Only perform the update if the client is in the allow query acl and - * returning the update would not cause a DNSSEC validation failure. - */ -static isc_result_t -redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_rdatatype_t qtype) -{ - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_name_t *found; - dns_rdataset_t trdataset; - isc_result_t result; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - ns_dbversion_t *dbversion; - - CTRACE(ISC_LOG_DEBUG(3), "redirect"); - - if (client->view->redirect == NULL) - return (ISC_R_NOTFOUND); - - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) - return (ISC_R_NOTFOUND); - - if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { - if (rdataset->trust == dns_trust_secure) - return (ISC_R_NOTFOUND); - if (rdataset->trust == dns_trust_ultimate && - (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3)) - return (ISC_R_NOTFOUND); - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (ISC_R_NOTFOUND); - } - } - } - - result = ns_client_checkaclsilent(client, NULL, - dns_zone_getqueryacl(client->view->redirect), - true); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - - result = dns_zone_getdb(client->view->redirect, &db); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - - dbversion = query_findversion(client, db); - if (dbversion == NULL) { - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - /* - * Lookup the requested data in the redirect zone. - */ - result = dns_db_findext(db, client->query.qname, dbversion->version, - qtype, DNS_DBFIND_NOZONECUT, client->now, - &node, found, &cm, &ci, &trdataset, NULL); - if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - goto nxrrset; - } else if (result != ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done"); - dns_name_copy(found, name, NULL); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) { - dns_rdataset_clone(&trdataset, rdataset); - dns_rdataset_disassociate(&trdataset); - } - nxrrset: - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - dns_db_detach(dbp); - dns_db_attachnode(db, node, nodep); - dns_db_attach(db, dbp); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - *versionp = dbversion->version; - - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - return (result); -} - -static isc_result_t -redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, - dns_rdatatype_t qtype, bool *is_zonep) -{ - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_fixedname_t fixedredirect; - dns_name_t *found, *redirectname; - dns_rdataset_t trdataset; - isc_result_t result; - dns_rdatatype_t type; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *version = NULL; - dns_zone_t *zone = NULL; - bool is_zone; - unsigned int labels; - unsigned int options; - - CTRACE(ISC_LOG_DEBUG(3), "redirect2"); - - if (client->view->redirectzone == NULL) - return (ISC_R_NOTFOUND); - - if (dns_name_issubdomain(name, client->view->redirectzone)) - return (ISC_R_NOTFOUND); - - found = dns_fixedname_initname(&fixed); - dns_rdataset_init(&trdataset); - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - - if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) - return (ISC_R_NOTFOUND); - - if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { - if (rdataset->trust == dns_trust_secure) - return (ISC_R_NOTFOUND); - if (rdataset->trust == dns_trust_ultimate && - (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3)) - return (ISC_R_NOTFOUND); - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, found, &trdataset); - type = trdataset.type; - dns_rdataset_disassociate(&trdataset); - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_rrsig) - return (ISC_R_NOTFOUND); - } - } - } - - redirectname = dns_fixedname_initname(&fixedredirect); - labels = dns_name_countlabels(client->query.qname); - if (labels > 1U) { - dns_name_t prefix; - - dns_name_init(&prefix, NULL); - dns_name_getlabelsequence(client->query.qname, 0, labels - 1, - &prefix); - result = dns_name_concatenate(&prefix, - client->view->redirectzone, - redirectname, NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - } else - dns_name_copy(redirectname, client->view->redirectzone, NULL); - - options = 0; - result = query_getdb(client, redirectname, qtype, options, &zone, - &db, &version, &is_zone); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOTFOUND); - if (zone != NULL) - dns_zone_detach(&zone); - - /* - * Lookup the requested data in the redirect zone. - */ - result = dns_db_findext(db, redirectname, version, - qtype, 0, client->now, - &node, found, &cm, &ci, &trdataset, NULL); - if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - goto nxrrset; - } else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) { - /* - * Cleanup. - */ - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - /* - * Don't loop forever if the lookup failed last time. - */ - if (!REDIRECT(client)) { - result = query_recurse(client, qtype, redirectname, - NULL, NULL, true); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - client->query.attributes |= - NS_QUERYATTR_REDIRECT; - return (DNS_R_CONTINUE); - } - } - return (ISC_R_NOTFOUND); - } else if (result != ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&trdataset)) - dns_rdataset_disassociate(&trdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (ISC_R_NOTFOUND); - } - - CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done"); - /* - * Adjust the found name to not include the redirectzone suffix. - */ - dns_name_split(found, dns_name_countlabels(client->view->redirectzone), - found, NULL); - /* - * Make the name absolute. - */ - result = dns_name_concatenate(found, dns_rootname, found, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_name_copy(found, name, NULL); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(&trdataset)) { - dns_rdataset_clone(&trdataset, rdataset); - dns_rdataset_disassociate(&trdataset); - } - nxrrset: - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - dns_db_detach(dbp); - dns_db_attachnode(db, node, nodep); - dns_db_attach(db, dbp); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - *is_zonep = is_zone; - *versionp = version; - - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - return (result); -} - -/* - * Do the bulk of query processing for the current query of 'client'. - * If 'event' is non-NULL, we are returning from recursion and 'qtype' - * is ignored. Otherwise, 'qtype' is the query type. - */ -static isc_result_t -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) -{ - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_rdatatype_t type = qtype; - dns_name_t *fname, *zfname, *tname, *prefix; - dns_rdataset_t *rdataset, *trdataset; - dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset; - dns_rdataset_t **sigrdatasetp; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatasetiter_t *rdsiter; - bool want_restart, is_zone, need_wildcardproof; - bool is_staticstub_zone; - bool authoritative = false; - bool answer_has_ns = false; - unsigned int n, nlabels; - dns_namereln_t namereln; - int order; - isc_buffer_t *dbuf; - isc_buffer_t b; - isc_result_t result, eresult, tresult; - dns_fixedname_t fixed; - dns_fixedname_t wildcardname; - dns_dbversion_t *version, *zversion; - dns_zone_t *zone; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - unsigned int options; - bool empty_wild; - dns_rdataset_t *noqname; - dns_rpz_st_t *rpz_st; - bool resuming; - int line = -1; - bool dns64_exclude, dns64, rpz; - bool nxrewrite = false; - bool want_stale = false; - bool redirected = false; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - char errmsg[256]; - bool associated; - dns_section_t section; - dns_ttl_t ttl; - bool failcache; - uint32_t flags; -#ifdef WANT_QUERYTRACE - char mbuf[4 * DNS_NAME_FORMATSIZE]; - char qbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; -#endif - dns_name_t *rpzqname; - - CTRACE(ISC_LOG_DEBUG(3), "query_find"); - - /* - * One-time initialization. - * - * It's especially important to initialize anything that the cleanup - * code might cleanup. - */ - - eresult = ISC_R_SUCCESS; - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - zversion = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - need_wildcardproof = false; - empty_wild = false; - dns64_exclude = dns64 = rpz = false; - options = 0; - resuming = false; - is_zone = false; - is_staticstub_zone = false; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - dns_clientinfo_init(&ci, client, NULL); - -#ifdef WANT_QUERYTRACE - if (client->query.origqname != NULL) - dns_name_format(client->query.origqname, qbuf, - sizeof(qbuf)); - else - snprintf(qbuf, sizeof(qbuf), ""); - - snprintf(mbuf, sizeof(mbuf) - 1, - "client attr:0x%x, query attr:0x%X, restarts:%u, " - "origqname:%s, timer:%d, authdb:%d, referral:%d", - client->attributes, - client->query.attributes, - client->query.restarts, qbuf, - (int) client->query.timerset, - (int) client->query.authdbset, - (int) client->query.isreferral); - CTRACE(ISC_LOG_DEBUG(3), mbuf); -#endif - - if (event != NULL) { - /* - * We're returning from recursion. Restore the query context - * and resume. - */ - want_restart = false; - - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) - { - CTRACE(ISC_LOG_DEBUG(3), "resume from RPZ recursion"); -#ifdef WANT_QUERYTRACE - { - char pbuf[DNS_NAME_FORMATSIZE] = ""; - char fbuf[DNS_NAME_FORMATSIZE] = ""; - if (rpz_st->r_name != NULL) - dns_name_format(rpz_st->r_name, - qbuf, sizeof(qbuf)); - else - snprintf(qbuf, sizeof(qbuf), - ""); - if (rpz_st->p_name != NULL) - dns_name_format(rpz_st->p_name, - pbuf, sizeof(pbuf)); - if (rpz_st->fname != NULL) - dns_name_format(rpz_st->fname, - fbuf, sizeof(fbuf)); - - snprintf(mbuf, sizeof(mbuf) - 1, - "rpz rname:%s, pname:%s, fname:%s", - qbuf, pbuf, fbuf); - CTRACE(ISC_LOG_DEBUG(3), mbuf); - } -#endif - - is_zone = rpz_st->q.is_zone; - authoritative = rpz_st->q.authoritative; - RESTORE(zone, rpz_st->q.zone); - RESTORE(node, rpz_st->q.node); - RESTORE(db, rpz_st->q.db); - RESTORE(rdataset, rpz_st->q.rdataset); - RESTORE(sigrdataset, rpz_st->q.sigrdataset); - qtype = rpz_st->q.qtype; - - if (event->node != NULL) - dns_db_detachnode(event->db, &event->node); - SAVE(rpz_st->r.db, event->db); - rpz_st->r.r_type = event->qtype; - SAVE(rpz_st->r.r_rdataset, event->rdataset); - query_putrdataset(client, &event->sigrdataset); - } else if (REDIRECT(client)) { - /* - * Restore saved state. - */ - CTRACE(ISC_LOG_DEBUG(3), - "resume from redirect recursion"); -#ifdef WANT_QUERYTRACE - dns_name_format(client->query.redirect.fname, - qbuf, sizeof(qbuf)); - dns_rdatatype_format(client->query.redirect.qtype, - tbuf, sizeof(tbuf)); - snprintf(mbuf, sizeof(mbuf) - 1, - "redirect fname:%s, qtype:%s, auth:%d", - qbuf, tbuf, - client->query.redirect.authoritative); - CTRACE(ISC_LOG_DEBUG(3), mbuf); -#endif - qtype = client->query.redirect.qtype; - INSIST(client->query.redirect.rdataset != NULL); - RESTORE(rdataset, client->query.redirect.rdataset); - RESTORE(sigrdataset, - client->query.redirect.sigrdataset); - RESTORE(db, client->query.redirect.db); - RESTORE(node, client->query.redirect.node); - RESTORE(zone, client->query.redirect.zone); - authoritative = client->query.redirect.authoritative; - is_zone = client->query.redirect.is_zone; - - /* - * Free resources used while recursing. - */ - query_putrdataset(client, &event->rdataset); - query_putrdataset(client, &event->sigrdataset); - if (event->node != NULL) - dns_db_detachnode(event->db, &event->node); - if (event->db != NULL) - dns_db_detach(&event->db); - } else { - CTRACE(ISC_LOG_DEBUG(3), - "resume from normal recursion"); - authoritative = false; - - qtype = event->qtype; - SAVE(db, event->db); - SAVE(node, event->node); - SAVE(rdataset, event->rdataset); - SAVE(sigrdataset, event->sigrdataset); - } - INSIST(rdataset != NULL); - - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - - if (DNS64(client)) { - client->query.attributes &= ~NS_QUERYATTR_DNS64; - dns64 = true; - } - if (DNS64EXCLUDE(client)) { - client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE; - dns64_exclude = true; - } - - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) - { - /* - * Has response policy changed out from under us? - */ - if (rpz_st->rpz_ver != client->view->rpzs->rpz_ver) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, - "query_find: RPZ settings " - "out of date " - "(rpz_ver %d, expected %d)", - client->view->rpzs->rpz_ver, - rpz_st->rpz_ver); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getnamebuf failed (1)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newname failed (1)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) { - tname = rpz_st->fname; - } else if (REDIRECT(client)) { - tname = client->query.redirect.fname; - } else { - tname = dns_fixedname_name(&event->foundname); - } - result = dns_name_copy(tname, fname, NULL); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_find: dns_name_copy failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_RECURSING) != 0) { - rpz_st->r.r_result = event->result; - result = rpz_st->q.result; - free_devent(client, ISC_EVENT_PTR(&event), &event); - } else if (REDIRECT(client)) { - result = client->query.redirect.result; - is_zone = client->query.redirect.is_zone; - } else { - result = event->result; - } - resuming = true; - goto resume; - } - - /* - * Not returning from recursion. - * - * First, check for a recent match in the view's SERVFAIL cache. - * If we find one, and it was from a query with CD=1, *or* - * if the current query has CD=0, then we can just return - * SERVFAIL now. - */ - if (RECURSIONOK(client)) { - flags = 0; -#ifdef ENABLE_AFL - if (ns_g_fuzz_type == ns_fuzz_resolver) { - failcache = false; - } else { - failcache = dns_badcache_find(client->view->failcache, - client->query.qname, qtype, - &flags, &client->tnow); - } -#else - failcache = dns_badcache_find(client->view->failcache, - client->query.qname, qtype, - &flags, &client->tnow); -#endif - if (failcache && - (((flags & NS_FAILCACHE_CD) != 0) || - ((client->message->flags & DNS_MESSAGEFLAG_CD) == 0))) - { - if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(1))) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_name_format(client->query.qname, - namebuf, sizeof(namebuf)); - dns_rdatatype_format(qtype, typebuf, - sizeof(typebuf)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(1), - "servfail cache hit %s/%s (%s)", - namebuf, typebuf, - ((flags & NS_FAILCACHE_CD) != 0) - ? "CD=1" - : "CD=0"); - } - client->attributes |= NS_CLIENTATTR_NOSETFC; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * If it's a SIG query, we'll iterate the node. - */ - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - - restart: - // query_start - CTRACE(ISC_LOG_DEBUG(3), "query_find: restart"); - want_restart = false; - authoritative = false; - version = NULL; - zversion = NULL; - need_wildcardproof = false; - rpz = false; - - /* - * If we require a server cookie then send back BADCOOKIE - * before we have done too much work. - */ - if (!TCP(client) && client->view->requireservercookie && - WANTCOOKIE(client) && !HAVECOOKIE(client)) - { - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - client->message->rcode = dns_rcode_badcookie; - goto cleanup; - } - - if (client->view->checknames && - !dns_rdata_checkowner(client->query.qname, - client->message->rdclass, - qtype, false)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdatatype_format(qtype, typebuf, sizeof(typebuf)); - dns_rdataclass_format(client->message->rdclass, classbuf, - sizeof(classbuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_ERROR, - "check-names failure %s/%s/%s", namebuf, - typebuf, classbuf); - QUERY_ERROR(DNS_R_REFUSED); - goto cleanup; - } - - /* - * Setup for root key sentinel processing. - */ - if (client->view->root_key_sentinel && - client->query.restarts == 0 && - (qtype == dns_rdatatype_a || - qtype == dns_rdatatype_aaaa) && - (client->message->flags & DNS_MESSAGEFLAG_CD) == 0) - { - root_key_sentinel_detect(client); - } - - /* - * First we must find the right database. - */ - options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ - if (dns_rdatatype_atparent(qtype) && - !dns_name_equal(client->query.qname, dns_rootname)) - options |= DNS_GETDB_NOEXACT; - result = query_getdb(client, client->query.qname, qtype, options, - &zone, &db, &version, &is_zone); - if (ISC_UNLIKELY((result != ISC_R_SUCCESS || !is_zone) && - qtype == dns_rdatatype_ds && - !RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0)) - { - /* - * If the query type is DS, look to see if we are - * authoritative for the child zone. - */ - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - - tresult = query_getzonedb(client, client->query.qname, qtype, - DNS_GETDB_PARTIAL, &tzone, &tdb, - &tversion); - if (tresult == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = NULL; - RESTORE(version, tversion); - RESTORE(db, tdb); - RESTORE(zone, tzone); - is_zone = true; - result = ISC_R_SUCCESS; - } else { - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - } - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_REFUSED) { - if (WANTRECURSION(client)) { - inc_stats(client, - dns_nsstatscounter_recurserej); - } else - inc_stats(client, dns_nsstatscounter_authrej); - if (!PARTIALANSWER(client)) - QUERY_ERROR(DNS_R_REFUSED); - } else { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getdb failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - } - goto cleanup; - } - - is_staticstub_zone = false; - if (is_zone) { - authoritative = true; - if (zone != NULL && - dns_zone_gettype(zone) == dns_zone_staticstub) - is_staticstub_zone = true; - } - - if (event == NULL && client->query.restarts == 0) { - if (is_zone) { - if (zone != NULL) { - /* - * if is_zone = true, zone = NULL then this is - * a DLZ zone. Don't attempt to attach zone. - */ - dns_zone_attach(zone, &client->query.authzone); - } - dns_db_attach(db, &client->query.authdb); - } - client->query.authdbset = true; - - /* Track TCP vs UDP stats per zone */ - if (TCP(client)) - inc_stats(client, dns_nsstatscounter_tcp); - else - inc_stats(client, dns_nsstatscounter_udp); - } - - db_find: - // query_lookup - CTRACE(ISC_LOG_DEBUG(3), "query_find: db_find"); - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (ISC_UNLIKELY(dbuf == NULL)) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_getnamebuf failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (ISC_UNLIKELY(fname == NULL || rdataset == NULL)) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newname failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: query_newrdataset failed (2)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * Now look for an answer in the database. If this is a dns64 - * AAAA lookup on a rpz database adjust the qname. - */ - if (dns64 && rpz) - rpzqname = client->query.rpz_st->p_name; - else - rpzqname = client->query.qname; - - result = dns_db_findext(db, rpzqname, version, type, - client->query.dboptions, client->now, - &node, fname, &cm, &ci, rdataset, sigrdataset); - /* - * Fixup fname and sigrdataset. - */ - if (dns64 && rpz) { - isc_result_t rresult; - - rresult = dns_name_copy(client->query.qname, fname, NULL); - RUNTIME_CHECK(rresult == ISC_R_SUCCESS); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - - if (!is_zone) - dns_cache_updatestats(client->view->cache, result); - - if (want_stale) { - char namebuf[DNS_NAME_FORMATSIZE]; - bool success; - - client->query.dboptions &= ~DNS_DBFIND_STALEOK; - want_stale = false; - - if (dns_rdataset_isassociated(rdataset) && - dns_rdataset_count(rdataset) > 0 && - STALE(rdataset)) { - rdataset->ttl = client->view->staleanswerttl; - success = true; - } else { - success = false; - } - - dns_name_format(client->query.qname, - namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_SERVE_STALE, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s resolver failure, stale answer %s", - namebuf, success ? "used" : "unavailable"); - - if (!success) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - resume: - CTRACE(ISC_LOG_DEBUG(3), "query_find: resume"); - - /* - * Rate limit these responses to this client. - * Do not delay counting and handling obvious referrals, - * since those won't come here again. - * Delay handling delegations for which we are certain to recurse and - * return here (DNS_R_DELEGATION, not a child of one of our - * own zones, and recursion enabled) - * Don't mess with responses rewritten by RPZ - * Count each response at most once. - */ - if (client->view->rrl != NULL && !HAVECOOKIE(client) && - ((fname != NULL && dns_name_isabsolute(fname)) || - (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) && - !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) && - (client->query.rpz_st == NULL || - (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&& - (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) - { - dns_rdataset_t nc_rdataset; - bool wouldlog; - char log_buf[DNS_RRL_LOG_BUF_LEN]; - isc_result_t nc_result, resp_result; - dns_rrl_result_t rrl_result; - - client->query.attributes |= NS_QUERYATTR_RRL_CHECKED; - - wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP); - tname = fname; - if (result == DNS_R_NXDOMAIN) { - /* - * Use the database origin name to rate limit NXDOMAIN - */ - if (db != NULL) - tname = dns_db_origin(db); - resp_result = result; - } else if (result == DNS_R_NCACHENXDOMAIN && - rdataset != NULL && - dns_rdataset_isassociated(rdataset) && - (rdataset->attributes & - DNS_RDATASETATTR_NEGATIVE) != 0) { - /* - * Try to use owner name in the negative cache SOA. - */ - dns_fixedname_init(&fixed); - dns_rdataset_init(&nc_rdataset); - for (nc_result = dns_rdataset_first(rdataset); - nc_result == ISC_R_SUCCESS; - nc_result = dns_rdataset_next(rdataset)) { - dns_ncache_current(rdataset, - dns_fixedname_name(&fixed), - &nc_rdataset); - if (nc_rdataset.type == dns_rdatatype_soa) { - dns_rdataset_disassociate(&nc_rdataset); - tname = dns_fixedname_name(&fixed); - break; - } - dns_rdataset_disassociate(&nc_rdataset); - } - resp_result = DNS_R_NXDOMAIN; - } else if (result == DNS_R_NXRRSET || - result == DNS_R_EMPTYNAME) { - resp_result = DNS_R_NXRRSET; - } else if (result == DNS_R_DELEGATION) { - resp_result = result; - } else if (result == ISC_R_NOTFOUND) { - /* - * Handle referral to ".", including when recursion - * is off or not requested and the hints have not - * been loaded or we have "additional-from-cache no". - */ - tname = dns_rootname; - resp_result = DNS_R_DELEGATION; - } else { - resp_result = ISC_R_SUCCESS; - } - rrl_result = dns_rrl(client->view, &client->peeraddr, - TCP(client), client->message->rdclass, - qtype, tname, resp_result, client->now, - wouldlog, log_buf, sizeof(log_buf)); - if (rrl_result != DNS_RRL_RESULT_OK) { - /* - * Log dropped or slipped responses in the query - * category so that requests are not silently lost. - * Starts of rate-limited bursts are logged in - * DNS_LOGCATEGORY_RRL. - * - * Dropped responses are counted with dropped queries - * in QryDropped while slipped responses are counted - * with other truncated responses in RespTruncated. - */ - if (wouldlog) { - ns_client_log(client, DNS_LOGCATEGORY_RRL, - NS_LOGMODULE_QUERY, - DNS_RRL_LOG_DROP, - "%s", log_buf); - } - if (!client->view->rrl->log_only) { - if (rrl_result == DNS_RRL_RESULT_DROP) { - /* - * These will also be counted in - * dns_nsstatscounter_dropped - */ - inc_stats(client, - dns_nsstatscounter_ratedropped); - QUERY_ERROR(DNS_R_DROP); - } else { - /* - * These will also be counted in - * dns_nsstatscounter_truncatedresp - */ - inc_stats(client, - dns_nsstatscounter_rateslipped); - if (WANTCOOKIE(client)) { - client->message->flags &= - ~DNS_MESSAGEFLAG_AA; - client->message->flags &= - ~DNS_MESSAGEFLAG_AD; - client->message->rcode = - dns_rcode_badcookie; - } else { - client->message->flags |= - DNS_MESSAGEFLAG_TC; - if (resp_result == - DNS_R_NXDOMAIN) - client->message->rcode = - dns_rcode_nxdomain; - } - } - goto cleanup; - } - } - } else if (!TCP(client) && client->view->requireservercookie && - WANTCOOKIE(client) && !HAVECOOKIE(client)) { - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - client->message->rcode = dns_rcode_badcookie; - goto cleanup; - } - - if (!RECURSING(client) && - !dns_name_equal(client->query.qname, dns_rootname)) - { - isc_result_t rresult; - - rresult = rpz_rewrite(client, qtype, result, resuming, - rdataset, sigrdataset); - rpz_st = client->query.rpz_st; - switch (rresult) { - case ISC_R_SUCCESS: - break; - case DNS_R_DISALLOWED: - goto norpz; - case DNS_R_DELEGATION: - /* - * recursing for NS names or addresses, - * so save the main query state - */ - rpz_st->q.qtype = qtype; - rpz_st->q.is_zone = is_zone; - rpz_st->q.authoritative = authoritative; - SAVE(rpz_st->q.zone, zone); - SAVE(rpz_st->q.db, db); - SAVE(rpz_st->q.node, node); - SAVE(rpz_st->q.rdataset, rdataset); - SAVE(rpz_st->q.sigrdataset, sigrdataset); - dns_name_copy(fname, rpz_st->fname, NULL); - rpz_st->q.result = result; - client->query.attributes |= NS_QUERYATTR_RECURSING; - goto cleanup; - default: - RECURSE_ERROR(rresult); - goto cleanup; - } - - if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS) - rpz_st->state |= DNS_RPZ_REWRITTEN; - if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS && - rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU && - (rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY || - !TCP(client)) && - rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) - { - /* - * We got a hit and are going to answer with our - * fiction. Ensure that we answer with the name - * we looked up even if we were stopped short - * in recursion or for a deferral. - */ - rresult = dns_name_copy(client->query.qname, - fname, NULL); - RUNTIME_CHECK(rresult == ISC_R_SUCCESS); - rpz_clean(&zone, &db, &node, NULL); - if (rpz_st->m.rdataset != NULL) { - query_putrdataset(client, &rdataset); - RESTORE(rdataset, rpz_st->m.rdataset); - } else if (rdataset != NULL && - dns_rdataset_isassociated(rdataset)) { - dns_rdataset_disassociate(rdataset); - } - version = NULL; - - RESTORE(node, rpz_st->m.node); - RESTORE(db, rpz_st->m.db); - RESTORE(version, rpz_st->m.version); - RESTORE(zone, rpz_st->m.zone); - - switch (rpz_st->m.policy) { - case DNS_RPZ_POLICY_TCP_ONLY: - client->message->flags |= DNS_MESSAGEFLAG_TC; - if (result == DNS_R_NXDOMAIN || - result == DNS_R_NCACHENXDOMAIN) - client->message->rcode = - dns_rcode_nxdomain; - rpz_log_rewrite(client, false, - rpz_st->m.policy, - rpz_st->m.type, zone, - rpz_st->p_name, NULL, - rpz_st->m.rpz->num); - goto cleanup; - case DNS_RPZ_POLICY_DROP: - QUERY_ERROR(DNS_R_DROP); - rpz_log_rewrite(client, false, - rpz_st->m.policy, - rpz_st->m.type, zone, - rpz_st->p_name, NULL, - rpz_st->m.rpz->num); - goto cleanup; - case DNS_RPZ_POLICY_NXDOMAIN: - result = DNS_R_NXDOMAIN; - nxrewrite = true; - rpz = true; - break; - case DNS_RPZ_POLICY_NODATA: - nxrewrite = true; - /* FALLTHROUGH */ - case DNS_RPZ_POLICY_DNS64: - result = DNS_R_NXRRSET; - rpz = true; - break; - case DNS_RPZ_POLICY_RECORD: - result = rpz_st->m.result; - if (qtype == dns_rdatatype_any && - result != DNS_R_CNAME) { - /* - * We will add all of the rdatasets of - * the node by iterating later, - * and set the TTL then. - */ - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - } else { - /* - * We will add this rdataset. - */ - rdataset->ttl = ISC_MIN(rdataset->ttl, - rpz_st->m.ttl); - } - rpz = true; - break; - case DNS_RPZ_POLICY_WILDCNAME: - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - result = rpz_add_cname(client, rpz_st, - &cname.cname, - fname, dbuf); - if (result != ISC_R_SUCCESS) - goto cleanup; - fname = NULL; - want_restart = true; - goto cleanup; - case DNS_RPZ_POLICY_CNAME: - /* - * Add overriding CNAME from a named.conf - * response-policy statement - */ - result = rpz_add_cname(client, rpz_st, - &rpz_st->m.rpz->cname, - fname, dbuf); - if (result != ISC_R_SUCCESS) - goto cleanup; - fname = NULL; - want_restart = true; - goto cleanup; - default: - INSIST(0); - } - - /* - * Turn off DNSSEC because the results of a - * response policy zone cannot verify. - */ - client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | - NS_CLIENTATTR_WANTAD); - client->message->flags &= ~DNS_MESSAGEFLAG_AD; - query_putrdataset(client, &sigrdataset); - is_zone = true; - rpz_log_rewrite(client, false, rpz_st->m.policy, - rpz_st->m.type, zone, rpz_st->p_name, - NULL, rpz_st->m.rpz->num); - } - } - - norpz: - /* - * If required, handle special "root-key-sentinel-is-ta-" and - * "root-key-sentinel-not-ta-" labels by returning SERVFAIL. - */ - if (root_key_sentinel_return_servfail(client, is_zone, - rdataset, result)) - { - /* - * Don't record this response in the SERVFAIL cache. - */ - client->attributes |= NS_CLIENTATTR_NOSETFC; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - switch (result) { - case ISC_R_SUCCESS: - /* - * This case is handled in the main line below. - */ - break; - case DNS_R_GLUE: - case DNS_R_ZONECUT: - /* - * These cases are handled in the main line below. - */ - INSIST(is_zone); - authoritative = false; - break; - case ISC_R_NOTFOUND: - /* - * The cache doesn't even have the root NS. Get them from - * the hints DB. - */ - // query_notfound - INSIST(!is_zone); - if (db != NULL) - dns_db_detach(&db); - - if (client->view->hints == NULL) { - /* We have no hints. */ - result = ISC_R_FAILURE; - } else { - dns_db_attach(client->view->hints, &db); - result = dns_db_findext(db, dns_rootname, - NULL, dns_rdatatype_ns, - 0, client->now, &node, - fname, &cm, &ci, - rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * Nonsensical root hints may require cleanup. - */ - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - /* - * We don't have any root server hints, but - * we may have working forwarders, so try to - * recurse anyway. - */ - if (RECURSIONOK(client)) { - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } else { - /* Unable to give root server referral. */ - CTRACE(ISC_LOG_ERROR, - "unable to give root server referral"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - /* - * XXXRTH We should trigger root server priming here. - */ - /* FALLTHROUGH */ - case DNS_R_DELEGATION: - // query_delegation - authoritative = false; - if (is_zone) { - /* - * Look to see if we are authoritative for the - * child zone if the query type is DS. - */ - // query_zone_delegation - if (!RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0 && - qtype == dns_rdatatype_ds) { - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - result = query_getzonedb(client, - client->query.qname, - qtype, - DNS_GETDB_PARTIAL, - &tzone, &tdb, - &tversion); - if (result == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - if (fname != NULL) - query_releasename(client, - &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = NULL; - RESTORE(version, tversion); - RESTORE(db, tdb); - RESTORE(zone, tzone); - authoritative = true; - goto db_find; - } - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - /* - * We're authoritative for an ancestor of QNAME. - */ - if (!USECACHE(client) || !RECURSIONOK(client)) { - bool detach = false; - - dns_fixedname_init(&fixed); - dns_name_copy(fname, - dns_fixedname_name(&fixed), NULL); - - /* - * If we don't have a cache, this is the best - * answer. - * - * If the client is making a nonrecursive - * query we always give out the authoritative - * delegation. This way even if we get - * junk in our cache, we won't fail in our - * role as the delegating authority if another - * nameserver asks us about a delegated - * subzone. - * - * We enable the retrieval of glue for this - * database by setting client->query.gluedb. - */ - if (db != NULL && - client->query.gluedb == NULL) { - dns_db_attach(db, - &client->query.gluedb); - detach = true; - } - client->query.isreferral = true; - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - if (detach) { - dns_db_detach(&client->query.gluedb); - } - if (WANTDNSSEC(client)) - query_addds(client, db, node, version, - dns_fixedname_name(&fixed)); - } else { - /* - * We might have a better answer or delegation - * in the cache. We'll remember the current - * values of fname, rdataset, and sigrdataset. - * We'll then go looking for QNAME in the - * cache. If we find something better, we'll - * use it instead. - */ - query_keepname(client, fname, dbuf); - dns_db_detachnode(db, &node); - SAVE(zdb, db); - SAVE(zfname, fname); - SAVE(zversion, version); - SAVE(zrdataset, rdataset); - SAVE(zsigrdataset, sigrdataset); - dns_db_attach(client->view->cachedb, &db); - is_zone = false; - goto db_find; - } - } else { - if (zfname != NULL && - (!dns_name_issubdomain(fname, zfname) || - (is_staticstub_zone && - dns_name_equal(fname, zfname)))) { - /* - * In the following cases use "authoritative" - * data instead of the cache delegation: - * 1. We've already got a delegation from - * authoritative data, and it is better - * than what we found in the cache. - * 2. The query name matches the origin name - * of a static-stub zone. This needs to be - * considered for the case where the NS of - * the static-stub zone and the cached NS - * are different. We still need to contact - * the nameservers configured in the - * static-stub zone. - */ - query_releasename(client, &fname); - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - version = NULL; - - RESTORE(fname, zfname); - RESTORE(version, zversion); - RESTORE(rdataset, zrdataset); - RESTORE(sigrdataset, zsigrdataset); - /* - * We don't clean up zdb here because we - * may still need it. It will get cleaned - * up by the main cleanup code. - */ - } - - if (RECURSIONOK(client)) { - /* - * Recurse! - */ - INSIST(!REDIRECT(client)); - if (dns_rdatatype_atparent(type)) - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - else if (dns64) - result = query_recurse(client, - dns_rdatatype_a, - client->query.qname, - NULL, NULL, resuming); - else - result = query_recurse(client, qtype, - client->query.qname, - fname, rdataset, - resuming); - - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) - QUERY_ERROR(result); - else - RECURSE_ERROR(result); - } else { - bool detach = false; - - dns_fixedname_init(&fixed); - dns_name_copy(fname, - dns_fixedname_name(&fixed), NULL); - /* - * This is the best answer. - */ - client->query.attributes |= - NS_QUERYATTR_CACHEGLUEOK; - client->query.isreferral = true; - - if (zdb != NULL && - client->query.gluedb == NULL) { - dns_db_attach(zdb, - &client->query.gluedb); - detach = true; - } - - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - client->query.attributes &= - ~NS_QUERYATTR_CACHEGLUEOK; - if (detach) { - dns_db_detach(&client->query.gluedb); - } - - if (WANTDNSSEC(client)) - query_addds(client, db, node, version, - dns_fixedname_name(&fixed)); - } - } - goto cleanup; - - case DNS_R_EMPTYNAME: - case DNS_R_NXRRSET: - iszone_nxrrset: - INSIST(is_zone); - -#ifdef dns64_bis_return_excluded_addresses - if (dns64) -#else - if (dns64 && !dns64_exclude) -#endif - { - /* - * Restore the answers from the previous AAAA lookup. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - RESTORE(rdataset, client->query.dns64_aaaa); - RESTORE(sigrdataset, client->query.dns64_sigaaaa); - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_getnamebuf failed (3)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_newname failed (3)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - dns_name_copy(client->query.qname, fname, NULL); - dns64 = false; -#ifdef dns64_bis_return_excluded_addresses - /* - * Resume the diverted processing of the AAAA response? - */ - if (dns64_excluded) - break; -#endif - } else if (result == DNS_R_NXRRSET && - !ISC_LIST_EMPTY(client->view->dns64) && - !nxrewrite && - client->message->rdclass == dns_rdataclass_in && - qtype == dns_rdatatype_aaaa) - { - /* - * Look to see if there are A records for this - * name. - */ - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - client->query.dns64_ttl = dns64_ttl(db, version); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64 = true; - goto db_find; - } - - /* - * Look for a NSEC3 record if we don't have a NSEC record. - */ - nxrrset_rrsig: - if (redirected) - goto cleanup; - if (!dns_rdataset_isassociated(rdataset) && - WANTDNSSEC(client)) { - if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) { - dns_name_t *found; - dns_name_t *qname; - - found = dns_fixedname_initname(&fixed); - qname = client->query.qname; - - query_findclosestnsec3(qname, db, version, - client, rdataset, - sigrdataset, fname, - true, found); - /* - * Did we find the closest provable encloser - * instead? If so add the nearest to the - * closest provable encloser. - */ - if (dns_rdataset_isassociated(rdataset) && - !dns_name_equal(qname, found) && - !(ns_g_nonearest && - qtype != dns_rdatatype_ds)) - { - unsigned int count; - unsigned int skip; - - /* - * Add the closest provable encloser. - */ - query_addrrset(client, &fname, - &rdataset, &sigrdataset, - dbuf, - DNS_SECTION_AUTHORITY); - - count = dns_name_countlabels(found) - + 1; - skip = dns_name_countlabels(qname) - - count; - dns_name_getlabelsequence(qname, skip, - count, - found); - - fixfname(client, &fname, &dbuf, &b); - fixrdataset(client, &rdataset); - fixrdataset(client, &sigrdataset); - if (fname == NULL || - rdataset == NULL || - sigrdataset == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "failure getting " - "closest encloser"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - /* - * 'nearest' doesn't exist so - * 'exist' is set to false. - */ - query_findclosestnsec3(found, db, - version, - client, - rdataset, - sigrdataset, - fname, - false, - NULL); - } - } else { - query_releasename(client, &fname); - query_addwildcardproof(client, db, version, - client->query.qname, - false, true); - } - } - // query_nxdomain - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else if (fname != NULL) { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - - /* - * Add SOA to the additional section if generated by a RPZ - * rewrite. - */ - associated = dns_rdataset_isassociated(rdataset); - section = nxrewrite ? DNS_SECTION_ADDITIONAL : - DNS_SECTION_AUTHORITY; - - result = query_addsoa(client, db, version, UINT32_MAX, - associated, section); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - - /* - * Add NSEC record if we found one. - */ - if (WANTDNSSEC(client)) { - if (dns_rdataset_isassociated(rdataset)) - query_addnxrrsetnsec(client, db, version, - &fname, &rdataset, - &sigrdataset); - } - goto cleanup; - - case DNS_R_EMPTYWILD: - empty_wild = true; - /* FALLTHROUGH */ - - case DNS_R_NXDOMAIN: - INSIST(is_zone || REDIRECT(client)); - if (!empty_wild) { - tresult = redirect(client, fname, rdataset, &node, - &db, &version, type); - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - is_zone = false; - goto ncache_nxrrset; - } - tresult = redirect2(client, fname, rdataset, &node, - &db, &version, type, &is_zone); - if (tresult == DNS_R_CONTINUE) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect_rlookup); - client->query.redirect.qtype = qtype; - INSIST(rdataset != NULL); - SAVE(client->query.redirect.rdataset, rdataset); - SAVE(client->query.redirect.sigrdataset, - sigrdataset); - SAVE(client->query.redirect.db, db); - SAVE(client->query.redirect.node, node); - SAVE(client->query.redirect.zone, zone); - client->query.redirect.result = DNS_R_NXDOMAIN; - dns_name_copy(fname, - client->query.redirect.fname, - NULL); - client->query.redirect.authoritative = - authoritative; - client->query.redirect.is_zone = is_zone; - goto cleanup; - } - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - is_zone = false; - goto ncache_nxrrset; - } - } - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else if (fname != NULL) { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - - /* - * Add SOA to the additional section if generated by a - * RPZ rewrite. - * - * If the query was for a SOA record force the - * ttl to zero so that it is possible for clients to find - * the containing zone of an arbitrary name with a stub - * resolver and not have it cached. - */ - associated = dns_rdataset_isassociated(rdataset); - section = nxrewrite ? DNS_SECTION_ADDITIONAL : - DNS_SECTION_AUTHORITY; - ttl = UINT32_MAX; - if (!nxrewrite && qtype == dns_rdatatype_soa && - zone != NULL && dns_zone_getzeronosoattl(zone)) - ttl = 0; - result = query_addsoa(client, db, version, ttl, associated, - section); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - - if (WANTDNSSEC(client)) { - /* - * Add NSEC record if we found one. - */ - if (dns_rdataset_isassociated(rdataset)) - query_addrrset(client, &fname, &rdataset, - &sigrdataset, - NULL, DNS_SECTION_AUTHORITY); - query_addwildcardproof(client, db, version, - client->query.qname, false, - false); - } - - /* - * Set message rcode. - */ - if (empty_wild) - client->message->rcode = dns_rcode_noerror; - else - client->message->rcode = dns_rcode_nxdomain; - goto cleanup; - - case DNS_R_NCACHENXDOMAIN: - tresult = redirect(client, fname, rdataset, &node, - &db, &version, type); - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - is_zone = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - result = tresult; - goto ncache_nxrrset; - } - tresult = redirect2(client, fname, rdataset, &node, - &db, &version, type, &is_zone); - if (tresult == DNS_R_CONTINUE) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect_rlookup); - SAVE(client->query.redirect.db, db); - SAVE(client->query.redirect.node, node); - SAVE(client->query.redirect.zone, zone); - client->query.redirect.qtype = qtype; - INSIST(rdataset != NULL); - SAVE(client->query.redirect.rdataset, rdataset); - SAVE(client->query.redirect.sigrdataset, sigrdataset); - client->query.redirect.result = DNS_R_NCACHENXDOMAIN; - dns_name_copy(fname, client->query.redirect.fname, - NULL); - client->query.redirect.authoritative = authoritative; - client->query.redirect.is_zone = is_zone; - goto cleanup; - } - if (tresult == ISC_R_SUCCESS) { - inc_stats(client, - dns_nsstatscounter_nxdomainredirect); - break; - } - if (tresult == DNS_R_NXRRSET) { - redirected = true; - is_zone = true; - goto iszone_nxrrset; - } - if (tresult == DNS_R_NCACHENXRRSET) { - redirected = true; - result = tresult; - goto ncache_nxrrset; - } - /* FALLTHROUGH */ - - case DNS_R_NCACHENXRRSET: - ncache_nxrrset: - INSIST(!is_zone); - authoritative = false; - /* - * Set message rcode, if required. - */ - if (result == DNS_R_NCACHENXDOMAIN) - client->message->rcode = dns_rcode_nxdomain; - /* - * Look for RFC 1918 leakage from Internet. - */ - if (result == DNS_R_NCACHENXDOMAIN && - qtype == dns_rdatatype_ptr && - client->message->rdclass == dns_rdataclass_in && - dns_name_countlabels(fname) == 7) - warn_rfc1918(client, fname, rdataset); - -#ifdef dns64_bis_return_excluded_addresses - if (dns64) -#else - if (dns64 && !dns64_exclude) -#endif - { - /* - * Restore the answers from the previous AAAA lookup. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - RESTORE(rdataset, client->query.dns64_aaaa); - RESTORE(sigrdataset, client->query.dns64_sigaaaa); - if (fname == NULL) { - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_getnamebuf failed (4)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - CTRACE(ISC_LOG_ERROR, - "query_find: " - "query_newname failed (4)"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - dns_name_copy(client->query.qname, fname, NULL); - dns64 = false; -#ifdef dns64_bis_return_excluded_addresses - if (dns64_excluded) - break; -#endif - } else if (result == DNS_R_NCACHENXRRSET && - !ISC_LIST_EMPTY(client->view->dns64) && - client->message->rdclass == dns_rdataclass_in && - qtype == dns_rdatatype_aaaa) - { - /* - * Look to see if there are A records for this - * name. - */ - - /* - * If the ttl is zero we need to workout if we have just - * decremented to zero or if there was no negative cache - * ttl in the answer. - */ - if (rdataset->ttl != 0) - client->query.dns64_ttl = rdataset->ttl; - else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS) - client->query.dns64_ttl = 0; - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64 = true; - goto db_find; - } - - /* - * We don't call query_addrrset() because we don't need any - * of its extra features (and things would probably break!). - */ - if (dns_rdataset_isassociated(rdataset)) { - query_keepname(client, fname, dbuf); - dns_message_addname(client->message, fname, - DNS_SECTION_AUTHORITY); - ISC_LIST_APPEND(fname->list, rdataset, link); - fname = NULL; - rdataset = NULL; - } - goto cleanup; - - case DNS_R_CNAME: - /* - * If we have a zero ttl from the cache refetch it. - */ - // query_cname - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && - RECURSIONOK(client)) - { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } - - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the CNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = true; - } - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Reset qname to be the target name of the CNAME and restart - * the query. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - dns_name_init(tname, NULL); - result = dns_name_dup(&cname.cname, client->mctx, tname); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - dns_rdata_freestruct(&cname); - goto cleanup; - } - dns_rdata_freestruct(&cname); - ns_client_qnamereplace(client, tname); - want_restart = true; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - goto addauth; - case DNS_R_DNAME: - /* - * Compare the current qname to the found name. We need - * to know how many labels and bits are in common because - * we're going to have to split qname later on. - */ - namereln = dns_name_fullcompare(client->query.qname, fname, - &order, &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the DNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = true; - } - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Get the target name of the DNAME. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - dns_name_clone(&dname.dname, tname); - dns_rdata_freestruct(&dname); - /* - * Construct the new qname consisting of - * . - */ - prefix = dns_fixedname_initname(&fixed); - dns_name_split(client->query.qname, nlabels, prefix, NULL); - INSIST(fname == NULL); - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - result = dns_name_concatenate(prefix, tname, fname, NULL); - dns_message_puttempname(client->message, &tname); - - /* - * RFC2672, section 4.1, subsection 3c says - * we should return YXDOMAIN if the constructed - * name would be too long. - */ - if (result == DNS_R_NAMETOOLONG) - client->message->rcode = dns_rcode_yxdomain; - if (result != ISC_R_SUCCESS) - goto cleanup; - - query_keepname(client, fname, dbuf); - /* - * Synthesize a CNAME consisting of - * CNAME - * with - * - * Synthesize a CNAME so old old clients that don't understand - * DNAME can chain. - * - * We do not try to synthesize a signature because we hope - * that security aware servers will understand DNAME. Also, - * even if we had an online key, making a signature - * on-the-fly is costly, and not really legitimate anyway - * since the synthesized CNAME is NOT in the zone. - */ - result = query_add_cname(client, client->query.qname, fname, - trdataset->trust, trdataset->ttl); - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * If the original query was not for a CNAME or ANY then - * follow the CNAME. - */ - if (qtype != dns_rdatatype_cname && - qtype != dns_rdatatype_any) - { - /* - * Switch to the new qname and restart. - */ - ns_client_qnamereplace(client, fname); - fname = NULL; - want_restart = true; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - } - goto addauth; - default: - /* - * Something has gone wrong. - */ - snprintf(errmsg, sizeof(errmsg) - 1, - "query_find: unexpected error after resuming: %s", - isc_result_totext(result)); - CTRACE(ISC_LOG_ERROR, errmsg); - if (resuming) { - want_stale = true; - } else { - QUERY_ERROR(DNS_R_SERVFAIL); - } - goto cleanup; - } - - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL); - need_wildcardproof = true; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * The filter-aaaa-on-v4 option should suppress AAAAs for IPv4 - * clients if there is an A; filter-aaaa-on-v6 option does the same - * for IPv6 clients. - */ - client->filter_aaaa = dns_aaaa_ok; - if (client->view->v4_aaaa != dns_aaaa_ok || - client->view->v6_aaaa != dns_aaaa_ok) - { - result = ns_client_checkaclsilent(client, NULL, - client->view->aaaa_acl, - true); - if (result == ISC_R_SUCCESS && - client->view->v4_aaaa != dns_aaaa_ok && - is_v4_client(client)) - client->filter_aaaa = client->view->v4_aaaa; - else if (result == ISC_R_SUCCESS && - client->view->v6_aaaa != dns_aaaa_ok && - is_v6_client(client)) - client->filter_aaaa = client->view->v6_aaaa; - } - -#endif - - if (type == dns_rdatatype_any) { - /* - * For minimal-any, we only add records that - * match this type or cover this type. - */ - dns_rdatatype_t onetype = 0; -#ifdef ALLOW_FILTER_AAAA - bool have_aaaa, have_a, have_sig; - - /* - * If we are not authoritative, assume there is a A - * even in if it is not in our cache. This assumption could - * be wrong but it is a good bet. - */ - have_aaaa = false; - have_a = !authoritative; - have_sig = false; -#endif - /* - * XXXRTH Need to handle zonecuts with special case - * code. - */ - n = 0; - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - if (result != ISC_R_SUCCESS) { - CTRACE(ISC_LOG_ERROR, - "query_find: type any; allrdatasets failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - /* - * Calling query_addrrset() with a non-NULL dbuf is going - * to either keep or release the name. We don't want it to - * release fname, since we may have to call query_addrrset() - * more than once. That means we have to call query_keepname() - * now, and pass a NULL dbuf to query_addrrset(). - * - * If we do a query_addrrset() below, we must set fname to - * NULL before leaving this block, otherwise we might try to - * cleanup fname even though we're using it! - */ - query_keepname(client, fname, dbuf); - tname = fname; - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, rdataset); -#ifdef ALLOW_FILTER_AAAA - /* - * Notice the presence of A and AAAAs so - * that AAAAs can be hidden from IPv4 clients. - */ - if (client->filter_aaaa != dns_aaaa_ok) { - if (rdataset->type == dns_rdatatype_aaaa) - have_aaaa = true; - else if (rdataset->type == dns_rdatatype_a) - have_a = true; - } -#endif - /* - * We found an NS RRset; no need to add one later. - */ - if (qtype == dns_rdatatype_any && - rdataset->type == dns_rdatatype_ns) - { - answer_has_ns = true; - } - - if (is_zone && qtype == dns_rdatatype_any && - !dns_db_issecure(db) && - dns_rdatatype_isdnssec(rdataset->type)) { - /* - * The zone is transitioning from insecure - * to secure. Hide the dnssec records from - * ANY queries. - */ - dns_rdataset_disassociate(rdataset); - } else if (client->view->minimal_any && - !TCP(client) && !WANTDNSSEC(client) && - qtype == dns_rdatatype_any && - (rdataset->type == dns_rdatatype_sig || - rdataset->type == dns_rdatatype_rrsig)) { - CTRACE(ISC_LOG_DEBUG(5), "query_find: " - "minimal-any skip signature"); - dns_rdataset_disassociate(rdataset); - } else if (client->view->minimal_any && - !TCP(client) && onetype != 0 && - rdataset->type != onetype && - rdataset->covers != onetype) { - CTRACE(ISC_LOG_DEBUG(5), "query_find: " - "minimal-any skip rdataset"); - dns_rdataset_disassociate(rdataset); - } else if ((qtype == dns_rdatatype_any || - rdataset->type == qtype) && rdataset->type != 0) { -#ifdef ALLOW_FILTER_AAAA - if (dns_rdatatype_isdnssec(rdataset->type)) - have_sig = true; -#endif - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - rpz_st = client->query.rpz_st; - if (rpz_st != NULL) - rdataset->ttl = ISC_MIN(rdataset->ttl, - rpz_st->m.ttl); - if (!is_zone && RECURSIONOK(client)) { - dns_name_t *name; - name = (fname != NULL) ? fname : tname; - query_prefetch(client, name, rdataset); - } - /* - * Remember the first RRtype we find so we - * can skip others with minimal-any. - */ - if (rdataset->type == dns_rdatatype_sig || - rdataset->type == dns_rdatatype_rrsig) - onetype = rdataset->covers; - else - onetype = rdataset->type; - query_addrrset(client, - fname != NULL ? &fname : &tname, - &rdataset, NULL, - NULL, DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - n++; - INSIST(tname != NULL); - /* - * rdataset is non-NULL only in certain - * pathological cases involving DNAMEs. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - rdataset = query_newrdataset(client); - if (rdataset == NULL) - break; - } else { - /* - * We're not interested in this rdataset. - */ - dns_rdataset_disassociate(rdataset); - } - result = dns_rdatasetiter_next(rdsiter); - } - -#ifdef ALLOW_FILTER_AAAA - /* - * Filter AAAAs if there is an A and there is no signature - * or we are supposed to break DNSSEC. - */ - if (client->filter_aaaa == dns_aaaa_break_dnssec) - client->attributes |= NS_CLIENTATTR_FILTER_AAAA; - else if (client->filter_aaaa != dns_aaaa_ok && - have_aaaa && have_a && - (!have_sig || !WANTDNSSEC(client))) - client->attributes |= NS_CLIENTATTR_FILTER_AAAA; -#endif - if (fname != NULL) - dns_message_puttempname(client->message, &fname); - - if (n == 0) { - /* - * No matching rdatasets found in cache. If we were - * searching for RRSIG/SIG, that's probably okay; - * otherwise this is an error condition. - */ - if ((qtype == dns_rdatatype_rrsig || - qtype == dns_rdatatype_sig) && - result == ISC_R_NOMORE) { - if (!is_zone) { - authoritative = false; - dns_rdatasetiter_destroy(&rdsiter); - client->attributes &= ~NS_CLIENTATTR_RA; - goto addauth; - } - - if (qtype == dns_rdatatype_rrsig && - dns_db_issecure(db)) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(client->query.qname, - namebuf, - sizeof(namebuf)); - ns_client_log(client, - DNS_LOGCATEGORY_DNSSEC, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "missing signature " - "for %s", namebuf); - } - - dns_rdatasetiter_destroy(&rdsiter); - fname = query_newname(client, dbuf, &b); - goto nxrrset_rrsig; - } else { - CTRACE(ISC_LOG_ERROR, - "query_find: no matching rdatasets " - "in cache"); - result = DNS_R_SERVFAIL; - } - } - - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_NOMORE) { - CTRACE(ISC_LOG_ERROR, - "query_find: dns_rdatasetiter_destroy failed"); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } else { - /* - * This is the "normal" case -- an ordinary question to which - * we know the answer. - */ - - /* - * If we have a zero ttl from the cache refetch it. - */ - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && - RECURSIONOK(client)) - { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - // query_respond - INSIST(!REDIRECT(client)); - result = query_recurse(client, qtype, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->query.attributes |= - NS_QUERYATTR_RECURSING; - if (dns64) - client->query.attributes |= - NS_QUERYATTR_DNS64; - if (dns64_exclude) - client->query.attributes |= - NS_QUERYATTR_DNS64EXCLUDE; - } else - RECURSE_ERROR(result); - goto cleanup; - } - - /* - * Check to see if the AAAA RRset has non-excluded addresses - * in it. If not look for a A RRset. - * - * Note: the order of dns64_aaaaok() and filter_aaaa check is - * important. Both result is fetches being called but the - * dns64 case goes to db_find while the filter_aaaa case - * adds the records now for later potential exclusion. - */ - INSIST(client->query.dns64_aaaaok == NULL); - - if (qtype == dns_rdatatype_aaaa && !dns64_exclude && - !ISC_LIST_EMPTY(client->view->dns64) && - client->message->rdclass == dns_rdataclass_in && - !dns64_aaaaok(client, rdataset, sigrdataset)) { - /* - * Look to see if there are A records for this - * name. - */ - client->query.dns64_ttl = rdataset->ttl; - SAVE(client->query.dns64_aaaa, rdataset); - SAVE(client->query.dns64_sigaaaa, sigrdataset); - query_releasename(client, &fname); - dns_db_detachnode(db, &node); - type = qtype = dns_rdatatype_a; - dns64_exclude = dns64 = true; - goto db_find; - } - -#ifdef ALLOW_FILTER_AAAA - /* - * Optionally hide AAAAs from IPv4 clients if there is an A. - * We add the AAAAs now, but might refuse to render them later - * after DNSSEC is figured out. - * This could be more efficient, but the whole idea is - * so fundamentally wrong, unavoidably inaccurate, and - * unneeded that it is best to keep it as short as possible. - */ - if (client->filter_aaaa == dns_aaaa_break_dnssec || - (client->filter_aaaa == dns_aaaa_filter && - (!WANTDNSSEC(client) || sigrdataset == NULL || - !dns_rdataset_isassociated(sigrdataset)))) - { - if (qtype == dns_rdatatype_aaaa) { - trdataset = query_newrdataset(client); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - trdataset, NULL); - if (dns_rdataset_isassociated(trdataset)) - dns_rdataset_disassociate(trdataset); - query_putrdataset(client, &trdataset); - - /* - * We have an AAAA but the A is not in our cache. - * Assume any result other than DNS_R_DELEGATION - * or ISC_R_NOTFOUND means there is no A and - * so AAAAs are ok. - * Assume there is no A if we can't recurse - * for this client, although that could be - * the wrong answer. What else can we do? - * Besides, that we have the AAAA and are using - * this mechanism suggests that we care more - * about As than AAAAs and would have cached - * the A if it existed. - */ - if (result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA; - - } else if (authoritative || - !RECURSIONOK(client) || - (result != DNS_R_DELEGATION && - result != ISC_R_NOTFOUND)) { - client->attributes &= - ~NS_CLIENTATTR_FILTER_AAAA; - } else { - /* - * This is an ugly kludge to recurse - * for the A and discard the result. - * - * Continue to add the AAAA now. - * We'll make a note to not render it - * if the recursion for the A succeeds. - */ - INSIST(!REDIRECT(client)); - result = query_recurse(client, - dns_rdatatype_a, - client->query.qname, - NULL, NULL, resuming); - if (result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA_RC; - client->query.attributes |= - NS_QUERYATTR_RECURSING; - } - } - - } else if (qtype == dns_rdatatype_a && - (client->attributes & - NS_CLIENTATTR_FILTER_AAAA_RC) != 0) { - client->attributes &= - ~NS_CLIENTATTR_FILTER_AAAA_RC; - client->attributes |= - NS_CLIENTATTR_FILTER_AAAA; - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - goto cleanup; - } - } -#endif - - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (NOQNAME(rdataset) && WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - /* - * Special case NS handling - */ - if (is_zone && qtype == dns_rdatatype_ns) { - /* - * We've already got an NS, no need to add one in - * the authority section - */ - if (dns_name_equal(client->query.qname, - dns_db_origin(db))) - { - answer_has_ns = true; - } - - /* - * Always add glue for root priming queries, regardless - * of "minimal-responses" setting. - */ - if (dns_name_equal(client->query.qname, dns_rootname)) { - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - dns_db_attach(db, &client->query.gluedb); - } - } - - /* - * Return the time to expire for slave and master zones. - */ - if (zone != NULL && is_zone && qtype == dns_rdatatype_soa && - (client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 && - client->query.restarts == 0) { - dns_zone_t *raw = NULL, *mayberaw; - - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - if (dns_zone_gettype(mayberaw) == dns_zone_slave) { - isc_time_t expiretime; - uint32_t secs; - dns_zone_getexpiretime(zone, &expiretime); - secs = isc_time_seconds(&expiretime); - if (secs >= client->now && - result == ISC_R_SUCCESS) { - client->attributes |= - NS_CLIENTATTR_HAVEEXPIRE; - client->expire = secs - client->now; - } - } - if (dns_zone_gettype(mayberaw) == dns_zone_master) { - dns_rdata_soa_t soa; - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - client->expire = soa.expire; - client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; - } - if (raw != NULL) - dns_zone_detach(&raw); - } - - if (dns64) { - qtype = type = dns_rdatatype_aaaa; - result = query_dns64(client, &fname, rdataset, - sigrdataset, dbuf, - DNS_SECTION_ANSWER); - noqname = NULL; - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, &rdataset); - if (result == ISC_R_NOMORE) { -#ifndef dns64_bis_return_excluded_addresses - if (dns64_exclude) { - if (!is_zone) - goto cleanup; - /* - * Add a fake SOA record. - */ - (void)query_addsoa(client, db, version, - 600, false, - DNS_SECTION_AUTHORITY); - goto cleanup; - } -#endif - if (is_zone) - goto iszone_nxrrset; - else - goto ncache_nxrrset; - } else if (result != ISC_R_SUCCESS) { - eresult = result; - goto cleanup; - } - } else if (client->query.dns64_aaaaok != NULL) { - query_filter64(client, &fname, rdataset, dbuf, - DNS_SECTION_ANSWER); - query_putrdataset(client, &rdataset); - } else { - if (!is_zone && RECURSIONOK(client)) - query_prefetch(client, fname, rdataset); - query_addrrset(client, &fname, &rdataset, - sigrdatasetp, dbuf, DNS_SECTION_ANSWER); - } - - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. - */ - INSIST(rdataset == NULL); - } - - addauth: - CTRACE(ISC_LOG_DEBUG(3), "query_find: addauth"); - /* - * Add NS records to the authority section (if we haven't already - * added them to the answer section). - */ - if (!want_restart && !NOAUTHORITY(client)) { - if (is_zone) { - if (!answer_has_ns) { - (void)query_addns(client, db, version); - } - } else if (!answer_has_ns && qtype != dns_rdatatype_ns) { - if (fname != NULL) { - query_releasename(client, &fname); - } - query_addbestns(client); - } - } - - /* - * Add NSEC records to the authority section if they're needed for - * DNSSEC wildcard proofs. - */ - if (need_wildcardproof && dns_db_issecure(db)) - query_addwildcardproof(client, db, version, - dns_fixedname_name(&wildcardname), - true, false); - cleanup: - // query_done - CTRACE(ISC_LOG_DEBUG(3), "query_find: cleanup"); - /* - * General cleanup. - */ - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) { - rpz_match_clear(rpz_st); - rpz_st->state &= ~DNS_RPZ_DONE_QNAME; - } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } - if (event != NULL) { - free_devent(client, ISC_EVENT_PTR(&event), &event); - } - - if (client->query.gluedb != NULL) { - dns_db_detach(&client->query.gluedb); - } - - /* - * AA bit. - */ - if (client->query.restarts == 0 && !authoritative) { - /* - * We're not authoritative, so we must ensure the AA bit - * isn't set. - */ - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - } - - /* - * Restart the query? - */ - if (want_restart && client->query.restarts < MAX_RESTARTS) { - client->query.restarts++; - goto restart; - } - - if (want_stale) { - dns_ttl_t stale_ttl = 0; - isc_result_t result; - bool staleanswersok = false; - - /* - * Stale answers only make sense if stale_ttl > 0 but - * we want rndc to be able to control returning stale - * answers if they are configured. - */ - dns_db_attach(client->view->cachedb, &db); - result = dns_db_getservestalettl(db, &stale_ttl); - if (result == ISC_R_SUCCESS && stale_ttl > 0) { - switch (client->view->staleanswersok) { - case dns_stale_answer_yes: - staleanswersok = true; - break; - case dns_stale_answer_conf: - staleanswersok = - client->view->staleanswersenable; - break; - case dns_stale_answer_no: - staleanswersok = false; - break; - } - } else { - staleanswersok = false; - } - - if (staleanswersok) { - client->query.dboptions |= DNS_DBFIND_STALEOK; - inc_stats(client, dns_nsstatscounter_trystale); - if (client->query.fetch != NULL) - dns_resolver_destroyfetch( - &client->query.fetch); - goto db_find; - } - dns_db_detach(&db); - want_stale = false; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - if (eresult != ISC_R_SUCCESS && - (!PARTIALANSWER(client) || WANTRECURSION(client) - || eresult == DNS_R_DROP)) { - if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) { - /* - * This was a duplicate query that we are - * recursing on or the result of rate limiting. - * Don't send a response now for a duplicate query, - * because the original will still cause a response. - */ - query_next(client, eresult); - } else { - /* - * If we don't have any answer to give the client, - * or if the client requested recursion and thus wanted - * the complete answer, send an error response. - */ - INSIST(line >= 0); - query_error(client, eresult, line); - } - ns_client_detach(&client); - } else if (!RECURSING(client)) { - /* - * We are done. Set up sortlist data for the message - * rendering code, make a final tweak to the AA bit if the - * auth-nxdomain config option says so, then render and - * send the response. - */ - setup_query_sortlist(client); - - /* - * If this is a referral and the answer to the question - * is in the glue sort it to the start of the additional - * section. - */ - if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) && - client->message->rcode == dns_rcode_noerror && - (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa)) - answer_in_glue(client, qtype); - - if (client->message->rcode == dns_rcode_nxdomain && - client->view->auth_nxdomain == true) - client->message->flags |= DNS_MESSAGEFLAG_AA; - - /* - * If the response is somehow unexpected for the client and this - * is a result of recursion, return an error to the caller - * to indicate it may need to be logged. - */ - if (resuming && - (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) || - client->message->rcode != dns_rcode_noerror)) - eresult = ISC_R_FAILURE; - - query_send(client); - ns_client_detach(&client); - } - CTRACE(ISC_LOG_DEBUG(3), "query_find: done"); - - return (eresult); -} - -static inline void -log_tat(ns_client_t *client) { - char namebuf[DNS_NAME_FORMATSIZE]; - char clientbuf[ISC_NETADDR_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - isc_netaddr_t netaddr; - char *tags = NULL; - size_t taglen = 0; - - if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_INFO)) { - return; - } - - if ((client->query.qtype != dns_rdatatype_null || - !dns_name_istat(client->query.qname)) && - (client->keytag == NULL || - client->query.qtype != dns_rdatatype_dnskey)) - { - return; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - isc_netaddr_format(&netaddr, clientbuf, sizeof(clientbuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - if (client->query.qtype == dns_rdatatype_dnskey) { - uint16_t keytags = client->keytag_len / 2; - size_t len = taglen = sizeof("65000") * keytags + 1; - char *cp = tags = isc_mem_get(client->mctx, taglen); - int i = 0; - - INSIST(client->keytag != NULL); - if (tags != NULL) { - while (keytags-- > 0U) { - int n; - uint16_t keytag; - keytag = (client->keytag[i * 2] << 8) | - client->keytag[i * 2 + 1]; - n = snprintf(cp, len, " %u", keytag); - if (n > 0 && (size_t)n <= len) { - cp += n; - len -= n; - i++; - } else { - break; - } - } - } - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY, - ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s", - namebuf, classbuf, clientbuf, tags != NULL? tags : ""); - if (tags != NULL) { - isc_mem_put(client->mctx, tags, taglen); - } -} - -static inline void -log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - char onbuf[ISC_NETADDR_FORMATSIZE]; - char ednsbuf[sizeof("E(65535)")] = { 0 }; - dns_rdataset_t *rdataset; - int level = ISC_LOG_INFO; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf)); - - if (client->ednsversion >= 0) - snprintf(ednsbuf, sizeof(ednsbuf), "E(%hd)", - client->ednsversion); - - ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, - level, "query: %s %s %s %s%s%s%s%s%s%s (%s)", namebuf, - classbuf, typebuf, WANTRECURSION(client) ? "+" : "-", - (client->signer != NULL) ? "S" : "", ednsbuf, - TCP(client) ? "T" : "", - ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "", - ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "", - HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "", - onbuf); -} - -static inline void -log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - const char *namep, *typep, *classp, *sep1, *sep2; - dns_rdataset_t *rdataset; - - if (!isc_log_wouldlog(ns_g_lctx, level)) - return; - - namep = typep = classp = sep1 = sep2 = ""; - - /* - * Query errors can happen for various reasons. In some cases we cannot - * even assume the query contains a valid question section, so we should - * expect exceptional cases. - */ - if (client->query.origqname != NULL) { - dns_name_format(client->query.origqname, namebuf, - sizeof(namebuf)); - namep = namebuf; - sep1 = " for "; - - rdataset = ISC_LIST_HEAD(client->query.origqname->list); - if (rdataset != NULL) { - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - classp = classbuf; - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - typep = typebuf; - sep2 = "/"; - } - } - - ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY, - level, "query failed (%s)%s%s%s%s%s%s at %s:%d", - isc_result_totext(result), sep1, namep, sep2, - classp, sep2, typep, __FILE__, line); -} - -void -ns_query_start(ns_client_t *client) { - isc_result_t result; - dns_message_t *message; - dns_rdataset_t *rdataset; - ns_client_t *qclient; - dns_rdatatype_t qtype; - unsigned int saved_extflags; - unsigned int saved_flags; - - REQUIRE(NS_CLIENT_VALID(client)); - - message = client->message; - saved_extflags = client->extflags; - saved_flags = client->message->flags; - - CTRACE(ISC_LOG_DEBUG(3), "ns_query_start"); - - /* - * Test only. - */ - if (ns_g_clienttest && !TCP(client)) { - result = ns_client_replace(client); - if (result == ISC_R_SHUTTINGDOWN) { - ns_client_next(client, result); - return; - } else if (result != ISC_R_SUCCESS) { - query_error(client, result, __LINE__); - return; - } - } - - /* - * Ensure that appropriate cleanups occur. - */ - client->next = query_next_callback; - - /* - * Behave as if we don't support DNSSEC if not enabled. - */ - if (!client->view->enablednssec) { - message->flags &= ~DNS_MESSAGEFLAG_CD; - client->extflags &= ~DNS_MESSAGEEXTFLAG_DO; - } - - if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) - client->query.attributes |= NS_QUERYATTR_WANTRECURSION; - - if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) - client->attributes |= NS_CLIENTATTR_WANTDNSSEC; - - switch (client->view->minimalresponses) { - case dns_minimal_no: - break; - case dns_minimal_yes: - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - break; - case dns_minimal_noauth: - client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; - break; - case dns_minimal_noauthrec: - if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) - client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; - break; - } - - if ((client->view->cachedb == NULL) - || (!client->view->additionalfromcache)) { - /* - * We don't have a cache. Turn off cache support and - * recursion. - */ - client->query.attributes &= - ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); - client->attributes |= NS_CLIENTATTR_NOSETFC; - } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || - (message->flags & DNS_MESSAGEFLAG_RD) == 0) { - /* - * If the client isn't allowed to recurse (due to - * "recursion no", the allow-recursion ACL, or the - * lack of a resolver in this view), or if it - * doesn't want recursion, turn recursion off. - */ - client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; - client->attributes |= NS_CLIENTATTR_NOSETFC; - } - - /* - * Check for multiple question queries, since edns1 is dead. - */ - if (message->counts[DNS_SECTION_QUESTION] > 1) { - query_error(client, DNS_R_FORMERR, __LINE__); - return; - } - - /* - * Get the question name. - */ - result = dns_message_firstname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - query_error(client, result, __LINE__); - return; - } - dns_message_currentname(message, DNS_SECTION_QUESTION, - &client->query.qname); - client->query.origqname = client->query.qname; - result = dns_message_nextname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) { - if (result == ISC_R_SUCCESS) { - /* - * There's more than one QNAME in the question - * section. - */ - query_error(client, DNS_R_FORMERR, __LINE__); - } else - query_error(client, result, __LINE__); - return; - } - - if (ns_g_server->log_queries) - log_query(client, saved_flags, saved_extflags); - - /* - * Check for meta-queries like IXFR and AXFR. - */ - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - client->query.qtype = qtype = rdataset->type; - dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype); - - log_tat(client); - - if (dns_rdatatype_ismeta(qtype)) { - switch (qtype) { - case dns_rdatatype_any: - break; /* Let query_find handle it. */ - case dns_rdatatype_ixfr: - case dns_rdatatype_axfr: - ns_xfr_start(client, rdataset->type); - return; - case dns_rdatatype_maila: - case dns_rdatatype_mailb: - query_error(client, DNS_R_NOTIMP, __LINE__); - return; - case dns_rdatatype_tkey: - result = dns_tkey_processquery(client->message, - ns_g_server->tkeyctx, - client->view->dynamickeys); - if (result == ISC_R_SUCCESS) - query_send(client); - else - query_error(client, result, __LINE__); - return; - default: /* TSIG, etc. */ - query_error(client, DNS_R_FORMERR, __LINE__); - return; - } - } - - /* - * Turn on minimal response for (C)DNSKEY and (C)DS queries. - */ - if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds || - qtype == dns_rdatatype_cdnskey || qtype == dns_rdatatype_cds) - { - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - } else if (qtype == dns_rdatatype_ns) { - /* - * Always turn on additional records for NS queries. - */ - client->query.attributes &= ~(NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - } - - /* - * Maybe turn on minimal responses for ANY queries. - */ - if (qtype == dns_rdatatype_any && - client->view->minimal_any && !TCP(client)) - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - /* - * Turn on minimal responses for EDNS/UDP bufsize 512 queries. - */ - if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client)) - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - /* - * If the client has requested that DNSSEC checking be disabled, - * allow lookups to return pending data and instruct the resolver - * to return data before validation has completed. - * - * We don't need to set DNS_DBFIND_PENDINGOK when validation is - * disabled as there will be no pending data. - */ - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0 || - qtype == dns_rdatatype_rrsig) - { - client->query.dboptions |= DNS_DBFIND_PENDINGOK; - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - } else if (!client->view->enablevalidation) - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - - /* - * Allow glue NS records to be added to the authority section - * if the answer is secure. - */ - if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) { - client->query.attributes &= ~NS_QUERYATTR_SECURE; - } - - /* - * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query. - * This allows AD to be returned on queries without DO set. - */ - if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) - client->attributes |= NS_CLIENTATTR_WANTAD; - - /* - * This is an ordinary query. - */ - result = dns_message_reply(message, true); - if (result != ISC_R_SUCCESS) { - query_next(client, result); - return; - } - - /* - * Assume authoritative response until it is known to be - * otherwise. - * - * If "-T noaa" has been set on the command line don't set - * AA on authoritative answers. - */ - if (!ns_g_noaa) - message->flags |= DNS_MESSAGEFLAG_AA; - - /* - * Set AD. We must clear it if we add non-validated data to a - * response. - */ - if (WANTDNSSEC(client) || WANTAD(client)) - message->flags |= DNS_MESSAGEFLAG_AD; - - qclient = NULL; - ns_client_attach(client, &qclient); - (void)query_find(qclient, NULL, qtype); -} diff --git a/bin/named-sdb/server.c b/bin/named-sdb/server.c deleted file mode 100644 index 3a5ba91..0000000 --- a/bin/named-sdb/server.c +++ /dev/null @@ -1,14734 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -#include -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#include -#endif - -#ifdef HAVE_LMDB -#include -#define count_newzones count_newzones_db -#define configure_newzones configure_newzones_db -#define dumpzone dumpzone_db -#else /* HAVE_LMDB */ -#define count_newzones count_newzones_file -#define configure_newzones configure_newzones_file -#define dumpzone dumpzone_file -#endif /* HAVE_LMDB */ - -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)-1) -#endif - -#ifndef SIZE_AS_PERCENT -#define SIZE_AS_PERCENT ((size_t)-2) -#endif - -#ifdef TUNE_LARGE -#define RESOLVER_NTASKS 523 -#define UDPBUFFERS 32768 -#define EXCLBUFFERS 32768 -#else -#define RESOLVER_NTASKS 31 -#define UDPBUFFERS 1000 -#define EXCLBUFFERS 4096 -#endif /* TUNE_LARGE */ - -/*% - * Check an operation for failure. Assumes that the function - * using it has a 'result' variable and a 'cleanup' label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -#define TCHECK(op) \ - do { tresult = (op); \ - if (tresult != ISC_R_SUCCESS) { \ - isc_buffer_clear(*text); \ - goto cleanup; \ - } \ - } while (0) - -#define CHECKM(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s: %s", msg, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKMF(op, msg, file) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s '%s': %s", msg, file, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKFATAL(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) \ - fatal(server, msg, result); \ - } while (0) \ - -/*% - * Maximum ADB size for views that share a cache. Use this limit to suppress - * the total of memory footprint, which should be the main reason for sharing - * a cache. Only effective when a finite max-cache-size is specified. - * This is currently defined to be 8MB. - */ -#define MAX_ADB_SIZE_FOR_CACHESHARE 8388608U - -struct ns_dispatch { - isc_sockaddr_t addr; - unsigned int dispatchgen; - dns_dispatch_t *dispatch; - ISC_LINK(struct ns_dispatch) link; -}; - -struct ns_cache { - dns_cache_t *cache; - dns_view_t *primaryview; - bool needflush; - bool adbsizeadjusted; - dns_rdataclass_t rdclass; - ISC_LINK(ns_cache_t) link; -}; - -struct dumpcontext { - isc_mem_t *mctx; - bool dumpcache; - bool dumpzones; - bool dumpadb; - bool dumpbad; - bool dumpfail; - FILE *fp; - ISC_LIST(struct viewlistentry) viewlist; - struct viewlistentry *view; - struct zonelistentry *zone; - dns_dumpctx_t *mdctx; - dns_db_t *db; - dns_db_t *cache; - isc_task_t *task; - dns_dbversion_t *version; -}; - -struct viewlistentry { - dns_view_t *view; - ISC_LINK(struct viewlistentry) link; - ISC_LIST(struct zonelistentry) zonelist; -}; - -struct zonelistentry { - dns_zone_t *zone; - ISC_LINK(struct zonelistentry) link; -}; - -/*% - * Configuration context to retain for each view that allows - * new zones to be added at runtime. - */ -typedef struct ns_cfgctx { - isc_mem_t * mctx; - cfg_parser_t * conf_parser; - cfg_parser_t * add_parser; - cfg_obj_t * config; - cfg_obj_t * vconfig; - cfg_obj_t * nzf_config; - cfg_aclconfctx_t * actx; -} ns_cfgctx_t; - -/*% - * A function to write out added-zone configuration to the new_zone_file - * specified in 'view'. Maybe called by delete_zoneconf(). - */ -typedef isc_result_t (*nzfwriter_t)(const cfg_obj_t *config, dns_view_t *view); - -/*% - * Holds state information for the initial zone loading process. - * Uses the isc_refcount structure to count the number of views - * with pending zone loads, dereferencing as each view finishes. - */ -typedef struct { - ns_server_t *server; - bool reconfig; - isc_refcount_t refs; -} ns_zoneload_t; - -typedef struct { - ns_server_t *server; -} catz_cb_data_t; - -typedef struct catz_chgzone_event { - ISC_EVENT_COMMON(struct catz_chgzone_event); - dns_catz_entry_t *entry; - dns_catz_zone_t *origin; - dns_view_t *view; - catz_cb_data_t *cbd; - bool mod; -} catz_chgzone_event_t; - -typedef struct { - unsigned int magic; -#define DZARG_MAGIC ISC_MAGIC('D', 'z', 'a', 'r') - isc_buffer_t **text; - isc_result_t result; -} ns_dzarg_t; - -/* - * These zones should not leak onto the Internet. - */ -const char *empty_zones[] = { - /* RFC 1918 */ - "10.IN-ADDR.ARPA", - "16.172.IN-ADDR.ARPA", - "17.172.IN-ADDR.ARPA", - "18.172.IN-ADDR.ARPA", - "19.172.IN-ADDR.ARPA", - "20.172.IN-ADDR.ARPA", - "21.172.IN-ADDR.ARPA", - "22.172.IN-ADDR.ARPA", - "23.172.IN-ADDR.ARPA", - "24.172.IN-ADDR.ARPA", - "25.172.IN-ADDR.ARPA", - "26.172.IN-ADDR.ARPA", - "27.172.IN-ADDR.ARPA", - "28.172.IN-ADDR.ARPA", - "29.172.IN-ADDR.ARPA", - "30.172.IN-ADDR.ARPA", - "31.172.IN-ADDR.ARPA", - "168.192.IN-ADDR.ARPA", - - /* RFC 6598 */ - "64.100.IN-ADDR.ARPA", - "65.100.IN-ADDR.ARPA", - "66.100.IN-ADDR.ARPA", - "67.100.IN-ADDR.ARPA", - "68.100.IN-ADDR.ARPA", - "69.100.IN-ADDR.ARPA", - "70.100.IN-ADDR.ARPA", - "71.100.IN-ADDR.ARPA", - "72.100.IN-ADDR.ARPA", - "73.100.IN-ADDR.ARPA", - "74.100.IN-ADDR.ARPA", - "75.100.IN-ADDR.ARPA", - "76.100.IN-ADDR.ARPA", - "77.100.IN-ADDR.ARPA", - "78.100.IN-ADDR.ARPA", - "79.100.IN-ADDR.ARPA", - "80.100.IN-ADDR.ARPA", - "81.100.IN-ADDR.ARPA", - "82.100.IN-ADDR.ARPA", - "83.100.IN-ADDR.ARPA", - "84.100.IN-ADDR.ARPA", - "85.100.IN-ADDR.ARPA", - "86.100.IN-ADDR.ARPA", - "87.100.IN-ADDR.ARPA", - "88.100.IN-ADDR.ARPA", - "89.100.IN-ADDR.ARPA", - "90.100.IN-ADDR.ARPA", - "91.100.IN-ADDR.ARPA", - "92.100.IN-ADDR.ARPA", - "93.100.IN-ADDR.ARPA", - "94.100.IN-ADDR.ARPA", - "95.100.IN-ADDR.ARPA", - "96.100.IN-ADDR.ARPA", - "97.100.IN-ADDR.ARPA", - "98.100.IN-ADDR.ARPA", - "99.100.IN-ADDR.ARPA", - "100.100.IN-ADDR.ARPA", - "101.100.IN-ADDR.ARPA", - "102.100.IN-ADDR.ARPA", - "103.100.IN-ADDR.ARPA", - "104.100.IN-ADDR.ARPA", - "105.100.IN-ADDR.ARPA", - "106.100.IN-ADDR.ARPA", - "107.100.IN-ADDR.ARPA", - "108.100.IN-ADDR.ARPA", - "109.100.IN-ADDR.ARPA", - "110.100.IN-ADDR.ARPA", - "111.100.IN-ADDR.ARPA", - "112.100.IN-ADDR.ARPA", - "113.100.IN-ADDR.ARPA", - "114.100.IN-ADDR.ARPA", - "115.100.IN-ADDR.ARPA", - "116.100.IN-ADDR.ARPA", - "117.100.IN-ADDR.ARPA", - "118.100.IN-ADDR.ARPA", - "119.100.IN-ADDR.ARPA", - "120.100.IN-ADDR.ARPA", - "121.100.IN-ADDR.ARPA", - "122.100.IN-ADDR.ARPA", - "123.100.IN-ADDR.ARPA", - "124.100.IN-ADDR.ARPA", - "125.100.IN-ADDR.ARPA", - "126.100.IN-ADDR.ARPA", - "127.100.IN-ADDR.ARPA", - - /* RFC 5735 and RFC 5737 */ - "0.IN-ADDR.ARPA", /* THIS NETWORK */ - "127.IN-ADDR.ARPA", /* LOOPBACK */ - "254.169.IN-ADDR.ARPA", /* LINK LOCAL */ - "2.0.192.IN-ADDR.ARPA", /* TEST NET */ - "100.51.198.IN-ADDR.ARPA", /* TEST NET 2 */ - "113.0.203.IN-ADDR.ARPA", /* TEST NET 3 */ - "255.255.255.255.IN-ADDR.ARPA", /* BROADCAST */ - - /* Local IPv6 Unicast Addresses */ - "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", - "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", - /* LOCALLY ASSIGNED LOCAL ADDRESS SCOPE */ - "D.F.IP6.ARPA", - "8.E.F.IP6.ARPA", /* LINK LOCAL */ - "9.E.F.IP6.ARPA", /* LINK LOCAL */ - "A.E.F.IP6.ARPA", /* LINK LOCAL */ - "B.E.F.IP6.ARPA", /* LINK LOCAL */ - - /* Example Prefix, RFC 3849. */ - "8.B.D.0.1.0.0.2.IP6.ARPA", - - /* RFC 7534 */ - "EMPTY.AS112.ARPA", - - /* RFC 8375 */ - "HOME.ARPA", - - NULL -}; - -ISC_PLATFORM_NORETURN_PRE static void -fatal(ns_server_t *server,const char *msg, isc_result_t result) -ISC_PLATFORM_NORETURN_POST; - -static void -ns_server_reload(isc_task_t *task, isc_event_t *event); - -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenelt_t **target); -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenlist_t **target); - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype); - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates); - -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf, - bool added, bool old_rpz_ok, - bool modify); - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx); - -static isc_result_t -add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx); - -static void -end_reserved_dispatches(ns_server_t *server, bool all); - -static void -newzone_cfgctx_destroy(void **cfgp); - -static inline isc_result_t -putstr(isc_buffer_t **b, const char *str); - -static isc_result_t -putmem(isc_buffer_t **b, const char *str, size_t len); - -static isc_result_t -putuint8(isc_buffer_t **b, uint8_t val); - -static inline isc_result_t -putnull(isc_buffer_t **b); - -static int -count_zones(const cfg_obj_t *conf); - -#ifdef HAVE_LMDB -static isc_result_t -migrate_nzf(dns_view_t *view); - -static isc_result_t -nzd_writable(dns_view_t *view); - -static isc_result_t -nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi); - -static isc_result_t -nzd_env_reopen(dns_view_t *view); - -static void -nzd_env_close(dns_view_t *view); - -static isc_result_t -nzd_close(MDB_txn **txnp, bool commit); - -static isc_result_t -nzd_count(dns_view_t *view, int *countp); -#else -static isc_result_t -nzf_append(dns_view_t *view, const cfg_obj_t *zconfig); -#endif - -/*% - * Configure a single view ACL at '*aclp'. Get its configuration from - * 'vconfig' (for per-view configuration) and maybe from 'config' - */ -static isc_result_t -configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config, - const cfg_obj_t *gconfig, const char *aclname, - const char *acltuplename, cfg_aclconfctx_t *actx, - isc_mem_t *mctx, dns_acl_t **aclp) -{ - isc_result_t result; - const cfg_obj_t *maps[4]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) { - dns_acl_detach(aclp); - } - if (vconfig != NULL) { - maps[i++] = cfg_tuple_get(vconfig, "options"); - } - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - if (gconfig != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(gconfig, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - maps[i] = NULL; - - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - /* - * No value available. *aclp == NULL. - */ - return (ISC_R_SUCCESS); - } - - if (acltuplename != NULL) { - /* - * If the ACL is given in an optional tuple, retrieve it. - * The parser should have ensured that a valid object be - * returned. - */ - aclobj = cfg_tuple_get(aclobj, acltuplename); - } - - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, - actx, mctx, 0, aclp); - - return (result); -} - -/*% - * Configure a sortlist at '*aclp'. Essentially the same as - * configure_view_acl() except it calls cfg_acl_fromconfig with a - * nest_level value of 2. - */ -static isc_result_t -configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - dns_acl_t **aclp) -{ - isc_result_t result; - const cfg_obj_t *maps[3]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) - dns_acl_detach(aclp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - (void)ns_config_get(maps, "sortlist", &aclobj); - if (aclobj == NULL) - return (ISC_R_SUCCESS); - - /* - * Use a nest level of 3 for the "top level" of the sortlist; - * this means each entry in the top three levels will be stored - * as lists of separate, nested ACLs, rather than merged together - * into IP tables as is usually done with ACLs. - */ - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, - actx, mctx, 3, aclp); - - return (result); -} - -static isc_result_t -configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, - const char *confname, const char *conftuplename, - isc_mem_t *mctx, dns_rbt_t **rbtp) -{ - isc_result_t result; - const cfg_obj_t *maps[3]; - const cfg_obj_t *obj = NULL; - const cfg_listelt_t *element; - int i = 0; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - const char *str; - const cfg_obj_t *nameobj; - - if (*rbtp != NULL) - dns_rbt_destroy(rbtp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - (void)ns_config_get(maps, confname, &obj); - if (obj == NULL) - /* - * No value available. *rbtp == NULL. - */ - return (ISC_R_SUCCESS); - - if (conftuplename != NULL) { - obj = cfg_tuple_get(obj, conftuplename); - if (cfg_obj_isvoid(obj)) - return (ISC_R_SUCCESS); - } - - result = dns_rbt_create(mctx, NULL, NULL, rbtp); - if (result != ISC_R_SUCCESS) - return (result); - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) { - nameobj = cfg_listelt_value(element); - str = cfg_obj_asstring(nameobj); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - /* - * We don't need the node data, but need to set dummy data to - * avoid a partial match with an empty node. For example, if - * we have foo.example.com and bar.example.com, we'd get a match - * for baz.example.com, which is not the expected result. - * We simply use (void *)1 as the dummy data. - */ - result = dns_rbt_addname(*rbtp, name, (void *)1); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR, - "failed to add %s for %s: %s", - str, confname, isc_result_totext(result)); - goto cleanup; - } - - } - - return (result); - - cleanup: - dns_rbt_destroy(rbtp); - return (result); - -} - -static isc_result_t -dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, - bool managed, dst_key_t **target, isc_mem_t *mctx) -{ - dns_rdataclass_t viewclass; - dns_rdata_dnskey_t keystruct; - uint32_t flags, proto, alg; - const char *keystr, *keynamestr; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; - unsigned char rrdata[4096]; - isc_buffer_t rrdatabuf; - isc_region_t r; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - isc_buffer_t namebuf; - isc_result_t result; - dst_key_t *dstkey = NULL; - - INSIST(target != NULL && *target == NULL); - - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); - keyname = dns_fixedname_name(&fkeyname); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - - if (managed) { - const char *initmethod; - initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init")); - - if (strcasecmp(initmethod, "initial-key") != 0) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "managed key '%s': " - "invalid initialization method '%s'", - keynamestr, initmethod); - result = ISC_R_FAILURE; - goto cleanup; - } - } - - if (vconfig == NULL) - viewclass = dns_rdataclass_in; - else { - const cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - } - keystruct.common.rdclass = viewclass; - keystruct.common.rdtype = dns_rdatatype_dnskey; - /* - * The key data in keystruct is not dynamically allocated. - */ - keystruct.mctx = NULL; - - ISC_LINK_INIT(&keystruct.common, link); - - if (flags > 0xffff) - CHECKM(ISC_R_RANGE, "key flags"); - if (proto > 0xff) - CHECKM(ISC_R_RANGE, "key protocol"); - if (alg > 0xff) - CHECKM(ISC_R_RANGE, "key algorithm"); - keystruct.flags = (uint16_t)flags; - keystruct.protocol = (uint8_t)proto; - keystruct.algorithm = (uint8_t)alg; - - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - CHECK(isc_base64_decodestring(keystr, &keydatabuf)); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; - - if ((keystruct.algorithm == DST_ALG_RSASHA1 || - keystruct.algorithm == DST_ALG_RSAMD5) && - r.length > 1 && r.base[0] == 1 && r.base[1] == 3) - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "%s key '%s' has a weak exponent", - managed ? "managed" : "trusted", - keynamestr); - - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf)); - dns_fixedname_init(&fkeyname); - isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL)); - CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, - mctx, &dstkey)); - - *target = dstkey; - return (ISC_R_SUCCESS); - - cleanup: - if (result == DST_R_NOCRYPTO) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "ignoring %s key for '%s': no crypto support", - managed ? "managed" : "trusted", - keynamestr); - } else if (result == DST_R_UNSUPPORTEDALG) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "skipping %s key for '%s': %s", - managed ? "managed" : "trusted", - keynamestr, isc_result_totext(result)); - } else { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring %s key for '%s': %s", - managed ? "managed" : "trusted", - keynamestr, isc_result_totext(result)); - result = ISC_R_FAILURE; - } - - if (dstkey != NULL) - dst_key_free(&dstkey); - - return (result); -} - -static isc_result_t -load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig, - dns_view_t *view, bool managed, - dns_name_t *keyname, isc_mem_t *mctx) -{ - const cfg_listelt_t *elt, *elt2; - const cfg_obj_t *key, *keylist; - dst_key_t *dstkey = NULL; - isc_result_t result; - dns_keytable_t *secroots = NULL; - - CHECK(dns_view_getsecroots(view, &secroots)); - - for (elt = cfg_list_first(keys); - elt != NULL; - elt = cfg_list_next(elt)) { - keylist = cfg_listelt_value(elt); - - for (elt2 = cfg_list_first(keylist); - elt2 != NULL; - elt2 = cfg_list_next(elt2)) { - key = cfg_listelt_value(elt2); - result = dstkey_fromconfig(vconfig, key, managed, - &dstkey, mctx); - if (result == DST_R_UNSUPPORTEDALG) { - result = ISC_R_SUCCESS; - continue; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * If keyname was specified, we only add that key. - */ - if (keyname != NULL && - !dns_name_equal(keyname, dst_key_name(dstkey))) - { - dst_key_free(&dstkey); - continue; - } - - CHECK(dns_keytable_add(secroots, managed, &dstkey)); - } - } - - cleanup: - if (dstkey != NULL) - dst_key_free(&dstkey); - if (secroots != NULL) - dns_keytable_detach(&secroots); - if (result == DST_R_NOCRYPTO) - result = ISC_R_SUCCESS; - return (result); -} - -/*% - * Check whether a key has been successfully loaded. - */ -static bool -keyloaded(dns_view_t *view, dns_name_t *name) { - isc_result_t result; - dns_keytable_t *secroots = NULL; - dns_keynode_t *keynode = NULL; - - result = dns_view_getsecroots(view, &secroots); - if (result != ISC_R_SUCCESS) - return (false); - - result = dns_keytable_find(secroots, name, &keynode); - - if (keynode != NULL) - dns_keytable_detachkeynode(secroots, &keynode); - if (secroots != NULL) - dns_keytable_detach(&secroots); - - return (result == ISC_R_SUCCESS); -} - -/*% - * Configure DNSSEC keys for a view. - * - * The per-view configuration values and the server-global defaults are read - * from 'vconfig' and 'config'. - */ -static isc_result_t -configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig, - const cfg_obj_t *config, const cfg_obj_t *bindkeys, - bool auto_root, isc_mem_t *mctx) -{ - isc_result_t result = ISC_R_SUCCESS; - const cfg_obj_t *view_keys = NULL; - const cfg_obj_t *global_keys = NULL; - const cfg_obj_t *view_managed_keys = NULL; - const cfg_obj_t *global_managed_keys = NULL; - const cfg_obj_t *maps[4]; - const cfg_obj_t *voptions = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *obj = NULL; - const char *directory; - bool need_mkey_dir = false; - int i = 0; - - /* We don't need trust anchors for the _bind view */ - if (strcmp(view->name, "_bind") == 0 && - view->rdclass == dns_rdataclass_chaos) - { - return (ISC_R_SUCCESS); - } - - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - if (voptions != NULL) { - (void) cfg_map_get(voptions, "trusted-keys", - &view_keys); - (void) cfg_map_get(voptions, "managed-keys", - &view_managed_keys); - maps[i++] = voptions; - } - } - - if (config != NULL) { - (void)cfg_map_get(config, "trusted-keys", &global_keys); - (void)cfg_map_get(config, "managed-keys", &global_managed_keys); - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - maps[i++] = options; - } - } - - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = dns_view_initsecroots(view, mctx); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "couldn't create keytable"); - return (ISC_R_UNEXPECTED); - } - - result = dns_view_initntatable(view, ns_g_taskmgr, ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "couldn't create NTA table"); - return (ISC_R_UNEXPECTED); - } - - if (auto_root && view->rdclass == dns_rdataclass_in) { - const cfg_obj_t *builtin_keys = NULL; - const cfg_obj_t *builtin_managed_keys = NULL; - - /* - * If bind.keys exists and is populated, it overrides - * the managed-keys clause hard-coded in ns_g_config. - */ - if (bindkeys != NULL) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "obtaining root key for view %s " - "from '%s'", - view->name, ns_g_server->bindkeysfile); - - (void)cfg_map_get(bindkeys, "trusted-keys", - &builtin_keys); - (void)cfg_map_get(bindkeys, "managed-keys", - &builtin_managed_keys); - - if ((builtin_keys == NULL) && - (builtin_managed_keys == NULL)) - isc_log_write(ns_g_lctx, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "dnssec-validation auto: " - "WARNING: root zone key " - "not found"); - } - - if ((builtin_keys == NULL) && - (builtin_managed_keys == NULL)) - { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using built-in root key for view %s", - view->name); - - (void)cfg_map_get(ns_g_config, "trusted-keys", - &builtin_keys); - (void)cfg_map_get(ns_g_config, "managed-keys", - &builtin_managed_keys); - } - - if (builtin_keys != NULL) - CHECK(load_view_keys(builtin_keys, vconfig, view, - false, dns_rootname, mctx)); - if (builtin_managed_keys != NULL) - CHECK(load_view_keys(builtin_managed_keys, vconfig, - view, true, dns_rootname, - mctx)); - - if (!keyloaded(view, dns_rootname)) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "root key not loaded"); - result = ISC_R_FAILURE; - goto cleanup; - } - } - - CHECK(load_view_keys(view_keys, vconfig, view, false, - NULL, mctx)); - CHECK(load_view_keys(view_managed_keys, vconfig, view, true, - NULL, mctx)); - - if (view->rdclass == dns_rdataclass_in) { - CHECK(load_view_keys(global_keys, vconfig, view, false, - NULL, mctx)); - CHECK(load_view_keys(global_managed_keys, vconfig, view, - true, NULL, mctx)); - } - - /* - * Add key zone for managed-keys. - */ - need_mkey_dir = (auto_root || view_managed_keys != NULL); - - obj = NULL; - (void)ns_config_get(maps, "managed-keys-directory", &obj); - directory = (obj != NULL ? cfg_obj_asstring(obj) : NULL); - if (directory != NULL) { - result = isc_file_isdirectory(directory); - } - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "invalid managed-keys-directory %s: %s", - directory, isc_result_totext(result)); - goto cleanup; - - } else if (need_mkey_dir && directory != NULL) { - if (!isc_file_isdirwritable(directory)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "managed-keys-directory '%s' " - "is not writable", directory); - result = ISC_R_NOPERM; - goto cleanup; - } - } else if (need_mkey_dir) { - char cwd[PATH_MAX]; - - if (getcwd(cwd, sizeof(cwd)) == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to retrieve " - "current working directory"); - result = ISC_R_FAILURE; - goto cleanup; - } - - if (!isc_file_isdirwritable(cwd)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "working directory '%s' " - "is not writable", cwd); - result = ISC_R_NOPERM; - goto cleanup; - } - } - - CHECK(add_keydata_zone(view, directory, ns_g_mctx)); - - cleanup: - return (result); -} - -static isc_result_t -mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) { - const cfg_listelt_t *element; - const cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - bool value; - isc_result_t result; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(mbs); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - value = cfg_obj_asboolean(cfg_tuple_get(obj, "value")); - CHECK(dns_resolver_setmustbesecure(resolver, name, value)); - } - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -/*% - * Get a dispatch appropriate for the resolver of a given view. - */ -static isc_result_t -get_view_querysource_dispatch(const cfg_obj_t **maps, int af, - dns_dispatch_t **dispatchp, isc_dscp_t *dscpp, - bool is_firstview) -{ - isc_result_t result = ISC_R_FAILURE; - dns_dispatch_t *disp; - isc_sockaddr_t sa; - unsigned int attrs, attrmask; - const cfg_obj_t *obj = NULL; - unsigned int maxdispatchbuffers = UDPBUFFERS; - isc_dscp_t dscp = -1; - - switch (af) { - case AF_INET: - result = ns_config_get(maps, "query-source", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - case AF_INET6: - result = ns_config_get(maps, "query-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - sa = *(cfg_obj_assockaddr(obj)); - INSIST(isc_sockaddr_pf(&sa) == af); - - dscp = cfg_obj_getdscp(obj); - if (dscp != -1 && dscpp != NULL) - *dscpp = dscp; - - /* - * If we don't support this address family, we're done! - */ - switch (af) { - case AF_INET: - result = isc_net_probeipv4(); - break; - case AF_INET6: - result = isc_net_probeipv6(); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - /* - * Try to find a dispatcher that we can share. - */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (af) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - } - if (isc_sockaddr_getport(&sa) == 0) { - attrs |= DNS_DISPATCHATTR_EXCLUSIVE; - maxdispatchbuffers = EXCLBUFFERS; - } else { - INSIST(obj != NULL); - if (is_firstview) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_INFO, - "using specific query-source port " - "suppresses port randomization and can be " - "insecure."); - } - } - - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - disp = NULL; - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &sa, 4096, - maxdispatchbuffers, 32768, 16411, 16433, - attrs, attrmask, &disp); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_t any; - char buf[ISC_SOCKADDR_FORMATSIZE]; - - switch (af) { - case AF_INET: - isc_sockaddr_any(&any); - break; - case AF_INET6: - isc_sockaddr_any6(&any); - break; - } - if (isc_sockaddr_equal(&sa, &any)) - return (ISC_R_SUCCESS); - isc_sockaddr_format(&sa, buf, sizeof(buf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not get query source dispatcher (%s)", - buf); - return (result); - } - - *dispatchp = disp; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_order(dns_order_t *order, const cfg_obj_t *ent) { - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - const cfg_obj_t *obj; - dns_fixedname_t fixed; - unsigned int mode = 0; - const char *str; - isc_buffer_t b; - isc_result_t result; - bool addroot; - - result = ns_config_getclass(cfg_tuple_get(ent, "class"), - dns_rdataclass_any, &rdclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_config_gettype(cfg_tuple_get(ent, "type"), - dns_rdatatype_any, &rdtype); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "name"); - if (cfg_obj_isstring(obj)) - str = cfg_obj_asstring(obj); - else - str = "*"; - addroot = (strcmp(str, "*") == 0); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dns_fixedname_init(&fixed); - result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "ordering"); - INSIST(cfg_obj_isstring(obj)); - str = cfg_obj_asstring(obj); - if (!strcasecmp(str, "fixed")) { -#if DNS_RDATASET_FIXED - mode = DNS_RDATASETATTR_FIXEDORDER; -#else - mode = 0; -#endif /* DNS_RDATASET_FIXED */ - } else if (!strcasecmp(str, "random")) { - mode = DNS_RDATASETATTR_RANDOMIZE; - } else if (!strcasecmp(str, "cyclic")) { - mode = 0; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * "*" should match everything including the root (BIND 8 compat). - * As dns_name_matcheswildcard(".", "*.") returns FALSE add a - * explicit entry for "." when the name is "*". - */ - if (addroot) { - result = dns_order_add(order, dns_rootname, - rdtype, rdclass, mode); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (dns_order_add(order, dns_fixedname_name(&fixed), - rdtype, rdclass, mode)); -} - -static isc_result_t -configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { - isc_netaddr_t na; - dns_peer_t *peer; - const cfg_obj_t *obj; - const char *str; - isc_result_t result; - unsigned int prefixlen; - - cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen); - - peer = NULL; - result = dns_peer_newprefix(mctx, &na, prefixlen, &peer); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - (void)cfg_map_get(cpeer, "bogus", &obj); - if (obj != NULL) - CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "provide-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-expire", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestexpire(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-nsid", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "send-cookie", &obj); - if (obj != NULL) - CHECK(dns_peer_setsendcookie(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns", &obj); - if (obj != NULL) - CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns-udp-size", &obj); - if (obj != NULL) { - uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setudpsize(peer, (uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "edns-version", &obj); - if (obj != NULL) { - uint32_t ednsversion = cfg_obj_asuint32(obj); - if (ednsversion > 255) - ednsversion = 255; - CHECK(dns_peer_setednsversion(peer, (uint8_t)ednsversion)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "max-udp-size", &obj); - if (obj != NULL) { - uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setmaxudp(peer, (uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "tcp-only", &obj); - if (obj != NULL) - CHECK(dns_peer_setforcetcp(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfers", &obj); - if (obj != NULL) - CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfer-format", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) { - CHECK(dns_peer_settransferformat(peer, - dns_many_answers)); - } else if (strcasecmp(str, "one-answer") == 0) { - CHECK(dns_peer_settransferformat(peer, - dns_one_answer)); - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - (void)cfg_map_get(cpeer, "keys", &obj); - if (obj != NULL) { - result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "transfer-source", &obj); - else - (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_settransfersource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_settransferdscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "notify-source", &obj); - else - (void)cfg_map_get(cpeer, "notify-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setnotifysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_setnotifydscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "query-source", &obj); - else - (void)cfg_map_get(cpeer, "query-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setquerysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_peer_setquerydscp(peer, cfg_obj_getdscp(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - *peerp = peer; - return (ISC_R_SUCCESS); - - cleanup: - dns_peer_detach(&peer); - return (result); -} - -#ifdef HAVE_DLOPEN -static isc_result_t -configure_dyndb(const cfg_obj_t *dyndb, isc_mem_t *mctx, - const dns_dyndbctx_t *dctx) -{ - isc_result_t result = ISC_R_SUCCESS; - const cfg_obj_t *obj; - const char *name, *library; - - /* Get the name of the dyndb instance and the library path . */ - name = cfg_obj_asstring(cfg_tuple_get(dyndb, "name")); - library = cfg_obj_asstring(cfg_tuple_get(dyndb, "library")); - - obj = cfg_tuple_get(dyndb, "parameters"); - if (obj != NULL) - result = dns_dyndb_load(library, name, cfg_obj_asstring(obj), - cfg_obj_file(obj), cfg_obj_line(obj), - mctx, dctx); - - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dynamic database '%s' configuration failed: %s", - name, isc_result_totext(result)); - return (result); -} -#endif - - -static isc_result_t -disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - const cfg_obj_t *algorithms; - const cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - - algorithms = cfg_tuple_get(disabled, "algorithms"); - for (element = cfg_list_first(algorithms); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_secalg_t alg; - - DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); - r.length = strlen(r.base); - - result = dns_secalg_fromtext(&alg, &r); - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { - uint8_t ui; - result = isc_parse_uint8(&ui, r.base, 10); - alg = ui; - } - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); - } - cleanup: - return (result); -} - -static isc_result_t -disable_ds_digests(const cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - const cfg_obj_t *digests; - const cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - - digests = cfg_tuple_get(disabled, "digests"); - for (element = cfg_list_first(digests); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_dsdigest_t digest; - - DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); - r.length = strlen(r.base); - - /* disable_ds_digests handles numeric values. */ - result = dns_dsdigest_fromtext(&digest, &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_ds_digest(resolver, name, digest)); - } - cleanup: - return (result); -} - -static bool -on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) { - const cfg_listelt_t *element; - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - const cfg_obj_t *value; - const char *str; - isc_buffer_t b; - - name = dns_fixedname_initname(&fixed); - - for (element = cfg_list_first(disablelist); - element != NULL; - element = cfg_list_next(element)) - { - value = cfg_listelt_value(element); - str = cfg_obj_asstring(value); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(name, &b, dns_rootname, - 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dns_name_equal(name, zonename)) - return (true); - } - return (false); -} - -static isc_result_t -check_dbtype(dns_zone_t *zone, unsigned int dbtypec, const char **dbargv, - isc_mem_t *mctx) -{ - char **argv = NULL; - unsigned int i; - isc_result_t result = ISC_R_SUCCESS; - - CHECK(dns_zone_getdbtype(zone, &argv, mctx)); - - /* - * Check that all the arguments match. - */ - for (i = 0; i < dbtypec; i++) - if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) - CHECK(ISC_R_FAILURE); - - /* - * Check that there are not extra arguments. - */ - if (i == dbtypec && argv[i] != NULL) - result = ISC_R_FAILURE; - - cleanup: - isc_mem_free(mctx, argv); - return (result); -} - -static isc_result_t -setquerystats(dns_zone_t *zone, isc_mem_t *mctx, dns_zonestat_level_t level) { - isc_result_t result; - isc_stats_t *zoneqrystats; - - dns_zone_setstatlevel(zone, level); - - zoneqrystats = NULL; - if (level == dns_zonestat_full) { - result = isc_stats_create(mctx, &zoneqrystats, - dns_nsstatscounter_max); - if (result != ISC_R_SUCCESS) - return (result); - } - dns_zone_setrequeststats(zone, zoneqrystats); - if (zoneqrystats != NULL) - isc_stats_detach(&zoneqrystats); - - return (ISC_R_SUCCESS); -} - -static ns_cache_t * -cachelist_find(ns_cachelist_t *cachelist, const char *cachename, - dns_rdataclass_t rdclass) -{ - ns_cache_t *nsc; - - for (nsc = ISC_LIST_HEAD(*cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (nsc->rdclass == rdclass && - strcmp(dns_cache_getname(nsc->cache), cachename) == 0) - return (nsc); - } - - return (NULL); -} - -static bool -cache_reusable(dns_view_t *originview, dns_view_t *view, - bool new_zero_no_soattl) -{ - if (originview->rdclass != view->rdclass || - originview->checknames != view->checknames || - dns_resolver_getzeronosoattl(originview->resolver) != - new_zero_no_soattl || - originview->acceptexpired != view->acceptexpired || - originview->enablevalidation != view->enablevalidation || - originview->maxcachettl != view->maxcachettl || - originview->maxncachettl != view->maxncachettl) { - return (false); - } - - return (true); -} - -static bool -cache_sharable(dns_view_t *originview, dns_view_t *view, - bool new_zero_no_soattl, - unsigned int new_cleaning_interval, - uint64_t new_max_cache_size, - uint32_t new_stale_ttl) -{ - /* - * If the cache cannot even reused for the same view, it cannot be - * shared with other views. - */ - if (!cache_reusable(originview, view, new_zero_no_soattl)) - return (false); - - /* - * Check other cache related parameters that must be consistent among - * the sharing views. - */ - if (dns_cache_getcleaninginterval(originview->cache) != - new_cleaning_interval || - dns_cache_getservestalettl(originview->cache) != new_stale_ttl || - dns_cache_getcachesize(originview->cache) != new_max_cache_size) { - return (false); - } - - return (true); -} - -/* - * Callback from DLZ configure when the driver sets up a writeable zone - */ -static isc_result_t -dlzconfigure_callback(dns_view_t *view, dns_dlzdb_t *dlzdb, dns_zone_t *zone) { - dns_name_t *origin = dns_zone_getorigin(zone); - dns_rdataclass_t zclass = view->rdclass; - isc_result_t result; - - result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone); - if (result != ISC_R_SUCCESS) - return (result); - dns_zone_setstats(zone, ns_g_server->zonestats); - - return (ns_zone_configure_writeable_dlz(dlzdb, zone, zclass, origin)); -} - -static isc_result_t -dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na, - unsigned int prefixlen, const char *server, - const char *contact) -{ - char reverse[48+sizeof("ip6.arpa.")] = { 0 }; - char buf[sizeof("x.x.")]; - const char *dns64_dbtype[4] = { "_dns64", "dns64", ".", "." }; - const char *sep = ": view "; - const char *viewname = view->name; - const unsigned char *s6; - dns_fixedname_t fixed; - dns_name_t *name; - dns_zone_t *zone = NULL; - int dns64_dbtypec = 4; - isc_buffer_t b; - isc_result_t result; - - REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 || - prefixlen == 56 || prefixlen == 64 || prefixlen == 96); - - if (!strcmp(viewname, "_default")) { - sep = ""; - viewname = ""; - } - - /* - * Construct the reverse name of the zone. - */ - s6 = na->type.in6.s6_addr; - while (prefixlen > 0) { - prefixlen -= 8; - snprintf(buf, sizeof(buf), "%x.%x.", s6[prefixlen/8] & 0xf, - (s6[prefixlen/8] >> 4) & 0xf); - strlcat(reverse, buf, sizeof(reverse)); - } - strlcat(reverse, "ip6.arpa.", sizeof(reverse)); - - /* - * Create the actual zone. - */ - if (server != NULL) - dns64_dbtype[2] = server; - if (contact != NULL) - dns64_dbtype[3] = contact; - name = dns_fixedname_initname(&fixed); - isc_buffer_constinit(&b, reverse, strlen(reverse)); - isc_buffer_add(&b, strlen(reverse)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - CHECK(dns_zone_create(&zone, mctx)); - CHECK(dns_zone_setorigin(zone, name)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - dns_zone_setclass(zone, view->rdclass); - dns_zone_settype(zone, dns_zone_master); - dns_zone_setstats(zone, ns_g_server->zonestats); - CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype)); - if (view->queryacl != NULL) - dns_zone_setqueryacl(zone, view->queryacl); - if (view->queryonacl != NULL) - dns_zone_setqueryonacl(zone, view->queryonacl); - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - CHECK(setquerystats(zone, mctx, dns_zonestat_none)); /* XXXMPA */ - CHECK(dns_view_addzone(view, zone)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep, - viewname, reverse); - -cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - return (result); -} - -static isc_result_t -configure_rpz_name(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, - const char *str, const char *msg) -{ - isc_result_t result; - - result = dns_name_fromstring(name, str, DNS_NAME_DOWNCASE, view->mctx); - if (result != ISC_R_SUCCESS) - cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid %s '%s'", msg, str); - return (result); -} - -static isc_result_t -configure_rpz_name2(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, - const char *str, const dns_name_t *origin) -{ - isc_result_t result; - - result = dns_name_fromstring2(name, str, origin, DNS_NAME_DOWNCASE, - view->mctx); - if (result != ISC_R_SUCCESS) - cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone '%s'", str); - return (result); -} - -static isc_result_t -configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element, - bool recursive_only_def, dns_ttl_t ttl_def, - const dns_rpz_zone_t *old, bool *old_rpz_okp) -{ - const cfg_obj_t *rpz_obj, *obj; - const char *str; - dns_rpz_zone_t *new; - isc_result_t result; - dns_rpz_num_t rpz_num; - - REQUIRE(old != NULL || !*old_rpz_okp); - - rpz_obj = cfg_listelt_value(element); - - if (view->rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "limit of %d response policy zones exceeded", - DNS_RPZ_MAX_ZONES); - return (ISC_R_FAILURE); - } - - new = isc_mem_get(view->rpzs->mctx, sizeof(*new)); - if (new == NULL) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "no memory for response policy zones"); - return (ISC_R_NOMEMORY); - } - - memset(new, 0, sizeof(*new)); - result = isc_refcount_init(&new->refs, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(view->rpzs->mctx, new, sizeof(*new)); - return (result); - } - dns_name_init(&new->origin, NULL); - dns_name_init(&new->client_ip, NULL); - dns_name_init(&new->ip, NULL); - dns_name_init(&new->nsdname, NULL); - dns_name_init(&new->nsip, NULL); - dns_name_init(&new->passthru, NULL); - dns_name_init(&new->drop, NULL); - dns_name_init(&new->tcp_only, NULL); - dns_name_init(&new->cname, NULL); - new->num = view->rpzs->p.num_zones++; - view->rpzs->zones[new->num] = new; - - obj = cfg_tuple_get(rpz_obj, "recursive-only"); - if (cfg_obj_isvoid(obj) ? recursive_only_def : cfg_obj_asboolean(obj)) { - view->rpzs->p.no_rd_ok &= ~DNS_RPZ_ZBIT(new->num); - } else { - view->rpzs->p.no_rd_ok |= DNS_RPZ_ZBIT(new->num); - } - - obj = cfg_tuple_get(rpz_obj, "log"); - if (!cfg_obj_isvoid(obj) && !cfg_obj_asboolean(obj)) { - view->rpzs->p.no_log |= DNS_RPZ_ZBIT(new->num); - } else { - view->rpzs->p.no_log &= ~DNS_RPZ_ZBIT(new->num); - } - - obj = cfg_tuple_get(rpz_obj, "max-policy-ttl"); - if (cfg_obj_isuint32(obj)) { - new->max_policy_ttl = cfg_obj_asuint32(obj); - } else { - new->max_policy_ttl = ttl_def; - } - if (*old_rpz_okp && new->max_policy_ttl != old->max_policy_ttl) - *old_rpz_okp = false; - - str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "zone name")); - result = configure_rpz_name(view, rpz_obj, &new->origin, str, "zone"); - if (result != ISC_R_SUCCESS) - return (result); - if (dns_name_equal(&new->origin, dns_rootname)) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone name '%s'", str); - return (DNS_R_EMPTYLABEL); - } - for (rpz_num = 0; rpz_num < view->rpzs->p.num_zones-1; ++rpz_num) { - if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin, - &new->origin)) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "duplicate '%s'", str); - result = DNS_R_DUPLICATE; - return (result); - } - } - if (*old_rpz_okp && !dns_name_equal(&old->origin, &new->origin)) - *old_rpz_okp = false; - - result = configure_rpz_name2(view, rpz_obj, &new->client_ip, - DNS_RPZ_CLIENT_IP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->ip, - DNS_RPZ_IP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->nsdname, - DNS_RPZ_NSDNAME_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name2(view, rpz_obj, &new->nsip, - DNS_RPZ_NSIP_ZONE, &new->origin); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->passthru, - DNS_RPZ_PASSTHRU_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->drop, - DNS_RPZ_DROP_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - result = configure_rpz_name(view, rpz_obj, &new->tcp_only, - DNS_RPZ_TCP_ONLY_NAME, "name"); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(rpz_obj, "policy"); - if (cfg_obj_isvoid(obj)) { - new->policy = DNS_RPZ_POLICY_GIVEN; - } else { - str = cfg_obj_asstring(cfg_tuple_get(obj, "policy name")); - new->policy = dns_rpz_str2policy(str); - INSIST(new->policy != DNS_RPZ_POLICY_ERROR); - if (new->policy == DNS_RPZ_POLICY_CNAME) { - str = cfg_obj_asstring(cfg_tuple_get(obj, "cname")); - result = configure_rpz_name(view, rpz_obj, &new->cname, - str, "cname"); - if (result != ISC_R_SUCCESS) - return (result); - } - } - if (*old_rpz_okp && (new->policy != old->policy || - !dns_name_equal(&old->cname, &new->cname))) - *old_rpz_okp = false; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_rpz(dns_view_t *view, const cfg_obj_t *rpz_obj, - bool *old_rpz_okp) -{ - const cfg_listelt_t *zone_element; - const cfg_obj_t *sub_obj; - bool recursive_only_def; - dns_ttl_t ttl_def; - dns_rpz_zones_t *new; - const dns_rpz_zones_t *old; - dns_view_t *pview; - const dns_rpz_zone_t *old_zone; - isc_result_t result; - int i; - - *old_rpz_okp = false; - - zone_element = cfg_list_first(cfg_tuple_get(rpz_obj, "zone list")); - if (zone_element == NULL) - return (ISC_R_SUCCESS); - - result = dns_rpz_new_zones(&view->rpzs, view->mctx); - if (result != ISC_R_SUCCESS) - return (result); - new = view->rpzs; - - sub_obj = cfg_tuple_get(rpz_obj, "recursive-only"); - if (!cfg_obj_isvoid(sub_obj) && - !cfg_obj_asboolean(sub_obj)) - recursive_only_def = false; - else - recursive_only_def = true; - - sub_obj = cfg_tuple_get(rpz_obj, "break-dnssec"); - if (!cfg_obj_isvoid(sub_obj) && - cfg_obj_asboolean(sub_obj)) - new->p.break_dnssec = true; - else - new->p.break_dnssec = false; - - sub_obj = cfg_tuple_get(rpz_obj, "max-policy-ttl"); - if (cfg_obj_isuint32(sub_obj)) - ttl_def = cfg_obj_asuint32(sub_obj); - else - ttl_def = DNS_RPZ_MAX_TTL_DEFAULT; - - sub_obj = cfg_tuple_get(rpz_obj, "min-ns-dots"); - if (cfg_obj_isuint32(sub_obj)) - new->p.min_ns_labels = cfg_obj_asuint32(sub_obj) + 1; - else - new->p.min_ns_labels = 2; - - sub_obj = cfg_tuple_get(rpz_obj, "qname-wait-recurse"); - if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) - new->p.qname_wait_recurse = true; - else - new->p.qname_wait_recurse = false; - - sub_obj = cfg_tuple_get(rpz_obj, "nsip-wait-recurse"); - if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj)) - new->p.nsip_wait_recurse = true; - else - new->p.nsip_wait_recurse = false; - - pview = NULL; - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, &pview); - if (result == ISC_R_SUCCESS) { - old = pview->rpzs; - } else { - old = NULL; - } - if (old == NULL) { - *old_rpz_okp = false; - } else { - *old_rpz_okp = true; - } - - for (i = 0; - zone_element != NULL; - ++i, zone_element = cfg_list_next(zone_element)) - { - INSIST(!*old_rpz_okp || old != NULL); - if (*old_rpz_okp && i < old->p.num_zones) { - old_zone = old->zones[i]; - } else { - *old_rpz_okp = false; - old_zone = NULL; - } - result = configure_rpz_zone(view, zone_element, - recursive_only_def, ttl_def, - old_zone, old_rpz_okp); - if (result != ISC_R_SUCCESS) { - if (pview != NULL) - dns_view_detach(&pview); - return (result); - } - } - - /* - * If this is a reloading and the parameters and list of policy - * zones are unchanged, then use the same policy data. - * Data for individual zones that must be reloaded will be merged. - */ - if (old != NULL && memcmp(&old->p, &new->p, sizeof(new->p)) != 0) - *old_rpz_okp = false; - if (*old_rpz_okp) { - dns_rpz_detach_rpzs(&view->rpzs); - dns_rpz_attach_rpzs(pview->rpzs, &view->rpzs); - } else if (old != NULL && pview != NULL) { - pview->rpzs->rpz_ver += 1; - view->rpzs->rpz_ver = pview->rpzs->rpz_ver; - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_DEBUG_LEVEL1, - "updated RPZ policy: version %d", - view->rpzs->rpz_ver); - } - - if (pview != NULL) { - dns_view_detach(&pview); - } - - return (ISC_R_SUCCESS); -} - -static void -catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) { - catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0; - isc_result_t result; - isc_buffer_t namebuf; - isc_buffer_t *confbuf; - char nameb[DNS_NAME_FORMATSIZE]; - const cfg_obj_t *zlist = NULL; - cfg_obj_t *zoneconf = NULL; - cfg_obj_t *zoneobj = NULL; - ns_cfgctx_t *cfg; - dns_zone_t *zone = NULL; - - cfg = (ns_cfgctx_t *) ev->view->new_zone_config; - if (cfg == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: allow-new-zones statement missing from " - "config; cannot add zone from the catalog"); - goto cleanup; - } - - isc_buffer_init(&namebuf, nameb, DNS_NAME_FORMATSIZE); - dns_name_totext(dns_catz_entry_getname(ev->entry), true, &namebuf); - isc_buffer_putuint8(&namebuf, 0); - - /* Zone shouldn't already exist */ - result = dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone); - - if (ev->mod == true) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to " - "modify zone \"%s\"", - isc_result_totext(result), - nameb); - goto cleanup; - } else { - if (!dns_zone_getadded(zone)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "catz: catz_addmodzone_taskaction: " - "zone '%s' is not a dynamically " - "added zone", - nameb); - goto cleanup; - } - if (dns_zone_get_parentcatz(zone) != ev->origin) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' exists in multiple " - "catalog zones", - nameb); - goto cleanup; - } - dns_zone_detach(&zone); - } - - } else { - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "catz: zone \"%s\" is overridden " - "by explicitly configured zone", - nameb); - goto cleanup; - } else if (result != ISC_R_NOTFOUND && - result != DNS_R_PARTIALMATCH) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to " - "add zone \"%s\"", - isc_result_totext(result), - nameb); - goto cleanup; - } else { /* this can happen in case of DNS_R_PARTIALMATCH */ - if (zone != NULL) - dns_zone_detach(&zone); - } - } - RUNTIME_CHECK(zone == NULL); - /* Create a config for new zone */ - confbuf = NULL; - result = dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf); - if (result == ISC_R_SUCCESS) { - cfg_parser_reset(cfg->add_parser); - result = cfg_parse_buffer3(cfg->add_parser, confbuf, "catz", 0, - &cfg_type_addzoneconf, &zoneconf); - isc_buffer_free(&confbuf); - } - /* - * Fail if either dns_catz_generate_zonecfg() or cfg_parse_buffer3() - * failed. - */ - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: error \"%s\" while trying to generate " - "config for zone \"%s\"", - isc_result_totext(result), nameb); - goto cleanup; - } - CHECK(cfg_map_get(zoneconf, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - /* For now we only support adding one zone at a time */ - zoneobj = cfg_listelt_value(cfg_list_first(zlist)); - - /* Mark view unfrozen so that zone can be added */ - - result = isc_task_beginexclusive(task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_view_thaw(ev->view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - ev->cbd->server->mctx, ev->view, - &ev->cbd->server->viewlist, cfg->actx, - true, false, ev->mod); - dns_view_freeze(ev->view); - isc_task_endexclusive(task); - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: failed to configure zone \"%s\" - %d", - nameb, result); - goto cleanup; - } - - /* Is it there yet? */ - CHECK(dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone)); - - /* - * Load the zone from the master file. If this fails, we'll - * need to undo the configuration we've done already. - */ - result = dns_zone_loadnew(zone); - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "catz: dns_zone_loadnew() failed " - "with %s; reverting.", - isc_result_totext(result)); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(ev->view->zonetable, zone); - goto cleanup; - } - - /* Flag the zone as having been added at runtime */ - dns_zone_setadded(zone, true); - dns_zone_set_parentcatz(zone, ev->origin); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (zoneconf != NULL) - cfg_obj_destroy(cfg->add_parser, &zoneconf); - dns_catz_entry_detach(ev->origin, &ev->entry); - dns_catz_zone_detach(&ev->origin); - dns_view_detach(&ev->view); - isc_event_free(ISC_EVENT_PTR(&ev)); -} - -static void -catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) { - catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0; - isc_result_t result; - dns_zone_t *zone = NULL; - dns_db_t *dbp = NULL; - char cname[DNS_NAME_FORMATSIZE]; - const char * file; - - result = isc_task_beginexclusive(task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_name_format(dns_catz_entry_getname(ev->entry), cname, - DNS_NAME_FORMATSIZE); - result = dns_zt_find(ev->view->zonetable, - dns_catz_entry_getname(ev->entry), 0, NULL, &zone); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' not found", cname); - goto cleanup; - } - - if (!dns_zone_getadded(zone)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' is not a dynamically added zone", - cname); - goto cleanup; - } - - if (dns_zone_get_parentcatz(zone) != ev->origin) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: zone " - "'%s' exists in multiple catalog zones", - cname); - goto cleanup; - } - - /* Stop answering for this zone */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - CHECK(dns_zt_unmount(ev->view->zonetable, zone)); - file = dns_zone_getfile(zone); - if (file != NULL) - isc_file_remove(file); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: catz_delzone_taskaction: " - "zone '%s' deleted", cname); - cleanup: - isc_task_endexclusive(task); - if (zone != NULL) - dns_zone_detach(&zone); - dns_catz_entry_detach(ev->origin, &ev->entry); - dns_catz_zone_detach(&ev->origin); - dns_view_detach(&ev->view); - isc_event_free(ISC_EVENT_PTR(&ev)); -} - -static isc_result_t -catz_create_chg_task(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata, - isc_eventtype_t type) -{ - catz_chgzone_event_t *event; - isc_task_t *task; - isc_result_t result; - isc_taskaction_t action = NULL; - - switch (type) { - case DNS_EVENT_CATZADDZONE: - case DNS_EVENT_CATZMODZONE: - action = catz_addmodzone_taskaction; - break; - case DNS_EVENT_CATZDELZONE: - action = catz_delzone_taskaction; - break; - default: - REQUIRE(0); - } - - event = (catz_chgzone_event_t *) isc_event_allocate(view->mctx, origin, - type, action, NULL, - sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - - event->cbd = (catz_cb_data_t *) udata; - event->entry = NULL; - event->origin = NULL; - event->view = NULL; - event->mod = (type == DNS_EVENT_CATZMODZONE); - dns_catz_entry_attach(entry, &event->entry); - dns_catz_zone_attach(origin, &event->origin); - dns_view_attach(view, &event->view); - - task = NULL; - result = isc_taskmgr_excltask(taskmgr, &task); - REQUIRE(result == ISC_R_SUCCESS); - isc_task_send(task, ISC_EVENT_PTR(&event)); - isc_task_detach(&task); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -catz_addzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZADDZONE)); -} - -static isc_result_t -catz_delzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZDELZONE)); -} - -static isc_result_t -catz_modzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin, - dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata) -{ - return (catz_create_chg_task(entry, origin, view, taskmgr, udata, - DNS_EVENT_CATZMODZONE)); -} - -static isc_result_t -configure_catz_zone(dns_view_t *view, const cfg_obj_t *config, - const cfg_listelt_t *element) -{ - const cfg_obj_t *catz_obj, *obj; - dns_catz_zone_t *zone = NULL; - const char *str; - isc_result_t result; - dns_name_t origin; - dns_catz_options_t *opts; - dns_view_t *pview = NULL; - - dns_name_init(&origin, NULL); - catz_obj = cfg_listelt_value(element); - - str = cfg_obj_asstring(cfg_tuple_get(catz_obj, "zone name")); - - result = dns_name_fromstring(&origin, str, DNS_NAME_DOWNCASE, - view->mctx); - if (result == ISC_R_SUCCESS && dns_name_equal(&origin, dns_rootname)) - result = DNS_R_EMPTYLABEL; - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: invalid zone name '%s'", str); - goto cleanup; - } - - result = dns_catz_add_zone(view->catzs, &origin, &zone); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: unable to create catalog zone '%s', " - "error %s", - str, isc_result_totext(result)); - goto cleanup; - } - - if (result == ISC_R_EXISTS) { - isc_ht_iter_t *it = NULL; - - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, - view->rdclass, &pview); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * xxxwpk todo: reconfigure the zone!!!! - */ - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: catalog zone '%s' will not be reconfigured", - str); - /* - * We have to walk through all the member zones and attach - * them to current view - */ - result = dns_catz_get_iterator(zone, &it); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: unable to create iterator"); - goto cleanup; - } - - for (result = isc_ht_iter_first(it); - result == ISC_R_SUCCESS; - result = isc_ht_iter_next(it)) - { - dns_name_t *name = NULL; - dns_zone_t *dnszone = NULL; - dns_catz_entry_t *entry = NULL; - isc_result_t tresult; - - isc_ht_iter_current(it, (void **) &entry); - name = dns_catz_entry_getname(entry); - - tresult = dns_view_findzone(pview, name, &dnszone); - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); - - dns_zone_setview(dnszone, view); - if (view->acache != NULL) - dns_zone_setacache(dnszone, view->acache); - dns_view_addzone(view, dnszone); - - /* - * The dns_view_findzone() call above increments the - * zone's reference count, which we need to decrement - * back. However, as dns_zone_detach() sets the - * supplied pointer to NULL, calling it is deferred - * until the dnszone variable is no longer used. - */ - dns_zone_detach(&dnszone); - } - - isc_ht_iter_destroy(&it); - - result = ISC_R_SUCCESS; - } - - dns_catz_zone_resetdefoptions(zone); - opts = dns_catz_zone_getdefoptions(zone); - - obj = cfg_tuple_get(catz_obj, "default-masters"); - if (obj != NULL && cfg_obj_istuple(obj)) - result = ns_config_getipandkeylist(config, obj, - view->mctx, &opts->masters); - - obj = cfg_tuple_get(catz_obj, "in-memory"); - if (obj != NULL && cfg_obj_isboolean(obj)) - opts->in_memory = cfg_obj_asboolean(obj); - - obj = cfg_tuple_get(catz_obj, "zone-directory"); - if (!opts->in_memory && obj != NULL && cfg_obj_isstring(obj)) { - opts->zonedir = isc_mem_strdup(view->mctx, - cfg_obj_asstring(obj)); - if (isc_file_isdirectory(opts->zonedir) != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL, - "catz: zone-directory '%s' " - "not found; zone files will not be " - "saved", opts->zonedir); - opts->in_memory = true; - } - } - - obj = cfg_tuple_get(catz_obj, "min-update-interval"); - if (obj != NULL && cfg_obj_isuint32(obj)) - opts->min_update_interval = cfg_obj_asuint32(obj); - - cleanup: - if (pview != NULL) - dns_view_detach(&pview); - dns_name_free(&origin, view->mctx); - - return (result); -} - -static catz_cb_data_t ns_catz_cbdata; -static dns_catz_zonemodmethods_t ns_catz_zonemodmethods = { - catz_addzone, - catz_modzone, - catz_delzone, - &ns_catz_cbdata -}; - -static isc_result_t -configure_catz(dns_view_t *view, const cfg_obj_t *config, - const cfg_obj_t *catz_obj) -{ - const cfg_listelt_t *zone_element; - const dns_catz_zones_t *old = NULL; - dns_view_t *pview = NULL; - isc_result_t result; - - /* xxxwpk TODO do it cleaner, once, somewhere */ - ns_catz_cbdata.server = ns_g_server; - - zone_element = cfg_list_first(cfg_tuple_get(catz_obj, "zone list")); - if (zone_element == NULL) - return (ISC_R_SUCCESS); - - CHECK(dns_catz_new_zones(&view->catzs, &ns_catz_zonemodmethods, - view->mctx, ns_g_taskmgr, ns_g_timermgr)); - - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result == ISC_R_SUCCESS) - old = pview->catzs; - - if (old != NULL) { - dns_catz_catzs_detach(&view->catzs); - dns_catz_catzs_attach(pview->catzs, &view->catzs); - dns_catz_prereconfig(view->catzs); - } - - while (zone_element != NULL) { - CHECK(configure_catz_zone(view, config, zone_element)); - zone_element = cfg_list_next(zone_element); - } - - if (old != NULL) - dns_catz_postreconfig(view->catzs); - - result = ISC_R_SUCCESS; - - cleanup: - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -#define CHECK_RRL(cond, pat, val1, val2) \ - do { \ - if (!(cond)) { \ - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, \ - pat, val1, val2); \ - result = ISC_R_RANGE; \ - goto cleanup; \ - } \ - } while (0) - -#define CHECK_RRL_RATE(rate, def, max_rate, name) \ - do { \ - obj = NULL; \ - rrl->rate.str = name; \ - result = cfg_map_get(map, name, &obj); \ - if (result == ISC_R_SUCCESS) { \ - rrl->rate.r = cfg_obj_asuint32(obj); \ - CHECK_RRL(rrl->rate.r <= max_rate, \ - name" %d > %d", \ - rrl->rate.r, max_rate); \ - } else { \ - rrl->rate.r = def; \ - } \ - rrl->rate.scaled = rrl->rate.r; \ - } while (0) - -static isc_result_t -configure_rrl(dns_view_t *view, const cfg_obj_t *config, const cfg_obj_t *map) { - const cfg_obj_t *obj; - dns_rrl_t *rrl; - isc_result_t result; - int min_entries, i, j; - - /* - * Most DNS servers have few clients, but intentinally open - * recursive and authoritative servers often have many. - * So start with a small number of entries unless told otherwise - * to reduce cold-start costs. - */ - min_entries = 500; - obj = NULL; - result = cfg_map_get(map, "min-table-size", &obj); - if (result == ISC_R_SUCCESS) { - min_entries = cfg_obj_asuint32(obj); - if (min_entries < 1) - min_entries = 1; - } - result = dns_rrl_init(&rrl, view, min_entries); - if (result != ISC_R_SUCCESS) - return (result); - - i = ISC_MAX(20000, min_entries); - obj = NULL; - result = cfg_map_get(map, "max-table-size", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= min_entries, - "max-table-size %d < min-table-size %d", - i, min_entries); - } - rrl->max_entries = i; - - CHECK_RRL_RATE(responses_per_second, 0, DNS_RRL_MAX_RATE, - "responses-per-second"); - CHECK_RRL_RATE(referrals_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "referrals-per-second"); - CHECK_RRL_RATE(nodata_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "nodata-per-second"); - CHECK_RRL_RATE(nxdomains_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "nxdomains-per-second"); - CHECK_RRL_RATE(errors_per_second, - rrl->responses_per_second.r, DNS_RRL_MAX_RATE, - "errors-per-second"); - - CHECK_RRL_RATE(all_per_second, 0, DNS_RRL_MAX_RATE, - "all-per-second"); - - CHECK_RRL_RATE(slip, 2, DNS_RRL_MAX_SLIP, - "slip"); - - i = 15; - obj = NULL; - result = cfg_map_get(map, "window", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 1 && i <= DNS_RRL_MAX_WINDOW, - "window %d < 1 or > %d", i, DNS_RRL_MAX_WINDOW); - } - rrl->window = i; - - i = 0; - obj = NULL; - result = cfg_map_get(map, "qps-scale", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 1, "invalid 'qps-scale %d'%s", i, ""); - } - rrl->qps_scale = i; - rrl->qps = 1.0; - - i = 24; - obj = NULL; - result = cfg_map_get(map, "ipv4-prefix-length", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 8 && i <= 32, - "invalid 'ipv4-prefix-length %d'%s", i, ""); - } - rrl->ipv4_prefixlen = i; - if (i == 32) - rrl->ipv4_mask = 0xffffffff; - else - rrl->ipv4_mask = htonl(0xffffffff << (32-i)); - - i = 56; - obj = NULL; - result = cfg_map_get(map, "ipv6-prefix-length", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - CHECK_RRL(i >= 16 && i <= DNS_RRL_MAX_PREFIX, - "ipv6-prefix-length %d < 16 or > %d", - i, DNS_RRL_MAX_PREFIX); - } - rrl->ipv6_prefixlen = i; - for (j = 0; j < 4; ++j) { - if (i <= 0) { - rrl->ipv6_mask[j] = 0; - } else if (i < 32) { - rrl->ipv6_mask[j] = htonl(0xffffffff << (32-i)); - } else { - rrl->ipv6_mask[j] = 0xffffffff; - } - i -= 32; - } - - obj = NULL; - result = cfg_map_get(map, "exempt-clients", &obj); - if (result == ISC_R_SUCCESS) { - result = cfg_acl_fromconfig(obj, config, ns_g_lctx, - ns_g_aclconfctx, ns_g_mctx, - 0, &rrl->exempt); - CHECK_RRL(result == ISC_R_SUCCESS, - "invalid %s%s", "address match list", ""); - } - - obj = NULL; - result = cfg_map_get(map, "log-only", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_asboolean(obj)) - rrl->log_only = true; - else - rrl->log_only = false; - - return (ISC_R_SUCCESS); - - cleanup: - dns_rrl_view_destroy(view); - return (result); -} - -static isc_result_t -add_soa(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_name_t *origin, dns_name_t *contact) -{ - dns_dbnode_t *node = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - isc_result_t result; - unsigned char buf[DNS_SOA_BUFFERSIZE]; - - CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db), - 0, 28800, 7200, 604800, 86400, buf, &rdata)); - - dns_rdatalist_init(&rdatalist); - rdatalist.type = rdata.type; - rdatalist.rdclass = rdata.rdclass; - rdatalist.ttl = 86400; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - dns_rdataset_init(&rdataset); - CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); - CHECK(dns_db_findnode(db, name, true, &node)); - CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL)); - - cleanup: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -add_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_name_t *nsname) -{ - dns_dbnode_t *node = NULL; - dns_rdata_ns_t ns; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - isc_result_t result; - isc_buffer_t b; - unsigned char buf[DNS_NAME_MAXWIRE]; - - isc_buffer_init(&b, buf, sizeof(buf)); - - ns.common.rdtype = dns_rdatatype_ns; - ns.common.rdclass = dns_db_class(db); - ns.mctx = NULL; - dns_name_init(&ns.name, NULL); - dns_name_clone(nsname, &ns.name); - CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns, - &ns, &b)); - - dns_rdatalist_init(&rdatalist); - rdatalist.type = rdata.type; - rdatalist.rdclass = rdata.rdclass; - rdatalist.ttl = 86400; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - dns_rdataset_init(&rdataset); - CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); - CHECK(dns_db_findnode(db, name, true, &node)); - CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL)); - - cleanup: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, - const cfg_obj_t *zonelist, const char **empty_dbtype, - int empty_dbtypec, dns_zonestat_level_t statlevel) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - const cfg_listelt_t *element; - const cfg_obj_t *obj; - const cfg_obj_t *zconfig; - const cfg_obj_t *zoptions; - const char *rbt_dbtype[4] = { "rbt" }; - const char *sep = ": view "; - const char *str; - const char *viewname = view->name; - dns_db_t *db = NULL; - dns_dbversion_t *version = NULL; - dns_fixedname_t cfixed; - dns_fixedname_t fixed; - dns_fixedname_t nsfixed; - dns_name_t *contact; - dns_name_t *ns; - dns_name_t *zname; - dns_zone_t *myzone = NULL; - int rbt_dbtypec = 1; - isc_result_t result; - dns_namereln_t namereln; - int order; - unsigned int nlabels; - - zname = dns_fixedname_initname(&fixed); - ns = dns_fixedname_initname(&nsfixed); - contact = dns_fixedname_initname(&cfixed); - - /* - * Look for forward "zones" beneath this empty zone and if so - * create a custom db for the empty zone. - */ - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) { - - zconfig = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - CHECK(dns_name_fromstring(zname, str, 0, NULL)); - namereln = dns_name_fullcompare(zname, name, &order, &nlabels); - if (namereln != dns_namereln_subdomain) - continue; - - zoptions = cfg_tuple_get(zconfig, "options"); - - obj = NULL; - (void)cfg_map_get(zoptions, "type", &obj); - if (obj != NULL && - strcasecmp(cfg_obj_asstring(obj), "forward") == 0) { - obj = NULL; - (void)cfg_map_get(zoptions, "forward", &obj); - if (obj == NULL) - continue; - if (strcasecmp(cfg_obj_asstring(obj), "only") != 0) - continue; - } - if (db == NULL) { - CHECK(dns_db_create(view->mctx, "rbt", name, - dns_dbtype_zone, view->rdclass, - 0, NULL, &db)); - CHECK(dns_db_newversion(db, &version)); - if (strcmp(empty_dbtype[2], "@") == 0) - dns_name_clone(name, ns); - else - CHECK(dns_name_fromstring(ns, empty_dbtype[2], - 0, NULL)); - CHECK(dns_name_fromstring(contact, empty_dbtype[3], - 0, NULL)); - CHECK(add_soa(db, version, name, ns, contact)); - CHECK(add_ns(db, version, name, ns)); - } - CHECK(add_ns(db, version, zname, dns_rootname)); - } - - /* - * Is the existing zone the ok to use? - */ - if (zone != NULL) { - unsigned int typec; - const char **dbargv; - - if (db != NULL) { - typec = rbt_dbtypec; - dbargv = rbt_dbtype; - } else { - typec = empty_dbtypec; - dbargv = empty_dbtype; - } - - result = check_dbtype(zone, typec, dbargv, view->mctx); - if (result != ISC_R_SUCCESS) - zone = NULL; - - if (zone != NULL && dns_zone_gettype(zone) != dns_zone_master) - zone = NULL; - if (zone != NULL && dns_zone_getfile(zone) != NULL) - zone = NULL; - if (zone != NULL) { - dns_zone_getraw(zone, &myzone); - if (myzone != NULL) { - dns_zone_detach(&myzone); - zone = NULL; - } - } - } - - if (zone == NULL) { - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &myzone)); - zone = myzone; - CHECK(dns_zone_setorigin(zone, name)); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - if (db == NULL) - CHECK(dns_zone_setdbtype(zone, empty_dbtypec, - empty_dbtype)); - dns_zone_setclass(zone, view->rdclass); - dns_zone_settype(zone, dns_zone_master); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - - dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setautomatic(zone, true); - if (view->queryacl != NULL) - dns_zone_setqueryacl(zone, view->queryacl); - else - dns_zone_clearqueryacl(zone); - if (view->queryonacl != NULL) - dns_zone_setqueryonacl(zone, view->queryonacl); - else - dns_zone_clearqueryonacl(zone); - dns_zone_clearupdateacl(zone); - if (view->transferacl != NULL) - dns_zone_setxfracl(zone, view->transferacl); - else - dns_zone_clearxfracl(zone); - - CHECK(setquerystats(zone, view->mctx, statlevel)); - if (db != NULL) { - dns_db_closeversion(db, &version, true); - CHECK(dns_zone_replacedb(zone, db, false)); - } - dns_zone_setoption2(zone, DNS_ZONEOPT2_AUTOEMPTY, true); - dns_zone_setview(zone, view); - CHECK(dns_view_addzone(view, zone)); - - if (!strcmp(viewname, "_default")) { - sep = ""; - viewname = ""; - } - dns_name_format(name, namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "automatic empty zone%s%s: %s", - sep, viewname, namebuf); - - cleanup: - if (myzone != NULL) - dns_zone_detach(&myzone); - if (version != NULL) - dns_db_closeversion(db, &version, false); - if (db != NULL) - dns_db_detach(&db); - - INSIST(version == NULL); - - return (result); -} - -#ifdef HAVE_DNSTAP -static isc_result_t -configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) { - isc_result_t result; - const cfg_obj_t *obj, *obj2; - const cfg_listelt_t *element; - const char *dpath; - const cfg_obj_t *dlist = NULL; - dns_dtmsgtype_t dttypes = 0; - dns_dtmode_t dmode; - unsigned int i; - struct fstrm_iothr_options *fopt = NULL; - - result = ns_config_get(maps, "dnstap", &dlist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - for (element = cfg_list_first(dlist); - element != NULL; - element = cfg_list_next(element)) - { - const char *str; - dns_dtmsgtype_t dt = 0; - - obj = cfg_listelt_value(element); - obj2 = cfg_tuple_get(obj, "type"); - str = cfg_obj_asstring(obj2); - if (strcasecmp(str, "client") == 0) { - dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR; - } else if (strcasecmp(str, "auth") == 0) { - dt |= DNS_DTTYPE_AQ|DNS_DTTYPE_AR; - } else if (strcasecmp(str, "resolver") == 0) { - dt |= DNS_DTTYPE_RQ|DNS_DTTYPE_RR; - } else if (strcasecmp(str, "forwarder") == 0) { - dt |= DNS_DTTYPE_FQ|DNS_DTTYPE_FR; - } else if (strcasecmp(str, "all") == 0) { - dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR| - DNS_DTTYPE_AQ|DNS_DTTYPE_AR| - DNS_DTTYPE_RQ|DNS_DTTYPE_RR| - DNS_DTTYPE_FQ|DNS_DTTYPE_FR; - } - - obj2 = cfg_tuple_get(obj, "mode"); - if (obj2 == NULL || cfg_obj_isvoid(obj2)) { - dttypes |= dt; - continue; - } - - str = cfg_obj_asstring(obj2); - if (strcasecmp(str, "query") == 0) { - dt &= ~DNS_DTTYPE_RESPONSE; - } else if (strcasecmp(str, "response") == 0) { - dt &= ~DNS_DTTYPE_QUERY; - } - - dttypes |= dt; - } - - if (ns_g_server->dtenv == NULL && dttypes != 0) { - obj = NULL; - CHECKM(ns_config_get(maps, "dnstap-output", &obj), - "'dnstap-output' must be set if 'dnstap' is set"); - - obj2 = cfg_tuple_get(obj, "mode"); - if (obj2 == NULL) - CHECKM(ISC_R_FAILURE, "dnstap-output mode not found"); - if (strcasecmp(cfg_obj_asstring(obj2), "file") == 0) - dmode = dns_dtmode_file; - else - dmode = dns_dtmode_unix; - - obj2 = cfg_tuple_get(obj, "path"); - if (obj2 == NULL) - CHECKM(ISC_R_FAILURE, "dnstap-output path not found"); - - dpath = cfg_obj_asstring(obj2); - - fopt = fstrm_iothr_options_init(); - fstrm_iothr_options_set_num_input_queues(fopt, ns_g_cpus); - fstrm_iothr_options_set_queue_model(fopt, - FSTRM_IOTHR_QUEUE_MODEL_MPSC); - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-buffer-hint", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_buffer_hint(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-flush-timeout", &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_flush_timeout(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-input-queue-size", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_input_queue_size(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, - "fstrm-set-output-notify-threshold", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_queue_notify_threshold(fopt, - i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-output-queue-model", - &obj); - if (result == ISC_R_SUCCESS) { - if (strcasecmp(cfg_obj_asstring(obj), "spsc") == 0) - i = FSTRM_IOTHR_QUEUE_MODEL_SPSC; - else - i = FSTRM_IOTHR_QUEUE_MODEL_MPSC; - fstrm_iothr_options_set_queue_model(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-output-queue-size", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_output_queue_size(fopt, i); - } - - obj = NULL; - result = ns_config_get(maps, "fstrm-set-reopen-interval", - &obj); - if (result == ISC_R_SUCCESS) { - i = cfg_obj_asuint32(obj); - fstrm_iothr_options_set_reopen_interval(fopt, i); - } - - CHECKM(dns_dt_create(ns_g_mctx, dmode, dpath, &fopt, - &ns_g_server->dtenv), - "unable to create dnstap environment"); - } - - if (ns_g_server->dtenv == NULL) - return (ISC_R_SUCCESS); - - obj = NULL; - result = ns_config_get(maps, "dnstap-version", &obj); - if (result != ISC_R_SUCCESS) { - /* not specified; use the product and version */ - dns_dt_setversion(ns_g_server->dtenv, PRODUCT " " VERSION); - } else if (result == ISC_R_SUCCESS && !cfg_obj_isvoid(obj)) { - /* Quoted string */ - dns_dt_setversion(ns_g_server->dtenv, cfg_obj_asstring(obj)); - } - - obj = NULL; - result = ns_config_get(maps, "dnstap-identity", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - /* "hostname" is interpreted as boolean true */ - char buf[256]; - result = ns_os_gethostname(buf, sizeof(buf)); - if (result == ISC_R_SUCCESS) - dns_dt_setidentity(ns_g_server->dtenv, buf); - } else if (result == ISC_R_SUCCESS && !cfg_obj_isvoid(obj)) { - /* Quoted string */ - dns_dt_setidentity(ns_g_server->dtenv, cfg_obj_asstring(obj)); - } - - dns_dt_attach(ns_g_server->dtenv, &view->dtenv); - view->dttypes = dttypes; - - result = ISC_R_SUCCESS; - - cleanup: - if (fopt != NULL) - fstrm_iothr_options_destroy(&fopt); - - return (result); -} -#endif /* HAVE_DNSTAP */ - -static isc_result_t -create_mapped_acl(void) { - isc_result_t result; - dns_acl_t *acl = NULL; - struct in6_addr in6 = IN6ADDR_V4MAPPED_INIT; - isc_netaddr_t addr; - - isc_netaddr_fromin6(&addr, &in6); - - result = dns_acl_create(ns_g_mctx, 1, &acl); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_iptable_addprefix2(acl->iptable, &addr, 96, - true, false); - if (result == ISC_R_SUCCESS) - dns_acl_attach(acl, &ns_g_mapped); - dns_acl_detach(&acl); - return (result); -} - -/* - * Configure 'view' according to 'vconfig', taking defaults from 'config' - * where values are missing in 'vconfig'. - * - * When configuring the default view, 'vconfig' will be NULL and the - * global defaults in 'config' used exclusively. - */ -static isc_result_t -configure_view(dns_view_t *view, dns_viewlist_t *viewlist, - cfg_obj_t *config, cfg_obj_t *vconfig, - ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys, - isc_mem_t *mctx, cfg_aclconfctx_t *actx, - bool need_hints) -{ - const cfg_obj_t *maps[4]; - const cfg_obj_t *cfgmaps[3]; - const cfg_obj_t *optionmaps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *voptions = NULL; - const cfg_obj_t *forwardtype; - const cfg_obj_t *forwarders; - const cfg_obj_t *alternates; - const cfg_obj_t *zonelist; - const cfg_obj_t *dlzlist; - const cfg_obj_t *dlz; - const cfg_obj_t *dlvobj = NULL; - unsigned int dlzargc; - char **dlzargv; - const cfg_obj_t *dyndb_list; - const cfg_obj_t *disabled; - const cfg_obj_t *obj, *obj2; - const cfg_listelt_t *element; - in_port_t port; - dns_cache_t *cache = NULL; - isc_result_t result; - unsigned int cleaning_interval; - size_t max_cache_size; - uint32_t max_cache_size_percent = 0; - size_t max_acache_size; - size_t max_adb_size; - uint32_t lame_ttl, fail_ttl; - uint32_t max_stale_ttl; - dns_tsig_keyring_t *ring = NULL; - dns_view_t *pview = NULL; /* Production view */ - isc_mem_t *cmctx = NULL, *hmctx = NULL; - dns_dispatch_t *dispatch4 = NULL; - dns_dispatch_t *dispatch6 = NULL; - bool reused_cache = false; - bool shared_cache = false; - int i = 0, j = 0, k = 0; - const char *str; - const char *cachename = NULL; - dns_order_t *order = NULL; - uint32_t udpsize; - uint32_t maxbits; - unsigned int resopts = 0; - dns_zone_t *zone = NULL; - uint32_t max_clients_per_query; - bool empty_zones_enable; - const cfg_obj_t *disablelist = NULL; - isc_stats_t *resstats = NULL; - dns_stats_t *resquerystats = NULL; - bool auto_root = false; - ns_cache_t *nsc; - bool zero_no_soattl; - dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL; - unsigned int query_timeout, ndisp; - bool old_rpz_ok = false; - isc_dscp_t dscp4 = -1, dscp6 = -1; - dns_dyndbctx_t *dctx = NULL; - unsigned int resolver_param; - - REQUIRE(DNS_VIEW_VALID(view)); - - if (config != NULL) - (void)cfg_map_get(config, "options", &options); - - /* - * maps: view options, options, defaults - * cfgmaps: view options, config - * optionmaps: view options, options - */ - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - maps[i++] = voptions; - optionmaps[j++] = voptions; - cfgmaps[k++] = voptions; - } - if (options != NULL) { - maps[i++] = options; - optionmaps[j++] = options; - } - - maps[i++] = ns_g_defaults; - maps[i] = NULL; - optionmaps[j] = NULL; - if (config != NULL) - cfgmaps[k++] = config; - cfgmaps[k] = NULL; - - /* - * Set the view's port number for outgoing queries. - */ - CHECKM(ns_config_getport(config, &port), "port"); - dns_view_setdstport(view, port); - - /* - * Create additional cache for this view and zones under the view - * if explicitly enabled. - * XXX950 default to on. - */ - obj = NULL; - (void)ns_config_get(maps, "acache-enable", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) { - cmctx = NULL; - CHECK(isc_mem_create(0, 0, &cmctx)); - CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr, - ns_g_timermgr)); - isc_mem_setname(cmctx, "acache", NULL); - isc_mem_detach(&cmctx); - } - if (view->acache != NULL) { - obj = NULL; - result = ns_config_get(maps, "acache-cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_acache_setcleaninginterval(view->acache, - cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-acache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_acache_size = 0; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > SIZE_MAX) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "'max-acache-size " - "%" PRIu64 "' " - "is too large for this " - "system; reducing to %lu", - value, (unsigned long)SIZE_MAX); - value = SIZE_MAX; - } - max_acache_size = (size_t) value; - } - dns_acache_setcachesize(view->acache, max_acache_size); - } - - /* - * Make the list of response policy zone names for a view that - * is used for real lookups and so cares about hints. - */ - obj = NULL; - if (view->rdclass == dns_rdataclass_in && need_hints && - ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) { - CHECK(configure_rpz(view, obj, &old_rpz_ok)); - } - - obj = NULL; - if (view->rdclass == dns_rdataclass_in && need_hints && - ns_config_get(maps, "catalog-zones", &obj) == ISC_R_SUCCESS) { - CHECK(configure_catz(view, config, obj)); - } - - /* - * Configure the zones. - */ - zonelist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "zone", &zonelist); - else - (void)cfg_map_get(config, "zone", &zonelist); - - /* - * Load zone configuration - */ - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, view, - viewlist, actx, false, old_rpz_ok, - false)); - } - - /* - * If we're allowing added zones, then load zone configuration - * from the newzone file for zones that were added during previous - * runs. - */ - CHECK(configure_newzones(view, config, vconfig, mctx, actx)); - - /* - * Create Dynamically Loadable Zone driver. - */ - dlzlist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "dlz", &dlzlist); - else - (void)cfg_map_get(config, "dlz", &dlzlist); - - for (element = cfg_list_first(dlzlist); - element != NULL; - element = cfg_list_next(element)) - { - dlz = cfg_listelt_value(element); - - obj = NULL; - (void)cfg_map_get(dlz, "database", &obj); - if (obj != NULL) { - dns_dlzdb_t *dlzdb = NULL; - const cfg_obj_t *name, *search = NULL; - char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - - if (s == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - result = isc_commandline_strtoargv(mctx, s, &dlzargc, - &dlzargv, 0); - if (result != ISC_R_SUCCESS) { - isc_mem_free(mctx, s); - goto cleanup; - } - - name = cfg_map_getname(dlz); - result = dns_dlzcreate(mctx, cfg_obj_asstring(name), - dlzargv[0], dlzargc, dlzargv, - &dlzdb); - isc_mem_free(mctx, s); - isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv)); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * If the DLZ backend supports configuration, - * and is searchable, then call its configure - * method now. If not searchable, we'll take - * care of it when we process the zone statement. - */ - (void)cfg_map_get(dlz, "search", &search); - if (search == NULL || cfg_obj_asboolean(search)) { - dlzdb->search = true; - result = dns_dlzconfigure(view, dlzdb, - dlzconfigure_callback); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(view->dlz_searched, - dlzdb, link); - } else { - dlzdb->search = false; - ISC_LIST_APPEND(view->dlz_unsearched, - dlzdb, link); - } - - } - } - - /* - * Obtain configuration parameters that affect the decision of whether - * we can reuse/share an existing cache. - */ - obj = NULL; - result = ns_config_get(maps, "cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - cleaning_interval = cfg_obj_asuint32(obj) * 60; - - obj = NULL; - result = ns_config_get(maps, "max-cache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_cache_size = 0; - } else if (cfg_obj_ispercentage(obj)) { - max_cache_size = SIZE_AS_PERCENT; - max_cache_size_percent = cfg_obj_aspercentage(obj); - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > SIZE_MAX) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "'max-cache-size " - "%" PRIu64 "' " - "is too large for this " - "system; reducing to %lu", - value, (unsigned long)SIZE_MAX); - value = SIZE_MAX; - } - max_cache_size = (size_t) value; - } - - if (max_cache_size == SIZE_AS_PERCENT) { - uint64_t totalphys = isc_meminfo_totalphys(); - - max_cache_size = - (size_t) (totalphys * max_cache_size_percent/100); - if (totalphys == 0) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_WARNING, - "Unable to determine amount of physical " - "memory, setting 'max-cache-size' to " - "unlimited"); - } else { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_INFO, - "'max-cache-size %d%%' " - "- setting to %" PRIu64 "MB " - "(out of %" PRIu64 "MB)", - max_cache_size_percent, - (uint64_t)(max_cache_size / (1024*1024)), - totalphys / (1024*1024)); - } - } - - /* Check-names. */ - obj = NULL; - result = ns_checknames_get(maps, "response", &obj); - INSIST(result == ISC_R_SUCCESS); - - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "fail") == 0) { - resopts |= DNS_RESOLVER_CHECKNAMES | - DNS_RESOLVER_CHECKNAMESFAIL; - view->checknames = true; - } else if (strcasecmp(str, "warn") == 0) { - resopts |= DNS_RESOLVER_CHECKNAMES; - view->checknames = false; - } else if (strcasecmp(str, "ignore") == 0) { - view->checknames = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - zero_no_soattl = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dns64", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") && - strcmp(view->name, "_meta")) { - isc_netaddr_t na, suffix, *sp; - unsigned int prefixlen; - const char *server, *contact; - const cfg_obj_t *myobj; - - myobj = NULL; - result = ns_config_get(maps, "dns64-server", &myobj); - if (result == ISC_R_SUCCESS) - server = cfg_obj_asstring(myobj); - else - server = NULL; - - myobj = NULL; - result = ns_config_get(maps, "dns64-contact", &myobj); - if (result == ISC_R_SUCCESS) - contact = cfg_obj_asstring(myobj); - else - contact = NULL; - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *map = cfg_listelt_value(element); - dns_dns64_t *dns64 = NULL; - unsigned int dns64options = 0; - - cfg_obj_asnetprefix(cfg_map_getname(map), &na, - &prefixlen); - - obj = NULL; - (void)cfg_map_get(map, "suffix", &obj); - if (obj != NULL) { - sp = &suffix; - isc_netaddr_fromsockaddr(sp, - cfg_obj_assockaddr(obj)); - } else - sp = NULL; - - clients = mapped = excluded = NULL; - obj = NULL; - (void)cfg_map_get(map, "clients", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &clients); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - obj = NULL; - (void)cfg_map_get(map, "mapped", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &mapped); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - obj = NULL; - (void)cfg_map_get(map, "exclude", &obj); - if (obj != NULL) { - result = cfg_acl_fromconfig(obj, config, - ns_g_lctx, actx, - mctx, 0, &excluded); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else { - if (ns_g_mapped == NULL) { - result = create_mapped_acl(); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - dns_acl_attach(ns_g_mapped, &excluded); - } - - obj = NULL; - (void)cfg_map_get(map, "recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - dns64options |= DNS_DNS64_RECURSIVE_ONLY; - - obj = NULL; - (void)cfg_map_get(map, "break-dnssec", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - dns64options |= DNS_DNS64_BREAK_DNSSEC; - - result = dns_dns64_create(mctx, &na, prefixlen, sp, - clients, mapped, excluded, - dns64options, &dns64); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_dns64_append(&view->dns64, dns64); - view->dns64cnt++; - result = dns64_reverse(view, mctx, &na, prefixlen, - server, contact); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (clients != NULL) - dns_acl_detach(&clients); - if (mapped != NULL) - dns_acl_detach(&mapped); - if (excluded != NULL) - dns_acl_detach(&excluded); - } - } - - obj = NULL; - result = ns_config_get(maps, "dnssec-accept-expired", &obj); - INSIST(result == ISC_R_SUCCESS); - view->acceptexpired = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-validation", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - view->enablevalidation = cfg_obj_asboolean(obj); - } else { - /* If dnssec-validation is not boolean, it must be "auto" */ - view->enablevalidation = true; - auto_root = true; - } - - obj = NULL; - result = ns_config_get(maps, "max-cache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxcachettl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "max-ncache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxncachettl = cfg_obj_asuint32(obj); - if (view->maxncachettl > 7 * 24 * 3600) - view->maxncachettl = 7 * 24 * 3600; - - obj = NULL; - result = ns_config_get(maps, "max-stale-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - max_stale_ttl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "stale-answer-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswersenable = cfg_obj_asboolean(obj); - - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result == ISC_R_SUCCESS) { - view->staleanswersok = pview->staleanswersok; - dns_view_detach(&pview); - } else - view->staleanswersok = dns_stale_answer_conf; - - /* - * Configure the view's cache. - * - * First, check to see if there are any attach-cache options. If yes, - * attempt to lookup an existing cache at attach it to the view. If - * there is not one, then try to reuse an existing cache if possible; - * otherwise create a new cache. - * - * Note that the ADB is not preserved or shared in either case. - * - * When a matching view is found, the associated statistics are also - * retrieved and reused. - * - * XXX Determining when it is safe to reuse or share a cache is tricky. - * When the view's configuration changes, the cached data may become - * invalid because it reflects our old view of the world. We check - * some of the configuration parameters that could invalidate the cache - * or otherwise make it unshareable, but there are other configuration - * options that should be checked. For example, if a view uses a - * forwarder, changes in the forwarder configuration may invalidate - * the cache. At the moment, it's the administrator's responsibility to - * ensure these configuration options don't invalidate reusing/sharing. - */ - obj = NULL; - result = ns_config_get(maps, "attach-cache", &obj); - if (result == ISC_R_SUCCESS) - cachename = cfg_obj_asstring(obj); - else - cachename = view->name; - cache = NULL; - nsc = cachelist_find(cachelist, cachename, view->rdclass); - if (nsc != NULL) { - if (!cache_sharable(nsc->primaryview, view, zero_no_soattl, - cleaning_interval, max_cache_size, - max_stale_ttl)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "views %s and %s can't share the cache " - "due to configuration parameter mismatch", - nsc->primaryview->name, view->name); - result = ISC_R_FAILURE; - goto cleanup; - } - dns_cache_attach(nsc->cache, &cache); - shared_cache = true; - } else { - if (strcmp(cachename, view->name) == 0) { - result = dns_viewlist_find(&ns_g_server->viewlist, - cachename, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - if (!cache_reusable(pview, view, - zero_no_soattl)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), - "cache cannot be reused " - "for view %s due to " - "configuration parameter " - "mismatch", view->name); - } else { - INSIST(pview->cache != NULL); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(3), - "reusing existing cache"); - reused_cache = true; - dns_cache_attach(pview->cache, &cache); - } - dns_view_getresstats(pview, &resstats); - dns_view_getresquerystats(pview, - &resquerystats); - dns_view_detach(&pview); - } - } - if (cache == NULL) { - /* - * Create a cache with the desired name. This normally - * equals the view name, but may also be a forward - * reference to a view that share the cache with this - * view but is not yet configured. If it is not the - * view name but not a forward reference either, then it - * is simply a named cache that is not shared. - * - * We use two separate memory contexts for the - * cache, for the main cache memory and the heap - * memory. - */ - CHECK(isc_mem_create(0, 0, &cmctx)); - isc_mem_setname(cmctx, "cache", NULL); - CHECK(isc_mem_create(0, 0, &hmctx)); - isc_mem_setname(hmctx, "cache_heap", NULL); - CHECK(dns_cache_create3(cmctx, hmctx, ns_g_taskmgr, - ns_g_timermgr, view->rdclass, - cachename, "rbt", 0, NULL, - &cache)); - isc_mem_detach(&cmctx); - isc_mem_detach(&hmctx); - } - nsc = isc_mem_get(mctx, sizeof(*nsc)); - if (nsc == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - nsc->cache = NULL; - dns_cache_attach(cache, &nsc->cache); - nsc->primaryview = view; - nsc->needflush = false; - nsc->adbsizeadjusted = false; - nsc->rdclass = view->rdclass; - ISC_LINK_INIT(nsc, link); - ISC_LIST_APPEND(*cachelist, nsc, link); - } - dns_view_setcache2(view, cache, shared_cache); - - /* - * cache-file cannot be inherited if views are present, but this - * should be caught by the configuration checking stage. - */ - obj = NULL; - result = ns_config_get(maps, "cache-file", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { - CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); - if (!reused_cache && !shared_cache) - CHECK(dns_cache_load(cache)); - } - - dns_cache_setcleaninginterval(cache, cleaning_interval); - dns_cache_setcachesize(cache, max_cache_size); - dns_cache_setservestalettl(cache, max_stale_ttl); - - dns_cache_detach(&cache); - - obj = NULL; - result = ns_config_get(maps, "stale-answer-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswerttl = ISC_MAX(cfg_obj_asuint32(obj), 1); - - /* - * Resolver. - * - * XXXRTH Hardwired number of tasks. - */ - CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4, &dscp4, - (ISC_LIST_PREV(view, link) - == NULL))); - CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6, &dscp6, - (ISC_LIST_PREV(view, link) - == NULL))); - if (dispatch4 == NULL && dispatch6 == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unable to obtain neither an IPv4 nor" - " an IPv6 dispatch"); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - if (resstats == NULL) { - CHECK(isc_stats_create(mctx, &resstats, - dns_resstatscounter_max)); - } - dns_view_setresstats(view, resstats); - if (resquerystats == NULL) - CHECK(dns_rdatatypestats_create(mctx, &resquerystats)); - dns_view_setresquerystats(view, resquerystats); - - ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH); - CHECK(dns_view_createresolver(view, ns_g_taskmgr, RESOLVER_NTASKS, - ndisp, ns_g_socketmgr, ns_g_timermgr, - resopts, ns_g_dispatchmgr, - dispatch4, dispatch6)); - - if (dscp4 == -1) - dscp4 = ns_g_dscp; - if (dscp6 == -1) - dscp6 = ns_g_dscp; - if (dscp4 != -1) - dns_resolver_setquerydscp4(view->resolver, dscp4); - if (dscp6 != -1) - dns_resolver_setquerydscp6(view->resolver, dscp6); - - /* - * Set the ADB cache size to 1/8th of the max-cache-size or - * MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared. - */ - max_adb_size = 0; - if (max_cache_size != 0U) { - max_adb_size = max_cache_size / 8; - if (max_adb_size == 0U) - max_adb_size = 1; /* Force minimum. */ - if (view != nsc->primaryview && - max_adb_size > MAX_ADB_SIZE_FOR_CACHESHARE) { - max_adb_size = MAX_ADB_SIZE_FOR_CACHESHARE; - if (!nsc->adbsizeadjusted) { - dns_adb_setadbsize(nsc->primaryview->adb, - MAX_ADB_SIZE_FOR_CACHESHARE); - nsc->adbsizeadjusted = true; - } - } - } - dns_adb_setadbsize(view->adb, max_adb_size); - - /* - * Set up ADB quotas - */ - { - uint32_t fps, freq; - double low, high, discount; - - obj = NULL; - result = ns_config_get(maps, "fetches-per-server", &obj); - INSIST(result == ISC_R_SUCCESS); - obj2 = cfg_tuple_get(obj, "fetches"); - fps = cfg_obj_asuint32(obj2); - obj2 = cfg_tuple_get(obj, "response"); - if (!cfg_obj_isvoid(obj2)) { - const char *resp = cfg_obj_asstring(obj2); - isc_result_t r = DNS_R_SERVFAIL; - - if (strcasecmp(resp, "drop") == 0) { - r = DNS_R_DROP; - } else if (strcasecmp(resp, "fail") == 0) { - r = DNS_R_SERVFAIL; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - dns_resolver_setquotaresponse(view->resolver, - dns_quotatype_server, r); - } - - obj = NULL; - result = ns_config_get(maps, "fetch-quota-params", &obj); - INSIST(result == ISC_R_SUCCESS); - - obj2 = cfg_tuple_get(obj, "frequency"); - freq = cfg_obj_asuint32(obj2); - - obj2 = cfg_tuple_get(obj, "low"); - low = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - obj2 = cfg_tuple_get(obj, "high"); - high = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - obj2 = cfg_tuple_get(obj, "discount"); - discount = (double) cfg_obj_asfixedpoint(obj2) / 100.0; - - dns_adb_setquota(view->adb, fps, freq, low, high, discount); - } - - /* - * Set resolver's lame-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "lame-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - lame_ttl = cfg_obj_asuint32(obj); - if (lame_ttl > 1800) - lame_ttl = 1800; - dns_resolver_setlamettl(view->resolver, lame_ttl); - - /* - * Set the resolver's query timeout. - */ - obj = NULL; - result = ns_config_get(maps, "resolver-query-timeout", &obj); - INSIST(result == ISC_R_SUCCESS); - query_timeout = cfg_obj_asuint32(obj); - dns_resolver_settimeout(view->resolver, query_timeout); - - /* Specify whether to use 0-TTL for negative response for SOA query */ - dns_resolver_setzeronosoattl(view->resolver, zero_no_soattl); - - /* - * Set the resolver's EDNS UDP size. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - dns_resolver_setudpsize(view->resolver, (uint16_t)udpsize); - - /* - * Set the maximum UDP response size. - */ - obj = NULL; - result = ns_config_get(maps, "max-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - view->maxudp = udpsize; - - /* - * Set the maximum UDP when a COOKIE is not provided. - */ - obj = NULL; - result = ns_config_get(maps, "nocookie-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 128) - udpsize = 128; - if (udpsize > view->maxudp) - udpsize = view->maxudp; - view->nocookieudp = udpsize; - - /* - * Set the maximum rsa exponent bits. - */ - obj = NULL; - result = ns_config_get(maps, "max-rsa-exponent-size", &obj); - INSIST(result == ISC_R_SUCCESS); - maxbits = cfg_obj_asuint32(obj); - if (maxbits != 0 && maxbits < 35) - maxbits = 35; - if (maxbits > 4096) - maxbits = 4096; - view->maxbits = maxbits; - - /* - * Set resolver retry parameters. - */ - obj = NULL; - CHECK(ns_config_get(maps, "resolver-retry-interval", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setretryinterval(view->resolver, resolver_param); - - obj = NULL; - CHECK(ns_config_get(maps, "resolver-nonbackoff-tries", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setnonbackofftries(view->resolver, resolver_param); - - /* - * Set supported DNSSEC algorithms. - */ - dns_resolver_reset_algorithms(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-algorithms", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_algorithms(cfg_listelt_value(element), - view->resolver)); - } - - /* - * Set supported DS/DLV digest types. - */ - dns_resolver_reset_ds_digests(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-ds-digests", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_ds_digests(cfg_listelt_value(element), - view->resolver)); - } - - /* - * A global or view "forwarders" option, if present, - * creates an entry for "." in the forwarding table. - */ - forwardtype = NULL; - forwarders = NULL; - (void)ns_config_get(maps, "forward", &forwardtype); - (void)ns_config_get(maps, "forwarders", &forwarders); - if (forwarders != NULL) - CHECK(configure_forward(config, view, dns_rootname, - forwarders, forwardtype)); - - /* - * Dual Stack Servers. - */ - alternates = NULL; - (void)ns_config_get(maps, "dual-stack-servers", &alternates); - if (alternates != NULL) - CHECK(configure_alternates(config, view, alternates)); - - /* - * We have default hints for class IN if we need them. - */ - if (view->rdclass == dns_rdataclass_in && view->hints == NULL) - dns_view_sethints(view, ns_g_server->in_roothints); - - /* - * If we still have no hints, this is a non-IN view with no - * "hints zone" configured. Issue a warning, except if this - * is a root server. Root servers never need to consult - * their hints, so it's no point requiring users to configure - * them. - */ - if (view->hints == NULL) { - dns_zone_t *rootzone = NULL; - (void)dns_view_findzone(view, dns_rootname, &rootzone); - if (rootzone != NULL) { - dns_zone_detach(&rootzone); - need_hints = false; - } - if (need_hints) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "no root hints for view '%s'", - view->name); - } - - /* - * Configure the view's TSIG keys. - */ - CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); - if (ns_g_server->sessionkey != NULL) { - CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname, - ns_g_server->sessionkey)); - } - dns_view_setkeyring(view, ring); - dns_tsigkeyring_detach(&ring); - - /* - * See if we can re-use a dynamic key ring. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - dns_view_getdynamickeyring(pview, &ring); - if (ring != NULL) - dns_view_setdynamickeyring(view, ring); - dns_tsigkeyring_detach(&ring); - dns_view_detach(&pview); - } else - dns_view_restorekeyring(view); - - /* - * Configure the view's peer list. - */ - { - const cfg_obj_t *peers = NULL; - dns_peerlist_t *newpeers = NULL; - - (void)ns_config_get(cfgmaps, "server", &peers); - CHECK(dns_peerlist_new(mctx, &newpeers)); - for (element = cfg_list_first(peers); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *cpeer = cfg_listelt_value(element); - dns_peer_t *peer; - - CHECK(configure_peer(cpeer, mctx, &peer)); - dns_peerlist_addpeer(newpeers, peer); - dns_peer_detach(&peer); - } - dns_peerlist_detach(&view->peers); - view->peers = newpeers; /* Transfer ownership. */ - } - - /* - * Configure the views rrset-order. - */ - { - const cfg_obj_t *rrsetorder = NULL; - - (void)ns_config_get(maps, "rrset-order", &rrsetorder); - CHECK(dns_order_create(mctx, &order)); - for (element = cfg_list_first(rrsetorder); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *ent = cfg_listelt_value(element); - - CHECK(configure_order(order, ent)); - } - if (view->order != NULL) - dns_order_detach(&view->order); - dns_order_attach(order, &view->order); - dns_order_detach(&order); - } - /* - * Copy the aclenv object. - */ - dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); - - /* - * Configure the "match-clients" and "match-destinations" ACL. - * (These are only meaningful at the view level, but 'config' - * must be passed so that named ACLs defined at the global level - * can be retrieved.) - */ - CHECK(configure_view_acl(vconfig, config, NULL, "match-clients", - NULL, actx, ns_g_mctx, - &view->matchclients)); - CHECK(configure_view_acl(vconfig, config, NULL, "match-destinations", - NULL, actx, ns_g_mctx, - &view->matchdestinations)); - - /* - * Configure the "match-recursive-only" option. - */ - obj = NULL; - (void)ns_config_get(maps, "match-recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - view->matchrecursiveonly = true; - else - view->matchrecursiveonly = false; - - /* - * Configure other configurable data. - */ - obj = NULL; - result = ns_config_get(maps, "recursion", &obj); - INSIST(result == ISC_R_SUCCESS); - view->recursion = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "auth-nxdomain", &obj); - INSIST(result == ISC_R_SUCCESS); - view->auth_nxdomain = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-any", &obj); - INSIST(result == ISC_R_SUCCESS); - view->minimal_any = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-responses", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->minimalresponses = dns_minimal_yes; - else - view->minimalresponses = dns_minimal_no; - } else { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "no-auth") == 0) { - view->minimalresponses = dns_minimal_noauth; - } else if (strcasecmp(str, "no-auth-recursive") == 0) { - view->minimalresponses = dns_minimal_noauthrec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "transfer-format", &obj); - INSIST(result == ISC_R_SUCCESS); - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) { - view->transfer_format = dns_many_answers; - } else if (strcasecmp(str, "one-answer") == 0) { - view->transfer_format = dns_one_answer; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "trust-anchor-telemetry", &obj); - INSIST(result == ISC_R_SUCCESS); - view->trust_anchor_telemetry = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "root-key-sentinel", &obj); - INSIST(result == ISC_R_SUCCESS); - view->root_key_sentinel = cfg_obj_asboolean(obj); - - /* - * Set sources where additional data and CNAME/DNAME - * targets for authoritative answers may be found. - */ - obj = NULL; - result = ns_config_get(maps, "additional-from-auth", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromauth = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromauth) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-auth no' is only supported " - "with 'recursion no'"); - view->additionalfromauth = true; - } - - obj = NULL; - result = ns_config_get(maps, "additional-from-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromcache = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromcache) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-cache no' is only supported " - "with 'recursion no'"); - view->additionalfromcache = true; - } - - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-query-cache-on", NULL, actx, - ns_g_mctx, &view->cacheonacl)); - - /* - * Set the "allow-query", "allow-query-cache", "allow-recursion", - * and "allow-recursion-on" ACLs if configured in named.conf, but - * NOT from the global defaults. This is done by leaving the third - * argument to configure_view_acl() NULL. - * - * We ignore the global defaults here because these ACLs - * can inherit from each other. If any are still unset after - * applying the inheritance rules, we'll look up the defaults at - * that time. - */ - - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-query", NULL, actx, - ns_g_mctx, &view->queryacl)); - - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-query-cache", NULL, actx, - ns_g_mctx, &view->cacheacl)); - - if (strcmp(view->name, "_bind") != 0 && - view->rdclass != dns_rdataclass_chaos) - { - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-recursion", NULL, actx, - ns_g_mctx, &view->recursionacl)); - /* named.conf only */ - CHECK(configure_view_acl(vconfig, config, NULL, - "allow-recursion-on", NULL, actx, - ns_g_mctx, &view->recursiononacl)); - } - - if (view->recursion) { - /* - * "allow-query-cache" inherits from "allow-recursion" if set, - * otherwise from "allow-query" if set. - * "allow-recursion" inherits from "allow-query-cache" if set, - * otherwise from "allow-query" if set. - */ - if (view->cacheacl == NULL) { - if (view->recursionacl != NULL) { - dns_acl_attach(view->recursionacl, - &view->cacheacl); - } else if (view->queryacl != NULL) { - dns_acl_attach(view->queryacl, - &view->cacheacl); - } - } - if (view->recursionacl == NULL) { - if (view->cacheacl != NULL) { - dns_acl_attach(view->cacheacl, - &view->recursionacl); - } else if (view->queryacl != NULL) { - dns_acl_attach(view->queryacl, - &view->recursionacl); - } - } - - /* - * If any are still unset, we now get default "allow-recursion", - * "allow-recursion-on" and "allow-query-cache" ACLs from - * the global config. - */ - /* cppcheck-suppress duplicateCondition */ - if (view->recursionacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-recursion", NULL, - actx, ns_g_mctx, - &view->recursionacl)); - } - /* cppcheck-suppress duplicateCondition */ - if (view->recursiononacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-recursion-on", NULL, - actx, ns_g_mctx, - &view->recursiononacl)); - } - if (view->cacheacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-query-cache", NULL, - actx, ns_g_mctx, - &view->cacheacl)); - } - } else if (view->cacheacl == NULL) { - /* - * We're not recursive; if "allow-query-cache" hasn't been - * set at the options/view level, set it to none. - */ - CHECK(dns_acl_none(mctx, &view->cacheacl)); - } - - if (view->queryacl == NULL) { - /* global default only */ - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-query", NULL, - actx, ns_g_mctx, - &view->queryacl)); - } - - /* - * Ignore case when compressing responses to the specified - * clients. This causes case not always to be preserved, - * and is needed by some broken clients. - */ - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "no-case-compress", NULL, actx, - ns_g_mctx, &view->nocasecompress)); - - /* - * Disable name compression completely, this is a tradeoff - * between CPU and network usage. - */ - obj = NULL; - result = ns_config_get(maps, "message-compression", &obj); - INSIST(result == ISC_R_SUCCESS); - view->msgcompression = cfg_obj_asboolean(obj); - - /* - * Filter setting on addresses in the answer section. - */ - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "deny-answer-addresses", "acl", - actx, ns_g_mctx, - &view->denyansweracl)); - CHECK(configure_view_nametable(vconfig, config, "deny-answer-addresses", - "except-from", ns_g_mctx, - &view->answeracl_exclude)); - - /* - * Filter setting on names (CNAME/DNAME targets) in the answer section. - */ - CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases", - "name", ns_g_mctx, - &view->denyanswernames)); - CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases", - "except-from", ns_g_mctx, - &view->answernames_exclude)); - - /* - * Configure sortlist, if set - */ - CHECK(configure_view_sortlist(vconfig, config, actx, ns_g_mctx, - &view->sortlist)); - - /* - * Configure default allow-notify, allow-update - * and allow-update-forwarding ACLs, so they can be - * inherited by zones. (Note these cannot be set at - * options/view level.) - */ - if (view->notifyacl == NULL) { - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-notify", NULL, actx, - ns_g_mctx, &view->notifyacl)); - } - if (view->updateacl == NULL) { - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-update", NULL, actx, - ns_g_mctx, &view->updateacl)); - } - if (view->upfwdacl == NULL) { - CHECK(configure_view_acl(NULL, NULL, ns_g_config, - "allow-update-forwarding", NULL, actx, - ns_g_mctx, &view->upfwdacl)); - } - - /* - * Configure default allow-transer ACL so it can be inherited - * by zones. (Note this *can* be set at options or view level.) - */ - if (view->transferacl == NULL) { - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "allow-transfer", NULL, actx, - ns_g_mctx, &view->transferacl)); - } - - obj = NULL; - result = ns_config_get(maps, "provide-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->provideixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "request-nsid", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requestnsid = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "send-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - view->sendcookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "require-server-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requireservercookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "v6-bias", &obj); - INSIST(result == ISC_R_SUCCESS); - view->v6bias = cfg_obj_asuint32(obj) * 1000; - - obj = NULL; - result = ns_config_get(maps, "max-clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - max_clients_per_query = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setclientsperquery(view->resolver, - cfg_obj_asuint32(obj), - max_clients_per_query); - - obj = NULL; - result = ns_config_get(maps, "max-recursion-depth", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-recursion-queries", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "fetches-per-zone", &obj); - INSIST(result == ISC_R_SUCCESS); - obj2 = cfg_tuple_get(obj, "fetches"); - dns_resolver_setfetchesperzone(view->resolver, cfg_obj_asuint32(obj2)); - obj2 = cfg_tuple_get(obj, "response"); - if (!cfg_obj_isvoid(obj2)) { - const char *resp = cfg_obj_asstring(obj2); - isc_result_t r = DNS_R_SERVFAIL; - - if (strcasecmp(resp, "drop") == 0) { - r = DNS_R_DROP; - } else if (strcasecmp(resp, "fail") == 0) { - r = DNS_R_SERVFAIL; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - dns_resolver_setquotaresponse(view->resolver, - dns_quotatype_zone, r); - } - -#ifdef ALLOW_FILTER_AAAA - obj = NULL; - result = ns_config_get(maps, "filter-aaaa-on-v4", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->v4_aaaa = dns_aaaa_filter; - else - view->v4_aaaa = dns_aaaa_ok; - } else { - const char *v4_aaaastr = cfg_obj_asstring(obj); - if (strcasecmp(v4_aaaastr, "break-dnssec") == 0) { - view->v4_aaaa = dns_aaaa_break_dnssec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "filter-aaaa-on-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - view->v6_aaaa = dns_aaaa_filter; - else - view->v6_aaaa = dns_aaaa_ok; - } else { - const char *v6_aaaastr = cfg_obj_asstring(obj); - if (strcasecmp(v6_aaaastr, "break-dnssec") == 0) { - view->v6_aaaa = dns_aaaa_break_dnssec; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - CHECK(configure_view_acl(vconfig, config, ns_g_config, - "filter-aaaa", NULL, actx, - ns_g_mctx, &view->aaaa_acl)); -#endif - obj = NULL; - result = ns_config_get(maps, "prefetch", &obj); - if (result == ISC_R_SUCCESS) { - const cfg_obj_t *trigger, *eligible; - - trigger = cfg_tuple_get(obj, "trigger"); - view->prefetch_trigger = cfg_obj_asuint32(trigger); - if (view->prefetch_trigger > 10) - view->prefetch_trigger = 10; - eligible = cfg_tuple_get(obj, "eligible"); - if (cfg_obj_isvoid(eligible)) { - int m; - for (m = 1; maps[m] != NULL; m++) { - obj = NULL; - result = ns_config_get(&maps[m], - "prefetch", &obj); - INSIST(result == ISC_R_SUCCESS); - eligible = cfg_tuple_get(obj, "eligible"); - if (cfg_obj_isuint32(eligible)) - break; - } - INSIST(cfg_obj_isuint32(eligible)); - } - view->prefetch_eligible = cfg_obj_asuint32(eligible); - if (view->prefetch_eligible < view->prefetch_trigger + 6) - view->prefetch_eligible = view->prefetch_trigger + 6; - } - - obj = NULL; - result = ns_config_get(maps, "dnssec-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->enablednssec = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(optionmaps, "dnssec-lookaside", &obj); - if (result == ISC_R_SUCCESS) { - /* "auto" is deprecated, log a warning if seen */ - const char *dom; - dlvobj = cfg_listelt_value(cfg_list_first(obj)); - dom = cfg_obj_asstring(cfg_tuple_get(dlvobj, "domain")); - if (cfg_obj_isvoid(cfg_tuple_get(dlvobj, "trust-anchor"))) { - /* If "no", skip; if "auto", log warning */ - if (!strcasecmp(dom, "no")) { - result = ISC_R_NOTFOUND; - } else if (!strcasecmp(dom, "auto")) { - /* - * Warning logged by libbind9. - */ - result = ISC_R_NOTFOUND; - } - } - } - - if (result == ISC_R_SUCCESS) { - dns_name_t *dlv, *iscdlv; - dns_fixedname_t f; - - /* Also log a warning if manually configured to dlv.isc.org */ - iscdlv = dns_fixedname_initname(&f); - CHECK(dns_name_fromstring(iscdlv, "dlv.isc.org", 0, NULL)); - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - obj = cfg_tuple_get(obj, "trust-anchor"); - - dlv = dns_fixedname_name(&view->dlv_fixed); - CHECK(dns_name_fromstring(dlv, cfg_obj_asstring(obj), - DNS_NAME_DOWNCASE, NULL)); - if (dns_name_equal(dlv, iscdlv)) { - /* - * Warning logged by libbind9. - */ - view->dlv = NULL; - } else { - view->dlv = dlv; - } - } - } else { - view->dlv = NULL; - } - - /* - * For now, there is only one kind of trusted keys, the - * "security roots". - */ - CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys, - auto_root, mctx)); - dns_resolver_resetmustbesecure(view->resolver); - obj = NULL; - result = ns_config_get(maps, "dnssec-must-be-secure", &obj); - if (result == ISC_R_SUCCESS) - CHECK(mustbesecure(obj, view->resolver)); - - obj = NULL; - result = ns_config_get(maps, "nta-recheck", &obj); - INSIST(result == ISC_R_SUCCESS); - view->nta_recheck = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "nta-lifetime", &obj); - INSIST(result == ISC_R_SUCCESS); - view->nta_lifetime = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "preferred-glue", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "a") == 0) - view->preferred_glue = dns_rdatatype_a; - else if (strcasecmp(str, "aaaa") == 0) - view->preferred_glue = dns_rdatatype_aaaa; - else - view->preferred_glue = 0; - } else - view->preferred_glue = 0; - - obj = NULL; - result = ns_config_get(maps, "root-delegation-only", &obj); - if (result == ISC_R_SUCCESS) - dns_view_setrootdelonly(view, true); - if (result == ISC_R_SUCCESS && ! cfg_obj_isvoid(obj)) { - const cfg_obj_t *exclude; - dns_fixedname_t fixed; - dns_name_t *name; - - name = dns_fixedname_initname(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - exclude = cfg_listelt_value(element); - CHECK(dns_name_fromstring(name, - cfg_obj_asstring(exclude), - 0, NULL)); - CHECK(dns_view_excludedelegationonly(view, name)); - } - } else - dns_view_setrootdelonly(view, false); - - /* - * Load DynDB modules. - */ - dyndb_list = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "dyndb", &dyndb_list); - else - (void)cfg_map_get(config, "dyndb", &dyndb_list); - -#ifdef HAVE_DLOPEN - for (element = cfg_list_first(dyndb_list); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *dyndb = cfg_listelt_value(element); - - if (dctx == NULL) { - const void *hashinit = isc_hash_get_initializer(); - CHECK(dns_dyndb_createctx(mctx, hashinit, - ns_g_lctx, view, - ns_g_server->zonemgr, - ns_g_server->task, - ns_g_timermgr, &dctx)); - } - - CHECK(configure_dyndb(dyndb, mctx, dctx)); - } -#endif - - /* - * Setup automatic empty zones. If recursion is off then - * they are disabled by default. - */ - obj = NULL; - (void)ns_config_get(maps, "empty-zones-enable", &obj); - (void)ns_config_get(maps, "disable-empty-zone", &disablelist); - if (obj == NULL && disablelist == NULL && - view->rdclass == dns_rdataclass_in) { - empty_zones_enable = view->recursion; - } else if (view->rdclass == dns_rdataclass_in) { - if (obj != NULL) - empty_zones_enable = cfg_obj_asboolean(obj); - else - empty_zones_enable = view->recursion; - } else { - empty_zones_enable = false; - } - - if (empty_zones_enable && !lwresd_g_useresolvconf) { - const char *empty; - int empty_zone = 0; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t buffer; - char server[DNS_NAME_FORMATSIZE + 1]; - char contact[DNS_NAME_FORMATSIZE + 1]; - const char *empty_dbtype[4] = - { "_builtin", "empty", NULL, NULL }; - int empty_dbtypec = 4; - dns_zonestat_level_t statlevel = dns_zonestat_none; - - name = dns_fixedname_initname(&fixed); - - obj = NULL; - result = ns_config_get(maps, "empty-server", &obj); - if (result == ISC_R_SUCCESS) { - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), - 0, NULL)); - isc_buffer_init(&buffer, server, sizeof(server) - 1); - CHECK(dns_name_totext(name, false, &buffer)); - server[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[2] = server; - } else - empty_dbtype[2] = "@"; - - obj = NULL; - result = ns_config_get(maps, "empty-contact", &obj); - if (result == ISC_R_SUCCESS) { - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), - 0, NULL)); - isc_buffer_init(&buffer, contact, sizeof(contact) - 1); - CHECK(dns_name_totext(name, false, &buffer)); - contact[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[3] = contact; - } else - empty_dbtype[3] = "."; - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - statlevel = dns_zonestat_full; - else - statlevel = dns_zonestat_none; - } else { - const char *levelstr = cfg_obj_asstring(obj); - if (strcasecmp(levelstr, "full") == 0) { - statlevel = dns_zonestat_full; - } else if (strcasecmp(levelstr, "terse") == 0) { - statlevel = dns_zonestat_terse; - } else if (strcasecmp(levelstr, "none") == 0) { - statlevel = dns_zonestat_none; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - for (empty = empty_zones[empty_zone]; - empty != NULL; - empty = empty_zones[++empty_zone]) - { - dns_forwarders_t *dnsforwarders = NULL; - - /* - * Look for zone on drop list. - */ - CHECK(dns_name_fromstring(name, empty, 0, NULL)); - if (disablelist != NULL && - on_disable_list(disablelist, name)) - continue; - - /* - * This zone already exists. - */ - (void)dns_view_findzone(view, name, &zone); - if (zone != NULL) { - dns_zone_detach(&zone); - continue; - } - - /* - * If we would forward this name don't add a - * empty zone for it. - */ - result = dns_fwdtable_find(view->fwdtable, name, - &dnsforwarders); - if (result == ISC_R_SUCCESS && - dnsforwarders->fwdpolicy == dns_fwdpolicy_only) - continue; - - /* - * See if we can re-use a existing zone. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && - result != ISC_R_SUCCESS) - goto cleanup; - - if (pview != NULL) { - (void)dns_view_findzone(pview, name, &zone); - dns_view_detach(&pview); - } - - CHECK(create_empty_zone(zone, name, view, zonelist, - empty_dbtype, empty_dbtypec, - statlevel)); - if (zone != NULL) - dns_zone_detach(&zone); - } - } - - obj = NULL; - result = ns_config_get(maps, "rate-limit", &obj); - if (result == ISC_R_SUCCESS) { - result = configure_rrl(view, config, obj); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - /* - * Set the servfail-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "servfail-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - fail_ttl = cfg_obj_asuint32(obj); - if (fail_ttl > 30) - fail_ttl = 30; - dns_view_setfailttl(view, fail_ttl); - - /* - * Name space to look up redirect information in. - */ - obj = NULL; - result = ns_config_get(maps, "nxdomain-redirect", &obj); - if (result == ISC_R_SUCCESS) { - dns_name_t *name = dns_fixedname_name(&view->redirectfixed); - CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), 0, - NULL)); - view->redirectzone = name; - } else - view->redirectzone = NULL; - -#ifdef HAVE_DNSTAP - /* - * Set up the dnstap environment and configure message - * types to log. - */ - CHECK(configure_dnstap(maps, view)); -#endif /* HAVE_DNSTAP */ - - result = ISC_R_SUCCESS; - - cleanup: - if (clients != NULL) - dns_acl_detach(&clients); - if (mapped != NULL) - dns_acl_detach(&mapped); - if (excluded != NULL) - dns_acl_detach(&excluded); - if (ring != NULL) - dns_tsigkeyring_detach(&ring); - if (zone != NULL) - dns_zone_detach(&zone); - if (dispatch4 != NULL) - dns_dispatch_detach(&dispatch4); - if (dispatch6 != NULL) - dns_dispatch_detach(&dispatch6); - if (resstats != NULL) - isc_stats_detach(&resstats); - if (resquerystats != NULL) - dns_stats_detach(&resquerystats); - if (order != NULL) - dns_order_detach(&order); - if (cmctx != NULL) - isc_mem_detach(&cmctx); - if (hmctx != NULL) - isc_mem_detach(&hmctx); - - if (cache != NULL) - dns_cache_detach(&cache); - if (dctx != NULL) - dns_dyndb_destroyctx(&dctx); - - return (result); -} - -static isc_result_t -configure_hints(dns_view_t *view, const char *filename) { - isc_result_t result; - dns_db_t *db; - - db = NULL; - result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); - if (result == ISC_R_SUCCESS) { - dns_view_sethints(view, db); - dns_db_detach(&db); - } - - return (result); -} - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates) -{ - const cfg_obj_t *portobj; - const cfg_obj_t *addresses; - const cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - in_port_t port; - - /* - * Determine which port to send requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (alternates != NULL) { - portobj = cfg_tuple_get(alternates, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - addresses = NULL; - if (alternates != NULL) - addresses = cfg_tuple_get(alternates, "addresses"); - - for (element = cfg_list_first(addresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *alternate = cfg_listelt_value(element); - isc_sockaddr_t sa; - - if (!cfg_obj_issockaddr(alternate)) { - dns_fixedname_t fixed; - dns_name_t *name; - const char *str = cfg_obj_asstring(cfg_tuple_get( - alternate, "name")); - isc_buffer_t buffer; - in_port_t myport = port; - - isc_buffer_constinit(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - name = dns_fixedname_initname(&fixed); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0, - NULL)); - - portobj = cfg_tuple_get(alternate, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, - ISC_LOG_ERROR, - "port '%u' out of range", - val); - return (ISC_R_RANGE); - } - myport = (in_port_t) val; - } - CHECK(dns_resolver_addalternate(view->resolver, NULL, - name, myport)); - continue; - } - - sa = *cfg_obj_assockaddr(alternate); - if (isc_sockaddr_getport(&sa) == 0) - isc_sockaddr_setport(&sa, port); - CHECK(dns_resolver_addalternate(view->resolver, &sa, - NULL, 0)); - } - - cleanup: - return (result); -} - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype) -{ - const cfg_obj_t *portobj, *dscpobj; - const cfg_obj_t *faddresses; - const cfg_listelt_t *element; - dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; - dns_forwarderlist_t fwdlist; - dns_forwarder_t *fwd; - isc_result_t result; - in_port_t port; - isc_dscp_t dscp = -1; - - ISC_LIST_INIT(fwdlist); - - /* - * Determine which port to send forwarded requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (forwarders != NULL) { - portobj = cfg_tuple_get(forwarders, "port"); - if (cfg_obj_isuint32(portobj)) { - uint32_t val = cfg_obj_asuint32(portobj); - if (val > UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - /* - * DSCP value for forwarded requests. - */ - dscp = ns_g_dscp; - if (forwarders != NULL) { - dscpobj = cfg_tuple_get(forwarders, "dscp"); - if (cfg_obj_isuint32(dscpobj)) { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - } - - faddresses = NULL; - if (forwarders != NULL) - faddresses = cfg_tuple_get(forwarders, "addresses"); - - for (element = cfg_list_first(faddresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *forwarder = cfg_listelt_value(element); - fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t)); - if (fwd == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - fwd->addr = *cfg_obj_assockaddr(forwarder); - if (isc_sockaddr_getport(&fwd->addr) == 0) - isc_sockaddr_setport(&fwd->addr, port); - fwd->dscp = cfg_obj_getdscp(forwarder); - if (fwd->dscp == -1) - fwd->dscp = dscp; - ISC_LINK_INIT(fwd, link); - ISC_LIST_APPEND(fwdlist, fwd, link); - } - - if (ISC_LIST_EMPTY(fwdlist)) { - if (forwardtype != NULL) - cfg_obj_log(forwardtype, ns_g_lctx, ISC_LOG_WARNING, - "no forwarders seen; disabling " - "forwarding"); - fwdpolicy = dns_fwdpolicy_none; - } else { - if (forwardtype == NULL) { - fwdpolicy = dns_fwdpolicy_first; - } else { - const char *forwardstr = cfg_obj_asstring(forwardtype); - if (strcasecmp(forwardstr, "first") == 0) { - fwdpolicy = dns_fwdpolicy_first; - } else if (strcasecmp(forwardstr, "only") == 0) { - fwdpolicy = dns_fwdpolicy_only; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - } - - result = dns_fwdtable_addfwd(view->fwdtable, origin, &fwdlist, - fwdpolicy); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(origin, namebuf, sizeof(namebuf)); - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "could not set up forwarding for domain '%s': %s", - namebuf, isc_result_totext(result)); - goto cleanup; - } - - result = ISC_R_SUCCESS; - - cleanup: - - while (!ISC_LIST_EMPTY(fwdlist)) { - fwd = ISC_LIST_HEAD(fwdlist); - ISC_LIST_UNLINK(fwdlist, fwd, link); - isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t)); - } - - return (result); -} - -static isc_result_t -get_viewinfo(const cfg_obj_t *vconfig, const char **namep, - dns_rdataclass_t *classp) -{ - isc_result_t result = ISC_R_SUCCESS; - const char *viewname; - dns_rdataclass_t viewclass; - - REQUIRE(namep != NULL && *namep == NULL); - REQUIRE(classp != NULL); - - if (vconfig != NULL) { - const cfg_obj_t *classobj = NULL; - - viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); - classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - if (dns_rdataclass_ismeta(viewclass)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "view '%s': class must not be meta", - viewname); - CHECK(ISC_R_FAILURE); - } - } else { - viewname = "_default"; - viewclass = dns_rdataclass_in; - } - - *namep = viewname; - *classp = viewclass; - -cleanup: - return (result); -} - -/* - * Find a view based on its configuration info and attach to it. - * - * If 'vconfig' is NULL, attach to the default view. - */ -static isc_result_t -find_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, - dns_view_t **viewp) -{ - isc_result_t result; - const char *viewname = NULL; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - result = get_viewinfo(vconfig, &viewname, &viewclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result != ISC_R_SUCCESS) - return (result); - - *viewp = view; - return (ISC_R_SUCCESS); -} - -/* - * Create a new view and add it to the list. - * - * If 'vconfig' is NULL, create the default view. - * - * The view created is attached to '*viewp'. - */ -static isc_result_t -create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, - dns_view_t **viewp) -{ - isc_result_t result; - const char *viewname = NULL; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - result = get_viewinfo(vconfig, &viewname, &viewclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result == ISC_R_SUCCESS) - return (ISC_R_EXISTS); - if (result != ISC_R_NOTFOUND) - return (result); - INSIST(view == NULL); - - result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_entropy_getdata(ns_g_entropy, view->secret, - sizeof(view->secret), NULL, 0); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - return (result); - } - -#ifdef HAVE_GEOIP - view->aclenv.geoip = ns_g_geoip; -#endif - - ISC_LIST_APPEND(*viewlist, view, link); - dns_view_attach(view, viewp); - return (ISC_R_SUCCESS); -} - -/* - * Configure or reconfigure a zone. - */ -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf, - bool added, bool old_rpz_ok, - bool modify) -{ - dns_view_t *pview = NULL; /* Production view */ - dns_zone_t *zone = NULL; /* New or reused zone */ - dns_zone_t *raw = NULL; /* New or reused raw zone */ - dns_zone_t *dupzone = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *typeobj = NULL; - const cfg_obj_t *forwarders = NULL; - const cfg_obj_t *forwardtype = NULL; - const cfg_obj_t *ixfrfromdiffs = NULL; - const cfg_obj_t *only = NULL; - const cfg_obj_t *signing = NULL; - const cfg_obj_t *viewobj = NULL; - isc_result_t result; - isc_result_t tresult; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - const char *zname; - dns_rdataclass_t zclass; - const char *ztypestr; - dns_rpz_num_t rpz_num; - bool zone_is_catz = false; - - options = NULL; - (void)cfg_map_get(config, "options", &options); - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * Get the zone origin as a dns_name_t. - */ - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - isc_buffer_constinit(&buffer, zname, strlen(zname)); - isc_buffer_add(&buffer, strlen(zname)); - dns_fixedname_init(&fixorigin); - CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), - &buffer, dns_rootname, 0, NULL)); - origin = dns_fixedname_name(&fixorigin); - - CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - view->rdclass, &zclass)); - if (zclass != view->rdclass) { - const char *vname = NULL; - if (vconfig != NULL) - vname = cfg_obj_asstring(cfg_tuple_get(vconfig, - "name")); - else - vname = ""; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': wrong class for view '%s'", - zname, vname); - result = ISC_R_FAILURE; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "in-view", &viewobj); - if (viewobj != NULL) { - const char *inview = cfg_obj_asstring(viewobj); - dns_view_t *otherview = NULL; - - if (viewlist == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "'in-view' option is not permitted in " - "dynamically added zones"); - result = ISC_R_FAILURE; - goto cleanup; - } - - result = dns_viewlist_find(viewlist, inview, view->rdclass, - &otherview); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "view '%s' is not yet defined.", inview); - result = ISC_R_FAILURE; - goto cleanup; - } - - result = dns_view_findzone(otherview, origin, &zone); - dns_view_detach(&otherview); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' not defined in view '%s'", - zname, inview); - result = ISC_R_FAILURE; - goto cleanup; - } - - CHECK(dns_view_addzone(view, zone)); - dns_zone_detach(&zone); - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. Note: this is not inherited from the - * other view. - */ - forwarders = NULL; - result = cfg_map_get(zoptions, "forwarders", &forwarders); - if (result == ISC_R_SUCCESS) { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, - forwarders, forwardtype)); - } - result = ISC_R_SUCCESS; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "type", &typeobj); - if (typeobj == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' 'type' not specified", zname); - result = ISC_R_FAILURE; - goto cleanup; - } - ztypestr = cfg_obj_asstring(typeobj); - - /* - * "hints zones" aren't zones. If we've got one, - * configure it and return. - */ - if (strcasecmp(ztypestr, "hint") == 0) { - const cfg_obj_t *fileobj = NULL; - if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - result = ISC_R_FAILURE; - goto cleanup; - } - if (dns_name_equal(origin, dns_rootname)) { - const char *hintsfile = cfg_obj_asstring(fileobj); - - CHECK(configure_hints(view, hintsfile)); - - /* - * Hint zones may also refer to delegation only points. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", - &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "ignoring non-root hint zone '%s'", - zname); - result = ISC_R_SUCCESS; - } - /* Skip ordinary zone processing. */ - goto cleanup; - } - - /* - * "forward zones" aren't zones either. Translate this syntax into - * the appropriate selective forwarding configuration and return. - */ - if (strcasecmp(ztypestr, "forward") == 0) { - forwardtype = NULL; - forwarders = NULL; - - (void)cfg_map_get(zoptions, "forward", &forwardtype); - (void)cfg_map_get(zoptions, "forwarders", &forwarders); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - - /* - * Forward zones may also set delegation only. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - goto cleanup; - } - - /* - * "delegation-only zones" aren't zones either. - */ - if (strcasecmp(ztypestr, "delegation-only") == 0) { - result = dns_view_adddelegationonly(view, origin); - goto cleanup; - } - - /* - * Redirect zones only require minimal configuration. - */ - if (strcasecmp(ztypestr, "redirect") == 0) { - if (view->redirect != NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "redirect zone already exists"); - result = ISC_R_EXISTS; - goto cleanup; - } - result = dns_viewlist_find(viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL && pview->redirect != NULL) { - dns_zone_attach(pview->redirect, &zone); - dns_zone_setview(zone, view); - } else { - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, - &zone)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, - zone)); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, - zone, NULL)); - dns_zone_attach(zone, &view->redirect); - goto cleanup; - } - - if (!modify) { - /* - * Check for duplicates in the new zone table. - */ - result = dns_view_findzone(view, origin, &dupzone); - if (result == ISC_R_SUCCESS) { - /* - * We already have this zone! - */ - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' already exists", zname); - dns_zone_detach(&dupzone); - result = ISC_R_EXISTS; - goto cleanup; - } - INSIST(dupzone == NULL); - } - - /* - * Note whether this is a response policy zone and which one if so. - */ - for (rpz_num = 0; ; ++rpz_num) { - if (view->rpzs == NULL || rpz_num >= view->rpzs->p.num_zones) { - rpz_num = DNS_RPZ_INVALID_NUM; - break; - } - if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin, origin)) - break; - } - - if (view->catzs != NULL && - dns_catz_get_zone(view->catzs, origin) != NULL) - zone_is_catz = true; - - /* - * See if we can reuse an existing zone. This is - * only possible if all of these are true: - * - The zone's view exists - * - A zone with the right name exists in the view - * - The zone is compatible with the config - * options (e.g., an existing master zone cannot - * be reused if the options specify a slave zone) - * - The zone was not and is still not a response policy zone - * or the zone is a policy zone with an unchanged number - * and we are using the old policy zone summary data. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) - result = dns_view_findzone(pview, origin, &zone); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - - if (zone != NULL && !ns_zone_reusable(zone, zconfig)) - dns_zone_detach(&zone); - - if (zone != NULL && (rpz_num != dns_zone_get_rpz_num(zone) || - (rpz_num != DNS_RPZ_INVALID_NUM && !old_rpz_ok))) - dns_zone_detach(&zone); - - if (zone != NULL) { - /* - * We found a reusable zone. Make it use the - * new view. - */ - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - } else { - /* - * We cannot reuse an existing zone, we have - * to create a new one. - */ - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - dns_zone_setstats(zone, ns_g_server->zonestats); - } - if (rpz_num != DNS_RPZ_INVALID_NUM) { - result = dns_zone_rpz_enable(zone, view->rpzs, rpz_num); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': incompatible" - " masterfile-format or database" - " for a response policy zone", - zname); - goto cleanup; - } - } - - if (zone_is_catz) - dns_zone_catz_enable(zone, view->catzs); - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. - */ - forwarders = NULL; - if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) - { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - } - - /* - * Stub and forward zones may also refer to delegation only points. - */ - only = NULL; - if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) - { - if (cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } - - /* - * Mark whether the zone was originally added at runtime or not - */ - dns_zone_setadded(zone, added); - - signing = NULL; - if ((strcasecmp(ztypestr, "master") == 0 || - strcasecmp(ztypestr, "slave") == 0) && - cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS && - cfg_obj_asboolean(signing)) - { - dns_zone_getraw(zone, &raw); - if (raw == NULL) { - CHECK(dns_zone_create(&raw, mctx)); - CHECK(dns_zone_setorigin(raw, origin)); - dns_zone_setview(raw, view); - if (view->acache != NULL) - dns_zone_setacache(raw, view->acache); - dns_zone_setstats(raw, ns_g_server->zonestats); - CHECK(dns_zone_link(zone, raw)); - } - if (cfg_map_get(zoptions, "ixfr-from-differences", - &ixfrfromdiffs) == ISC_R_SUCCESS) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "zone '%s': 'ixfr-from-differences' is " - "ignored for inline-signed zones", - zname); - } - } - - /* - * Configure the zone. - */ - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone, raw)); - - /* - * Add the zone to its view in the new view list. - */ - if (!modify) - CHECK(dns_view_addzone(view, zone)); - - if (zone_is_catz) { - /* - * force catz reload if the zone is loaded; - * if it's not it'll get reloaded on zone load - */ - dns_db_t *db = NULL; - - tresult = dns_zone_getdb(zone, &db); - if (tresult == ISC_R_SUCCESS) { - dns_catz_dbupdate_callback(db, view->catzs); - dns_db_detach(&db); - } - - } - - /* - * Ensure that zone keys are reloaded on reconfig - */ - if ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0) - dns_zone_rekey(zone, false); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (raw != NULL) - dns_zone_detach(&raw); - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -/* - * Configure built-in zone for storing managed-key data. - */ - -static isc_result_t -add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) { - isc_result_t result; - dns_view_t *pview = NULL; - dns_zone_t *zone = NULL; - dns_acl_t *none = NULL; - char filename[PATH_MAX]; - bool defaultview; - - REQUIRE(view != NULL); - - /* See if we can re-use an existing keydata zone. */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && - result != ISC_R_SUCCESS) - return (result); - - if (pview != NULL && pview->managed_keys != NULL) { - dns_zone_attach(pview->managed_keys, &view->managed_keys); - dns_zone_setview(pview->managed_keys, view); - dns_view_detach(&pview); - dns_zone_synckeyzone(view->managed_keys); - return (ISC_R_SUCCESS); - } - - /* No existing keydata zone was found; create one */ - CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone)); - CHECK(dns_zone_setorigin(zone, dns_rootname)); - - defaultview = (strcmp(view->name, "_default") == 0); - CHECK(isc_file_sanitize(directory, - defaultview ? "managed-keys" : view->name, - defaultview ? "bind" : "mkeys", - filename, sizeof(filename))); - CHECK(dns_zone_setfile(zone, filename)); - - dns_zone_setview(zone, view); - dns_zone_settype(zone, dns_zone_key); - dns_zone_setclass(zone, view->rdclass); - - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - - CHECK(dns_acl_none(mctx, &none)); - dns_zone_setqueryacl(zone, none); - dns_zone_setqueryonacl(zone, none); - dns_acl_detach(&none); - - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); - dns_zone_setjournalsize(zone, 0); - - dns_zone_setstats(zone, ns_g_server->zonestats); - CHECK(setquerystats(zone, mctx, dns_zonestat_none)); - - if (view->managed_keys != NULL) - dns_zone_detach(&view->managed_keys); - dns_zone_attach(zone, &view->managed_keys); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "set up managed keys zone for view %s, file '%s'", - view->name, filename); - -cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (none != NULL) - dns_acl_detach(&none); - - return (result); -} - -/* - * Configure a single server quota. - */ -static void -configure_server_quota(const cfg_obj_t **maps, const char *name, - isc_quota_t *quota) -{ - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = ns_config_get(maps, name, &obj); - INSIST(result == ISC_R_SUCCESS); - isc_quota_max(quota, cfg_obj_asuint32(obj)); -} - -/* - * This function is called as soon as the 'directory' statement has been - * parsed. This can be extended to support other options if necessary. - */ -static isc_result_t -directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { - isc_result_t result; - const char *directory; - - REQUIRE(strcasecmp("directory", clausename) == 0); - - UNUSED(arg); - UNUSED(clausename); - - /* - * Change directory. - */ - directory = cfg_obj_asstring(obj); - - if (! isc_file_ischdiridempotent(directory)) - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "option 'directory' contains relative path '%s'", - directory); - - result = isc_dir_chdir(directory); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "change directory to '%s' failed: %s", - directory, isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -scan_interfaces(ns_server_t *server, bool verbose) { - isc_result_t result; - bool match_mapped = server->aclenv.match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - bool use_ecs = server->aclenv.geoip_use_ecs; -#endif - - result = ns_interfacemgr_scan(server->interfacemgr, verbose); - /* - * Update the "localhost" and "localnets" ACLs to match the - * current set of network interfaces. - */ - dns_aclenv_copy(&server->aclenv, - ns_interfacemgr_getaclenv(server->interfacemgr)); - - server->aclenv.match_mapped = match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - server->aclenv.geoip_use_ecs = use_ecs; -#endif - - return (result); -} - -static isc_result_t -add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr, - isc_dscp_t dscp, bool wcardport_ok) -{ - ns_listenelt_t *lelt = NULL; - dns_acl_t *src_acl = NULL; - isc_result_t result; - isc_sockaddr_t any_sa6; - isc_netaddr_t netaddr; - - REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); - - isc_sockaddr_any6(&any_sa6); - if (!isc_sockaddr_equal(&any_sa6, addr) && - (wcardport_ok || isc_sockaddr_getport(addr) != 0)) { - isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr); - - result = dns_acl_create(mctx, 0, &src_acl); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_iptable_addprefix(src_acl->iptable, - &netaddr, 128, true); - if (result != ISC_R_SUCCESS) - goto clean; - - result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), - dscp, src_acl, &lelt); - if (result != ISC_R_SUCCESS) - goto clean; - ISC_LIST_APPEND(list->elts, lelt, link); - } - - return (ISC_R_SUCCESS); - - clean: - INSIST(lelt == NULL); - dns_acl_detach(&src_acl); - - return (result); -} - -/* - * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() - * to update the listening interfaces accordingly. - * We currently only consider IPv6, because this only affects IPv6 wildcard - * sockets. - */ -static void -adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { - isc_result_t result; - ns_listenlist_t *list = NULL; - dns_view_t *view; - dns_zone_t *zone, *next; - isc_sockaddr_t addr, *addrp; - isc_dscp_t dscp = -1; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - return; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_dispatch_t *dispatch6; - - dispatch6 = dns_resolver_dispatchv6(view->resolver); - if (dispatch6 == NULL) - continue; - result = dns_dispatch_getlocaladdress(dispatch6, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * We always add non-wildcard address regardless of whether - * the port is 'any' (the fourth arg is TRUE): if the port is - * specific, we need to add it since it may conflict with a - * listening interface; if it's zero, we'll dynamically open - * query ports, and some of them may override an existing - * wildcard IPv6 port. - */ - /* XXXMPA fix dscp */ - result = add_listenelt(mctx, list, &addr, dscp, true); - if (result != ISC_R_SUCCESS) - goto fail; - } - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) { - dns_view_t *zoneview; - - /* - * At this point the zone list may contain a stale zone - * just removed from the configuration. To see the validity, - * check if the corresponding view is in our current view list. - * There may also be old zones that are still in the process - * of shutting down and have detached from their old view - * (zoneview == NULL). - */ - zoneview = dns_zone_getview(zone); - if (zoneview == NULL) - continue; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL && view != zoneview; - view = ISC_LIST_NEXT(view, link)) - ; - if (view == NULL) - continue; - - addrp = dns_zone_getnotifysrc6(zone); - dscp = dns_zone_getnotifysrc6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) - goto fail; - - addrp = dns_zone_getxfrsource6(zone); - dscp = dns_zone_getxfrsource6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) - goto fail; - } - - ns_interfacemgr_adjust(server->interfacemgr, list, true); - - clean: - ns_listenlist_detach(&list); - return; - - fail: - /* - * Even when we failed the procedure, most of other interfaces - * should work correctly. We therefore just warn it. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "could not adjust the listen-on list; " - "some interfaces may not work"); - goto clean; -} - -/* - * This event callback is invoked to do periodic network interface - * scanning. It is also called by ns_server_scan_interfaces(), - * invoked by "rndc scan" - */ - -static void -interface_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - INSIST(task == server->task); - UNUSED(task); - - isc_event_free(&event); - - /* - * XXX should scan interfaces unlocked and get exclusive access - * only to replace ACLs. - */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, false); - isc_task_endexclusive(server->task); -} - -static void -heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *) event->ev_arg; - dns_view_t *view; - - UNUSED(task); - isc_event_free(&event); - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - dns_view_dialup(view); - view = ISC_LIST_NEXT(view, link); - } -} - -typedef struct { - isc_mem_t *mctx; - isc_task_t *task; - dns_fetch_t *fetch; - dns_view_t *view; - dns_fixedname_t tatname; - dns_fixedname_t keyname; - dns_rdataset_t rdataset; - dns_rdataset_t sigrdataset; -} ns_tat_t; - -static int -cid(const void *a, const void *b) { - const uint16_t ida = *(const uint16_t *)a; - const uint16_t idb = *(const uint16_t *)b; - if (ida < idb) - return (-1); - else if (ida > idb) - return (1); - else - return (0); -} - -static void -tat_done(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent; - ns_tat_t *tat; - - INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); - INSIST(event->ev_arg != NULL); - - UNUSED(task); - - tat = event->ev_arg; - devent = (dns_fetchevent_t *) event; - - /* Free resources which are not of interest */ - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - isc_event_free(&event); - dns_resolver_destroyfetch(&tat->fetch); - if (dns_rdataset_isassociated(&tat->rdataset)) - dns_rdataset_disassociate(&tat->rdataset); - if (dns_rdataset_isassociated(&tat->sigrdataset)) - dns_rdataset_disassociate(&tat->sigrdataset); - dns_view_detach(&tat->view); - isc_task_detach(&tat->task); - isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat)); -} - -struct dotat_arg { - dns_view_t *view; - isc_task_t *task; -}; - -/*% - * Prepare the QNAME for the TAT query to be sent by processing the trust - * anchors present at 'keynode' of 'keytable'. Store the result in 'dst' and - * the domain name which 'keynode' is associated with in 'keyname'. - * - * A maximum of 12 key IDs can be reported in a single TAT query due to the - * 63-octet length limit for any single label in a domain name. If there are - * more than 12 keys configured at 'keynode', only the first 12 will be - * reported in the TAT query. - */ -static isc_result_t -get_tat_qname(dns_name_t *dst, dns_name_t **keyname, dns_keytable_t *keytable, - dns_keynode_t *keynode) -{ - dns_keynode_t *firstnode = keynode; - dns_keynode_t *nextnode; - unsigned int i, n = 0; - uint16_t ids[12]; - isc_textregion_t r; - char label[64]; - int m; - - REQUIRE(keyname != NULL && *keyname == NULL); - - do { - dst_key_t *key = dns_keynode_key(keynode); - if (key != NULL) { - *keyname = dst_key_name(key); - if (n < (sizeof(ids)/sizeof(ids[0]))) { - ids[n] = dst_key_id(key); - n++; - } - } - nextnode = NULL; - (void)dns_keytable_nextkeynode(keytable, keynode, &nextnode); - if (keynode != firstnode) - dns_keytable_detachkeynode(keytable, &keynode); - keynode = nextnode; - } while (keynode != NULL); - - if (n == 0) { - return (DNS_R_EMPTYNAME); - } - - if (n > 1) - qsort(ids, n, sizeof(ids[0]), cid); - - /* - * Encoded as "_ta-xxxx\(-xxxx\)*" where xxxx is the hex version of - * of the keyid. - */ - label[0] = 0; - r.base = label; - r.length = sizeof(label);; - m = snprintf(r.base, r.length, "_ta"); - if (m < 0 || (unsigned)m > r.length) { - return (ISC_R_FAILURE); - } - isc_textregion_consume(&r, m); - for (i = 0; i < n; i++) { - m = snprintf(r.base, r.length, "-%04x", ids[i]); - if (m < 0 || (unsigned)m > r.length) { - return (ISC_R_FAILURE); - } - isc_textregion_consume(&r, m); - } - - return (dns_name_fromstring2(dst, label, *keyname, 0, NULL)); -} - -static void -tat_send(isc_task_t *task, isc_event_t *event) { - ns_tat_t *tat; - char namebuf[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fdomain; - dns_name_t *domain; - dns_rdataset_t nameservers; - isc_result_t result; - dns_name_t *keyname; - dns_name_t *tatname; - - INSIST(event != NULL && event->ev_type == NS_EVENT_TATSEND); - INSIST(event->ev_arg != NULL); - - UNUSED(task); - - tat = event->ev_arg; - - tatname = dns_fixedname_name(&tat->tatname); - keyname = dns_fixedname_name(&tat->keyname); - - dns_name_format(tatname, namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "%s: sending trust-anchor-telemetry query '%s/NULL'", - tat->view->name, namebuf); - - /* - * TAT queries should be sent to the authoritative servers for a given - * zone. If this function is called for a keytable node corresponding - * to a locally served zone, calling dns_resolver_createfetch() with - * NULL 'domain' and 'nameservers' arguments will cause 'tatname' to be - * resolved locally, without sending any TAT queries upstream. - * - * Work around this issue by calling dns_view_findzonecut() first. If - * the zone is served locally, the NS RRset for the given domain name - * will be retrieved from local data; if it is not, the deepest zone - * cut we have for it will be retrieved from cache. In either case, - * passing the results to dns_resolver_createfetch() will prevent it - * from returning NXDOMAIN for 'tatname' while still allowing it to - * chase down any potential delegations returned by upstream servers in - * order to eventually find the destination host to send the TAT query - * to. - * - * 'keyname' holds the domain name at 'keynode', i.e. the domain name - * for which the trust anchors to be reported by this TAT query are - * defined. - * - * After the dns_view_findzonecut() call, 'domain' will hold the - * deepest zone cut we can find for 'keyname' while 'nameservers' will - * hold the NS RRset at that zone cut. - */ - domain = dns_fixedname_initname(&fdomain); - dns_rdataset_init(&nameservers); - result = dns_view_findzonecut(tat->view, keyname, domain, 0, 0, true, - &nameservers, NULL); - if (result == ISC_R_SUCCESS) { - result = dns_resolver_createfetch(tat->view->resolver, tatname, - dns_rdatatype_null, domain, - &nameservers, NULL, 0, - tat->task, tat_done, tat, - &tat->rdataset, - &tat->sigrdataset, - &tat->fetch); - } - - /* - * 'domain' holds the dns_name_t pointer inside a dst_key_t structure. - * dns_resolver_createfetch() creates its own copy of 'domain' if it - * succeeds. Thus, 'domain' is not freed here. - * - * Even if dns_view_findzonecut() returned something else than - * ISC_R_SUCCESS, it still could have associated 'nameservers'. - * dns_resolver_createfetch() creates its own copy of 'nameservers' if - * it succeeds. Thus, we need to check whether 'nameservers' is - * associated and release it if it is. - */ - if (dns_rdataset_isassociated(&nameservers)) { - dns_rdataset_disassociate(&nameservers); - } - - if (result != ISC_R_SUCCESS) { - dns_view_detach(&tat->view); - isc_task_detach(&tat->task); - isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat)); - } - isc_event_free(&event); -} - -static void -dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) { - struct dotat_arg *dotat_arg = arg; - dns_name_t *keyname = NULL; - isc_result_t result; - dns_view_t *view; - isc_task_t *task; - ns_tat_t *tat; - isc_event_t *event; - - REQUIRE(keytable != NULL); - REQUIRE(keynode != NULL); - REQUIRE(dotat_arg != NULL); - - view = dotat_arg->view; - task = dotat_arg->task; - - tat = isc_mem_get(dotat_arg->view->mctx, sizeof(*tat)); - - tat->fetch = NULL; - tat->mctx = NULL; - tat->task = NULL; - tat->view = NULL; - dns_rdataset_init(&tat->rdataset); - dns_rdataset_init(&tat->sigrdataset); - result = get_tat_qname(dns_fixedname_initname(&tat->tatname), &keyname, - keytable, keynode); - if (result != ISC_R_SUCCESS) { - isc_mem_put(dotat_arg->view->mctx, tat, sizeof(*tat)); - return; - } - dns_name_copy(keyname, dns_fixedname_initname(&tat->keyname), NULL); - isc_mem_attach(dotat_arg->view->mctx, &tat->mctx); - isc_task_attach(task, &tat->task); - dns_view_attach(view, &tat->view); - - /* - * We don't want to be holding the keytable lock when calling - * dns_view_findzonecut() as it creates a lock order loop so - * call dns_view_findzonecut() in a event handler. - * - * zone->lock (dns_zone_setviewcommit) while holding view->lock - * (dns_view_setviewcommit) - * - * keytable->lock (dns_keytable_find) while holding zone->lock - * (zone_asyncload) - * - * view->lock (dns_view_findzonecut) while holding keytable->lock - * (dns_keytable_forall) - */ - event = isc_event_allocate(tat->mctx, keytable, NS_EVENT_TATSEND, - tat_send, tat, sizeof(isc_event_t)); - isc_task_send(task, &event); -} - -static void -tat_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - struct dotat_arg arg; - dns_view_t *view; - dns_keytable_t *secroots = NULL; - - isc_event_free(&event); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (!view->trust_anchor_telemetry || - !view->enablevalidation) - { - continue; - } - - result = dns_view_getsecroots(view, &secroots); - if (result != ISC_R_SUCCESS) { - continue; - } - - arg.view = view; - arg.task = task; - (void)dns_keytable_forall(secroots, dotat, &arg); - dns_keytable_detach(&secroots); - } -} - -static void -pps_timer_tick(isc_task_t *task, isc_event_t *event) { - static unsigned int oldrequests = 0; - unsigned int requests = ncr_load(ns_client_requests); - - UNUSED(task); - isc_event_free(&event); - - /* - * Don't worry about wrapping as the overflow result will be right. - */ - dns_pps = (requests - oldrequests) / 1200; - oldrequests = requests; -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with a dynamically allocated copy of the - * null-terminated string pointed to by 'value', or NULL. - */ -static isc_result_t -setstring(ns_server_t *server, char **field, const char *value) { - char *copy; - - if (value != NULL) { - copy = isc_mem_strdup(server->mctx, value); - if (copy == NULL) - return (ISC_R_NOMEMORY); - } else { - copy = NULL; - } - - if (*field != NULL) - isc_mem_free(server->mctx, *field); - - *field = copy; - return (ISC_R_SUCCESS); -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with another dynamically allocated string - * or NULL if whether 'obj' is a string or void value, respectively. - */ -static isc_result_t -setoptstring(ns_server_t *server, char **field, const cfg_obj_t *obj) { - if (cfg_obj_isvoid(obj)) - return (setstring(server, field, NULL)); - else - return (setstring(server, field, cfg_obj_asstring(obj))); -} - -static void -set_limit(const cfg_obj_t **maps, const char *configname, - const char *description, isc_resource_t resourceid, - isc_resourcevalue_t defaultvalue) -{ - const cfg_obj_t *obj = NULL; - const char *resource; - isc_resourcevalue_t value; - isc_result_t result; - - if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) - return; - - if (cfg_obj_isstring(obj)) { - resource = cfg_obj_asstring(obj); - if (strcasecmp(resource, "unlimited") == 0) - value = ISC_RESOURCE_UNLIMITED; - else { - INSIST(strcasecmp(resource, "default") == 0); - value = defaultvalue; - } - } else - value = cfg_obj_asuint64(obj); - - result = isc_resource_setlimit(resourceid, value); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - result == ISC_R_SUCCESS ? - ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, - "set maximum %s to %" PRIu64 ": %s", - description, value, isc_result_totext(result)); -} - -#define SETLIMIT(cfgvar, resource, description) \ - set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ - ns_g_init ## resource) - -static void -set_limits(const cfg_obj_t **maps) { - SETLIMIT("stacksize", stacksize, "stack size"); - SETLIMIT("datasize", datasize, "data size"); - SETLIMIT("coresize", coresize, "core size"); - SETLIMIT("files", openfiles, "open files"); -} - -static void -portset_fromconf(isc_portset_t *portset, const cfg_obj_t *ports, - bool positive) -{ - const cfg_listelt_t *element; - - for (element = cfg_list_first(ports); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *obj = cfg_listelt_value(element); - - if (cfg_obj_isuint32(obj)) { - in_port_t port = (in_port_t)cfg_obj_asuint32(obj); - - if (positive) - isc_portset_add(portset, port); - else - isc_portset_remove(portset, port); - } else { - const cfg_obj_t *obj_loport, *obj_hiport; - in_port_t loport, hiport; - - obj_loport = cfg_tuple_get(obj, "loport"); - loport = (in_port_t)cfg_obj_asuint32(obj_loport); - obj_hiport = cfg_tuple_get(obj, "hiport"); - hiport = (in_port_t)cfg_obj_asuint32(obj_hiport); - - if (positive) - isc_portset_addrange(portset, loport, hiport); - else { - isc_portset_removerange(portset, loport, - hiport); - } - } - } -} - -static isc_result_t -removed(dns_zone_t *zone, void *uap) { - const char *type; - - if (dns_zone_getview(zone) != uap) - return (ISC_R_SUCCESS); - - switch (dns_zone_gettype(zone)) { - case dns_zone_master: - type = "master"; - break; - case dns_zone_slave: - type = "slave"; - break; - case dns_zone_stub: - type = "stub"; - break; - case dns_zone_staticstub: - type = "static-stub"; - break; - case dns_zone_redirect: - type = "redirect"; - break; - default: - type = "other"; - break; - } - dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type); - return (ISC_R_SUCCESS); -} - -static void -cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) { - if (server->session_keyfile != NULL) { - isc_file_remove(server->session_keyfile); - isc_mem_free(mctx, server->session_keyfile); - server->session_keyfile = NULL; - } - - if (server->session_keyname != NULL) { - if (dns_name_dynamic(server->session_keyname)) - dns_name_free(server->session_keyname, mctx); - isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t)); - server->session_keyname = NULL; - } - - if (server->sessionkey != NULL) - dns_tsigkey_detach(&server->sessionkey); - - server->session_keyalg = DST_ALG_UNKNOWN; - server->session_keybits = 0; -} - -static isc_result_t -generate_session_key(const char *filename, const char *keynamestr, - dns_name_t *keyname, const char *algstr, - dns_name_t *algname, unsigned int algtype, - uint16_t bits, isc_mem_t *mctx, bool first_time, - dns_tsigkey_t **tsigkeyp) -{ - isc_result_t result = ISC_R_SUCCESS; - dst_key_t *key = NULL; - isc_buffer_t key_txtbuffer; - isc_buffer_t key_rawbuffer; - char key_txtsecret[256]; - char key_rawsecret[64]; - isc_region_t key_rawregion; - isc_stdtime_t now; - dns_tsigkey_t *tsigkey = NULL; - FILE *fp = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "generating session key for dynamic DNS"); - - /* generate key */ - result = dst_key_generate(keyname, algtype, bits, 1, 0, - DNS_KEYPROTO_ANY, dns_rdataclass_in, - mctx, &key); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Dump the key to the buffer for later use. Should be done before - * we transfer the ownership of key to tsigkey. - */ - isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret)); - CHECK(dst_key_tobuffer(key, &key_rawbuffer)); - - isc_buffer_usedregion(&key_rawbuffer, &key_rawregion); - isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret)); - CHECK(isc_base64_totext(&key_rawregion, -1, "", &key_txtbuffer)); - - /* Store the key in tsigkey. */ - isc_stdtime_get(&now); - CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key, - false, NULL, now, now, mctx, NULL, - &tsigkey)); - - /* Dump the key to the key file. */ - fp = ns_os_openfile(filename, S_IRUSR|S_IWUSR, first_time); - if (fp == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not create %s", filename); - result = ISC_R_NOPERM; - goto cleanup; - } - - fprintf(fp, "key \"%s\" {\n" - "\talgorithm %s;\n" - "\tsecret \"%.*s\";\n};\n", keynamestr, algstr, - (int) isc_buffer_usedlength(&key_txtbuffer), - (char*) isc_buffer_base(&key_txtbuffer)); - - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - if (result != ISC_R_SUCCESS) - goto cleanup; - - dst_key_free(&key); - - *tsigkeyp = tsigkey; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to generate session key " - "for dynamic DNS: %s", isc_result_totext(result)); - if (fp != NULL) { - (void)isc_stdio_close(fp); - (void)isc_file_remove(filename); - } - if (tsigkey != NULL) - dns_tsigkey_detach(&tsigkey); - if (key != NULL) - dst_key_free(&key); - - return (result); -} - -static isc_result_t -configure_session_key(const cfg_obj_t **maps, ns_server_t *server, - isc_mem_t *mctx, bool first_time) -{ - const char *keyfile, *keynamestr, *algstr; - unsigned int algtype; - dns_fixedname_t fname; - dns_name_t *keyname, *algname; - isc_buffer_t buffer; - uint16_t bits; - const cfg_obj_t *obj; - bool need_deleteold = false; - bool need_createnew = false; - isc_result_t result; - - obj = NULL; - result = ns_config_get(maps, "session-keyfile", &obj); - if (result == ISC_R_SUCCESS) { - if (cfg_obj_isvoid(obj)) - keyfile = NULL; /* disable it */ - else - keyfile = cfg_obj_asstring(obj); - } else - keyfile = ns_g_defaultsessionkeyfile; - - obj = NULL; - result = ns_config_get(maps, "session-keyname", &obj); - INSIST(result == ISC_R_SUCCESS); - keynamestr = cfg_obj_asstring(obj); - isc_buffer_constinit(&buffer, keynamestr, strlen(keynamestr)); - isc_buffer_add(&buffer, strlen(keynamestr)); - keyname = dns_fixedname_initname(&fname); - result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = ns_config_get(maps, "session-keyalg", &obj); - INSIST(result == ISC_R_SUCCESS); - algstr = cfg_obj_asstring(obj); - algname = NULL; - result = ns_config_getkeyalgorithm2(algstr, &algname, &algtype, &bits); - if (result != ISC_R_SUCCESS) { - const char *s = " (keeping current key)"; - - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: " - "unsupported or unknown algorithm '%s'%s", - algstr, - server->session_keyfile != NULL ? s : ""); - return (result); - } - - /* See if we need to (re)generate a new key. */ - if (keyfile == NULL) { - if (server->session_keyfile != NULL) - need_deleteold = true; - } else if (server->session_keyfile == NULL) - need_createnew = true; - else if (strcmp(keyfile, server->session_keyfile) != 0 || - !dns_name_equal(server->session_keyname, keyname) || - server->session_keyalg != algtype || - server->session_keybits != bits) { - need_deleteold = true; - need_createnew = true; - } - - if (need_deleteold) { - INSIST(server->session_keyfile != NULL); - INSIST(server->session_keyname != NULL); - INSIST(server->sessionkey != NULL); - - cleanup_session_key(server, mctx); - } - - if (need_createnew) { - INSIST(server->sessionkey == NULL); - INSIST(server->session_keyfile == NULL); - INSIST(server->session_keyname == NULL); - INSIST(server->session_keyalg == DST_ALG_UNKNOWN); - INSIST(server->session_keybits == 0); - - server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t)); - if (server->session_keyname == NULL) - goto cleanup; - dns_name_init(server->session_keyname, NULL); - CHECK(dns_name_dup(keyname, mctx, server->session_keyname)); - - server->session_keyfile = isc_mem_strdup(mctx, keyfile); - if (server->session_keyfile == NULL) - goto cleanup; - - server->session_keyalg = algtype; - server->session_keybits = bits; - - CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr, - algname, algtype, bits, mctx, - first_time, &server->sessionkey)); - } - - return (result); - - cleanup: - cleanup_session_key(server, mctx); - return (result); -} - -#ifndef HAVE_LMDB -static isc_result_t -count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) { - isc_result_t result; - - /* The new zone file may not exist. That is OK. */ - if (!isc_file_exists(view->new_zone_file)) { - *num_zonesp = 0; - return (ISC_R_SUCCESS); - } - - /* - * In the case of NZF files, we also parse the configuration in - * the file at this stage. - * - * This may be called in multiple views, so we reset - * the parser each time. - */ - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_file(ns_g_addparser, view->new_zone_file, - &cfg_type_addzoneconf, &nzcfg->nzf_config); - if (result == ISC_R_SUCCESS) { - int num_zones; - - num_zones = count_zones(nzcfg->nzf_config); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "NZF file '%s' contains %d zones", - view->new_zone_file, num_zones); - if (num_zonesp != NULL) - *num_zonesp = num_zones; - } else { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error parsing NZF file '%s': %s", - view->new_zone_file, - isc_result_totext(result)); - } - - return (result); -} - -#else /* HAVE_LMDB */ - -static isc_result_t -count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) { - isc_result_t result; - int n; - - UNUSED(nzcfg); - - REQUIRE(num_zonesp != NULL); - - LOCK(&view->new_zone_lock); - - CHECK(migrate_nzf(view)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD zone count from '%s' " - "for view '%s'", - view->new_zone_db, view->name); - - CHECK(nzd_count(view, &n)); - - *num_zonesp = n; - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "NZD database '%s' contains %d zones", - view->new_zone_db, n); - - cleanup: - if (result != ISC_R_SUCCESS) - *num_zonesp = 0; - - UNLOCK(&view->new_zone_lock); - - return (ISC_R_SUCCESS); -} - -#endif /* HAVE_LMDB */ - -static isc_result_t -setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - cfg_parser_t *conf_parser, cfg_aclconfctx_t *actx, - int *num_zones) -{ - isc_result_t result = ISC_R_SUCCESS; - bool allow = false; - ns_cfgctx_t *nzcfg = NULL; - const cfg_obj_t *maps[4]; - const cfg_obj_t *options = NULL, *voptions = NULL; - const cfg_obj_t *nz = NULL; - const cfg_obj_t *obj = NULL; - int i = 0; - uint64_t mapsize = 0ULL; - - REQUIRE(config != NULL); - - if (vconfig != NULL) - voptions = cfg_tuple_get(vconfig, "options"); - if (voptions != NULL) - maps[i++] = voptions; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "allow-new-zones", &nz); - if (result == ISC_R_SUCCESS) - allow = cfg_obj_asboolean(nz); - -#ifdef HAVE_LMDB - result = ns_config_get(maps, "lmdb-mapsize", &obj); - if (result == ISC_R_SUCCESS && obj != NULL) { - mapsize = cfg_obj_asuint64(obj); - if (mapsize < (1ULL << 20)) { /* 1 megabyte */ - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'lmdb-mapsize " - "%" PRId64 "' " - "is too small", - mapsize); - return (ISC_R_FAILURE); - } else if (mapsize > (1ULL << 40)) { /* 1 terabyte */ - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'lmdb-mapsize " - "%" PRId64 "' " - "is too large", - mapsize); - return (ISC_R_FAILURE); - } - } -#else - UNUSED(obj); -#endif /* HAVE_LMDB */ - - /* - * A non-empty catalog-zones statement implies allow-new-zones - */ - if (!allow) { - const cfg_obj_t *cz = NULL; - result = ns_config_get(maps, "catalog-zones", &cz); - if (result == ISC_R_SUCCESS) { - const cfg_listelt_t *e = - cfg_list_first(cfg_tuple_get(cz, "zone list")); - if (e != NULL) - allow = true; - } - } - - if (!allow) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - if (num_zones != NULL) - *num_zones = 0; - return (ISC_R_SUCCESS); - } - - nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg)); - if (nzcfg == NULL) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - return (ISC_R_NOMEMORY); - } - - /* - * We attach the parser that was used for config as well - * as the one that will be used for added zones, to avoid - * a shutdown race later. - */ - memset(nzcfg, 0, sizeof(*nzcfg)); - cfg_parser_attach(conf_parser, &nzcfg->conf_parser); - cfg_parser_attach(ns_g_addparser, &nzcfg->add_parser); - isc_mem_attach(view->mctx, &nzcfg->mctx); - cfg_aclconfctx_attach(actx, &nzcfg->actx); - - result = dns_view_setnewzones(view, allow, nzcfg, - newzone_cfgctx_destroy, mapsize); - if (result != ISC_R_SUCCESS) { - dns_view_setnewzones(view, false, NULL, NULL, 0ULL); - return (result); - } - - cfg_obj_attach(config, &nzcfg->config); - if (vconfig != NULL) - cfg_obj_attach(vconfig, &nzcfg->vconfig); - - result = count_newzones(view, nzcfg, num_zones); - return (result); -} - -static void -configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig, - dns_view_t *view) -{ - const char *zname; - dns_fixedname_t fixorigin; - dns_name_t *origin; - isc_result_t result2; - dns_view_t *pview = NULL; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - origin = dns_fixedname_initname(&fixorigin); - - result2 = dns_name_fromstring(origin, zname, 0, NULL); - if (result2 != ISC_R_SUCCESS) { - return; - } - - result2 = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result2 != ISC_R_SUCCESS) { - return; - } - - result2 = dns_view_findzone(pview, origin, &zone); - if (result2 != ISC_R_SUCCESS) { - dns_view_detach(&pview); - return; - } - - dns_zone_getraw(zone, &raw); - - if (result == ISC_R_SUCCESS) { - dns_zone_setviewcommit(zone); - if (raw != NULL) - dns_zone_setviewcommit(raw); - } else { - dns_zone_setviewrevert(zone); - if (raw != NULL) - dns_zone_setviewrevert(raw); - } - - if (raw != NULL) { - dns_zone_detach(&raw); - } - - dns_zone_detach(&zone); - dns_view_detach(&pview); -} - -#ifndef HAVE_LMDB - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx) -{ - isc_result_t result; - ns_cfgctx_t *nzctx; - const cfg_obj_t *zonelist; - const cfg_listelt_t *element; - - nzctx = view->new_zone_config; - if (nzctx == NULL || nzctx->nzf_config == NULL) { - return (ISC_R_SUCCESS); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "loading additional zones for view '%s'", - view->name); - - zonelist = NULL; - cfg_map_get(nzctx->nzf_config, "zone", &zonelist); - - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, - view, &ns_g_server->viewlist, actx, - true, false, false)); - } - - result = ISC_R_SUCCESS; - - cleanup: - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - configure_zone_setviewcommit(result, zconfig, view); - } - - return (result); -} - -#else /* HAVE_LMDB */ - -static isc_result_t -data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, - isc_buffer_t **text, cfg_obj_t **zoneconfig) -{ - isc_result_t result; - const char *zone_name; - size_t zone_name_len; - const char *zone_config; - size_t zone_config_len; - cfg_obj_t *zoneconf = NULL; - char bufname[DNS_NAME_FORMATSIZE]; - - REQUIRE(view != NULL); - REQUIRE(key != NULL); - REQUIRE(data != NULL); - REQUIRE(text != NULL); - REQUIRE(zoneconfig != NULL && *zoneconfig == NULL); - - if (*text == NULL) { - result = isc_buffer_allocate(view->mctx, text, 256); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else { - isc_buffer_clear(*text); - } - - zone_name = (const char *) key->mv_data; - zone_name_len = key->mv_size; - INSIST(zone_name != NULL && zone_name_len > 0); - - zone_config = (const char *) data->mv_data; - zone_config_len = data->mv_size; - INSIST(zone_config != NULL && zone_config_len > 0); - - /* zone zonename { config; }; */ - result = isc_buffer_reserve(text, 6 + zone_name_len + 2 + - zone_config_len + 2); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - CHECK(putstr(text, "zone \"")); - CHECK(putmem(text, (const void *) zone_name, zone_name_len)); - CHECK(putstr(text, "\" ")); - CHECK(putmem(text, (const void *) zone_config, zone_config_len)); - CHECK(putstr(text, ";\n")); - - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_buffer3(ns_g_addparser, *text, bufname, 0, - &cfg_type_addzoneconf, &zoneconf); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "parsing config for zone '%.*s' in " - "NZD database '%s' failed", - (int) zone_name_len, zone_name, - view->new_zone_db); - goto cleanup; - } - - *zoneconfig = zoneconf; - zoneconf = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (zoneconf != NULL) { - cfg_obj_destroy(ns_g_addparser, &zoneconf); - } - - return (result); -} - -/*% - * Prototype for a callback which can be used with for_all_newzone_cfgs(). - */ -typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj_t *zconfig, - cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx); - -/*% - * For each zone found in a NZD opened by the caller, create an object - * representing its configuration and invoke "callback" with the created - * object, "config", "vconfig", "mctx", "view" and "actx" as arguments (all - * these are non-global variables required to invoke configure_zone()). - * Immediately interrupt processing if an error is encountered while - * transforming NZD data into a zone configuration object or if "callback" - * returns an error. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx, MDB_txn *txn, MDB_dbi dbi) -{ - const cfg_obj_t *zconfig, *zlist; - isc_result_t result = ISC_R_SUCCESS; - cfg_obj_t *zconfigobj = NULL; - isc_buffer_t *text = NULL; - MDB_cursor *cursor = NULL; - MDB_val data, key; - int status; - - status = mdb_cursor_open(txn, dbi, &cursor); - if (status != MDB_SUCCESS) { - return (ISC_R_FAILURE); - } - - for (status = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); - status == MDB_SUCCESS; - status = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) - { - /* - * Create a configuration object from data fetched from NZD. - */ - result = data_to_cfg(view, &key, &data, &text, &zconfigobj); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Extract zone configuration from configuration object. - */ - zlist = NULL; - result = cfg_map_get(zconfigobj, "zone", &zlist); - if (result != ISC_R_SUCCESS) { - break; - } else if (!cfg_obj_islist(zlist)) { - result = ISC_R_FAILURE; - break; - } - zconfig = cfg_listelt_value(cfg_list_first(zlist)); - - /* - * Invoke callback. - */ - result = callback(zconfig, config, vconfig, mctx, view, actx); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Destroy the configuration object created in this iteration. - */ - cfg_obj_destroy(ns_g_addparser, &zconfigobj); - } - - if (text != NULL) { - isc_buffer_free(&text); - } - if (zconfigobj != NULL) { - cfg_obj_destroy(ns_g_addparser, &zconfigobj); - } - mdb_cursor_close(cursor); - - return (result); -} - -/*% - * Attempt to configure a zone found in NZD and return the result. - */ -static isc_result_t -configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx) -{ - return (configure_zone(config, zconfig, vconfig, mctx, view, - &ns_g_server->viewlist, actx, true, - false, false)); -} - -/*% - * Revert new view assignment for a zone found in NZD. - */ -static isc_result_t -configure_newzone_revert(const cfg_obj_t *zconfig, cfg_obj_t *config, - cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *actx) -{ - UNUSED(config); - UNUSED(vconfig); - UNUSED(mctx); - UNUSED(actx); - - configure_zone_setviewcommit(ISC_R_FAILURE, zconfig, view); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, cfg_aclconfctx_t *actx) -{ - isc_result_t result; - MDB_txn *txn = NULL; - MDB_dbi dbi; - - if (view->new_zone_config == NULL) { - return (ISC_R_SUCCESS); - } - - LOCK(&view->new_zone_lock); - - result = nzd_open(view, MDB_RDONLY, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - UNLOCK(&view->new_zone_lock); - return (ISC_R_SUCCESS); - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD configs from '%s' " - "for view '%s'", - view->new_zone_db, view->name); - - result = for_all_newzone_cfgs(configure_newzone, config, vconfig, mctx, - view, actx, txn, dbi); - if (result != ISC_R_SUCCESS) { - /* - * An error was encountered while attempting to configure zones - * found in NZD. As this error may have been caused by a - * configure_zone() failure, try restoring a sane configuration - * by reattaching all zones found in NZD to the old view. If - * this also fails, too bad, there is nothing more we can do in - * terms of trying to make things right. - */ - (void) for_all_newzone_cfgs(configure_newzone_revert, config, - vconfig, mctx, view, actx, txn, - dbi); - } - - (void) nzd_close(&txn, false); - - UNLOCK(&view->new_zone_lock); - - return (result); -} - -static isc_result_t -get_newzone_config(dns_view_t *view, const char *zonename, - cfg_obj_t **zoneconfig) -{ - isc_result_t result; - int status; - cfg_obj_t *zoneconf = NULL; - isc_buffer_t *text = NULL; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_val key, data; - char zname[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - - INSIST(zoneconfig != NULL && *zoneconfig == NULL); - - LOCK(&view->new_zone_lock); - - CHECK(nzd_open(view, MDB_RDONLY, &txn, &dbi)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading NZD config from '%s' " - "for zone '%s'", - view->new_zone_db, zonename); - - /* Normalize zone name */ - isc_buffer_constinit(&b, zonename, strlen(zonename)); - isc_buffer_add(&b, strlen(zonename)); - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - DNS_NAME_DOWNCASE, NULL)); - dns_name_format(name, zname, sizeof(zname)); - - key.mv_data = zname; - key.mv_size = strlen(zname); - - status = mdb_get(txn, dbi, &key, &data); - if (status != MDB_SUCCESS) { - CHECK(ISC_R_FAILURE); - } - - CHECK(data_to_cfg(view, &key, &data, &text, &zoneconf)); - - *zoneconfig = zoneconf; - zoneconf = NULL; - result = ISC_R_SUCCESS; - - cleanup: - (void) nzd_close(&txn, false); - - UNLOCK(&view->new_zone_lock); - - if (zoneconf != NULL) { - cfg_obj_destroy(ns_g_addparser, &zoneconf); - } - if (text != NULL) { - isc_buffer_free(&text); - } - - return (result); -} - -#endif /* HAVE_LMDB */ - -static int -count_zones(const cfg_obj_t *conf) { - const cfg_obj_t *zonelist = NULL; - const cfg_listelt_t *element; - int n = 0; - - REQUIRE(conf != NULL); - - cfg_map_get(conf, "zone", &zonelist); - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - n++; - - return (n); -} - -static isc_result_t -check_lockfile(ns_server_t *server, const cfg_obj_t *config, - bool first_time) -{ - isc_result_t result; - const char *filename = NULL; - const cfg_obj_t *maps[3]; - const cfg_obj_t *options; - const cfg_obj_t *obj; - int i; - - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - obj = NULL; - (void) ns_config_get(maps, "lock-file", &obj); - - if (!first_time) { - if (obj != NULL && !cfg_obj_isstring(obj) && - server->lockfile != NULL && - strcmp(cfg_obj_asstring(obj), server->lockfile) != 0) - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "changing 'lock-file' " - "has no effect until the " - "server is restarted"); - - return (ISC_R_SUCCESS); - } - - if (obj != NULL) { - if (cfg_obj_isvoid(obj)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "skipping lock-file check "); - return (ISC_R_SUCCESS); - } else if (ns_g_forcelock) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "'lock-file' has no effect " - "because the server was run with -X"); - server->lockfile = isc_mem_strdup(server->mctx, - ns_g_defaultlockfile); - } else { - filename = cfg_obj_asstring(obj); - server->lockfile = isc_mem_strdup(server->mctx, - filename); - } - - if (server->lockfile == NULL) - return (ISC_R_NOMEMORY); - } - - if (ns_g_forcelock && ns_g_defaultlockfile != NULL) { - INSIST(server->lockfile == NULL); - server->lockfile = isc_mem_strdup(server->mctx, - ns_g_defaultlockfile); - } - - if (server->lockfile == NULL) - return (ISC_R_SUCCESS); - - if (ns_os_issingleton(server->lockfile)) - return (ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not lock %s; another named " - "process may be running", server->lockfile); - return (ISC_R_FAILURE); -} - -static isc_result_t -load_configuration(const char *filename, ns_server_t *server, - bool first_time) -{ - cfg_obj_t *config = NULL, *bindkeys = NULL; - cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *builtin_views; - const cfg_obj_t *maps[3]; - const cfg_obj_t *obj; - const cfg_obj_t *options; - const cfg_obj_t *usev4ports, *avoidv4ports, *usev6ports, *avoidv6ports; - const cfg_obj_t *views; - dns_view_t *view = NULL; - dns_view_t *view_next; - dns_viewlist_t tmpviewlist; - dns_viewlist_t viewlist, builtin_viewlist; - in_port_t listen_port, udpport_low, udpport_high; - int i; - int num_zones = 0; - bool exclusive = false; - isc_interval_t interval; - isc_logconfig_t *logc = NULL; - isc_portset_t *v4portset = NULL; - isc_portset_t *v6portset = NULL; - isc_resourcevalue_t nfiles; - isc_result_t result, tresult; - uint32_t heartbeat_interval; - uint32_t interface_interval; - uint32_t reserved; - uint32_t udpsize; - uint32_t transfer_message_size; - ns_cache_t *nsc; - ns_cachelist_t cachelist, tmpcachelist; - ns_altsecret_t *altsecret; - ns_altsecretlist_t altsecrets, tmpaltsecrets; - unsigned int maxsocks; - uint32_t softquota = 0; - - ISC_LIST_INIT(viewlist); - ISC_LIST_INIT(builtin_viewlist); - ISC_LIST_INIT(cachelist); - ISC_LIST_INIT(altsecrets); - - /* Create the ACL configuration context */ - if (ns_g_aclconfctx != NULL) { - cfg_aclconfctx_detach(&ns_g_aclconfctx); - } - CHECK(cfg_aclconfctx_create(ns_g_mctx, &ns_g_aclconfctx)); - - /* - * Shut down all dyndb instances. - */ - dns_dyndb_cleanup(false); - - /* - * Parse the global default pseudo-config file. - */ - if (first_time) { - result = ns_config_parsedefaults(ns_g_parser, &ns_g_config); - if (result != ISC_R_SUCCESS) { - ns_main_earlyfatal("unable to load " - "internal defaults: %s", - isc_result_totext(result)); - } - RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", - &ns_g_defaults) == ISC_R_SUCCESS); - } - - /* - * Parse the configuration file using the new config code. - */ - config = NULL; - - /* - * Unless this is lwresd with the -C option, parse the config file. - */ - if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - filename); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser)); - cfg_parser_setcallback(conf_parser, directory_callback, NULL); - result = cfg_parse_file(conf_parser, filename, - &cfg_type_namedconf, &config); - } - - /* - * If this is lwresd with the -C option, or lwresd with no -C or -c - * option where the above parsing failed, parse resolv.conf. - */ - if (ns_g_lwresdonly && - (lwresd_g_useresolvconf || - (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) - { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - lwresd_g_resolvconffile); - if (conf_parser != NULL) { - cfg_parser_destroy(&conf_parser); - } - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser)); - result = ns_lwresd_parseeresolvconf(ns_g_mctx, conf_parser, - &config); - } - CHECK(result); - - /* - * Check the validity of the configuration. - */ - CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx)); - - /* - * Fill in the maps array, used for resolving defaults. - */ - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) { - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - /* - * If bind.keys exists, load it. If "dnssec-validation auto" - * is turned on, the root key found there will be used as a - * default trust anchor. - */ - obj = NULL; - result = ns_config_get(maps, "bindkeys-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->bindkeysfile, - cfg_obj_asstring(obj)), "strdup"); - INSIST(server->bindkeysfile != NULL); - - if (access(server->bindkeysfile, R_OK) == 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reading built-in trust anchors " - "from file '%s'", server->bindkeysfile); - - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, - &bindkeys_parser)); - - result = cfg_parse_file(bindkeys_parser, server->bindkeysfile, - &cfg_type_bindkeys, &bindkeys); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "unable to parse '%s' error '%s'; using " - "built-in keys instead", - server->bindkeysfile, - isc_result_totext(result)); - } - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "unable to open '%s'; using built-in keys " - "instead", server->bindkeysfile); - } - - /* Ensure exclusive access to configuration data. */ - if (!exclusive) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - } - - /* - * Set process limits, which (usually) needs to be done as root. - */ - set_limits(maps); - - /* - * Check the process lockfile. - */ - CHECK(check_lockfile(server, config, first_time)); - - /* - * Check if max number of open sockets that the system allows is - * sufficiently large. Failing this condition is not necessarily fatal, - * but may cause subsequent runtime failures for a busy recursive - * server. - */ - result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &maxsocks); - if (result != ISC_R_SUCCESS) { - maxsocks = 0; - } - result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles); - if (result == ISC_R_SUCCESS && (isc_resourcevalue_t)maxsocks > nfiles) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "max open files (%" PRIu64 ")" - " is smaller than max sockets (%u)", - nfiles, maxsocks); - } - - /* - * Set the number of socket reserved for TCP, stdio etc. - */ - obj = NULL; - result = ns_config_get(maps, "reserved-sockets", &obj); - INSIST(result == ISC_R_SUCCESS); - reserved = cfg_obj_asuint32(obj); - if (maxsocks != 0) { - if (maxsocks < 128U) { /* Prevent underflow. */ - reserved = 0; - } else if (reserved > maxsocks - 128U) { /* Minimum UDP space. */ - reserved = maxsocks - 128; - } - } - /* Minimum TCP/stdio space. */ - if (reserved < 128U) { - reserved = 128; - } - if (reserved + 128U > maxsocks && maxsocks != 0) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "less than 128 UDP sockets available after " - "applying 'reserved-sockets' and 'maxsockets'"); - } - isc__socketmgr_setreserved(ns_g_socketmgr, reserved); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - /* - * Release any previously opened GeoIP2 databases. - */ - ns_geoip_shutdown(); - /* - * Initialize GeoIP databases from the configured location. - * This should happen before configuring any ACLs, so that we - * know what databases are available and can reject any GeoIP - * ACLs that can't work. - */ - obj = NULL; - result = ns_config_get(maps, "geoip-directory", &obj); - if (result == ISC_R_SUCCESS && cfg_obj_isstring(obj)) { - char *dir; - DE_CONST(cfg_obj_asstring(obj), dir); - ns_geoip_load(dir); - } - ns_g_aclconfctx->geoip = ns_g_geoip; - - obj = NULL; - result = ns_config_get(maps, "geoip-use-ecs", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_server->aclenv.geoip_use_ecs = cfg_obj_asboolean(obj); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - /* - * Configure various server options. - */ - configure_server_quota(maps, "transfers-out", &server->xfroutquota); - configure_server_quota(maps, "tcp-clients", &server->tcpquota); - configure_server_quota(maps, "recursive-clients", - &server->recursionquota); - - if (server->recursionquota.max > 1000) { - int margin = ISC_MAX(100, ns_g_cpus + 1); - if (margin > server->recursionquota.max - 100) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "'recursive-clients %d' too low when " - "running with %d worker threads", - server->recursionquota.max, ns_g_cpus); - CHECK(ISC_R_RANGE); - } - softquota = server->recursionquota.max - margin; - } else { - softquota = (server->recursionquota.max * 90) / 100; - } - - isc_quota_soft(&server->recursionquota, softquota); - - /* - * Set "blackhole". Only legal at options level; there is - * no default. - */ - CHECK(configure_view_acl(NULL, config, NULL, "blackhole", NULL, - ns_g_aclconfctx, ns_g_mctx, - &server->blackholeacl)); - if (server->blackholeacl != NULL) { - dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, - server->blackholeacl); - } - - /* - * Set "keep-response-order". Only legal at options or - * global defaults level. - */ - CHECK(configure_view_acl(NULL, config, ns_g_config, - "keep-response-order", NULL, - ns_g_aclconfctx, ns_g_mctx, - &server->keepresporder)); - - obj = NULL; - result = ns_config_get(maps, "match-mapped-addresses", &obj); - INSIST(result == ISC_R_SUCCESS); - server->aclenv.match_mapped = cfg_obj_asboolean(obj); - - CHECKM(ns_statschannels_configure(ns_g_server, config, ns_g_aclconfctx), - "configuring statistics server(s)"); - - /* - * Configure sets of UDP query source ports. - */ - CHECKM(isc_portset_create(ns_g_mctx, &v4portset), - "creating UDP port set"); - CHECKM(isc_portset_create(ns_g_mctx, &v6portset), - "creating UDP port set"); - - usev4ports = NULL; - usev6ports = NULL; - avoidv4ports = NULL; - avoidv6ports = NULL; - - (void)ns_config_get(maps, "use-v4-udp-ports", &usev4ports); - if (usev4ports != NULL) { - portset_fromconf(v4portset, usev4ports, true); - } else { - CHECKM(isc_net_getudpportrange(AF_INET, &udpport_low, - &udpport_high), - "get the default UDP/IPv4 port range"); - if (udpport_low == udpport_high) { - isc_portset_add(v4portset, udpport_low); - } else { - isc_portset_addrange(v4portset, udpport_low, - udpport_high); - } - if (!ns_g_disable4) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using default UDP/IPv4 port range: " - "[%d, %d]", udpport_low, udpport_high); - } - } - (void)ns_config_get(maps, "avoid-v4-udp-ports", &avoidv4ports); - if (avoidv4ports != NULL) { - portset_fromconf(v4portset, avoidv4ports, false); - } - - (void)ns_config_get(maps, "use-v6-udp-ports", &usev6ports); - if (usev6ports != NULL) { - portset_fromconf(v6portset, usev6ports, true); - } else { - CHECKM(isc_net_getudpportrange(AF_INET6, &udpport_low, - &udpport_high), - "get the default UDP/IPv6 port range"); - if (udpport_low == udpport_high) { - isc_portset_add(v6portset, udpport_low); - } else { - isc_portset_addrange(v6portset, udpport_low, - udpport_high); - } - if (!ns_g_disable6) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "using default UDP/IPv6 port range: " - "[%d, %d]", udpport_low, udpport_high); - } - } - (void)ns_config_get(maps, "avoid-v6-udp-ports", &avoidv6ports); - if (avoidv6ports != NULL) { - portset_fromconf(v6portset, avoidv6ports, false); - } - - dns_dispatchmgr_setavailports(ns_g_dispatchmgr, v4portset, v6portset); - - /* - * Set the EDNS UDP size when we don't match a view. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) { - udpsize = 512; - } - if (udpsize > 4096) { - udpsize = 4096; - } - ns_g_udpsize = (uint16_t)udpsize; - - /* Set the transfer message size for TCP */ - obj = NULL; - result = ns_config_get(maps, "transfer-message-size", &obj); - INSIST(result == ISC_R_SUCCESS); - transfer_message_size = cfg_obj_asuint32(obj); - if (transfer_message_size < 512) { - transfer_message_size = 512; - } else if (transfer_message_size > 65535) { - transfer_message_size = 65535; - } - server->transfer_tcp_message_size = (uint16_t) transfer_message_size; - - /* - * Configure the zone manager. - */ - obj = NULL; - result = ns_config_get(maps, "transfers-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfers-per-ns", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setnotifyrate(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "startup-notify-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setstartupnotifyrate(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "serial-query-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); - - /* - * Determine which port to use for listening for incoming connections. - */ - if (ns_g_port != 0) { - listen_port = ns_g_port; - } else { - CHECKM(ns_config_getport(config, &listen_port), "port"); - } - - /* - * Determining the default DSCP code point. - */ - CHECKM(ns_config_getdscp(config, &ns_g_dscp), "dscp"); - - /* - * Find the listen queue depth. - */ - obj = NULL; - result = ns_config_get(maps, "tcp-listen-queue", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_listen = cfg_obj_asuint32(obj); - if ((ns_g_listen > 0) && (ns_g_listen < 10)) { - ns_g_listen = 10; - } - - /* - * Configure the interface manager according to the "listen-on" - * statement. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - clistenon = NULL; - /* - * Even though listen-on is present in the default - * configuration, we can't use it here, since it isn't - * used if we're in lwresd mode. This way is easier. - */ - if (options != NULL) { - (void)cfg_map_get(options, "listen-on", &clistenon); - } - if (clistenon != NULL) { - /* check return code? */ - (void)ns_listenlist_fromconfig(clistenon, config, - ns_g_aclconfctx, - ns_g_mctx, AF_INET, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - -1, true, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon4(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - /* - * Ditto for IPv6. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - if (options != NULL) { - (void)cfg_map_get(options, "listen-on-v6", &clistenon); - } - if (clistenon != NULL) { - /* check return code? */ - (void)ns_listenlist_fromconfig(clistenon, config, - ns_g_aclconfctx, - ns_g_mctx, AF_INET6, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - -1, true, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon6(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - - /* - * Rescan the interface list to pick up changes in the - * listen-on option. It's important that we do this before we try - * to configure the query source, since the dispatcher we use might - * be shared with an interface. - */ - result = scan_interfaces(server, true); - - /* - * Check that named is able to TCP listen on at least one - * interface. Otherwise, another named process could be running - * and we should fail. - */ - if (first_time && (result == ISC_R_ADDRINUSE)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to listen on any configured interfaces"); - result = ISC_R_FAILURE; - goto cleanup; - } - - /* - * Arrange for further interface scanning to occur periodically - * as specified by the "interface-interval" option. - */ - obj = NULL; - result = ns_config_get(maps, "interface-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - interface_interval = cfg_obj_asuint32(obj) * 60; - if (interface_interval == 0) { - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_inactive, - NULL, NULL, true)); - } else if (server->interface_interval != interface_interval) { - isc_interval_set(&interval, interface_interval, 0); - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_ticker, - NULL, &interval, false)); - } - server->interface_interval = interface_interval; - - /* - * Enable automatic interface scans. - */ - obj = NULL; - result = ns_config_get(maps, "automatic-interface-scan", &obj); - INSIST(result == ISC_R_SUCCESS); - server->interface_auto = cfg_obj_asboolean(obj); - - /* - * Configure the dialup heartbeat timer. - */ - obj = NULL; - result = ns_config_get(maps, "heartbeat-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - heartbeat_interval = cfg_obj_asuint32(obj) * 60; - if (heartbeat_interval == 0) { - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_inactive, - NULL, NULL, true)); - } else if (server->heartbeat_interval != heartbeat_interval) { - isc_interval_set(&interval, heartbeat_interval, 0); - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_ticker, - NULL, &interval, false)); - } - server->heartbeat_interval = heartbeat_interval; - - isc_interval_set(&interval, 1200, 0); - CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL, - &interval, false)); - - isc_interval_set(&interval, ns_g_tat_interval, 0); - CHECK(isc_timer_reset(server->tat_timer, isc_timertype_ticker, NULL, - &interval, false)); - - /* - * Write the PID file. - */ - obj = NULL; - if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) { - if (cfg_obj_isvoid(obj)) { - ns_os_writepidfile(NULL, first_time); - } else { - ns_os_writepidfile(cfg_obj_asstring(obj), first_time); - } - } else if (ns_g_lwresdonly) { - ns_os_writepidfile(lwresd_g_defaultpidfile, first_time); - } else { - ns_os_writepidfile(ns_g_defaultpidfile, first_time); - } - - /* - * Configure the server-wide session key. This must be done before - * configure views because zone configuration may need to know - * session-keyname. - * - * Failure of session key generation isn't fatal at this time; if it - * turns out that a session key is really needed but doesn't exist, - * we'll treat it as a fatal error then. - */ - (void)configure_session_key(maps, server, ns_g_mctx, first_time); - - views = NULL; - (void)cfg_map_get(config, "view", &views); - - /* - * Create the views and count all the configured zones in - * order to correctly size the zone manager's task table. - * (We only count zones for configured views; the built-in - * "bind" view can be ignored as it only adds a negligible - * number of zones.) - * - * If we're allowing new zones, we need to be able to find the - * new zone file and count those as well. So we setup the new - * zone configuration context, but otherwise view configuration - * waits until after the zone manager's task list has been sized. - */ - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - const cfg_obj_t *voptions = cfg_tuple_get(vconfig, "options"); - int nzf_num_zones; - - view = NULL; - - CHECK(create_view(vconfig, &viewlist, &view)); - INSIST(view != NULL); - - num_zones += count_zones(voptions); - - CHECK(setup_newzones(view, config, vconfig, conf_parser, - ns_g_aclconfctx, &nzf_num_zones)); - num_zones += nzf_num_zones; - - dns_view_detach(&view); - } - - /* - * If there were no explicit views then we do the default - * view here. - */ - if (views == NULL) { - int nzf_num_zones; - - CHECK(create_view(NULL, &viewlist, &view)); - INSIST(view != NULL); - - num_zones = count_zones(config); - - CHECK(setup_newzones(view, config, NULL, conf_parser, - ns_g_aclconfctx, &nzf_num_zones)); - num_zones += nzf_num_zones; - - dns_view_detach(&view); - } - - /* - * Zones have been counted; set the zone manager task pool size. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "sizing zone task pool based on %d zones", num_zones); - CHECK(dns_zonemgr_setsize(ns_g_server->zonemgr, num_zones)); - - /* - * Configure and freeze all explicit views. Explicit - * views that have zones were already created at parsing - * time, but views with no zones must be created here. - */ - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - - view = NULL; - CHECK(find_view(vconfig, &viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, vconfig, - &cachelist, bindkeys, ns_g_mctx, - ns_g_aclconfctx, true)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Make sure we have a default view if and only if there - * were no explicit views. - */ - if (views == NULL) { - view = NULL; - CHECK(find_view(NULL, &viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, NULL, - &cachelist, bindkeys, - ns_g_mctx, ns_g_aclconfctx, true)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Create (or recreate) the built-in views. - */ - builtin_views = NULL; - RUNTIME_CHECK(cfg_map_get(ns_g_config, "view", - &builtin_views) == ISC_R_SUCCESS); - for (element = cfg_list_first(builtin_views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - - CHECK(create_view(vconfig, &builtin_viewlist, &view)); - CHECK(configure_view(view, &viewlist, config, vconfig, - &cachelist, bindkeys, - ns_g_mctx, ns_g_aclconfctx, false)); - dns_view_freeze(view); - dns_view_detach(&view); - view = NULL; - } - - /* Now combine the two viewlists into one */ - ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link); - - /* - * Commit any dns_zone_setview() calls on all zones in the new - * view. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_view_setviewcommit(view); - } - - /* Swap our new view list with the production one. */ - tmpviewlist = server->viewlist; - server->viewlist = viewlist; - viewlist = tmpviewlist; - - /* Make the view list available to each of the views */ - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - view->viewlist = &server->viewlist; - view = ISC_LIST_NEXT(view, link); - } - - /* Swap our new cache list with the production one. */ - tmpcachelist = server->cachelist; - server->cachelist = cachelist; - cachelist = tmpcachelist; - - /* Load the TKEY information from the configuration. */ - if (options != NULL) { - dns_tkeyctx_t *t = NULL; - CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy, - &t), - "configuring TKEY"); - if (server->tkeyctx != NULL) { - dns_tkeyctx_destroy(&server->tkeyctx); - } - server->tkeyctx = t; - } - - /* - * Bind the control port(s). - */ - CHECKM(ns_controls_configure(ns_g_server->controls, config, - ns_g_aclconfctx), - "binding control channel(s)"); - - /* - * Bind the lwresd port(s). - */ - CHECKM(ns_lwresd_configure(ns_g_mctx, config), - "binding lightweight resolver ports"); - - /* - * Open the source of entropy. - */ - if (first_time) { - const char *randomdev = NULL; - int level = ISC_LOG_ERROR; - obj = NULL; - result = ns_config_get(maps, "random-device", &obj); - if (result == ISC_R_SUCCESS) { - if (!cfg_obj_isvoid(obj)) { - level = ISC_LOG_INFO; - randomdev = cfg_obj_asstring(obj); - } - } - if (randomdev == NULL) { -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_entropy_usehook(ns_g_entropy, true); -#else - if ((obj != NULL) && !cfg_obj_isvoid(obj)) - level = ISC_LOG_INFO; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, level, - "no source of entropy found"); - if ((obj == NULL) || cfg_obj_isvoid(obj)) { - CHECK(ISC_R_FAILURE); - } -#endif - } else { - result = isc_entropy_createfilesource(ns_g_entropy, - randomdev); -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - level = ISC_LOG_INFO; - } -#endif - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - level, - "could not open " - "entropy source %s: %s", - randomdev, - isc_result_totext(result)); - } -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "using pre-chroot entropy source " - "%s", - PATH_RANDOMDEV); - isc_entropy_detach(&ns_g_entropy); - isc_entropy_attach(ns_g_fallbackentropy, - &ns_g_entropy); - } - isc_entropy_detach(&ns_g_fallbackentropy); - } -#endif - } - -#ifdef HAVE_LMDB - /* - * If we're using LMDB, we may have created newzones - * databases as root, making it impossible to reopen - * them later after switching to a new userid. We - * close them now, and reopen after relinquishing - * privileges them. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; view = ISC_LIST_NEXT(view, link)) - { - nzd_env_close(view); - } -#endif /* HAVE_LMDB */ - - /* - * Relinquish root privileges. - */ - ns_os_changeuser(); - } - - /* - * Check that the working directory is writable. - */ - if (!isc_file_isdirwritable(".")) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "the working directory is not writable"); - } - -#ifdef HAVE_LMDB - /* - * Reopen NZD databases. - */ - if (first_time) { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - nzd_env_reopen(view); - } - } -#endif /* HAVE_LMDB */ - - /* - * Configure the logging system. - * - * Do this after changing UID to make sure that any log - * files specified in named.conf get created by the - * unprivileged user, not root. - */ - if (ns_g_logstderr) { - const cfg_obj_t *logobj = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "not using config file logging " - "statement for logging due to " - "-g option"); - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - result = ns_log_configure(NULL, logobj); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "checking logging configuration " - "failed: %s", - isc_result_totext(result)); - goto cleanup; - } - } - } else { - const cfg_obj_t *logobj = NULL; - - CHECKM(isc_logconfig_create(ns_g_lctx, &logc), - "creating new logging configuration"); - - logobj = NULL; - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - CHECKM(ns_log_configure(logc, logobj), - "configuring logging"); - } else { - CHECKM(ns_log_setdefaultchannels(logc), - "setting up default logging channels"); - CHECKM(ns_log_setunmatchedcategory(logc), - "setting up default 'category unmatched'"); - CHECKM(ns_log_setdefaultcategory(logc), - "setting up default 'category default'"); - } - - CHECKM(isc_logconfig_use(ns_g_lctx, logc), - "installing logging configuration"); - logc = NULL; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "now using logging configuration from " - "config file"); - } - - /* - * Set the default value of the query logging flag depending - * whether a "queries" category has been defined. This is - * a disgusting hack, but we need to do this for BIND 8 - * compatibility. - */ - if (first_time) { - const cfg_obj_t *logobj = NULL; - const cfg_obj_t *categories = NULL; - - obj = NULL; - if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) { - server->log_queries = cfg_obj_asboolean(obj); - } else { - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) - (void)cfg_map_get(logobj, "category", - &categories); - if (categories != NULL) { - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *catobj; - const char *str; - - obj = cfg_listelt_value(element); - catobj = cfg_tuple_get(obj, "name"); - str = cfg_obj_asstring(catobj); - if (strcasecmp(str, "queries") == 0) - server->log_queries = true; - } - } - } - } - - obj = NULL; - if (options != NULL && - cfg_map_get(options, "memstatistics", &obj) == ISC_R_SUCCESS) { - ns_g_memstatistics = cfg_obj_asboolean(obj); - } else { - ns_g_memstatistics = - ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0); - } - - obj = NULL; - if (ns_config_get(maps, "memstatistics-file", &obj) == ISC_R_SUCCESS) { - ns_main_setmemstats(cfg_obj_asstring(obj)); - } else if (ns_g_memstatistics) { - ns_main_setmemstats("named.memstats"); - } else { - ns_main_setmemstats(NULL); - } - - obj = NULL; - result = ns_config_get(maps, "statistics-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "dump-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "secroots-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->secrootsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "recursing-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "version", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->version, obj), "strdup"); - server->version_set = true; - } else { - server->version_set = false; - } - - obj = NULL; - result = ns_config_get(maps, "hostname", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->hostname, obj), "strdup"); - server->hostname_set = true; - } else { - server->hostname_set = false; - } - - obj = NULL; - result = ns_config_get(maps, "server-id", &obj); - server->server_usehostname = false; - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - /* The parser translates "hostname" to true */ - server->server_usehostname = cfg_obj_asboolean(obj); - result = setstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } else if (result == ISC_R_SUCCESS) { - /* Found a quoted string */ - CHECKM(setoptstring(server, &server->server_id, obj), "strdup"); - } else { - result = setstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - obj = NULL; - result = ns_config_get(maps, "flush-zones-on-shutdown", &obj); - if (result == ISC_R_SUCCESS) { - server->flushonshutdown = cfg_obj_asboolean(obj); - } else { - server->flushonshutdown = false; - } - - obj = NULL; - result = ns_config_get(maps, "answer-cookie", &obj); - INSIST(result == ISC_R_SUCCESS); - server->answercookie = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "cookie-algorithm", &obj); - INSIST(result == ISC_R_SUCCESS); - if (strcasecmp(cfg_obj_asstring(obj), "siphash24") == 0) { - server->cookiealg = ns_cookiealg_siphash24; - } else if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) { -#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES) - server->cookiealg = ns_cookiealg_aes; -#else - INSIST(0); - ISC_UNREACHABLE(); -#endif - } else if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0) { - server->cookiealg = ns_cookiealg_sha1; - } else if (strcasecmp(cfg_obj_asstring(obj), "sha256") == 0) { - server->cookiealg = ns_cookiealg_sha256; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - obj = NULL; - result = ns_config_get(maps, "cookie-secret", &obj); - if (result == ISC_R_SUCCESS) { - const char *str; - bool first = true; - isc_buffer_t b; - unsigned int usedlength; - - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - - if (first) { - memset(server->secret, 0, - sizeof(server->secret)); - isc_buffer_init(&b, server->secret, - sizeof(server->secret)); - result = isc_hex_decodestring(str, &b); - if (result != ISC_R_SUCCESS && - result != ISC_R_NOSPACE) - goto cleanup; - first = false; - } else { - altsecret = isc_mem_get(server->mctx, - sizeof(*altsecret)); - if (altsecret == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_buffer_init(&b, altsecret->secret, - sizeof(altsecret->secret)); - result = isc_hex_decodestring(str, &b); - if (result != ISC_R_SUCCESS && - result != ISC_R_NOSPACE) { - isc_mem_put(server->mctx, altsecret, - sizeof(*altsecret)); - goto cleanup; - } - ISC_LIST_INITANDAPPEND(altsecrets, - altsecret, link); - } - - usedlength = isc_buffer_usedlength(&b); - switch (server->cookiealg) { - case ns_cookiealg_siphash24: - if (usedlength != ISC_SIPHASH24_KEY_LENGTH) { - CHECKM(ISC_R_RANGE, - "SipHash-2-4 cookie-secret must be 128 bits"); - } - break; - case ns_cookiealg_aes: - if (usedlength != ISC_AES128_KEYLENGTH) { - CHECKM(ISC_R_RANGE, - "AES cookie-secret must be 128 bits"); - } - break; - case ns_cookiealg_sha1: - if (usedlength != ISC_SHA1_DIGESTLENGTH) { - CHECKM(ISC_R_RANGE, - "SHA1 cookie-secret must be " - "160 bits"); - } - break; - case ns_cookiealg_sha256: - if (usedlength != ISC_SHA256_DIGESTLENGTH) { - CHECKM(ISC_R_RANGE, - "SHA256 cookie-secret must be " - "256 bits"); - } - break; - } - } - } else { - result = isc_entropy_getdata(ns_g_entropy, - server->secret, - sizeof(server->secret), - NULL, - 0); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - - /* - * Swap altsecrets lists. - */ - tmpaltsecrets = server->altsecrets; - server->altsecrets = altsecrets; - altsecrets = tmpaltsecrets; - - (void) ns_server_loadnta(server); - - result = ISC_R_SUCCESS; - - cleanup: - if (logc != NULL) { - isc_logconfig_destroy(&logc); - } - - if (v4portset != NULL) { - isc_portset_destroy(ns_g_mctx, &v4portset); - } - - if (v6portset != NULL) { - isc_portset_destroy(ns_g_mctx, &v6portset); - } - - if (conf_parser != NULL) { - if (config != NULL) { - cfg_obj_destroy(conf_parser, &config); - } - cfg_parser_destroy(&conf_parser); - } - - if (bindkeys_parser != NULL) { - if (bindkeys != NULL) { - cfg_obj_destroy(bindkeys_parser, &bindkeys); - } - cfg_parser_destroy(&bindkeys_parser); - } - - if (view != NULL) { - dns_view_detach(&view); - } - - ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link); - - /* - * This cleans up either the old production view list - * or our temporary list depending on whether they - * were swapped above or not. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(viewlist, view, link); - if (result == ISC_R_SUCCESS && - strcmp(view->name, "_bind") != 0) - { - dns_view_setviewrevert(view); - (void)dns_zt_apply(view->zonetable, false, - removed, view); - } - dns_view_detach(&view); - } - - /* Same cleanup for cache list. */ - while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) { - ISC_LIST_UNLINK(cachelist, nsc, link); - dns_cache_detach(&nsc->cache); - isc_mem_put(server->mctx, nsc, sizeof(*nsc)); - } - - /* Same cleanup for altsecrets list. */ - while ((altsecret = ISC_LIST_HEAD(altsecrets)) != NULL) { - ISC_LIST_UNLINK(altsecrets, altsecret, link); - isc_mem_put(server->mctx, altsecret, sizeof(*altsecret)); - } - - /* - * Adjust the listening interfaces in accordance with the source - * addresses specified in views and zones. - */ - if (isc_net_probeipv6() == ISC_R_SUCCESS) { - adjust_interfaces(server, ns_g_mctx); - } - - /* - * Record the time of most recent configuration - */ - tresult = isc_time_now(&ns_g_configtime); - if (tresult != ISC_R_SUCCESS) { - ns_main_earlyfatal("isc_time_now() failed: %s", - isc_result_totext(result)); - } - - /* Relinquish exclusive access to configuration data. */ - if (exclusive) { - isc_task_endexclusive(server->task); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), "load_configuration: %s", - isc_result_totext(result)); - - return (result); -} - -static isc_result_t -view_loaded(void *arg) { - isc_result_t result; - ns_zoneload_t *zl = (ns_zoneload_t *) arg; - ns_server_t *server; - bool reconfig; - unsigned int refs; - - - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - * - * We use the zoneload reference counter to let us - * know when all views are finished. - */ - isc_refcount_decrement(&zl->refs, &refs); - if (refs != 0) - return (ISC_R_SUCCESS); - - server = zl->server; - reconfig = zl->reconfig; - - isc_refcount_destroy(&zl->refs); - isc_mem_put(server->mctx, zl, sizeof (*zl)); - - /* - * To maintain compatibility with log parsing tools that might - * be looking for this string after "rndc reconfig", we keep it - * as it is - */ - if (reconfig) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "any newly configured zones are now loaded"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, - "all zones loaded"); - } - - CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr), - "forcing zone maintenance"); - - ns_os_started(); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "running"); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_zones(ns_server_t *server, bool init, bool reconfig) { - isc_result_t result; - dns_view_t *view; - ns_zoneload_t *zl; - unsigned int refs = 0; - - zl = isc_mem_get(server->mctx, sizeof (*zl)); - if (zl == NULL) - return (ISC_R_NOMEMORY); - zl->server = server; - zl->reconfig = reconfig; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_refcount_init(&zl->refs, 1); - - /* - * Schedule zones to be loaded from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (view->managed_keys != NULL) { - result = dns_zone_load(view->managed_keys); - if (result != ISC_R_SUCCESS && - result != DNS_R_UPTODATE && - result != DNS_R_CONTINUE) - goto cleanup; - } - if (view->redirect != NULL) { - result = dns_zone_load(view->redirect); - if (result != ISC_R_SUCCESS && - result != DNS_R_UPTODATE && - result != DNS_R_CONTINUE) - goto cleanup; - } - - /* - * 'dns_view_asyncload' calls view_loaded if there are no - * zones. - */ - isc_refcount_increment(&zl->refs, NULL); - CHECK(dns_view_asyncload2(view, view_loaded, zl, reconfig)); - } - - cleanup: - isc_refcount_decrement(&zl->refs, &refs); - if (refs == 0) { - isc_refcount_destroy(&zl->refs); - isc_mem_put(server->mctx, zl, sizeof (*zl)); - } else if (init) { - /* - * Place the task manager into privileged mode. This - * ensures that after we leave task-exclusive mode, no - * other tasks will be able to run except for the ones - * that are loading zones. (This should only be done during - * the initial server setup; it isn't necessary during - * a reload.) - */ - isc_taskmgr_setmode(ns_g_taskmgr, isc_taskmgrmode_privileged); - } - - isc_task_endexclusive(server->task); - return (result); -} - -static void -run_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - - isc_event_free(&event); - - CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy, - &ns_g_dispatchmgr), - "creating dispatch manager"); - - dns_dispatchmgr_setstats(ns_g_dispatchmgr, server->resolverstats); - - CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, - ns_g_socketmgr, ns_g_dispatchmgr, - server->task, &server->interfacemgr), - "creating interface manager"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - interface_timer_tick, - server, &server->interface_timer), - "creating interface timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - heartbeat_timer_tick, - server, &server->heartbeat_timer), - "creating heartbeat timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, tat_timer_tick, - server, &server->tat_timer), - "creating trust anchor telemetry timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, pps_timer_tick, - server, &server->pps_timer), - "creating pps timer"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_parser), - "creating default configuration parser"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_addparser), - "creating additional configuration parser"); - - if (ns_g_lwresdonly) - CHECKFATAL(load_configuration(lwresd_g_conffile, server, - true), - "loading configuration"); - else - CHECKFATAL(load_configuration(ns_g_conffile, server, true), - "loading configuration"); - - isc_hash_init(); - - CHECKFATAL(load_zones(server, true, false), "loading zones"); -#ifdef ENABLE_AFL - ns_g_run_done = true; -#endif -} - -void -ns_server_flushonshutdown(ns_server_t *server, bool flush) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->flushonshutdown = flush; -} - -static void -shutdown_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_view_t *view, *view_next; - ns_server_t *server = (ns_server_t *)event->ev_arg; - bool flush = server->flushonshutdown; - ns_cache_t *nsc; - ns_altsecret_t *altsecret; - - UNUSED(task); - INSIST(task == server->task); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "shutting down%s", - flush ? ": flushing changes" : ""); - - ns_statschannels_shutdown(server); - ns_controls_shutdown(server->controls); - end_reserved_dispatches(server, true); - cleanup_session_key(server, server->mctx); - - if (ns_g_aclconfctx != NULL) - cfg_aclconfctx_detach(&ns_g_aclconfctx); - - cfg_obj_destroy(ns_g_parser, &ns_g_config); - cfg_parser_destroy(&ns_g_parser); - cfg_parser_destroy(&ns_g_addparser); - - (void) ns_server_saventa(server); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(server->viewlist, view, link); - if (flush) - dns_view_flushanddetach(&view); - else - dns_view_detach(&view); - } - - dns_dyndb_cleanup(true); - - while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) { - ISC_LIST_UNLINK(server->cachelist, nsc, link); - dns_cache_detach(&nsc->cache); - isc_mem_put(server->mctx, nsc, sizeof(*nsc)); - } - - while ((altsecret = ISC_LIST_HEAD(server->altsecrets)) != NULL) { - ISC_LIST_UNLINK(server->altsecrets, altsecret, link); - isc_mem_put(server->mctx, altsecret, sizeof(*altsecret)); - } - - isc_timer_detach(&server->interface_timer); - isc_timer_detach(&server->heartbeat_timer); - isc_timer_detach(&server->pps_timer); - isc_timer_detach(&server->tat_timer); - - ns_interfacemgr_shutdown(server->interfacemgr); - ns_interfacemgr_detach(&server->interfacemgr); - - dns_dispatchmgr_destroy(&ns_g_dispatchmgr); - - dns_zonemgr_shutdown(server->zonemgr); - - if (ns_g_sessionkey != NULL) { - dns_tsigkey_detach(&ns_g_sessionkey); - dns_name_free(&ns_g_sessionkeyname, server->mctx); - } - - if (server->keepresporder != NULL) - dns_acl_detach(&server->keepresporder); - - if (server->blackholeacl != NULL) - dns_acl_detach(&server->blackholeacl); - -#ifdef HAVE_DNSTAP - dns_dt_shutdown(); -#endif -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - ns_geoip_shutdown(); - dns_geoip_shutdown(); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - dns_db_detach(&server->in_roothints); - - isc_task_endexclusive(server->task); - - isc_task_detach(&server->task); - - isc_event_free(&event); -} - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { - isc_result_t result; - ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); - - if (server == NULL) - fatal(server, "allocating server object", ISC_R_NOMEMORY); - - server->mctx = mctx; - server->task = NULL; - - /* Initialize configuration data with default values. */ - result = isc_quota_init(&server->xfroutquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->tcpquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->recursionquota, 100); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_aclenv_init(mctx, &server->aclenv); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - /* Initialize GeoIP before using ACL environment */ - ns_geoip_init(); - server->aclenv.geoip = ns_g_geoip; -#endif - - /* Initialize server data structures. */ - server->zonemgr = NULL; - server->interfacemgr = NULL; - ISC_LIST_INIT(server->viewlist); - server->in_roothints = NULL; - server->blackholeacl = NULL; - server->keepresporder = NULL; - server->rngctx = NULL; - - /* Must be first. */ - CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, - ns_g_engine, ISC_ENTROPY_GOODONLY), - "initializing DST"); - - CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, - &server->in_roothints), - "setting up root hints"); - - CHECKFATAL(isc_mutex_init(&server->reload_event_lock), - "initializing reload event lock"); - server->reload_event = - isc_event_allocate(ns_g_mctx, server, - NS_EVENT_RELOAD, - ns_server_reload, - server, - sizeof(isc_event_t)); - CHECKFATAL(server->reload_event == NULL ? - ISC_R_NOMEMORY : ISC_R_SUCCESS, - "allocating reload event"); - - server->tkeyctx = NULL; - CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, - &server->tkeyctx), - "creating TKEY context"); - server->rngctx = NULL; - CHECKFATAL(isc_rng_create(ns_g_mctx, ns_g_entropy, &server->rngctx), - "creating random numbers context"); - - /* - * Setup the server task, which is responsible for coordinating - * startup and shutdown of the server, as well as all exclusive - * tasks. - */ - CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task), - "creating server task"); - isc_task_setname(server->task, "server", server); - isc_taskmgr_setexcltask(ns_g_taskmgr, server->task); - CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server), - "isc_task_onshutdown"); - CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server), - "isc_app_onrun"); - - server->interface_timer = NULL; - server->heartbeat_timer = NULL; - server->pps_timer = NULL; - server->tat_timer = NULL; - - server->interface_interval = 0; - server->heartbeat_interval = 0; - - CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, - ns_g_socketmgr, &server->zonemgr), - "dns_zonemgr_create"); - CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), - "dns_zonemgr_setsize"); - - server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); - CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - server->nsstats = NULL; - server->rcvquerystats = NULL; - server->opcodestats = NULL; - server->rcodestats = NULL; - server->zonestats = NULL; - server->resolverstats = NULL; - server->sockstats = NULL; - server->udpinstats4 = NULL; - server->udpoutstats4 = NULL; - server->udpinstats6 = NULL; - server->udpoutstats6 = NULL; - server->tcpinstats4 = NULL; - server->tcpoutstats4 = NULL; - server->tcpinstats6 = NULL; - server->tcpoutstats6 = NULL; - CHECKFATAL(isc_stats_create(server->mctx, &server->sockstats, - isc_sockstatscounter_max), - "isc_stats_create"); - isc_socketmgr_setstats(ns_g_socketmgr, server->sockstats); - - server->bindkeysfile = isc_mem_strdup(server->mctx, "bind.keys"); - CHECKFATAL(server->bindkeysfile == NULL ? ISC_R_NOMEMORY : - ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db"); - CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->secrootsfile = isc_mem_strdup(server->mctx, "named.secroots"); - CHECKFATAL(server->secrootsfile == NULL ? ISC_R_NOMEMORY : - ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->recfile = isc_mem_strdup(server->mctx, "named.recursing"); - CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->hostname_set = false; - server->hostname = NULL; - server->version_set = false; - server->version = NULL; - server->server_usehostname = false; - server->server_id = NULL; - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->nsstats, - dns_nsstatscounter_max), - "dns_stats_create (server)"); - - CHECKFATAL(dns_rdatatypestats_create(ns_g_mctx, - &server->rcvquerystats), - "dns_stats_create (rcvquery)"); - - CHECKFATAL(dns_opcodestats_create(ns_g_mctx, &server->opcodestats), - "dns_stats_create (opcode)"); - - CHECKFATAL(dns_rcodestats_create(ns_g_mctx, &server->rcodestats), - "dns_stats_create (rcode)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->zonestats, - dns_zonestatscounter_max), - "dns_stats_create (zone)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->resolverstats, - dns_resstatscounter_max), - "dns_stats_create (resolver)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats4, - dns_sizecounter_in_max), - "dns_stats_create (inbound UDP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats4, - dns_sizecounter_out_max), - "dns_stats_create (outbound UDP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats6, - dns_sizecounter_in_max), - "dns_stats_create (inbound UDP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats6, - dns_sizecounter_out_max), - "dns_stats_create (outbound UDP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats4, - dns_sizecounter_in_max), - "dns_stats_create (inbound TCP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats4, - dns_sizecounter_out_max), - "dns_stats_create (outbound TCP IPv4 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats6, - dns_sizecounter_in_max), - "dns_stats_create (inbound TCP IPv6 traffic size)"); - - CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats6, - dns_sizecounter_out_max), - "dns_stats_create (outbound TCP IPv6 traffic size)"); - - server->flushonshutdown = false; - server->log_queries = false; - - server->controls = NULL; - CHECKFATAL(ns_controls_create(server, &server->controls), - "ns_controls_create"); - server->dispatchgen = 0; - ISC_LIST_INIT(server->dispatches); - - ISC_LIST_INIT(server->statschannels); - - ISC_LIST_INIT(server->cachelist); - - ISC_LIST_INIT(server->altsecrets); - - server->sessionkey = NULL; - server->session_keyfile = NULL; - server->session_keyname = NULL; - server->session_keyalg = DST_ALG_UNKNOWN; - server->session_keybits = 0; - - server->lockfile = NULL; - - server->dtenv = NULL; - server->answercookie = true; - - server->magic = NS_SERVER_MAGIC; - *serverp = server; -} - -void -ns_server_destroy(ns_server_t **serverp) { - ns_server_t *server = *serverp; - REQUIRE(NS_SERVER_VALID(server)); - -#ifdef HAVE_DNSTAP - if (server->dtenv != NULL) - dns_dt_detach(&server->dtenv); -#endif /* HAVE_DNSTAP */ - - ns_controls_destroy(&server->controls); - - isc_stats_detach(&server->nsstats); - dns_stats_detach(&server->rcvquerystats); - dns_stats_detach(&server->opcodestats); - dns_stats_detach(&server->rcodestats); - isc_stats_detach(&server->zonestats); - isc_stats_detach(&server->resolverstats); - isc_stats_detach(&server->sockstats); - isc_stats_detach(&server->udpinstats4); - isc_stats_detach(&server->udpoutstats4); - isc_stats_detach(&server->udpinstats6); - isc_stats_detach(&server->udpoutstats6); - isc_stats_detach(&server->tcpinstats4); - isc_stats_detach(&server->tcpoutstats4); - isc_stats_detach(&server->tcpinstats6); - isc_stats_detach(&server->tcpoutstats6); - - isc_mem_free(server->mctx, server->statsfile); - isc_mem_free(server->mctx, server->bindkeysfile); - isc_mem_free(server->mctx, server->dumpfile); - isc_mem_free(server->mctx, server->secrootsfile); - isc_mem_free(server->mctx, server->recfile); - - if (server->version != NULL) - isc_mem_free(server->mctx, server->version); - if (server->hostname != NULL) - isc_mem_free(server->mctx, server->hostname); - if (server->server_id != NULL) - isc_mem_free(server->mctx, server->server_id); - if (server->lockfile != NULL) - isc_mem_free(server->mctx, server->lockfile); - - if (server->zonemgr != NULL) - dns_zonemgr_detach(&server->zonemgr); - if (server->rngctx != NULL) - isc_rng_detach(&server->rngctx); - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - - dst_lib_destroy(); - - isc_event_free(&server->reload_event); - - INSIST(ISC_LIST_EMPTY(server->viewlist)); - INSIST(ISC_LIST_EMPTY(server->cachelist)); - - dns_aclenv_destroy(&server->aclenv); - - isc_quota_destroy(&server->recursionquota); - isc_quota_destroy(&server->tcpquota); - isc_quota_destroy(&server->xfroutquota); - - server->magic = 0; - isc_mem_put(server->mctx, server, sizeof(*server)); - *serverp = NULL; -} - -static void -fatal(ns_server_t *server, const char *msg, isc_result_t result) { - if (server != NULL && server->task != NULL) { - /* - * Prevent races between the OpenSSL on_exit registered - * function and any other OpenSSL calls from other tasks - * by requesting exclusive access to the task manager. - */ - (void)isc_task_beginexclusive(server->task); - } - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "%s: %s", msg, - isc_result_totext(result)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "exiting (due to fatal error)"); - ns_os_shutdown(); - exit(1); -} - -static void -start_reserved_dispatches(ns_server_t *server) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->dispatchgen++; -} - -static void -end_reserved_dispatches(ns_server_t *server, bool all) { - ns_dispatch_t *dispatch, *nextdispatch; - - REQUIRE(NS_SERVER_VALID(server)); - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = nextdispatch) { - nextdispatch = ISC_LIST_NEXT(dispatch, link); - if (!all && server->dispatchgen == dispatch-> dispatchgen) - continue; - ISC_LIST_UNLINK(server->dispatches, dispatch, link); - dns_dispatch_detach(&dispatch->dispatch); - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - } -} - -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr) { - ns_dispatch_t *dispatch; - in_port_t port; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - unsigned int attrs, attrmask; - - REQUIRE(NS_SERVER_VALID(server)); - - port = isc_sockaddr_getport(addr); - if (port == 0 || port >= 1024) - return; - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = ISC_LIST_NEXT(dispatch, link)) { - if (isc_sockaddr_equal(&dispatch->addr, addr)) - break; - } - if (dispatch != NULL) { - dispatch->dispatchgen = server->dispatchgen; - return; - } - - dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); - if (dispatch == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - dispatch->addr = *addr; - dispatch->dispatchgen = server->dispatchgen; - dispatch->dispatch = NULL; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &dispatch->addr, 4096, - UDPBUFFERS, 32768, 16411, 16433, - attrs, attrmask, &dispatch->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); - - return; - - cleanup: - if (dispatch != NULL) - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "unable to create dispatch for reserved port %s: %s", - addrbuf, isc_result_totext(result)); -} - - -static isc_result_t -loadconfig(ns_server_t *server) { - isc_result_t result; - start_reserved_dispatches(server); - result = load_configuration(ns_g_lwresdonly ? - lwresd_g_conffile : ns_g_conffile, - server, false); - if (result == ISC_R_SUCCESS) { - end_reserved_dispatches(server, false); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reloading configuration succeeded"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading configuration failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -static isc_result_t -reload(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_zones(server, false, false); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "reloading zones succeeded"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading zones failed: %s", - isc_result_totext(result)); - - cleanup: - return (result); -} - -/* - * Handle a reload event (from SIGHUP). - */ -static void -ns_server_reload(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - UNUSED(task); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "received SIGHUP signal to reload zones"); - (void)reload(server); - - LOCK(&server->reload_event_lock); - INSIST(server->reload_event == NULL); - server->reload_event = event; - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_reloadwanted(ns_server_t *server) { - LOCK(&server->reload_event_lock); - if (server->reload_event != NULL) - isc_task_send(server->task, &server->reload_event); - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_scan_interfaces(ns_server_t *server) { - isc_result_t result; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "automatic interface rescan"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, true); - isc_task_endexclusive(server->task); -} - -/* - * Get the next token from lexer 'lex'. - * - * NOTE: the token value for string tokens always uses the same pointer - * value. Multiple calls to this function on the same lexer will always - * return either that value (lex->data) or NULL. It is necessary to copy - * the token into local storage if it needs to be referenced after the next - * call to next_token(). - */ -static char * -next_token(isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - isc_token_t token; - - token.type = isc_tokentype_unknown; - result = isc_lex_gettoken(lex, ISC_LEXOPT_EOF|ISC_LEXOPT_QSTRING, - &token); - - switch (result) { - case ISC_R_NOMORE: - (void) isc_lex_close(lex); - break; - case ISC_R_SUCCESS: - if (token.type == isc_tokentype_eof) - (void) isc_lex_close(lex); - break; - case ISC_R_NOSPACE: - if (text != NULL) { - (void) putstr(text, "token too large"); - (void) putnull(text); - } - return (NULL); - default: - if (text != NULL) { - (void) putstr(text, isc_result_totext(result)); - (void) putnull(text); - } - return (NULL); - } - - if (token.type == isc_tokentype_string || - token.type == isc_tokentype_qstring) - return (token.value.as_textregion.base); - - return (NULL); -} - -/* - * Find the zone specified in the control channel command, if any. - * If a zone is specified, point '*zonep' at it, otherwise - * set '*zonep' to NULL, and f 'zonename' is not NULL, copy - * the zone name into it (N.B. 'zonename' must have space to hold - * a full DNS name). - * - * If 'zonetxt' is set, the caller has already pulled a token - * off the command line that is to be used as the zone name. (This - * is sometimes done when it's necessary to check for an optional - * argument before the zone name, as in "rndc sync [-clean] zone".) - */ -static isc_result_t -zone_from_args(ns_server_t *server, isc_lex_t *lex, const char *zonetxt, - dns_zone_t **zonep, char *zonename, - isc_buffer_t **text, bool skip) -{ - char *ptr; - char *classtxt; - const char *viewtxt = NULL; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - char problem[DNS_NAME_FORMATSIZE + 500] = ""; - char zonebuf[DNS_NAME_FORMATSIZE]; - - REQUIRE(zonep != NULL && *zonep == NULL); - - if (skip) { - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - } - - /* Look for the zone name. */ - if (zonetxt == NULL) - zonetxt = next_token(lex, text); - if (zonetxt == NULL) - return (ISC_R_SUCCESS); - - /* Copy zonetxt because it'll be overwritten by next_token() */ - strlcpy(zonebuf, zonetxt, DNS_NAME_FORMATSIZE); - if (zonename != NULL) - strlcpy(zonename, zonetxt, DNS_NAME_FORMATSIZE); - - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromstring(name, zonebuf, 0, NULL)); - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - CHECK(dns_rdataclass_fromtext(&rdclass, &r)); - - /* Look for the optional view name. */ - viewtxt = next_token(lex, text); - } else - rdclass = dns_rdataclass_in; - - if (viewtxt == NULL) { - result = dns_viewlist_findzone(&server->viewlist, name, - (classtxt == NULL), - rdclass, zonep); - if (result == ISC_R_NOTFOUND) - snprintf(problem, sizeof(problem), - "no matching zone '%s' in any view", - zonebuf); - else if (result == ISC_R_MULTIPLE) - snprintf(problem, sizeof(problem), - "zone '%s' was found in multiple views", - zonebuf); - } else { - result = dns_viewlist_find(&server->viewlist, viewtxt, - rdclass, &view); - if (result != ISC_R_SUCCESS) { - snprintf(problem, sizeof(problem), - "no matching view '%s'", viewtxt); - goto report; - } - - result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); - if (result != ISC_R_SUCCESS) - snprintf(problem, sizeof(problem), - "no matching zone '%s' in view '%s'", - zonebuf, viewtxt); - } - - /* Partial match? */ - if (result != ISC_R_SUCCESS && *zonep != NULL) - dns_zone_detach(zonep); - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - report: - if (result != ISC_R_SUCCESS) { - isc_result_t tresult; - - tresult = putstr(text, problem); - if (tresult == ISC_R_SUCCESS) - (void) putnull(text); - } - - cleanup: - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -/* - * Act on a "retransfer" command from the command channel. - */ -isc_result_t -ns_server_retransfercommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - dns_zonetype_t type; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) - dns_zone_forcereload(zone); - else - result = ISC_R_NOTFOUND; - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "reload" command from the command channel. - */ -isc_result_t -ns_server_reloadcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - const char *msg = NULL; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) { - result = reload(server); - if (result == ISC_R_SUCCESS) - msg = "server reload successful"; - } else { - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - msg = "zone refresh queued"; - } else { - result = dns_zone_load(zone); - dns_zone_detach(&zone); - switch (result) { - case ISC_R_SUCCESS: - msg = "zone reload successful"; - break; - case DNS_R_CONTINUE: - msg = "zone reload queued"; - result = ISC_R_SUCCESS; - break; - case DNS_R_UPTODATE: - msg = "zone reload up-to-date"; - result = ISC_R_SUCCESS; - break; - default: - /* failure message will be generated by rndc */ - break; - } - } - } - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - return (result); -} - -/* - * Act on a "reconfig" command from the command channel. - */ -isc_result_t -ns_server_reconfigcommand(ns_server_t *server) { - isc_result_t result; - - CHECK(loadconfig(server)); - - result = load_zones(server, false, true); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "scheduled loading new zones"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "loading new zones failed: %s", - isc_result_totext(result)); -cleanup: - return (result); -} - -/* - * Act on a "notify" command from the command channel. - */ -isc_result_t -ns_server_notifycommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL; - const char msg[] = "zone notify queued"; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_notify(zone); - dns_zone_detach(&zone); - (void) putstr(text, msg); - (void) putnull(text); - - return (ISC_R_SUCCESS); -} - -/* - * Act on a "refresh" command from the command channel. - */ -isc_result_t -ns_server_refreshcommand(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_zone_t *zone = NULL, *raw = NULL; - const char msg1[] = "zone refresh queued"; - const char msg2[] = "not a slave or stub zone"; - dns_zonetype_t type; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - (void) putstr(text, msg1); - (void) putnull(text); - return (ISC_R_SUCCESS); - } - - dns_zone_detach(&zone); - (void) putstr(text, msg2); - (void) putnull(text); - return (ISC_R_FAILURE); -} - -isc_result_t -ns_server_togglequerylog(ns_server_t *server, isc_lex_t *lex) { - bool value; - char *ptr; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, NULL); - if (ptr == NULL) { - value = server->log_queries ? false : true; - } else if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || - !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) { - value = true; - } else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || - !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) { - value = false; - } else { - return (DNS_R_SYNTAX); - } - - if (server->log_queries == value) - return (ISC_R_SUCCESS); - - server->log_queries = value; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "query logging is now %s", - server->log_queries ? "on" : "off"); - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenlist_t **target) -{ - isc_result_t result; - const cfg_listelt_t *element; - ns_listenlist_t *dlist = NULL; - - REQUIRE(target != NULL && *target == NULL); - - result = ns_listenlist_create(mctx, &dlist); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(listenlist); - element != NULL; - element = cfg_list_next(element)) - { - ns_listenelt_t *delt = NULL; - const cfg_obj_t *listener = cfg_listelt_value(element); - result = ns_listenelt_fromconfig(listener, config, actx, - mctx, family, &delt); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(dlist->elts, delt, link); - } - *target = dlist; - return (ISC_R_SUCCESS); - - cleanup: - ns_listenlist_detach(&dlist); - return (result); -} - -/* - * Create a listen list from the corresponding configuration - * data structure. - */ -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, isc_mem_t *mctx, - uint16_t family, ns_listenelt_t **target) -{ - isc_result_t result; - const cfg_obj_t *portobj, *dscpobj; - in_port_t port; - isc_dscp_t dscp = -1; - ns_listenelt_t *delt = NULL; - REQUIRE(target != NULL && *target == NULL); - - portobj = cfg_tuple_get(listener, "port"); - if (!cfg_obj_isuint32(portobj)) { - if (ns_g_port != 0) { - port = ns_g_port; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - } else { - if (cfg_obj_asuint32(portobj) >= UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port value '%u' is out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - port = (in_port_t)cfg_obj_asuint32(portobj); - } - - dscpobj = cfg_tuple_get(listener, "dscp"); - if (!cfg_obj_isuint32(dscpobj)) - dscp = ns_g_dscp; - else { - if (cfg_obj_asuint32(dscpobj) > 63) { - cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, - "dscp value '%u' is out of range", - cfg_obj_asuint32(dscpobj)); - return (ISC_R_RANGE); - } - dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); - } - - result = ns_listenelt_create(mctx, port, dscp, NULL, &delt); - if (result != ISC_R_SUCCESS) - return (result); - - result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), - config, ns_g_lctx, actx, mctx, 0, - family, &delt->acl); - if (result != ISC_R_SUCCESS) { - ns_listenelt_destroy(delt); - return (result); - } - *target = delt; - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_dumpstats(ns_server_t *server) { - isc_result_t result; - FILE *fp = NULL; - - CHECKMF(isc_stdio_open(server->statsfile, "a", &fp), - "could not open statistics dump file", server->statsfile); - - result = ns_stats_dump(server, fp); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpstats complete"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpstats failed: %s", - dns_result_totext(result)); - return (result); -} - -static isc_result_t -add_zone_tolist(dns_zone_t *zone, void *uap) { - struct dumpcontext *dctx = uap; - struct zonelistentry *zle; - - zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) - return (ISC_R_NOMEMORY); - zle->zone = NULL; - dns_zone_attach(zone, &zle->zone); - ISC_LINK_INIT(zle, link); - ISC_LIST_APPEND(ISC_LIST_TAIL(dctx->viewlist)->zonelist, zle, link); - return (ISC_R_SUCCESS); -} - -static isc_result_t -add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) { - struct viewlistentry *vle; - isc_result_t result = ISC_R_SUCCESS; - - /* - * Prevent duplicate views. - */ - for (vle = ISC_LIST_HEAD(dctx->viewlist); - vle != NULL; - vle = ISC_LIST_NEXT(vle, link)) - if (vle->view == view) - return (ISC_R_SUCCESS); - - vle = isc_mem_get(dctx->mctx, sizeof *vle); - if (vle == NULL) - return (ISC_R_NOMEMORY); - vle->view = NULL; - dns_view_attach(view, &vle->view); - ISC_LINK_INIT(vle, link); - ISC_LIST_INIT(vle->zonelist); - ISC_LIST_APPEND(dctx->viewlist, vle, link); - if (dctx->dumpzones) - result = dns_zt_apply(view->zonetable, true, - add_zone_tolist, dctx); - return (result); -} - -static void -dumpcontext_destroy(struct dumpcontext *dctx) { - struct viewlistentry *vle; - struct zonelistentry *zle; - - vle = ISC_LIST_HEAD(dctx->viewlist); - while (vle != NULL) { - ISC_LIST_UNLINK(dctx->viewlist, vle, link); - zle = ISC_LIST_HEAD(vle->zonelist); - while (zle != NULL) { - ISC_LIST_UNLINK(vle->zonelist, zle, link); - dns_zone_detach(&zle->zone); - isc_mem_put(dctx->mctx, zle, sizeof *zle); - zle = ISC_LIST_HEAD(vle->zonelist); - } - dns_view_detach(&vle->view); - isc_mem_put(dctx->mctx, vle, sizeof *vle); - vle = ISC_LIST_HEAD(dctx->viewlist); - } - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, false); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->cache != NULL) - dns_db_detach(&dctx->cache); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - if (dctx->fp != NULL) - (void)isc_stdio_close(dctx->fp); - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - isc_mem_put(dctx->mctx, dctx, sizeof *dctx); -} - -static void -dumpdone(void *arg, isc_result_t result) { - struct dumpcontext *dctx = arg; - char buf[1024+32]; - const dns_master_style_t *style; - - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - if (dctx->mdctx != NULL) { - dns_dumpctx_detach(&dctx->mdctx); - } - if (dctx->view == NULL) { - dctx->view = ISC_LIST_HEAD(dctx->viewlist); - if (dctx->view == NULL) { - goto done; - } - INSIST(dctx->zone == NULL); - } else { - goto resume; - } - nextview: - fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name); - resume: - if (dctx->dumpcache && dns_view_iscacheshared(dctx->view->view)) { - fprintf(dctx->fp, - ";\n; Cache of view '%s' is shared as '%s'\n", - dctx->view->view->name, - dns_cache_getname(dctx->view->view->cache)); - } else if (dctx->zone == NULL && dctx->cache == NULL && - dctx->dumpcache) - { - style = &dns_master_style_cache; - /* start cache dump */ - if (dctx->view->view->cachedb != NULL) { - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - } - if (dctx->cache != NULL) { - fprintf(dctx->fp, - ";\n; Cache dump of view '%s' (cache %s)\n;\n", - dctx->view->view->name, - dns_cache_getname(dctx->view->view->cache)); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->cache, NULL, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) { - return; - } - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - } else if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - } - - if ((dctx->dumpadb || dctx->dumpbad || dctx->dumpfail) && - dctx->cache == NULL && dctx->view->view->cachedb != NULL) { - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - } - - if (dctx->cache != NULL) { - if (dctx->dumpadb) { - dns_adb_dump(dctx->view->view->adb, dctx->fp); - } - if (dctx->dumpbad) { - dns_resolver_printbadcache(dctx->view->view->resolver, - dctx->fp); - } - if (dctx->dumpfail) { - dns_badcache_print(dctx->view->view->failcache, - "SERVFAIL cache", dctx->fp); - } - dns_db_detach(&dctx->cache); - } - if (dctx->dumpzones) { - style = &dns_master_style_full; - nextzone: - if (dctx->version != NULL) { - dns_db_closeversion(dctx->db, &dctx->version, - false); - } - if (dctx->db != NULL) { - dns_db_detach(&dctx->db); - } - if (dctx->zone == NULL) { - dctx->zone = ISC_LIST_HEAD(dctx->view->zonelist); - } else { - dctx->zone = ISC_LIST_NEXT(dctx->zone, link); - } - if (dctx->zone != NULL) { - /* start zone dump */ - dns_zone_name(dctx->zone->zone, buf, sizeof(buf)); - fprintf(dctx->fp, ";\n; Zone dump of '%s'\n;\n", buf); - result = dns_zone_getdb(dctx->zone->zone, &dctx->db); - if (result != ISC_R_SUCCESS) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - goto nextzone; - } - dns_db_currentversion(dctx->db, &dctx->version); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->db, - dctx->version, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) { - return; - } - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - result = ISC_R_SUCCESS; - POST(result); - goto nextzone; - } - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - } - if (dctx->view != NULL) { - dctx->view = ISC_LIST_NEXT(dctx->view, link); - if (dctx->view != NULL) { - goto nextview; - } - } - done: - fprintf(dctx->fp, "; Dump complete\n"); - result = isc_stdio_flush(dctx->fp); - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb complete"); - } - cleanup: - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpdb failed: %s", dns_result_totext(result)); - } - dumpcontext_destroy(dctx); -} - -isc_result_t -ns_server_dumpdb(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - struct dumpcontext *dctx = NULL; - dns_view_t *view; - isc_result_t result; - char *ptr; - const char *sep; - bool found; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - dctx = isc_mem_get(server->mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - dctx->mctx = server->mctx; - dctx->dumpcache = true; - dctx->dumpadb = true; - dctx->dumpbad = true; - dctx->dumpfail = true; - dctx->dumpzones = false; - dctx->fp = NULL; - ISC_LIST_INIT(dctx->viewlist); - dctx->view = NULL; - dctx->zone = NULL; - dctx->cache = NULL; - dctx->mdctx = NULL; - dctx->db = NULL; - dctx->cache = NULL; - dctx->task = NULL; - dctx->version = NULL; - isc_task_attach(server->task, &dctx->task); - - CHECKMF(isc_stdio_open(server->dumpfile, "w", &dctx->fp), - "could not open dump file", server->dumpfile); - - ptr = next_token(lex, NULL); - sep = (ptr == NULL) ? "" : ": "; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb started%s%s", sep, (ptr != NULL) ? ptr : ""); - - if (ptr != NULL && strcmp(ptr, "-all") == 0) { - /* also dump zones */ - dctx->dumpzones = true; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-cache") == 0) { - /* this is the default */ - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-zones") == 0) { - /* only dump zones, suppress caches */ - dctx->dumpadb = false; - dctx->dumpbad = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - dctx->dumpzones = true; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-adb") == 0) { - /* only dump adb, suppress other caches */ - dctx->dumpbad = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-bad") == 0) { - /* only dump badcache, suppress other caches */ - dctx->dumpadb = false; - dctx->dumpcache = false; - dctx->dumpfail = false; - ptr = next_token(lex, NULL); - } else if (ptr != NULL && strcmp(ptr, "-fail") == 0) { - /* only dump servfail cache, suppress other caches */ - dctx->dumpadb = false; - dctx->dumpbad = false; - dctx->dumpcache = false; - ptr = next_token(lex, NULL); - } - - nextview: - found = false; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) - continue; - found = true; - CHECK(add_view_tolist(dctx, view)); - } - if (ptr != NULL) { - if (!found) { - CHECK(putstr(text, "view '")); - CHECK(putstr(text, ptr)); - CHECK(putstr(text, "' not found")); - CHECK(putnull(text)); - result = ISC_R_NOTFOUND; - dumpdone(dctx, result); - return (result); - } - ptr = next_token(lex, NULL); - if (ptr != NULL) - goto nextview; - } - dumpdone(dctx, ISC_R_SUCCESS); - return (ISC_R_SUCCESS); - - cleanup: - if (dctx != NULL) - dumpcontext_destroy(dctx); - return (result); -} - -isc_result_t -ns_server_dumpsecroots(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - dns_view_t *view; - dns_keytable_t *secroots = NULL; - dns_ntatable_t *ntatable = NULL; - isc_result_t result; - char *ptr; - FILE *fp = NULL; - isc_time_t now; - char tbuf[64]; - unsigned int used = isc_buffer_usedlength(*text); - bool first = true; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* "-" here means print the output instead of dumping to file */ - ptr = next_token(lex, text); - if (ptr != NULL && strcmp(ptr, "-") == 0) { - ptr = next_token(lex, text); - } else { - result = isc_stdio_open(server->secrootsfile, "w", &fp); - if (result != ISC_R_SUCCESS) { - (void) putstr(text, "could not open "); - (void) putstr(text, server->secrootsfile); - CHECKMF(result, "could not open secroots dump file", - server->secrootsfile); - } - } - - TIME_NOW(&now); - isc_time_formattimestamp(&now, tbuf, sizeof(tbuf)); - CHECK(putstr(text, "secure roots as of ")); - CHECK(putstr(text, tbuf)); - CHECK(putstr(text, ":\n")); - used = isc_buffer_usedlength(*text); - - do { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) { - continue; - } - if (secroots != NULL) { - dns_keytable_detach(&secroots); - } - result = dns_view_getsecroots(view, &secroots); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - if (first || used != isc_buffer_usedlength(*text)) { - CHECK(putstr(text, "\n")); - first = false; - } - CHECK(putstr(text, " Start view ")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, "\n Secure roots:\n\n")); - used = isc_buffer_usedlength(*text); - CHECK(dns_keytable_totext(secroots, text)); - - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - if (used != isc_buffer_usedlength(*text)) { - CHECK(putstr(text, "\n")); - } - CHECK(putstr(text, " Negative trust anchors:\n\n")); - used = isc_buffer_usedlength(*text); - CHECK(dns_ntatable_totext(ntatable, text)); - } - - if (ptr != NULL) { - ptr = next_token(lex, text); - } - } while (ptr != NULL); - - cleanup: - if (secroots != NULL) { - dns_keytable_detach(&secroots); - } - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - - if (fp != NULL) { - if (used != isc_buffer_usedlength(*text)) { - (void)putstr(text, "\n"); - } - fprintf(fp, "%.*s", (int) isc_buffer_usedlength(*text), - (char *) isc_buffer_base(*text)); - isc_buffer_clear(*text); - (void)isc_stdio_close(fp); - } else if (isc_buffer_usedlength(*text) > 0) { - (void)putnull(text); - } - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpsecroots complete"); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumpsecroots failed: %s", - dns_result_totext(result)); - } - return (result); -} - -isc_result_t -ns_server_dumprecursing(ns_server_t *server) { - FILE *fp = NULL; - dns_view_t *view; - isc_result_t result; - - CHECKMF(isc_stdio_open(server->recfile, "w", &fp), - "could not open dump file", server->recfile); - fprintf(fp, ";\n; Recursing Queries\n;\n"); - ns_interfacemgr_dumprecursing(fp, server->interfacemgr); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - fprintf(fp, ";\n; Active fetch domains [view: %s]\n;\n", - view->name); - dns_resolver_dumpfetches(view->resolver, - isc_statsformat_file, fp); - } - - fprintf(fp, "; Dump complete\n"); - - cleanup: - if (fp != NULL) - result = isc_stdio_close(fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumprecursing complete"); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "dumprecursing failed: %s", - dns_result_totext(result)); - return (result); -} - -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, isc_lex_t *lex) { - char *ptr; - char *endp; - long newlevel; - - UNUSED(server); - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the new level name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) { - if (ns_g_debuglevel < 99) - ns_g_debuglevel++; - } else { - newlevel = strtol(ptr, &endp, 10); - if (*endp != '\0' || newlevel < 0 || newlevel > 99) - return (ISC_R_RANGE); - ns_g_debuglevel = (unsigned int)newlevel; - } - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "debug level is now %u", ns_g_debuglevel); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_validation(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - char *ptr; - dns_view_t *view; - bool changed = false; - isc_result_t result; - bool enable = true, set = true, first = true; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || - !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) { - enable = true; - } else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || - !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) { - enable = false; - } else if (!strcasecmp(ptr, "check") || !strcasecmp(ptr, "status")) { - set = false; - } else { - return (DNS_R_SYNTAX); - } - - /* Look for the view name. */ - ptr = next_token(lex, text); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcasecmp(ptr, view->name) != 0) - continue; - CHECK(dns_view_flushcache(view)); - - if (set) { - view->enablevalidation = enable; - changed = true; - } else { - if (!first) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "DNSSEC validation is ")); - CHECK(putstr(text, view->enablevalidation - ? "enabled" : "disabled")); - CHECK(putstr(text, " (view ")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ")")); - CHECK(putnull(text)); - first = false; - } - } - - if (!set) - result = ISC_R_SUCCESS; - else if (changed) - result = ISC_R_SUCCESS; - else - result = ISC_R_FAILURE; - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushcache(ns_server_t *server, isc_lex_t *lex) { - char *ptr; - dns_view_t *view; - bool flushed; - bool found; - isc_result_t result; - ns_cache_t *nsc; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the view name. */ - ptr = next_token(lex, NULL); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = true; - found = false; - - /* - * Flushing a cache is tricky when caches are shared by multiple views. - * We first identify which caches should be flushed in the local cache - * list, flush these caches, and then update other views that refer to - * the flushed cache DB. - */ - if (ptr != NULL) { - /* - * Mark caches that need to be flushed. This is an O(#view^2) - * operation in the very worst case, but should be normally - * much more lightweight because only a few (most typically just - * one) views will match. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (strcasecmp(ptr, view->name) != 0) - continue; - found = true; - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (nsc->cache == view->cache) - break; - } - INSIST(nsc != NULL); - nsc->needflush = true; - } - } else - found = true; - - /* Perform flush */ - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (ptr != NULL && !nsc->needflush) - continue; - nsc->needflush = true; - result = dns_view_flushcache2(nsc->primaryview, false); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing cache in view '%s' failed: %s", - nsc->primaryview->name, - isc_result_totext(result)); - } - } - - /* - * Fix up views that share a flushed cache: let the views update the - * cache DB they're referring to. This could also be an expensive - * operation, but should typically be marginal: the inner loop is only - * necessary for views that share a cache, and if there are many such - * views the number of shared cache should normally be small. - * A worst case is that we have n views and n/2 caches, each shared by - * two views. Then this will be a O(n^2/4) operation. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (!dns_view_iscacheshared(view)) - continue; - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - if (!nsc->needflush || nsc->cache != view->cache) - continue; - result = dns_view_flushcache2(view, true); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "fixing cache in view '%s' " - "failed: %s", view->name, - isc_result_totext(result)); - } - } - } - - /* Cleanup the cache list. */ - for (nsc = ISC_LIST_HEAD(server->cachelist); - nsc != NULL; - nsc = ISC_LIST_NEXT(nsc, link)) { - nsc->needflush = false; - } - - if (flushed && found) { - if (ptr != NULL) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing cache in view '%s' succeeded", - ptr); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing caches in all views succeeded"); - result = ISC_R_SUCCESS; - } else { - if (!found) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing cache in view '%s' failed: " - "view not found", ptr); - result = ISC_R_NOTFOUND; - } else - result = ISC_R_FAILURE; - } - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushnode(ns_server_t *server, isc_lex_t *lex, bool tree) { - char *ptr, *viewname; - char target[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - bool flushed; - bool found; - isc_result_t result; - isc_buffer_t b; - dns_fixedname_t fixed; - dns_name_t *name; - - /* Skip the command name. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find the domain name to flush. */ - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - strlcpy(target, ptr, DNS_NAME_FORMATSIZE); - isc_buffer_constinit(&b, target, strlen(target)); - isc_buffer_add(&b, strlen(target)); - name = dns_fixedname_initname(&fixed); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - /* Look for the view name. */ - viewname = next_token(lex, NULL); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = true; - found = false; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - found = true; - /* - * It's a little inefficient to try flushing name for all views - * if some of the views share a single cache. But since the - * operation is lightweight we prefer simplicity here. - */ - result = dns_view_flushnode(view, name, tree); - if (result != ISC_R_SUCCESS) { - flushed = false; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing %s '%s' in cache view '%s' " - "failed: %s", - tree ? "tree" : "name", - target, view->name, - isc_result_totext(result)); - } - } - if (flushed && found) { - if (viewname != NULL) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing %s '%s' in cache view '%s' " - "succeeded", - tree ? "tree" : "name", - target, viewname); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing %s '%s' in all cache views " - "succeeded", - tree ? "tree" : "name", - target); - result = ISC_R_SUCCESS; - } else { - if (!found) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing %s '%s' in cache view '%s' " - "failed: view not found", - tree ? "tree" : "name", - target, viewname); - result = ISC_R_FAILURE; - } - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t **text) { - isc_result_t result; - unsigned int zonecount, xferrunning, xferdeferred, soaqueries; - unsigned int automatic; - const char *ob = "", *cb = "", *alt = ""; - char boottime[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char configtime[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char line[1024], hostname[256]; - - if (ns_g_server->version_set) { - ob = " ("; - cb = ")"; - if (ns_g_server->version == NULL) - alt = "version.bind/txt/ch disabled"; - else - alt = ns_g_server->version; - } - zonecount = dns_zonemgr_getcount(server->zonemgr, DNS_ZONESTATE_ANY); - xferrunning = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERRUNNING); - xferdeferred = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERDEFERRED); - soaqueries = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_SOAQUERY); - automatic = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_AUTOMATIC); - - isc_time_formathttptimestamp(&ns_g_boottime, boottime, - sizeof(boottime)); - isc_time_formathttptimestamp(&ns_g_configtime, configtime, - sizeof(configtime)); - - snprintf(line, sizeof(line), "version: %s %s%s%s %s%s%s\n", - ns_g_product, ns_g_version, - (*ns_g_description != '\0') ? " " : "", - ns_g_description, ns_g_srcid, ob, alt, cb); - CHECK(putstr(text, line)); - - result = ns_os_gethostname(hostname, sizeof(hostname)); - if (result != ISC_R_SUCCESS) - strlcpy(hostname, "localhost", sizeof(hostname)); - snprintf(line, sizeof(line), "running on %s: %s\n", - hostname, ns_os_uname()); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "boot time: %s\n", boottime); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "last configured: %s\n", configtime); - CHECK(putstr(text, line)); - - if (ns_g_chrootdir != NULL) { - snprintf(line, sizeof(line), "configuration file: %s (%s%s)\n", - ns_g_conffile, ns_g_chrootdir, ns_g_conffile); - } else { - snprintf(line, sizeof(line), "configuration file: %s\n", - ns_g_conffile); - } - CHECK(putstr(text, line)); - -#ifdef ISC_PLATFORM_USETHREADS - snprintf(line, sizeof(line), "CPUs found: %u\n", ns_g_cpus_detected); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "worker threads: %u\n", ns_g_cpus); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "UDP listeners per interface: %u\n", - ns_g_udpdisp); - CHECK(putstr(text, line)); -#else - snprintf(line, sizeof(line), "CPUs found: N/A (threads disabled)\n"); - CHECK(putstr(text, line)); -#endif - - snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n", - zonecount, automatic); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "debug level: %u\n", ns_g_debuglevel); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "xfers running: %u\n", xferrunning); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "xfers deferred: %u\n", xferdeferred); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "soa queries in progress: %u\n", - soaqueries); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "query logging is %s\n", - server->log_queries ? "ON" : "OFF"); - CHECK(putstr(text, line)); - - LOCK(&server->recursionquota.lock); - snprintf(line, sizeof(line), "recursive clients: %d/%d/%d\n", - server->recursionquota.used, server->recursionquota.soft, - server->recursionquota.max); - UNLOCK(&server->recursionquota.lock); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "tcp clients: %d/%d\n", - server->tcpquota.used, server->tcpquota.max); - CHECK(putstr(text, line)); - - snprintf(line, sizeof(line), "TCP high-water: %" PRIu64 "\n", - isc_stats_get_counter(ns_g_server->nsstats, - dns_nsstatscounter_tcphighwater)); - CHECK(putstr(text, line)); - - CHECK(putstr(text, "server is up and running")); - CHECK(putnull(text)); - - return (ISC_R_SUCCESS); - cleanup: - return (result); -} - -isc_result_t -ns_server_testgen(isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - char *ptr; - unsigned long count; - unsigned long i; - const unsigned char chars[] = "abcdefghijklmnopqrstuvwxyz0123456789"; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, text); - if (ptr == NULL) - count = 26; - else - count = strtoul(ptr, NULL, 10); - - CHECK(isc_buffer_reserve(text, count)); - for (i = 0; i < count; i++) - CHECK(putuint8(text, chars[i % (sizeof(chars) - 1)])); - - CHECK(putnull(text)); - - cleanup: - return (result); -} - -static isc_result_t -delete_keynames(dns_tsig_keyring_t *ring, char *target, - unsigned int *foundkeys) -{ - char namestr[DNS_NAME_FORMATSIZE]; - isc_result_t result; - dns_rbtnodechain_t chain; - dns_name_t foundname; - dns_fixedname_t fixedorigin; - dns_name_t *origin; - dns_rbtnode_t *node; - dns_tsigkey_t *tkey; - - dns_name_init(&foundname, NULL); - origin = dns_fixedname_initname(&fixedorigin); - - again: - dns_rbtnodechain_init(&chain, ring->mctx); - result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, - origin); - if (result == ISC_R_NOTFOUND) { - dns_rbtnodechain_invalidate(&chain); - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - - for (;;) { - node = NULL; - dns_rbtnodechain_current(&chain, &foundname, origin, &node); - tkey = node->data; - - if (tkey != NULL) { - if (!tkey->generated) - goto nextkey; - - dns_name_format(&tkey->name, namestr, sizeof(namestr)); - if (strcmp(namestr, target) == 0) { - (*foundkeys)++; - dns_rbtnodechain_invalidate(&chain); - (void)dns_rbt_deletename(ring->keys, - &tkey->name, - false); - goto again; - } - } - - nextkey: - result = dns_rbtnodechain_next(&chain, &foundname, origin); - if (result == ISC_R_NOMORE) - break; - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_tsigdelete(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result; - dns_view_t *view; - unsigned int foundkeys = 0; - char *ptr, *viewname; - char target[DNS_NAME_FORMATSIZE]; - char fbuf[16]; - - (void)next_token(lex, text); /* skip command name */ - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(target, ptr, DNS_NAME_FORMATSIZE); - - viewname = next_token(lex, text); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (viewname == NULL || strcmp(view->name, viewname) == 0) { - RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_write); - result = delete_keynames(view->dynamickeys, target, - &foundkeys); - RWUNLOCK(&view->dynamickeys->lock, - isc_rwlocktype_write); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - } - } - isc_task_endexclusive(server->task); - - snprintf(fbuf, sizeof(fbuf), "%u", foundkeys); - - CHECK(putstr(text, fbuf)); - CHECK(putstr(text, " tsig keys deleted.")); - CHECK(putnull(text)); - - cleanup: - return (result); -} - -static isc_result_t -list_keynames(dns_view_t *view, dns_tsig_keyring_t *ring, isc_buffer_t **text, - unsigned int *foundkeys) -{ - char namestr[DNS_NAME_FORMATSIZE]; - char creatorstr[DNS_NAME_FORMATSIZE]; - isc_result_t result; - dns_rbtnodechain_t chain; - dns_name_t foundname; - dns_fixedname_t fixedorigin; - dns_name_t *origin; - dns_rbtnode_t *node; - dns_tsigkey_t *tkey; - const char *viewname; - - if (view != NULL) - viewname = view->name; - else - viewname = "(global)"; - - dns_name_init(&foundname, NULL); - origin = dns_fixedname_initname(&fixedorigin); - dns_rbtnodechain_init(&chain, ring->mctx); - result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, - origin); - if (result == ISC_R_NOTFOUND) { - dns_rbtnodechain_invalidate(&chain); - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - dns_rbtnodechain_invalidate(&chain); - return (result); - } - - for (;;) { - node = NULL; - dns_rbtnodechain_current(&chain, &foundname, origin, &node); - tkey = node->data; - - if (tkey != NULL) { - dns_name_format(&tkey->name, namestr, sizeof(namestr)); - if (tkey->generated) { - dns_name_format(tkey->creator, creatorstr, - sizeof(creatorstr)); - if (*foundkeys != 0) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "view \"")); - CHECK(putstr(text, viewname)); - CHECK(putstr(text, - "\"; type \"dynamic\"; key \"")); - CHECK(putstr(text, namestr)); - CHECK(putstr(text, "\"; creator \"")); - CHECK(putstr(text, creatorstr)); - CHECK(putstr(text, "\";")); - } else { - if (*foundkeys != 0) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, "view \"")); - CHECK(putstr(text, viewname)); - CHECK(putstr(text, - "\"; type \"static\"; key \"")); - CHECK(putstr(text, namestr)); - CHECK(putstr(text, "\";")); - } - (*foundkeys)++; - } - result = dns_rbtnodechain_next(&chain, &foundname, origin); - if (result == ISC_R_NOMORE || result == DNS_R_NEWORIGIN) - break; - } - - return (ISC_R_SUCCESS); - cleanup: - dns_rbtnodechain_invalidate(&chain); - return (result); -} - -isc_result_t -ns_server_tsiglist(ns_server_t *server, isc_buffer_t **text) { - isc_result_t result; - dns_view_t *view; - unsigned int foundkeys = 0; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - RWLOCK(&view->statickeys->lock, isc_rwlocktype_read); - result = list_keynames(view, view->statickeys, text, - &foundkeys); - RWUNLOCK(&view->statickeys->lock, isc_rwlocktype_read); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - RWLOCK(&view->dynamickeys->lock, isc_rwlocktype_read); - result = list_keynames(view, view->dynamickeys, text, - &foundkeys); - RWUNLOCK(&view->dynamickeys->lock, isc_rwlocktype_read); - if (result != ISC_R_SUCCESS) { - isc_task_endexclusive(server->task); - return (result); - } - } - isc_task_endexclusive(server->task); - - if (foundkeys == 0) - CHECK(putstr(text, "no tsig keys found.")); - - if (isc_buffer_usedlength(*text) > 0) - CHECK(putnull(text)); - - cleanup: - return (result); -} - -/* - * Act on a "sign" or "loadkeys" command from the command channel. - */ -isc_result_t -ns_server_rekey(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - uint16_t keyopts; - bool fullsign = false; - char *ptr; - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, NS_COMMAND_SIGN) == 0) - fullsign = true; - - result = zone_from_args(server, lex, NULL, &zone, NULL, - text, false); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); /* XXX: or do all zones? */ - - type = dns_zone_gettype(zone); - if (type != dns_zone_master) { - dns_zone_detach(&zone); - return (DNS_R_NOTMASTER); - } - - keyopts = dns_zone_getkeyopts(zone); - - /* "rndc loadkeys" requires "auto-dnssec maintain". */ - if ((keyopts & DNS_ZONEKEY_ALLOW) == 0) - result = ISC_R_NOPERM; - else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign) - result = ISC_R_NOPERM; - else - dns_zone_rekey(zone, fullsign); - - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "sync" command from the command channel. -*/ -static isc_result_t -synczone(dns_zone_t *zone, void *uap) { - bool cleanup = *(bool *)uap; - isc_result_t result; - dns_zone_t *raw = NULL; - char *journal; - - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - synczone(raw, uap); - dns_zone_detach(&raw); - } - - result = dns_zone_flush(zone); - if (result != ISC_R_SUCCESS) - cleanup = false; - if (cleanup) { - journal = dns_zone_getjournal(zone); - if (journal != NULL) - (void)isc_file_remove(journal); - } - - return (result); -} - -isc_result_t -ns_server_sync(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result, tresult; - dns_view_t *view; - dns_zone_t *zone = NULL; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - const char *vname, *sep, *arg; - bool cleanup = false; - - (void) next_token(lex, text); - - arg = next_token(lex, text); - if (arg != NULL && - (strcmp(arg, "-clean") == 0 || strcmp(arg, "-clear") == 0)) { - cleanup = true; - arg = next_token(lex, text); - } - - result = zone_from_args(server, lex, arg, &zone, NULL, - text, false); - if (result != ISC_R_SUCCESS) - return (result); - - if (zone == NULL) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tresult = ISC_R_SUCCESS; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - result = dns_zt_apply(view->zonetable, false, - synczone, &cleanup); - if (result != ISC_R_SUCCESS && - tresult == ISC_R_SUCCESS) - tresult = result; - } - isc_task_endexclusive(server->task); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumping all zones%s: %s", - cleanup ? ", removing journal files" : "", - isc_result_totext(result)); - return (tresult); - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = synczone(zone, &cleanup); - isc_task_endexclusive(server->task); - - view = dns_zone_getview(zone); - if (strcmp(view->name, "_default") == 0 || - strcmp(view->name, "_bind") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(zone), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "sync: dumping zone '%s/%s'%s%s%s: %s", - zonename, classstr, sep, vname, - cleanup ? ", removing journal file" : "", - isc_result_totext(result)); - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "freeze" or "thaw" command from the command channel. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, bool freeze, - isc_lex_t *lex, isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *mayberaw = NULL, *raw = NULL; - dns_zonetype_t type; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - const char *vname, *sep; - bool frozen; - const char *msg = NULL; - - result = zone_from_args(server, lex, NULL, &mayberaw, NULL, - text, true); - if (result != ISC_R_SUCCESS) - return (result); - if (mayberaw == NULL) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tresult = ISC_R_SUCCESS; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - result = dns_view_freezezones(view, freeze); - if (result != ISC_R_SUCCESS && - tresult == ISC_R_SUCCESS) - tresult = result; - } - isc_task_endexclusive(server->task); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s all zones: %s", - freeze ? "freezing" : "thawing", - isc_result_totext(tresult)); - return (tresult); - } - dns_zone_getraw(mayberaw, &raw); - if (raw != NULL) { - dns_zone_detach(&mayberaw); - dns_zone_attach(raw, &mayberaw); - dns_zone_detach(&raw); - } - type = dns_zone_gettype(mayberaw); - if (type != dns_zone_master) { - dns_zone_detach(&mayberaw); - return (DNS_R_NOTMASTER); - } - - if (freeze && !dns_zone_isdynamic(mayberaw, true)) { - dns_zone_detach(&mayberaw); - return (DNS_R_NOTDYNAMIC); - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - frozen = dns_zone_getupdatedisabled(mayberaw); - if (freeze) { - if (frozen) { - msg = "WARNING: The zone was already frozen.\n" - "Someone else may be editing it or " - "it may still be re-loading."; - result = DNS_R_FROZEN; - } - if (result == ISC_R_SUCCESS) { - result = dns_zone_flush(mayberaw); - if (result != ISC_R_SUCCESS) - msg = "Flushing the zone updates to " - "disk failed."; - } - if (result == ISC_R_SUCCESS) - dns_zone_setupdatedisabled(mayberaw, freeze); - } else { - if (frozen) { - result = dns_zone_loadandthaw(mayberaw); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_UPTODATE: - msg = "The zone reload and thaw was " - "successful."; - result = ISC_R_SUCCESS; - break; - case DNS_R_CONTINUE: - msg = "A zone reload and thaw was started.\n" - "Check the logs to see the result."; - result = ISC_R_SUCCESS; - break; - } - } - } - isc_task_endexclusive(server->task); - - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - - view = dns_zone_getview(mayberaw); - if (strcmp(view->name, "_default") == 0 || - strcmp(view->name, "_bind") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(mayberaw), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(mayberaw), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone '%s/%s'%s%s: %s", - freeze ? "freezing" : "thawing", - zonename, classstr, sep, vname, - isc_result_totext(result)); - dns_zone_detach(&mayberaw); - return (result); -} - -#ifdef HAVE_LIBSCF -/* - * This function adds a message for rndc to echo if named - * is managed by smf and is also running chroot. - */ -isc_result_t -ns_smf_add_message(isc_buffer_t **text) { - return (putstr(text, "use svcadm(1M) to manage named")); -} -#endif /* HAVE_LIBSCF */ - -#ifndef HAVE_LMDB - -/* - * Emit a comment at the top of the nzf file containing the viewname - * Expects the fp to already be open for writing - */ -#define HEADER1 "# New zone file for view: " -#define HEADER2 "\n# This file contains configuration for zones added by\n" \ - "# the 'rndc addzone' command. DO NOT EDIT BY HAND.\n" -static isc_result_t -add_comment(FILE *fp, const char *viewname) { - isc_result_t result; - CHECK(isc_stdio_write(HEADER1, sizeof(HEADER1) - 1, 1, fp, NULL)); - CHECK(isc_stdio_write(viewname, strlen(viewname), 1, fp, NULL)); - CHECK(isc_stdio_write(HEADER2, sizeof(HEADER2) - 1, 1, fp, NULL)); - cleanup: - return (result); -} - -static void -dumpzone(void *arg, const char *buf, int len) { - FILE *fp = arg; - - (void) isc_stdio_write(buf, len, 1, fp, NULL); -} - -static isc_result_t -nzf_append(dns_view_t *view, const cfg_obj_t *zconfig) { - isc_result_t result; - off_t offset; - FILE *fp = NULL; - bool offsetok = false; - - LOCK(&view->new_zone_lock); - - CHECK(isc_stdio_open(view->new_zone_file, "a", &fp)); - CHECK(isc_stdio_seek(fp, 0, SEEK_END)); - - CHECK(isc_stdio_tell(fp, &offset)); - offsetok = true; - if (offset == 0) - CHECK(add_comment(fp, view->name)); - - CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL)); - cfg_printx(zconfig, CFG_PRINTER_ONELINE, dumpzone, fp); - CHECK(isc_stdio_write(";\n", 2, 1, fp, NULL)); - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - - cleanup: - if (fp != NULL) { - (void)isc_stdio_close(fp); - if (offsetok) { - isc_result_t result2; - - result2 = isc_file_truncate(view->new_zone_file, - offset); - if (result2 != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error truncating NZF file '%s' " - "during rollback from append: " - "%s", - view->new_zone_file, - isc_result_totext(result2)); - } - } - } - UNLOCK(&view->new_zone_lock); - return (result); -} - -static isc_result_t -nzf_writeconf(const cfg_obj_t *config, dns_view_t *view) { - const cfg_obj_t *zl = NULL; - cfg_list_t *list; - const cfg_listelt_t *elt; - - FILE *fp = NULL; - char tmp[1024]; - isc_result_t result; - - result = isc_file_template("", "nzf-XXXXXXXX", tmp, sizeof(tmp)); - if (result == ISC_R_SUCCESS) - result = isc_file_openunique(tmp, &fp); - if (result != ISC_R_SUCCESS) - return (result); - - cfg_map_get(config, "zone", &zl); - if (!cfg_obj_islist(zl)) - CHECK(ISC_R_FAILURE); - - DE_CONST(&zl->value.list, list); - - CHECK(add_comment(fp, view->name)); /* force a comment */ - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(elt); - - CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL)); - cfg_printx(zconfig, CFG_PRINTER_ONELINE, dumpzone, fp); - CHECK(isc_stdio_write(";\n", 2, 1, fp, NULL)); - } - - CHECK(isc_stdio_flush(fp)); - result = isc_stdio_close(fp); - fp = NULL; - if (result != ISC_R_SUCCESS) - goto cleanup; - CHECK(isc_file_rename(tmp, view->new_zone_file)); - return (result); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - (void)isc_file_remove(tmp); - return (result); -} - -#else /* HAVE_LMDB */ - -static void -nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen) { - dns_fixedname_t fixed; - - dns_fixedname_init(&fixed); - dns_name_downcase(name, dns_fixedname_name(&fixed), NULL); - dns_name_format(dns_fixedname_name(&fixed), namebuf, buflen); - - key->mv_data = namebuf; - key->mv_size = strlen(namebuf); -} - -static void -dumpzone(void *arg, const char *buf, int len) { - ns_dzarg_t *dzarg = arg; - isc_result_t result; - - REQUIRE(dzarg != NULL && ISC_MAGIC_VALID(dzarg, DZARG_MAGIC)); - - result = putmem(dzarg->text, buf, len); - if (result != ISC_R_SUCCESS && dzarg->result == ISC_R_SUCCESS) { - dzarg->result = result; - } -} - -static isc_result_t -nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone, - const cfg_obj_t *zconfig) -{ - isc_result_t result; - int status; - dns_view_t *view; - bool commit = false; - isc_buffer_t *text = NULL; - char namebuf[1024]; - MDB_val key, data; - ns_dzarg_t dzarg; - - view = dns_zone_getview(zone); - - nzd_setkey(&key, dns_zone_getorigin(zone), namebuf, sizeof(namebuf)); - - if (zconfig == NULL) { - /* We're deleting the zone from the database */ - status = mdb_del(*txnp, dbi, &key, NULL); - if (status != MDB_SUCCESS && status != MDB_NOTFOUND) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error deleting zone %s " - "from NZD database: %s", - namebuf, mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } else if (status != MDB_NOTFOUND) { - commit = true; - } - } else { - /* We're creating or overwriting the zone */ - const cfg_obj_t *zoptions; - - result = isc_buffer_allocate(view->mctx, &text, 256); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Unable to allocate buffer in " - "nzd_save(): %s", - isc_result_totext(result)); - goto cleanup; - } - - zoptions = cfg_tuple_get(zconfig, "options"); - if (zoptions == NULL) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Unable to get options from config in " - "nzd_save()"); - result = ISC_R_FAILURE; - goto cleanup; - } - - dzarg.magic = DZARG_MAGIC; - dzarg.text = &text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg); - if (dzarg.result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error writing zone config to " - "buffer in nzd_save(): %s", - isc_result_totext(result)); - result = dzarg.result; - goto cleanup; - } - - data.mv_data = isc_buffer_base(text); - data.mv_size = isc_buffer_usedlength(text); - - status = mdb_put(*txnp, dbi, &key, &data, 0); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error inserting zone in " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - commit = true; - } - - result = ISC_R_SUCCESS; - - cleanup: - if (!commit || result != ISC_R_SUCCESS) { - (void) mdb_txn_abort(*txnp); - } else { - status = mdb_txn_commit(*txnp); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error committing " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - } - } - *txnp = NULL; - - if (text != NULL) { - isc_buffer_free(&text); - } - - return (result); -} - -/* - * Check whether the new zone database for 'view' can be opened for writing. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_writable(dns_view_t *view) { - isc_result_t result = ISC_R_SUCCESS; - int status; - MDB_dbi dbi; - MDB_txn *txn = NULL; - - REQUIRE(view != NULL); - - status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0, 0, &txn); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_txn_begin: %s", - mdb_strerror(status)); - return (ISC_R_FAILURE); - } - - status = mdb_dbi_open(txn, NULL, 0, &dbi); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_dbi_open: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - } - - mdb_txn_abort(txn); - return (result); -} - -/* - * Open the new zone database for 'view' and start a transaction for it. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) { - int status; - MDB_txn *txn = NULL; - - REQUIRE(view != NULL); - REQUIRE(txnp != NULL && *txnp == NULL); - REQUIRE(dbi != NULL); - - status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0, - flags, &txn); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_txn_begin: %s", - mdb_strerror(status)); - goto cleanup; - } - - status = mdb_dbi_open(txn, NULL, 0, dbi); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_dbi_open: %s", - mdb_strerror(status)); - goto cleanup; - } - - *txnp = txn; - - cleanup: - if (status != MDB_SUCCESS) { - if (txn != NULL) { - mdb_txn_abort(txn); - } - return (ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); -} - -/* - * nzd_env_close() and nzd_env_reopen are a kluge to address the - * problem of an NZD file possibly being created before we drop - * root privileges. - */ -static void -nzd_env_close(dns_view_t *view) { - const char *dbpath = NULL; - char dbpath_copy[PATH_MAX]; - char lockpath[PATH_MAX]; - int status, ret; - - if (view->new_zone_dbenv == NULL) { - return; - } - - status = mdb_env_get_path(view->new_zone_dbenv, &dbpath); - INSIST(status == MDB_SUCCESS); - snprintf(lockpath, sizeof(lockpath), "%s-lock", dbpath); - strlcpy(dbpath_copy, dbpath, sizeof(dbpath_copy)); - mdb_env_close((MDB_env *) view->new_zone_dbenv); - - /* - * Database files must be owned by the eventual user, not by root. - */ - ret = chown(dbpath_copy, ns_os_uid(), -1); - UNUSED(ret); - - /* - * Some platforms need the lockfile not to exist when we reopen the - * environment. - */ - (void) isc_file_remove(lockpath); - - view->new_zone_dbenv = NULL; -} - -static isc_result_t -nzd_env_reopen(dns_view_t *view) { - isc_result_t result; - MDB_env *env = NULL; - int status; - - if (view->new_zone_db == NULL) { - return (ISC_R_SUCCESS); - } - - nzd_env_close(view); - - status = mdb_env_create(&env); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_create failed: %s", - mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - - if (view->new_zone_mapsize != 0ULL) { - status = mdb_env_set_mapsize(env, view->new_zone_mapsize); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_set_mapsize failed: %s", - mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - } - - status = mdb_env_open(env, view->new_zone_db, DNS_LMDB_FLAGS, 0600); - if (status != MDB_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, - "mdb_env_open of '%s' failed: %s", - view->new_zone_db, mdb_strerror(status)); - CHECK(ISC_R_FAILURE); - } - - view->new_zone_dbenv = env; - env = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (env != NULL) { - mdb_env_close(env); - } - return (result); -} - -/* - * If 'commit' is true, commit the new zone database transaction pointed to by - * 'txnp'; otherwise, abort that transaction. - * - * Caller must hold 'view->new_zone_lock' for the view that the transaction - * pointed to by 'txnp' was started for. - */ -static isc_result_t -nzd_close(MDB_txn **txnp, bool commit) { - isc_result_t result = ISC_R_SUCCESS; - int status; - - REQUIRE(txnp != NULL); - - if (*txnp != NULL) { - if (commit) { - status = mdb_txn_commit(*txnp); - if (status != MDB_SUCCESS) { - result = ISC_R_FAILURE; - } - } else { - mdb_txn_abort(*txnp); - } - *txnp = NULL; - } - - return (result); -} - -/* - * Count the zones configured in the new zone database for 'view' and store the - * result in 'countp'. - * - * Caller must hold 'view->new_zone_lock'. - */ -static isc_result_t -nzd_count(dns_view_t *view, int *countp) { - isc_result_t result; - int status; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_stat statbuf; - - REQUIRE(countp != NULL); - - result = nzd_open(view, MDB_RDONLY, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - status = mdb_stat(txn, dbi, &statbuf); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, "mdb_stat: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - *countp = statbuf.ms_entries; - - cleanup: - (void) nzd_close(&txn, false); - - return (result); -} - -/* - * Migrate zone configuration from an NZF file to an NZD database. - * Caller must hold view->new_zone_lock. - */ -static isc_result_t -migrate_nzf(dns_view_t *view) { - isc_result_t result; - cfg_obj_t *nzf_config = NULL; - int status, n; - isc_buffer_t *text = NULL; - bool commit = false; - const cfg_obj_t *zonelist; - const cfg_listelt_t *element; - char tempname[PATH_MAX]; - MDB_txn *txn = NULL; - MDB_dbi dbi; - MDB_val key, data; - ns_dzarg_t dzarg; - - /* - * If NZF file doesn't exist, or NZD DB exists and already - * has data, return without attempting migration. - */ - if (!isc_file_exists(view->new_zone_file)) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - result = nzd_count(view, &n); - if (result == ISC_R_SUCCESS && n > 0) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "Migrating zones from NZF file '%s' to " - "NZD database '%s'", - view->new_zone_file, view->new_zone_db); - /* - * Instead of blindly copying lines, we parse the NZF file using - * the configuration parser, because it validates it against the - * config type, giving us a guarantee that valid configuration - * will be written to DB. - */ - cfg_parser_reset(ns_g_addparser); - result = cfg_parse_file(ns_g_addparser, view->new_zone_file, - &cfg_type_addzoneconf, &nzf_config); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error parsing NZF file '%s': %s", - view->new_zone_file, - isc_result_totext(result)); - goto cleanup; - } - - zonelist = NULL; - CHECK(cfg_map_get(nzf_config, "zone", &zonelist)); - if (!cfg_obj_islist(zonelist)) { - CHECK(ISC_R_FAILURE); - } - - CHECK(nzd_open(view, 0, &txn, &dbi)); - - CHECK(isc_buffer_allocate(view->mctx, &text, 256)); - - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig; - const cfg_obj_t *zoptions; - char zname[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fname; - dns_name_t *name; - const char *origin; - isc_buffer_t b; - - zconfig = cfg_listelt_value(element); - - origin = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - if (origin == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - /* Normalize zone name */ - isc_buffer_constinit(&b, origin, strlen(origin)); - isc_buffer_add(&b, strlen(origin)); - name = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - DNS_NAME_DOWNCASE, NULL)); - dns_name_format(name, zname, sizeof(zname)); - - key.mv_data = zname; - key.mv_size = strlen(zname); - - zoptions = cfg_tuple_get(zconfig, "options"); - if (zoptions == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - isc_buffer_clear(text); - dzarg.magic = DZARG_MAGIC; - dzarg.text = &text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg); - if (dzarg.result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error writing zone config to " - "buffer in migrate_nzf(): %s", - isc_result_totext(result)); - result = dzarg.result; - goto cleanup; - } - - data.mv_data = isc_buffer_base(text); - data.mv_size = isc_buffer_usedlength(text); - - status = mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE); - if (status != MDB_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "Error inserting zone in " - "NZD database: %s", - mdb_strerror(status)); - result = ISC_R_FAILURE; - goto cleanup; - } - - commit = true; - } - - result = ISC_R_SUCCESS; - - /* - * Leaving the NZF file in place is harmless as we won't use it - * if an NZD database is found for the view. But we rename NZF file - * to a backup name here. - */ - strlcpy(tempname, view->new_zone_file, sizeof(tempname)); - if (strlen(tempname) < sizeof(tempname) - 1) { - strlcat(tempname, "~", sizeof(tempname)); - isc_file_rename(view->new_zone_file, tempname); - } - - cleanup: - if (result != ISC_R_SUCCESS) { - (void) nzd_close(&txn, false); - } else { - result = nzd_close(&txn, commit); - } - - if (text != NULL) { - isc_buffer_free(&text); - } - - if (nzf_config != NULL) { - cfg_obj_destroy(ns_g_addparser, &nzf_config); - } - - return (result); -} - -#endif /* HAVE_LMDB */ - -static isc_result_t -newzone_parse(ns_server_t *server, char *command, dns_view_t **viewp, - cfg_obj_t **zoneconfp, const cfg_obj_t **zoneobjp, - isc_buffer_t **text) -{ - isc_result_t result; - isc_buffer_t argbuf; - cfg_obj_t *zoneconf = NULL; - const cfg_obj_t *zlist = NULL; - const cfg_obj_t *zoneobj = NULL; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *obj = NULL; - const char *viewname = NULL; - dns_rdataclass_t rdclass; - dns_view_t *view = NULL; - const char *bn = NULL; - - REQUIRE(viewp != NULL && *viewp == NULL); - REQUIRE(zoneobjp != NULL && *zoneobjp == NULL); - REQUIRE(zoneconfp != NULL && *zoneconfp == NULL); - - /* Try to parse the argument string */ - isc_buffer_init(&argbuf, command, (unsigned int) strlen(command)); - isc_buffer_add(&argbuf, strlen(command)); - - if (strncasecmp(command, "add", 3) == 0) { - bn = "addzone"; - } else if (strncasecmp(command, "mod", 3) == 0) { - bn = "modzone"; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - /* - * Convert the "addzone" or "modzone" to just "zone", for - * the benefit of the parser - */ - isc_buffer_forward(&argbuf, 3); - - cfg_parser_reset(ns_g_addparser); - CHECK(cfg_parse_buffer3(ns_g_addparser, &argbuf, bn, 0, - &cfg_type_addzoneconf, &zoneconf)); - CHECK(cfg_map_get(zoneconf, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - /* For now we only support adding one zone at a time */ - zoneobj = cfg_listelt_value(cfg_list_first(zlist)); - - /* Check the zone type for ones that are not supported by addzone. */ - zoptions = cfg_tuple_get(zoneobj, "options"); - - obj = NULL; - (void)cfg_map_get(zoptions, "type", &obj); - if (obj == NULL) { - (void) cfg_map_get(zoptions, "in-view", &obj); - if (obj != NULL) { - (void) putstr(text, - "'in-view' zones not supported by "); - (void) putstr(text, bn); - } else - (void) putstr(text, "zone type not specified"); - CHECK(ISC_R_FAILURE); - } - - if (strcasecmp(cfg_obj_asstring(obj), "hint") == 0 || - strcasecmp(cfg_obj_asstring(obj), "forward") == 0 || - strcasecmp(cfg_obj_asstring(obj), "redirect") == 0 || - strcasecmp(cfg_obj_asstring(obj), "delegation-only") == 0) - { - (void) putstr(text, "'"); - (void) putstr(text, cfg_obj_asstring(obj)); - (void) putstr(text, "' zones not supported by "); - (void) putstr(text, bn); - CHECK(ISC_R_FAILURE); - } - - /* Make sense of optional class argument */ - obj = cfg_tuple_get(zoneobj, "class"); - CHECK(ns_config_getclass(obj, dns_rdataclass_in, &rdclass)); - - /* Make sense of optional view argument */ - obj = cfg_tuple_get(zoneobj, "view"); - if (obj && cfg_obj_isstring(obj)) - viewname = cfg_obj_asstring(obj); - if (viewname == NULL || *viewname == '\0') - viewname = "_default"; - result = dns_viewlist_find(&server->viewlist, viewname, rdclass, - &view); - if (result == ISC_R_NOTFOUND) { - (void) putstr(text, "no matching view found for '"); - (void) putstr(text, viewname); - (void) putstr(text, "'"); - goto cleanup; - } else if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - *viewp = view; - *zoneobjp = zoneobj; - *zoneconfp = zoneconf; - - return (ISC_R_SUCCESS); - - cleanup: - if (zoneconf != NULL) - cfg_obj_destroy(ns_g_addparser, &zoneconf); - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -static isc_result_t -delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, - const cfg_obj_t *config, const dns_name_t *zname, - nzfwriter_t nzfwriter) -{ - isc_result_t result = ISC_R_NOTFOUND; - const cfg_listelt_t *elt = NULL; - const cfg_obj_t *zl = NULL; - cfg_list_t *list; - dns_fixedname_t myfixed; - dns_name_t *myname; - - REQUIRE(view != NULL); - REQUIRE(pctx != NULL); - REQUIRE(config != NULL); - REQUIRE(zname != NULL); - - LOCK(&view->new_zone_lock); - - cfg_map_get(config, "zone", &zl); - - if (!cfg_obj_islist(zl)) - CHECK(ISC_R_FAILURE); - - DE_CONST(&zl->value.list, list); - - myname = dns_fixedname_initname(&myfixed); - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) - { - const cfg_obj_t *zconf = cfg_listelt_value(elt); - const char *zn; - cfg_listelt_t *e; - - zn = cfg_obj_asstring(cfg_tuple_get(zconf, "name")); - result = dns_name_fromstring(myname, zn, 0, NULL); - if (result != ISC_R_SUCCESS || - !dns_name_equal(zname, myname)) - continue; - - DE_CONST(elt, e); - ISC_LIST_UNLINK(*list, e, link); - cfg_obj_destroy(pctx, &e->obj); - isc_mem_put(pctx->mctx, e, sizeof(*e)); - result = ISC_R_SUCCESS; - break; - } - - /* - * Write config to NZF file if appropriate - */ - if (nzfwriter != NULL && view->new_zone_file != NULL) - result = nzfwriter(config, view); - - cleanup: - UNLOCK(&view->new_zone_lock); - return (result); -} - -static isc_result_t -do_addzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, - dns_name_t *name, cfg_obj_t *zoneconf, const cfg_obj_t *zoneobj, - isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *zone = NULL; -#ifndef HAVE_LMDB - FILE *fp = NULL; - bool cleanup_config = false; -#else /* HAVE_LMDB */ - MDB_txn *txn = NULL; - MDB_dbi dbi; - - UNUSED(zoneconf); - LOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - /* Zone shouldn't already exist */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result == ISC_R_SUCCESS) { - result = ISC_R_EXISTS; - goto cleanup; - } else if (result == DNS_R_PARTIALMATCH) { - /* Create our sub-zone anyway */ - dns_zone_detach(&zone); - zone = NULL; - } else if (result != ISC_R_NOTFOUND) - goto cleanup; - -#ifndef HAVE_LMDB - /* - * Make sure we can open the configuration save file - */ - result = isc_stdio_open(view->new_zone_file, "a", &fp); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to create '")); - TCHECK(putstr(text, view->new_zone_file)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - (void)isc_stdio_close(fp); - fp = NULL; -#else /* HAVE_LMDB */ - /* Make sure we can open the NZD database */ - result = nzd_writable(view); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open NZD database for '")); - TCHECK(putstr(text, view->new_zone_db)); - TCHECK(putstr(text, "'")); - result = ISC_R_FAILURE; - goto cleanup; - } -#endif /* HAVE_LMDB */ - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* Mark view unfrozen and configure zone */ - dns_view_thaw(view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - server->mctx, view, &server->viewlist, - cfg->actx, true, false, false); - dns_view_freeze(view); - - isc_task_endexclusive(server->task); - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "configure_zone failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - /* Is it there yet? */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "added new zone was not found: %s", - isc_result_totext(result)); - goto cleanup; - } - -#ifndef HAVE_LMDB - /* - * If there wasn't a previous newzone config, just save the one - * we've created. If there was a previous one, merge the new - * zone into it. - */ - if (cfg->nzf_config == NULL) { - cfg_obj_attach(zoneconf, &cfg->nzf_config); - } else { - cfg_obj_t *z; - DE_CONST(zoneobj, z); - CHECK(cfg_parser_mapadd(cfg->add_parser, - cfg->nzf_config, z, "zone")); - } - cleanup_config = true; -#endif /* HAVE_LMDB */ - - /* - * Load the zone from the master file. If this fails, we'll - * need to undo the configuration we've done already. - */ - result = dns_zone_loadnew(zone); - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - - TCHECK(putstr(text, "dns_zone_loadnew failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "addzone failed; reverting."); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(view->zonetable, zone); - goto cleanup; - } - - /* Flag the zone as having been added at runtime */ - dns_zone_setadded(zone, true); - -#ifdef HAVE_LMDB - /* Save the new zone configuration into the NZD */ - CHECK(nzd_open(view, 0, &txn, &dbi)); - CHECK(nzd_save(&txn, dbi, zone, zoneobj)); -#else - /* Append the zone configuration to the NZF */ - result = nzf_append(view, zoneobj); -#endif /* HAVE_LMDB */ - - cleanup: - -#ifndef HAVE_LMDB - if (fp != NULL) - (void)isc_stdio_close(fp); - if (result != ISC_R_SUCCESS && cleanup_config) { - tresult = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, name, - NULL); - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); - } -#else /* HAVE_LMDB */ - if (txn != NULL) - (void) nzd_close(&txn, false); - UNLOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -static isc_result_t -do_modzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, - dns_name_t *name, const char *zname, const cfg_obj_t *zoneobj, - isc_buffer_t **text) -{ - isc_result_t result, tresult; - dns_zone_t *zone = NULL; - bool added; - bool exclusive = false; -#ifndef HAVE_LMDB - FILE *fp = NULL; - cfg_obj_t *z; -#else /* HAVE_LMDB */ - MDB_txn *txn = NULL; - MDB_dbi dbi; - LOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - /* Zone must already exist */ - result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - added = dns_zone_getadded(zone); - dns_zone_detach(&zone); - -#ifndef HAVE_LMDB - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - TCHECK(putstr(text, "new zone config is not set")); - CHECK(ISC_R_FAILURE); - } -#endif - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - -#ifndef HAVE_LMDB - /* Make sure we can open the configuration save file */ - result = isc_stdio_open(view->new_zone_file, "a", &fp); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open '")); - TCHECK(putstr(text, view->new_zone_file)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - (void)isc_stdio_close(fp); - fp = NULL; -#else /* HAVE_LMDB */ - /* Make sure we can open the NZD database */ - result = nzd_writable(view); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "unable to open NZD database for '")); - TCHECK(putstr(text, view->new_zone_db)); - TCHECK(putstr(text, "'")); - result = ISC_R_FAILURE; - goto cleanup; - } -#endif /* HAVE_LMDB */ - - /* Reconfigure the zone */ - dns_view_thaw(view); - result = configure_zone(cfg->config, zoneobj, cfg->vconfig, - server->mctx, view, &server->viewlist, - cfg->actx, true, false, true); - dns_view_freeze(view); - - exclusive = false; - isc_task_endexclusive(server->task); - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "configure_zone failed: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - - /* Is it there yet? */ - CHECK(dns_zt_find(view->zonetable, name, 0, NULL, &zone)); - -#ifndef HAVE_LMDB - /* Remove old zone from configuration (and NZF file if applicable) */ - if (added) { - result = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, - dns_zone_getorigin(zone), - nzf_writeconf); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "former zone configuration " - "not deleted: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - } -#endif /* HAVE_LMDB */ - - if (!added) { - if (cfg->vconfig == NULL) { - result = delete_zoneconf(view, cfg->conf_parser, - cfg->config, - dns_zone_getorigin(zone), - NULL); - } else { - const cfg_obj_t *voptions = - cfg_tuple_get(cfg->vconfig, "options"); - result = delete_zoneconf(view, cfg->conf_parser, - voptions, - dns_zone_getorigin(zone), - NULL); - } - - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "former zone configuration " - "not deleted: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } - } - - /* Load the zone from the master file if it needs reloading. */ - result = dns_zone_loadnew(zone); - - /* - * Dynamic zones need no reloading, so we can pass this result. - */ - if (result == DNS_R_DYNAMIC) - result = ISC_R_SUCCESS; - - if (result != ISC_R_SUCCESS) { - dns_db_t *dbp = NULL; - - TCHECK(putstr(text, "failed to load zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "': ")); - TCHECK(putstr(text, isc_result_totext(result))); - TCHECK(putstr(text, "\nThe zone is no longer being served. ")); - TCHECK(putstr(text, "Use 'rndc addzone' to correct\n")); - TCHECK(putstr(text, "the problem and restore service.")); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "modzone failed; removing zone."); - - /* If the zone loaded partially, unload it */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Remove the zone from the zone table */ - dns_zt_unmount(view->zonetable, zone); - goto cleanup; - } - -#ifndef HAVE_LMDB - /* Store the new zone configuration; also in NZF if applicable */ - DE_CONST(zoneobj, z); - CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z, "zone")); -#endif /* HAVE_LMDB */ - - if (added) { -#ifdef HAVE_LMDB - CHECK(nzd_open(view, 0, &txn, &dbi)); - CHECK(nzd_save(&txn, dbi, zone, zoneobj)); -#else - result = nzf_append(view, zoneobj); - if (result != ISC_R_SUCCESS) { - TCHECK(putstr(text, "\nNew zone config not saved: ")); - TCHECK(putstr(text, isc_result_totext(result))); - goto cleanup; - } -#endif /* HAVE_LMDB */ - - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "' reconfigured.")); - - } else { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zname)); - TCHECK(putstr(text, "' must also be reconfigured in\n")); - TCHECK(putstr(text, "named.conf to make changes permanent.")); - } - - cleanup: - if (exclusive) - isc_task_endexclusive(server->task); - -#ifndef HAVE_LMDB - if (fp != NULL) - (void)isc_stdio_close(fp); -#else /* HAVE_LMDB */ - if (txn != NULL) - (void) nzd_close(&txn, false); - UNLOCK(&view->new_zone_lock); -#endif /* HAVE_LMDB */ - - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -/* - * Act on an "addzone" or "modzone" command from the command channel. - */ -isc_result_t -ns_server_changezone(ns_server_t *server, char *command, isc_buffer_t **text) { - isc_result_t result; - bool addzone; - ns_cfgctx_t *cfg = NULL; - cfg_obj_t *zoneconf = NULL; - const cfg_obj_t *zoneobj = NULL; - const char *zonename; - dns_view_t *view = NULL; - isc_buffer_t buf; - dns_fixedname_t fname; - dns_name_t *dnsname; - - if (strncasecmp(command, "add", 3) == 0) - addzone = true; - else { - INSIST(strncasecmp(command, "mod", 3) == 0); - addzone = false; - } - - CHECK(newzone_parse(server, command, &view, &zoneconf, - &zoneobj, text)); - - /* Are we accepting new zones in this view? */ -#ifdef HAVE_LMDB - if (view->new_zone_db == NULL) -#else - if (view->new_zone_file == NULL) -#endif /* HAVE_LMDB */ - { - (void) putstr(text, "Not allowing new zones in view '"); - (void) putstr(text, view->name); - (void) putstr(text, "'"); - result = ISC_R_NOPERM; - goto cleanup; - } - - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - zonename = cfg_obj_asstring(cfg_tuple_get(zoneobj, "name")); - isc_buffer_constinit(&buf, zonename, strlen(zonename)); - isc_buffer_add(&buf, strlen(zonename)); - - dnsname = dns_fixedname_initname(&fname); - CHECK(dns_name_fromtext(dnsname, &buf, dns_rootname, 0, NULL)); - - if (addzone) - CHECK(do_addzone(server, cfg, view, dnsname, zoneconf, - zoneobj, text)); - else - CHECK(do_modzone(server, cfg, view, dnsname, zonename, - zoneobj, text)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone %s in view %s via %s", - addzone ? "added" : "updated", - zonename, view->name, - addzone ? NS_COMMAND_ADDZONE : NS_COMMAND_MODZONE); - - /* Changing a zone counts as reconfiguration */ - CHECK(isc_time_now(&ns_g_configtime)); - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (zoneconf != NULL) - cfg_obj_destroy(ns_g_addparser, &zoneconf); - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -static bool -inuse(const char* file, bool first, isc_buffer_t **text) { - if (file != NULL && isc_file_exists(file)) { - if (first) - (void) putstr(text, - "The following files were in use " - "and may now be removed:\n"); - else - (void) putstr(text, "\n"); - (void) putstr(text, file); - (void) putnull(text); - return (false); - } - return (first); -} - -typedef struct { - dns_zone_t *zone; - bool cleanup; -} ns_dzctx_t; - -/* - * Carry out a zone deletion scheduled by ns_server_delzone(). - */ -static void -rmzone(isc_task_t *task, isc_event_t *event) { - ns_dzctx_t *dz = (ns_dzctx_t *)event->ev_arg; - dns_zone_t *zone, *raw = NULL, *mayberaw; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - ns_cfgctx_t *cfg; - dns_db_t *dbp = NULL; - bool added; - isc_result_t result; -#ifdef HAVE_LMDB - MDB_txn *txn = NULL; - MDB_dbi dbi; -#endif - - REQUIRE(dz != NULL); - - isc_event_free(&event); - - /* Dig out configuration for this zone */ - zone = dz->zone; - view = dns_zone_getview(zone); - cfg = (ns_cfgctx_t *) view->new_zone_config; - dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "deleting zone %s in view %s via delzone", - zonename, view->name); - - /* Remove the zone from configuration (and NZF file if applicable) */ - added = dns_zone_getadded(zone); - - if (added && cfg != NULL) { -#ifdef HAVE_LMDB - /* Make sure we can open the NZD database */ - LOCK(&view->new_zone_lock); - result = nzd_open(view, 0, &txn, &dbi); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "unable to open NZD database for '%s'", - view->new_zone_db); - } else { - result = nzd_save(&txn, dbi, zone, NULL); - } - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } - - if (txn != NULL) { - (void)nzd_close(&txn, false); - } - UNLOCK(&view->new_zone_lock); -#else - result = delete_zoneconf(view, cfg->add_parser, - cfg->nzf_config, - dns_zone_getorigin(zone), - nzf_writeconf); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } -#endif /* HAVE_LMDB */ - } - - if (!added && cfg != NULL) { - if (cfg->vconfig != NULL) { - const cfg_obj_t *voptions = - cfg_tuple_get(cfg->vconfig, "options"); - result = delete_zoneconf(view, cfg->conf_parser, - voptions, - dns_zone_getorigin(zone), - NULL); - } else { - result = delete_zoneconf(view, cfg->conf_parser, - cfg->config, - dns_zone_getorigin(zone), - NULL); - } - if (result != ISC_R_SUCCESS){ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "unable to " - "delete zone configuration: %s", - isc_result_totext(result)); - } - } - - /* Unload zone database */ - if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { - dns_db_detach(&dbp); - dns_zone_unload(zone); - } - - /* Clean up stub/slave zone files if requested to do so */ - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - if (added && dz->cleanup) { - const char *file; - - file = dns_zone_getfile(mayberaw); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - file = dns_zone_getjournal(mayberaw); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - if (zone != mayberaw) { - file = dns_zone_getfile(zone); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - - file = dns_zone_getjournal(zone); - result = isc_file_remove(file); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "file %s not removed: %s", - file, isc_result_totext(result)); - } - } - } - - if (raw != NULL) - dns_zone_detach(&raw); - dns_zone_detach(&zone); - isc_mem_put(ns_g_mctx, dz, sizeof(*dz)); - isc_task_detach(&task); -} - -/* - * Act on a "delzone" command from the command channel. - */ -isc_result_t -ns_server_delzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result, tresult; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - dns_zone_t *mayberaw; - dns_view_t *view = NULL; - char zonename[DNS_NAME_FORMATSIZE]; - bool cleanup = false; - const char *ptr; - bool added; - ns_dzctx_t *dz = NULL; - isc_event_t *dzevent = NULL; - isc_task_t *task = NULL; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcmp(ptr, "-clean") == 0 || strcmp(ptr, "-clear") == 0) { - cleanup = true; - ptr = next_token(lex, text); - } - - CHECK(zone_from_args(server, lex, ptr, &zone, zonename, - text, false)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - INSIST(zonename != NULL); - - /* Is this a policy zone? */ - if (dns_zone_get_rpz_num(zone) != DNS_RPZ_INVALID_NUM) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, - "' cannot be deleted: response-policy zone.")); - result = ISC_R_FAILURE; - goto cleanup; - } - - view = dns_zone_getview(zone); - CHECK(dns_zt_unmount(view->zonetable, zone)); - - /* Send cleanup event */ - dz = isc_mem_get(ns_g_mctx, sizeof(*dz)); - if (dz == NULL) - CHECK(ISC_R_NOMEMORY); - - dz->cleanup = cleanup; - dz->zone = NULL; - dns_zone_attach(zone, &dz->zone); - dzevent = isc_event_allocate(ns_g_mctx, server, NS_EVENT_DELZONE, - rmzone, dz, sizeof(isc_event_t)); - if (dzevent == NULL) - CHECK(ISC_R_NOMEMORY); - - dns_zone_gettask(zone, &task); - isc_task_send(task, &dzevent); - dz = NULL; - - /* Inform user about cleaning up stub/slave zone files */ - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - - added = dns_zone_getadded(zone); - if (!added) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, - "' is no longer active and will be deleted.\n")); - TCHECK(putstr(text, "To keep it from returning ")); - TCHECK(putstr(text, "when the server is restarted, it\n")); - TCHECK(putstr(text, "must also be removed from named.conf.")); - } else if (cleanup) { - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, "' and associated files will be deleted.")); - } else if (dns_zone_gettype(mayberaw) == dns_zone_slave || - dns_zone_gettype(mayberaw) == dns_zone_stub) - { - bool first; - const char *file; - - TCHECK(putstr(text, "zone '")); - TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, "' will be deleted.")); - - file = dns_zone_getfile(mayberaw); - first = inuse(file, true, text); - - file = dns_zone_getjournal(mayberaw); - first = inuse(file, first, text); - - if (zone != mayberaw) { - file = dns_zone_getfile(zone); - first = inuse(file, first, text); - - file = dns_zone_getjournal(zone); - (void) inuse(file, first, text); - } - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "zone %s scheduled for removal via delzone", zonename); - - /* Removing a zone counts as reconfiguration */ - CHECK(isc_time_now(&ns_g_configtime)); - - result = ISC_R_SUCCESS; - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (raw != NULL) - dns_zone_detach(&raw); - if (zone != NULL) - dns_zone_detach(&zone); - if (dz != NULL) { - dns_zone_detach(&dz->zone); - isc_mem_put(ns_g_mctx, dz, sizeof(*dz)); - } - - return (result); -} - -static const cfg_obj_t * -find_name_in_list_from_map(const cfg_obj_t *config, - const char *map_key_for_list, - const char *name) -{ - const cfg_obj_t *list = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *obj = NULL; - dns_fixedname_t fixed1, fixed2; - dns_name_t *name1 = NULL, *name2 = NULL; - isc_result_t result; - - if (strcmp(map_key_for_list, "zone") == 0) { - name1 = dns_fixedname_initname(&fixed1); - name2 = dns_fixedname_initname(&fixed2); - result = dns_name_fromstring(name1, name, 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - cfg_map_get(config, map_key_for_list, &list); - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - const char *vname; - - obj = cfg_listelt_value(element); - INSIST(obj != NULL); - vname = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - if (vname == NULL) { - obj = NULL; - continue; - } - - if (name1 != NULL) { - result = dns_name_fromstring(name2, vname, 0, NULL); - if (result == ISC_R_SUCCESS && - dns_name_equal(name1, name2)) - break; - } else if (strcasecmp(vname, name) == 0) - break; - - obj = NULL; - } - - return (obj); -} - -static void -emitzone(void *arg, const char *buf, int len) { - ns_dzarg_t *dzarg = arg; - isc_result_t result; - - REQUIRE(dzarg != NULL && ISC_MAGIC_VALID(dzarg, DZARG_MAGIC)); - result = putmem(dzarg->text, buf, len); - if (result != ISC_R_SUCCESS && dzarg->result == ISC_R_SUCCESS) { - dzarg->result = result; - } -} - -/* - * Act on a "showzone" command from the command channel. - */ -isc_result_t -ns_server_showzone(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result; - const cfg_obj_t *vconfig = NULL, *zconfig = NULL; - char zonename[DNS_NAME_FORMATSIZE]; - const cfg_obj_t *map; - dns_view_t *view = NULL; - dns_zone_t *zone = NULL; - ns_cfgctx_t *cfg = NULL; - bool exclusive = false; -#ifdef HAVE_LMDB - cfg_obj_t *nzconfig = NULL; -#endif /* HAVE_LMDB */ - ns_dzarg_t dzarg; - - /* Parse parameters */ - CHECK(zone_from_args(server, lex, NULL, &zone, zonename, - text, true)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - view = dns_zone_getview(zone); - dns_zone_detach(&zone); - - cfg = (ns_cfgctx_t *) view->new_zone_config; - if (cfg == NULL) { - result = ISC_R_FAILURE; - goto cleanup; - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - exclusive = true; - - /* Find the view statement */ - vconfig = find_name_in_list_from_map(cfg->config, "view", view->name); - - /* Find the zone statement */ - if (vconfig != NULL) - map = cfg_tuple_get(vconfig, "options"); - else - map = cfg->config; - - zconfig = find_name_in_list_from_map(map, "zone", zonename); - -#ifndef HAVE_LMDB - if (zconfig == NULL && cfg->nzf_config != NULL) - zconfig = find_name_in_list_from_map(cfg->nzf_config, - "zone", zonename); -#else /* HAVE_LMDB */ - if (zconfig == NULL) { - const cfg_obj_t *zlist = NULL; - CHECK(get_newzone_config(view, zonename, &nzconfig)); - CHECK(cfg_map_get(nzconfig, "zone", &zlist)); - if (!cfg_obj_islist(zlist)) - CHECK(ISC_R_FAILURE); - - zconfig = cfg_listelt_value(cfg_list_first(zlist)); - } -#endif /* HAVE_LMDB */ - - if (zconfig == NULL) - CHECK(ISC_R_NOTFOUND); - - CHECK(putstr(text, "zone ")); - dzarg.magic = DZARG_MAGIC; - dzarg.text = text; - dzarg.result = ISC_R_SUCCESS; - cfg_printx(zconfig, CFG_PRINTER_ONELINE, emitzone, &dzarg); - CHECK(dzarg.result); - - CHECK(putstr(text, ";")); - - result = ISC_R_SUCCESS; - - cleanup: -#ifdef HAVE_LMDB - if (nzconfig != NULL) - cfg_obj_destroy(ns_g_addparser, &nzconfig); -#endif /* HAVE_LMDB */ - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - if (exclusive) - isc_task_endexclusive(server->task); - - return (result); -} - -static void -newzone_cfgctx_destroy(void **cfgp) { - ns_cfgctx_t *cfg; - - REQUIRE(cfgp != NULL && *cfgp != NULL); - - cfg = *cfgp; - - if (cfg->conf_parser != NULL) { - if (cfg->config != NULL) - cfg_obj_destroy(cfg->conf_parser, &cfg->config); - if (cfg->vconfig != NULL) - cfg_obj_destroy(cfg->conf_parser, &cfg->vconfig); - cfg_parser_destroy(&cfg->conf_parser); - } - if (cfg->add_parser != NULL) { - if (cfg->nzf_config != NULL) - cfg_obj_destroy(cfg->add_parser, &cfg->nzf_config); - cfg_parser_destroy(&cfg->add_parser); - } - - if (cfg->actx != NULL) - cfg_aclconfctx_detach(&cfg->actx); - - isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg)); - *cfgp = NULL; -} - -static isc_result_t -generate_salt(unsigned char *salt, size_t saltlen) { - size_t i, n; - union { - unsigned char rnd[256]; - uint16_t rnd16[128]; - } rnd; - unsigned char text[512 + 1]; - isc_region_t r; - isc_buffer_t buf; - isc_result_t result; - - if (saltlen > 256U) - return (ISC_R_RANGE); - - n = (saltlen + sizeof(uint16_t) - 1) / sizeof(uint16_t); - for (i = 0; i < n; i++) { - rnd.rnd16[i] = isc_rng_random(ns_g_server->rngctx); - } - - memmove(salt, rnd.rnd, saltlen); - - r.base = rnd.rnd; - r.length = (unsigned int) saltlen; - - isc_buffer_init(&buf, text, sizeof(text)); - result = isc_hex_totext(&r, 2, "", &buf); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - text[saltlen * 2] = 0; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "generated salt: %s", text); - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_signing(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - isc_result_t result = ISC_R_SUCCESS; - dns_zone_t *zone = NULL; - dns_name_t *origin; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_dbversion_t *version = NULL; - dns_rdatatype_t privatetype; - dns_rdataset_t privset; - bool first = true; - bool list = false, clear = false; - bool chain = false; - bool setserial = false; - uint32_t serial = 0; - char keystr[DNS_SECALG_FORMATSIZE + 7]; /* <5-digit keyid>/ */ - unsigned short hash = 0, flags = 0, iter = 0, saltlen = 0; - unsigned char salt[255]; - const char *ptr; - size_t n; - - dns_rdataset_init(&privset); - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "-list") == 0) - list = true; - else if ((strcasecmp(ptr, "-clear") == 0) || - (strcasecmp(ptr, "-clean") == 0)) - { - clear = true; - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(keystr, ptr, sizeof(keystr)); - } else if (strcasecmp(ptr, "-nsec3param") == 0) { - char hashbuf[64], flagbuf[64], iterbuf[64]; - char nbuf[256]; - - chain = true; - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "none") == 0) - hash = 0; - else { - strlcpy(hashbuf, ptr, sizeof(hashbuf)); - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(flagbuf, ptr, sizeof(flagbuf)); - - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - strlcpy(iterbuf, ptr, sizeof(iterbuf)); - - n = snprintf(nbuf, sizeof(nbuf), "%s %s %s", - hashbuf, flagbuf, iterbuf); - if (n == sizeof(nbuf)) - return (ISC_R_NOSPACE); - n = sscanf(nbuf, "%hu %hu %hu", &hash, &flags, &iter); - if (n != 3U) - return (ISC_R_BADNUMBER); - - if (hash > 0xffU || flags > 0xffU) - return (ISC_R_RANGE); - - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } else if (strcasecmp(ptr, "auto") == 0) { - /* Auto-generate a random salt. - * XXXMUKS: This currently uses the - * minimum recommended length by RFC - * 5155 (64 bits). It should be made - * configurable. - */ - saltlen = 8; - CHECK(generate_salt(salt, saltlen)); - } else if (strcmp(ptr, "-") != 0) { - isc_buffer_t buf; - - isc_buffer_init(&buf, salt, sizeof(salt)); - CHECK(isc_hex_decodestring(ptr, &buf)); - saltlen = isc_buffer_usedlength(&buf); - } - } - } else if (strcasecmp(ptr, "-serial") == 0) { - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - CHECK(isc_parse_uint32(&serial, ptr, 10)); - setserial = true; - } else - CHECK(DNS_R_SYNTAX); - - CHECK(zone_from_args(server, lex, NULL, &zone, NULL, - text, false)); - if (zone == NULL) - CHECK(ISC_R_UNEXPECTEDEND); - - if (clear) { - CHECK(dns_zone_keydone(zone, keystr)); - (void) putstr(text, "request queued"); - (void) putnull(text); - } else if (chain) { - CHECK(dns_zone_setnsec3param(zone, (uint8_t)hash, - (uint8_t)flags, iter, - (uint8_t)saltlen, salt, - true)); - (void) putstr(text, "nsec3param request queued"); - (void) putnull(text); - } else if (setserial) { - CHECK(dns_zone_setserial(zone, serial)); - (void) putstr(text, "serial request queued"); - (void) putnull(text); - } else if (list) { - privatetype = dns_zone_getprivatetype(zone); - origin = dns_zone_getorigin(zone); - CHECK(dns_zone_getdb(zone, &db)); - CHECK(dns_db_findnode(db, origin, false, &node)); - dns_db_currentversion(db, &version); - - result = dns_db_findrdataset(db, node, version, privatetype, - dns_rdatatype_none, 0, - &privset, NULL); - if (result == ISC_R_NOTFOUND) { - (void) putstr(text, "No signing records found"); - (void) putnull(text); - result = ISC_R_SUCCESS; - goto cleanup; - } - - for (result = dns_rdataset_first(&privset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&privset)) - { - dns_rdata_t priv = DNS_RDATA_INIT; - char output[BUFSIZ]; - isc_buffer_t buf; - - dns_rdataset_current(&privset, &priv); - - isc_buffer_init(&buf, output, sizeof(output)); - CHECK(dns_private_totext(&priv, &buf)); - if (!first) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, output)); - first = false; - } - if (!first) - CHECK(putnull(text)); - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - } - - cleanup: - if (dns_rdataset_isassociated(&privset)) - dns_rdataset_disassociate(&privset); - if (node != NULL) - dns_db_detachnode(db, &node); - if (version != NULL) - dns_db_closeversion(db, &version, false); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -static isc_result_t -putmem(isc_buffer_t **b, const char *str, size_t len) { - isc_result_t result; - - result = isc_buffer_reserve(b, (unsigned int)len); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOSPACE); - - isc_buffer_putmem(*b, (const unsigned char *)str, (unsigned int)len); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -putstr(isc_buffer_t **b, const char *str) { - return (putmem(b, str, strlen(str))); -} - -static isc_result_t -putuint8(isc_buffer_t **b, uint8_t val) { - isc_result_t result; - - result = isc_buffer_reserve(b, 1); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOSPACE); - - isc_buffer_putuint8(*b, val); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -putnull(isc_buffer_t **b) { - return (putuint8(b, 0)); -} - -isc_result_t -ns_server_zonestatus(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_zone_t *zone = NULL, *raw = NULL, *mayberaw = NULL; - const char *type, *file; - char zonename[DNS_NAME_FORMATSIZE]; - uint32_t serial, signed_serial, nodes; - char serbuf[16], sserbuf[16], nodebuf[16]; - char resignbuf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 2]; - char lbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char xbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char kbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char rtbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_t loadtime, expiretime, refreshtime; - isc_time_t refreshkeytime, resigntime; - dns_zonetype_t zonetype; - bool dynamic = false, frozen = false; - bool hasraw = false; - bool secure, maintain, allow; - dns_db_t *db = NULL, *rawdb = NULL; - char **incfiles = NULL; - int nfiles = 0; - - isc_time_settoepoch(&loadtime); - isc_time_settoepoch(&refreshtime); - isc_time_settoepoch(&expiretime); - isc_time_settoepoch(&refreshkeytime); - isc_time_settoepoch(&resigntime); - - CHECK(zone_from_args(server, lex, NULL, &zone, zonename, - text, true)); - if (zone == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - /* Inline signing? */ - CHECK(dns_zone_getdb(zone, &db)); - dns_zone_getraw(zone, &raw); - hasraw = (raw != NULL); - if (hasraw) { - mayberaw = raw; - zonetype = dns_zone_gettype(raw); - CHECK(dns_zone_getdb(raw, &rawdb)); - } else { - mayberaw = zone; - zonetype = dns_zone_gettype(zone); - } - - switch (zonetype) { - case dns_zone_master: - type = "master"; - break; - case dns_zone_slave: - type = "slave"; - break; - case dns_zone_stub: - type = "stub"; - break; - case dns_zone_staticstub: - type = "staticstub"; - break; - case dns_zone_redirect: - type = "redirect"; - break; - case dns_zone_key: - type = "key"; - break; - case dns_zone_dlz: - type = "dlz"; - break; - default: - type = "unknown"; - } - - /* Serial number */ - serial = dns_zone_getserial(mayberaw); - snprintf(serbuf, sizeof(serbuf), "%u", serial); - if (hasraw) { - signed_serial = dns_zone_getserial(zone); - snprintf(sserbuf, sizeof(sserbuf), "%u", signed_serial); - } - - /* Database node count */ - nodes = dns_db_nodecount(hasraw ? rawdb : db); - snprintf(nodebuf, sizeof(nodebuf), "%u", nodes); - - /* Security */ - secure = dns_db_issecure(db); - allow = ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_ALLOW) != 0); - maintain = ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0); - - /* Master files */ - file = dns_zone_getfile(mayberaw); - nfiles = dns_zone_getincludes(mayberaw, &incfiles); - - /* Load time */ - dns_zone_getloadtime(zone, &loadtime); - isc_time_formathttptimestamp(&loadtime, lbuf, sizeof(lbuf)); - - /* Refresh/expire times */ - if (zonetype == dns_zone_slave || - zonetype == dns_zone_stub || - zonetype == dns_zone_redirect) - { - dns_zone_getexpiretime(mayberaw, &expiretime); - isc_time_formathttptimestamp(&expiretime, xbuf, sizeof(xbuf)); - dns_zone_getrefreshtime(mayberaw, &refreshtime); - isc_time_formathttptimestamp(&refreshtime, rbuf, sizeof(rbuf)); - } - - /* Key refresh time */ - if (zonetype == dns_zone_master || - (zonetype == dns_zone_slave && hasraw)) - { - dns_zone_getrefreshkeytime(zone, &refreshkeytime); - isc_time_formathttptimestamp(&refreshkeytime, kbuf, - sizeof(kbuf)); - } - - /* Dynamic? */ - if (zonetype == dns_zone_master) { - dynamic = dns_zone_isdynamic(mayberaw, true); - frozen = dynamic && !dns_zone_isdynamic(mayberaw, false); - } - - /* Next resign event */ - if (secure && (zonetype == dns_zone_master || - (zonetype == dns_zone_slave && hasraw)) && - ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_NORESIGN) == 0)) - { - dns_name_t *name; - dns_fixedname_t fixed; - dns_rdataset_t next; - - dns_rdataset_init(&next); - name = dns_fixedname_initname(&fixed); - - result = dns_db_getsigningtime(db, &next, name); - if (result == ISC_R_SUCCESS) { - isc_stdtime_t timenow; - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - isc_stdtime_get(&timenow); - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(next.covers, - typebuf, sizeof(typebuf)); - snprintf(resignbuf, sizeof(resignbuf), - "%s/%s", namebuf, typebuf); - isc_time_set(&resigntime, next.resign - - dns_zone_getsigresigninginterval(zone), 0); - isc_time_formathttptimestamp(&resigntime, rtbuf, - sizeof(rtbuf)); - dns_rdataset_disassociate(&next); - } - } - - /* Create text */ - CHECK(putstr(text, "name: ")); - CHECK(putstr(text, zonename)); - - CHECK(putstr(text, "\ntype: ")); - CHECK(putstr(text, type)); - - if (file != NULL) { - int i; - CHECK(putstr(text, "\nfiles: ")); - CHECK(putstr(text, file)); - for (i = 0; i < nfiles; i++) { - CHECK(putstr(text, ", ")); - if (incfiles[i] != NULL) { - CHECK(putstr(text, incfiles[i])); - } - } - } - - CHECK(putstr(text, "\nserial: ")); - CHECK(putstr(text, serbuf)); - if (hasraw) { - CHECK(putstr(text, "\nsigned serial: ")); - CHECK(putstr(text, sserbuf)); - } - - CHECK(putstr(text, "\nnodes: ")); - CHECK(putstr(text, nodebuf)); - - if (! isc_time_isepoch(&loadtime)) { - CHECK(putstr(text, "\nlast loaded: ")); - CHECK(putstr(text, lbuf)); - } - - if (! isc_time_isepoch(&refreshtime)) { - CHECK(putstr(text, "\nnext refresh: ")); - CHECK(putstr(text, rbuf)); - } - - if (! isc_time_isepoch(&expiretime)) { - CHECK(putstr(text, "\nexpires: ")); - CHECK(putstr(text, xbuf)); - } - - if (secure) { - CHECK(putstr(text, "\nsecure: yes")); - if (hasraw) { - CHECK(putstr(text, "\ninline signing: yes")); - } else { - CHECK(putstr(text, "\ninline signing: no")); - } - } else { - CHECK(putstr(text, "\nsecure: no")); - } - - if (maintain) { - CHECK(putstr(text, "\nkey maintenance: automatic")); - if (! isc_time_isepoch(&refreshkeytime)) { - CHECK(putstr(text, "\nnext key event: ")); - CHECK(putstr(text, kbuf)); - } - } else if (allow) { - CHECK(putstr(text, "\nkey maintenance: on command")); - } else if (secure || hasraw) { - CHECK(putstr(text, "\nkey maintenance: none")); - } - - if (!isc_time_isepoch(&resigntime)) { - CHECK(putstr(text, "\nnext resign node: ")); - CHECK(putstr(text, resignbuf)); - CHECK(putstr(text, "\nnext resign time: ")); - CHECK(putstr(text, rtbuf)); - } - - if (dynamic) { - CHECK(putstr(text, "\ndynamic: yes")); - if (frozen) { - CHECK(putstr(text, "\nfrozen: yes")); - } else { - CHECK(putstr(text, "\nfrozen: no")); - } - } else { - CHECK(putstr(text, "\ndynamic: no")); - } - - CHECK(putstr(text, "\nreconfigurable via modzone: ")); - CHECK(putstr(text, dns_zone_getadded(zone) ? "yes" : "no")); - - cleanup: - /* Indicate truncated output if possible. */ - if (result == ISC_R_NOSPACE) { - (void) putstr(text, "\n..."); - } - if ((result == ISC_R_SUCCESS || result == ISC_R_NOSPACE)) { - (void) putnull(text); - } - - if (db != NULL) { - dns_db_detach(&db); - } - if (rawdb != NULL) { - dns_db_detach(&rawdb); - } - if (incfiles != NULL && mayberaw != NULL) { - int i; - isc_mem_t *mctx = dns_zone_getmctx(mayberaw); - - for (i = 0; i < nfiles; i++) { - if (incfiles[i] != NULL) { - isc_mem_free(mctx, incfiles[i]); - } - } - isc_mem_free(mctx, incfiles); - } - if (raw != NULL) { - dns_zone_detach(&raw); - } - if (zone != NULL) { - dns_zone_detach(&zone); - } - return (result); -} - -static inline bool -argcheck(char *cmd, const char *full) { - size_t l; - - if (cmd == NULL || cmd[0] != '-') - return (false); - - cmd++; - l = strlen(cmd); - if (l > strlen(full) || strncasecmp(cmd, full, l) != 0) - return (false); - - return (true); -} - -isc_result_t -ns_server_nta(ns_server_t *server, isc_lex_t *lex, bool readonly, - isc_buffer_t **text) -{ - dns_view_t *view; - dns_ntatable_t *ntatable = NULL; - isc_result_t result = ISC_R_SUCCESS; - char *ptr, *nametext = NULL, *viewname; - char namebuf[DNS_NAME_FORMATSIZE]; - isc_stdtime_t now, when; - isc_time_t t; - char tbuf[64]; - const char *msg = NULL; - bool dump = false, force = false; - dns_fixedname_t fn; - dns_name_t *ntaname; - dns_ttl_t ntattl; - bool ttlset = false, excl = false; - dns_rdataclass_t rdclass = dns_rdataclass_in; - - UNUSED(force); - - ntaname = dns_fixedname_initname(&fn); - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - for (;;) { - /* Check for options */ - ptr = next_token(lex, text); - if (ptr == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - if (argcheck(ptr, "dump")) { - dump = true; - } else if (argcheck(ptr, "remove")) { - ntattl = 0; - ttlset = true; - } else if (argcheck(ptr, "force")) { - force = true; - continue; - } else if (argcheck(ptr, "lifetime")) { - isc_textregion_t tr; - - ptr = next_token(lex, text); - if (ptr == NULL) { - msg = "No lifetime specified"; - CHECK(ISC_R_UNEXPECTEDEND); - } - - tr.base = ptr; - tr.length = strlen(ptr); - result = dns_ttl_fromtext(&tr, &ntattl); - if (result != ISC_R_SUCCESS) { - msg = "could not parse NTA lifetime"; - CHECK(result); - } - - if (ntattl > 604800) { - msg = "NTA lifetime cannot exceed one week"; - CHECK(ISC_R_RANGE); - } - - ttlset = true; - continue; - } else if (argcheck(ptr, "class")) { - isc_textregion_t tr; - - ptr = next_token(lex, text); - if (ptr == NULL) { - msg = "No class specified"; - CHECK(ISC_R_UNEXPECTEDEND); - } - - tr.base = ptr; - tr.length = strlen(ptr); - CHECK(dns_rdataclass_fromtext(&rdclass, &tr)); - continue; - } else { - nametext = ptr; - } - - break; - } - - /* - * If -dump was specified, list NTA's and return - */ - if (dump) { - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - continue; - } - CHECK(dns_ntatable_totext(ntatable, text)); - } - CHECK(putnull(text)); - - goto cleanup; - } - - if (readonly) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_INFO, - "rejecting restricted control channel " - "NTA command"); - CHECK(ISC_R_FAILURE); - } - - /* Get the NTA name. */ - if (nametext == NULL) { - nametext = next_token(lex, text); - } - if (nametext == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* Copy nametext as it'll be overwritten by next_token() */ - strlcpy(namebuf, nametext, DNS_NAME_FORMATSIZE); - - if (strcmp(namebuf, ".") == 0) { - ntaname = dns_rootname; - } else { - isc_buffer_t b; - isc_buffer_init(&b, namebuf, strlen(namebuf)); - isc_buffer_add(&b, strlen(namebuf)); - CHECK(dns_name_fromtext(ntaname, &b, dns_rootname, 0, NULL)); - } - - /* Look for the view name. */ - viewname = next_token(lex, text); - - isc_stdtime_get(&now); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - excl = true; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - static bool first = true; - - if (viewname != NULL && strcmp(view->name, viewname) != 0) { - continue; - } - - if (view->rdclass != rdclass && rdclass != dns_rdataclass_any) { - continue; - } - - if (view->nta_lifetime == 0) { - continue; - } - - if (!ttlset) { - ntattl = view->nta_lifetime; - } - - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - - result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - continue; - } - - result = dns_view_flushnode(view, ntaname, true); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flush tree '%s' in cache view '%s': %s", - namebuf, view->name, - isc_result_totext(result)); - - if (ntattl != 0) { - CHECK(dns_ntatable_add(ntatable, ntaname, - force, now, ntattl)); - - when = now + ntattl; - isc_time_set(&t, when, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); - - if (!first) { - CHECK(putstr(text, "\n")); - } - first = false; - - CHECK(putstr(text, "Negative trust anchor added: ")); - CHECK(putstr(text, namebuf)); - CHECK(putstr(text, "/")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ", expires ")); - CHECK(putstr(text, tbuf)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "added NTA '%s' (%d sec) in view '%s'", - namebuf, ntattl, view->name); - } else { - CHECK(dns_ntatable_delete(ntatable, ntaname)); - - if (!first) { - CHECK(putstr(text, "\n")); - } - first = false; - - CHECK(putstr(text, "Negative trust anchor removed: ")); - CHECK(putstr(text, namebuf)); - CHECK(putstr(text, "/")); - CHECK(putstr(text, view->name)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "removed NTA '%s' in view %s", - namebuf, view->name); - } - - result = dns_view_saventa(view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error writing NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - (void) putnull(text); - - cleanup: - if (msg != NULL) { - (void) putstr(text, msg); - (void) putnull(text); - } - if (excl) { - isc_task_endexclusive(server->task); - } - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - return (result); -} - -isc_result_t -ns_server_saventa(ns_server_t *server) { - dns_view_t *view; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - isc_result_t result = dns_view_saventa(view); - - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error writing NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_loadnta(ns_server_t *server) { - dns_view_t *view; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - isc_result_t result = dns_view_loadnta(view); - - if ((result != ISC_R_SUCCESS) && - (result != ISC_R_FILENOTFOUND) && - (result != ISC_R_NOTFOUND)) - { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "error loading NTA file " - "for view '%s': %s", - view->name, isc_result_totext(result)); - } - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -mkey_refresh(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - char msg[DNS_NAME_FORMATSIZE + 500] = ""; - - snprintf(msg, sizeof(msg), - "refreshing managed keys for '%s'", view->name); - CHECK(putstr(text, msg)); - CHECK(dns_zone_synckeyzone(view->managed_keys)); - - cleanup: - return (result); -} - -static isc_result_t -mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rriterator_t rrit; - isc_stdtime_t now; - dns_name_t *prevname = NULL; - - isc_stdtime_get(&now); - - CHECK(dns_zone_getdb(view->managed_keys, &db)); - dns_db_currentversion(db, &ver); - dns_rriterator_init(&rrit, db, ver, 0); - for (result = dns_rriterator_first(&rrit); - result == ISC_R_SUCCESS; - result = dns_rriterator_nextrrset(&rrit)) - { - char buf[DNS_NAME_FORMATSIZE + 500]; - dns_name_t *name = NULL; - dns_rdataset_t *kdset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_keydata_t kd; - uint32_t ttl; - - dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); - if (kdset == NULL || kdset->type != dns_rdatatype_keydata || - !dns_rdataset_isassociated(kdset)) - continue; - - if (name != prevname) { - char nbuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, nbuf, sizeof(nbuf)); - snprintf(buf, sizeof(buf), "\n\n name: %s", nbuf); - CHECK(putstr(text, buf)); - } - - - for (result = dns_rdataset_first(kdset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(kdset)) - { - char alg[DNS_SECALG_FORMATSIZE]; - char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - dns_keytag_t keyid; - isc_region_t r; - isc_time_t t; - bool revoked; - - dns_rdata_reset(&rdata); - dns_rdataset_current(kdset, &rdata); - result = dns_rdata_tostruct(&rdata, &kd, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_rdata_toregion(&rdata, &r); - isc_region_consume(&r, 12); - keyid = dst_region_computeid(&r, kd.algorithm); - - snprintf(buf, sizeof(buf), "\n keyid: %u", keyid); - CHECK(putstr(text, buf)); - - dns_secalg_format(kd.algorithm, alg, sizeof(alg)); - snprintf(buf, sizeof(buf), "\n\talgorithm: %s", alg); - CHECK(putstr(text, buf)); - - revoked = ((kd.flags & DNS_KEYFLAG_REVOKE) != 0); - snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s", - revoked ? " REVOKE" : "", - ((kd.flags & DNS_KEYFLAG_KSK) != 0) - ? " SEP" : "", - (kd.flags == 0) ? " (none)" : ""); - CHECK(putstr(text, buf)); - - isc_time_set(&t, kd.refresh, 0); - isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf)); - snprintf(buf, sizeof(buf), - "\n\tnext refresh: %s", tbuf); - CHECK(putstr(text, buf)); - - if (kd.removehd != 0) { - isc_time_set(&t, kd.removehd, 0); - isc_time_formathttptimestamp(&t, tbuf, - sizeof(tbuf)); - snprintf(buf, sizeof(buf), - "\n\tremove at: %s", tbuf); - CHECK(putstr(text, buf)); - } - - isc_time_set(&t, kd.addhd, 0); - isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf)); - if (kd.addhd == 0) - snprintf(buf, sizeof(buf), "\n\tno trust"); - else if (revoked) - snprintf(buf, sizeof(buf), - "\n\ttrust revoked"); - else if (kd.addhd <= now) - snprintf(buf, sizeof(buf), - "\n\ttrusted since: %s", tbuf); - else if (kd.addhd > now) - snprintf(buf, sizeof(buf), - "\n\ttrust pending: %s", tbuf); - CHECK(putstr(text, buf)); - } - } - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup: - if (ver != NULL) { - dns_rriterator_destroy(&rrit); - dns_db_closeversion(db, &ver, false); - } - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static isc_result_t -mkey_status(dns_view_t *view, isc_buffer_t **text) { - isc_result_t result; - char msg[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_t t; - - CHECK(putstr(text, "view: ")); - CHECK(putstr(text, view->name)); - - CHECK(putstr(text, "\nnext scheduled event: ")); - - dns_zone_getrefreshkeytime(view->managed_keys, &t); - if (isc_time_isepoch(&t)) { - CHECK(putstr(text, "never")); - } else { - isc_time_formathttptimestamp(&t, msg, sizeof(msg)); - CHECK(putstr(text, msg)); - } - - CHECK(mkey_dumpzone(view, text)); - - cleanup: - return (result); -} - -isc_result_t -ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { - char *cmd, *classtxt, *viewtxt = NULL; - isc_result_t result = ISC_R_SUCCESS; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - char msg[DNS_NAME_FORMATSIZE + 500] = ""; - enum { NONE, STATUS, REFRESH, SYNC } opt = NONE; - bool found = false; - bool first = true; - - /* Skip rndc command name */ - cmd = next_token(lex, text); - if (cmd == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - /* Get managed-keys subcommand */ - cmd = next_token(lex, text); - if (cmd == NULL) { - return (ISC_R_UNEXPECTEDEND); - } - - if (strcasecmp(cmd, "status") == 0) { - opt = STATUS; - } else if (strcasecmp(cmd, "refresh") == 0) { - opt = REFRESH; - } else if (strcasecmp(cmd, "sync") == 0) { - opt = SYNC; - } else { - snprintf(msg, sizeof(msg), "unknown command '%s'", cmd); - (void) putstr(text, msg); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - snprintf(msg, sizeof(msg), - "unknown class '%s'", classtxt); - (void) putstr(text, msg); - goto cleanup; - } - viewtxt = next_token(lex, text); - } - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewtxt != NULL && - (rdclass != view->rdclass || - strcmp(view->name, viewtxt) != 0)) - { - continue; - } - - if (view->managed_keys == NULL) { - if (viewtxt != NULL) { - snprintf(msg, sizeof(msg), - "view '%s': no managed keys", viewtxt); - CHECK(putstr(text, msg)); - goto cleanup; - } else { - continue; - } - } - - found = true; - - switch (opt) { - case REFRESH: - if (!first) { - CHECK(putstr(text, "\n")); - } - CHECK(mkey_refresh(view, text)); - break; - case STATUS: - if (!first) { - CHECK(putstr(text, "\n\n")); - } - CHECK(mkey_status(view, text)); - break; - case SYNC: - CHECK(dns_zone_flush(view->managed_keys)); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (viewtxt != NULL) { - break; - } - - first = false; - } - - if (!found) { - CHECK(putstr(text, "no views with managed keys")); - } - - cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - - return (result); -} - -isc_result_t -ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { -#ifdef HAVE_DNSTAP - char *ptr; - isc_result_t result; - bool reopen = false; - int backups = 0; - - if (server->dtenv == NULL) - return (ISC_R_NOTFOUND); - - /* Check the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* "dnstap-reopen" was used in 9.11.0b1 */ - if (strcasecmp(ptr, "dnstap-reopen") == 0) { - reopen = true; - } else { - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - } - - if (reopen || strcasecmp(ptr, "-reopen") == 0) { - backups = -1; - } else if ((strcasecmp(ptr, "-roll") == 0)) { - unsigned int n; - ptr = next_token(lex, text); - if (ptr != NULL) { - unsigned int u; - n = sscanf(ptr, "%u", &u); - if (n != 1U || u > INT_MAX) - return (ISC_R_BADNUMBER); - backups = u; - } - } else - return (DNS_R_SYNTAX); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = dns_dt_reopen(server->dtenv, backups); - isc_task_endexclusive(server->task); - return (result); -#else - UNUSED(server); - UNUSED(lex); - UNUSED(text); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - char *ptr, *classtxt, *viewtxt = NULL; - char msg[128]; - dns_rdataclass_t rdclass = dns_rdataclass_in; - dns_view_t *view; - bool found = false; - dns_stale_answer_t staleanswersok = dns_stale_answer_conf; - bool wantstatus = false; - isc_result_t result = ISC_R_SUCCESS; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "on") == 0 || strcasecmp(ptr, "yes") == 0) { - staleanswersok = dns_stale_answer_yes; - } else if (strcasecmp(ptr, "off") == 0 || strcasecmp(ptr, "no") == 0) { - staleanswersok = dns_stale_answer_no; - } else if (strcasecmp(ptr, "reset") == 0) { - staleanswersok = dns_stale_answer_conf; - } else if (strcasecmp(ptr, "status") == 0) { - wantstatus = true; - } else - return (DNS_R_SYNTAX); - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - /* Look for the optional view name. */ - viewtxt = next_token(lex, text); - } - - if (classtxt != NULL) { - isc_textregion_t r; - - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - if (viewtxt == NULL) { - viewtxt = classtxt; - classtxt = NULL; - result = ISC_R_SUCCESS; - } else { - snprintf(msg, sizeof(msg), - "unknown class '%s'", classtxt); - (void) putstr(text, msg); - goto cleanup; - } - } - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_ttl_t stale_ttl = 0; - dns_db_t *db = NULL; - - if (classtxt != NULL && rdclass != view->rdclass) - continue; - - if (viewtxt != NULL && strcmp(view->name, viewtxt) != 0) - continue; - - if (!wantstatus) { - view->staleanswersok = staleanswersok; - found = true; - continue; - } - - db = NULL; - dns_db_attach(view->cachedb, &db); - (void)dns_db_getservestalettl(db, &stale_ttl); - dns_db_detach(&db); - if (found) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ": ")); - switch (view->staleanswersok) { - case dns_stale_answer_yes: - if (stale_ttl > 0) - CHECK(putstr(text, "on (rndc)")); - else - CHECK(putstr(text, "off (not-cached)")); - break; - case dns_stale_answer_no: - CHECK(putstr(text, "off (rndc)")); - break; - case dns_stale_answer_conf: - if (view->staleanswersenable && stale_ttl > 0) - CHECK(putstr(text, "on")); - else if (view->staleanswersenable) - CHECK(putstr(text, "off (not-cached)")); - else - CHECK(putstr(text, "off")); - break; - } - if (stale_ttl > 0) { - snprintf(msg, sizeof(msg), - " (stale-answer-ttl=%u max-stale-ttl=%u)", - view->staleanswerttl, stale_ttl); - CHECK(putstr(text, msg)); - } - found = true; - } - isc_task_endexclusive(ns_g_server->task); - - if (!found) - result = ISC_R_NOTFOUND; - -cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - - return (result); -} diff --git a/bin/named-sdb/sortlist.c b/bin/named-sdb/sortlist.c deleted file mode 100644 index b36b0a0..0000000 --- a/bin/named-sdb/sortlist.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp) -{ - unsigned int i; - - if (acl == NULL) - goto dont_sort; - - for (i = 0; i < acl->length; i++) { - /* - * 'e' refers to the current 'top level statement' - * in the sortlist (see ARM). - */ - dns_aclelement_t *e = &acl->elements[i]; - dns_aclelement_t *try_elt; - dns_aclelement_t *order_elt = NULL; - const dns_aclelement_t *matched_elt = NULL; - - if (e->type == dns_aclelementtype_nestedacl) { - dns_acl_t *inner = e->nestedacl; - - if (inner->length == 0) - try_elt = e; - else if (inner->length > 2) - goto dont_sort; - else if (inner->elements[0].negative) - goto dont_sort; - else { - try_elt = &inner->elements[0]; - if (inner->length == 2) - order_elt = &inner->elements[1]; - } - } else { - /* - * BIND 8 allows bare elements at the top level - * as an undocumented feature. - */ - try_elt = e; - } - - if (dns_aclelement_match(clientaddr, NULL, try_elt, - &ns_g_server->aclenv, - &matched_elt)) { - if (order_elt != NULL) { - if (order_elt->type == - dns_aclelementtype_nestedacl) { - *argp = order_elt->nestedacl; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localhost && - ns_g_server->aclenv.localhost != NULL) { - *argp = ns_g_server->aclenv.localhost; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localnets && - ns_g_server->aclenv.localnets != NULL) { - *argp = ns_g_server->aclenv.localnets; - return (NS_SORTLISTTYPE_2ELEMENT); - } else { - /* - * BIND 8 allows a bare IP prefix as - * the 2nd element of a 2-element - * sortlist statement. - */ - *argp = order_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } else { - INSIST(matched_elt != NULL); - *argp = matched_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } - } - - /* No match; don't sort. */ - dont_sort: - *argp = NULL; - return (NS_SORTLISTTYPE_NONE); -} - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) { - const dns_acl_t *sortacl = (const dns_acl_t *) arg; - int match; - - (void)dns_acl_match(addr, NULL, sortacl, - &ns_g_server->aclenv, - &match, NULL); - if (match > 0) - return (match); - else if (match < 0) - return (INT_MAX - (-match)); - else - return (INT_MAX / 2); -} - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) { - const dns_aclelement_t *matchelt = (const dns_aclelement_t *) arg; - if (dns_aclelement_match(addr, NULL, matchelt, - &ns_g_server->aclenv, - NULL)) { - return (0); - } else { - return (INT_MAX); - } -} - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp) -{ - ns_sortlisttype_t sortlisttype; - - sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp); - - switch (sortlisttype) { - case NS_SORTLISTTYPE_1ELEMENT: - *orderp = ns_sortlist_addrorder1; - break; - case NS_SORTLISTTYPE_2ELEMENT: - *orderp = ns_sortlist_addrorder2; - break; - case NS_SORTLISTTYPE_NONE: - *orderp = NULL; - break; - default: - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unexpected return from ns_sortlist_setup(): " - "%d", sortlisttype); - break; - } -} - diff --git a/bin/named-sdb/sqlitedb.c b/bin/named-sdb/sqlitedb.c deleted file mode 100644 index dc93db4..0000000 --- a/bin/named-sdb/sqlitedb.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2007, 2016 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - - -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include "sqlitedb.h" - -/* - * A simple database driver that interfaces to a SQLite database. - * - * The table must contain the fields "name", "rdtype", and "rdata", and - * is expected to contain a properly constructed zone. The program "zonetodb" - * creates such a table. - */ - -static dns_sdbimplementation_t *sqlitedb = NULL; - -typedef struct _dbinfo { - sqlite3 *db; - char *filename; - char *table; -} dbinfo_t; - - -static isc_result_t -db_connect(dbinfo_t *dbi) -{ - if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) { - return (ISC_R_SUCCESS); - } else { - /* a connection is returned even if the open fails */ - sqlite3_close(dbi->db); - dbi->db = NULL; - return (ISC_R_FAILURE); - } -} - - -typedef struct _lookup_parm_t { - int i; - dns_sdblookup_t *lookup; - isc_result_t result; -} lookup_parm_t; - - -static int -sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn) -{ - lookup_parm_t *parm = p; - dns_ttl_t ttl; - char *endp; - - /* FIXME - check these(num/names); I'm assuming a mapping for now */ - char *ttlstr = cv[0]; - char *type = cv[1]; - char *data = cv[2]; - - UNUSED(cc); - UNUSED(cn); - - ttl = strtol(ttlstr, &endp, 10); - if (*endp) { - parm->result = DNS_R_BADTTL; - return 1; - } - - parm->result = dns_sdb_putrr(parm->lookup, type, ttl, data); - - if (parm->result != ISC_R_SUCCESS) - return 1; - - (parm->i)++; - - return 0; -} - - -#ifdef DNS_CLIENTINFO_VERSION -static isc_result_t -sqlitedb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -#else -static isc_result_t -sqlitedb_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -#endif /* DNS_CLIENTINFO_VERSION */ -/* - * synchronous absolute name lookup - */ -{ - dbinfo_t *dbi = (dbinfo_t *) dbdata; - char *sql; - lookup_parm_t parm = { 0, lookup, ISC_R_SUCCESS }; - char *errmsg = NULL; - int result; - - UNUSED(zone); -#ifdef DNS_CLIENTINFO_VERSION - UNUSED(methods); - UNUSED(clientinfo); -#endif /* DNS_CLIENTINFO_VERSION */ - - sql = sqlite3_mprintf( - "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE " - "lower(NAME) = lower('%q')", - dbi->table, name); - - result = sqlite3_exec(dbi->db, sql, - &sqlitedb_lookup_cb, &parm, - &errmsg); - sqlite3_free(sql); - - if (result != SQLITE_OK) - return (ISC_R_FAILURE); - if (parm.i == 0) - return (ISC_R_NOTFOUND); - - return (ISC_R_SUCCESS); -} - - -typedef struct _allnodes_parm_t { - int i; - dns_sdballnodes_t *allnodes; - isc_result_t result; -} allnodes_parm_t; - - -static int -sqlitedb_allnodes_cb(void *p, int cc, char **cv, char **cn) -{ - allnodes_parm_t *parm = p; - dns_ttl_t ttl; - char *endp; - - /* FIXME - check these(num/names); I'm assuming a mapping for now */ - char *ttlstr = cv[0]; - char *name = cv[1]; - char *type = cv[2]; - char *data = cv[3]; - - UNUSED(cc); - UNUSED(cn); - - ttl = strtol(ttlstr, &endp, 10); - if (*endp) { - parm->result = DNS_R_BADTTL; - return 1; - } - - parm->result = dns_sdb_putnamedrr(parm->allnodes, name, type, ttl, data); - - if (parm->result != ISC_R_SUCCESS) - return 1; - - (parm->i)++; - - return 0; -} - - -static isc_result_t -sqlitedb_allnodes(const char *zone, - void *dbdata, - dns_sdballnodes_t *allnodes) -{ - dbinfo_t *dbi = (dbinfo_t *) dbdata; - char *sql; - allnodes_parm_t parm = { 0, allnodes, ISC_R_SUCCESS }; - char *errmsg = NULL; - int result; - - UNUSED(zone); - - sql = sqlite3_mprintf( - "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME", - dbi->table); - - result = sqlite3_exec(dbi->db, sql, - &sqlitedb_allnodes_cb, &parm, - &errmsg); - sqlite3_free(sql); - - if (result != SQLITE_OK) - return (ISC_R_FAILURE); - if (parm.i == 0) - return (ISC_R_NOTFOUND); - - return (ISC_R_SUCCESS); -} - - -static void -sqlitedb_destroy(const char *zone, void *driverdata, void **dbdata) -{ - dbinfo_t *dbi = *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - if (dbi->db != NULL) - sqlite3_close(dbi->db); - if (dbi->table != NULL) - isc_mem_free(ns_g_mctx, dbi->table); - if (dbi->filename != NULL) - isc_mem_free(ns_g_mctx, dbi->filename); - - isc_mem_put(ns_g_mctx, dbi, sizeof(dbinfo_t)); -} - - -#define STRDUP_OR_FAIL(target, source) \ - do { \ - target = isc_mem_strdup(ns_g_mctx, source); \ - if (target == NULL) { \ - result = ISC_R_NOMEMORY; \ - goto cleanup; \ - } \ - } while (0); - -/* - * Create a connection to the database and save any necessary information - * in dbdata. - * - * argv[0] is the name of the database file - * argv[1] is the name of the table - */ -static isc_result_t -sqlitedb_create(const char *zone, - int argc, char **argv, - void *driverdata, void **dbdata) -{ - dbinfo_t *dbi; - isc_result_t result; - - UNUSED(zone); - UNUSED(driverdata); - - if (argc < 2) - return (ISC_R_FAILURE); - - dbi = isc_mem_get(ns_g_mctx, sizeof(dbinfo_t)); - if (dbi == NULL) - return (ISC_R_NOMEMORY); - dbi->db = NULL; - dbi->filename = NULL; - dbi->table = NULL; - - STRDUP_OR_FAIL(dbi->filename, argv[0]); - STRDUP_OR_FAIL(dbi->table, argv[1]); - - result = db_connect(dbi); - if (result != ISC_R_SUCCESS) - goto cleanup; - - *dbdata = dbi; - return (ISC_R_SUCCESS); - -cleanup: - sqlitedb_destroy(zone, driverdata, (void **)&dbi); - return (result); -} - - -/* - * Since the SQL database corresponds to a zone, the authority data should - * be returned by the lookup() function. Therefore the authority() function - * is NULL. - */ -static dns_sdbmethods_t sqlitedb_methods = { - sqlitedb_lookup, - NULL, /* authority */ - sqlitedb_allnodes, - sqlitedb_create, - sqlitedb_destroy, - NULL /* lookup2 */ -}; - - -/* - * Wrapper around dns_sdb_register(). - */ -isc_result_t -sqlitedb_init(void) -{ - unsigned int flags; - flags = 0; - return (dns_sdb_register("sqlite", &sqlitedb_methods, NULL, flags, - ns_g_mctx, &sqlitedb)); -} - - -/* - * Wrapper around dns_sdb_unregister(). - */ -void -sqlitedb_clear(void) -{ - if (sqlitedb != NULL) - dns_sdb_unregister(&sqlitedb); -} diff --git a/bin/named-sdb/sqlitedb.h b/bin/named-sdb/sqlitedb.h deleted file mode 100644 index 34f63dc..0000000 --- a/bin/named-sdb/sqlitedb.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2000-2002, 2016 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - - -#include - -isc_result_t sqlitedb_init(void); - -void sqlitedb_clear(void); - diff --git a/bin/named-sdb/statschannel.c b/bin/named-sdb/statschannel.c deleted file mode 100644 index 4938c03..0000000 --- a/bin/named-sdb/statschannel.c +++ /dev/null @@ -1,3594 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bind9.xsl.h" - -struct ns_statschannel { - /* Unlocked */ - isc_httpdmgr_t *httpdmgr; - isc_sockaddr_t address; - isc_mem_t *mctx; - - /* - * Locked by channel lock: can be referenced and modified by both - * the server task and the channel task. - */ - isc_mutex_t lock; - dns_acl_t *acl; - - /* Locked by server task */ - ISC_LINK(struct ns_statschannel) link; -}; - -typedef struct -stats_dumparg { - isc_statsformat_t type; - void *arg; /* type dependent argument */ - int ncounters; /* for general statistics */ - int *counterindices; /* for general statistics */ - uint64_t *countervalues; /* for general statistics */ - isc_result_t result; -} stats_dumparg_t; - -static isc_once_t once = ISC_ONCE_INIT; - -#if defined(HAVE_LIBXML2) || defined(HAVE_JSON) -#define EXTENDED_STATS -#else -#undef EXTENDED_STATS -#endif - -#ifdef EXTENDED_STATS -static const char * -user_zonetype( dns_zone_t *zone ) { - dns_zonetype_t ztype; - dns_view_t *view; - static const struct zt { - const dns_zonetype_t type; - const char *const string; - } typemap[] = { - { dns_zone_none, "none" }, - { dns_zone_master, "master" }, - { dns_zone_slave, "slave" }, - { dns_zone_stub, "stub" }, - { dns_zone_staticstub, "static-stub" }, - { dns_zone_key, "key" }, - { dns_zone_dlz, "dlz" }, - { dns_zone_redirect, "redirect" }, - { 0, NULL } - }; - const struct zt *tp; - - if ((dns_zone_getoptions2(zone) & DNS_ZONEOPT2_AUTOEMPTY) != 0) - return ("builtin"); - - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_bind") == 0) - return ("builtin"); - - ztype = dns_zone_gettype(zone); - for (tp = typemap; tp->string != NULL && tp->type != ztype; tp++) - /* empty */; - return (tp->string); -} -#endif - -/*% - * Statistics descriptions. These could be statistically initialized at - * compile time, but we configure them run time in the init_desc() function - * below so that they'll be less susceptible to counter name changes. - */ -static const char *nsstats_desc[dns_nsstatscounter_max]; -static const char *resstats_desc[dns_resstatscounter_max]; -static const char *adbstats_desc[dns_adbstats_max]; -static const char *zonestats_desc[dns_zonestatscounter_max]; -static const char *sockstats_desc[isc_sockstatscounter_max]; -static const char *dnssecstats_desc[dns_dnssecstats_max]; -static const char *udpinsizestats_desc[dns_sizecounter_in_max]; -static const char *udpoutsizestats_desc[dns_sizecounter_out_max]; -static const char *tcpinsizestats_desc[dns_sizecounter_in_max]; -static const char *tcpoutsizestats_desc[dns_sizecounter_out_max]; -static const char *dnstapstats_desc[dns_dnstapcounter_max]; -#if defined(EXTENDED_STATS) -static const char *nsstats_xmldesc[dns_nsstatscounter_max]; -static const char *resstats_xmldesc[dns_resstatscounter_max]; -static const char *adbstats_xmldesc[dns_adbstats_max]; -static const char *zonestats_xmldesc[dns_zonestatscounter_max]; -static const char *sockstats_xmldesc[isc_sockstatscounter_max]; -static const char *dnssecstats_xmldesc[dns_dnssecstats_max]; -static const char *udpinsizestats_xmldesc[dns_sizecounter_in_max]; -static const char *udpoutsizestats_xmldesc[dns_sizecounter_out_max]; -static const char *tcpinsizestats_xmldesc[dns_sizecounter_in_max]; -static const char *tcpoutsizestats_xmldesc[dns_sizecounter_out_max]; -static const char *dnstapstats_xmldesc[dns_dnstapcounter_max]; -#else -#define nsstats_xmldesc NULL -#define resstats_xmldesc NULL -#define adbstats_xmldesc NULL -#define zonestats_xmldesc NULL -#define sockstats_xmldesc NULL -#define dnssecstats_xmldesc NULL -#define udpinsizestats_xmldesc NULL -#define udpoutsizestats_xmldesc NULL -#define tcpinsizestats_xmldesc NULL -#define tcpoutsizestats_xmldesc NULL -#define dnstapstats_xmldesc NULL -#endif /* EXTENDED_STATS */ - -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) - -/*% - * Mapping arrays to represent statistics counters in the order of our - * preference, regardless of the order of counter indices. For example, - * nsstats_desc[nsstats_index[0]] will be the description that is shown first. - */ -static int nsstats_index[dns_nsstatscounter_max]; -static int resstats_index[dns_resstatscounter_max]; -static int adbstats_index[dns_adbstats_max]; -static int zonestats_index[dns_zonestatscounter_max]; -static int sockstats_index[isc_sockstatscounter_max]; -static int dnssecstats_index[dns_dnssecstats_max]; -static int udpinsizestats_index[dns_sizecounter_in_max]; -static int udpoutsizestats_index[dns_sizecounter_out_max]; -static int tcpinsizestats_index[dns_sizecounter_in_max]; -static int tcpoutsizestats_index[dns_sizecounter_out_max]; -static int dnstapstats_index[dns_dnstapcounter_max]; - -static inline void -set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs, - const char *xdesc, const char **xdescs) -{ - REQUIRE(counter < maxcounter); - REQUIRE(fdescs != NULL && fdescs[counter] == NULL); -#if defined(EXTENDED_STATS) - REQUIRE(xdescs != NULL && xdescs[counter] == NULL); -#endif - - fdescs[counter] = fdesc; -#if defined(EXTENDED_STATS) - xdescs[counter] = xdesc; -#else - UNUSED(xdesc); - UNUSED(xdescs); -#endif -} - -static void -init_desc(void) { - int i; - - /* Initialize name server statistics */ - for (i = 0; i < dns_nsstatscounter_max; i++) - nsstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - nsstats_xmldesc[i] = NULL; -#endif - -#define SET_NSSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_nsstatscounter_ ## counterid, \ - dns_nsstatscounter_max, \ - desc, nsstats_desc, xmldesc, nsstats_xmldesc); \ - nsstats_index[i++] = dns_nsstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_NSSTATDESC(requestv4, "IPv4 requests received", "Requestv4"); - SET_NSSTATDESC(requestv6, "IPv6 requests received", "Requestv6"); - SET_NSSTATDESC(edns0in, "requests with EDNS(0) received", "ReqEdns0"); - SET_NSSTATDESC(badednsver, - "requests with unsupported EDNS version received", - "ReqBadEDNSVer"); - SET_NSSTATDESC(tsigin, "requests with TSIG received", "ReqTSIG"); - SET_NSSTATDESC(sig0in, "requests with SIG(0) received", "ReqSIG0"); - SET_NSSTATDESC(invalidsig, "requests with invalid signature", - "ReqBadSIG"); - SET_NSSTATDESC(requesttcp, "TCP requests received", "ReqTCP"); - SET_NSSTATDESC(tcphighwater, "TCP connection high-water", - "TCPConnHighWater"); - SET_NSSTATDESC(authrej, "auth queries rejected", "AuthQryRej"); - SET_NSSTATDESC(recurserej, "recursive queries rejected", "RecQryRej"); - SET_NSSTATDESC(xfrrej, "transfer requests rejected", "XfrRej"); - SET_NSSTATDESC(updaterej, "update requests rejected", "UpdateRej"); - SET_NSSTATDESC(response, "responses sent", "Response"); - SET_NSSTATDESC(truncatedresp, "truncated responses sent", - "TruncatedResp"); - SET_NSSTATDESC(edns0out, "responses with EDNS(0) sent", "RespEDNS0"); - SET_NSSTATDESC(tsigout, "responses with TSIG sent", "RespTSIG"); - SET_NSSTATDESC(sig0out, "responses with SIG(0) sent", "RespSIG0"); - SET_NSSTATDESC(success, "queries resulted in successful answer", - "QrySuccess"); - SET_NSSTATDESC(authans, "queries resulted in authoritative answer", - "QryAuthAns"); - SET_NSSTATDESC(nonauthans, - "queries resulted in non authoritative answer", - "QryNoauthAns"); - SET_NSSTATDESC(referral, "queries resulted in referral answer", - "QryReferral"); - SET_NSSTATDESC(nxrrset, "queries resulted in nxrrset", "QryNxrrset"); - SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL"); - SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR"); - SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN"); - SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion"); - SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate"); - SET_NSSTATDESC(dropped, "queries dropped", "QryDropped"); - SET_NSSTATDESC(failure, "other query failures", "QryFailure"); - SET_NSSTATDESC(xfrdone, "requested transfers completed", "XfrReqDone"); - SET_NSSTATDESC(updatereqfwd, "update requests forwarded", - "UpdateReqFwd"); - SET_NSSTATDESC(updaterespfwd, "update responses forwarded", - "UpdateRespFwd"); - SET_NSSTATDESC(updatefwdfail, "update forward failed", "UpdateFwdFail"); - SET_NSSTATDESC(updatedone, "updates completed", "UpdateDone"); - SET_NSSTATDESC(updatefail, "updates failed", "UpdateFail"); - SET_NSSTATDESC(updatebadprereq, - "updates rejected due to prerequisite failure", - "UpdateBadPrereq"); - SET_NSSTATDESC(recursclients, "recursing clients", - "RecursClients"); - SET_NSSTATDESC(dns64, "queries answered by DNS64", "DNS64"); - SET_NSSTATDESC(ratedropped, "responses dropped for rate limits", - "RateDropped"); - SET_NSSTATDESC(rateslipped, "responses truncated for rate limits", - "RateSlipped"); - SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites", - "RPZRewrites"); - SET_NSSTATDESC(udp, "UDP queries received", "QryUDP"); - SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP"); - SET_NSSTATDESC(nsidopt, "NSID option received", "NSIDOpt"); - SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt"); - SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt"); - SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn"); - SET_NSSTATDESC(cookienew, "COOKIE - client only", "CookieNew"); - SET_NSSTATDESC(cookiebadsize, "COOKIE - bad size", "CookieBadSize"); - SET_NSSTATDESC(cookiebadtime, "COOKIE - bad time", "CookieBadTime"); - SET_NSSTATDESC(cookienomatch, "COOKIE - no match", "CookieNoMatch"); - SET_NSSTATDESC(cookiematch, "COOKIE - match", "CookieMatch"); - SET_NSSTATDESC(ecsopt, "EDNS client subnet option received", "ECSOpt"); - SET_NSSTATDESC(nxdomainredirect, - "queries resulted in NXDOMAIN that were redirected", - "QryNXRedir"); - SET_NSSTATDESC(nxdomainredirect_rlookup, - "queries resulted in NXDOMAIN that were redirected and " - "resulted in a successful remote lookup", - "QryNXRedirRLookup"); - SET_NSSTATDESC(badcookie, "sent badcookie response", "QryBADCOOKIE"); - SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt"); - SET_NSSTATDESC(reclimitdropped, - "queries dropped due to recursive client limit", - "RecLimitDropped"); - SET_NSSTATDESC(trystale, - "attempts to use stale cache data after lookup failure", - "QryTryStale"); - SET_NSSTATDESC(usedstale, - "successful uses of stale cache data after lookup failure", - "QryUsedStale"); - INSIST(i == dns_nsstatscounter_max); - - /* Initialize resolver statistics */ - for (i = 0; i < dns_resstatscounter_max; i++) - resstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_resstatscounter_max; i++) - resstats_xmldesc[i] = NULL; -#endif - -#define SET_RESSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_resstatscounter_ ## counterid, \ - dns_resstatscounter_max, \ - desc, resstats_desc, xmldesc, resstats_xmldesc); \ - resstats_index[i++] = dns_resstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_RESSTATDESC(queryv4, "IPv4 queries sent", "Queryv4"); - SET_RESSTATDESC(queryv6, "IPv6 queries sent", "Queryv6"); - SET_RESSTATDESC(responsev4, "IPv4 responses received", "Responsev4"); - SET_RESSTATDESC(responsev6, "IPv6 responses received", "Responsev6"); - SET_RESSTATDESC(nxdomain, "NXDOMAIN received", "NXDOMAIN"); - SET_RESSTATDESC(servfail, "SERVFAIL received", "SERVFAIL"); - SET_RESSTATDESC(formerr, "FORMERR received", "FORMERR"); - SET_RESSTATDESC(othererror, "other errors received", "OtherError"); - SET_RESSTATDESC(edns0fail, "EDNS(0) query failures", "EDNS0Fail"); - SET_RESSTATDESC(mismatch, "mismatch responses received", "Mismatch"); - SET_RESSTATDESC(truncated, "truncated responses received", "Truncated"); - SET_RESSTATDESC(lame, "lame delegations received", "Lame"); - SET_RESSTATDESC(retry, "query retries", "Retry"); - SET_RESSTATDESC(dispabort, "queries aborted due to quota", - "QueryAbort"); - SET_RESSTATDESC(dispsockfail, "failures in opening query sockets", - "QuerySockFail"); - SET_RESSTATDESC(disprequdp, "UDP queries in progress", "QueryCurUDP"); - SET_RESSTATDESC(dispreqtcp, "TCP queries in progress", "QueryCurTCP"); - SET_RESSTATDESC(querytimeout, "query timeouts", "QueryTimeout"); - SET_RESSTATDESC(gluefetchv4, "IPv4 NS address fetches", "GlueFetchv4"); - SET_RESSTATDESC(gluefetchv6, "IPv6 NS address fetches", "GlueFetchv6"); - SET_RESSTATDESC(gluefetchv4fail, "IPv4 NS address fetch failed", - "GlueFetchv4Fail"); - SET_RESSTATDESC(gluefetchv6fail, "IPv6 NS address fetch failed", - "GlueFetchv6Fail"); - SET_RESSTATDESC(val, "DNSSEC validation attempted", "ValAttempt"); - SET_RESSTATDESC(valsuccess, "DNSSEC validation succeeded", "ValOk"); - SET_RESSTATDESC(valnegsuccess, "DNSSEC NX validation succeeded", - "ValNegOk"); - SET_RESSTATDESC(valfail, "DNSSEC validation failed", "ValFail"); - SET_RESSTATDESC(queryrtt0, "queries with RTT < " - DNS_RESOLVER_QRYRTTCLASS0STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS0STR); - SET_RESSTATDESC(queryrtt1, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS0STR "-" - DNS_RESOLVER_QRYRTTCLASS1STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS1STR); - SET_RESSTATDESC(queryrtt2, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS1STR "-" - DNS_RESOLVER_QRYRTTCLASS2STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS2STR); - SET_RESSTATDESC(queryrtt3, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS2STR "-" - DNS_RESOLVER_QRYRTTCLASS3STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS3STR); - SET_RESSTATDESC(queryrtt4, "queries with RTT " - DNS_RESOLVER_QRYRTTCLASS3STR "-" - DNS_RESOLVER_QRYRTTCLASS4STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR); - SET_RESSTATDESC(queryrtt5, "queries with RTT > " - DNS_RESOLVER_QRYRTTCLASS4STR "ms", - "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR "+"); - SET_RESSTATDESC(nfetch, "active fetches", "NumFetch"); - SET_RESSTATDESC(buckets, "bucket size", "BucketSize"); - SET_RESSTATDESC(refused, "REFUSED received", "REFUSED"); - SET_RESSTATDESC(cookienew, "COOKIE send with client cookie only", - "ClientCookieOut"); - SET_RESSTATDESC(cookieout, "COOKIE sent with client and server cookie", - "ServerCookieOut"); - SET_RESSTATDESC(cookiein, "COOKIE replies received", "CookieIn"); - SET_RESSTATDESC(cookieok, "COOKIE client ok", "CookieClientOk"); - SET_RESSTATDESC(badvers, "bad EDNS version", "BadEDNSVersion"); - SET_RESSTATDESC(badcookie, "bad cookie rcode", "BadCookieRcode"); - SET_RESSTATDESC(zonequota, "spilled due to zone quota", "ZoneQuota"); - SET_RESSTATDESC(serverquota, "spilled due to server quota", - "ServerQuota"); - SET_RESSTATDESC(nextitem, "waited for next item", "NextItem"); - - INSIST(i == dns_resstatscounter_max); - - /* Initialize adb statistics */ - for (i = 0; i < dns_adbstats_max; i++) - adbstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_adbstats_max; i++) - adbstats_xmldesc[i] = NULL; -#endif - -#define SET_ADBSTATDESC(id, desc, xmldesc) \ - do { \ - set_desc(dns_adbstats_ ## id, dns_adbstats_max, \ - desc, adbstats_desc, xmldesc, adbstats_xmldesc); \ - adbstats_index[i++] = dns_adbstats_ ## id; \ - } while (0) - i = 0; - SET_ADBSTATDESC(nentries, "Address hash table size", "nentries"); - SET_ADBSTATDESC(entriescnt, "Addresses in hash table", "entriescnt"); - SET_ADBSTATDESC(nnames, "Name hash table size", "nnames"); - SET_ADBSTATDESC(namescnt, "Names in hash table", "namescnt"); - - INSIST(i == dns_adbstats_max); - - /* Initialize zone statistics */ - for (i = 0; i < dns_zonestatscounter_max; i++) - zonestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_zonestatscounter_max; i++) - zonestats_xmldesc[i] = NULL; -#endif - -#define SET_ZONESTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_zonestatscounter_ ## counterid, \ - dns_zonestatscounter_max, \ - desc, zonestats_desc, xmldesc, zonestats_xmldesc); \ - zonestats_index[i++] = dns_zonestatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_ZONESTATDESC(notifyoutv4, "IPv4 notifies sent", "NotifyOutv4"); - SET_ZONESTATDESC(notifyoutv6, "IPv6 notifies sent", "NotifyOutv6"); - SET_ZONESTATDESC(notifyinv4, "IPv4 notifies received", "NotifyInv4"); - SET_ZONESTATDESC(notifyinv6, "IPv6 notifies received", "NotifyInv6"); - SET_ZONESTATDESC(notifyrej, "notifies rejected", "NotifyRej"); - SET_ZONESTATDESC(soaoutv4, "IPv4 SOA queries sent", "SOAOutv4"); - SET_ZONESTATDESC(soaoutv6, "IPv6 SOA queries sent", "SOAOutv6"); - SET_ZONESTATDESC(axfrreqv4, "IPv4 AXFR requested", "AXFRReqv4"); - SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6"); - SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4"); - SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6"); - SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded", - "XfrSuccess"); - SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail"); - INSIST(i == dns_zonestatscounter_max); - - /* Initialize socket statistics */ - for (i = 0; i < isc_sockstatscounter_max; i++) - sockstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < isc_sockstatscounter_max; i++) - sockstats_xmldesc[i] = NULL; -#endif - -#define SET_SOCKSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(isc_sockstatscounter_ ## counterid, \ - isc_sockstatscounter_max, \ - desc, sockstats_desc, xmldesc, sockstats_xmldesc); \ - sockstats_index[i++] = isc_sockstatscounter_ ## counterid; \ - } while (0) - - i = 0; - SET_SOCKSTATDESC(udp4open, "UDP/IPv4 sockets opened", "UDP4Open"); - SET_SOCKSTATDESC(udp6open, "UDP/IPv6 sockets opened", "UDP6Open"); - SET_SOCKSTATDESC(tcp4open, "TCP/IPv4 sockets opened", "TCP4Open"); - SET_SOCKSTATDESC(tcp6open, "TCP/IPv6 sockets opened", "TCP6Open"); - SET_SOCKSTATDESC(unixopen, "Unix domain sockets opened", "UnixOpen"); - SET_SOCKSTATDESC(rawopen, "Raw sockets opened", "RawOpen"); - SET_SOCKSTATDESC(udp4openfail, "UDP/IPv4 socket open failures", - "UDP4OpenFail"); - SET_SOCKSTATDESC(udp6openfail, "UDP/IPv6 socket open failures", - "UDP6OpenFail"); - SET_SOCKSTATDESC(tcp4openfail, "TCP/IPv4 socket open failures", - "TCP4OpenFail"); - SET_SOCKSTATDESC(tcp6openfail, "TCP/IPv6 socket open failures", - "TCP6OpenFail"); - SET_SOCKSTATDESC(unixopenfail, "Unix domain socket open failures", - "UnixOpenFail"); - SET_SOCKSTATDESC(rawopenfail, "Raw socket open failures", - "RawOpenFail"); - SET_SOCKSTATDESC(udp4close, "UDP/IPv4 sockets closed", "UDP4Close"); - SET_SOCKSTATDESC(udp6close, "UDP/IPv6 sockets closed", "UDP6Close"); - SET_SOCKSTATDESC(tcp4close, "TCP/IPv4 sockets closed", "TCP4Close"); - SET_SOCKSTATDESC(tcp6close, "TCP/IPv6 sockets closed", "TCP6Close"); - SET_SOCKSTATDESC(unixclose, "Unix domain sockets closed", "UnixClose"); - SET_SOCKSTATDESC(fdwatchclose, "FDwatch sockets closed", - "FDWatchClose"); - SET_SOCKSTATDESC(rawclose, "Raw sockets closed", "RawClose"); - SET_SOCKSTATDESC(udp4bindfail, "UDP/IPv4 socket bind failures", - "UDP4BindFail"); - SET_SOCKSTATDESC(udp6bindfail, "UDP/IPv6 socket bind failures", - "UDP6BindFail"); - SET_SOCKSTATDESC(tcp4bindfail, "TCP/IPv4 socket bind failures", - "TCP4BindFail"); - SET_SOCKSTATDESC(tcp6bindfail, "TCP/IPv6 socket bind failures", - "TCP6BindFail"); - SET_SOCKSTATDESC(unixbindfail, "Unix domain socket bind failures", - "UnixBindFail"); - SET_SOCKSTATDESC(fdwatchbindfail, "FDwatch socket bind failures", - "FdwatchBindFail"); - SET_SOCKSTATDESC(udp4connectfail, "UDP/IPv4 socket connect failures", - "UDP4ConnFail"); - SET_SOCKSTATDESC(udp6connectfail, "UDP/IPv6 socket connect failures", - "UDP6ConnFail"); - SET_SOCKSTATDESC(tcp4connectfail, "TCP/IPv4 socket connect failures", - "TCP4ConnFail"); - SET_SOCKSTATDESC(tcp6connectfail, "TCP/IPv6 socket connect failures", - "TCP6ConnFail"); - SET_SOCKSTATDESC(unixconnectfail, "Unix domain socket connect failures", - "UnixConnFail"); - SET_SOCKSTATDESC(fdwatchconnectfail, "FDwatch socket connect failures", - "FDwatchConnFail"); - SET_SOCKSTATDESC(udp4connect, "UDP/IPv4 connections established", - "UDP4Conn"); - SET_SOCKSTATDESC(udp6connect, "UDP/IPv6 connections established", - "UDP6Conn"); - SET_SOCKSTATDESC(tcp4connect, "TCP/IPv4 connections established", - "TCP4Conn"); - SET_SOCKSTATDESC(tcp6connect, "TCP/IPv6 connections established", - "TCP6Conn"); - SET_SOCKSTATDESC(unixconnect, "Unix domain connections established", - "UnixConn"); - SET_SOCKSTATDESC(fdwatchconnect, - "FDwatch domain connections established", - "FDwatchConn"); - SET_SOCKSTATDESC(tcp4acceptfail, "TCP/IPv4 connection accept failures", - "TCP4AcceptFail"); - SET_SOCKSTATDESC(tcp6acceptfail, "TCP/IPv6 connection accept failures", - "TCP6AcceptFail"); - SET_SOCKSTATDESC(unixacceptfail, - "Unix domain connection accept failures", - "UnixAcceptFail"); - SET_SOCKSTATDESC(tcp4accept, "TCP/IPv4 connections accepted", - "TCP4Accept"); - SET_SOCKSTATDESC(tcp6accept, "TCP/IPv6 connections accepted", - "TCP6Accept"); - SET_SOCKSTATDESC(unixaccept, "Unix domain connections accepted", - "UnixAccept"); - SET_SOCKSTATDESC(udp4sendfail, "UDP/IPv4 send errors", "UDP4SendErr"); - SET_SOCKSTATDESC(udp6sendfail, "UDP/IPv6 send errors", "UDP6SendErr"); - SET_SOCKSTATDESC(tcp4sendfail, "TCP/IPv4 send errors", "TCP4SendErr"); - SET_SOCKSTATDESC(tcp6sendfail, "TCP/IPv6 send errors", "TCP6SendErr"); - SET_SOCKSTATDESC(unixsendfail, "Unix domain send errors", - "UnixSendErr"); - SET_SOCKSTATDESC(fdwatchsendfail, "FDwatch send errors", - "FDwatchSendErr"); - SET_SOCKSTATDESC(udp4recvfail, "UDP/IPv4 recv errors", "UDP4RecvErr"); - SET_SOCKSTATDESC(udp6recvfail, "UDP/IPv6 recv errors", "UDP6RecvErr"); - SET_SOCKSTATDESC(tcp4recvfail, "TCP/IPv4 recv errors", "TCP4RecvErr"); - SET_SOCKSTATDESC(tcp6recvfail, "TCP/IPv6 recv errors", "TCP6RecvErr"); - SET_SOCKSTATDESC(unixrecvfail, "Unix domain recv errors", - "UnixRecvErr"); - SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors", - "FDwatchRecvErr"); - SET_SOCKSTATDESC(rawrecvfail, "Raw recv errors", "RawRecvErr"); - SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active"); - SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active"); - SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active"); - SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active"); - SET_SOCKSTATDESC(unixactive, "Unix domain sockets active", - "UnixActive"); - SET_SOCKSTATDESC(rawactive, "Raw sockets active", "RawActive"); - INSIST(i == isc_sockstatscounter_max); - - /* Initialize DNSSEC statistics */ - for (i = 0; i < dns_dnssecstats_max; i++) - dnssecstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_dnssecstats_max; i++) - dnssecstats_xmldesc[i] = NULL; -#endif - -#define SET_DNSSECSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_dnssecstats_ ## counterid, \ - dns_dnssecstats_max, \ - desc, dnssecstats_desc, \ - xmldesc, dnssecstats_xmldesc); \ - dnssecstats_index[i++] = dns_dnssecstats_ ## counterid; \ - } while (0) - - i = 0; - SET_DNSSECSTATDESC(asis, "dnssec validation success with signer " - "\"as is\"", "DNSSECasis"); - SET_DNSSECSTATDESC(downcase, "dnssec validation success with signer " - "lower cased", "DNSSECdowncase"); - SET_DNSSECSTATDESC(wildcard, "dnssec validation of wildcard signature", - "DNSSECwild"); - SET_DNSSECSTATDESC(fail, "dnssec validation failures", "DNSSECfail"); - INSIST(i == dns_dnssecstats_max); - - /* Initialize dnstap statistics */ - for (i = 0; i < dns_dnstapcounter_max; i++) - dnstapstats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_dnstapcounter_max; i++) - dnstapstats_xmldesc[i] = NULL; -#endif - -#define SET_DNSTAPSTATDESC(counterid, desc, xmldesc) \ - do { \ - set_desc(dns_dnstapcounter_ ## counterid, \ - dns_dnstapcounter_max, \ - desc, dnstapstats_desc, \ - xmldesc, dnstapstats_xmldesc); \ - dnstapstats_index[i++] = dns_dnstapcounter_ ## counterid; \ - } while (0) - i = 0; - SET_DNSTAPSTATDESC(success, "dnstap messages written", "DNSTAPsuccess"); - SET_DNSTAPSTATDESC(drop, "dnstap messages dropped", "DNSTAPdropped"); - INSIST(i == dns_dnstapcounter_max); - - /* Sanity check */ - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_desc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_desc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_desc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_desc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_desc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_desc[i] != NULL); - for (i = 0; i < dns_dnstapcounter_max; i++) - INSIST(dnstapstats_desc[i] != NULL); -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_xmldesc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_xmldesc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_xmldesc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_xmldesc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnstapcounter_max; i++) - INSIST(dnstapstats_xmldesc[i] != NULL); -#endif - - /* Initialize traffic size statistics */ - for (i = 0; i < dns_sizecounter_in_max; i++) { - udpinsizestats_desc[i] = NULL; - tcpinsizestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - udpinsizestats_xmldesc[i] = NULL; - tcpinsizestats_xmldesc[i] = NULL; -#endif - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - udpoutsizestats_desc[i] = NULL; - tcpoutsizestats_desc[i] = NULL; -#if defined(EXTENDED_STATS) - udpoutsizestats_xmldesc[i] = NULL; - tcpoutsizestats_xmldesc[i] = NULL; -#endif - } - -#define SET_SIZESTATDESC(counterid, desc, xmldesc, inout) \ - do { \ - set_desc(dns_sizecounter_ ## inout ## _ ## counterid, \ - dns_sizecounter_ ## inout ## _max, \ - desc, udp ## inout ## sizestats_desc, \ - xmldesc, udp ## inout ## sizestats_xmldesc); \ - set_desc(dns_sizecounter_ ## inout ## _ ## counterid, \ - dns_sizecounter_ ## inout ## _max, \ - desc, tcp ## inout ## sizestats_desc, \ - xmldesc, tcp ## inout ## sizestats_xmldesc); \ - udp ## inout ## sizestats_index[i] = dns_sizecounter_ ## inout ## _ ## counterid; \ - tcp ## inout ## sizestats_index[i] = dns_sizecounter_ ## inout ## _ ## counterid; \ - i++; \ - } while (0) - - i = 0; - SET_SIZESTATDESC(0, "requests received 0-15 bytes", "0-15", in); - SET_SIZESTATDESC(16, "requests received 16-31 bytes", "16-31", in); - SET_SIZESTATDESC(32, "requests received 32-47 bytes", "32-47", in); - SET_SIZESTATDESC(48, "requests received 48-63 bytes", "48-63", in); - SET_SIZESTATDESC(64, "requests received 64-79 bytes", "64-79", in); - SET_SIZESTATDESC(80, "requests received 80-95 bytes", "80-95", in); - SET_SIZESTATDESC(96, "requests received 96-111 bytes", "96-111", in); - SET_SIZESTATDESC(112, "requests received 112-127 bytes", "112-127", in); - SET_SIZESTATDESC(128, "requests received 128-143 bytes", "128-143", in); - SET_SIZESTATDESC(144, "requests received 144-159 bytes", "144-159", in); - SET_SIZESTATDESC(160, "requests received 160-175 bytes", "160-175", in); - SET_SIZESTATDESC(176, "requests received 176-191 bytes", "176-191", in); - SET_SIZESTATDESC(192, "requests received 192-207 bytes", "192-207", in); - SET_SIZESTATDESC(208, "requests received 208-223 bytes", "208-223", in); - SET_SIZESTATDESC(224, "requests received 224-239 bytes", "224-239", in); - SET_SIZESTATDESC(240, "requests received 240-255 bytes", "240-255", in); - SET_SIZESTATDESC(256, "requests received 256-271 bytes", "256-271", in); - SET_SIZESTATDESC(272, "requests received 272-287 bytes", "272-287", in); - SET_SIZESTATDESC(288, "requests received 288+ bytes", "288+", in); - INSIST(i == dns_sizecounter_in_max); - - i = 0; - SET_SIZESTATDESC(0, "responses sent 0-15 bytes", "0-15", out); - SET_SIZESTATDESC(16, "responses sent 16-31 bytes", "16-31", out); - SET_SIZESTATDESC(32, "responses sent 32-47 bytes", "32-47", out); - SET_SIZESTATDESC(48, "responses sent 48-63 bytes", "48-63", out); - SET_SIZESTATDESC(64, "responses sent 64-79 bytes", "64-79", out); - SET_SIZESTATDESC(80, "responses sent 80-95 bytes", "80-95", out); - SET_SIZESTATDESC(96, "responses sent 96-111 bytes", "96-111", out); - SET_SIZESTATDESC(112, "responses sent 112-127 bytes", "112-127", out); - SET_SIZESTATDESC(128, "responses sent 128-143 bytes", "128-143", out); - SET_SIZESTATDESC(144, "responses sent 144-159 bytes", "144-159", out); - SET_SIZESTATDESC(160, "responses sent 160-175 bytes", "160-175", out); - SET_SIZESTATDESC(176, "responses sent 176-191 bytes", "176-191", out); - SET_SIZESTATDESC(192, "responses sent 192-207 bytes", "192-207", out); - SET_SIZESTATDESC(208, "responses sent 208-223 bytes", "208-223", out); - SET_SIZESTATDESC(224, "responses sent 224-239 bytes", "224-239", out); - SET_SIZESTATDESC(240, "responses sent 240-255 bytes", "240-255", out); - SET_SIZESTATDESC(256, "responses sent 256-271 bytes", "256-271", out); - SET_SIZESTATDESC(272, "responses sent 272-287 bytes", "272-287", out); - SET_SIZESTATDESC(288, "responses sent 288-303 bytes", "288-303", out); - SET_SIZESTATDESC(304, "responses sent 304-319 bytes", "304-319", out); - SET_SIZESTATDESC(320, "responses sent 320-335 bytes", "320-335", out); - SET_SIZESTATDESC(336, "responses sent 336-351 bytes", "336-351", out); - SET_SIZESTATDESC(352, "responses sent 352-367 bytes", "352-367", out); - SET_SIZESTATDESC(368, "responses sent 368-383 bytes", "368-383", out); - SET_SIZESTATDESC(384, "responses sent 384-399 bytes", "384-399", out); - SET_SIZESTATDESC(400, "responses sent 400-415 bytes", "400-415", out); - SET_SIZESTATDESC(416, "responses sent 416-431 bytes", "416-431", out); - SET_SIZESTATDESC(432, "responses sent 432-447 bytes", "432-447", out); - SET_SIZESTATDESC(448, "responses sent 448-463 bytes", "448-463", out); - SET_SIZESTATDESC(464, "responses sent 464-479 bytes", "464-479", out); - SET_SIZESTATDESC(480, "responses sent 480-495 bytes", "480-495", out); - SET_SIZESTATDESC(496, "responses sent 496-511 bytes", "496-511", out); - SET_SIZESTATDESC(512, "responses sent 512-527 bytes", "512-527", out); - SET_SIZESTATDESC(528, "responses sent 528-543 bytes", "528-543", out); - SET_SIZESTATDESC(544, "responses sent 544-559 bytes", "544-559", out); - SET_SIZESTATDESC(560, "responses sent 560-575 bytes", "560-575", out); - SET_SIZESTATDESC(576, "responses sent 576-591 bytes", "576-591", out); - SET_SIZESTATDESC(592, "responses sent 592-607 bytes", "592-607", out); - SET_SIZESTATDESC(608, "responses sent 608-623 bytes", "608-623", out); - SET_SIZESTATDESC(624, "responses sent 624-639 bytes", "624-639", out); - SET_SIZESTATDESC(640, "responses sent 640-655 bytes", "640-655", out); - SET_SIZESTATDESC(656, "responses sent 656-671 bytes", "656-671", out); - SET_SIZESTATDESC(672, "responses sent 672-687 bytes", "672-687", out); - SET_SIZESTATDESC(688, "responses sent 688-703 bytes", "688-703", out); - SET_SIZESTATDESC(704, "responses sent 704-719 bytes", "704-719", out); - SET_SIZESTATDESC(720, "responses sent 720-735 bytes", "720-735", out); - SET_SIZESTATDESC(736, "responses sent 736-751 bytes", "736-751", out); - SET_SIZESTATDESC(752, "responses sent 752-767 bytes", "752-767", out); - SET_SIZESTATDESC(768, "responses sent 768-783 bytes", "768-783", out); - SET_SIZESTATDESC(784, "responses sent 784-799 bytes", "784-799", out); - SET_SIZESTATDESC(800, "responses sent 800-815 bytes", "800-815", out); - SET_SIZESTATDESC(816, "responses sent 816-831 bytes", "816-831", out); - SET_SIZESTATDESC(832, "responses sent 832-847 bytes", "832-847", out); - SET_SIZESTATDESC(848, "responses sent 848-863 bytes", "848-863", out); - SET_SIZESTATDESC(864, "responses sent 864-879 bytes", "864-879", out); - SET_SIZESTATDESC(880, "responses sent 880-895 bytes", "880-895", out); - SET_SIZESTATDESC(896, "responses sent 896-911 bytes", "896-911", out); - SET_SIZESTATDESC(912, "responses sent 912-927 bytes", "912-927", out); - SET_SIZESTATDESC(928, "responses sent 928-943 bytes", "928-943", out); - SET_SIZESTATDESC(944, "responses sent 944-959 bytes", "944-959", out); - SET_SIZESTATDESC(960, "responses sent 960-975 bytes", "960-975", out); - SET_SIZESTATDESC(976, "responses sent 976-991 bytes", "976-991", out); - SET_SIZESTATDESC(992, "responses sent 992-1007 bytes", "992-1007", out); - SET_SIZESTATDESC(1008, "responses sent 1008-1023 bytes", "1008-1023", out); - SET_SIZESTATDESC(1024, "responses sent 1024-1039 bytes", "1024-1039", out); - SET_SIZESTATDESC(1040, "responses sent 1040-1055 bytes", "1040-1055", out); - SET_SIZESTATDESC(1056, "responses sent 1056-1071 bytes", "1056-1071", out); - SET_SIZESTATDESC(1072, "responses sent 1072-1087 bytes", "1072-1087", out); - SET_SIZESTATDESC(1088, "responses sent 1088-1103 bytes", "1088-1103", out); - SET_SIZESTATDESC(1104, "responses sent 1104-1119 bytes", "1104-1119", out); - SET_SIZESTATDESC(1120, "responses sent 1120-1135 bytes", "1120-1135", out); - SET_SIZESTATDESC(1136, "responses sent 1136-1151 bytes", "1136-1151", out); - SET_SIZESTATDESC(1152, "responses sent 1152-1167 bytes", "1152-1167", out); - SET_SIZESTATDESC(1168, "responses sent 1168-1183 bytes", "1168-1183", out); - SET_SIZESTATDESC(1184, "responses sent 1184-1199 bytes", "1184-1199", out); - SET_SIZESTATDESC(1200, "responses sent 1200-1215 bytes", "1200-1215", out); - SET_SIZESTATDESC(1216, "responses sent 1216-1231 bytes", "1216-1231", out); - SET_SIZESTATDESC(1232, "responses sent 1232-1247 bytes", "1232-1247", out); - SET_SIZESTATDESC(1248, "responses sent 1248-1263 bytes", "1248-1263", out); - SET_SIZESTATDESC(1264, "responses sent 1264-1279 bytes", "1264-1279", out); - SET_SIZESTATDESC(1280, "responses sent 1280-1295 bytes", "1280-1295", out); - SET_SIZESTATDESC(1296, "responses sent 1296-1311 bytes", "1296-1311", out); - SET_SIZESTATDESC(1312, "responses sent 1312-1327 bytes", "1312-1327", out); - SET_SIZESTATDESC(1328, "responses sent 1328-1343 bytes", "1328-1343", out); - SET_SIZESTATDESC(1344, "responses sent 1344-1359 bytes", "1344-1359", out); - SET_SIZESTATDESC(1360, "responses sent 1360-1375 bytes", "1360-1375", out); - SET_SIZESTATDESC(1376, "responses sent 1376-1391 bytes", "1376-1391", out); - SET_SIZESTATDESC(1392, "responses sent 1392-1407 bytes", "1392-1407", out); - SET_SIZESTATDESC(1408, "responses sent 1408-1423 bytes", "1408-1423", out); - SET_SIZESTATDESC(1424, "responses sent 1424-1439 bytes", "1424-1439", out); - SET_SIZESTATDESC(1440, "responses sent 1440-1455 bytes", "1440-1455", out); - SET_SIZESTATDESC(1456, "responses sent 1456-1471 bytes", "1456-1471", out); - SET_SIZESTATDESC(1472, "responses sent 1472-1487 bytes", "1472-1487", out); - SET_SIZESTATDESC(1488, "responses sent 1488-1503 bytes", "1488-1503", out); - SET_SIZESTATDESC(1504, "responses sent 1504-1519 bytes", "1504-1519", out); - SET_SIZESTATDESC(1520, "responses sent 1520-1535 bytes", "1520-1535", out); - SET_SIZESTATDESC(1536, "responses sent 1536-1551 bytes", "1536-1551", out); - SET_SIZESTATDESC(1552, "responses sent 1552-1567 bytes", "1552-1567", out); - SET_SIZESTATDESC(1568, "responses sent 1568-1583 bytes", "1568-1583", out); - SET_SIZESTATDESC(1584, "responses sent 1584-1599 bytes", "1584-1599", out); - SET_SIZESTATDESC(1600, "responses sent 1600-1615 bytes", "1600-1615", out); - SET_SIZESTATDESC(1616, "responses sent 1616-1631 bytes", "1616-1631", out); - SET_SIZESTATDESC(1632, "responses sent 1632-1647 bytes", "1632-1647", out); - SET_SIZESTATDESC(1648, "responses sent 1648-1663 bytes", "1648-1663", out); - SET_SIZESTATDESC(1664, "responses sent 1664-1679 bytes", "1664-1679", out); - SET_SIZESTATDESC(1680, "responses sent 1680-1695 bytes", "1680-1695", out); - SET_SIZESTATDESC(1696, "responses sent 1696-1711 bytes", "1696-1711", out); - SET_SIZESTATDESC(1712, "responses sent 1712-1727 bytes", "1712-1727", out); - SET_SIZESTATDESC(1728, "responses sent 1728-1743 bytes", "1728-1743", out); - SET_SIZESTATDESC(1744, "responses sent 1744-1759 bytes", "1744-1759", out); - SET_SIZESTATDESC(1760, "responses sent 1760-1775 bytes", "1760-1775", out); - SET_SIZESTATDESC(1776, "responses sent 1776-1791 bytes", "1776-1791", out); - SET_SIZESTATDESC(1792, "responses sent 1792-1807 bytes", "1792-1807", out); - SET_SIZESTATDESC(1808, "responses sent 1808-1823 bytes", "1808-1823", out); - SET_SIZESTATDESC(1824, "responses sent 1824-1839 bytes", "1824-1839", out); - SET_SIZESTATDESC(1840, "responses sent 1840-1855 bytes", "1840-1855", out); - SET_SIZESTATDESC(1856, "responses sent 1856-1871 bytes", "1856-1871", out); - SET_SIZESTATDESC(1872, "responses sent 1872-1887 bytes", "1872-1887", out); - SET_SIZESTATDESC(1888, "responses sent 1888-1903 bytes", "1888-1903", out); - SET_SIZESTATDESC(1904, "responses sent 1904-1919 bytes", "1904-1919", out); - SET_SIZESTATDESC(1920, "responses sent 1920-1935 bytes", "1920-1935", out); - SET_SIZESTATDESC(1936, "responses sent 1936-1951 bytes", "1936-1951", out); - SET_SIZESTATDESC(1952, "responses sent 1952-1967 bytes", "1952-1967", out); - SET_SIZESTATDESC(1968, "responses sent 1968-1983 bytes", "1968-1983", out); - SET_SIZESTATDESC(1984, "responses sent 1984-1999 bytes", "1984-1999", out); - SET_SIZESTATDESC(2000, "responses sent 2000-2015 bytes", "2000-2015", out); - SET_SIZESTATDESC(2016, "responses sent 2016-2031 bytes", "2016-2031", out); - SET_SIZESTATDESC(2032, "responses sent 2032-2047 bytes", "2032-2047", out); - SET_SIZESTATDESC(2048, "responses sent 2048-2063 bytes", "2048-2063", out); - SET_SIZESTATDESC(2064, "responses sent 2064-2079 bytes", "2064-2079", out); - SET_SIZESTATDESC(2080, "responses sent 2080-2095 bytes", "2080-2095", out); - SET_SIZESTATDESC(2096, "responses sent 2096-2111 bytes", "2096-2111", out); - SET_SIZESTATDESC(2112, "responses sent 2112-2127 bytes", "2112-2127", out); - SET_SIZESTATDESC(2128, "responses sent 2128-2143 bytes", "2128-2143", out); - SET_SIZESTATDESC(2144, "responses sent 2144-2159 bytes", "2144-2159", out); - SET_SIZESTATDESC(2160, "responses sent 2160-2175 bytes", "2160-2175", out); - SET_SIZESTATDESC(2176, "responses sent 2176-2191 bytes", "2176-2191", out); - SET_SIZESTATDESC(2192, "responses sent 2192-2207 bytes", "2192-2207", out); - SET_SIZESTATDESC(2208, "responses sent 2208-2223 bytes", "2208-2223", out); - SET_SIZESTATDESC(2224, "responses sent 2224-2239 bytes", "2224-2239", out); - SET_SIZESTATDESC(2240, "responses sent 2240-2255 bytes", "2240-2255", out); - SET_SIZESTATDESC(2256, "responses sent 2256-2271 bytes", "2256-2271", out); - SET_SIZESTATDESC(2272, "responses sent 2272-2287 bytes", "2272-2287", out); - SET_SIZESTATDESC(2288, "responses sent 2288-2303 bytes", "2288-2303", out); - SET_SIZESTATDESC(2304, "responses sent 2304-2319 bytes", "2304-2319", out); - SET_SIZESTATDESC(2320, "responses sent 2320-2335 bytes", "2320-2335", out); - SET_SIZESTATDESC(2336, "responses sent 2336-2351 bytes", "2336-2351", out); - SET_SIZESTATDESC(2352, "responses sent 2352-2367 bytes", "2352-2367", out); - SET_SIZESTATDESC(2368, "responses sent 2368-2383 bytes", "2368-2383", out); - SET_SIZESTATDESC(2384, "responses sent 2384-2399 bytes", "2384-2399", out); - SET_SIZESTATDESC(2400, "responses sent 2400-2415 bytes", "2400-2415", out); - SET_SIZESTATDESC(2416, "responses sent 2416-2431 bytes", "2416-2431", out); - SET_SIZESTATDESC(2432, "responses sent 2432-2447 bytes", "2432-2447", out); - SET_SIZESTATDESC(2448, "responses sent 2448-2463 bytes", "2448-2463", out); - SET_SIZESTATDESC(2464, "responses sent 2464-2479 bytes", "2464-2479", out); - SET_SIZESTATDESC(2480, "responses sent 2480-2495 bytes", "2480-2495", out); - SET_SIZESTATDESC(2496, "responses sent 2496-2511 bytes", "2496-2511", out); - SET_SIZESTATDESC(2512, "responses sent 2512-2527 bytes", "2512-2527", out); - SET_SIZESTATDESC(2528, "responses sent 2528-2543 bytes", "2528-2543", out); - SET_SIZESTATDESC(2544, "responses sent 2544-2559 bytes", "2544-2559", out); - SET_SIZESTATDESC(2560, "responses sent 2560-2575 bytes", "2560-2575", out); - SET_SIZESTATDESC(2576, "responses sent 2576-2591 bytes", "2576-2591", out); - SET_SIZESTATDESC(2592, "responses sent 2592-2607 bytes", "2592-2607", out); - SET_SIZESTATDESC(2608, "responses sent 2608-2623 bytes", "2608-2623", out); - SET_SIZESTATDESC(2624, "responses sent 2624-2639 bytes", "2624-2639", out); - SET_SIZESTATDESC(2640, "responses sent 2640-2655 bytes", "2640-2655", out); - SET_SIZESTATDESC(2656, "responses sent 2656-2671 bytes", "2656-2671", out); - SET_SIZESTATDESC(2672, "responses sent 2672-2687 bytes", "2672-2687", out); - SET_SIZESTATDESC(2688, "responses sent 2688-2703 bytes", "2688-2703", out); - SET_SIZESTATDESC(2704, "responses sent 2704-2719 bytes", "2704-2719", out); - SET_SIZESTATDESC(2720, "responses sent 2720-2735 bytes", "2720-2735", out); - SET_SIZESTATDESC(2736, "responses sent 2736-2751 bytes", "2736-2751", out); - SET_SIZESTATDESC(2752, "responses sent 2752-2767 bytes", "2752-2767", out); - SET_SIZESTATDESC(2768, "responses sent 2768-2783 bytes", "2768-2783", out); - SET_SIZESTATDESC(2784, "responses sent 2784-2799 bytes", "2784-2799", out); - SET_SIZESTATDESC(2800, "responses sent 2800-2815 bytes", "2800-2815", out); - SET_SIZESTATDESC(2816, "responses sent 2816-2831 bytes", "2816-2831", out); - SET_SIZESTATDESC(2832, "responses sent 2832-2847 bytes", "2832-2847", out); - SET_SIZESTATDESC(2848, "responses sent 2848-2863 bytes", "2848-2863", out); - SET_SIZESTATDESC(2864, "responses sent 2864-2879 bytes", "2864-2879", out); - SET_SIZESTATDESC(2880, "responses sent 2880-2895 bytes", "2880-2895", out); - SET_SIZESTATDESC(2896, "responses sent 2896-2911 bytes", "2896-2911", out); - SET_SIZESTATDESC(2912, "responses sent 2912-2927 bytes", "2912-2927", out); - SET_SIZESTATDESC(2928, "responses sent 2928-2943 bytes", "2928-2943", out); - SET_SIZESTATDESC(2944, "responses sent 2944-2959 bytes", "2944-2959", out); - SET_SIZESTATDESC(2960, "responses sent 2960-2975 bytes", "2960-2975", out); - SET_SIZESTATDESC(2976, "responses sent 2976-2991 bytes", "2976-2991", out); - SET_SIZESTATDESC(2992, "responses sent 2992-3007 bytes", "2992-3007", out); - SET_SIZESTATDESC(3008, "responses sent 3008-3023 bytes", "3008-3023", out); - SET_SIZESTATDESC(3024, "responses sent 3024-3039 bytes", "3024-3039", out); - SET_SIZESTATDESC(3040, "responses sent 3040-3055 bytes", "3040-3055", out); - SET_SIZESTATDESC(3056, "responses sent 3056-3071 bytes", "3056-3071", out); - SET_SIZESTATDESC(3072, "responses sent 3072-3087 bytes", "3072-3087", out); - SET_SIZESTATDESC(3088, "responses sent 3088-3103 bytes", "3088-3103", out); - SET_SIZESTATDESC(3104, "responses sent 3104-3119 bytes", "3104-3119", out); - SET_SIZESTATDESC(3120, "responses sent 3120-3135 bytes", "3120-3135", out); - SET_SIZESTATDESC(3136, "responses sent 3136-3151 bytes", "3136-3151", out); - SET_SIZESTATDESC(3152, "responses sent 3152-3167 bytes", "3152-3167", out); - SET_SIZESTATDESC(3168, "responses sent 3168-3183 bytes", "3168-3183", out); - SET_SIZESTATDESC(3184, "responses sent 3184-3199 bytes", "3184-3199", out); - SET_SIZESTATDESC(3200, "responses sent 3200-3215 bytes", "3200-3215", out); - SET_SIZESTATDESC(3216, "responses sent 3216-3231 bytes", "3216-3231", out); - SET_SIZESTATDESC(3232, "responses sent 3232-3247 bytes", "3232-3247", out); - SET_SIZESTATDESC(3248, "responses sent 3248-3263 bytes", "3248-3263", out); - SET_SIZESTATDESC(3264, "responses sent 3264-3279 bytes", "3264-3279", out); - SET_SIZESTATDESC(3280, "responses sent 3280-3295 bytes", "3280-3295", out); - SET_SIZESTATDESC(3296, "responses sent 3296-3311 bytes", "3296-3311", out); - SET_SIZESTATDESC(3312, "responses sent 3312-3327 bytes", "3312-3327", out); - SET_SIZESTATDESC(3328, "responses sent 3328-3343 bytes", "3328-3343", out); - SET_SIZESTATDESC(3344, "responses sent 3344-3359 bytes", "3344-3359", out); - SET_SIZESTATDESC(3360, "responses sent 3360-3375 bytes", "3360-3375", out); - SET_SIZESTATDESC(3376, "responses sent 3376-3391 bytes", "3376-3391", out); - SET_SIZESTATDESC(3392, "responses sent 3392-3407 bytes", "3392-3407", out); - SET_SIZESTATDESC(3408, "responses sent 3408-3423 bytes", "3408-3423", out); - SET_SIZESTATDESC(3424, "responses sent 3424-3439 bytes", "3424-3439", out); - SET_SIZESTATDESC(3440, "responses sent 3440-3455 bytes", "3440-3455", out); - SET_SIZESTATDESC(3456, "responses sent 3456-3471 bytes", "3456-3471", out); - SET_SIZESTATDESC(3472, "responses sent 3472-3487 bytes", "3472-3487", out); - SET_SIZESTATDESC(3488, "responses sent 3488-3503 bytes", "3488-3503", out); - SET_SIZESTATDESC(3504, "responses sent 3504-3519 bytes", "3504-3519", out); - SET_SIZESTATDESC(3520, "responses sent 3520-3535 bytes", "3520-3535", out); - SET_SIZESTATDESC(3536, "responses sent 3536-3551 bytes", "3536-3551", out); - SET_SIZESTATDESC(3552, "responses sent 3552-3567 bytes", "3552-3567", out); - SET_SIZESTATDESC(3568, "responses sent 3568-3583 bytes", "3568-3583", out); - SET_SIZESTATDESC(3584, "responses sent 3584-3599 bytes", "3584-3599", out); - SET_SIZESTATDESC(3600, "responses sent 3600-3615 bytes", "3600-3615", out); - SET_SIZESTATDESC(3616, "responses sent 3616-3631 bytes", "3616-3631", out); - SET_SIZESTATDESC(3632, "responses sent 3632-3647 bytes", "3632-3647", out); - SET_SIZESTATDESC(3648, "responses sent 3648-3663 bytes", "3648-3663", out); - SET_SIZESTATDESC(3664, "responses sent 3664-3679 bytes", "3664-3679", out); - SET_SIZESTATDESC(3680, "responses sent 3680-3695 bytes", "3680-3695", out); - SET_SIZESTATDESC(3696, "responses sent 3696-3711 bytes", "3696-3711", out); - SET_SIZESTATDESC(3712, "responses sent 3712-3727 bytes", "3712-3727", out); - SET_SIZESTATDESC(3728, "responses sent 3728-3743 bytes", "3728-3743", out); - SET_SIZESTATDESC(3744, "responses sent 3744-3759 bytes", "3744-3759", out); - SET_SIZESTATDESC(3760, "responses sent 3760-3775 bytes", "3760-3775", out); - SET_SIZESTATDESC(3776, "responses sent 3776-3791 bytes", "3776-3791", out); - SET_SIZESTATDESC(3792, "responses sent 3792-3807 bytes", "3792-3807", out); - SET_SIZESTATDESC(3808, "responses sent 3808-3823 bytes", "3808-3823", out); - SET_SIZESTATDESC(3824, "responses sent 3824-3839 bytes", "3824-3839", out); - SET_SIZESTATDESC(3840, "responses sent 3840-3855 bytes", "3840-3855", out); - SET_SIZESTATDESC(3856, "responses sent 3856-3871 bytes", "3856-3871", out); - SET_SIZESTATDESC(3872, "responses sent 3872-3887 bytes", "3872-3887", out); - SET_SIZESTATDESC(3888, "responses sent 3888-3903 bytes", "3888-3903", out); - SET_SIZESTATDESC(3904, "responses sent 3904-3919 bytes", "3904-3919", out); - SET_SIZESTATDESC(3920, "responses sent 3920-3935 bytes", "3920-3935", out); - SET_SIZESTATDESC(3936, "responses sent 3936-3951 bytes", "3936-3951", out); - SET_SIZESTATDESC(3952, "responses sent 3952-3967 bytes", "3952-3967", out); - SET_SIZESTATDESC(3968, "responses sent 3968-3983 bytes", "3968-3983", out); - SET_SIZESTATDESC(3984, "responses sent 3984-3999 bytes", "3984-3999", out); - SET_SIZESTATDESC(4000, "responses sent 4000-4015 bytes", "4000-4015", out); - SET_SIZESTATDESC(4016, "responses sent 4016-4031 bytes", "4016-4031", out); - SET_SIZESTATDESC(4032, "responses sent 4032-4047 bytes", "4032-4047", out); - SET_SIZESTATDESC(4048, "responses sent 4048-4063 bytes", "4048-4063", out); - SET_SIZESTATDESC(4064, "responses sent 4064-4079 bytes", "4064-4079", out); - SET_SIZESTATDESC(4080, "responses sent 4080-4095 bytes", "4080-4095", out); - SET_SIZESTATDESC(4096, "responses sent 4096+ bytes", "4096+", out); - INSIST(i == dns_sizecounter_out_max); - - /* Sanity check */ - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_desc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_desc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_desc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_desc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_desc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_desc[i] != NULL); - for (i = 0; i < dns_sizecounter_in_max; i++) { - INSIST(udpinsizestats_desc[i] != NULL); - INSIST(tcpinsizestats_desc[i] != NULL); - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - INSIST(udpoutsizestats_desc[i] != NULL); - INSIST(tcpoutsizestats_desc[i] != NULL); - } -#if defined(EXTENDED_STATS) - for (i = 0; i < dns_nsstatscounter_max; i++) - INSIST(nsstats_xmldesc[i] != NULL); - for (i = 0; i < dns_resstatscounter_max; i++) - INSIST(resstats_xmldesc[i] != NULL); - for (i = 0; i < dns_adbstats_max; i++) - INSIST(adbstats_xmldesc[i] != NULL); - for (i = 0; i < dns_zonestatscounter_max; i++) - INSIST(zonestats_xmldesc[i] != NULL); - for (i = 0; i < isc_sockstatscounter_max; i++) - INSIST(sockstats_xmldesc[i] != NULL); - for (i = 0; i < dns_dnssecstats_max; i++) - INSIST(dnssecstats_xmldesc[i] != NULL); - for (i = 0; i < dns_sizecounter_in_max; i++) { - INSIST(udpinsizestats_xmldesc[i] != NULL); - INSIST(tcpinsizestats_xmldesc[i] != NULL); - } - for (i = 0; i < dns_sizecounter_out_max; i++) { - INSIST(udpoutsizestats_xmldesc[i] != NULL); - INSIST(tcpoutsizestats_xmldesc[i] != NULL); - } -#endif -} - -/*% - * Dump callback functions. - */ -static void -generalstat_dump(isc_statscounter_t counter, uint64_t val, void *arg) { - stats_dumparg_t *dumparg = arg; - - REQUIRE(counter < dumparg->ncounters); - dumparg->countervalues[counter] = val; -} - -static isc_result_t -dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg, - const char *category, const char **desc, int ncounters, - int *indices, uint64_t *values, int options) -{ - int i, idx; - uint64_t value; - stats_dumparg_t dumparg; - FILE *fp; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *job, *cat, *counter; -#endif - -#if !defined(EXTENDED_STATS) - UNUSED(category); -#endif - - dumparg.type = type; - dumparg.ncounters = ncounters; - dumparg.counterindices = indices; - dumparg.countervalues = values; - - memset(values, 0, sizeof(values[0]) * ncounters); - isc_stats_dump(stats, generalstat_dump, &dumparg, options); - -#ifdef HAVE_JSON - cat = job = (json_object *) arg; - if (ncounters > 0 && type == isc_statsformat_json) { - if (category != NULL) { - cat = json_object_new_object(); - if (cat == NULL) - return (ISC_R_NOMEMORY); - json_object_object_add(job, category, cat); - } - } -#endif - - for (i = 0; i < ncounters; i++) { - idx = indices[i]; - value = values[idx]; - - if (value == 0 && (options & ISC_STATSDUMP_VERBOSE) == 0) - continue; - - switch (dumparg.type) { - case isc_statsformat_file: - fp = arg; - fprintf(fp, "%20" PRIu64 " %s\n", - value, desc[idx]); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = (xmlTextWriterPtr) arg; - - if (category != NULL) { - /* */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - category)); - - /* inside category */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "name")); - TRY0(xmlTextWriterWriteString(writer, - ISC_XMLCHAR - desc[idx])); - TRY0(xmlTextWriterEndElement(writer)); - /* */ - - /* */ - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "counter")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, value)); - - TRY0(xmlTextWriterEndElement(writer)); - /* */ - TRY0(xmlTextWriterEndElement(writer)); - /* */ - - } else { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR - "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR - "name", - ISC_XMLCHAR - desc[idx])); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, value)); - TRY0(xmlTextWriterEndElement(writer)); - /* counter */ - } - -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - counter = json_object_new_int64(value); - if (counter == NULL) - return (ISC_R_NOMEMORY); - json_object_object_add(cat, desc[idx], counter); -#endif - break; - } - } - return (ISC_R_SUCCESS); -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at dump_counters()"); - return (ISC_R_FAILURE); -#endif -} - -static void -rdtypestat_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) { - char typebuf[64]; - const char *typestr; - stats_dumparg_t *dumparg = arg; - FILE *fp; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) - == 0) { - dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf, - sizeof(typebuf)); - typestr = typebuf; - } else - typestr = "Others"; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, typestr); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR typestr)); - - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - - TRY0(xmlTextWriterEndElement(writer)); /* type */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, typestr, obj); -#endif - break; - } - return; -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rdtypestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -static void -rdatasetstats_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) { - stats_dumparg_t *dumparg = arg; - FILE *fp; - char typebuf[64]; - const char *typestr; - bool nxrrset = false; - bool stale = false; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; - char buf[1024]; -#endif - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) - != 0) { - typestr = "NXDOMAIN"; - } else if ((DNS_RDATASTATSTYPE_ATTR(type) & - DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0) { - typestr = "Others"; - } else { - dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf, - sizeof(typebuf)); - typestr = typebuf; - } - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXRRSET) - != 0) - nxrrset = true; - - if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_STALE) - != 0) - stale = true; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s%s%s\n", val, - stale ? "#" : "", nxrrset ? "!" : "", typestr); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteFormatString(writer, "%s%s%s", - stale ? "#" : "", - nxrrset ? "!" : "", typestr)); - TRY0(xmlTextWriterEndElement(writer)); /* name */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ - - TRY0(xmlTextWriterEndElement(writer)); /* rrset */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - snprintf(buf, sizeof(buf), "%s%s%s", - stale ? "#" : "", nxrrset ? "!" : "", typestr); - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, buf, obj); -#endif - break; - } - return; -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rdatasetstats_dump()"); - dumparg->result = ISC_R_FAILURE; -#endif - -} - -static void -opcodestat_dump(dns_opcode_t code, uint64_t val, void *arg) { - FILE *fp; - isc_buffer_t b; - char codebuf[64]; - stats_dumparg_t *dumparg = arg; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); - dns_opcode_totext(code, &b); - codebuf[isc_buffer_usedlength(&b)] = '\0'; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR codebuf )); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, codebuf, obj); -#endif - break; - } - return; - -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at opcodestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -static void -rcodestat_dump(dns_rcode_t code, uint64_t val, void *arg) { - FILE *fp; - isc_buffer_t b; - char codebuf[64]; - stats_dumparg_t *dumparg = arg; -#ifdef HAVE_LIBXML2 - xmlTextWriterPtr writer; - int xmlrc; -#endif -#ifdef HAVE_JSON - json_object *zoneobj, *obj; -#endif - - isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); - dns_rcode_totext(code, &b); - codebuf[isc_buffer_usedlength(&b)] = '\0'; - - switch (dumparg->type) { - case isc_statsformat_file: - fp = dumparg->arg; - fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf); - break; - case isc_statsformat_xml: -#ifdef HAVE_LIBXML2 - writer = dumparg->arg; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR codebuf )); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ -#endif - break; - case isc_statsformat_json: -#ifdef HAVE_JSON - zoneobj = (json_object *) dumparg->arg; - obj = json_object_new_int64(val); - if (obj == NULL) - return; - json_object_object_add(zoneobj, codebuf, obj); -#endif - break; - } - return; - -#ifdef HAVE_LIBXML2 - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed at rcodestat_dump()"); - dumparg->result = ISC_R_FAILURE; - return; -#endif -} - -#ifdef HAVE_LIBXML2 -/* - * Which statistics to include when rendering to XML - */ -#define STATS_XML_STATUS 0x00 /* display only common statistics */ -#define STATS_XML_SERVER 0x01 -#define STATS_XML_ZONES 0x02 -#define STATS_XML_TASKS 0x04 -#define STATS_XML_NET 0x08 -#define STATS_XML_MEM 0x10 -#define STATS_XML_TRAFFIC 0x20 -#define STATS_XML_ALL 0xff - -static isc_result_t -zone_xmlrender(dns_zone_t *zone, void *arg) { - isc_result_t result; - char buf[1024 + 32]; /* sufficiently large for zone name and class */ - dns_rdataclass_t rdclass; - uint32_t serial; - xmlTextWriterPtr writer = arg; - isc_stats_t *zonestats; - dns_stats_t *rcvquerystats; - dns_zonestat_level_t statlevel; - uint64_t nsstat_values[dns_nsstatscounter_max]; - int xmlrc; - stats_dumparg_t dumparg; - const char *ztype; - - statlevel = dns_zone_getstatlevel(zone); - if (statlevel == dns_zonestat_none) - return (ISC_R_SUCCESS); - - dumparg.type = isc_statsformat_xml; - dumparg.arg = writer; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); - - dns_zone_nameonly(zone, buf, sizeof(buf)); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR buf)); - - rdclass = dns_zone_getclass(zone); - dns_rdataclass_format(rdclass, buf, sizeof(buf)); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass", - ISC_XMLCHAR buf)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); - ztype = user_zonetype(zone); - if (ztype != NULL) - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ztype)); - else - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "unknown")); - TRY0(xmlTextWriterEndElement(writer)); /* type */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial")); - if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS) - TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial)); - else - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-")); - TRY0(xmlTextWriterEndElement(writer)); /* serial */ - - zonestats = dns_zone_getrequeststats(zone); - rcvquerystats = dns_zone_getrcvquerystats(zone); - if (statlevel == dns_zonestat_full && zonestats != NULL) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "rcode")); - - result = dump_counters(zonestats, isc_statsformat_xml, writer, - NULL, nsstats_xmldesc, - dns_nsstatscounter_max, nsstats_index, - nsstat_values, ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - /* counters type="rcode"*/ - TRY0(xmlTextWriterEndElement(writer)); - } - - if (statlevel == dns_zonestat_full && rcvquerystats != NULL) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "qtype")); - - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if(dumparg.result != ISC_R_SUCCESS) - goto error; - - /* counters type="qtype"*/ - TRY0(xmlTextWriterEndElement(writer)); - } - - TRY0(xmlTextWriterEndElement(writer)); /* zone */ - - return (ISC_R_SUCCESS); - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "Failed at zone_xmlrender()"); - return (ISC_R_FAILURE); -} - -static isc_result_t -generatexml(ns_server_t *server, uint32_t flags, - int *buflen, xmlChar **buf) -{ - char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - isc_time_t now; - xmlTextWriterPtr writer = NULL; - xmlDocPtr doc = NULL; - int xmlrc; - dns_view_t *view; - stats_dumparg_t dumparg; - dns_stats_t *cacherrstats; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - uint64_t udpinsizestat_values[dns_sizecounter_in_max]; - uint64_t udpoutsizestat_values[dns_sizecounter_out_max]; - uint64_t tcpinsizestat_values[dns_sizecounter_in_max]; - uint64_t tcpoutsizestat_values[dns_sizecounter_out_max]; -#ifdef HAVE_DNSTAP - uint64_t dnstapstat_values[dns_dnstapcounter_max]; -#endif - isc_result_t result; - - isc_time_now(&now); - isc_time_formatISO8601ms(&ns_g_boottime, boottime, sizeof boottime); - isc_time_formatISO8601ms(&ns_g_configtime, configtime, sizeof configtime); - isc_time_formatISO8601ms(&now, nowstr, sizeof nowstr); - - writer = xmlNewTextWriterDoc(&doc, 0); - if (writer == NULL) - goto error; - TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); - TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", - ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "3.8")); - - /* Set common fields for statistics dump */ - dumparg.type = isc_statsformat_xml; - dumparg.arg = writer; - - /* Render server information */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime)); - TRY0(xmlTextWriterEndElement(writer)); /* boot-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "config-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR configtime)); - TRY0(xmlTextWriterEndElement(writer)); /* config-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr)); - TRY0(xmlTextWriterEndElement(writer)); /* current-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "version")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ns_g_version)); - TRY0(xmlTextWriterEndElement(writer)); /* version */ - - if ((flags & STATS_XML_SERVER) != 0) { - dumparg.result = ISC_R_SUCCESS; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "opcode")); - - dns_opcodestats_dump(server->opcodestats, opcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "rcode")); - - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "qtype")); - - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* counters */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "nsstat")); - - result = dump_counters(server->nsstats, isc_statsformat_xml, - writer, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /nsstat */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "zonestat")); - - result = dump_counters(server->zonestats, isc_statsformat_xml, - writer, NULL, zonestats_xmldesc, - dns_zonestatscounter_max, - zonestats_index, zonestat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /zonestat */ - - /* - * Most of the common resolver statistics entries are 0, so - * we don't use the verbose dump here. - */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resstat")); - result = dump_counters(server->resolverstats, - isc_statsformat_xml, writer, - NULL, resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* resstat */ - -#ifdef HAVE_DNSTAP - if (server->dtenv != NULL) { - isc_stats_t *dnstapstats = NULL; - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "type", - ISC_XMLCHAR "dnstap")); - dns_dt_getstats(ns_g_server->dtenv, &dnstapstats); - result = dump_counters(dnstapstats, - isc_statsformat_xml, writer, - NULL, dnstapstats_xmldesc, - dns_dnstapcounter_max, - dnstapstats_index, - dnstapstat_values, 0); - isc_stats_detach(&dnstapstats); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* dnstap */ - } -#endif - } - - if ((flags & STATS_XML_NET) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "sockstat")); - - result = dump_counters(server->sockstats, isc_statsformat_xml, - writer, NULL, sockstats_xmldesc, - isc_sockstatscounter_max, - sockstats_index, sockstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* /sockstat */ - } - TRY0(xmlTextWriterEndElement(writer)); /* /server */ - - if ((flags & STATS_XML_TRAFFIC) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "traffic")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv4")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->udpinstats4, - isc_statsformat_xml, writer, - NULL, udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->udpoutstats4, - isc_statsformat_xml, writer, - NULL, udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->tcpinstats4, - isc_statsformat_xml, writer, - NULL, tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->tcpoutstats4, - isc_statsformat_xml, writer, - NULL, tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv6")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->udpinstats6, - isc_statsformat_xml, writer, - NULL, udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->udpoutstats6, - isc_statsformat_xml, writer, - NULL, udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "request-size")); - - result = dump_counters(server->tcpinstats6, - isc_statsformat_xml, writer, - NULL, tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "response-size")); - - result = dump_counters(server->tcpoutstats6, - isc_statsformat_xml, writer, - NULL, tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0); - if (result != ISC_R_SUCCESS) - goto error; - - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - TRY0(xmlTextWriterEndElement(writer)); /* */ - } - - /* - * Render views. For each view we know of, call its - * rendering function. - */ - view = ISC_LIST_HEAD(server->viewlist); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); - while (view != NULL && - ((flags & (STATS_XML_SERVER | STATS_XML_ZONES)) != 0)) - { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", - ISC_XMLCHAR view->name)); - - if ((flags & STATS_XML_ZONES) != 0) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "zones")); - result = dns_zt_apply(view->zonetable, true, - zone_xmlrender, writer); - if (result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* /zones */ - } - - if ((flags & STATS_XML_SERVER) == 0) { - TRY0(xmlTextWriterEndElement(writer)); /* /view */ - view = ISC_LIST_NEXT(view, link); - continue; - } - - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resqtype")); - - if (view->resquerystats != NULL) { - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(view->resquerystats, - rdtypestat_dump, &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "resstats")); - if (view->resstats != NULL) { - result = dump_counters(view->resstats, - isc_statsformat_xml, writer, - NULL, resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); /* */ - - cacherrstats = dns_db_getrrsetstats(view->cachedb); - if (cacherrstats != NULL) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "cache")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "name", - ISC_XMLCHAR - dns_cache_getname(view->cache))); - dumparg.result = ISC_R_SUCCESS; - dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) - goto error; - TRY0(xmlTextWriterEndElement(writer)); /* cache */ - } - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "adbstat")); - if (view->adbstats != NULL) { - result = dump_counters(view->adbstats, - isc_statsformat_xml, writer, - NULL, adbstats_xmldesc, - dns_adbstats_max, - adbstats_index, adbstat_values, - ISC_STATSDUMP_VERBOSE); - if (result != ISC_R_SUCCESS) - goto error; - } - TRY0(xmlTextWriterEndElement(writer)); /* */ - - /* */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR "cachestats")); - TRY0(dns_cache_renderxml(view->cache, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* */ - - TRY0(xmlTextWriterEndElement(writer)); /* view */ - - view = ISC_LIST_NEXT(view, link); - } - TRY0(xmlTextWriterEndElement(writer)); /* /views */ - - if ((flags & STATS_XML_NET) != 0) { - TRY0(xmlTextWriterStartElement(writer, - ISC_XMLCHAR "socketmgr")); - TRY0(isc_socketmgr_renderxml(ns_g_socketmgr, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /socketmgr */ - } - - if ((flags & STATS_XML_TASKS) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr")); - TRY0(isc_taskmgr_renderxml(ns_g_taskmgr, writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /taskmgr */ - } - - if ((flags & STATS_XML_MEM) != 0) { - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); - TRY0(isc_mem_renderxml(writer)); - TRY0(xmlTextWriterEndElement(writer)); /* /memory */ - } - - - TRY0(xmlTextWriterEndElement(writer)); /* /statistics */ - TRY0(xmlTextWriterEndDocument(writer)); - - xmlFreeTextWriter(writer); - - xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0); - if (*buf == NULL) - goto error; - xmlFreeDoc(doc); - return (ISC_R_SUCCESS); - - error: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, "failed generating XML response"); - if (writer != NULL) - xmlFreeTextWriter(writer); - if (doc != NULL) - xmlFreeDoc(doc); - return (ISC_R_FAILURE); -} - -static void -wrap_xmlfree(isc_buffer_t *buffer, void *arg) { - UNUSED(arg); - - xmlFree(isc_buffer_base(buffer)); -} - -static isc_result_t -render_xml(uint32_t flags, const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - unsigned char *msg = NULL; - int msglen; - ns_server_t *server = arg; - isc_result_t result; - - UNUSED(url); - UNUSED(urlinfo); - UNUSED(headers); - UNUSED(querystring); - - result = generatexml(server, flags, &msglen, &msg); - - if (result == ISC_R_SUCCESS) { - *retcode = 200; - *retmsg = "OK"; - *mimetype = "text/xml"; - isc_buffer_reinit(b, msg, msglen); - isc_buffer_add(b, msglen); - *freecb = wrap_xmlfree; - *freecb_args = NULL; - } else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed at rendering XML()"); - - return (result); -} - -static isc_result_t -render_xml_all(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_ALL, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_status(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_STATUS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_server(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_SERVER, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_zones(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_ZONES, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_net(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_NET, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_tasks(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_TASKS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_mem(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_MEM, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_xml_traffic(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_xml(STATS_XML_TRAFFIC, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -#endif /* HAVE_LIBXML2 */ - -#ifdef HAVE_JSON -/* - * Which statistics to include when rendering to JSON - */ -#define STATS_JSON_STATUS 0x00 /* display only common statistics */ -#define STATS_JSON_SERVER 0x01 -#define STATS_JSON_ZONES 0x02 -#define STATS_JSON_TASKS 0x04 -#define STATS_JSON_NET 0x08 -#define STATS_JSON_MEM 0x10 -#define STATS_JSON_TRAFFIC 0x20 -#define STATS_JSON_ALL 0xff - -#define CHECK(m) do { \ - result = (m); \ - if (result != ISC_R_SUCCESS) \ - goto error; \ -} while (0) - -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) - -static void -wrap_jsonfree(isc_buffer_t *buffer, void *arg) { - json_object_put(isc_buffer_base(buffer)); - if (arg != NULL) - json_object_put((json_object *) arg); -} - -static json_object * -addzone(char *name, char *classname, const char *ztype, - uint32_t serial, bool add_serial) -{ - json_object *node = json_object_new_object(); - - if (node == NULL) - return (NULL); - - json_object_object_add(node, "name", json_object_new_string(name)); - json_object_object_add(node, "class", - json_object_new_string(classname)); - if (add_serial) - json_object_object_add(node, "serial", - json_object_new_int64(serial)); - if (ztype != NULL) - json_object_object_add(node, "type", - json_object_new_string(ztype)); - return (node); -} - -static isc_result_t -zone_jsonrender(dns_zone_t *zone, void *arg) { - isc_result_t result = ISC_R_SUCCESS; - char buf[1024 + 32]; /* sufficiently large for zone name and class */ - char classbuf[64]; /* sufficiently large for class */ - char *zone_name_only = NULL; - char *class_only = NULL; - dns_rdataclass_t rdclass; - uint32_t serial; - uint64_t nsstat_values[dns_nsstatscounter_max]; - isc_stats_t *zonestats; - dns_stats_t *rcvquerystats; - json_object *zonearray = (json_object *) arg; - json_object *zoneobj = NULL; - dns_zonestat_level_t statlevel; - - statlevel = dns_zone_getstatlevel(zone); - if (statlevel == dns_zonestat_none) - return (ISC_R_SUCCESS); - - dns_zone_nameonly(zone, buf, sizeof(buf)); - zone_name_only = buf; - - rdclass = dns_zone_getclass(zone); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - class_only = classbuf; - - if (dns_zone_getserial2(zone, &serial) != ISC_R_SUCCESS) - zoneobj = addzone(zone_name_only, class_only, - user_zonetype(zone), 0, false); - else - zoneobj = addzone(zone_name_only, class_only, - user_zonetype(zone), serial, true); - - if (zoneobj == NULL) - return (ISC_R_NOMEMORY); - - zonestats = dns_zone_getrequeststats(zone); - rcvquerystats = dns_zone_getrcvquerystats(zone); - if (statlevel == dns_zonestat_full && zonestats != NULL) { - json_object *counters = json_object_new_object(); - if (counters == NULL) { - result = ISC_R_NOMEMORY; - goto error; - } - - result = dump_counters(zonestats, isc_statsformat_json, - counters, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, nsstats_index, - nsstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(zoneobj, "rcodes", counters); - else - json_object_put(counters); - } - - if (statlevel == dns_zonestat_full && rcvquerystats != NULL) { - stats_dumparg_t dumparg; - json_object *counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(zoneobj, "qtypes", counters); - else - json_object_put(counters); - } - - json_object_array_add(zonearray, zoneobj); - zoneobj = NULL; - result = ISC_R_SUCCESS; - - error: - if (zoneobj != NULL) - json_object_put(zoneobj); - return (result); -} - -static isc_result_t -generatejson(ns_server_t *server, size_t *msglen, - const char **msg, json_object **rootp, uint32_t flags) -{ - dns_view_t *view; - isc_result_t result = ISC_R_SUCCESS; - json_object *bindstats, *viewlist, *counters, *obj; - json_object *traffic = NULL; - json_object *udpreq4 = NULL, *udpresp4 = NULL; - json_object *tcpreq4 = NULL, *tcpresp4 = NULL; - json_object *udpreq6 = NULL, *udpresp6 = NULL; - json_object *tcpreq6 = NULL, *tcpresp6 = NULL; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - uint64_t udpinsizestat_values[dns_sizecounter_in_max]; - uint64_t udpoutsizestat_values[dns_sizecounter_out_max]; - uint64_t tcpinsizestat_values[dns_sizecounter_in_max]; - uint64_t tcpoutsizestat_values[dns_sizecounter_out_max]; -#ifdef HAVE_DNSTAP - uint64_t dnstapstat_values[dns_dnstapcounter_max]; -#endif - stats_dumparg_t dumparg; - char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"]; - isc_time_t now; - - REQUIRE(msglen != NULL); - REQUIRE(msg != NULL && *msg == NULL); - REQUIRE(rootp == NULL || *rootp == NULL); - - bindstats = json_object_new_object(); - if (bindstats == NULL) - return (ISC_R_NOMEMORY); - - /* - * These statistics are included no matter which URL we use. - */ - obj = json_object_new_string("1.2"); - CHECKMEM(obj); - json_object_object_add(bindstats, "json-stats-version", obj); - - isc_time_now(&now); - isc_time_formatISO8601ms(&ns_g_boottime, - boottime, sizeof(boottime)); - isc_time_formatISO8601ms(&ns_g_configtime, - configtime, sizeof configtime); - isc_time_formatISO8601ms(&now, nowstr, sizeof(nowstr)); - - obj = json_object_new_string(boottime); - CHECKMEM(obj); - json_object_object_add(bindstats, "boot-time", obj); - - obj = json_object_new_string(configtime); - CHECKMEM(obj); - json_object_object_add(bindstats, "config-time", obj); - - obj = json_object_new_string(nowstr); - CHECKMEM(obj); - json_object_object_add(bindstats, "current-time", obj); - obj = json_object_new_string(ns_g_version); - CHECKMEM(obj); - json_object_object_add(bindstats, "version", obj); - - if ((flags & STATS_JSON_SERVER) != 0) { - /* OPCODE counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - - dns_opcodestats_dump(server->opcodestats, - opcodestat_dump, &dumparg, - ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "opcodes", counters); - else - json_object_put(counters); - - /* OPCODE counters */ - counters = json_object_new_object(); - - dumparg.type = isc_statsformat_json; - dumparg.arg = counters; - - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, - &dumparg, ISC_STATSDUMP_VERBOSE); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "rcodes", counters); - else - json_object_put(counters); - - /* QTYPE counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - dns_rdatatypestats_dump(server->rcvquerystats, - rdtypestat_dump, &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "qtypes", counters); - else - json_object_put(counters); - - /* server stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->nsstats, isc_statsformat_json, - counters, NULL, nsstats_xmldesc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "nsstats", counters); - else - json_object_put(counters); - - /* zone stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->zonestats, isc_statsformat_json, - counters, NULL, zonestats_xmldesc, - dns_zonestatscounter_max, - zonestats_index, zonestat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "zonestats", - counters); - else - json_object_put(counters); - - /* resolver stat counters */ - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->resolverstats, - isc_statsformat_json, counters, NULL, - resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, resstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "resstats", counters); - else - json_object_put(counters); - -#ifdef HAVE_DNSTAP - /* dnstap stat counters */ - if (ns_g_server->dtenv != NULL) { - isc_stats_t *dnstapstats = NULL; - dns_dt_getstats(ns_g_server->dtenv, &dnstapstats); - counters = json_object_new_object(); - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - result = dump_counters(dnstapstats, - isc_statsformat_json, counters, - NULL, dnstapstats_xmldesc, - dns_dnstapcounter_max, - dnstapstats_index, - dnstapstat_values, 0); - isc_stats_detach(&dnstapstats); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, - "dnstapstats", - counters); - else - json_object_put(counters); - } -#endif - } - - if ((flags & (STATS_JSON_ZONES | STATS_JSON_SERVER)) != 0) { - viewlist = json_object_new_object(); - CHECKMEM(viewlist); - - json_object_object_add(bindstats, "views", viewlist); - - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - json_object *za, *v = json_object_new_object(); - - CHECKMEM(v); - json_object_object_add(viewlist, view->name, v); - - za = json_object_new_array(); - CHECKMEM(za); - - if ((flags & STATS_JSON_ZONES) != 0) { - result = dns_zt_apply(view->zonetable, true, - zone_jsonrender, za); - if (result != ISC_R_SUCCESS) { - goto error; - } - } - - if (json_object_array_length(za) != 0) - json_object_object_add(v, "zones", za); - else - json_object_put(za); - - if ((flags & STATS_JSON_SERVER) != 0) { - json_object *res; - dns_stats_t *dstats; - isc_stats_t *istats; - - res = json_object_new_object(); - CHECKMEM(res); - json_object_object_add(v, "resolver", res); - - istats = view->resstats; - if (istats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dump_counters(istats, - isc_statsformat_json, - counters, NULL, - resstats_xmldesc, - dns_resstatscounter_max, - resstats_index, - resstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "stats", - counters); - } - - dstats = view->resquerystats; - if (dstats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatatypestats_dump(dstats, - rdtypestat_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "qtypes", - counters); - } - - dstats = dns_db_getrrsetstats(view->cachedb); - if (dstats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - dumparg.arg = counters; - dumparg.result = ISC_R_SUCCESS; - dns_rdatasetstats_dump(dstats, - rdatasetstats_dump, - &dumparg, 0); - if (dumparg.result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, - "cache", - counters); - } - - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dns_cache_renderjson(view->cache, - counters); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - json_object_object_add(res, "cachestats", - counters); - - istats = view->adbstats; - if (istats != NULL) { - counters = json_object_new_object(); - CHECKMEM(counters); - - result = dump_counters(istats, - isc_statsformat_json, - counters, NULL, - adbstats_xmldesc, - dns_adbstats_max, - adbstats_index, - adbstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - result = dumparg.result; - goto error; - } - - json_object_object_add(res, "adb", - counters); - } - } - - view = ISC_LIST_NEXT(view, link); - } - } - - if ((flags & STATS_JSON_NET) != 0) { - /* socket stat counters */ - json_object *sockets; - counters = json_object_new_object(); - - dumparg.result = ISC_R_SUCCESS; - dumparg.arg = counters; - - result = dump_counters(server->sockstats, - isc_statsformat_json, counters, - NULL, sockstats_xmldesc, - isc_sockstatscounter_max, - sockstats_index, sockstat_values, 0); - if (result != ISC_R_SUCCESS) { - json_object_put(counters); - goto error; - } - - if (json_object_get_object(counters)->count != 0) - json_object_object_add(bindstats, "sockstats", - counters); - else - json_object_put(counters); - - sockets = json_object_new_object(); - CHECKMEM(sockets); - - result = isc_socketmgr_renderjson(ns_g_socketmgr, sockets); - if (result != ISC_R_SUCCESS) { - json_object_put(sockets); - goto error; - } - - json_object_object_add(bindstats, "socketmgr", sockets); - } - - if ((flags & STATS_JSON_TASKS) != 0) { - json_object *tasks = json_object_new_object(); - CHECKMEM(tasks); - - result = isc_taskmgr_renderjson(ns_g_taskmgr, tasks); - if (result != ISC_R_SUCCESS) { - json_object_put(tasks); - goto error; - } - - json_object_object_add(bindstats, "taskmgr", tasks); - } - - if ((flags & STATS_JSON_MEM) != 0) { - json_object *memory = json_object_new_object(); - CHECKMEM(memory); - - result = isc_mem_renderjson(memory); - if (result != ISC_R_SUCCESS) { - json_object_put(memory); - goto error; - } - - json_object_object_add(bindstats, "memory", memory); - } - - if ((flags & STATS_JSON_TRAFFIC) != 0) { - - traffic = json_object_new_object(); - CHECKMEM(traffic); - - udpreq4 = json_object_new_object(); - CHECKMEM(udpreq4); - - udpresp4 = json_object_new_object(); - CHECKMEM(udpresp4); - - tcpreq4 = json_object_new_object(); - CHECKMEM(tcpreq4); - - tcpresp4 = json_object_new_object(); - CHECKMEM(tcpresp4); - - udpreq6 = json_object_new_object(); - CHECKMEM(udpreq6); - - udpresp6 = json_object_new_object(); - CHECKMEM(udpresp6); - - tcpreq6 = json_object_new_object(); - CHECKMEM(tcpreq6); - - tcpresp6 = json_object_new_object(); - CHECKMEM(tcpresp6); - - CHECK(dump_counters(server->udpinstats4, - isc_statsformat_json, udpreq4, NULL, - udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0)); - - CHECK(dump_counters(server->udpoutstats4, - isc_statsformat_json, udpresp4, NULL, - udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0)); - - CHECK(dump_counters(server->tcpinstats4, - isc_statsformat_json, tcpreq4, NULL, - tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0)); - - CHECK(dump_counters(server->tcpoutstats4, - isc_statsformat_json, tcpresp4, NULL, - tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0)); - - CHECK(dump_counters(server->udpinstats6, - isc_statsformat_json, udpreq6, NULL, - udpinsizestats_xmldesc, - dns_sizecounter_in_max, - udpinsizestats_index, - udpinsizestat_values, 0)); - - CHECK(dump_counters(server->udpoutstats6, - isc_statsformat_json, udpresp6, NULL, - udpoutsizestats_xmldesc, - dns_sizecounter_out_max, - udpoutsizestats_index, - udpoutsizestat_values, 0)); - - CHECK(dump_counters(server->tcpinstats6, - isc_statsformat_json, tcpreq6, NULL, - tcpinsizestats_xmldesc, - dns_sizecounter_in_max, - tcpinsizestats_index, - tcpinsizestat_values, 0)); - - CHECK(dump_counters(server->tcpoutstats6, - isc_statsformat_json, tcpresp6, NULL, - tcpoutsizestats_xmldesc, - dns_sizecounter_out_max, - tcpoutsizestats_index, - tcpoutsizestat_values, 0)); - - json_object_object_add(traffic, - "dns-udp-requests-sizes-received-ipv4", - udpreq4); - json_object_object_add(traffic, - "dns-udp-responses-sizes-sent-ipv4", - udpresp4); - json_object_object_add(traffic, - "dns-tcp-requests-sizes-received-ipv4", - tcpreq4); - json_object_object_add(traffic, - "dns-tcp-responses-sizes-sent-ipv4", - tcpresp4); - json_object_object_add(traffic, - "dns-udp-requests-sizes-received-ipv6", - udpreq6); - json_object_object_add(traffic, - "dns-udp-responses-sizes-sent-ipv6", - udpresp6); - json_object_object_add(traffic, - "dns-tcp-requests-sizes-received-ipv6", - tcpreq6); - json_object_object_add(traffic, - "dns-tcp-responses-sizes-sent-ipv6", - tcpresp6); - json_object_object_add(bindstats, "traffic", traffic); - udpreq4 = NULL; - udpresp4 = NULL; - tcpreq4 = NULL; - tcpresp4 = NULL; - udpreq6 = NULL; - udpresp6 = NULL; - tcpreq6 = NULL; - tcpresp6 = NULL; - traffic = NULL; - } - - *msg = json_object_to_json_string_ext(bindstats, - JSON_C_TO_STRING_PRETTY); - *msglen = strlen(*msg); - - if (rootp != NULL) { - *rootp = bindstats; - bindstats = NULL; - } - - result = ISC_R_SUCCESS; - - error: - if (udpreq4 != NULL) - json_object_put(udpreq4); - if (udpresp4 != NULL) - json_object_put(udpresp4); - if (tcpreq4 != NULL) - json_object_put(tcpreq4); - if (tcpresp4 != NULL) - json_object_put(tcpresp4); - if (udpreq6 != NULL) - json_object_put(udpreq6); - if (udpresp6 != NULL) - json_object_put(udpresp6); - if (tcpreq6 != NULL) - json_object_put(tcpreq6); - if (tcpresp6 != NULL) - json_object_put(tcpresp6); - if (traffic != NULL) - json_object_put(traffic); - if (bindstats != NULL) - json_object_put(bindstats); - - return (result); -} - -static isc_result_t -render_json(uint32_t flags, - const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, - void *arg, unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - isc_result_t result; - json_object *bindstats = NULL; - ns_server_t *server = arg; - const char *msg = NULL; - size_t msglen = 0; - char *p; - - UNUSED(url); - UNUSED(urlinfo); - UNUSED(headers); - UNUSED(querystring); - - result = generatejson(server, &msglen, &msg, &bindstats, flags); - if (result == ISC_R_SUCCESS) { - *retcode = 200; - *retmsg = "OK"; - *mimetype = "application/json"; - DE_CONST(msg, p); - isc_buffer_reinit(b, p, msglen); - isc_buffer_add(b, msglen); - *freecb = wrap_jsonfree; - *freecb_args = bindstats; - } else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed at rendering JSON()"); - - return (result); -} - -static isc_result_t -render_json_all(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_ALL, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_status(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_STATUS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_server(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_SERVER, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_zones(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_ZONES, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_mem(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_MEM, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_tasks(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_TASKS, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_net(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_NET, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -static isc_result_t -render_json_traffic(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, void *arg, - unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - return (render_json(STATS_JSON_TRAFFIC, url, urlinfo, - querystring, headers, arg, - retcode, retmsg, mimetype, b, - freecb, freecb_args)); -} - -#endif /* HAVE_JSON */ - -static isc_result_t -render_xsl(const char *url, isc_httpdurl_t *urlinfo, - const char *querystring, const char *headers, - void *args, unsigned int *retcode, const char **retmsg, - const char **mimetype, isc_buffer_t *b, - isc_httpdfree_t **freecb, void **freecb_args) -{ - isc_result_t result; - - UNUSED(url); - UNUSED(querystring); - UNUSED(args); - - *freecb = NULL; - *freecb_args = NULL; - *mimetype = "text/xslt+xml"; - - if (urlinfo->isstatic) { - isc_time_t when; - char *p = strcasestr(headers, "If-Modified-Since: "); - - if (p != NULL) { - time_t t1, t2; - p += strlen("If-Modified-Since: "); - result = isc_time_parsehttptimestamp(p, &when); - if (result != ISC_R_SUCCESS) - goto send; - - result = isc_time_secondsastimet(&when, &t1); - if (result != ISC_R_SUCCESS) - goto send; - - result = isc_time_secondsastimet(&urlinfo->loadtime, - &t2); - if (result != ISC_R_SUCCESS) - goto send; - - if (t1 < t2) - goto send; - - *retcode = 304; - *retmsg = "Not modified"; - return (ISC_R_SUCCESS); - } - } - - send: - *retcode = 200; - *retmsg = "OK"; - isc_buffer_reinit(b, xslmsg, strlen(xslmsg)); - isc_buffer_add(b, strlen(xslmsg)); - - return (ISC_R_SUCCESS); -} - -static void -shutdown_listener(ns_statschannel_t *listener) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "stopping statistics channel on %s", - socktext); - - isc_httpdmgr_shutdown(&listener->httpdmgr); -} - -static bool -client_ok(const isc_sockaddr_t *fromaddr, void *arg) { - ns_statschannel_t *listener = arg; - isc_netaddr_t netaddr; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - int match; - - REQUIRE(listener != NULL); - - isc_netaddr_fromsockaddr(&netaddr, fromaddr); - - LOCK(&listener->lock); - if (dns_acl_match(&netaddr, NULL, listener->acl, &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && match > 0) { - UNLOCK(&listener->lock); - return (true); - } - UNLOCK(&listener->lock); - - isc_sockaddr_format(fromaddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "rejected statistics connection from %s", socktext); - - return (false); -} - -static void -destroy_listener(void *arg) { - ns_statschannel_t *listener = arg; - - REQUIRE(listener != NULL); - REQUIRE(!ISC_LINK_LINKED(listener, link)); - - /* We don't have to acquire the lock here since it's already unlinked */ - dns_acl_detach(&listener->acl); - - DESTROYLOCK(&listener->lock); - isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener)); -} - -static isc_result_t -add_listener(ns_server_t *server, ns_statschannel_t **listenerp, - const cfg_obj_t *listen_params, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext) -{ - isc_result_t result; - ns_statschannel_t *listener; - isc_task_t *task = NULL; - isc_socket_t *sock = NULL; - const cfg_obj_t *allow; - dns_acl_t *new_acl = NULL; - - listener = isc_mem_get(server->mctx, sizeof(*listener)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - listener->httpdmgr = NULL; - listener->address = *addr; - listener->acl = NULL; - listener->mctx = NULL; - ISC_LINK_INIT(listener, link); - - result = isc_mutex_init(&listener->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, listener, sizeof(*listener)); - return (ISC_R_FAILURE); - } - - isc_mem_attach(server->mctx, &listener->mctx); - - allow = cfg_tuple_get(listen_params, "allow"); - if (allow != NULL && cfg_obj_islist(allow)) { - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else - result = dns_acl_any(listener->mctx, &new_acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - result = isc_task_create(ns_g_taskmgr, 0, &task); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_task_setname(task, "statchannel", NULL); - - result = isc_socket_create(ns_g_socketmgr, isc_sockaddr_pf(addr), - isc_sockettype_tcp, &sock); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_socket_setname(sock, "statchannel", NULL); - -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(sock, true); -#endif - - result = isc_socket_bind(sock, addr, ISC_SOCKET_REUSEADDRESS); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_httpdmgr_create(server->mctx, sock, task, client_ok, - destroy_listener, listener, ns_g_timermgr, - &listener->httpdmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; - -#ifdef HAVE_LIBXML2 - isc_httpdmgr_addurl(listener->httpdmgr, "/", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3", - render_xml_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/status", - render_xml_status, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/server", - render_xml_server, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/zones", - render_xml_zones, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/net", - render_xml_net, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/tasks", - render_xml_tasks, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/mem", - render_xml_mem, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/traffic", - render_xml_traffic, server); -#endif -#ifdef HAVE_JSON - isc_httpdmgr_addurl(listener->httpdmgr, "/json", - render_json_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1", - render_json_all, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/status", - render_json_status, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/server", - render_json_server, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/zones", - render_json_zones, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/tasks", - render_json_tasks, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/net", - render_json_net, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/mem", - render_json_mem, server); - isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/traffic", - render_json_traffic, server); -#endif - isc_httpdmgr_addurl2(listener->httpdmgr, "/bind9.xsl", true, - render_xsl, server); - - *listenerp = listener; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, - "statistics channel listening on %s", socktext); - -cleanup: - if (result != ISC_R_SUCCESS) { - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - DESTROYLOCK(&listener->lock); - isc_mem_putanddetach(&listener->mctx, listener, - sizeof(*listener)); - } - if (task != NULL) - isc_task_detach(&task); - if (sock != NULL) - isc_socket_detach(&sock); - - return (result); -} - -static void -update_listener(ns_server_t *server, ns_statschannel_t **listenerp, - const cfg_obj_t *listen_params, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext) -{ - ns_statschannel_t *listener; - const cfg_obj_t *allow = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(server->statschannels); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * Now, keep the old access list unless a new one can be made. - */ - allow = cfg_tuple_get(listen_params, "allow"); - if (allow != NULL && cfg_obj_islist(allow)) { - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, 0, - &new_acl); - } else - result = dns_acl_any(listener->mctx, &new_acl); - - if (result == ISC_R_SUCCESS) { - LOCK(&listener->lock); - - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - UNLOCK(&listener->lock); - } else { - cfg_obj_log(listen_params, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "statistics channel %s: %s", - socktext, isc_result_totext(result)); - } - - *listenerp = listener; -} - -isc_result_t -ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx) -{ - ns_statschannel_t *listener, *listener_next; - ns_statschannellist_t new_listeners; - const cfg_obj_t *statschannellist = NULL; - const cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS); - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'statistics-channels' statements. - */ - (void)cfg_map_get(config, "statistics-channels", &statschannellist); - - /* - * Run through the new address/port list, noting sockets that are - * already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (statschannellist != NULL) { -#ifndef EXTENDED_STATS - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels specified but not effective " - "due to missing XML and/or JSON library"); -#else /* EXTENDED_STATS */ -#ifndef HAVE_LIBXML2 - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels: XML library missing, " - "only JSON stats will be available"); -#endif /* !HAVE_LIBXML2 */ -#ifndef HAVE_JSON - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "statistics-channels: JSON library missing, " - "only XML stats will be available"); -#endif /* !HAVE_JSON */ -#endif /* EXTENDED_STATS */ - - for (element = cfg_list_first(statschannellist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *statschannel; - const cfg_obj_t *listenercfg = NULL; - - statschannel = cfg_listelt_value(element); - (void)cfg_map_get(statschannel, "inet", - &listenercfg); - if (listenercfg == NULL) - continue; - - for (element2 = cfg_list_first(listenercfg); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *listen_params; - const cfg_obj_t *obj; - isc_sockaddr_t addr; - - listen_params = cfg_listelt_value(element2); - - obj = cfg_tuple_get(listen_params, "address"); - addr = *cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, - NS_STATSCHANNEL_HTTPPORT); - - isc_sockaddr_format(&addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(9), - "processing statistics " - "channel %s", - socktext); - - update_listener(server, &listener, - listen_params, config, &addr, - aclconfctx, socktext); - - if (listener != NULL) { - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(server->statschannels, - listener, link); - } else { - /* - * This is a new listener. - */ - isc_result_t r; - - r = add_listener(server, &listener, - listen_params, config, - &addr, aclconfctx, - socktext); - if (r != ISC_R_SUCCESS) { - cfg_obj_log(listen_params, - ns_g_lctx, - ISC_LOG_WARNING, - "couldn't allocate " - "statistics channel" - " %s: %s", - socktext, - isc_result_totext(r)); - } - } - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, listener, - link); - } - } - } - - for (listener = ISC_LIST_HEAD(server->statschannels); - listener != NULL; - listener = listener_next) { - listener_next = ISC_LIST_NEXT(listener, link); - ISC_LIST_UNLINK(server->statschannels, listener, link); - shutdown_listener(listener); - } - - ISC_LIST_APPENDLIST(server->statschannels, new_listeners, link); - return (ISC_R_SUCCESS); -} - -void -ns_statschannels_shutdown(ns_server_t *server) { - ns_statschannel_t *listener; - - while ((listener = ISC_LIST_HEAD(server->statschannels)) != NULL) { - ISC_LIST_UNLINK(server->statschannels, listener, link); - shutdown_listener(listener); - } -} - -isc_result_t -ns_stats_dump(ns_server_t *server, FILE *fp) { - isc_stdtime_t now; - isc_result_t result; - dns_view_t *view; - dns_zone_t *zone, *next; - stats_dumparg_t dumparg; - uint64_t nsstat_values[dns_nsstatscounter_max]; - uint64_t resstat_values[dns_resstatscounter_max]; - uint64_t adbstat_values[dns_adbstats_max]; - uint64_t zonestat_values[dns_zonestatscounter_max]; - uint64_t sockstat_values[isc_sockstatscounter_max]; - - RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS); - - /* Set common fields */ - dumparg.type = isc_statsformat_file; - dumparg.arg = fp; - - isc_stdtime_get(&now); - fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now); - - fprintf(fp, "++ Incoming Requests ++\n"); - dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); - - fprintf(fp, "++ Incoming Queries ++\n"); - dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, - &dumparg, 0); - - fprintf(fp, "++ Outgoing Rcodes ++\n"); - dns_rcodestats_dump(server->rcodestats, rcodestat_dump, &dumparg, 0); - - fprintf(fp, "++ Outgoing Queries ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->resquerystats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump, - &dumparg, 0); - } - - fprintf(fp, "++ Name Server Statistics ++\n"); - (void) dump_counters(server->nsstats, isc_statsformat_file, fp, NULL, - nsstats_desc, dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - - fprintf(fp, "++ Zone Maintenance Statistics ++\n"); - (void) dump_counters(server->zonestats, isc_statsformat_file, fp, NULL, - zonestats_desc, dns_zonestatscounter_max, - zonestats_index, zonestat_values, 0); - - fprintf(fp, "++ Resolver Statistics ++\n"); - fprintf(fp, "[Common]\n"); - (void) dump_counters(server->resolverstats, isc_statsformat_file, fp, - NULL, resstats_desc, dns_resstatscounter_max, - resstats_index, resstat_values, 0); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->resstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - (void) dump_counters(view->resstats, isc_statsformat_file, fp, - NULL, resstats_desc, - dns_resstatscounter_max, resstats_index, - resstat_values, 0); - } - - fprintf(fp, "++ Cache Statistics ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s (Cache: %s)]\n", view->name, - dns_cache_getname(view->cache)); - /* - * Avoid dumping redundant statistics when the cache is shared. - */ - if (dns_view_iscacheshared(view)) - continue; - dns_cache_dumpstats(view->cache, fp); - } - - fprintf(fp, "++ Cache DB RRsets ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_stats_t *cacherrstats; - - cacherrstats = dns_db_getrrsetstats(view->cachedb); - if (cacherrstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s (Cache: %s)]\n", view->name, - dns_cache_getname(view->cache)); - if (dns_view_iscacheshared(view)) { - /* - * Avoid dumping redundant statistics when the cache is - * shared. - */ - continue; - } - dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump, - &dumparg, 0); - } - - fprintf(fp, "++ ADB stats ++\n"); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (view->adbstats == NULL) - continue; - if (strcmp(view->name, "_default") == 0) - fprintf(fp, "[View: default]\n"); - else - fprintf(fp, "[View: %s]\n", view->name); - (void) dump_counters(view->adbstats, isc_statsformat_file, fp, - NULL, adbstats_desc, dns_adbstats_max, - adbstats_index, adbstat_values, 0); - } - - fprintf(fp, "++ Socket I/O Statistics ++\n"); - (void) dump_counters(server->sockstats, isc_statsformat_file, fp, NULL, - sockstats_desc, isc_sockstatscounter_max, - sockstats_index, sockstat_values, 0); - - fprintf(fp, "++ Per Zone Query Statistics ++\n"); - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) - { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) { - char zonename[DNS_NAME_FORMATSIZE]; - - view = dns_zone_getview(zone); - if (view == NULL) - continue; - - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - fprintf(fp, "[%s", zonename); - if (strcmp(view->name, "_default") != 0) - fprintf(fp, " (view: %s)", view->name); - fprintf(fp, "]\n"); - - (void) dump_counters(zonestats, isc_statsformat_file, - fp, NULL, nsstats_desc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, 0); - } - } - - fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now); - - return (ISC_R_SUCCESS); /* this function currently always succeeds */ -} diff --git a/bin/named-sdb/tkeyconf.c b/bin/named-sdb/tkeyconf.c deleted file mode 100644 index a65a94a..0000000 --- a/bin/named-sdb/tkeyconf.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include - -#include -#include -#include -#include - -#include - -#include - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -#include -#define LOG(msg) \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s", msg) - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) -{ - isc_result_t result; - dns_tkeyctx_t *tctx = NULL; - const char *s; - uint32_t n; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - const cfg_obj_t *obj; - int type; - - result = dns_tkeyctx_create(mctx, ectx, &tctx); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(options, "tkey-dhkey", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; - RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, - type, NULL, mctx, &tctx->dhkey)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-domain", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); - if (tctx->domain == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(tctx->domain, NULL); - RETERR(dns_name_dup(name, mctx, tctx->domain)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-credential", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - RETERR(dst_gssapi_acquirecred(name, false, &tctx->gsscred)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-keytab", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - tctx->gssapi_keytab = isc_mem_strdup(mctx, s); - if (tctx->gssapi_keytab == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - } - - *tctxp = tctx; - return (ISC_R_SUCCESS); - - failure: - dns_tkeyctx_destroy(&tctx); - return (result); -} - diff --git a/bin/named-sdb/tsigconf.c b/bin/named-sdb/tsigconf.c deleted file mode 100644 index 7d732a5..0000000 --- a/bin/named-sdb/tsigconf.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -static isc_result_t -add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, - isc_mem_t *mctx) -{ - dns_tsigkey_t *tsigkey = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *key = NULL; - const char *keyid = NULL; - unsigned char *secret = NULL; - int secretalloc = 0; - int secretlen = 0; - isc_result_t ret; - isc_stdtime_t now; - uint16_t bits; - - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - dns_name_t keyname; - dns_name_t *alg; - const char *algstr; - char keynamedata[1024]; - isc_buffer_t keynamesrc, keynamebuf; - const char *secretstr; - isc_buffer_t secretbuf; - - key = cfg_listelt_value(element); - keyid = cfg_obj_asstring(cfg_map_getname(key)); - - algobj = NULL; - secretobj = NULL; - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - /* - * Create the key name. - */ - dns_name_init(&keyname, NULL); - isc_buffer_constinit(&keynamesrc, keyid, strlen(keyid)); - isc_buffer_add(&keynamesrc, strlen(keyid)); - isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); - ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, - DNS_NAME_DOWNCASE, &keynamebuf); - if (ret != ISC_R_SUCCESS) - goto failure; - - /* - * Create the algorithm. - */ - algstr = cfg_obj_asstring(algobj); - if (ns_config_getkeyalgorithm(algstr, &alg, &bits) - != ISC_R_SUCCESS) { - cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, - "key '%s': has a unsupported algorithm '%s'", - keyid, algstr); - ret = DNS_R_BADALG; - goto failure; - } - - secretstr = cfg_obj_asstring(secretobj); - secretalloc = secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_get(mctx, secretlen); - if (secret == NULL) { - ret = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&secretbuf, secret, secretlen); - ret = isc_base64_decodestring(secretstr, &secretbuf); - if (ret != ISC_R_SUCCESS) - goto failure; - secretlen = isc_buffer_usedlength(&secretbuf); - - isc_stdtime_get(&now); - ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, - false, NULL, now, now, - mctx, ring, &tsigkey); - isc_mem_put(mctx, secret, secretalloc); - secret = NULL; - if (ret != ISC_R_SUCCESS) - goto failure; - /* - * Set digest bits. - */ - dst_key_setbits(tsigkey->key, bits); - dns_tsigkey_detach(&tsigkey); - } - - return (ISC_R_SUCCESS); - - failure: - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring key '%s': %s", keyid, - isc_result_totext(ret)); - - if (secret != NULL) - isc_mem_put(mctx, secret, secretalloc); - return (ret); -} - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp) -{ - const cfg_obj_t *maps[3]; - const cfg_obj_t *keylist; - dns_tsig_keyring_t *ring = NULL; - isc_result_t result; - int i; - - REQUIRE(ringp != NULL && *ringp == NULL); - - i = 0; - if (config != NULL) - maps[i++] = config; - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - maps[i] = NULL; - - result = dns_tsigkeyring_create(mctx, &ring); - if (result != ISC_R_SUCCESS) - return (result); - - for (i = 0; ; i++) { - if (maps[i] == NULL) - break; - keylist = NULL; - result = cfg_map_get(maps[i], "key", &keylist); - if (result != ISC_R_SUCCESS) - continue; - result = add_initial_keys(keylist, ring, mctx); - if (result != ISC_R_SUCCESS) - goto failure; - } - - *ringp = ring; - return (ISC_R_SUCCESS); - - failure: - dns_tsigkeyring_detach(&ring); - return (result); -} diff --git a/bin/named-sdb/unix/Makefile.in b/bin/named-sdb/unix/Makefile.in deleted file mode 100644 index 1498222..0000000 --- a/bin/named-sdb/unix/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -EXT_CFLAGS = -fpie - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} \ - ${DNS_INCLUDES} ${ISC_INCLUDES} @DST_OPENSSL_INC@ - -CDEFINES = @CRYPTO@ -CWARNINGS = - -OBJS = os.@O@ dlz_dlopen_driver.@O@ - -SRCS = os.c dlz_dlopen_driver.c - -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ diff --git a/bin/named-sdb/unix/dlz_dlopen_driver.c b/bin/named-sdb/unix/dlz_dlopen_driver.c deleted file mode 100644 index 398df91..0000000 --- a/bin/named-sdb/unix/dlz_dlopen_driver.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include -#include -#include -#include -#if HAVE_DLFCN_H -#include -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#ifdef ISC_DLZ_DLOPEN -static dns_sdlzimplementation_t *dlz_dlopen = NULL; - - -typedef struct dlopen_data { - isc_mem_t *mctx; - char *dl_path; - char *dlzname; - void *dl_handle; - void *dbdata; - unsigned int flags; - isc_mutex_t lock; - int version; - bool in_configure; - - dlz_dlopen_version_t *dlz_version; - dlz_dlopen_create_t *dlz_create; - dlz_dlopen_findzonedb_t *dlz_findzonedb; - dlz_dlopen_lookup_t *dlz_lookup; - dlz_dlopen_authority_t *dlz_authority; - dlz_dlopen_allnodes_t *dlz_allnodes; - dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr; - dlz_dlopen_newversion_t *dlz_newversion; - dlz_dlopen_closeversion_t *dlz_closeversion; - dlz_dlopen_configure_t *dlz_configure; - dlz_dlopen_ssumatch_t *dlz_ssumatch; - dlz_dlopen_addrdataset_t *dlz_addrdataset; - dlz_dlopen_subrdataset_t *dlz_subrdataset; - dlz_dlopen_delrdataset_t *dlz_delrdataset; - dlz_dlopen_destroy_t *dlz_destroy; -} dlopen_data_t; - -/* Modules can choose whether they are lock-safe or not. */ -#define MAYBE_LOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - LOCK(&cd->lock); \ - } while (0) - -#define MAYBE_UNLOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - UNLOCK(&cd->lock); \ - } while (0) - -/* - * Log a message at the given level. - */ -static void dlopen_log(int level, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), - fmt, ap); - va_end(ap); -} - -/* - * SDLZ methods - */ - -static isc_result_t -dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata, - dns_sdlzallnodes_t *allnodes) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - - UNUSED(driverarg); - - if (cd->dlz_allnodes == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allnodes(zone, cd->dbdata, allnodes); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, - const char *client) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - - if (cd->dlz_allowzonexfr == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allowzonexfr(cd->dbdata, name, client); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_authority == NULL) { - return (ISC_R_NOTIMPLEMENTED); - } - - MAYBE_LOCK(cd); - result = cd->dlz_authority(zone, cd->dbdata, lookup); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, - methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Load a symbol from the library - */ -static void * -dl_load_symbol(dlopen_data_t *cd, const char *symbol, bool mandatory) { - void *ptr = dlsym(cd->dl_handle, symbol); - if (ptr == NULL && mandatory) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: library '%s' is missing " - "required symbol '%s'", cd->dl_path, symbol); - } - return (ptr); -} - -/* - * Called at startup for each dlopen zone in named.conf - */ -static isc_result_t -dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], - void *driverarg, void **dbdata) -{ - dlopen_data_t *cd; - isc_mem_t *mctx = NULL; - isc_result_t result = ISC_R_FAILURE; - int dlopen_flags = 0; - - UNUSED(driverarg); - - if (argc < 2) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen driver for '%s' needs a path to " - "the shared library", dlzname); - return (ISC_R_FAILURE); - } - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - - cd = isc_mem_get(mctx, sizeof(*cd)); - if (cd == NULL) { - isc_mem_destroy(&mctx); - return (ISC_R_NOMEMORY); - } - memset(cd, 0, sizeof(*cd)); - - cd->mctx = mctx; - - cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]); - if (cd->dl_path == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - cd->dlzname = isc_mem_strdup(cd->mctx, dlzname); - if (cd->dlzname == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - /* Initialize the lock */ - result = isc_mutex_init(&cd->lock); - if (result != ISC_R_SUCCESS) - goto failed; - - /* Open the library */ - dlopen_flags = RTLD_NOW|RTLD_GLOBAL; - -#if defined(RTLD_DEEPBIND) && !__SANITIZE_ADDRESS__ - /* - * If RTLD_DEEPBIND is available then use it. This can avoid - * issues with a module using a different version of a system - * library than one that bind9 uses. For example, bind9 may link - * to MIT kerberos, but the module may use Heimdal. If we don't - * use RTLD_DEEPBIND then we could end up with Heimdal functions - * calling MIT functions, which leads to bizarre results (usually - * a segfault). - */ - dlopen_flags |= RTLD_DEEPBIND; -#endif - - cd->dl_handle = dlopen(cd->dl_path, dlopen_flags); - if (cd->dl_handle == NULL) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen failed to open library '%s' - %s", - cd->dl_path, dlerror()); - result = ISC_R_FAILURE; - goto failed; - } - - /* Find the symbols */ - cd->dlz_version = (dlz_dlopen_version_t *) - dl_load_symbol(cd, "dlz_version", true); - cd->dlz_create = (dlz_dlopen_create_t *) - dl_load_symbol(cd, "dlz_create", true); - cd->dlz_lookup = (dlz_dlopen_lookup_t *) - dl_load_symbol(cd, "dlz_lookup", true); - cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *) - dl_load_symbol(cd, "dlz_findzonedb", true); - - if (cd->dlz_create == NULL || - cd->dlz_version == NULL || - cd->dlz_lookup == NULL || - cd->dlz_findzonedb == NULL) - { - /* We're missing a required symbol */ - result = ISC_R_FAILURE; - goto failed; - } - - cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *) - dl_load_symbol(cd, "dlz_allowzonexfr", false); - cd->dlz_allnodes = (dlz_dlopen_allnodes_t *) - dl_load_symbol(cd, "dlz_allnodes", - (cd->dlz_allowzonexfr != NULL)); - cd->dlz_authority = (dlz_dlopen_authority_t *) - dl_load_symbol(cd, "dlz_authority", false); - cd->dlz_newversion = (dlz_dlopen_newversion_t *) - dl_load_symbol(cd, "dlz_newversion", false); - cd->dlz_closeversion = (dlz_dlopen_closeversion_t *) - dl_load_symbol(cd, "dlz_closeversion", - (cd->dlz_newversion != NULL)); - cd->dlz_configure = (dlz_dlopen_configure_t *) - dl_load_symbol(cd, "dlz_configure", false); - cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *) - dl_load_symbol(cd, "dlz_ssumatch", false); - cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *) - dl_load_symbol(cd, "dlz_addrdataset", false); - cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *) - dl_load_symbol(cd, "dlz_subrdataset", false); - cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *) - dl_load_symbol(cd, "dlz_delrdataset", false); - cd->dlz_destroy = (dlz_dlopen_destroy_t *) - dl_load_symbol(cd, "dlz_destroy", false); - - /* Check the version of the API is the same */ - cd->version = cd->dlz_version(&cd->flags); - if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) || - cd->version > DLZ_DLOPEN_VERSION) - { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: %s: incorrect driver API version %d, " - "requires %d", - cd->dl_path, cd->version, DLZ_DLOPEN_VERSION); - result = ISC_R_FAILURE; - goto failed; - } - - /* - * Call the library's create function. Note that this is an - * extended version of dlz create, with the addition of - * named function pointers for helper functions that the - * driver will need. This avoids the need for the backend to - * link the BIND9 libraries - */ - MAYBE_LOCK(cd); - result = cd->dlz_create(dlzname, argc-1, argv+1, - &cd->dbdata, - "log", dlopen_log, - "putrr", dns_sdlz_putrr, - "putnamedrr", dns_sdlz_putnamedrr, - "writeable_zone", dns_dlz_writeablezone, - NULL); - MAYBE_UNLOCK(cd); - if (result != ISC_R_SUCCESS) - goto failed; - - *dbdata = cd; - - return (ISC_R_SUCCESS); - -failed: - dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname); - if (cd->dl_path != NULL) - isc_mem_free(mctx, cd->dl_path); - if (cd->dlzname != NULL) - isc_mem_free(mctx, cd->dlzname); - if (dlopen_flags != 0) - (void) isc_mutex_destroy(&cd->lock); -#ifdef HAVE_DLCLOSE - if (cd->dl_handle) - dlclose(cd->dl_handle); -#endif - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); - return (result); -} - -/* - * Called when bind is shutting down - */ -static void -dlopen_dlz_destroy(void *driverarg, void *dbdata) { - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_mem_t *mctx; - - UNUSED(driverarg); - - if (cd->dlz_destroy) { - MAYBE_LOCK(cd); - cd->dlz_destroy(cd->dbdata); - MAYBE_UNLOCK(cd); - } - - if (cd->dl_path) - isc_mem_free(cd->mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(cd->mctx, cd->dlzname); - -#ifdef HAVE_DLCLOSE - if (cd->dl_handle) - dlclose(cd->dl_handle); -#endif - - (void) isc_mutex_destroy(&cd->lock); - - mctx = cd->mctx; - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); -} - -/* - * Called to start a transaction - */ -static isc_result_t -dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata, - void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_newversion(zone, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Called to end a transaction - */ -static void -dlopen_dlz_closeversion(const char *zone, bool commit, - void *driverarg, void *dbdata, void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) { - *versionp = NULL; - return; - } - - MAYBE_LOCK(cd); - cd->dlz_closeversion(zone, commit, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); -} - -/* - * Called on startup to configure any writeable zones - */ -static isc_result_t -dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, - void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_configure == NULL) - return (ISC_R_SUCCESS); - - MAYBE_LOCK(cd); - cd->in_configure = true; - result = cd->dlz_configure(view, dlzdb, cd->dbdata); - cd->in_configure = false; - MAYBE_UNLOCK(cd); - - return (result); -} - - -/* - * Check for authority to change a name. - */ -static bool -dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, - const char *type, const char *key, uint32_t keydatalen, - unsigned char *keydata, void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - bool ret; - - UNUSED(driverarg); - - if (cd->dlz_ssumatch == NULL) - return (false); - - MAYBE_LOCK(cd); - ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen, - keydata, cd->dbdata); - MAYBE_UNLOCK(cd); - - return (ret); -} - - -/* - * Add an rdataset. - */ -static isc_result_t -dlopen_dlz_addrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_addrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Subtract an rdataset. - */ -static isc_result_t -dlopen_dlz_subrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_subrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Delete a rdataset. - */ -static isc_result_t -dlopen_dlz_delrdataset(const char *name, const char *type, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_delrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_delrdataset(name, type, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - - -static dns_sdlzmethods_t dlz_dlopen_methods = { - dlopen_dlz_create, - dlopen_dlz_destroy, - dlopen_dlz_findzonedb, - dlopen_dlz_lookup, - dlopen_dlz_authority, - dlopen_dlz_allnodes, - dlopen_dlz_allowzonexfr, - dlopen_dlz_newversion, - dlopen_dlz_closeversion, - dlopen_dlz_configure, - dlopen_dlz_ssumatch, - dlopen_dlz_addrdataset, - dlopen_dlz_subrdataset, - dlopen_dlz_delrdataset -}; -#endif - -/* - * Register driver with BIND - */ -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx) { -#ifndef ISC_DLZ_DLOPEN - UNUSED(mctx); - return (ISC_R_NOTIMPLEMENTED); -#else - isc_result_t result; - - dlopen_log(2, "Registering DLZ_dlopen driver"); - - result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL, - DNS_SDLZFLAG_RELATIVEOWNER | - DNS_SDLZFLAG_RELATIVERDATA | - DNS_SDLZFLAG_THREADSAFE, - mctx, &dlz_dlopen); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_sdlzregister() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - } - - return (result); -#endif -} - - -/* - * Unregister the driver - */ -void -dlz_dlopen_clear(void) { -#ifdef ISC_DLZ_DLOPEN - dlopen_log(2, "Unregistering DLZ_dlopen driver"); - if (dlz_dlopen != NULL) - dns_sdlzunregister(&dlz_dlopen); -#endif -} diff --git a/bin/named-sdb/unix/include/named/os.h b/bin/named-sdb/unix/include/named/os.h deleted file mode 100644 index 87498b8..0000000 --- a/bin/named-sdb/unix/include/named/os.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -/*! \file */ - -#include -#include - -#include - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -uid_t -ns_os_uid(void); - -void -ns_os_adjustnofile(void); - -void -ns_os_minprivs(void); - -FILE * -ns_os_openfile(const char *filename, mode_t mode, bool switch_user); - -void -ns_os_writepidfile(const char *filename, bool first_time); - -bool -ns_os_issingleton(const char *filename); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -const char * -ns_os_uname(void); - -#endif /* NS_OS_H */ diff --git a/bin/named-sdb/unix/os.c b/bin/named-sdb/unix/os.c deleted file mode 100644 index 42c6276..0000000 --- a/bin/named-sdb/unix/os.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include -#include - -#include /* dev_t FreeBSD 2.1 */ -#include -#ifdef HAVE_UNAME -#include -#endif - -#include -#include -#include -#include /* Required for initgroups() on IRIX. */ -#include -#include -#include -#include -#include -#ifdef HAVE_TZSET -#include -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static char *pidfile = NULL; -static char *lockfile = NULL; -static int devnullfd = -1; -static int singletonfd = -1; - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/* - * If there's no , we don't care about - */ -#ifndef HAVE_LINUX_CAPABILITY_H -#undef HAVE_SYS_PRCTL_H -#endif - -/* - * Linux defines: - * (T) HAVE_LINUXTHREADS - * (C) HAVE_SYS_CAPABILITY_H (or HAVE_LINUX_CAPABILITY_H) - * (P) HAVE_SYS_PRCTL_H - * The possible cases are: - * none: setuid() normally - * T: no setuid() - * C: setuid() normally, drop caps (keep CAP_SETUID) - * T+C: no setuid(), drop caps (don't keep CAP_SETUID) - * T+C+P: setuid() early, drop caps (keep CAP_SETUID) - * C+P: setuid() normally, drop caps (keep CAP_SETUID) - * P: not possible - * T+P: not possible - * - * if (C) - * caps = BIND_SERVICE + CHROOT + SETGID - * if ((T && C && P) || !T) - * caps += SETUID - * endif - * capset(caps) - * endif - * if (T && C && P && -u) - * setuid() - * else if (T && -u) - * fail - * --> start threads - * if (!T && -u) - * setuid() - * if (C && (P || !-u)) - * caps = BIND_SERVICE - * capset(caps) - * endif - * - * It will be nice when Linux threads work properly with setuid(). - */ - -#ifdef HAVE_LINUXTHREADS -static pid_t mainpid = 0; -#endif - -static struct passwd *runas_pw = NULL; -static bool done_setuid = false; -static int dfd[2] = { -1, -1 }; - -#ifdef HAVE_LINUX_CAPABILITY_H - -static bool non_root = false; -static bool non_root_caps = false; - -#ifdef HAVE_SYS_CAPABILITY_H -#include -#else -#ifdef HAVE_LINUX_TYPES_H -#include -#endif -/*% - * We define _LINUX_FS_H to prevent it from being included. We don't need - * anything from it, and the files it includes cause warnings with 2.2 - * kernels, and compilation failures (due to conflicts between - * and ) on 2.3 kernels. - */ -#define _LINUX_FS_H -#include -#include -#ifndef SYS_capset -#ifndef __NR_capset -#include /* Slackware 4.0 needs this. */ -#endif /* __NR_capset */ -#define SYS_capset __NR_capset -#endif /* SYS_capset */ -#endif /* HAVE_SYS_CAPABILITY_H */ - -#ifdef HAVE_SYS_PRCTL_H -#include /* Required for prctl(). */ - -/* - * If the value of PR_SET_KEEPCAPS is not in , define it - * here. This allows setuid() to work on systems running a new enough - * kernel but with /usr/include/linux pointing to "standard" kernel - * headers. - */ -#ifndef PR_SET_KEEPCAPS -#define PR_SET_KEEPCAPS 8 -#endif - -#endif /* HAVE_SYS_PRCTL_H */ - -#ifdef HAVE_LIBCAP -#define SETCAPS_FUNC "cap_set_proc " -#else -typedef unsigned int cap_t; -#define SETCAPS_FUNC "syscall(capset) " -#endif /* HAVE_LIBCAP */ - -static void -linux_setcaps(cap_t caps) { -#ifndef HAVE_LIBCAP - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct cap; -#endif - char strbuf[ISC_STRERRORSIZE]; - - if ((getuid() != 0 && !non_root_caps) || non_root) - return; -#ifndef HAVE_LIBCAP - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&cap, 0, sizeof(cap)); - cap.effective = caps; - cap.permitted = caps; - cap.inheritable = 0; -#endif -#ifdef HAVE_LIBCAP - if (cap_set_proc(caps) < 0) { -#else - if (syscall(SYS_capset, &caphead, &cap) < 0) { -#endif - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal(SETCAPS_FUNC "failed: %s:" - " please ensure that the capset kernel" - " module is loaded. see insmod(8)", - strbuf); - } -} - -#ifdef HAVE_LIBCAP -#define SET_CAP(flag) \ - do { \ - cap_flag_value_t curval; \ - capval = (flag); \ - err = cap_get_flag(curcaps, capval, CAP_PERMITTED, &curval); \ - if (err != -1 && curval) { \ - err = cap_set_flag(caps, CAP_EFFECTIVE, 1, &capval, CAP_SET); \ - if (err == -1) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \ - } \ - \ - err = cap_set_flag(caps, CAP_PERMITTED, 1, &capval, CAP_SET); \ - if (err == -1) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \ - } \ - } \ - } while (0) -#define INIT_CAP \ - do { \ - caps = cap_init(); \ - if (caps == NULL) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_init failed: %s", strbuf); \ - } \ - curcaps = cap_get_proc(); \ - if (curcaps == NULL) { \ - isc__strerror(errno, strbuf, sizeof(strbuf)); \ - ns_main_earlyfatal("cap_get_proc failed: %s", strbuf); \ - } \ - } while (0) -#define FREE_CAP \ - { \ - cap_free(caps); \ - cap_free(curcaps); \ - } while (0) -#else -#define SET_CAP(flag) \ - do { \ - if (curcaps & (1 << (flag))) { \ - caps |= (1 << (flag)); \ - } \ - } while (0) -#define INIT_CAP do { caps = 0; } while (0) -#endif /* HAVE_LIBCAP */ - -#ifndef HAVE_LIBCAP -/*% - * Store the bitmask representing the permitted capability set in 'capsp'. To - * match libcap-enabled behavior, capget() syscall errors are not reported, - * they just cause 'capsp' to be set to 0, which effectively prevents any - * capability from being subsequently requested. - */ -static void -linux_getpermittedcaps(cap_t *capsp) { - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct curcaps; - - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&curcaps, 0, sizeof(curcaps)); - syscall(SYS_capget, &caphead, &curcaps); - - *capsp = curcaps.permitted; -} -#endif /* HAVE_LIBCAP */ - -static void -linux_initialprivs(void) { - cap_t curcaps; - cap_t caps; -#ifdef HAVE_LIBCAP - cap_value_t capval; - char strbuf[ISC_STRERRORSIZE]; - int err; -#else - linux_getpermittedcaps(&curcaps); -#endif - - /*% - * We don't need most privileges, so we drop them right away. - * Later on linux_minprivs() will be called, which will drop our - * capabilities to the minimum needed to run the server. - */ - INIT_CAP; - - /* - * We need to be able to bind() to privileged ports, notably port 53! - */ - SET_CAP(CAP_NET_BIND_SERVICE); - - /* - * We need chroot() initially too. - */ - SET_CAP(CAP_SYS_CHROOT); - -#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS) - /* - * We can setuid() only if either the kernel supports keeping - * capabilities after setuid() (which we don't know until we've - * tried) or we're not using threads. If either of these is - * true, we want the setuid capability. - */ - SET_CAP(CAP_SETUID); -#endif - - /* - * Since we call initgroups, we need this. - */ - SET_CAP(CAP_SETGID); - - /* - * Without this, we run into problems reading a configuration file - * owned by a non-root user and non-world-readable on startup. - */ - SET_CAP(CAP_DAC_READ_SEARCH); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - SET_CAP(CAP_SYS_RESOURCE); - - /* - * We need to be able to set the ownership of the containing - * directory of the pid file when we create it. - */ - SET_CAP(CAP_CHOWN); - - linux_setcaps(caps); - -#ifdef HAVE_LIBCAP - FREE_CAP; -#endif -} - -static void -linux_minprivs(void) { - cap_t curcaps; - cap_t caps; -#ifdef HAVE_LIBCAP - cap_value_t capval; - char strbuf[ISC_STRERRORSIZE]; - int err; -#else - linux_getpermittedcaps(&curcaps); -#endif - - INIT_CAP; - /*% - * Drop all privileges except the ability to bind() to privileged - * ports. - * - * It's important that we drop CAP_SYS_CHROOT. If we didn't, it - * chroot() could be used to escape from the chrooted area. - */ - - SET_CAP(CAP_NET_BIND_SERVICE); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - SET_CAP(CAP_SYS_RESOURCE); - - linux_setcaps(caps); - -#ifdef HAVE_LIBCAP - FREE_CAP; -#endif -} - -#ifdef HAVE_SYS_PRCTL_H -static void -linux_keepcaps(void) { - char strbuf[ISC_STRERRORSIZE]; - /*% - * Ask the kernel to allow us to keep our capabilities after we - * setuid(). - */ - - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("prctl() failed: %s", strbuf); - } - } else { - non_root_caps = true; - if (getuid() != 0) - non_root = true; - } -} -#endif - -#endif /* HAVE_LINUX_CAPABILITY_H */ - - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - openlog(isc_file_basename(progname), options, ISC_FACILITY); -} - -void -ns_os_init(const char *progname) { - setup_syslog(progname); -#ifdef HAVE_LINUX_CAPABILITY_H - linux_initialprivs(); -#endif -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_IGN); -#endif -} - -void -ns_os_daemonize(void) { - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - - if (pipe(dfd) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("pipe(): %s", strbuf); - } - - pid = fork(); - if (pid == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("fork(): %s", strbuf); - } - if (pid != 0) { - int n; - /* - * Wait for the child to finish loading for the first time. - * This would be so much simpler if fork() worked once we - * were multi-threaded. - */ - (void)close(dfd[1]); - do { - char buf; - n = read(dfd[0], &buf, 1); - if (n == 1) - _exit(0); - } while (n == -1 && errno == EINTR); - _exit(1); - } - (void)close(dfd[0]); - - /* - * We're the child. - */ - -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif - - if (setsid() == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setsid(): %s", strbuf); - } - - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - * - * XXXMLG The close() calls here are unneeded on all but NetBSD, but - * are harmless to include everywhere. dup2() is supposed to close - * the FD if it is in use, but unproven-pthreads-0.16 is broken - * and will end up closing the wrong FD. This will be fixed eventually, - * and these calls will be removed. - */ - if (devnullfd != -1) { - if (devnullfd != STDIN_FILENO) { - (void)close(STDIN_FILENO); - (void)dup2(devnullfd, STDIN_FILENO); - } - if (devnullfd != STDOUT_FILENO) { - (void)close(STDOUT_FILENO); - (void)dup2(devnullfd, STDOUT_FILENO); - } - if (devnullfd != STDERR_FILENO && !ns_g_keepstderr) { - (void)close(STDERR_FILENO); - (void)dup2(devnullfd, STDERR_FILENO); - } - } -} - -void -ns_os_started(void) { - char buf = 0; - - /* - * Signal to the parent that we started successfully. - */ - if (dfd[0] != -1 && dfd[1] != -1) { - if (write(dfd[1], &buf, 1) != 1) - ns_main_earlyfatal("unable to signal parent that we " - "otherwise started successfully."); - close(dfd[1]); - dfd[0] = dfd[1] = -1; - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("/dev/null", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != STDIN_FILENO && - devnullfd != STDOUT_FILENO && - devnullfd != STDERR_FILENO) { - close(devnullfd); - devnullfd = -1; - } -} - -static bool -all_digits(const char *s) { - if (*s == '\0') - return (false); - while (*s != '\0') { - if (!isdigit((*s)&0xff)) - return (false); - s++; - } - return (true); -} - -void -ns_os_chroot(const char *root) { - char strbuf[ISC_STRERRORSIZE]; -#ifdef HAVE_LIBSCF - ns_smf_chroot = 0; -#endif - if (root != NULL) { -#ifdef HAVE_CHROOT - if (chroot(root) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chroot(): %s", strbuf); - } -#else - ns_main_earlyfatal("chroot(): disabled"); -#endif - if (chdir("/") < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chdir(/): %s", strbuf); - } -#ifdef HAVE_LIBSCF - /* Set ns_smf_chroot flag on successful chroot. */ - ns_smf_chroot = 1; -#endif - } -} - -void -ns_os_inituserinfo(const char *username) { - char strbuf[ISC_STRERRORSIZE]; - if (username == NULL) - return; - - if (all_digits(username)) - runas_pw = getpwuid((uid_t)atoi(username)); - else - runas_pw = getpwnam(username); - endpwent(); - - if (runas_pw == NULL) - ns_main_earlyfatal("user '%s' unknown", username); - - if (getuid() == 0) { - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("initgroups(): %s", strbuf); - } - } - -} - -void -ns_os_changeuser(void) { - char strbuf[ISC_STRERRORSIZE]; - if (runas_pw == NULL || done_setuid) - return; - - done_setuid = true; - -#ifdef HAVE_LINUXTHREADS -#ifdef HAVE_LINUX_CAPABILITY_H - if (!non_root_caps) - ns_main_earlyfatal("-u with Linux threads not supported: " - "requires kernel support for " - "prctl(PR_SET_KEEPCAPS)"); -#else - ns_main_earlyfatal("-u with Linux threads not supported: " - "no capabilities support or capabilities " - "disabled at build time"); -#endif -#endif - - if (setgid(runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setgid(): %s", strbuf); - } - - if (setuid(runas_pw->pw_uid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setuid(): %s", strbuf); - } - -#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) - /* - * Restore the ability of named to drop core after the setuid() - * call has disabled it. - */ - if (prctl(PR_SET_DUMPABLE,1,0,0,0) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("prctl(PR_SET_DUMPABLE) failed: %s", - strbuf); - } -#endif -#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -uid_t -ns_os_uid(void) { - if (runas_pw == NULL) - return (0); - return (runas_pw->pw_uid); -} - -void -ns_os_adjustnofile(void) { -#ifdef HAVE_LINUXTHREADS - isc_result_t result; - isc_resourcevalue_t newvalue; - - /* - * Linux: max number of open files specified by one thread doesn't seem - * to apply to other threads on Linux. - */ - newvalue = ISC_RESOURCE_UNLIMITED; - - result = isc_resource_setlimit(isc_resource_openfiles, newvalue); - if (result != ISC_R_SUCCESS) - ns_main_earlywarning("couldn't adjust limit on open files"); -#endif -} - -void -ns_os_minprivs(void) { -#ifdef HAVE_SYS_PRCTL_H - linux_keepcaps(); -#endif - -#ifdef HAVE_LINUXTHREADS - ns_os_changeuser(); /* Call setuid() before threads are started */ -#endif - -#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -static int -safe_open(const char *filename, mode_t mode, bool append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) { - errno = EOPNOTSUPP; - return (-1); - } - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode); - else { - if (unlink(filename) < 0 && errno != ENOENT) - return (-1); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - int n; - if (pidfile != NULL) { - n = unlink(pidfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", pidfile); - free(pidfile); - } - pidfile = NULL; -} - -static void -cleanup_lockfile(void) { - if (singletonfd != -1) { - close(singletonfd); - singletonfd = -1; - } - - if (lockfile != NULL) { - int n = unlink(lockfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", lockfile); - free(lockfile); - lockfile = NULL; - } -} - -/* - * Ensure that a directory exists. - * NOTE: This function overwrites the '/' characters in 'filename' with - * nulls. The caller should copy the filename to a fresh buffer first. - */ -static int -mkdirpath(char *filename, void (*report)(const char *, ...)) { - char *slash = strrchr(filename, '/'); - char strbuf[ISC_STRERRORSIZE]; - unsigned int mode; - - if (slash != NULL && slash != filename) { - struct stat sb; - *slash = '\0'; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't stat '%s': %s", filename, - strbuf); - goto error; - } - if (mkdirpath(filename, report) == -1) - goto error; - /* - * Handle "//", "/./" and "/../" in path. - */ - if (!strcmp(slash + 1, "") || - !strcmp(slash + 1, ".") || - !strcmp(slash + 1, "..")) { - *slash = '/'; - return (0); - } - mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */ - mode |= S_IRGRP | S_IXGRP; /* g=rx */ - mode |= S_IROTH | S_IXOTH; /* o=rx */ - if (mkdir(filename, mode) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't mkdir '%s': %s", filename, - strbuf); - goto error; - } - if (runas_pw != NULL && - chown(filename, runas_pw->pw_uid, - runas_pw->pw_gid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't chown '%s': %s", filename, - strbuf); - } - } - *slash = '/'; - } - return (0); - - error: - *slash = '/'; - return (-1); -} - -#ifndef HAVE_LINUXTHREADS -static void -setperms(uid_t uid, gid_t gid) { -#if defined(HAVE_SETEGID) || defined(HAVE_SETRESGID) - char strbuf[ISC_STRERRORSIZE]; -#endif -#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) - gid_t oldgid, tmpg; -#endif -#if !defined(HAVE_SETEUID) && defined(HAVE_SETRESUID) - uid_t olduid, tmpu; -#endif -#if defined(HAVE_SETEGID) - if (getegid() != gid && setegid(gid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective gid to %ld: %s", - (long)gid, strbuf); - } -#elif defined(HAVE_SETRESGID) - if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) { - if (setresgid(-1, gid, -1) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective " - "gid to %d: %s", gid, strbuf); - } - } -#endif - -#if defined(HAVE_SETEUID) - if (geteuid() != uid && seteuid(uid) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective uid to %ld: %s", - (long)uid, strbuf); - } -#elif defined(HAVE_SETRESUID) - if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) { - if (setresuid(-1, uid, -1) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("unable to set effective " - "uid to %d: %s", uid, strbuf); - } - } -#endif -} -#endif /* !HAVE_LINUXTHREADS */ - -FILE * -ns_os_openfile(const char *filename, mode_t mode, bool switch_user) { - char strbuf[ISC_STRERRORSIZE], *f; - FILE *fp; - int fd; - - /* - * Make the containing directory if it doesn't exist. - */ - f = strdup(filename); - if (f == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("couldn't strdup() '%s': %s", - filename, strbuf); - return (NULL); - } - if (mkdirpath(f, ns_main_earlywarning) == -1) { - free(f); - return (NULL); - } - free(f); - - if (switch_user && runas_pw != NULL) { - uid_t olduid = getuid(); - gid_t oldgid = getgid(); -#ifdef HAVE_LINUXTHREADS - REQUIRE(olduid == runas_pw->pw_uid); - REQUIRE(oldgid == runas_pw->pw_gid); -#else - /* Set UID/GID to the one we'll be running with eventually */ - setperms(runas_pw->pw_uid, runas_pw->pw_gid); -#endif - fd = safe_open(filename, mode, false); - -#ifndef HAVE_LINUXTHREADS - /* Restore UID/GID to root */ - setperms(olduid, oldgid); -#endif /* HAVE_LINUXTHREADS */ - - if (fd == -1) { -#ifndef HAVE_LINUXTHREADS - fd = safe_open(filename, mode, false); - if (fd != -1) { - ns_main_earlywarning("Required root " - "permissions to open " - "'%s'.", filename); - } else { - ns_main_earlywarning("Could not open " - "'%s'.", filename); - } - ns_main_earlywarning("Please check file and " - "directory permissions " - "or reconfigure the filename."); -#else /* HAVE_LINUXTHREADS */ - ns_main_earlywarning("Could not open " - "'%s'.", filename); - ns_main_earlywarning("Please check file and " - "directory permissions " - "or reconfigure the filename."); -#endif /* HAVE_LINUXTHREADS */ - } - } else { - fd = safe_open(filename, mode, false); - } - - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not open file '%s': %s", - filename, strbuf); - return (NULL); - } - - fp = fdopen(fd, "w"); - if (fp == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not fdopen() file '%s': %s", - filename, strbuf); - } - - return (fp); -} - -void -ns_os_writepidfile(const char *filename, bool first_time) { - FILE *fh; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - pidfile = strdup(filename); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't strdup() '%s': %s", filename, strbuf); - return; - } - - fh = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, - first_time); - if (fh == NULL) { - cleanup_pidfile(); - return; - } -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - if (fprintf(fh, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(fh); - cleanup_pidfile(); - return; - } - if (fflush(fh) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(fh); - cleanup_pidfile(); - return; - } - (void)fclose(fh); -} - -bool -ns_os_issingleton(const char *filename) { - char strbuf[ISC_STRERRORSIZE]; - struct flock lock; - - if (singletonfd != -1) - return (true); - - if (strcasecmp(filename, "none") == 0) - return (true); - - /* - * Make the containing directory if it doesn't exist. - */ - lockfile = strdup(filename); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't allocate memory for '%s': %s", - filename, strbuf); - } else { - int ret = mkdirpath(lockfile, ns_main_earlywarning); - if (ret == -1) { - ns_main_earlywarning("couldn't create '%s'", filename); - cleanup_lockfile(); - return (false); - } - } - - /* - * ns_os_openfile() uses safeopen() which removes any existing - * files. We can't use that here. - */ - singletonfd = open(filename, O_WRONLY | O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (singletonfd == -1) { - cleanup_lockfile(); - return (false); - } - - memset(&lock, 0, sizeof(lock)); - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 1; - - /* Non-blocking (does not wait for lock) */ - if (fcntl(singletonfd, F_SETLK, &lock) == -1) { - close(singletonfd); - singletonfd = -1; - return (false); - } - - return (true); -} - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); - cleanup_lockfile(); -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - char *input, *ptr; - unsigned int n; - pid_t pid; - - input = command; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - if (strcmp(ptr, "-p") != 0) - return; - -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "pid: %ld", (long)pid); - /* Only send a message if it is complete. */ - if (n > 0 && n < isc_buffer_availablelength(text)) - isc_buffer_add(text, n); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} - -#ifdef HAVE_UNAME -static char unamebuf[sizeof(struct utsname)]; -#else -static const char unamebuf[] = { "unknown architecture" }; -#endif -static const char *unamep = NULL; - -static void -getuname(void) { -#ifdef HAVE_UNAME - struct utsname uts; - - memset(&uts, 0, sizeof(uts)); - if (uname(&uts) < 0) { - snprintf(unamebuf, sizeof(unamebuf), "unknown architecture"); - return; - } - - snprintf(unamebuf, sizeof(unamebuf), "%s %s %s %s", uts.sysname, - uts.machine, uts.release, uts.version); -#endif /* ifdef HAVE_UNAME */ - unamep = unamebuf; -} - -const char * -ns_os_uname(void) { - if (unamep == NULL) { - getuname(); - } - return (unamep); -} diff --git a/bin/named-sdb/update.c b/bin/named-sdb/update.c deleted file mode 100644 index ffd2caf..0000000 --- a/bin/named-sdb/update.c +++ /dev/null @@ -1,3513 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/*! \file - * \brief - * This module implements dynamic update as in RFC2136. - */ - -/* - * XXX TODO: - * - document strict minimality - */ - -/**************************************************************************/ - -/*% - * Log level for tracing dynamic update protocol requests. - */ -#define LOGLEVEL_PROTOCOL ISC_LOG_INFO - -/*% - * Log level for low-level debug tracing. - */ -#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) - -/*% - * Check an operation for failure. These macros all assume that - * the function using them has a 'result' variable and a 'failure' - * label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally with result 'code', which must not - * be ISC_R_SUCCESS. The reason for failure presumably has - * been logged already. - * - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ - -#define FAIL(code) \ - do { \ - result = (code); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s (%s)", _what, \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILC(code, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILC(code, msg); \ - } while (0) - -#define FAILN(code, name, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s: %s (%s)", _what, _nbuf, \ - msg, isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILN(code, name, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILN(code, name, msg); \ - } while (0) - -#define FAILNT(code, name, type, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s/%s: %s (%s)", \ - _what, _nbuf, _tbuf, msg, \ - isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -#define PREREQFAILNT(code, name, type, msg) \ - do { \ - inc_stats(zone, dns_nsstatscounter_updatebadprereq); \ - FAILNT(code, name, type, msg); \ - } while (0) - -/*% - * Fail unconditionally and log as a server error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILS(code, msg) \ - do { \ - result = (code); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "error: %s: %s", \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/* - * Return TRUE if NS_CLIENTATTR_TCP is set in the attributes other FALSE. - */ -#define TCPCLIENT(client) (((client)->attributes & NS_CLIENTATTR_TCP) != 0) - -/**************************************************************************/ - -typedef struct rr rr_t; - -struct rr { - /* dns_name_t name; */ - uint32_t ttl; - dns_rdata_t rdata; -}; - -typedef struct update_event update_event_t; - -struct update_event { - ISC_EVENT_COMMON(update_event_t); - dns_zone_t *zone; - isc_result_t result; - dns_message_t *answer; -}; - -/*% - * Prepare an RR for the addition of the new RR 'ctx->update_rr', - * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting - * the RRs if it is replaced by the new RR or has a conflicting TTL. - * The necessary changes are appended to ctx->del_diff and ctx->add_diff; - * we need to do all deletions before any additions so that we don't run - * into transient states with conflicting TTLs. - */ - -typedef struct { - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_name_t *oldname; - dns_rdata_t *update_rr; - dns_ttl_t update_rr_ttl; - bool ignore_add; - dns_diff_t del_diff; - dns_diff_t add_diff; -} add_rr_prepare_ctx_t; - -/**************************************************************************/ -/* - * Forward declarations. - */ - -static void update_action(isc_task_t *task, isc_event_t *event); -static void updatedone_action(isc_task_t *task, isc_event_t *event); -static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone); -static void forward_done(isc_task_t *task, isc_event_t *event); -static isc_result_t add_rr_prepare_action(void *data, rr_t *rr); - -/**************************************************************************/ - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) -{ - va_list ap; - char message[4096]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - if (client == NULL) { - return; - } - - if (isc_log_wouldlog(ns_g_lctx, level) == false) { - return; - } - - va_start(ap, fmt); - vsnprintf(message, sizeof(message), fmt, ap); - va_end(ap); - - if (zone != NULL) { - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, - NS_LOGMODULE_UPDATE, - level, "updating zone '%s/%s': %s", - namebuf, classbuf, message); - } else { - ns_client_log(client, NS_LOGCATEGORY_UPDATE, - NS_LOGMODULE_UPDATE, - level, "%s", message); - } - -} - -static void -update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { - update_log(arg, zone, level, "%s", message); -} - -/*% - * Increment updated-related statistics counters. - */ -static inline void -inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { - isc_stats_increment(ns_g_server->nsstats, counter); - - if (zone != NULL) { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - } -} - -/*% - * Check if we could have queried for the contents of this zone or - * if the zone is potentially updateable. - * If the zone can potentially be updated and the check failed then - * log a error otherwise we log a informational message. - */ -static isc_result_t -checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename, - dns_acl_t *updateacl, dns_ssutable_t *ssutable) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level; - isc_result_t result; - - result = ns_client_checkaclsilent(client, NULL, queryacl, true); - if (result != ISC_R_SUCCESS) { - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - level = (updateacl == NULL && ssutable == NULL) ? - ISC_LOG_INFO : ISC_LOG_ERROR; - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, - "update '%s/%s' denied due to allow-query", - namebuf, classbuf); - } else if (updateacl == NULL && ssutable == NULL) { - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - result = DNS_R_REFUSED; - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, ISC_LOG_INFO, - "update '%s/%s' denied", namebuf, classbuf); - } - return (result); -} - -/*% - * Override the default acl logging when checking whether a client - * can update the zone or whether we can forward the request to the - * master based on IP address. - * - * 'message' contains the type of operation that is being attempted. - * 'slave' indicates if this is a slave zone. If 'acl' is NULL then - * log at debug=3. - * If the zone has no access controls configured ('acl' == NULL && - * 'has_ssutable == ISC_FALS) log the attempt at info, otherwise - * at error. - * - * If the request was signed log that we received it. - */ -static isc_result_t -checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message, - dns_name_t *zonename, bool slave, - bool has_ssutable) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level = ISC_LOG_ERROR; - const char *msg = "denied"; - isc_result_t result; - - if (slave && acl == NULL) { - result = DNS_R_NOTIMP; - level = ISC_LOG_DEBUG(3); - msg = "disabled"; - } else { - result = ns_client_checkaclsilent(client, NULL, acl, false); - if (result == ISC_R_SUCCESS) { - level = ISC_LOG_DEBUG(3); - msg = "approved"; - } else if (acl == NULL && !has_ssutable) { - level = ISC_LOG_INFO; - } - } - - if (client->signer != NULL) { - dns_name_format(client->signer, namebuf, sizeof(namebuf)); - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, ISC_LOG_INFO, - "signer \"%s\" %s", namebuf, msg); - } - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, "%s '%s/%s' %s", - message, namebuf, classbuf, msg); - return (result); -} - -/*% - * Update a single RR in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li '*tuple' == NULL. Either the tuple is freed, or its - * ownership has been transferred to the diff. - */ -static isc_result_t -do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - dns_diff_t temp_diff; - isc_result_t result; - - /* - * Create a singleton diff. - */ - dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); - - /* - * Apply it to the database. - */ - result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); - if (result != ISC_R_SUCCESS) { - dns_difftuple_free(tuple); - return (result); - } - - /* - * Merge it into the current pending journal entry. - */ - dns_diff_appendminimal(diff, tuple); - - /* - * Do not clear temp_diff. - */ - return (ISC_R_SUCCESS); -} - -/*% - * Perform the updates in 'updates' in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li 'updates' is empty. - */ -static isc_result_t -do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - isc_result_t result; - while (! ISC_LIST_EMPTY(updates->tuples)) { - dns_difftuple_t *t = ISC_LIST_HEAD(updates->tuples); - ISC_LIST_UNLINK(updates->tuples, t, link); - CHECK(do_one_tuple(&t, db, ver, diff)); - } - return (ISC_R_SUCCESS); - - failure: - dns_diff_clear(diff); - return (result); -} - -static isc_result_t -update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, - dns_rdata_t *rdata) -{ - dns_difftuple_t *tuple = NULL; - isc_result_t result; - result = dns_difftuple_create(diff->mctx, op, - name, ttl, rdata, &tuple); - if (result != ISC_R_SUCCESS) - return (result); - return (do_one_tuple(&tuple, db, ver, diff)); -} - -/**************************************************************************/ -/* - * Callback-style iteration over rdatasets and rdatas. - * - * foreach_rrset() can be used to iterate over the RRsets - * of a name and call a callback function with each - * one. Similarly, foreach_rr() can be used to iterate - * over the individual RRs at name, optionally restricted - * to RRs of a given type. - * - * The callback functions are called "actions" and take - * two arguments: a void pointer for passing arbitrary - * context information, and a pointer to the current RRset - * or RR. By convention, their names end in "_action". - */ - -/* - * XXXRTH We might want to make this public somewhere in libdns. - */ - -/*% - * Function type for foreach_rrset() iterator actions. - */ -typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); - -/*% - * Function type for foreach_rr() iterator actions. - */ -typedef isc_result_t rr_func(void *data, rr_t *rr); - -/*% - * Internal context struct for foreach_node_rr(). - */ -typedef struct { - rr_func * rr_action; - void * rr_action_data; -} foreach_node_rr_ctx_t; - -/*% - * Internal helper function for foreach_node_rr(). - */ -static isc_result_t -foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { - isc_result_t result; - foreach_node_rr_ctx_t *ctx = data; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - - dns_rdataset_current(rdataset, &rr.rdata); - rr.ttl = rdataset->ttl; - result = (*ctx->rr_action)(ctx->rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - return (result); - } - if (result != ISC_R_NOMORE) - return (result); - return (ISC_R_SUCCESS); -} - -/*% - * For each rdataset of 'name' in 'ver' of 'db', call 'action' - * with the rdataset and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - rrset_func *action, void *action_data) -{ - isc_result_t result; - dns_dbnode_t *node; - dns_rdatasetiter_t *iter; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *oldver = NULL; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - - /* - * Only set the clientinfo 'versionp' if the new version is - * different from the current version - */ - dns_db_currentversion(db, &oldver); - dns_clientinfo_init(&ci, NULL, (ver != oldver) ? ver : NULL); - dns_db_closeversion(db, &oldver, false); - - node = NULL; - result = dns_db_findnodeext(db, name, false, &cm, &ci, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - iter = NULL; - result = dns_db_allrdatasets(db, node, ver, - (isc_stdtime_t) 0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(iter, &rdataset); - - result = (*action)(action_data, &rdataset); - - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup_iterator; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup_iterator: - dns_rdatasetiter_destroy(&iter); - - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/*% - * For each RR of 'name' in 'ver' of 'db', call 'action' - * with the RR and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration - * and return the error. - */ -static isc_result_t -foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - rr_func *rr_action, void *rr_action_data) -{ - foreach_node_rr_ctx_t ctx; - ctx.rr_action = rr_action; - ctx.rr_action_data = rr_action_data; - return (foreach_rrset(db, ver, name, - foreach_node_rr_action, &ctx)); -} - - -/*% - * For each of the RRs specified by 'db', 'ver', 'name', 'type', - * (which can be dns_rdatatype_any to match any type), and 'covers', call - * 'action' with the RR and 'action_data' as arguments. If the name - * does not exist, or if no RRset of the given type exists at the name, - * do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action, - void *rr_action_data) -{ - - isc_result_t result; - dns_dbnode_t *node; - dns_rdataset_t rdataset; - dns_clientinfomethods_t cm; - dns_clientinfo_t ci; - dns_dbversion_t *oldver = NULL; - dns_fixedname_t fixed; - - dns_clientinfomethods_init(&cm, ns_client_sourceip); - - /* - * Only set the clientinfo 'versionp' if the new version is - * different from the current version - */ - dns_db_currentversion(db, &oldver); - dns_clientinfo_init(&ci, NULL, (ver != oldver) ? ver : NULL); - dns_db_closeversion(db, &oldver, false); - - if (type == dns_rdatatype_any) - return (foreach_node_rr(db, ver, name, - rr_action, rr_action_data)); - - node = NULL; - if (type == dns_rdatatype_nsec3 || - (type == dns_rdatatype_rrsig && covers == dns_rdatatype_nsec3)) - result = dns_db_findnsec3node(db, name, false, &node); - else - result = dns_db_findnodeext(db, name, false, - &cm, &ci, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, covers, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_node; - } - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - if (rr_action == add_rr_prepare_action) { - add_rr_prepare_ctx_t *ctx = rr_action_data; - - ctx->oldname = dns_fixedname_initname(&fixed); - dns_name_copy(name, ctx->oldname, NULL); - dns_rdataset_getownercase(&rdataset, ctx->oldname); - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - dns_rdataset_current(&rdataset, &rr.rdata); - rr.ttl = rdataset.ttl; - result = (*rr_action)(rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - goto cleanup_rdataset; - } - if (result != ISC_R_NOMORE) - goto cleanup_rdataset; - result = ISC_R_SUCCESS; - - cleanup_rdataset: - dns_rdataset_disassociate(&rdataset); - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/**************************************************************************/ -/* - * Various tests on the database contents (for prerequisites, etc). - */ - -/*% - * Function type for predicate functions that compare a database RR 'db_rr' - * against an update RR 'update_rr'. - */ -typedef bool rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); - -/*% - * Helper function for rrset_exists(). - */ -static isc_result_t -rrset_exists_action(void *data, rr_t *rr) { - UNUSED(data); - UNUSED(rr); - return (ISC_R_EXISTS); -} - -/*% - * Utility macro for RR existence checking functions. - * - * If the variable 'result' has the value ISC_R_EXISTS or - * ISC_R_SUCCESS, set *exists to true or false, - * respectively, and return success. - * - * If 'result' has any other value, there was a failure. - * Return the failure result code and do not set *exists. - * - * This would be more readable as "do { if ... } while(0)", - * but that form generates tons of warnings on Solaris 2.6. - */ -#define RETURN_EXISTENCE_FLAG \ - return ((result == ISC_R_EXISTS) ? \ - (*exists = true, ISC_R_SUCCESS) : \ - ((result == ISC_R_SUCCESS) ? \ - (*exists = false, ISC_R_SUCCESS) : \ - result)) - -/*% - * Set '*exists' to true iff an rrset of the given type exists, - * to false otherwise. - */ -static isc_result_t -rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, - bool *exists) -{ - isc_result_t result; - result = foreach_rr(db, ver, name, type, covers, - rrset_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for cname_incompatible_rrset_exists. - */ -static isc_result_t -cname_compatibility_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (rrset->type != dns_rdatatype_cname && - ! dns_rdatatype_atcname(rrset->type)) - { - return (ISC_R_EXISTS); - } - return (ISC_R_SUCCESS); -} - -/*% - * Check whether there is an rrset incompatible with adding a CNAME RR, - * i.e., anything but another CNAME (which can be replaced) or a - * DNSSEC RR (which can coexist). - * - * If such an incompatible rrset exists, set '*exists' to true. - * Otherwise, set it to false. - */ -static isc_result_t -cname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, bool *exists) { - isc_result_t result; - result = foreach_rrset(db, ver, name, - cname_compatibility_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for rr_count(). - */ -static isc_result_t -count_rr_action(void *data, rr_t *rr) { - int *countp = data; - UNUSED(rr); - (*countp)++; - return (ISC_R_SUCCESS); -} - -/*% - * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'. - */ -static isc_result_t -rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, int *countp) -{ - *countp = 0; - return (foreach_rr(db, ver, name, type, covers, - count_rr_action, countp)); -} - -/*% - * Context struct and helper function for name_exists(). - */ - -static isc_result_t -name_exists_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - UNUSED(rrset); - return (ISC_R_EXISTS); -} - -/*% - * Set '*exists' to true iff the given name exists, to false otherwise. - */ -static isc_result_t -name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - bool *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - name_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/* - * 'ssu_check_t' is used to pass the arguments to - * dns_ssutable_checkrules() to the callback function - * ssu_checkrule(). - */ -typedef struct { - /* The ownername of the record to be updated. */ - dns_name_t *name; - - /* The signature's name if the request was signed. */ - dns_name_t *signer; - - /* The address of the client. */ - isc_netaddr_t *addr; - - /* Whether the request was sent via TCP. */ - bool tcp; - - /* The ssu table to check against. */ - dns_ssutable_t *table; - - /* the key used for TKEY requests */ - dst_key_t *key; -} ssu_check_t; - -static isc_result_t -ssu_checkrule(void *data, dns_rdataset_t *rrset) { - ssu_check_t *ssuinfo = data; - bool result; - - /* - * If we're deleting all records, it's ok to delete RRSIG and NSEC even - * if we're normally not allowed to. - */ - if (rrset->type == dns_rdatatype_rrsig || - rrset->type == dns_rdatatype_nsec) - return (ISC_R_SUCCESS); - result = dns_ssutable_checkrules2(ssuinfo->table, ssuinfo->signer, - ssuinfo->name, ssuinfo->addr, - ssuinfo->tcp, &ns_g_server->aclenv, - rrset->type, ssuinfo->key); - return (result == true ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static bool -ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_ssutable_t *ssutable, dns_name_t *signer, - isc_netaddr_t *addr, bool tcp, dst_key_t *key) -{ - isc_result_t result; - ssu_check_t ssuinfo; - - ssuinfo.name = name; - ssuinfo.table = ssutable; - ssuinfo.signer = signer; - ssuinfo.addr = addr; - ssuinfo.tcp = tcp; - ssuinfo.key = key; - result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo); - return (result == ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Checking of "RRset exists (value dependent)" prerequisites. - * - * In the RFC2136 section 3.2.5, this is the pseudocode involving - * a variable called "temp", a mapping of tuples to rrsets. - * - * Here, we represent the "temp" data structure as (non-minimal) "dns_diff_t" - * where each tuple has op==DNS_DIFFOP_EXISTS. - */ - - -/*% - * Append a tuple asserting the existence of the RR with - * 'name' and 'rdata' to 'diff'. - */ -static isc_result_t -temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - REQUIRE(DNS_DIFF_VALID(diff)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, - name, 0, rdata, &tuple)); - ISC_LIST_APPEND(diff->tuples, tuple, link); - failure: - return (result); -} - -/*% - * Compare two rdatasets represented as sorted lists of tuples. - * All list elements must have the same owner name and type. - * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset) - * if not. - */ -static isc_result_t -temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) { - for (;;) { - if (a == NULL || b == NULL) - break; - INSIST(a->op == DNS_DIFFOP_EXISTS && - b->op == DNS_DIFFOP_EXISTS); - INSIST(a->rdata.type == b->rdata.type); - INSIST(dns_name_equal(&a->name, &b->name)); - if (dns_rdata_casecompare(&a->rdata, &b->rdata) != 0) - return (DNS_R_NXRRSET); - a = ISC_LIST_NEXT(a, link); - b = ISC_LIST_NEXT(b, link); - } - if (a != NULL || b != NULL) - return (DNS_R_NXRRSET); - return (ISC_R_SUCCESS); -} - -/*% - * A comparison function defining the sorting order for the entries - * in the "temp" data structure. The major sort key is the owner name, - * followed by the type and rdata. - */ -static int -temp_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - r = dns_name_compare(&a->name, &b->name); - if (r != 0) - return (r); - r = (b->rdata.type - a->rdata.type); - if (r != 0) - return (r); - r = dns_rdata_casecompare(&a->rdata, &b->rdata); - return (r); -} - -/*% - * Check the "RRset exists (value dependent)" prerequisite information - * in 'temp' against the contents of the database 'db'. - * - * Return ISC_R_SUCCESS if the prerequisites are satisfied, - * rcode(dns_rcode_nxrrset) if not. - * - * 'temp' must be pre-sorted. - */ - -static isc_result_t -temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) -{ - isc_result_t result; - dns_name_t *name; - dns_dbnode_t *node; - dns_difftuple_t *t; - dns_diff_t trash; - - dns_diff_init(mctx, &trash); - - /* - * For each name and type in the prerequisites, - * construct a sorted rdata list of the corresponding - * database contents, and compare the lists. - */ - t = ISC_LIST_HEAD(temp->tuples); - while (t != NULL) { - name = &t->name; - (void)dns_name_copy(name, tmpname, NULL); - *typep = t->rdata.type; - - /* A new unique name begins here. */ - node = NULL; - result = dns_db_findnode(db, name, false, &node); - if (result == ISC_R_NOTFOUND) { - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } - if (result != ISC_R_SUCCESS) { - dns_diff_clear(&trash); - return (result); - } - - /* A new unique type begins here. */ - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_rdataset_t rdataset; - dns_diff_t d_rrs; /* Database RRs with - this name and type */ - dns_diff_t u_rrs; /* Update RRs with - this name and type */ - - *typep = type = t->rdata.type; - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&t->rdata); - else if (type == dns_rdatatype_any) { - dns_db_detachnode(db, &node); - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } else - covers = 0; - - /* - * Collect all database RRs for this name and type - * onto d_rrs and sort them. - */ - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, - covers, (isc_stdtime_t) 0, - &rdataset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - dns_diff_clear(&trash); - return (DNS_R_NXRRSET); - } - - dns_diff_init(mctx, &d_rrs); - dns_diff_init(mctx, &u_rrs); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = temp_append(&d_rrs, name, &rdata); - if (result != ISC_R_SUCCESS) - goto failure; - } - if (result != ISC_R_NOMORE) - goto failure; - result = dns_diff_sort(&d_rrs, temp_order); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Collect all update RRs for this name and type - * onto u_rrs. No need to sort them here - - * they are already sorted. - */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - dns_difftuple_t *next = - ISC_LIST_NEXT(t, link); - ISC_LIST_UNLINK(temp->tuples, t, link); - ISC_LIST_APPEND(u_rrs.tuples, t, link); - t = next; - } - - /* Compare the two sorted lists. */ - result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples), - ISC_LIST_HEAD(d_rrs.tuples)); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * We are done with the tuples, but we can't free - * them yet because "name" still points into one - * of them. Move them on a temporary list. - */ - ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); - ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); - dns_rdataset_disassociate(&rdataset); - - continue; - - failure: - dns_diff_clear(&d_rrs); - dns_diff_clear(&u_rrs); - dns_diff_clear(&trash); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); - } - - dns_db_detachnode(db, &node); - } - - dns_diff_clear(&trash); - return (ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Conditional deletion of RRs. - */ - -/*% - * Context structure for delete_if(). - */ - -typedef struct { - rr_predicate *predicate; - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; -} conditional_delete_ctx_t; - -/*% - * Predicate functions for delete_if(). - */ - -/*% - * Return true iff 'db_rr' is neither a SOA nor an NS RR nor - * an RRSIG nor an NSEC3PARAM nor a NSEC. - */ -static bool -type_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_soa && - db_rr->type != dns_rdatatype_ns && - db_rr->type != dns_rdatatype_nsec3param && - db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - true : false); -} - -/*% - * Return true iff 'db_rr' is neither a RRSIG nor a NSEC. - */ -static bool -type_not_dnssec(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - true : false); -} - -/*% - * Return true always. - */ -static bool -true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - UNUSED(db_rr); - return (true); -} - -/*% - * Return true iff the two RRs have identical rdata. - */ -static bool -rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - /* - * XXXRTH This is not a problem, but we should consider creating - * dns_rdata_equal() (that used dns_name_equal()), since it - * would be faster. Not a priority. - */ - return (dns_rdata_casecompare(update_rr, db_rr) == 0 ? - true : false); -} - -/*% - * Return true iff 'update_rr' should replace 'db_rr' according - * to the special RFC2136 rules for CNAME, SOA, and WKS records. - * - * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs - * make little sense, so we replace those, too. - * - * Additionally replace RRSIG that have been generated by the same key - * for the same type. This simplifies refreshing a offline KSK by not - * requiring that the old RRSIG be deleted. It also simplifies key - * rollover by only requiring that the new RRSIG be added. - */ -static bool -replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - dns_rdata_rrsig_t updatesig, dbsig; - isc_result_t result; - - if (db_rr->type != update_rr->type) - return (false); - if (db_rr->type == dns_rdatatype_cname) - return (true); - if (db_rr->type == dns_rdatatype_dname) - return (true); - if (db_rr->type == dns_rdatatype_soa) - return (true); - if (db_rr->type == dns_rdatatype_nsec) - return (true); - if (db_rr->type == dns_rdatatype_rrsig) { - /* - * Replace existing RRSIG with the same keyid, - * covered and algorithm. - */ - result = dns_rdata_tostruct(db_rr, &dbsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = dns_rdata_tostruct(update_rr, &updatesig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dbsig.keyid == updatesig.keyid && - dbsig.covered == updatesig.covered && - dbsig.algorithm == updatesig.algorithm) - return (true); - } - if (db_rr->type == dns_rdatatype_wks) { - /* - * Compare the address and protocol fields only. These - * form the first five bytes of the RR data. Do a - * raw binary comparison; unpacking the WKS RRs using - * dns_rdata_tostruct() might be cleaner in some ways. - */ - INSIST(db_rr->length >= 5 && update_rr->length >= 5); - return (memcmp(db_rr->data, update_rr->data, 5) == 0 ? - true : false); - } - - if (db_rr->type == dns_rdatatype_nsec3param) { - if (db_rr->length != update_rr->length) - return (false); - INSIST(db_rr->length >= 4 && update_rr->length >= 4); - /* - * Replace NSEC3PARAM records that only differ by the - * flags field. - */ - if (db_rr->data[0] == update_rr->data[0] && - memcmp(db_rr->data+2, update_rr->data+2, - update_rr->length - 2) == 0) - return (true); - } - return (false); -} - -/*% - * Internal helper function for delete_if(). - */ -static isc_result_t -delete_if_action(void *data, rr_t *rr) { - conditional_delete_ctx_t *ctx = data; - if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { - isc_result_t result; - result = update_one_rr(ctx->db, ctx->ver, ctx->diff, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, &rr->rdata); - return (result); - } else { - return (ISC_R_SUCCESS); - } -} - -/*% - * Conditionally delete RRs. Apply 'predicate' to the RRs - * specified by 'db', 'ver', 'name', and 'type' (which can - * be dns_rdatatype_any to match any type). Delete those - * RRs for which the predicate returns true, and log the - * deletions in 'diff'. - */ -static isc_result_t -delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, - dns_rdata_t *update_rr, dns_diff_t *diff) -{ - conditional_delete_ctx_t ctx; - ctx.predicate = predicate; - ctx.db = db; - ctx.ver = ver; - ctx.diff = diff; - ctx.name = name; - ctx.update_rr = update_rr; - return (foreach_rr(db, ver, name, type, covers, - delete_if_action, &ctx)); -} - -/**************************************************************************/ - -static isc_result_t -add_rr_prepare_action(void *data, rr_t *rr) { - isc_result_t result = ISC_R_SUCCESS; - add_rr_prepare_ctx_t *ctx = data; - dns_difftuple_t *tuple = NULL; - bool equal, case_equal, ttl_equal; - - /* - * Are the new and old cases equal? - */ - case_equal = dns_name_caseequal(ctx->name, ctx->oldname); - - /* - * Are the ttl's equal? - */ - ttl_equal = rr->ttl == ctx->update_rr_ttl; - - /* - * If the update RR is a "duplicate" of a existing RR, - * the update should be silently ignored. - */ - equal = !dns_rdata_casecompare(&rr->rdata, ctx->update_rr); - if (equal && case_equal && ttl_equal) { - ctx->ignore_add = true; - return (ISC_R_SUCCESS); - } - - /* - * If this RR is "equal" to the update RR, it should - * be deleted before the update RR is added. - */ - if (replaces_p(ctx->update_rr, &rr->rdata)) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL, - ctx->oldname, rr->ttl, &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - return (ISC_R_SUCCESS); - } - - /* - * If this RR differs in TTL or case from the update RR, - * its TTL and case must be adjusted. - */ - if (!ttl_equal || !case_equal) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL, - ctx->oldname, rr->ttl, &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - if (!equal) { - CHECK(dns_difftuple_create(ctx->add_diff.mctx, - DNS_DIFFOP_ADD, ctx->name, - ctx->update_rr_ttl, - &rr->rdata, &tuple)); - dns_diff_append(&ctx->add_diff, &tuple); - } - } - failure: - return (result); -} - -/**************************************************************************/ -/* - * Miscellaneous subroutines. - */ - -/*% - * Extract a single update RR from 'section' of dynamic update message - * 'msg', with consistency checking. - * - * Stores the owner name, rdata, and TTL of the update RR at 'name', - * 'rdata', and 'ttl', respectively. - */ -static void -get_current_rr(dns_message_t *msg, dns_section_t section, - dns_rdataclass_t zoneclass, dns_name_t **name, - dns_rdata_t *rdata, dns_rdatatype_t *covers, - dns_ttl_t *ttl, dns_rdataclass_t *update_class) -{ - dns_rdataset_t *rdataset; - isc_result_t result; - dns_message_currentname(msg, section, name); - rdataset = ISC_LIST_HEAD((*name)->list); - INSIST(rdataset != NULL); - INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); - *covers = rdataset->covers; - *ttl = rdataset->ttl; - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, rdata); - INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE); - *update_class = rdata->rdclass; - rdata->rdclass = zoneclass; -} - -/*% - * Increment the SOA serial number of database 'db', version 'ver'. - * Replace the SOA record in the database, and log the - * change in 'diff'. - */ - - /* - * XXXRTH Failures in this routine will be worth logging, when - * we have a logging system. Failure to find the zonename - * or the SOA rdataset warrant at least an UNEXPECTED_ERROR(). - */ - -static isc_result_t -update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - isc_mem_t *mctx, dns_updatemethod_t method) -{ - dns_difftuple_t *deltuple = NULL; - dns_difftuple_t *addtuple = NULL; - uint32_t serial; - isc_result_t result; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); - CHECK(dns_difftuple_copy(deltuple, &addtuple)); - addtuple->op = DNS_DIFFOP_ADD; - - serial = dns_soa_getserial(&addtuple->rdata); - serial = dns_update_soaserial(serial, method); - dns_soa_setserial(serial, &addtuple->rdata); - CHECK(do_one_tuple(&deltuple, db, ver, diff)); - CHECK(do_one_tuple(&addtuple, db, ver, diff)); - result = ISC_R_SUCCESS; - - failure: - if (addtuple != NULL) - dns_difftuple_free(&addtuple); - if (deltuple != NULL) - dns_difftuple_free(&deltuple); - return (result); -} - -/*% - * Check that the new SOA record at 'update_rdata' does not - * illegally cause the SOA serial number to decrease or stay - * unchanged relative to the existing SOA in 'db'. - * - * Sets '*ok' to true if the update is legal, false if not. - * - * William King points out that RFC2136 is inconsistent about - * the case where the serial number stays unchanged: - * - * section 3.4.2.2 requires a server to ignore a SOA update request - * if the serial number on the update SOA is less_than_or_equal to - * the zone SOA serial. - * - * section 3.6 requires a server to ignore a SOA update request if - * the serial is less_than the zone SOA serial. - * - * Paul says 3.4.2.2 is correct. - * - */ -static isc_result_t -check_soa_increment(dns_db_t *db, dns_dbversion_t *ver, - dns_rdata_t *update_rdata, bool *ok) -{ - uint32_t db_serial; - uint32_t update_serial; - isc_result_t result; - - update_serial = dns_soa_getserial(update_rdata); - - result = dns_db_getsoaserial(db, ver, &db_serial); - if (result != ISC_R_SUCCESS) - return (result); - - if (DNS_SERIAL_GE(db_serial, update_serial)) { - *ok = false; - } else { - *ok = true; - } - - return (ISC_R_SUCCESS); - -} - -/**************************************************************************/ -/*% - * The actual update code in all its glory. We try to follow - * the RFC2136 pseudocode as closely as possible. - */ - -static isc_result_t -send_update_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - update_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - isc_result_t msg_result; - - msg_result = dns_message_reply(client->message, true); - if (msg_result != ISC_R_SUCCESS) - goto msg_failure; - client->message->rcode = dns_result_torcode(result); - - ns_client_send(client); - return; - - msg_failure: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - ISC_LOG_ERROR, - "could not create update response message: %s", - isc_result_totext(msg_result)); - ns_client_next(client, msg_result); -} - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL, *raw = NULL; - - /* - * Interpret the zone section. - */ - result = dns_message_firstname(request, DNS_SECTION_ZONE); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, "update zone section empty"); - - /* - * The zone section must contain exactly one "question", and - * it must be of type SOA. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_ZONE, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (zone_rdataset->type != dns_rdatatype_soa) - FAILC(DNS_R_FORMERR, - "update zone section contains non-SOA"); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_NOTAUTH, "not authoritative for update zone"); - - /* - * If there is a raw (unsigned) zone associated with this - * zone then it processes the UPDATE request. - */ - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&zone); - dns_zone_attach(raw, &zone); - dns_zone_detach(&raw); - } - - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_dlz: - /* - * We can now fail due to a bad signature as we now know - * that we are the master. - */ - if (sigresult != ISC_R_SUCCESS) - FAIL(sigresult); - CHECK(send_update_event(client, zone)); - break; - case dns_zone_slave: - CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone), - "update forwarding", zonename, true, - false)); - CHECK(send_forward_event(client, zone)); - break; - default: - FAILC(DNS_R_NOTAUTH, "not authoritative for update zone"); - } - return; - - failure: - if (result == DNS_R_REFUSED) { - INSIST(dns_zone_gettype(zone) == dns_zone_slave); - inc_stats(zone, dns_nsstatscounter_updaterej); - } - /* - * We failed without having sent an update event to the zone. - * We are still in the client task context, so we can - * simply give an error response without switching tasks. - */ - respond(client, result); - if (zone != NULL) - dns_zone_detach(&zone); -} - -/*% - * DS records are not allowed to exist without corresponding NS records, - * RFC 3658, 2.2 Protocol Change, - * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". - */ - -static isc_result_t -remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { - isc_result_t result; - bool ns_exists; - dns_difftuple_t *tupple; - dns_diff_t temp_diff; - - dns_diff_init(diff->mctx, &temp_diff); - - for (tupple = ISC_LIST_HEAD(diff->tuples); - tupple != NULL; - tupple = ISC_LIST_NEXT(tupple, link)) { - if (!((tupple->op == DNS_DIFFOP_DEL && - tupple->rdata.type == dns_rdatatype_ns) || - (tupple->op == DNS_DIFFOP_ADD && - tupple->rdata.type == dns_rdatatype_ds))) - continue; - CHECK(rrset_exists(db, newver, &tupple->name, - dns_rdatatype_ns, 0, &ns_exists)); - if (ns_exists && - !dns_name_equal(&tupple->name, dns_db_origin(db))) - continue; - CHECK(delete_if(true_p, db, newver, &tupple->name, - dns_rdatatype_ds, 0, NULL, &temp_diff)); - } - result = ISC_R_SUCCESS; - - failure: - for (tupple = ISC_LIST_HEAD(temp_diff.tuples); - tupple != NULL; - tupple = ISC_LIST_HEAD(temp_diff.tuples)) { - ISC_LIST_UNLINK(temp_diff.tuples, tupple, link); - dns_diff_appendminimal(diff, &tupple); - } - return (result); -} - -/* - * This implements the post load integrity checks for mx records. - */ -static isc_result_t -check_mx(ns_client_t *client, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) -{ - char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char altbuf[DNS_NAME_FORMATSIZE]; - dns_difftuple_t *t; - dns_fixedname_t fixed; - dns_name_t *foundname; - dns_rdata_mx_t mx; - dns_rdata_t rdata; - bool ok = true; - bool isaddress; - isc_result_t result; - struct in6_addr addr6; - struct in_addr addr; - unsigned int options; - - foundname = dns_fixedname_initname(&fixed); - dns_rdata_init(&rdata); - options = dns_zone_getoptions(zone); - - for (t = ISC_LIST_HEAD(diff->tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) { - if (t->op != DNS_DIFFOP_ADD || - t->rdata.type != dns_rdatatype_mx) - continue; - - result = dns_rdata_tostruct(&t->rdata, &mx, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* - * Check if we will error out if we attempt to reload the - * zone. - */ - dns_name_format(&mx.mx, namebuf, sizeof(namebuf)); - dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf)); - isaddress = false; - if ((options & DNS_ZONEOPT_CHECKMX) != 0 && - strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) { - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - isaddress = true; - } - - if (isaddress && (options & DNS_ZONEOPT_CHECKMXFAIL) != 0) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - ok = false; - } else if (isaddress) { - update_log(client, zone, ISC_LOG_WARNING, - "%s/MX: warning: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - } - - /* - * Check zone integrity checks. - */ - if ((options & DNS_ZONEOPT_CHECKINTEGRITY) == 0) - continue; - result = dns_db_find(db, &mx.mx, newver, dns_rdatatype_a, - 0, 0, NULL, foundname, NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - - if (result == DNS_R_NXRRSET) { - result = dns_db_find(db, &mx.mx, newver, - dns_rdatatype_aaaa, - 0, 0, NULL, foundname, - NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - } - - if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' has no address records " - "(A or AAAA)", ownerbuf, namebuf); - ok = false; - } else if (result == DNS_R_CNAME) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is a CNAME (illegal)", - ownerbuf, namebuf); - ok = false; - } else if (result == DNS_R_DNAME) { - dns_name_format(foundname, altbuf, sizeof altbuf); - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is below a DNAME '%s' (illegal)", - ownerbuf, namebuf, altbuf); - ok = false; - } - } - return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED); -} - -static isc_result_t -rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - const dns_rdata_t *rdata, bool *flag) -{ - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - isc_result_t result; - - dns_rdataset_init(&rdataset); - if (rdata->type == dns_rdatatype_nsec3) - CHECK(dns_db_findnsec3node(db, name, false, &node)); - else - CHECK(dns_db_findnode(db, name, false, &node)); - result = dns_db_findrdataset(db, node, ver, rdata->type, 0, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - *flag = false; - result = ISC_R_SUCCESS; - goto failure; - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t myrdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &myrdata); - if (!dns_rdata_casecompare(&myrdata, rdata)) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - *flag = true; - } else if (result == ISC_R_NOMORE) { - *flag = false; - result = ISC_R_SUCCESS; - } - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_result_t -get_iterations(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype, - unsigned int *iterationsp) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - dns_rdataset_t rdataset; - isc_result_t result; - unsigned int iterations = 0; - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto try_private; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (nsec3param.iterations > iterations) - iterations = nsec3param.iterations; - } - if (result != ISC_R_NOMORE) - goto failure; - - dns_rdataset_disassociate(&rdataset); - - try_private: - if (privatetype == 0) - goto success; - - result = dns_db_findrdataset(db, node, ver, privatetype, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t private = DNS_RDATA_INIT; - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) - continue; - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (nsec3param.iterations > iterations) - iterations = nsec3param.iterations; - } - if (result != ISC_R_NOMORE) - goto failure; - - success: - *iterationsp = iterations; - result = ISC_R_SUCCESS; - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (result); -} - -/* - * Prevent the zone entering a inconsistent state where - * NSEC only DNSKEYs are present with NSEC3 chains. - */ -static isc_result_t -check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_difftuple_t *tuple; - bool nseconly = false, nsec3 = false; - isc_result_t result; - unsigned int iterations = 0, max; - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - - /* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - if (tuple->op != DNS_DIFFOP_ADD) - continue; - - if (tuple->rdata.type == dns_rdatatype_dnskey) { - uint8_t alg; - alg = tuple->rdata.data[3]; - if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || - alg == DST_ALG_DSA || alg == DST_ALG_ECC) { - nseconly = true; - break; - } - } else if (tuple->rdata.type == dns_rdatatype_nsec3param) { - nsec3 = true; - break; - } - } - - /* Check existing DB for NSEC-only DNSKEY */ - if (!nseconly) { - result = dns_nsec_nseconly(db, ver, &nseconly); - - /* - * An NSEC3PARAM update can proceed without a DNSKEY (it - * will trigger a delayed change), so we can ignore - * ISC_R_NOTFOUND here. - */ - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - - CHECK(result); - } - - /* Check existing DB for NSEC3 */ - if (!nsec3) - CHECK(dns_nsec3_activex(db, ver, false, - privatetype, &nsec3)); - - /* Refuse to allow NSEC3 with NSEC-only keys */ - if (nseconly && nsec3) { - update_log(client, zone, ISC_LOG_ERROR, - "NSEC only DNSKEYs and NSEC3 chains not allowed"); - result = DNS_R_REFUSED; - goto failure; - } - - /* Verify NSEC3 params */ - CHECK(get_iterations(db, ver, privatetype, &iterations)); - CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max)); - if (max != 0 && iterations > max) { - update_log(client, zone, ISC_LOG_ERROR, - "too many NSEC3 iterations (%u) for " - "weakest DNSKEY (%u)", iterations, max); - result = DNS_R_REFUSED; - goto failure; - } - - failure: - return (result); -} - -/* - * Delay NSEC3PARAM changes as they need to be applied to the whole zone. - */ -static isc_result_t -add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1]; - dns_diff_t temp_diff; - dns_diffop_t op; - bool flag; - dns_name_t *name = dns_zone_getorigin(zone); - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - uint32_t ttl = 0; - bool ttl_good = false; - - update_log(client, zone, ISC_LOG_DEBUG(3), - "checking for NSEC3PARAM changes"); - - dns_diff_init(diff->mctx, &temp_diff); - - /* - * Extract NSEC3PARAM tuples from list. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; - tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != dns_rdatatype_nsec3param || - !dns_name_equal(name, &tuple->name)) - continue; - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_APPEND(temp_diff.tuples, tuple, link); - } - - /* - * Extract TTL changes pairs, we don't need to convert these to - * delayed changes. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - if (tuple->op == DNS_DIFFOP_ADD) { - if (!ttl_good) { - /* - * Any adds here will contain the final - * NSEC3PARAM RRset TTL. - */ - ttl = tuple->ttl; - ttl_good = true; - } - /* - * Walk the temp_diff list looking for the - * corresponding delete. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op == DNS_DIFFOP_DEL && - next->rdata.length == tuple->rdata.length && - !memcmp(next_data, tuple_data, - next->rdata.length)) { - ISC_LIST_UNLINK(temp_diff.tuples, next, - link); - ISC_LIST_APPEND(diff->tuples, next, - link); - break; - } - next = ISC_LIST_NEXT(next, link); - } - /* - * If we have not found a pair move onto the next - * tuple. - */ - if (next == NULL) { - next = ISC_LIST_NEXT(tuple, link); - continue; - } - /* - * Find the next tuple to be processed before - * unlinking then complete moving the pair to 'diff'. - */ - next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - /* - * Preserve any ongoing changes from a BIND 9.6.x upgrade. - * - * Any NSEC3PARAM records with flags other than OPTOUT named - * in managing and should not be touched so revert such changes - * taking into account any TTL change of the NSEC3PARAM RRset. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - next = ISC_LIST_NEXT(tuple, link); - if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) { - /* - * If we haven't had any adds then the tuple->ttl must - * be the original ttl and should be used for any - * future changes. - */ - if (!ttl_good) { - ttl = tuple->ttl; - ttl_good = true; - } - op = (tuple->op == DNS_DIFFOP_DEL) ? - DNS_DIFFOP_ADD : DNS_DIFFOP_DEL; - CHECK(dns_difftuple_create(diff->mctx, op, name, - ttl, &tuple->rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - } - } - - /* - * We now have just the actual changes to the NSEC3PARAM RRset. - * Convert the adds to delayed adds and the deletions into delayed - * deletions. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - /* - * If we haven't had any adds then the tuple->ttl must be the - * original ttl and should be used for any future changes. - */ - if (!ttl_good) { - ttl = tuple->ttl; - ttl_good = true; - } - if (tuple->op == DNS_DIFFOP_ADD) { - bool nseconly = false; - - /* - * Look for any deletes which match this ADD ignoring - * flags. We don't need to explicitly remove them as - * they will be removed a side effect of processing - * the add. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op != DNS_DIFFOP_DEL || - next->rdata.length != tuple->rdata.length || - next_data[0] != tuple_data[0] || - next_data[2] != tuple_data[2] || - next_data[3] != tuple_data[3] || - memcmp(next_data + 4, tuple_data + 4, - tuple->rdata.length - 4)) { - next = ISC_LIST_NEXT(next, link); - continue; - } - ISC_LIST_UNLINK(temp_diff.tuples, next, link); - ISC_LIST_APPEND(diff->tuples, next, link); - next = ISC_LIST_HEAD(temp_diff.tuples); - } - - /* - * Create a private-type record to signal that - * we want a delayed NSEC3 chain add/delete - */ - dns_nsec3param_toprivate(&tuple->rdata, &rdata, - privatetype, buf, sizeof(buf)); - buf[2] |= DNS_NSEC3FLAG_CREATE; - - /* - * If the zone is not currently capable of - * supporting an NSEC3 chain, then we set the - * INITIAL flag to indicate that these parameters - * are to be used later. - */ - result = dns_nsec_nseconly(db, ver, &nseconly); - if (result == ISC_R_NOTFOUND || nseconly) - buf[2] |= DNS_NSEC3FLAG_INITIAL; - - /* - * See if this CREATE request already exists. - */ - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, - DNS_DIFFOP_ADD, - name, 0, &rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - - /* - * Remove any existing CREATE request to add an - * otherwise identical chain with a reversed - * OPTOUT state. - */ - buf[2] ^= DNS_NSEC3FLAG_OPTOUT; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - - if (flag) { - CHECK(dns_difftuple_create(diff->mctx, - DNS_DIFFOP_DEL, - name, 0, &rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - - /* - * Find the next tuple to be processed and remove the - * temporary add record. - */ - next = ISC_LIST_NEXT(tuple, link); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, - name, ttl, &tuple->rdata, - &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - dns_rdata_reset(&rdata); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - - INSIST(ttl_good); - - next = ISC_LIST_NEXT(tuple, link); - /* - * See if we already have a REMOVE request in progress. - */ - dns_nsec3param_toprivate(&tuple->rdata, &rdata, privatetype, - buf, sizeof(buf)); - - buf[2] |= DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC; - - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (!flag) { - buf[2] &= ~DNS_NSEC3FLAG_NONSEC; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - } - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - } - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, - ttl, &tuple->rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - dns_diff_appendminimal(diff, &tuple); - dns_rdata_reset(&rdata); - } - - result = ISC_R_SUCCESS; - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -static isc_result_t -rollback_private(dns_db_t *db, dns_rdatatype_t privatetype, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_diff_t temp_diff; - dns_diffop_t op; - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_name_t *name = dns_db_origin(db); - isc_mem_t *mctx = diff->mctx; - isc_result_t result; - - if (privatetype == 0) - return (ISC_R_SUCCESS); - - dns_diff_init(mctx, &temp_diff); - - /* - * Extract the changes to be rolled back. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != privatetype || - !dns_name_equal(name, &tuple->name)) - continue; - - /* - * Allow records which indicate that a zone has been - * signed with a DNSKEY to be removed. - */ - if (tuple->op == DNS_DIFFOP_DEL && - tuple->rdata.length == 5 && - tuple->rdata.data[0] != 0 && - tuple->rdata.data[4] != 0) - continue; - - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_PREPEND(temp_diff.tuples, tuple, link); - } - - /* - * Rollback the changes. - */ - while ((tuple = ISC_LIST_HEAD(temp_diff.tuples)) != NULL) { - op = (tuple->op == DNS_DIFFOP_DEL) ? - DNS_DIFFOP_ADD : DNS_DIFFOP_DEL; - CHECK(dns_difftuple_create(mctx, op, name, tuple->ttl, - &tuple->rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff)); - } - result = ISC_R_SUCCESS; - - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -/* - * Add records to cause the delayed signing of the zone by added DNSKEY - * to remove the RRSIG records generated by a deleted DNSKEY. - */ -static isc_result_t -add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, - dns_dbversion_t *ver, dns_diff_t *diff) -{ - dns_difftuple_t *tuple, *newtuple = NULL, *next; - dns_rdata_dnskey_t dnskey; - dns_rdata_t rdata = DNS_RDATA_INIT; - bool flag; - isc_region_t r; - isc_result_t result = ISC_R_SUCCESS; - uint16_t keyid; - unsigned char buf[5]; - dns_name_t *name = dns_db_origin(db); - dns_diff_t temp_diff; - - dns_diff_init(diff->mctx, &temp_diff); - - /* - * Extract the DNSKEY tuples from the list. - */ - for (tuple = ISC_LIST_HEAD(diff->tuples); - tuple != NULL; tuple = next) { - - next = ISC_LIST_NEXT(tuple, link); - - if (tuple->rdata.type != dns_rdatatype_dnskey) - continue; - - ISC_LIST_UNLINK(diff->tuples, tuple, link); - ISC_LIST_APPEND(temp_diff.tuples, tuple, link); - } - - /* - * Extract TTL changes pairs, we don't need signing records for these. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; tuple = next) { - if (tuple->op == DNS_DIFFOP_ADD) { - /* - * Walk the temp_diff list looking for the - * corresponding delete. - */ - next = ISC_LIST_HEAD(temp_diff.tuples); - while (next != NULL) { - unsigned char *next_data = next->rdata.data; - unsigned char *tuple_data = tuple->rdata.data; - if (next->op == DNS_DIFFOP_DEL && - dns_name_equal(&tuple->name, &next->name) && - next->rdata.length == tuple->rdata.length && - !memcmp(next_data, tuple_data, - next->rdata.length)) { - ISC_LIST_UNLINK(temp_diff.tuples, next, - link); - ISC_LIST_APPEND(diff->tuples, next, - link); - break; - } - next = ISC_LIST_NEXT(next, link); - } - /* - * If we have not found a pair move onto the next - * tuple. - */ - if (next == NULL) { - next = ISC_LIST_NEXT(tuple, link); - continue; - } - /* - * Find the next tuple to be processed before - * unlinking then complete moving the pair to 'diff'. - */ - next = ISC_LIST_NEXT(tuple, link); - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - } else - next = ISC_LIST_NEXT(tuple, link); - } - - /* - * Process the remaining DNSKEY entries. - */ - for (tuple = ISC_LIST_HEAD(temp_diff.tuples); - tuple != NULL; - tuple = ISC_LIST_HEAD(temp_diff.tuples)) { - - ISC_LIST_UNLINK(temp_diff.tuples, tuple, link); - ISC_LIST_APPEND(diff->tuples, tuple, link); - - result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if ((dnskey.flags & - (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) - != DNS_KEYOWNER_ZONE) - continue; - - dns_rdata_toregion(&tuple->rdata, &r); - - keyid = dst_region_computeid(&r, dnskey.algorithm); - - buf[0] = dnskey.algorithm; - buf[1] = (keyid & 0xff00) >> 8; - buf[2] = (keyid & 0xff); - buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; - buf[4] = 0; - rdata.data = buf; - rdata.length = sizeof(buf); - rdata.type = privatetype; - rdata.rdclass = tuple->rdata.rdclass; - - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (flag) - continue; - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - INSIST(newtuple == NULL); - /* - * Remove any record which says this operation has already - * completed. - */ - buf[4] = 1; - CHECK(rr_exists(db, ver, name, &rdata, &flag)); - if (flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, - name, 0, &rdata, &newtuple)); - CHECK(do_one_tuple(&newtuple, db, ver, diff)); - INSIST(newtuple == NULL); - } - } - - failure: - dns_diff_clear(&temp_diff); - return (result); -} - -static bool -isdnssec(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype) { - isc_result_t result; - bool build_nsec, build_nsec3; - - if (dns_db_issecure(db)) - return (true); - - result = dns_private_chains(db, ver, privatetype, - &build_nsec, &build_nsec3); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - return (build_nsec || build_nsec3); -} - -static void -update_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *oldver = NULL; - dns_dbversion_t *ver = NULL; - dns_diff_t diff; /* Pending updates. */ - dns_diff_t temp; /* Pending RR existence assertions. */ - bool soa_serial_changed = false; - isc_mem_t *mctx = client->mctx; - dns_rdatatype_t covers; - dns_message_t *request = client->message; - dns_rdataclass_t zoneclass; - dns_name_t *zonename; - dns_ssutable_t *ssutable = NULL; - dns_fixedname_t tmpnamefixed; - dns_name_t *tmpname = NULL; - unsigned int options, options2; - dns_difftuple_t *tuple; - dns_rdata_dnskey_t dnskey; - bool had_dnskey; - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - dns_ttl_t maxttl = 0; - uint32_t maxrecords; - uint64_t records; - - INSIST(event->ev_type == DNS_EVENT_UPDATE); - - dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &temp); - - CHECK(dns_zone_getdb(zone, &db)); - zonename = dns_db_origin(db); - zoneclass = dns_db_class(db); - dns_zone_getssutable(zone, &ssutable); - - /* - * Update message processing can leak record existence information - * so check that we are allowed to query this zone. Additionally - * if we would refuse all updates for this zone we bail out here. - */ - CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename, - dns_zone_getupdateacl(zone), ssutable)); - - /* - * Get old and new versions now that queryacl has been checked. - */ - dns_db_currentversion(db, &oldver); - CHECK(dns_db_newversion(db, &ver)); - - /* - * Check prerequisites. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - bool flag; - - get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (ttl != 0) - PREREQFAILC(DNS_R_FORMERR, - "prerequisite TTL is not zero"); - - if (! dns_name_issubdomain(name, zonename)) - PREREQFAILN(DNS_R_NOTZONE, name, - "prerequisite name is out of zone"); - - if (update_class == dns_rdataclass_any) { - if (rdata.length != 0) - PREREQFAILC(DNS_R_FORMERR, - "class ANY prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (! flag) { - PREREQFAILN(DNS_R_NXDOMAIN, name, - "'name in use' " - "prerequisite not " - "satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (! flag) { - /* RRset does not exist. */ - PREREQFAILNT(DNS_R_NXRRSET, name, rdata.type, - "'rrset exists (value independent)' " - "prerequisite not satisfied"); - } - } - } else if (update_class == dns_rdataclass_none) { - if (rdata.length != 0) - PREREQFAILC(DNS_R_FORMERR, - "class NONE prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (flag) { - PREREQFAILN(DNS_R_YXDOMAIN, name, - "'name not in use' " - "prerequisite not " - "satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (flag) { - /* RRset exists. */ - PREREQFAILNT(DNS_R_YXRRSET, name, - rdata.type, - "'rrset does not exist' " - "prerequisite not " - "satisfied"); - } - } - } else if (update_class == zoneclass) { - /* "temp += rr;" */ - result = temp_append(&temp, name, &rdata); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "temp entry creation failed: %s", - dns_result_totext(result)); - FAIL(ISC_R_UNEXPECTED); - } - } else { - PREREQFAILC(DNS_R_FORMERR, "malformed prerequisite"); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * Perform the final check of the "rrset exists (value dependent)" - * prerequisites. - */ - if (ISC_LIST_HEAD(temp.tuples) != NULL) { - dns_rdatatype_t type; - - /* - * Sort the prerequisite records by owner name, - * type, and rdata. - */ - result = dns_diff_sort(&temp, temp_order); - if (result != ISC_R_SUCCESS) - FAILC(result, "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - - tmpname = dns_fixedname_initname(&tmpnamefixed); - result = temp_check(mctx, &temp, db, ver, tmpname, &type); - if (result != ISC_R_SUCCESS) - FAILNT(result, tmpname, type, - "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - } - - update_log(client, zone, LOGLEVEL_DEBUG, - "prerequisites are OK"); - - /* - * Check Requestor's Permissions. It seems a bit silly to do this - * only after prerequisite testing, but that is what RFC2136 says. - */ - if (ssutable == NULL) - CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone), - "update", zonename, false, false)); - else if (client->signer == NULL && !TCPCLIENT(client)) - CHECK(checkupdateacl(client, NULL, "update", zonename, - false, true)); - - if (dns_zone_getupdatedisabled(zone)) - FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled " - "because the zone is frozen. Use " - "'rndc thaw' to re-enable updates."); - - /* - * Perform the Update Section Prescan. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (! dns_name_issubdomain(name, zonename)) - FAILC(DNS_R_NOTZONE, - "update RR is outside zone"); - if (update_class == zoneclass) { - /* - * Check for meta-RRs. The RFC2136 pseudocode says - * check for ANY|AXFR|MAILA|MAILB, but the text adds - * "or any other QUERY metatype" - */ - if (dns_rdatatype_ismeta(rdata.type)) { - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } - result = dns_zone_checknames(zone, name, &rdata); - if (result != ISC_R_SUCCESS) - FAIL(DNS_R_REFUSED); - } else if (update_class == dns_rdataclass_any) { - if (ttl != 0 || rdata.length != 0 || - (dns_rdatatype_ismeta(rdata.type) && - rdata.type != dns_rdatatype_any)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else if (update_class == dns_rdataclass_none) { - if (ttl != 0 || - dns_rdatatype_ismeta(rdata.type)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else { - update_log(client, zone, ISC_LOG_WARNING, - "update RR has incorrect class %d", - update_class); - FAIL(DNS_R_FORMERR); - } - - /* - * draft-ietf-dnsind-simple-secure-update-01 says - * "Unlike traditional dynamic update, the client - * is forbidden from updating NSEC records." - */ - if (rdata.type == dns_rdatatype_nsec3) { - FAILC(DNS_R_REFUSED, - "explicit NSEC3 updates are not allowed " - "in secure zones"); - } else if (rdata.type == dns_rdatatype_nsec) { - FAILC(DNS_R_REFUSED, - "explicit NSEC updates are not allowed " - "in secure zones"); - } else if (rdata.type == dns_rdatatype_rrsig && - !dns_name_equal(name, zonename)) { - FAILC(DNS_R_REFUSED, - "explicit RRSIG updates are currently " - "not supported in secure zones except " - "at the apex"); - } - - if (ssutable != NULL) { - isc_netaddr_t netaddr; - dst_key_t *tsigkey = NULL; - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (client->message->tsigkey != NULL) - tsigkey = client->message->tsigkey->key; - - if (rdata.type != dns_rdatatype_any) { - if (!dns_ssutable_checkrules2 - (ssutable, client->signer, name, &netaddr, - TCPCLIENT(client), - &ns_g_server->aclenv, - rdata.type, tsigkey)) - { - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } else { - if (!ssu_checkall(db, ver, name, ssutable, - client->signer, - &netaddr, - TCPCLIENT(client), - tsigkey)) - { - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - update_log(client, zone, LOGLEVEL_DEBUG, - "update section prescan OK"); - - /* - * Process the Update Section. - */ - - options = dns_zone_getoptions(zone); - options2 = dns_zone_getoptions2(zone); - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - bool flag; - - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (update_class == zoneclass) { - - /* - * RFC1123 doesn't allow MF and MD in master zones. - */ - if (rdata.type == dns_rdatatype_md || - rdata.type == dns_rdatatype_mf) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add %s ignored", - typebuf); - continue; - } - if ((rdata.type == dns_rdatatype_ns || - rdata.type == dns_rdatatype_dname) && - dns_name_iswildcard(name)) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add wildcard %s record " - "ignored", typebuf); - continue; - } - if (rdata.type == dns_rdatatype_cname) { - CHECK(cname_incompatible_rrset_exists(db, ver, - name, - &flag)); - if (flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add CNAME " - "alongside non-CNAME " - "ignored"); - continue; - } - } else { - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_cname, 0, - &flag)); - if (flag && - ! dns_rdatatype_atcname(rdata.type)) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add non-CNAME " - "alongside CNAME ignored"); - continue; - } - } - if (rdata.type == dns_rdatatype_soa) { - bool ok; - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_soa, 0, - &flag)); - if (! flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to create 2nd " - "SOA ignored"); - continue; - } - CHECK(check_soa_increment(db, ver, &rdata, - &ok)); - if (! ok) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "SOA update failed to " - "increment serial, " - "ignoring it"); - continue; - } - soa_serial_changed = true; - } - - if (rdata.type == privatetype) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add a private type " - "(%u) record rejected internal " - "use only", privatetype); - continue; - } - - if (rdata.type == dns_rdatatype_nsec3param) { - /* - * Ignore attempts to add NSEC3PARAM records - * with any flags other than OPTOUT. - */ - if ((rdata.data[1] & - ~DNS_NSEC3FLAG_OPTOUT) != 0) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add NSEC3PARAM " - "record with non OPTOUT " - "flag"); - continue; - } - } - - if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 && - dns_name_internalwildcard(name)) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "warning: ownername '%s' contains " - "a non-terminal wildcard", namestr); - } - - if ((options2 & DNS_ZONEOPT2_CHECKTTL) != 0) { - maxttl = dns_zone_getmaxttl(zone); - if (ttl > maxttl) { - ttl = maxttl; - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "reducing TTL to the " - "configured max-zone-ttl %d", - maxttl); - } - } - - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - char rdstr[2048]; - isc_buffer_t buf; - int len = 0; - const char *truncated = ""; - - dns_name_format(name, namestr, sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - isc_buffer_init(&buf, rdstr, sizeof(rdstr)); - result = dns_rdata_totext(&rdata, NULL, &buf); - if (result == ISC_R_NOSPACE) { - len = (int)isc_buffer_usedlength(&buf); - truncated = " [TRUNCATED]"; - } else if (result != ISC_R_SUCCESS) { - snprintf(rdstr, sizeof(rdstr), "[dns_" - "rdata_totext failed: %s]", - dns_result_totext(result)); - len = strlen(rdstr); - } else - len = (int)isc_buffer_usedlength(&buf); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "adding an RR at '%s' %s %.*s%s", - namestr, typestr, len, rdstr, - truncated); - } - - /* Prepare the affected RRset for the addition. */ - { - add_rr_prepare_ctx_t ctx; - ctx.db = db; - ctx.ver = ver; - ctx.diff = &diff; - ctx.name = name; - ctx.oldname = name; - ctx.update_rr = &rdata; - ctx.update_rr_ttl = ttl; - ctx.ignore_add = false; - dns_diff_init(mctx, &ctx.del_diff); - dns_diff_init(mctx, &ctx.add_diff); - CHECK(foreach_rr(db, ver, name, rdata.type, - covers, add_rr_prepare_action, - &ctx)); - - if (ctx.ignore_add) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - } else { - result = do_diff(&ctx.del_diff, db, ver, - &diff); - if (result == ISC_R_SUCCESS) { - result = do_diff(&ctx.add_diff, - db, ver, - &diff); - } - if (result != ISC_R_SUCCESS) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - goto failure; - } - CHECK(update_one_rr(db, ver, &diff, - DNS_DIFFOP_ADD, - name, ttl, &rdata)); - } - } - } else if (update_class == dns_rdataclass_any) { - if (rdata.type == dns_rdatatype_any) { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "delete all rrsets from " - "name '%s'", namestr); - } - if (dns_name_equal(name, zonename)) { - CHECK(delete_if(type_not_soa_nor_ns_p, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } else { - CHECK(delete_if(type_not_dnssec, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } - } else if (dns_name_equal(name, zonename) && - (rdata.type == dns_rdatatype_soa || - rdata.type == dns_rdatatype_ns)) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to delete all SOA " - "or NS records ignored"); - continue; - } else { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, - typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting rrset at '%s' %s", - namestr, typestr); - } - CHECK(delete_if(true_p, db, ver, name, - rdata.type, covers, &rdata, - &diff)); - } - } else if (update_class == dns_rdataclass_none) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - - /* - * The (name == zonename) condition appears in - * RFC2136 3.4.2.4 but is missing from the pseudocode. - */ - if (dns_name_equal(name, zonename)) { - if (rdata.type == dns_rdatatype_soa) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete SOA " - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_ns) { - int count; - CHECK(rr_count(db, ver, name, - dns_rdatatype_ns, - 0, &count)); - if (count == 1) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to " - "delete last " - "NS ignored"); - continue; - } - } - } - dns_name_format(name, namestr, sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "deleting an RR at %s %s", namestr, typestr); - CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type, - covers, &rdata, &diff)); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * Check that any changes to DNSKEY/NSEC3PARAM records make sense. - * If they don't then back out all changes to DNSKEY/NSEC3PARAM - * records. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) - CHECK(check_dnssec(client, zone, db, ver, &diff)); - - if (! ISC_LIST_EMPTY(diff.tuples)) { - unsigned int errors = 0; - CHECK(dns_zone_nscheck(zone, db, ver, &errors)); - if (errors != 0) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: post update name server " - "sanity check failed"); - result = DNS_R_REFUSED; - goto failure; - } - } - if (! ISC_LIST_EMPTY(diff.tuples)) { - result = dns_zone_cdscheck(zone, db, ver); - if (result == DNS_R_BADCDS || result == DNS_R_BADCDNSKEY) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: bad %s RRset", - result == DNS_R_BADCDS ? "CDS" : "CDNSKEY"); - result = DNS_R_REFUSED; - goto failure; - } - if (result != ISC_R_SUCCESS) - goto failure; - - } - - /* - * If any changes were made, increment the SOA serial number, - * update RRSIGs and NSECs (if zone is secure), and write the update - * to the journal. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) { - char *journalfile; - dns_journal_t *journal; - bool has_dnskey; - - /* - * Increment the SOA serial, but only if it was not - * changed as a result of an update operation. - */ - if (! soa_serial_changed) { - CHECK(update_soa_serial(db, ver, &diff, mctx, - dns_zone_getserialupdatemethod(zone))); - } - - CHECK(check_mx(client, zone, db, ver, &diff)); - - CHECK(remove_orphaned_ds(db, ver, &diff)); - - CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey, - 0, &has_dnskey)); - -#define ALLOW_SECURE_TO_INSECURE(zone) \ - ((dns_zone_getoptions(zone) & DNS_ZONEOPT_SECURETOINSECURE) != 0) - - CHECK(rrset_exists(db, oldver, zonename, dns_rdatatype_dnskey, - 0, &had_dnskey)); - if (!ALLOW_SECURE_TO_INSECURE(zone)) { - if (had_dnskey && !has_dnskey) { - update_log(client, zone, LOGLEVEL_PROTOCOL, - "update rejected: all DNSKEY " - "records removed and " - "'dnssec-secure-to-insecure' " - "not set"); - result = DNS_R_REFUSED; - goto failure; - } - } - - CHECK(rollback_private(db, privatetype, ver, &diff)); - - CHECK(add_signing_records(db, privatetype, ver, &diff)); - - CHECK(add_nsec3param_records(client, zone, db, ver, &diff)); - - if (had_dnskey && !has_dnskey) { - /* - * We are transitioning from secure to insecure. - * Cause all NSEC3 chains to be deleted. When the - * the last signature for the DNSKEY records are - * remove any NSEC chain present will also be removed. - */ - CHECK(dns_nsec3param_deletechains(db, ver, zone, - true, &diff)); - } else if (has_dnskey && isdnssec(db, ver, privatetype)) { - uint32_t interval; - dns_update_log_t log; - - interval = dns_zone_getsigvalidityinterval(zone); - log.func = update_log_cb; - log.arg = client; - result = dns_update_signatures(&log, zone, db, oldver, - ver, &diff, interval); - - if (result != ISC_R_SUCCESS) { - update_log(client, zone, - ISC_LOG_ERROR, - "RRSIG/NSEC/NSEC3 update failed: %s", - isc_result_totext(result)); - goto failure; - } - } - - maxrecords = dns_zone_getmaxrecords(zone); - if (maxrecords != 0U) { - result = dns_db_getsize(db, ver, &records, NULL); - if (result == ISC_R_SUCCESS && records > maxrecords) { - update_log(client, zone, ISC_LOG_ERROR, - "records in zone (%" - PRIu64 - ") exceeds max-records (%u)", - records, maxrecords); - result = DNS_R_TOOMANYRECORDS; - goto failure; - } - } - - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "writing journal %s", journalfile); - - journal = NULL; - result = dns_journal_open(mctx, journalfile, - DNS_JOURNAL_CREATE, &journal); - if (result != ISC_R_SUCCESS) - FAILS(result, "journal open failed"); - - result = dns_journal_write_transaction(journal, &diff); - if (result != ISC_R_SUCCESS) { - dns_journal_destroy(&journal); - FAILS(result, "journal write failed"); - } - - dns_journal_destroy(&journal); - } - - /* - * XXXRTH Just a note that this committing code will have - * to change to handle databases that need two-phase - * commit, but this isn't a priority. - */ - update_log(client, zone, LOGLEVEL_DEBUG, - "committing update transaction"); - - dns_db_closeversion(db, &ver, true); - - /* - * Mark the zone as dirty so that it will be written to disk. - */ - dns_zone_markdirty(zone); - - /* - * Notify slaves of the change we just made. - */ - dns_zone_notify(zone); - - /* - * Cause the zone to be signed with the key that we - * have just added or have the corresponding signatures - * deleted. - * - * Note: we are already committed to this course of action. - */ - for (tuple = ISC_LIST_HEAD(diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - isc_region_t r; - dns_secalg_t algorithm; - uint16_t keyid; - - if (tuple->rdata.type != dns_rdatatype_dnskey) - continue; - - dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); - if ((dnskey.flags & - (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) - != DNS_KEYOWNER_ZONE) - continue; - - dns_rdata_toregion(&tuple->rdata, &r); - algorithm = dnskey.algorithm; - keyid = dst_region_computeid(&r, algorithm); - - result = dns_zone_signwithkey(zone, algorithm, keyid, - (tuple->op == DNS_DIFFOP_DEL)); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "dns_zone_signwithkey failed: %s", - dns_result_totext(result)); - } - } - - /* - * Cause the zone to add/delete NSEC3 chains for the - * deferred NSEC3PARAM changes. - * - * Note: we are already committed to this course of action. - */ - for (tuple = ISC_LIST_HEAD(diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3param_t nsec3param; - - if (tuple->rdata.type != privatetype || - tuple->op != DNS_DIFFOP_ADD) - continue; - - if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, - buf, sizeof(buf))) - continue; - dns_rdata_tostruct(&rdata, &nsec3param, NULL); - if (nsec3param.flags == 0) - continue; - - result = dns_zone_addnsec3chain(zone, &nsec3param); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "dns_zone_addnsec3chain failed: %s", - dns_result_totext(result)); - } - } - } else { - update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); - dns_db_closeversion(db, &ver, true); - } - result = ISC_R_SUCCESS; - goto common; - - failure: - /* - * The reason for failure should have been logged at this point. - */ - if (ver != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "rolling back"); - dns_db_closeversion(db, &ver, false); - } - - common: - dns_diff_clear(&temp); - dns_diff_clear(&diff); - - if (oldver != NULL) - dns_db_closeversion(db, &oldver, false); - - if (db != NULL) - dns_db_detach(&db); - - if (ssutable != NULL) - dns_ssutable_detach(&ssutable); - - isc_task_detach(&task); - uev->result = result; - if (zone != NULL) - INSIST(uev->zone == zone); /* we use this later */ - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = updatedone_action; - isc_task_send(client->task, &event); - - INSIST(ver == NULL); - INSIST(event == NULL); -} - -static void -updatedone_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *) event->ev_arg; - - UNUSED(task); - - INSIST(event->ev_type == DNS_EVENT_UPDATEDONE); - INSIST(task == client->task); - - INSIST(client->nupdates > 0); - switch (uev->result) { - case ISC_R_SUCCESS: - inc_stats(uev->zone, dns_nsstatscounter_updatedone); - break; - case DNS_R_REFUSED: - inc_stats(uev->zone, dns_nsstatscounter_updaterej); - break; - default: - inc_stats(uev->zone, dns_nsstatscounter_updatefail); - break; - } - if (uev->zone != NULL) - dns_zone_detach(&uev->zone); - client->nupdates--; - respond(client, uev->result); - isc_event_free(&event); - ns_client_detach(&client); -} - -/*% - * Update forwarding support. - */ - -static void -forward_fail(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, DNS_R_SERVFAIL); - isc_event_free(&event); - ns_client_detach(&client); -} - - -static void -forward_callback(void *arg, isc_result_t result, dns_message_t *answer) { - update_event_t *uev = arg; - ns_client_t *client = uev->ev_arg; - dns_zone_t *zone = uev->zone; - - if (result != ISC_R_SUCCESS) { - INSIST(answer == NULL); - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - inc_stats(zone, dns_nsstatscounter_updatefwdfail); - } else { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_done; - uev->answer = answer; - inc_stats(zone, dns_nsstatscounter_updaterespfwd); - } - isc_task_send(client->task, ISC_EVENT_PTR(&uev)); - dns_zone_detach(&zone); -} - -static void -forward_done(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - ns_client_sendraw(client, uev->answer); - dns_message_detach(&uev->answer); - isc_event_free(&event); - ns_client_detach(&client); -} - -static void -forward_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - - result = dns_zone_forwardupdate(zone, client->message, - forward_callback, event); - if (result != ISC_R_SUCCESS) { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - isc_task_send(client->task, &event); - inc_stats(zone, dns_nsstatscounter_updatefwdfail); - dns_zone_detach(&zone); - } else - inc_stats(zone, dns_nsstatscounter_updatereqfwd); - isc_task_detach(&task); -} - -static isc_result_t -send_forward_event(ns_client_t *client, dns_zone_t *zone) { - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - /* - * This may take some time so replace this client. - */ - if (!client->mortal && (client->attributes & NS_CLIENTATTR_TCP) == 0) - CHECK(ns_client_replace(client)); - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - forward_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - LOGLEVEL_PROTOCOL, "forwarding update for zone '%s/%s'", - namebuf, classbuf); - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} diff --git a/bin/named-sdb/win32/dlz_dlopen_driver.c b/bin/named-sdb/win32/dlz_dlopen_driver.c deleted file mode 100644 index 7ba1f0c..0000000 --- a/bin/named-sdb/win32/dlz_dlopen_driver.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#ifdef ISC_DLZ_DLOPEN -static dns_sdlzimplementation_t *dlz_dlopen = NULL; - - -typedef struct dlopen_data { - isc_mem_t *mctx; - char *dl_path; - char *dlzname; - HMODULE dl_handle; - void *dbdata; - unsigned int flags; - isc_mutex_t lock; - int version; - bool in_configure; - - dlz_dlopen_version_t *dlz_version; - dlz_dlopen_create_t *dlz_create; - dlz_dlopen_findzonedb_t *dlz_findzonedb; - dlz_dlopen_lookup_t *dlz_lookup; - dlz_dlopen_authority_t *dlz_authority; - dlz_dlopen_allnodes_t *dlz_allnodes; - dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr; - dlz_dlopen_newversion_t *dlz_newversion; - dlz_dlopen_closeversion_t *dlz_closeversion; - dlz_dlopen_configure_t *dlz_configure; - dlz_dlopen_ssumatch_t *dlz_ssumatch; - dlz_dlopen_addrdataset_t *dlz_addrdataset; - dlz_dlopen_subrdataset_t *dlz_subrdataset; - dlz_dlopen_delrdataset_t *dlz_delrdataset; - dlz_dlopen_destroy_t *dlz_destroy; -} dlopen_data_t; - -/* Modules can choose whether they are lock-safe or not. */ -#define MAYBE_LOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - LOCK(&cd->lock); \ - } while (0) - -#define MAYBE_UNLOCK(cd) \ - do { \ - if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \ - cd->in_configure == false) \ - UNLOCK(&cd->lock); \ - } while (0) - -/* - * Log a message at the given level. - */ -static void dlopen_log(int level, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), - fmt, ap); - va_end(ap); -} - -/* - * SDLZ methods - */ - -static isc_result_t -dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata, - dns_sdlzallnodes_t *allnodes) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - - UNUSED(driverarg); - - if (cd->dlz_allnodes == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allnodes(zone, cd->dbdata, allnodes); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, - const char *client) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - - if (cd->dlz_allowzonexfr == NULL) { - return (ISC_R_NOPERM); - } - - MAYBE_LOCK(cd); - result = cd->dlz_allowzonexfr(cd->dbdata, name, client); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_authority == NULL) { - return (ISC_R_NOTIMPLEMENTED); - } - - MAYBE_LOCK(cd); - result = cd->dlz_authority(zone, cd->dbdata, lookup); - MAYBE_UNLOCK(cd); - return (result); -} - -static isc_result_t -dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - - -static isc_result_t -dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, - methods, clientinfo); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Load a symbol from the library - */ -static void * -dl_load_symbol(dlopen_data_t *cd, const char *symbol, bool mandatory) { - void *ptr = GetProcAddress(cd->dl_handle, symbol); - if (ptr == NULL && mandatory) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: library '%s' is missing " - "required symbol '%s'", cd->dl_path, symbol); - } - return (ptr); -} - -/* - * Called at startup for each dlopen zone in named.conf - */ -static isc_result_t -dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], - void *driverarg, void **dbdata) -{ - dlopen_data_t *cd; - isc_mem_t *mctx = NULL; - isc_result_t result = ISC_R_FAILURE; - bool triedload = false; - - UNUSED(driverarg); - - if (argc < 2) { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen driver for '%s' needs a path to " - "the shared library", dlzname); - return (ISC_R_FAILURE); - } - - isc_mem_create(0, 0, &mctx); - - cd = isc_mem_get(mctx, sizeof(*cd)); - if (cd == NULL) { - isc_mem_destroy(&mctx); - return (ISC_R_NOMEMORY); - } - memset(cd, 0, sizeof(*cd)); - - cd->mctx = mctx; - - cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]); - if (cd->dl_path == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - cd->dlzname = isc_mem_strdup(cd->mctx, dlzname); - if (cd->dlzname == NULL) { - result = ISC_R_NOMEMORY; - goto failed; - } - - triedload = true; - - /* Initialize the lock */ - result = isc_mutex_init(&cd->lock); - if (result != ISC_R_SUCCESS) - goto failed; - - /* Open the library */ - cd->dl_handle = LoadLibraryA(cd->dl_path); - if (cd->dl_handle == NULL) { - unsigned int error = GetLastError(); - - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen failed to open library '%s' - %u", - cd->dl_path, error); - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - /* Find the symbols */ - cd->dlz_version = (dlz_dlopen_version_t *) - dl_load_symbol(cd, "dlz_version", true); - cd->dlz_create = (dlz_dlopen_create_t *) - dl_load_symbol(cd, "dlz_create", true); - cd->dlz_lookup = (dlz_dlopen_lookup_t *) - dl_load_symbol(cd, "dlz_lookup", true); - cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *) - dl_load_symbol(cd, "dlz_findzonedb", true); - - if (cd->dlz_create == NULL || - cd->dlz_version == NULL || - cd->dlz_lookup == NULL || - cd->dlz_findzonedb == NULL) - { - /* We're missing a required symbol */ - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *) - dl_load_symbol(cd, "dlz_allowzonexfr", false); - cd->dlz_allnodes = (dlz_dlopen_allnodes_t *) - dl_load_symbol(cd, "dlz_allnodes", - (cd->dlz_allowzonexfr != NULL)); - cd->dlz_authority = (dlz_dlopen_authority_t *) - dl_load_symbol(cd, "dlz_authority", false); - cd->dlz_newversion = (dlz_dlopen_newversion_t *) - dl_load_symbol(cd, "dlz_newversion", false); - cd->dlz_closeversion = (dlz_dlopen_closeversion_t *) - dl_load_symbol(cd, "dlz_closeversion", - (cd->dlz_newversion != NULL)); - cd->dlz_configure = (dlz_dlopen_configure_t *) - dl_load_symbol(cd, "dlz_configure", false); - cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *) - dl_load_symbol(cd, "dlz_ssumatch", false); - cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *) - dl_load_symbol(cd, "dlz_addrdataset", false); - cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *) - dl_load_symbol(cd, "dlz_subrdataset", false); - cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *) - dl_load_symbol(cd, "dlz_delrdataset", false); - - /* Check the version of the API is the same */ - cd->version = cd->dlz_version(&cd->flags); - if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) || - cd->version > DLZ_DLOPEN_VERSION) - { - dlopen_log(ISC_LOG_ERROR, - "dlz_dlopen: %s: incorrect driver API version %d, " - "requires %d", - cd->dl_path, cd->version, DLZ_DLOPEN_VERSION); - result = ISC_R_FAILURE; - goto cleanup_lock; - } - - /* - * Call the library's create function. Note that this is an - * extended version of dlz create, with the addition of - * named function pointers for helper functions that the - * driver will need. This avoids the need for the backend to - * link the BIND9 libraries - */ - MAYBE_LOCK(cd); - result = cd->dlz_create(dlzname, argc-1, argv+1, - &cd->dbdata, - "log", dlopen_log, - "putrr", dns_sdlz_putrr, - "putnamedrr", dns_sdlz_putnamedrr, - "writeable_zone", dns_dlz_writeablezone, - NULL); - MAYBE_UNLOCK(cd); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - *dbdata = cd; - - return (ISC_R_SUCCESS); - -cleanup_lock: - DESTROYLOCK(&cd->lock); -failed: - dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname); - if (cd->dl_path) - isc_mem_free(mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(mctx, cd->dlzname); - if (triedload) - (void) isc_mutex_destroy(&cd->lock); - if (cd->dl_handle) - FreeLibrary(cd->dl_handle); - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); - return (result); -} - - -/* - * Called when bind is shutting down - */ -static void -dlopen_dlz_destroy(void *driverarg, void *dbdata) { - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_mem_t *mctx; - - UNUSED(driverarg); - - if (cd->dlz_destroy) { - MAYBE_LOCK(cd); - cd->dlz_destroy(cd->dbdata); - MAYBE_UNLOCK(cd); - } - - if (cd->dl_path) - isc_mem_free(cd->mctx, cd->dl_path); - if (cd->dlzname) - isc_mem_free(cd->mctx, cd->dlzname); - - if (cd->dl_handle) - FreeLibrary(cd->dl_handle); - - DESTROYLOCK(&cd->lock); - - mctx = cd->mctx; - isc_mem_put(mctx, cd, sizeof(*cd)); - isc_mem_destroy(&mctx); -} - -/* - * Called to start a transaction - */ -static isc_result_t -dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata, - void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_newversion(zone, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); - return (result); -} - -/* - * Called to end a transaction - */ -static void -dlopen_dlz_closeversion(const char *zone, bool commit, - void *driverarg, void *dbdata, void **versionp) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - - UNUSED(driverarg); - - if (cd->dlz_newversion == NULL) { - *versionp = NULL; - return; - } - - MAYBE_LOCK(cd); - cd->dlz_closeversion(zone, commit, cd->dbdata, versionp); - MAYBE_UNLOCK(cd); -} - -/* - * Called on startup to configure any writeable zones - */ -static isc_result_t -dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, - void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_configure == NULL) - return (ISC_R_SUCCESS); - - MAYBE_LOCK(cd); - cd->in_configure = true; - result = cd->dlz_configure(view, dlzdb, cd->dbdata); - cd->in_configure = false; - MAYBE_UNLOCK(cd); - - return (result); -} - - -/* - * Check for authority to change a name - */ -static bool -dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, - const char *type, const char *key, uint32_t keydatalen, - unsigned char *keydata, void *driverarg, void *dbdata) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - bool ret; - - UNUSED(driverarg); - - if (cd->dlz_ssumatch == NULL) - return (false); - - MAYBE_LOCK(cd); - ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen, - keydata, cd->dbdata); - MAYBE_UNLOCK(cd); - - return (ret); -} - - -/* - * Add an rdataset - */ -static isc_result_t -dlopen_dlz_addrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_addrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - * Subtract an rdataset - */ -static isc_result_t -dlopen_dlz_subrdataset(const char *name, const char *rdatastr, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_subrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - -/* - delete a rdataset - */ -static isc_result_t -dlopen_dlz_delrdataset(const char *name, const char *type, - void *driverarg, void *dbdata, void *version) -{ - dlopen_data_t *cd = (dlopen_data_t *) dbdata; - isc_result_t result; - - UNUSED(driverarg); - - if (cd->dlz_delrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - MAYBE_LOCK(cd); - result = cd->dlz_delrdataset(name, type, cd->dbdata, version); - MAYBE_UNLOCK(cd); - - return (result); -} - - -static dns_sdlzmethods_t dlz_dlopen_methods = { - dlopen_dlz_create, - dlopen_dlz_destroy, - dlopen_dlz_findzonedb, - dlopen_dlz_lookup, - dlopen_dlz_authority, - dlopen_dlz_allnodes, - dlopen_dlz_allowzonexfr, - dlopen_dlz_newversion, - dlopen_dlz_closeversion, - dlopen_dlz_configure, - dlopen_dlz_ssumatch, - dlopen_dlz_addrdataset, - dlopen_dlz_subrdataset, - dlopen_dlz_delrdataset -}; -#endif - -/* - * Register driver with BIND - */ -isc_result_t -dlz_dlopen_init(isc_mem_t *mctx) { -#ifndef ISC_DLZ_DLOPEN - UNUSED(mctx); - return (ISC_R_NOTIMPLEMENTED); -#else - isc_result_t result; - - dlopen_log(2, "Registering DLZ_dlopen driver"); - - result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL, - DNS_SDLZFLAG_RELATIVEOWNER | - DNS_SDLZFLAG_RELATIVERDATA | - DNS_SDLZFLAG_THREADSAFE, - mctx, &dlz_dlopen); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_sdlzregister() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - } - - return (result); -#endif -} - - -/* - * Unregister the driver - */ -void -dlz_dlopen_clear(void) { -#ifdef ISC_DLZ_DLOPEN - dlopen_log(2, "Unregistering DLZ_dlopen driver"); - if (dlz_dlopen != NULL) - dns_sdlzunregister(&dlz_dlopen); -#endif -} diff --git a/bin/named-sdb/win32/include/named/ntservice.h b/bin/named-sdb/win32/include/named/ntservice.h deleted file mode 100644 index 77f4ba5..0000000 --- a/bin/named-sdb/win32/include/named/ntservice.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef NTSERVICE_H -#define NTSERVICE_H - -#include - -#define BIND_DISPLAY_NAME "ISC BIND" -#define BIND_SERVICE_NAME "named" - -void -ntservice_init(); -void UpdateSCM(DWORD); -void ServiceControl(DWORD dwCtrlCode); -void -ntservice_shutdown(); -BOOL ntservice_isservice(); -#endif diff --git a/bin/named-sdb/win32/include/named/os.h b/bin/named-sdb/win32/include/named/os.h deleted file mode 100644 index e65a321..0000000 --- a/bin/named-sdb/win32/include/named/os.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -#include - -#include - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -unsigned int -ns_os_uid(void); - -void -ns_os_adjustnofile(void); - -void -ns_os_minprivs(void); - -FILE * -ns_os_openfile(const char *filename, int mode, bool switch_user); - -void -ns_os_writepidfile(const char *filename, bool first_time); - -bool -ns_os_issingleton(const char *filename); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -const char * -ns_os_uname(void); - -#endif /* NS_OS_H */ diff --git a/bin/named-sdb/win32/named.dsp.in b/bin/named-sdb/win32/named.dsp.in deleted file mode 100644 index 354b88b..0000000 --- a/bin/named-sdb/win32/named.dsp.in +++ /dev/null @@ -1,341 +0,0 @@ -# Microsoft Developer Studio Project File - Name="named" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 - -CFG=named - @PLATFORM@ Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "named.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "named.mak" CFG="named - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "named - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "named - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 @OPENSSL_INC@ @GSSAPI_INC@ @GEOIP_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"old Visual Studio\"" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console @MACHINE@ -# ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/lwres/win32/Release/liblwres.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/named.exe" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @OPENSSL_INC@ @GSSAPI_INC@ @GEOIP_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"old Visual Studio\"" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR /FD /GZ /c -# SUBTRACT CPP /X @COPTY@ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.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 /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept -# ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/lwres/win32/Debug/liblwres.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /map /debug @MACHINE@ /out:"../../../Build/Debug/named.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "named - @PLATFORM@ Release" -# Name "named - @PLATFORM@ Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\builtin.c -# End Source File -# Begin Source File - -SOURCE=..\client.c -# End Source File -# Begin Source File - -SOURCE=..\config.c -# End Source File -# Begin Source File - -SOURCE=..\control.c -# End Source File -# Begin Source File - -SOURCE=..\controlconf.c -# End Source File -# Begin Source File - -SOURCE=.\dlz_dlopen_driver.c -# End Source File -@IF GEOIP -# Begin Source File - -SOURCE=..\geoip.c -# End Source File -@END GEOIP -# Begin Source File - -SOURCE=..\interfacemgr.c -# End Source File -# Begin Source File - -SOURCE=..\listenlist.c -# End Source File -# Begin Source File - -SOURCE=..\log.c -# End Source File -# Begin Source File - -SOURCE=..\logconf.c -# End Source File -# Begin Source File - -SOURCE=..\lwaddr.c -# End Source File -# Begin Source File - -SOURCE=..\lwdclient.c -# End Source File -# Begin Source File - -SOURCE=..\lwderror.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgabn.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgnba.c -# End Source File -# Begin Source File - -SOURCE=..\lwdgrbn.c -# End Source File -# Begin Source File - -SOURCE=..\lwdnoop.c -# End Source File -# Begin Source File - -SOURCE=..\lwresd.c -# End Source File -# Begin Source File - -SOURCE=..\lwsearch.c -# End Source File -# Begin Source File - -SOURCE=..\main.c -# End Source File -# Begin Source File - -SOURCE=..\notify.c -# End Source File -# Begin Source File - -SOURCE=.\ntservice.c -# End Source File -# Begin Source File - -SOURCE=.\os.c -# End Source File -# Begin Source File - -SOURCE=..\query.c -# End Source File -# Begin Source File - -SOURCE=..\server.c -# End Source File -# Begin Source File - -SOURCE=..\sortlist.c -# End Source File -# Begin Source File - -SOURCE=..\statschannel.c -# End Source File -# Begin Source File - -SOURCE=..\tkeyconf.c -# End Source File -# Begin Source File - -SOURCE=..\tsigconf.c -# End Source File -# Begin Source File - -SOURCE=..\update.c -# End Source File -# Begin Source File - -SOURCE=..\xfrout.c -# End Source File -# Begin Source File - -SOURCE=..\zoneconf.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\include\named\client.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\config.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\globals.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\interfacemgr.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\listenlist.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\log.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\logconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwaddr.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwdclient.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwresd.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\lwsearch.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\main.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\notify.h -# End Source File -# Begin Source File - -SOURCE=.\include\named\ntservice.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\omapi.h -# End Source File -# Begin Source File - -SOURCE=.\include\named\os.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\query.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\seccomp.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\server.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\sortlist.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\statschannel.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\tkeyconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\tsigconf.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\types.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\update.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\xfrout.h -# End Source File -# Begin Source File - -SOURCE=..\include\named\zoneconf.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/bin/named-sdb/win32/named.dsw b/bin/named-sdb/win32/named.dsw deleted file mode 100644 index a1a4f34..0000000 --- a/bin/named-sdb/win32/named.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "named"=".\named.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/bin/named-sdb/win32/named.mak.in b/bin/named-sdb/win32/named.mak.in deleted file mode 100644 index 9e73888..0000000 --- a/bin/named-sdb/win32/named.mak.in +++ /dev/null @@ -1,1233 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on named.dsp -!IF "$(CFG)" == "" -CFG=named - @PLATFORM@ Debug -!MESSAGE No configuration specified. Defaulting to named - @PLATFORM@ Debug. -!ENDIF - -!IF "$(CFG)" != "named - @PLATFORM@ Release" && "$(CFG)" != "named - @PLATFORM@ Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "named.mak" CFG="named - @PLATFORM@ Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "named - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE "named - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -RSC=rc.exe -LIBXML=@LIBXML2_LIB@ - -!IF "$(CFG)" == "named - @PLATFORM@ Release" -_VC_MANIFEST_INC=0 -_VC_MANIFEST_BASENAME=__VC80 -!ELSE -_VC_MANIFEST_INC=1 -_VC_MANIFEST_BASENAME=__VC80.Debug -!ENDIF - -#################################################### -# Specifying name of temporary resource file used only in incremental builds: - -!if "$(_VC_MANIFEST_INC)" == "1" -_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res -!else -_VC_MANIFEST_AUTO_RES= -!endif - -#################################################### -# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 - -!endif - -#################################################### -# _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: - -!if "$(_VC_MANIFEST_INC)" == "1" - -#MT_SPECIAL_RETURN=1090650113 -#MT_SPECIAL_SWITCH=-notify_resource_update -MT_SPECIAL_RETURN=0 -MT_SPECIAL_SWITCH= -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ -if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ -rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ -link $** /out:$@ $(LFLAGS) - -!else - -_VC_MANIFEST_EMBED_EXE= \ -if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 - -!endif -#################################################### -# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: - -!if "$(_VC_MANIFEST_INC)" == "1" - -_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ - $(_VC_MANIFEST_BASENAME).auto.rc \ - $(_VC_MANIFEST_BASENAME).auto.manifest - -!else - -_VC_MANIFEST_CLEAN= - -!endif - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -OUTDIR=.\Release -INTDIR=.\Release - -!IF "$(RECURSE)" == "0" - -ALL : "..\..\..\Build\Release\named.exe" - -!ELSE - -ALL : "libisccfg - @PLATFORM@ Release" "libisccc - @PLATFORM@ Release" "liblwres - @PLATFORM@ Release" "libbind9 - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\named.exe" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libbind9 - @PLATFORM@ ReleaseCLEAN" "liblwres - @PLATFORM@ ReleaseCLEAN" "libisccc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\builtin.obj" - -@erase "$(INTDIR)\client.obj" - -@erase "$(INTDIR)\config.obj" - -@erase "$(INTDIR)\control.obj" - -@erase "$(INTDIR)\controlconf.obj" - -@erase "$(INTDIR)\dlz_dlopen_driver.obj" -@IF GEOIP - -@erase "$(INTDIR)\geoip.obj" -@END GEOIP - -@erase "$(INTDIR)\interfacemgr.obj" - -@erase "$(INTDIR)\listenlist.obj" - -@erase "$(INTDIR)\log.obj" - -@erase "$(INTDIR)\logconf.obj" - -@erase "$(INTDIR)\lwaddr.obj" - -@erase "$(INTDIR)\lwdclient.obj" - -@erase "$(INTDIR)\lwderror.obj" - -@erase "$(INTDIR)\lwdgabn.obj" - -@erase "$(INTDIR)\lwdgnba.obj" - -@erase "$(INTDIR)\lwdgrbn.obj" - -@erase "$(INTDIR)\lwdnoop.obj" - -@erase "$(INTDIR)\lwresd.obj" - -@erase "$(INTDIR)\lwsearch.obj" - -@erase "$(INTDIR)\main.obj" - -@erase "$(INTDIR)\notify.obj" - -@erase "$(INTDIR)\ntservice.obj" - -@erase "$(INTDIR)\os.obj" - -@erase "$(INTDIR)\query.obj" - -@erase "$(INTDIR)\server.obj" - -@erase "$(INTDIR)\sortlist.obj" - -@erase "$(INTDIR)\statschannel.obj" - -@erase "$(INTDIR)\tkeyconf.obj" - -@erase "$(INTDIR)\tsigconf.obj" - -@erase "$(INTDIR)\update.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\xfrout.obj" - -@erase "$(INTDIR)\zoneconf.obj" - -@erase "..\..\..\Build\Release\named.exe" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 @OPENSSL_INC@ @GSSAPI_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"nmake\"" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\named.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\named.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/lwres/win32/Release/liblwres.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib $(LIBXML) @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\named.pdb" @MACHINE@ /out:"../../../Build/Release/named.exe" -LINK32_OBJS= \ - "$(INTDIR)\client.obj" \ - "$(INTDIR)\config.obj" \ - "$(INTDIR)\control.obj" \ - "$(INTDIR)\controlconf.obj" \ - "$(INTDIR)\dlz_dlopen_driver.obj" \ -@IF GEOIP - "$(INTDIR)\geoip.obj" \ -@END GEOIP - "$(INTDIR)\interfacemgr.obj" \ - "$(INTDIR)\listenlist.obj" \ - "$(INTDIR)\log.obj" \ - "$(INTDIR)\logconf.obj" \ - "$(INTDIR)\lwaddr.obj" \ - "$(INTDIR)\lwdclient.obj" \ - "$(INTDIR)\lwderror.obj" \ - "$(INTDIR)\lwdgabn.obj" \ - "$(INTDIR)\lwdgnba.obj" \ - "$(INTDIR)\lwdgrbn.obj" \ - "$(INTDIR)\lwdnoop.obj" \ - "$(INTDIR)\lwresd.obj" \ - "$(INTDIR)\lwsearch.obj" \ - "$(INTDIR)\main.obj" \ - "$(INTDIR)\notify.obj" \ - "$(INTDIR)\ntservice.obj" \ - "$(INTDIR)\os.obj" \ - "$(INTDIR)\query.obj" \ - "$(INTDIR)\server.obj" \ - "$(INTDIR)\sortlist.obj" \ - "$(INTDIR)\statschannel.obj" \ - "$(INTDIR)\tkeyconf.obj" \ - "$(INTDIR)\tsigconf.obj" \ - "$(INTDIR)\update.obj" \ - "$(INTDIR)\xfrout.obj" \ - "$(INTDIR)\zoneconf.obj" \ - "$(INTDIR)\builtin.obj" \ - "..\..\..\lib\dns\win32\Release\libdns.lib" \ - "..\..\..\lib\isc\win32\Release\libisc.lib" \ - "..\..\..\lib\bind9\win32\Release\libbind9.lib" \ - "..\..\..\lib\lwres\win32\Release\liblwres.lib" \ - "..\..\..\lib\isccc\win32\Release\libisccc.lib" \ - "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" - -"..\..\..\Build\Release\named.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "..\..\..\Build\Debug\named.exe" "$(OUTDIR)\named.bsc" - -!ELSE - -ALL : "libisccfg - @PLATFORM@ Debug" "libisccc - @PLATFORM@ Debug" "liblwres - @PLATFORM@ Debug" "libbind9 - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\named.exe" "$(OUTDIR)\named.bsc" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libbind9 - @PLATFORM@ DebugCLEAN" "liblwres - @PLATFORM@ DebugCLEAN" "libisccc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\builtin.obj" - -@erase "$(INTDIR)\builtin.sbr" - -@erase "$(INTDIR)\client.obj" - -@erase "$(INTDIR)\client.sbr" - -@erase "$(INTDIR)\config.obj" - -@erase "$(INTDIR)\config.sbr" - -@erase "$(INTDIR)\control.obj" - -@erase "$(INTDIR)\control.sbr" - -@erase "$(INTDIR)\controlconf.obj" - -@erase "$(INTDIR)\controlconf.sbr" - -@erase "$(INTDIR)\dlz_dlopen_driver.obj" - -@erase "$(INTDIR)\dlz_dlopen_driver.sbr" -@IF GEOIP - -@erase "$(INTDIR)\geoip.obj" - -@erase "$(INTDIR)\geoip.sbr" -@END GEOIP - -@erase "$(INTDIR)\interfacemgr.obj" - -@erase "$(INTDIR)\interfacemgr.sbr" - -@erase "$(INTDIR)\listenlist.obj" - -@erase "$(INTDIR)\listenlist.sbr" - -@erase "$(INTDIR)\log.obj" - -@erase "$(INTDIR)\log.sbr" - -@erase "$(INTDIR)\logconf.obj" - -@erase "$(INTDIR)\logconf.sbr" - -@erase "$(INTDIR)\lwaddr.obj" - -@erase "$(INTDIR)\lwaddr.sbr" - -@erase "$(INTDIR)\lwdclient.obj" - -@erase "$(INTDIR)\lwdclient.sbr" - -@erase "$(INTDIR)\lwderror.obj" - -@erase "$(INTDIR)\lwderror.sbr" - -@erase "$(INTDIR)\lwdgabn.obj" - -@erase "$(INTDIR)\lwdgabn.sbr" - -@erase "$(INTDIR)\lwdgnba.obj" - -@erase "$(INTDIR)\lwdgnba.sbr" - -@erase "$(INTDIR)\lwdgrbn.obj" - -@erase "$(INTDIR)\lwdgrbn.sbr" - -@erase "$(INTDIR)\lwdnoop.obj" - -@erase "$(INTDIR)\lwdnoop.sbr" - -@erase "$(INTDIR)\lwresd.obj" - -@erase "$(INTDIR)\lwresd.sbr" - -@erase "$(INTDIR)\lwsearch.obj" - -@erase "$(INTDIR)\lwsearch.sbr" - -@erase "$(INTDIR)\main.obj" - -@erase "$(INTDIR)\main.sbr" - -@erase "$(INTDIR)\notify.obj" - -@erase "$(INTDIR)\notify.sbr" - -@erase "$(INTDIR)\ntservice.obj" - -@erase "$(INTDIR)\ntservice.sbr" - -@erase "$(INTDIR)\os.obj" - -@erase "$(INTDIR)\os.sbr" - -@erase "$(INTDIR)\query.obj" - -@erase "$(INTDIR)\query.sbr" - -@erase "$(INTDIR)\server.obj" - -@erase "$(INTDIR)\server.sbr" - -@erase "$(INTDIR)\sortlist.obj" - -@erase "$(INTDIR)\sortlist.sbr" - -@erase "$(INTDIR)\statschannel.obj" - -@erase "$(INTDIR)\statschannel.sbr" - -@erase "$(INTDIR)\tkeyconf.obj" - -@erase "$(INTDIR)\tkeyconf.sbr" - -@erase "$(INTDIR)\tsigconf.obj" - -@erase "$(INTDIR)\tsigconf.sbr" - -@erase "$(INTDIR)\update.obj" - -@erase "$(INTDIR)\update.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(INTDIR)\xfrout.obj" - -@erase "$(INTDIR)\xfrout.sbr" - -@erase "$(INTDIR)\zoneconf.obj" - -@erase "$(INTDIR)\zoneconf.sbr" - -@erase "$(OUTDIR)\named.bsc" - -@erase "$(OUTDIR)\named.map" - -@erase "$(OUTDIR)\named.pdb" - -@erase "..\..\..\Build\Debug\named.exe" - -@erase "..\..\..\Build\Debug\named.ilk" - -@$(_VC_MANIFEST_CLEAN) - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @OPENSSL_INC@ @GSSAPI_INC@ /I "./" /I "../../../" @LIBXML2_INC@ /I "../win32/include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isccc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" @CRYPTO@ @USE_GSSAPI@ /D "BUILDER=\"nmake\"" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\named.bsc" -BSC32_SBRS= \ - "$(INTDIR)\client.sbr" \ - "$(INTDIR)\config.sbr" \ - "$(INTDIR)\control.sbr" \ - "$(INTDIR)\controlconf.sbr" \ - "$(INTDIR)\dlz_dlopen_driver.sbr" \ -@IF GEOIP - "$(INTDIR)\geoip.sbr" \ -@END GEOIP - "$(INTDIR)\interfacemgr.sbr" \ - "$(INTDIR)\listenlist.sbr" \ - "$(INTDIR)\log.sbr" \ - "$(INTDIR)\logconf.sbr" \ - "$(INTDIR)\lwaddr.sbr" \ - "$(INTDIR)\lwdclient.sbr" \ - "$(INTDIR)\lwderror.sbr" \ - "$(INTDIR)\lwdgabn.sbr" \ - "$(INTDIR)\lwdgnba.sbr" \ - "$(INTDIR)\lwdgrbn.sbr" \ - "$(INTDIR)\lwdnoop.sbr" \ - "$(INTDIR)\lwresd.sbr" \ - "$(INTDIR)\lwsearch.sbr" \ - "$(INTDIR)\main.sbr" \ - "$(INTDIR)\notify.sbr" \ - "$(INTDIR)\ntservice.sbr" \ - "$(INTDIR)\os.sbr" \ - "$(INTDIR)\query.sbr" \ - "$(INTDIR)\server.sbr" \ - "$(INTDIR)\sortlist.sbr" \ - "$(INTDIR)\statschannel.sbr" \ - "$(INTDIR)\tkeyconf.sbr" \ - "$(INTDIR)\tsigconf.sbr" \ - "$(INTDIR)\update.sbr" \ - "$(INTDIR)\xfrout.sbr" \ - "$(INTDIR)\zoneconf.sbr" \ - "$(INTDIR)\builtin.sbr" - -"$(OUTDIR)\named.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib version.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/lwres/win32/Debug/liblwres.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib $(LIBXML) @OPENSSL_LIB@ @GSSAPI_LIB@ @GEOIP_LIB@ /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\named.pdb" /map:"$(INTDIR)\named.map" /debug @MACHINE@ /out:"../../../Build/Debug/named.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\client.obj" \ - "$(INTDIR)\config.obj" \ - "$(INTDIR)\control.obj" \ - "$(INTDIR)\controlconf.obj" \ - "$(INTDIR)\dlz_dlopen_driver.obj" \ -@IF GEOIP - "$(INTDIR)\geoip.obj" \ -@END GEOIP - "$(INTDIR)\interfacemgr.obj" \ - "$(INTDIR)\listenlist.obj" \ - "$(INTDIR)\log.obj" \ - "$(INTDIR)\logconf.obj" \ - "$(INTDIR)\lwaddr.obj" \ - "$(INTDIR)\lwdclient.obj" \ - "$(INTDIR)\lwderror.obj" \ - "$(INTDIR)\lwdgabn.obj" \ - "$(INTDIR)\lwdgnba.obj" \ - "$(INTDIR)\lwdgrbn.obj" \ - "$(INTDIR)\lwdnoop.obj" \ - "$(INTDIR)\lwresd.obj" \ - "$(INTDIR)\lwsearch.obj" \ - "$(INTDIR)\main.obj" \ - "$(INTDIR)\notify.obj" \ - "$(INTDIR)\ntservice.obj" \ - "$(INTDIR)\os.obj" \ - "$(INTDIR)\query.obj" \ - "$(INTDIR)\server.obj" \ - "$(INTDIR)\sortlist.obj" \ - "$(INTDIR)\statschannel.obj" \ - "$(INTDIR)\tkeyconf.obj" \ - "$(INTDIR)\tsigconf.obj" \ - "$(INTDIR)\update.obj" \ - "$(INTDIR)\xfrout.obj" \ - "$(INTDIR)\zoneconf.obj" \ - "$(INTDIR)\builtin.obj" \ - "..\..\..\lib\dns\win32\Debug\libdns.lib" \ - "..\..\..\lib\isc\win32\Debug\libisc.lib" \ - "..\..\..\lib\bind9\win32\Debug\libbind9.lib" \ - "..\..\..\lib\lwres\win32\Debug\liblwres.lib" \ - "..\..\..\lib\isccc\win32\Debug\libisccc.lib" \ - "..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" - -"..\..\..\Build\Debug\named.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - $(_VC_MANIFEST_EMBED_EXE) - -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("named.dep") -!INCLUDE "named.dep" -!ELSE -!MESSAGE Warning: cannot find "named.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "named - @PLATFORM@ Release" || "$(CFG)" == "named - @PLATFORM@ Debug" -SOURCE=..\builtin.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\builtin.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\builtin.obj" "$(INTDIR)\builtin.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\client.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\client.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\client.obj" "$(INTDIR)\client.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\config.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\config.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\config.obj" "$(INTDIR)\config.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\control.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\control.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\control.obj" "$(INTDIR)\control.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\controlconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\controlconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\controlconf.obj" "$(INTDIR)\controlconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=.\dlz_dlopen_driver.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\dlz_dlopen_driver.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\dlz_dlopen_driver.obj" "$(INTDIR)\dlz_dlopen_driver.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -@IF GEOIP -SOURCE=..\geoip.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\geoip.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\geoip.obj" "$(INTDIR)\geoip.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF -@END GEOIP - -SOURCE=..\interfacemgr.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\interfacemgr.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\interfacemgr.obj" "$(INTDIR)\interfacemgr.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\listenlist.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\listenlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\listenlist.obj" "$(INTDIR)\listenlist.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\log.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\log.obj" "$(INTDIR)\log.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\logconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\logconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\logconf.obj" "$(INTDIR)\logconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwaddr.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwaddr.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwaddr.obj" "$(INTDIR)\lwaddr.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdclient.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdclient.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdclient.obj" "$(INTDIR)\lwdclient.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwderror.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwderror.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwderror.obj" "$(INTDIR)\lwderror.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgabn.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgabn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgabn.obj" "$(INTDIR)\lwdgabn.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgnba.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgnba.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgnba.obj" "$(INTDIR)\lwdgnba.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdgrbn.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdgrbn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdgrbn.obj" "$(INTDIR)\lwdgrbn.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwdnoop.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwdnoop.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwdnoop.obj" "$(INTDIR)\lwdnoop.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwresd.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwresd.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwresd.obj" "$(INTDIR)\lwresd.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\lwsearch.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\lwsearch.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\lwsearch.obj" "$(INTDIR)\lwsearch.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\main.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\notify.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\notify.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\notify.obj" "$(INTDIR)\notify.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=.\ntservice.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\ntservice.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\ntservice.obj" "$(INTDIR)\ntservice.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -SOURCE=.\os.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\os.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\os.obj" "$(INTDIR)\os.sbr" : $(SOURCE) "$(INTDIR)" - - -!ENDIF - -SOURCE=..\query.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\query.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\query.obj" "$(INTDIR)\query.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\server.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\server.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\server.obj" "$(INTDIR)\server.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\sortlist.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\sortlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\sortlist.obj" "$(INTDIR)\sortlist.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\statschannel.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\statschannel.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\statschannel.obj" "$(INTDIR)\statschannel.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\tkeyconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\tkeyconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\tkeyconf.obj" "$(INTDIR)\tkeyconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\tsigconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\tsigconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\tsigconf.obj" "$(INTDIR)\tsigconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\update.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\update.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\update.obj" "$(INTDIR)\update.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\xfrout.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\xfrout.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\xfrout.obj" "$(INTDIR)\xfrout.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -SOURCE=..\zoneconf.c - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - - -"$(INTDIR)\zoneconf.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - - -"$(INTDIR)\zoneconf.obj" "$(INTDIR)\zoneconf.sbr" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libdns - @PLATFORM@ Release" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libdns - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libdns - @PLATFORM@ Debug" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libdns - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\dns\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisc - @PLATFORM@ Release" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisc - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisc - @PLATFORM@ Debug" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisc - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libbind9 - @PLATFORM@ Release" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libbind9 - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libbind9 - @PLATFORM@ Debug" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libbind9 - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\bind9\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"liblwres - @PLATFORM@ Release" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"liblwres - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"liblwres - @PLATFORM@ Debug" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"liblwres - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\lwres\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisccc - @PLATFORM@ Release" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisccc - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisccc - @PLATFORM@ Debug" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisccc - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isccc\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - -!IF "$(CFG)" == "named - @PLATFORM@ Release" - -"libisccfg - @PLATFORM@ Release" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" - cd "..\..\..\bin\named\win32" - -"libisccfg - @PLATFORM@ ReleaseCLEAN" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ELSEIF "$(CFG)" == "named - @PLATFORM@ Debug" - -"libisccfg - @PLATFORM@ Debug" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" - cd "..\..\..\bin\named\win32" - -"libisccfg - @PLATFORM@ DebugCLEAN" : - cd "..\..\..\lib\isccfg\win32" - $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN - cd "..\..\..\bin\named\win32" - -!ENDIF - - -!ENDIF - -#################################################### -# Commands to generate initial empty manifest file and the RC file -# that references it, and for generating the .res file: - -$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc - -$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest - type <<$@ -#include -1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" -<< KEEP - -$(_VC_MANIFEST_BASENAME).auto.manifest : - type <<$@ - - - -<< KEEP diff --git a/bin/named-sdb/win32/named.vcxproj.filters.in b/bin/named-sdb/win32/named.vcxproj.filters.in deleted file mode 100644 index 8a5173e..0000000 --- a/bin/named-sdb/win32/named.vcxproj.filters.in +++ /dev/null @@ -1,221 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - -@IF GEOIP - - Source Files - -@END GEOIP -@IF GEOIPLEGACY - - Source Files - -@END GEOIPLEGACY - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - -@IF GEOIP - - Header Files - -@END GEOIP -@IF GEOIPLEGACY - - Header Files - -@END GEOIPLEGACY - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/bin/named-sdb/win32/named.vcxproj.in b/bin/named-sdb/win32/named.vcxproj.in deleted file mode 100644 index 0487405..0000000 --- a/bin/named-sdb/win32/named.vcxproj.in +++ /dev/null @@ -1,190 +0,0 @@ - - - - - Debug - @PLATFORM@ - - - Release - @PLATFORM@ - - - - {723C65DA-A96C-4BA3-A34E-44F11CA346F9} - Win32Proj - named - @WINDOWS_TARGET_PLATFORM_VERSION@ - - - - Application - true - MultiByte - @PLATFORM_TOOLSET@ - - - Application - false - true - MultiByte - @PLATFORM_TOOLSET@ - - - - - - - - - - - - - true - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - - - false - ..\..\..\Build\$(Configuration)\ - .\$(Configuration)\ - None - - - - - - Level4 - false - Disabled - WIN32;@CRYPTO@@USE_GSSAPI@BUILDER="Visual Studio";_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - true - @OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) - @LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;liblwres.lib;libisccfg.lib;libbind9.lib;version.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level1 - true - - - MaxSpeed - true - @INTRINSIC@ - WIN32;@CRYPTO@@USE_GSSAPI@BUILDER="Visual Studio";NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - OnlyExplicitInline - false - true - .\$(Configuration)\$(TargetName).pch - .\$(Configuration)\ - .\$(Configuration)\ - $(OutDir)$(TargetName).pdb - @OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) - CompileAsC - - - Console - false - true - true - ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) - Default - ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) - @LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;liblwres.lib;libisccfg.lib;libbind9.lib;version.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - - - - -@IF GEOIP - -@END GEOIP -@IF GEOIPLEGACY - -@END GEOIPLEGACY - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@IF GEOIP - -@END GEOIP -@IF GEOIPLEGACY - -@END GEOIPLEGACY - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/named-sdb/win32/named.vcxproj.user b/bin/named-sdb/win32/named.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/bin/named-sdb/win32/named.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/bin/named-sdb/win32/ntservice.c b/bin/named-sdb/win32/ntservice.c deleted file mode 100644 index 77cafe3..0000000 --- a/bin/named-sdb/win32/ntservice.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Handle to SCM for updating service status */ -static SERVICE_STATUS_HANDLE hServiceStatus = 0; -static BOOL foreground = FALSE; -static char ConsoleTitle[128]; - -/* - * Forward declarations - */ -void ServiceControl(DWORD dwCtrlCode); -int bindmain(int, char *[]); /* From main.c */ - -/* - * Initialize the Service by registering it. - */ -void -ntservice_init(void) { - if (!foreground) { - /* Register handler with the SCM */ - hServiceStatus = RegisterServiceCtrlHandler(BIND_SERVICE_NAME, - (LPHANDLER_FUNCTION)ServiceControl); - if (!hServiceStatus) { - ns_main_earlyfatal( - "could not register service control handler"); - } - UpdateSCM(SERVICE_RUNNING); - } else { - strlcpy(ConsoleTitle, "BIND Version ", sizeof(ConsoleTitle)); - strlcat(ConsoleTitle, VERSION, sizeof(ConsoleTitle)); - SetConsoleTitle(ConsoleTitle); - } -} - -void -ntservice_shutdown(void) { - UpdateSCM(SERVICE_STOPPED); -} -/* - * Routine to check if this is a service or a foreground program - */ -BOOL -ntservice_isservice(void) { - return(!foreground); -} -/* - * ServiceControl(): Handles requests from the SCM and passes them on - * to named. - */ -void -ServiceControl(DWORD dwCtrlCode) { - /* Handle the requested control code */ - switch(dwCtrlCode) { - case SERVICE_CONTROL_INTERROGATE: - UpdateSCM(0); - break; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - ns_server_flushonshutdown(ns_g_server, true); - isc_app_shutdown(); - UpdateSCM(SERVICE_STOP_PENDING); - break; - default: - break; - } -} - -/* - * Tell the Service Control Manager the state of the service. - */ -void UpdateSCM(DWORD state) { - SERVICE_STATUS ss; - static DWORD dwState = SERVICE_STOPPED; - - if (hServiceStatus) { - if (state) - dwState = state; - - memset(&ss, 0, sizeof(SERVICE_STATUS)); - ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS; - ss.dwCurrentState = dwState; - ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SHUTDOWN; - ss.dwCheckPoint = 0; - ss.dwServiceSpecificExitCode = 0; - ss.dwWin32ExitCode = NO_ERROR; - ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 10000 : 1000; - - if (!SetServiceStatus(hServiceStatus, &ss)) { - ss.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(hServiceStatus, &ss); - } - } -} - -/* unhook main */ - -#undef main - -/* - * This is the entry point for the executable - * We can now call bindmain() explicitly or via StartServiceCtrlDispatcher() - * as we need to. - */ -int main(int argc, char *argv[]) -{ - int rc, ch; - - /* Command line users should put -f in the options. */ - isc_commandline_errprint = false; - while ((ch = isc_commandline_parse(argc, argv, NS_MAIN_ARGS)) != -1) { - switch (ch) { - case 'f': - case 'g': - case 'v': - case 'V': - foreground = TRUE; - break; - default: - break; - } - } - isc_commandline_reset = true; - - if (foreground) { - /* run in console window */ - exit(bindmain(argc, argv)); - } else { - /* Start up as service */ - char *SERVICE_NAME = BIND_SERVICE_NAME; - - SERVICE_TABLE_ENTRY dispatchTable[] = { - { TEXT(SERVICE_NAME), - (LPSERVICE_MAIN_FUNCTION)bindmain }, - { NULL, NULL } - }; - - rc = StartServiceCtrlDispatcher(dispatchTable); - if (!rc) { - fprintf(stderr, - "Use -f to run from the command line.\n"); - /* will be 1063 when launched as a console app */ - exit(GetLastError()); - } - } - exit(0); -} diff --git a/bin/named-sdb/win32/os.c b/bin/named-sdb/win32/os.c deleted file mode 100644 index 300e115..0000000 --- a/bin/named-sdb/win32/os.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -static char *lockfile = NULL; -static char *pidfile = NULL; -static int devnullfd = -1; -static int lockfilefd = -1; - -static BOOL Initialized = FALSE; - -static char *version_error = - "named requires Windows 2000 Service Pack 2 or later to run correctly"; - -void -ns_paths_init(void) { - if (!Initialized) - isc_ntpaths_init(); - - lwresd_g_conffile = isc_ntpaths_get(LWRES_CONF_PATH); - lwresd_g_resolvconffile = isc_ntpaths_get(RESOLV_CONF_PATH); - ns_g_conffile = isc_ntpaths_get(NAMED_CONF_PATH); - ns_g_defaultpidfile = isc_ntpaths_get(NAMED_PID_PATH); - lwresd_g_defaultpidfile = isc_ntpaths_get(LWRESD_PID_PATH); - ns_g_defaultlockfile = isc_ntpaths_get(NAMED_LOCK_PATH); - ns_g_keyfile = isc_ntpaths_get(RNDC_KEY_PATH); - ns_g_defaultsessionkeyfile = isc_ntpaths_get(SESSION_KEY_PATH); - - Initialized = TRUE; -} - -/* - * Due to Knowledge base article Q263823 we need to make sure that - * Windows 2000 systems have Service Pack 2 or later installed and - * warn when it isn't. - */ -static void -version_check(const char *progname) { - - if ((isc_win32os_versioncheck(4, 0, 0, 0) >= 0) && - (isc_win32os_versioncheck(5, 0, 0, 0) < 0)) - return; /* No problem with Version 4.0 */ - if (isc_win32os_versioncheck(5, 0, 2, 0) < 0) - if (ntservice_isservice()) - NTReportError(progname, version_error); - else - fprintf(stderr, "%s\n", version_error); -} - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - - openlog(progname, options, LOG_DAEMON); -} - -void -ns_os_init(const char *progname) { - ns_paths_init(); - setup_syslog(progname); - /* - * XXXMPA. We may need to split ntservice_init() in two and - * just mark as running in ns_os_started(). If we do that - * this is where the first part of ntservice_init() should be - * called from. - * - * XXX970 Remove comment if no problems by 9.7.0. - * - * ntservice_init(); - */ - version_check(progname); - /* - * If running in a Cygwin environment, clear the SEM_NOGPFAULTERRORBOX - * bit in the process error mode to prevent Cygwin from concealing - * non-abort() crashes, giving Windows Error Reporting a chance to - * handle such crashes. This is done to ensure all crashes triggered - * by system tests can be detected. - */ - if (getenv("CYGWIN") != NULL) { - SetErrorMode(SetErrorMode(0) & ~SEM_NOGPFAULTERRORBOX); - } -} - -void -ns_os_daemonize(void) { - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - */ - if (devnullfd != -1) { - if (devnullfd != _fileno(stdin)) { - close(_fileno(stdin)); - (void)_dup2(devnullfd, _fileno(stdin)); - } - if (devnullfd != _fileno(stdout)) { - close(_fileno(stdout)); - (void)_dup2(devnullfd, _fileno(stdout)); - } - if (devnullfd != _fileno(stderr)) { - close(_fileno(stderr)); - (void)_dup2(devnullfd, _fileno(stderr)); - } - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("NUL", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != _fileno(stdin) && - devnullfd != _fileno(stdout) && - devnullfd != _fileno(stderr)) { - close(devnullfd); - devnullfd = -1; - } -} - -void -ns_os_chroot(const char *root) { - if (root != NULL) - ns_main_earlyfatal("chroot(): isn't supported by Win32 API"); -} - -void -ns_os_inituserinfo(const char *username) { -} - -void -ns_os_changeuser(void) { -} - -unsigned int -ns_os_uid(void) { - return (0); -} - -void -ns_os_adjustnofile(void) { -} - -void -ns_os_minprivs(void) { -} - -static int -safe_open(const char *filename, int mode, bool append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) - return (-1); - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode); - else { - (void)unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - if (pidfile != NULL) { - (void)unlink(pidfile); - free(pidfile); - } - pidfile = NULL; -} - -static void -cleanup_lockfile(void) { - if (lockfilefd != -1) { - close(lockfilefd); - lockfilefd = -1; - } - - if (lockfile != NULL) { - int n = unlink(lockfile); - if (n == -1 && errno != ENOENT) - ns_main_earlywarning("unlink '%s': failed", lockfile); - free(lockfile); - lockfile = NULL; - } -} - -FILE * -ns_os_openfile(const char *filename, int mode, bool switch_user) { - char strbuf[ISC_STRERRORSIZE]; - FILE *fp; - int fd; - - UNUSED(switch_user); - fd = safe_open(filename, mode, false); - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not open file '%s': %s", - filename, strbuf); - return (NULL); - } - - fp = fdopen(fd, "w"); - if (fp == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlywarning("could not fdopen() file '%s': %s", - filename, strbuf); - close(fd); - } - - return (fp); -} - -void -ns_os_writepidfile(const char *filename, bool first_time) { - FILE *pidlockfile; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - pidfile = strdup(filename); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't strdup() '%s': %s", filename, strbuf); - return; - } - - pidlockfile = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, - false); - if (pidlockfile == NULL) { - free(pidfile); - pidfile = NULL; - return; - } - - pid = getpid(); - - if (fprintf(pidlockfile, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(pidlockfile); - cleanup_pidfile(); - return; - } - if (fflush(pidlockfile) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(pidlockfile); - cleanup_pidfile(); - return; - } - (void)fclose(pidlockfile); -} - -bool -ns_os_issingleton(const char *filename) { - char strbuf[ISC_STRERRORSIZE]; - OVERLAPPED o; - - if (lockfilefd != -1) - return (true); - - if (strcasecmp(filename, "none") == 0) - return (true); - - lockfile = strdup(filename); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("couldn't allocate memory for '%s': %s", - filename, strbuf); - } - - /* - * ns_os_openfile() uses safeopen() which removes any existing - * files. We can't use that here. - */ - lockfilefd = open(filename, O_WRONLY | O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (lockfilefd == -1) { - cleanup_lockfile(); - return (false); - } - - memset(&o, 0, sizeof(o)); - /* Expect ERROR_LOCK_VIOLATION if already locked */ - if (!LockFileEx((HANDLE) _get_osfhandle(lockfilefd), - LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, - 0, 0, 1, &o)) { - cleanup_lockfile(); - return (false); - } - - return (true); -} - - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); - - if (lockfilefd != -1) { - (void) UnlockFile((HANDLE) _get_osfhandle(lockfilefd), - 0, 0, 0, 1); - } - cleanup_lockfile(); - - ntservice_shutdown(); /* This MUST be the last thing done */ -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, (int)len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - UNUSED(command); - UNUSED(text); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} - -void -ns_os_started(void) { - ntservice_init(); -} - -static char unamebuf[BUFSIZ]; -static const char *unamep = NULL; - -static void -getuname(void) { - DWORD fvilen; - char *fvi; - VS_FIXEDFILEINFO *ffi; - UINT ffilen; - SYSTEM_INFO sysinfo; - char *arch; - - fvi = NULL; - fvilen = GetFileVersionInfoSize("kernel32.dll", 0); - if (fvilen == 0) { - goto err; - } - fvi = (char *)malloc(fvilen); - if (fvi == NULL) { - goto err; - } - memset(fvi, 0, fvilen); - if (GetFileVersionInfo("kernel32.dll", 0, fvilen, fvi) == 0) { - goto err; - } - ffi = NULL; - ffilen = 0; - if ((VerQueryValue(fvi, "\\", &ffi, &ffilen) == 0) || - (ffi == NULL) || (ffilen == 0)) { - goto err; - } - memset(&sysinfo, 0, sizeof(sysinfo)); - GetSystemInfo(&sysinfo); - switch (sysinfo.wProcessorArchitecture) { - case PROCESSOR_ARCHITECTURE_INTEL: - arch = "x86"; - break; - case PROCESSOR_ARCHITECTURE_ARM: - arch = "arm"; - break; - case PROCESSOR_ARCHITECTURE_IA64: - arch = "ia64"; - break; - case PROCESSOR_ARCHITECTURE_AMD64: - arch = "x64"; - break; - default: - arch = "unknown architecture"; - break; - } - - snprintf(unamebuf, sizeof(unamebuf), - "Windows %d %d build %d %d for %s\n", - (ffi->dwProductVersionMS >> 16) & 0xffff, - ffi->dwProductVersionMS & 0xffff, - (ffi->dwProductVersionLS >> 16) & 0xffff, - ffi->dwProductVersionLS & 0xffff, - arch); - - err: - if (fvi != NULL) { - free(fvi); - } - unamep = unamebuf; -} - -/* - * GetVersionEx() returns 6.2 (aka Windows 8.1) since it was obsoleted - * so we had to switch to the recommended way to get the Windows version. - */ -const char * -ns_os_uname(void) { - if (unamep == NULL) { - getuname(); - } - return (unamep); -} diff --git a/bin/named-sdb/xfrout.c b/bin/named-sdb/xfrout.c deleted file mode 100644 index 7149825..0000000 --- a/bin/named-sdb/xfrout.c +++ /dev/null @@ -1,1745 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/*! \file - * \brief - * Outgoing AXFR and IXFR. - */ - -/* - * TODO: - * - IXFR over UDP - */ - -#define XFROUT_COMMON_LOGARGS \ - ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT - -#define XFROUT_PROTOCOL_LOGARGS \ - XFROUT_COMMON_LOGARGS, ISC_LOG_INFO - -#define XFROUT_DEBUG_LOGARGS(n) \ - XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) - -#define XFROUT_RR_LOGARGS \ - XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL - -#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - result = (code); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: %s (%s)", \ - msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILQ(code, msg, question, rdclass) \ - do { \ - char _buf1[DNS_NAME_FORMATSIZE]; \ - char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ - result = (code); \ - dns_name_format(question, _buf1, sizeof(_buf1)); \ - dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: '%s/%s': %s (%s)", \ - _buf1, _buf2, msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ - -static inline void -inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { - isc_stats_increment(ns_g_server->nsstats, counter); - if (zone != NULL) { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); - } -} - -/**************************************************************************/ - -/*% Log an RR (for debugging) */ - -static void -log_rr(dns_name_t *name, dns_rdata_t *rdata, uint32_t ttl) { - isc_result_t result; - isc_buffer_t buf; - char mem[2000]; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdata_t rd = DNS_RDATA_INIT; - - dns_rdatalist_init(&rdl); - rdl.type = rdata->type; - rdl.rdclass = rdata->rdclass; - rdl.ttl = ttl; - if (rdata->type == dns_rdatatype_sig || - rdata->type == dns_rdatatype_rrsig) - rdl.covers = dns_rdata_covers(rdata); - else - rdl.covers = dns_rdatatype_none; - dns_rdataset_init(&rds); - dns_rdata_init(&rd); - dns_rdata_clone(rdata, &rd); - ISC_LIST_APPEND(rdl.rdata, &rd, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); - - isc_buffer_init(&buf, mem, sizeof(mem)); - result = dns_rdataset_totext(&rds, name, - false, false, &buf); - - /* - * We could use xfrout_log(), but that would produce - * very long lines with a repetitive prefix. - */ - if (result == ISC_R_SUCCESS) { - /* - * Get rid of final newline. - */ - INSIST(buf.used >= 1 && - ((char *) buf.base)[buf.used - 1] == '\n'); - buf.used--; - - isc_log_write(XFROUT_RR_LOGARGS, "%.*s", - (int)isc_buffer_usedlength(&buf), - (char *)isc_buffer_base(&buf)); - } else { - isc_log_write(XFROUT_RR_LOGARGS, ""); - } -} - -/**************************************************************************/ -/* - * An 'rrstream_t' is a polymorphic iterator that returns - * a stream of resource records. There are multiple implementations, - * e.g. for generating AXFR and IXFR records streams. - */ - -typedef struct rrstream_methods rrstream_methods_t; - -typedef struct rrstream { - isc_mem_t *mctx; - rrstream_methods_t *methods; -} rrstream_t; - -struct rrstream_methods { - isc_result_t (*first)(rrstream_t *); - isc_result_t (*next)(rrstream_t *); - void (*current)(rrstream_t *, - dns_name_t **, - uint32_t *, - dns_rdata_t **); - void (*pause)(rrstream_t *); - void (*destroy)(rrstream_t **); -}; - -static void -rrstream_noop_pause(rrstream_t *rs) { - UNUSED(rs); -} - -/**************************************************************************/ -/* - * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns - * an IXFR-like RR stream from a journal file. - * - * The SOA at the beginning of each sequence of additions - * or deletions are included in the stream, but the extra - * SOAs at the beginning and end of the entire transfer are - * not included. - */ - -typedef struct ixfr_rrstream { - rrstream_t common; - dns_journal_t *journal; -} ixfr_rrstream_t; - -/* Forward declarations. */ -static void -ixfr_rrstream_destroy(rrstream_t **sp); - -static rrstream_methods_t ixfr_rrstream_methods; - -/* - * Returns: anything dns_journal_open() or dns_journal_iter_init() - * may return. - */ - -static isc_result_t -ixfr_rrstream_create(isc_mem_t *mctx, - const char *journal_filename, - uint32_t begin_serial, - uint32_t end_serial, - rrstream_t **sp) -{ - ixfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &ixfr_rrstream_methods; - s->journal = NULL; - - CHECK(dns_journal_open(mctx, journal_filename, - DNS_JOURNAL_READ, &s->journal)); - CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - ixfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -ixfr_rrstream_first(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_first_rr(s->journal)); -} - -static isc_result_t -ixfr_rrstream_next(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_next_rr(s->journal)); -} - -static void -ixfr_rrstream_current(rrstream_t *rs, - dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - dns_journal_current_rr(s->journal, name, ttl, rdata); -} - -static void -ixfr_rrstream_destroy(rrstream_t **rsp) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; - if (s->journal != 0) - dns_journal_destroy(&s->journal); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t ixfr_rrstream_methods = { - ixfr_rrstream_first, - ixfr_rrstream_next, - ixfr_rrstream_current, - rrstream_noop_pause, - ixfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'axfr_rrstream_t' is an 'rrstream_t' that returns - * an AXFR-like RR stream from a database. - * - * The SOAs at the beginning and end of the transfer are - * not included in the stream. - */ - -typedef struct axfr_rrstream { - rrstream_t common; - dns_rriterator_t it; - bool it_valid; -} axfr_rrstream_t; - -/* - * Forward declarations. - */ -static void -axfr_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t axfr_rrstream_methods; - -static isc_result_t -axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - axfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &axfr_rrstream_methods; - s->it_valid = false; - - CHECK(dns_rriterator_init(&s->it, db, ver, 0)); - s->it_valid = true; - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - axfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -axfr_rrstream_first(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - result = dns_rriterator_first(&s->it); - if (result != ISC_R_SUCCESS) - return (result); - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - dns_rriterator_current(&s->it, &name_dummy, - &ttl_dummy, NULL, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - result = dns_rriterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -axfr_rrstream_next(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - result = dns_rriterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - dns_rriterator_current(&s->it, &name_dummy, - &ttl_dummy, NULL, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - } - return (result); -} - -static void -axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - dns_rriterator_current(&s->it, name, ttl, NULL, rdata); -} - -static void -axfr_rrstream_pause(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - dns_rriterator_pause(&s->it); -} - -static void -axfr_rrstream_destroy(rrstream_t **rsp) { - axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; - if (s->it_valid) - dns_rriterator_destroy(&s->it); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t axfr_rrstream_methods = { - axfr_rrstream_first, - axfr_rrstream_next, - axfr_rrstream_current, - axfr_rrstream_pause, - axfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns - * a single SOA record. - */ - -typedef struct soa_rrstream { - rrstream_t common; - dns_difftuple_t *soa_tuple; -} soa_rrstream_t; - -/* - * Forward declarations. - */ -static void -soa_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t soa_rrstream_methods; - -static isc_result_t -soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - soa_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &soa_rrstream_methods; - s->soa_tuple = NULL; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - &s->soa_tuple)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - soa_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -soa_rrstream_first(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_SUCCESS); -} - -static isc_result_t -soa_rrstream_next(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_NOMORE); -} - -static void -soa_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - soa_rrstream_t *s = (soa_rrstream_t *) rs; - *name = &s->soa_tuple->name; - *ttl = s->soa_tuple->ttl; - *rdata = &s->soa_tuple->rdata; -} - -static void -soa_rrstream_destroy(rrstream_t **rsp) { - soa_rrstream_t *s = (soa_rrstream_t *) *rsp; - if (s->soa_tuple != NULL) - dns_difftuple_free(&s->soa_tuple); - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t soa_rrstream_methods = { - soa_rrstream_first, - soa_rrstream_next, - soa_rrstream_current, - rrstream_noop_pause, - soa_rrstream_destroy -}; - -/**************************************************************************/ -/* - * A 'compound_rrstream_t' objects owns a soa_rrstream - * and another rrstream, the "data stream". It returns - * a concatenated stream consisting of the soa_rrstream, then - * the data stream, then the soa_rrstream again. - * - * The component streams are owned by the compound_rrstream_t - * and are destroyed with it. - */ - -typedef struct compound_rrstream { - rrstream_t common; - rrstream_t *components[3]; - int state; - isc_result_t result; -} compound_rrstream_t; - -/* - * Forward declarations. - */ -static void -compound_rrstream_destroy(rrstream_t **rsp); - -static isc_result_t -compound_rrstream_next(rrstream_t *rs); - -static rrstream_methods_t compound_rrstream_methods; - -/* - * Requires: - * soa_stream != NULL && *soa_stream != NULL - * data_stream != NULL && *data_stream != NULL - * sp != NULL && *sp == NULL - * - * Ensures: - * *soa_stream == NULL - * *data_stream == NULL - * *sp points to a valid compound_rrstream_t - * The soa and data streams will be destroyed - * when the compound_rrstream_t is destroyed. - */ -static isc_result_t -compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, - rrstream_t **data_stream, rrstream_t **sp) -{ - compound_rrstream_t *s; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = NULL; - isc_mem_attach(mctx, &s->common.mctx); - s->common.methods = &compound_rrstream_methods; - s->components[0] = *soa_stream; - s->components[1] = *data_stream; - s->components[2] = *soa_stream; - s->state = -1; - s->result = ISC_R_FAILURE; - - *soa_stream = NULL; - *data_stream = NULL; - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); -} - -static isc_result_t -compound_rrstream_first(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - s->state = 0; - do { - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } while (s->result == ISC_R_NOMORE && s->state < 2); - return (s->result); -} - -static isc_result_t -compound_rrstream_next(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->next(curstream); - while (s->result == ISC_R_NOMORE) { - /* - * Make sure locks held by the current stream - * are released before we switch streams. - */ - curstream->methods->pause(curstream); - if (s->state == 2) - return (ISC_R_NOMORE); - s->state++; - curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } - return (s->result); -} - -static void -compound_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - INSIST(s->result == ISC_R_SUCCESS); - curstream = s->components[s->state]; - curstream->methods->current(curstream, name, ttl, rdata); -} - -static void -compound_rrstream_pause(rrstream_t *rs) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - curstream = s->components[s->state]; - curstream->methods->pause(curstream); -} - -static void -compound_rrstream_destroy(rrstream_t **rsp) { - compound_rrstream_t *s = (compound_rrstream_t *) *rsp; - s->components[0]->methods->destroy(&s->components[0]); - s->components[1]->methods->destroy(&s->components[1]); - s->components[2] = NULL; /* Copy of components[0]. */ - isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t compound_rrstream_methods = { - compound_rrstream_first, - compound_rrstream_next, - compound_rrstream_current, - compound_rrstream_pause, - compound_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR - * in progress. - */ - -typedef struct { - isc_mem_t *mctx; - ns_client_t *client; - unsigned int id; /* ID of request */ - dns_name_t *qname; /* Question name of request */ - dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ - dns_rdataclass_t qclass; - dns_zone_t *zone; /* (necessary for stats) */ - dns_db_t *db; - dns_dbversion_t *ver; - isc_quota_t *quota; - rrstream_t *stream; /* The XFR RR stream */ - bool end_of_stream; /* EOS has been reached */ - isc_buffer_t buf; /* Buffer for message owner - names and rdatas */ - isc_buffer_t txlenbuf; /* Transmit length buffer */ - isc_buffer_t txbuf; /* Transmit message buffer */ - void *txmem; - unsigned int txmemlen; - unsigned int nmsg; /* Number of messages sent */ - dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ - isc_buffer_t *lasttsig; /* the last TSIG */ - bool verified_tsig; /* verified request MAC */ - bool many_answers; - int sends; /* Send in progress */ - bool shuttingdown; - const char *mnemonic; /* Style of transfer */ -} xfrout_ctx_t; - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, - unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, - bool verified_tsig, - unsigned int maxtime, - unsigned int idletime, - bool many_answers, - xfrout_ctx_t **xfrp); - -static void -sendstream(xfrout_ctx_t *xfr); - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event); - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr); - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp); - -static void -xfrout_client_shutdown(void *arg, isc_result_t result); - -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -/**************************************************************************/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { - isc_result_t result; - dns_name_t *question_name; - dns_rdataset_t *question_rdataset; - dns_zone_t *zone = NULL, *raw = NULL, *mayberaw; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rdataclass_t question_class; - rrstream_t *soa_stream = NULL; - rrstream_t *data_stream = NULL; - rrstream_t *stream = NULL; - dns_difftuple_t *current_soa_tuple = NULL; - dns_name_t *soa_name; - dns_rdataset_t *soa_rdataset; - dns_rdata_t soa_rdata = DNS_RDATA_INIT; - bool have_soa = false; - const char *mnemonic = NULL; - isc_mem_t *mctx = client->mctx; - dns_message_t *request = client->message; - xfrout_ctx_t *xfr = NULL; - isc_quota_t *quota = NULL; - dns_transfer_format_t format = client->view->transfer_format; - isc_netaddr_t na; - dns_peer_t *peer = NULL; - isc_buffer_t *tsigbuf = NULL; - char *journalfile; - char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; - char keyname[DNS_NAME_FORMATSIZE]; - bool is_poll = false; - bool is_dlz = false; - bool is_ixfr = false; - uint32_t begin_serial = 0, current_serial; - - switch (reqtype) { - case dns_rdatatype_axfr: - mnemonic = "AXFR"; - break; - case dns_rdatatype_ixfr: - mnemonic = "IXFR"; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - ns_client_log(client, - DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(6), "%s request", mnemonic); - /* - * Apply quota. - */ - result = isc_quota_attach(&ns_g_server->xfroutquota, "a); - if (result != ISC_R_SUCCESS) { - isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, - "%s request denied: %s", mnemonic, - isc_result_totext(result)); - goto failure; - } - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - - /* - * The question section must contain exactly one question, and - * it must be for AXFR/IXFR as appropriate. - */ - question_name = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); - question_rdataset = ISC_LIST_HEAD(question_name->list); - question_class = question_rdataset->rdclass; - INSIST(question_rdataset->type == reqtype); - if (ISC_LIST_NEXT(question_rdataset, link) != NULL) { - FAILC(DNS_R_FORMERR, "multiple questions"); - } - result = dns_message_nextname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) { - FAILC(DNS_R_FORMERR, "multiple questions"); - } - - result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, - &zone); - - if (result != ISC_R_SUCCESS || dns_zone_gettype(zone) == dns_zone_dlz) { - /* - * The normal zone table does not have a match, or this is - * marked in the zone table as a DLZ zone. Check the DLZ - * databases for a match. - */ - if (! ISC_LIST_EMPTY(client->view->dlz_searched)) { - result = dns_dlzallowzonexfr(client->view, - question_name, - &client->peeraddr, - &db); - - if (result == ISC_R_NOPERM) { - char _buf1[DNS_NAME_FORMATSIZE]; - char _buf2[DNS_RDATACLASS_FORMATSIZE]; - - result = DNS_R_REFUSED; - dns_name_format(question_name, _buf1, - sizeof(_buf1)); - dns_rdataclass_format(question_class, - _buf2, sizeof(_buf2)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_ERROR, - "zone transfer '%s/%s' denied", - _buf1, _buf2); - goto failure; - } - if (result != ISC_R_SUCCESS) - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - is_dlz = true; - } else { - /* - * not DLZ and not in normal zone table, we are - * not authoritative - */ - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - } else { - /* zone table has a match */ - switch(dns_zone_gettype(zone)) { - /* Master and slave zones are OK for transfer. */ - case dns_zone_master: - case dns_zone_slave: - case dns_zone_dlz: - break; - default: - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - CHECK(dns_zone_getdb(zone, &db)); - dns_db_currentversion(db, &ver); - } - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s question section OK", mnemonic); - - /* - * Check the authority section. Look for a SOA record with - * the same name and class as the question. - */ - for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) - { - soa_name = NULL; - dns_message_currentname(request, DNS_SECTION_AUTHORITY, - &soa_name); - - /* - * Ignore data whose owner name is not the zone apex. - */ - if (! dns_name_equal(soa_name, question_name)) { - continue; - } - - for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); - soa_rdataset != NULL; - soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) - { - /* - * Ignore non-SOA data. - */ - if (soa_rdataset->type != dns_rdatatype_soa) { - continue; - } - if (soa_rdataset->rdclass != question_class) { - continue; - } - - CHECK(dns_rdataset_first(soa_rdataset)); - dns_rdataset_current(soa_rdataset, &soa_rdata); - result = dns_rdataset_next(soa_rdataset); - if (result == ISC_R_SUCCESS) { - FAILC(DNS_R_FORMERR, - "IXFR authority section " - "has multiple SOAs"); - } - have_soa = true; - goto got_soa; - } - } - got_soa: - if (result != ISC_R_NOMORE) { - CHECK(result); - } - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s authority section OK", mnemonic); - - /* - * If not a DLZ zone, decide whether to allow this transfer. - */ - if (!is_dlz) { - ns_client_aclmsg("zone transfer", question_name, reqtype, - client->view->rdclass, msg, sizeof(msg)); - CHECK(ns_client_checkacl(client, NULL, msg, - dns_zone_getxfracl(zone), - true, ISC_LOG_ERROR)); - } - - /* - * AXFR over UDP is not possible. - */ - if (reqtype == dns_rdatatype_axfr && - (client->attributes & NS_CLIENTATTR_TCP) == 0) { - FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); - } - - /* - * Look up the requesting server in the peer table. - */ - isc_netaddr_fromsockaddr(&na, &client->peeraddr); - (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); - - /* - * Decide on the transfer format (one-answer or many-answers). - */ - if (peer != NULL) { - (void)dns_peer_gettransferformat(peer, &format); - } - - /* - * Get a dynamically allocated copy of the current SOA. - */ - if (is_dlz) - dns_db_currentversion(db, &ver); - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - ¤t_soa_tuple)); - - current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); - if (reqtype == dns_rdatatype_ixfr) { - if (!have_soa) { - FAILC(DNS_R_FORMERR, "IXFR request missing SOA"); - } - - begin_serial = dns_soa_getserial(&soa_rdata); - - /* - * RFC1995 says "If an IXFR query with the same or - * newer version number than that of the server - * is received, it is replied to with a single SOA - * record of the server's current version, just as - * in AXFR". The claim about AXFR is incorrect, - * but other than that, we do as the RFC says. - * - * Sending a single SOA record is also how we refuse - * IXFR over UDP (currently, we always do). - */ - if (DNS_SERIAL_GE(begin_serial, current_serial) || - (client->attributes & NS_CLIENTATTR_TCP) == 0) - { - CHECK(soa_rrstream_create(mctx, db, ver, &stream)); - is_poll = true; - goto have_stream; - } - - /* - * Outgoing IXFR may have been disabled for this peer - * or globally. - */ - if ((client->attributes & NS_CLIENTATTR_TCP) != 0) { - bool provide_ixfr; - - provide_ixfr = client->view->provideixfr; - if (peer != NULL) { - (void)dns_peer_getprovideixfr(peer, - &provide_ixfr); - } - if (!provide_ixfr) { - xfrout_log1(client, question_name, - question_class, ISC_LOG_DEBUG(4), - "IXFR delta response disabled due " - "to 'provide-ixfr no;' being set"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - } - - journalfile = is_dlz ? NULL : dns_zone_getjournal(zone); - if (journalfile != NULL) { - result = ixfr_rrstream_create(mctx, - journalfile, - begin_serial, - current_serial, - &data_stream); - } else { - result = ISC_R_NOTFOUND; - } - if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(4), - "IXFR version not in journal, " - "falling back to AXFR"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - CHECK(result); - is_ixfr = true; - } else { - axfr_fallback: - CHECK(axfr_rrstream_create(mctx, db, ver, &data_stream)); - } - - /* - * Bracket the data stream with SOAs. - */ - CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); - CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, - &stream)); - soa_stream = NULL; - 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. - */ - - - - if (is_dlz) { - CHECK(xfrout_ctx_create(mctx, client, request->id, - question_name, reqtype, question_class, - zone, db, ver, quota, stream, - dns_message_gettsigkey(request), - tsigbuf, - request->verified_sig, - 3600, - 3600, - (format == dns_many_answers) ? - true : false, - &xfr)); - } else { - CHECK(xfrout_ctx_create(mctx, client, request->id, - question_name, reqtype, question_class, - zone, db, ver, quota, stream, - dns_message_gettsigkey(request), - tsigbuf, - request->verified_sig, - dns_zone_getmaxxfrout(zone), - dns_zone_getidleout(zone), - (format == dns_many_answers) ? - true : false, - &xfr)); - } - - xfr->mnemonic = mnemonic; - stream = NULL; - quota = NULL; - - CHECK(xfr->stream->methods->first(xfr->stream)); - - if (xfr->tsigkey != NULL) { - dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); - } else { - keyname[0] = '\0'; - } - if (is_poll) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - } else if (is_ixfr) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s (serial %u -> %u)", - mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", - keyname, begin_serial, current_serial); - } else { - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s (serial %u)", - mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", - keyname, current_serial); - } - - - if (zone != NULL) { - dns_zone_getraw(zone, &raw); - mayberaw = (raw != NULL) ? raw : zone; - if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 && - dns_zone_gettype(mayberaw) == dns_zone_slave) { - isc_time_t expiretime; - uint32_t secs; - dns_zone_getexpiretime(zone, &expiretime); - secs = isc_time_seconds(&expiretime); - if (secs >= client->now && result == ISC_R_SUCCESS) { - client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; - client->expire = secs - client->now; - } - } - if (raw != NULL) { - dns_zone_detach(&raw); - } - } - - /* - * Hand the context over to sendstream(). Set xfr to NULL; - * sendstream() is responsible for either passing the - * context on to a later event handler or destroying it. - */ - sendstream(xfr); - xfr = NULL; - - result = ISC_R_SUCCESS; - - failure: - if (result == DNS_R_REFUSED) { - inc_stats(zone, dns_nsstatscounter_xfrrej); - } - if (quota != NULL) { - isc_quota_detach("a); - } - if (current_soa_tuple != NULL) { - dns_difftuple_free(¤t_soa_tuple); - } - if (stream != NULL) { - stream->methods->destroy(&stream); - } - if (soa_stream != NULL) { - soa_stream->methods->destroy(&soa_stream); - } - if (data_stream != NULL) { - data_stream->methods->destroy(&data_stream); - } - if (ver != NULL) { - dns_db_closeversion(db, &ver, false); - } - if (db != NULL) { - dns_db_detach(&db); - } - if (zone != NULL) { - dns_zone_detach(&zone); - } - /* XXX kludge */ - if (xfr != NULL) { - xfrout_fail(xfr, result, "setting up zone transfer"); - } else if (result != ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(3), "zone transfer setup failed"); - ns_client_error(client, result); - } -} - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, - dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, bool verified_tsig, - unsigned int maxtime, unsigned int idletime, - bool many_answers, xfrout_ctx_t **xfrp) -{ - xfrout_ctx_t *xfr; - isc_result_t result; - unsigned int len; - void *mem; - - INSIST(xfrp != NULL && *xfrp == NULL); - xfr = isc_mem_get(mctx, sizeof(*xfr)); - if (xfr == NULL) - return (ISC_R_NOMEMORY); - xfr->mctx = NULL; - isc_mem_attach(mctx, &xfr->mctx); - xfr->client = NULL; - ns_client_attach(client, &xfr->client); - xfr->id = id; - xfr->qname = qname; - xfr->qtype = qtype; - xfr->qclass = qclass; - xfr->zone = NULL; - xfr->db = NULL; - xfr->ver = NULL; - if (zone != NULL) /* zone will be NULL if it's DLZ */ - dns_zone_attach(zone, &xfr->zone); - dns_db_attach(db, &xfr->db); - dns_db_attachversion(db, ver, &xfr->ver); - xfr->end_of_stream = false; - xfr->tsigkey = tsigkey; - xfr->lasttsig = lasttsig; - xfr->verified_tsig = verified_tsig; - xfr->nmsg = 0; - xfr->many_answers = many_answers; - xfr->sends = 0; - xfr->shuttingdown = false; - xfr->mnemonic = NULL; - xfr->buf.base = NULL; - xfr->buf.length = 0; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->stream = NULL; - xfr->quota = NULL; - - /* - * Allocate a temporary buffer for the uncompressed response - * message data. The size should be no more than 65535 bytes - * so that the compressed data will fit in a TCP message, - * and no less than 65535 bytes so that an almost maximum-sized - * RR will fit. Note that although 65535-byte RRs are allowed - * in principle, they cannot be zone-transferred (at least not - * if uncompressible), because the message and RR headers would - * push the size of the TCP message over the 65536 byte limit. - */ - len = 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->buf, mem, len); - - /* - * Allocate another temporary buffer for the compressed - * response message and its TCP length prefix. - */ - len = 2 + 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->txlenbuf, mem, 2); - isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); - xfr->txmem = mem; - xfr->txmemlen = len; - - CHECK(dns_timer_setidle(xfr->client->timer, - maxtime, idletime, false)); - - /* - * Register a shutdown callback with the client, so that we - * can stop the transfer immediately when the client task - * gets a shutdown event. - */ - xfr->client->shutdown = xfrout_client_shutdown; - xfr->client->shutdown_arg = xfr; - /* - * These MUST be after the last "goto failure;" / CHECK to - * prevent a double free by the caller. - */ - xfr->quota = quota; - xfr->stream = stream; - - *xfrp = xfr; - return (ISC_R_SUCCESS); - -failure: - xfrout_ctx_destroy(&xfr); - return (result); -} - - -/* - * Arrange to send as much as we can of "stream" without blocking. - * - * Requires: - * The stream iterator is initialized and points at an RR, - * or possibly at the end of the stream (that is, the - * _first method of the iterator has been called). - */ -static void -sendstream(xfrout_ctx_t *xfr) { - dns_message_t *tcpmsg = NULL; - dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ - isc_result_t result; - isc_region_t used; - isc_region_t region; - dns_rdataset_t *qrdataset; - dns_name_t *msgname = NULL; - dns_rdata_t *msgrdata = NULL; - dns_rdatalist_t *msgrdl = NULL; - dns_rdataset_t *msgrds = NULL; - dns_compress_t cctx; - bool cleanup_cctx = false; - bool is_tcp; - - int n_rrs; - - isc_buffer_clear(&xfr->buf); - isc_buffer_clear(&xfr->txlenbuf); - isc_buffer_clear(&xfr->txbuf); - - is_tcp = ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0); - if (!is_tcp) { - /* - * In the UDP case, we put the response data directly into - * the client message. - */ - msg = xfr->client->message; - CHECK(dns_message_reply(msg, true)); - } else { - /* - * TCP. Build a response dns_message_t, temporarily storing - * the raw, uncompressed owner names and RR data contiguously - * in xfr->buf. We know that if the uncompressed data fits - * in xfr->buf, the compressed data will surely fit in a TCP - * message. - */ - - CHECK(dns_message_create(xfr->mctx, - DNS_MESSAGE_INTENTRENDER, &tcpmsg)); - msg = tcpmsg; - - msg->id = xfr->id; - msg->rcode = dns_rcode_noerror; - msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; - if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) - msg->flags |= DNS_MESSAGEFLAG_RA; - CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); - CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - msg->verified_sig = xfr->verified_tsig; - - /* - * Add a EDNS option to the message? - */ - if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { - dns_rdataset_t *opt = NULL; - - CHECK(ns_client_addopt(xfr->client, msg, &opt)); - CHECK(dns_message_setopt(msg, opt)); - /* - * Add to first message only. - */ - xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID; - xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE; - } - - /* - * Account for reserved space. - */ - if (xfr->tsigkey != NULL) - INSIST(msg->reserved != 0U); - isc_buffer_add(&xfr->buf, msg->reserved); - - /* - * Include a question section in the first message only. - * BIND 8.2.1 will not recognize an IXFR if it does not - * have a question section. - */ - if (xfr->nmsg == 0) { - dns_name_t *qname = NULL; - isc_region_t r; - - /* - * Reserve space for the 12-byte message header - * and 4 bytes of question. - */ - isc_buffer_add(&xfr->buf, 12 + 4); - - qrdataset = NULL; - result = dns_message_gettemprdataset(msg, &qrdataset); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_makequestion(qrdataset, - xfr->client->message->rdclass, - xfr->qtype); - - result = dns_message_gettempname(msg, &qname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(qname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= xfr->qname->length); - r.length = xfr->qname->length; - isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, - xfr->qname->length); - dns_name_fromregion(qname, &r); - ISC_LIST_INIT(qname->list); - ISC_LIST_APPEND(qname->list, qrdataset, link); - - dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - } else { - /* - * Reserve space for the 12-byte message header - */ - isc_buffer_add(&xfr->buf, 12); - msg->tcp_continuation = 1; - } - } - - /* - * Try to fit in as many RRs as possible, unless "one-answer" - * format has been requested. - */ - for (n_rrs = 0; ; n_rrs++) { - dns_name_t *name = NULL; - uint32_t ttl; - dns_rdata_t *rdata = NULL; - - unsigned int size; - isc_region_t r; - - msgname = NULL; - msgrdata = NULL; - msgrdl = NULL; - msgrds = NULL; - - xfr->stream->methods->current(xfr->stream, - &name, &ttl, &rdata); - size = name->length + 10 + rdata->length; - isc_buffer_availableregion(&xfr->buf, &r); - if (size >= r.length) { - /* - * RR would not fit. If there are other RRs in the - * buffer, send them now and leave this RR to the - * next message. If this RR overflows the buffer - * all by itself, fail. - * - * In theory some RRs might fit in a TCP message - * when compressed even if they do not fit when - * uncompressed, but surely we don't want - * to send such monstrosities to an unsuspecting - * slave. - */ - if (n_rrs == 0) { - xfrout_log(xfr, ISC_LOG_WARNING, - "RR too large for zone transfer " - "(%d bytes)", size); - /* XXX DNS_R_RRTOOLARGE? */ - result = ISC_R_NOSPACE; - goto failure; - } - break; - } - - if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) - log_rr(name, rdata, ttl); /* XXX */ - - result = dns_message_gettempname(msg, &msgname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(msgname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= name->length); - r.length = name->length; - isc_buffer_putmem(&xfr->buf, name->ndata, name->length); - dns_name_fromregion(msgname, &r); - - /* Reserve space for RR header. */ - isc_buffer_add(&xfr->buf, 10); - - result = dns_message_gettemprdata(msg, &msgrdata); - if (result != ISC_R_SUCCESS) - goto failure; - isc_buffer_availableregion(&xfr->buf, &r); - r.length = rdata->length; - isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); - dns_rdata_init(msgrdata); - dns_rdata_fromregion(msgrdata, - rdata->rdclass, rdata->type, &r); - - result = dns_message_gettemprdatalist(msg, &msgrdl); - if (result != ISC_R_SUCCESS) - goto failure; - msgrdl->type = rdata->type; - msgrdl->rdclass = rdata->rdclass; - msgrdl->ttl = ttl; - if (rdata->type == dns_rdatatype_sig || - rdata->type == dns_rdatatype_rrsig) - msgrdl->covers = dns_rdata_covers(rdata); - else - msgrdl->covers = dns_rdatatype_none; - ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); - - result = dns_message_gettemprdataset(msg, &msgrds); - if (result != ISC_R_SUCCESS) - goto failure; - result = dns_rdatalist_tordataset(msgrdl, msgrds); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_APPEND(msgname->list, msgrds, link); - - dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); - msgname = NULL; - - result = xfr->stream->methods->next(xfr->stream); - if (result == ISC_R_NOMORE) { - xfr->end_of_stream = true; - break; - } - CHECK(result); - - if (! xfr->many_answers) - break; - /* - * At this stage, at least 1 RR has been rendered into - * the message. Check if we want to clamp this message - * here (TCP only). - */ - if ((isc_buffer_usedlength(&xfr->buf) >= - ns_g_server->transfer_tcp_message_size) && is_tcp) - break; - } - - if (is_tcp) { - CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); - dns_compress_setsensitive(&cctx, true); - cleanup_cctx = true; - CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); - CHECK(dns_message_renderend(msg)); - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - - isc_buffer_usedregion(&xfr->txbuf, &used); - isc_buffer_putuint16(&xfr->txlenbuf, - (uint16_t)used.length); - region.base = xfr->txlenbuf.base; - region.length = 2 + used.length; - xfrout_log(xfr, ISC_LOG_DEBUG(8), - "sending TCP message of %d bytes", - used.length); - CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ - ®ion, xfr->client->task, - xfrout_senddone, - xfr)); - xfr->sends++; - } else { - xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); - ns_client_send(xfr->client); - xfr->stream->methods->pause(xfr->stream); - xfrout_ctx_destroy(&xfr); - return; - } - - /* Advance lasttsig to be the last TSIG generated */ - CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); - - xfr->nmsg++; - - failure: - if (msgname != NULL) { - if (msgrds != NULL) { - if (dns_rdataset_isassociated(msgrds)) - dns_rdataset_disassociate(msgrds); - dns_message_puttemprdataset(msg, &msgrds); - } - if (msgrdl != NULL) { - ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); - dns_message_puttemprdatalist(msg, &msgrdl); - } - if (msgrdata != NULL) - dns_message_puttemprdata(msg, &msgrdata); - dns_message_puttempname(msg, &msgname); - } - - if (tcpmsg != NULL) - dns_message_detach(&tcpmsg); - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - /* - * Make sure to release any locks held by database - * iterators before returning from the event handler. - */ - xfr->stream->methods->pause(xfr->stream); - - if (result == ISC_R_SUCCESS) - return; - - xfrout_fail(xfr, result, "sending zone data"); -} - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { - xfrout_ctx_t *xfr = *xfrp; - ns_client_t *client = NULL; - - INSIST(xfr->sends == 0); - - xfr->client->shutdown = NULL; - xfr->client->shutdown_arg = NULL; - - if (xfr->stream != NULL) - xfr->stream->methods->destroy(&xfr->stream); - if (xfr->buf.base != NULL) - 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) - isc_buffer_free(&xfr->lasttsig); - if (xfr->quota != NULL) - isc_quota_detach(&xfr->quota); - if (xfr->ver != NULL) - dns_db_closeversion(xfr->db, &xfr->ver, false); - if (xfr->zone != NULL) - dns_zone_detach(&xfr->zone); - if (xfr->db != NULL) - dns_db_detach(&xfr->db); - - /* - * We want to detch the client after we have released the memory - * context as ns_client_detach checks the memory reference count. - */ - ns_client_attach(xfr->client, &client); - ns_client_detach(&xfr->client); - isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); - ns_client_detach(&client); - - *xfrp = NULL; -} - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sev = (isc_socketevent_t *)event; - xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; - isc_result_t evresult = sev->result; - - UNUSED(task); - - INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - isc_event_free(&event); - xfr->sends--; - INSIST(xfr->sends == 0); - - (void)isc_timer_touch(xfr->client->timer); - if (xfr->shuttingdown == true) { - xfrout_maybe_destroy(xfr); - } else if (evresult != ISC_R_SUCCESS) { - xfrout_fail(xfr, evresult, "send"); - } else if (xfr->end_of_stream == false) { - sendstream(xfr); - } else { - /* End of zone transfer stream. */ - inc_stats(xfr->zone, dns_nsstatscounter_xfrdone); - xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); - ns_client_next(xfr->client, ISC_R_SUCCESS); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { - xfr->shuttingdown = true; - xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", - msg, isc_result_totext(result)); - xfrout_maybe_destroy(xfr); -} - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr) { - INSIST(xfr->shuttingdown == true); - if (xfr->sends > 0) { - /* - * If we are currently sending, cancel it and wait for - * cancel event before destroying the context. - */ - isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, - ISC_SOCKCANCEL_SEND); - } else { - ns_client_next(xfr->client, ISC_R_CANCELED); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_client_shutdown(void *arg, isc_result_t result) { - xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; - xfrout_fail(xfr, result, "aborted"); -} - -/* - * Log outgoing zone transfer messages in a format like - * : transfer of : - */ - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) - ISC_FORMAT_PRINTF(5, 0); - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, level, - "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); -} - -/* - * Logging function for use when a xfrout_ctx_t has not yet been created. - */ -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(client, zonename, rdclass, level, fmt, ap); - va_end(ap); -} - -/* - * Logging function for use when there is a xfrout_ctx_t. - */ -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); - va_end(ap); -} diff --git a/bin/named-sdb/zoneconf.c b/bin/named-sdb/zoneconf.c deleted file mode 100644 index fa6dbf9..0000000 --- a/bin/named-sdb/zoneconf.c +++ /dev/null @@ -1,1851 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* ACLs associated with zone */ -typedef enum { - allow_notify, - allow_query, - allow_query_on, - allow_transfer, - allow_update, - allow_update_forwarding -} acl_type_t; - -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -/*% - * Convenience function for configuring a single zone ACL. - */ -static isc_result_t -configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, - const cfg_obj_t *config, acl_type_t acltype, - cfg_aclconfctx_t *actx, dns_zone_t *zone, - void (*setzacl)(dns_zone_t *, dns_acl_t *), - void (*clearzacl)(dns_zone_t *)) -{ - isc_result_t result; - const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL}; - const cfg_obj_t *aclobj = NULL; - int i = 0; - dns_acl_t **aclp = NULL, *acl = NULL; - const char *aclname; - dns_view_t *view; - - view = dns_zone_getview(zone); - - switch (acltype) { - case allow_notify: - if (view != NULL) - aclp = &view->notifyacl; - aclname = "allow-notify"; - break; - case allow_query: - if (view != NULL) - aclp = &view->queryacl; - aclname = "allow-query"; - break; - case allow_query_on: - if (view != NULL) - aclp = &view->queryonacl; - aclname = "allow-query-on"; - break; - case allow_transfer: - if (view != NULL) - aclp = &view->transferacl; - aclname = "allow-transfer"; - break; - case allow_update: - if (view != NULL) - aclp = &view->updateacl; - aclname = "allow-update"; - break; - case allow_update_forwarding: - if (view != NULL) - aclp = &view->upfwdacl; - aclname = "allow-update-forwarding"; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - /* First check to see if ACL is defined within the zone */ - if (zconfig != NULL) { - maps[0] = cfg_tuple_get(zconfig, "options"); - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj != NULL) { - aclp = NULL; - goto parse_acl; - } - } - - /* Failing that, see if there's a default ACL already in the view */ - if (aclp != NULL && *aclp != NULL) { - (*setzacl)(zone, *aclp); - return (ISC_R_SUCCESS); - } - - /* Check for default ACLs that haven't been parsed yet */ - if (vconfig != NULL) { - const cfg_obj_t *options = cfg_tuple_get(vconfig, "options"); - if (options != NULL) - maps[i++] = options; - } - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - (*clearzacl)(zone); - return (ISC_R_SUCCESS); - } - -parse_acl: - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, - dns_zone_getmctx(zone), 0, &acl); - if (result != ISC_R_SUCCESS) - return (result); - (*setzacl)(zone, acl); - - /* Set the view default now */ - if (aclp != NULL) - dns_acl_attach(acl, aclp); - - dns_acl_detach(&acl); - return (ISC_R_SUCCESS); -} - -/*% - * Parse the zone update-policy statement. - */ -static isc_result_t -configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, - const char *zname) -{ - const cfg_obj_t *updatepolicy = NULL; - const cfg_listelt_t *element, *element2; - dns_ssutable_t *table = NULL; - isc_mem_t *mctx = dns_zone_getmctx(zone); - bool autoddns = false; - isc_result_t result; - - (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); - - if (updatepolicy == NULL) { - dns_zone_setssutable(zone, NULL); - return (ISC_R_SUCCESS); - } - - if (cfg_obj_isstring(updatepolicy) && - strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) { - autoddns = true; - updatepolicy = NULL; - } - - result = dns_ssutable_create(mctx, &table); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(updatepolicy); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *stmt = cfg_listelt_value(element); - const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); - const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); - const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); - const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); - const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); - const char *str; - bool grant = false; - bool usezone = false; - dns_ssumatchtype_t mtype = DNS_SSUMATCHTYPE_NAME; - dns_fixedname_t fname, fident; - isc_buffer_t b; - dns_rdatatype_t *types; - unsigned int i, n; - - str = cfg_obj_asstring(mode); - if (strcasecmp(str, "grant") == 0) { - grant = true; - } else if (strcasecmp(str, "deny") == 0) { - grant = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - str = cfg_obj_asstring(matchtype); - CHECK(dns_ssu_mtypefromstring(str, &mtype)); - if (mtype == dns_ssumatchtype_subdomain && - strcasecmp(str, "zonesub") == 0) { - usezone = true; - } - - dns_fixedname_init(&fident); - str = cfg_obj_asstring(identity); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fident), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - dns_fixedname_init(&fname); - if (usezone) { - result = dns_name_copy(dns_zone_getorigin(zone), - dns_fixedname_name(&fname), - NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "error copying origin: %s", - isc_result_totext(result)); - goto cleanup; - } - } else { - str = cfg_obj_asstring(dname); - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fname), - &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - } - - n = ns_config_listcount(typelist); - if (n == 0) - types = NULL; - else { - types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); - if (types == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - i = 0; - for (element2 = cfg_list_first(typelist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - const cfg_obj_t *typeobj; - isc_textregion_t r; - - INSIST(i < n); - - typeobj = cfg_listelt_value(element2); - str = cfg_obj_asstring(typeobj); - DE_CONST(str, r.base); - r.length = strlen(str); - - result = dns_rdatatype_fromtext(&types[i++], &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid type", str); - isc_mem_put(mctx, types, - n * sizeof(dns_rdatatype_t)); - goto cleanup; - } - } - INSIST(i == n); - - result = dns_ssutable_addrule(table, grant, - dns_fixedname_name(&fident), - mtype, - dns_fixedname_name(&fname), - n, types); - if (types != NULL) - isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - - /* - * If "update-policy local;" and a session key exists, - * then use the default policy, which is equivalent to: - * update-policy { grant zonesub any; }; - */ - if (autoddns) { - dns_rdatatype_t any = dns_rdatatype_any; - - if (ns_g_server->session_keyname == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "failed to enable auto DDNS policy " - "for zone %s: session key not found", - zname); - result = ISC_R_NOTFOUND; - goto cleanup; - } - - result = dns_ssutable_addrule(table, true, - ns_g_server->session_keyname, - DNS_SSUMATCHTYPE_LOCAL, - dns_zone_getorigin(zone), - 1, &any); - - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - result = ISC_R_SUCCESS; - dns_zone_setssutable(zone, table); - - cleanup: - dns_ssutable_detach(&table); - return (result); -} - -/* - * This is the TTL used for internally generated RRsets for static-stub zones. - * The value doesn't matter because the mapping is static, but needs to be - * defined for the sake of implementation. - */ -#define STATICSTUB_SERVER_TTL 86400 - -/*% - * Configure an apex NS with glues for a static-stub zone. - * For example, for the zone named "example.com", the following RRs will be - * added to the zone DB: - * example.com. NS example.com. - * example.com. A 192.0.2.1 - * example.com. AAAA 2001:db8::1 - */ -static isc_result_t -configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone, - dns_rdatalist_t *rdatalist_ns, - dns_rdatalist_t *rdatalist_a, - dns_rdatalist_t *rdatalist_aaaa) -{ - const cfg_listelt_t *element; - isc_mem_t *mctx = dns_zone_getmctx(zone); - isc_region_t region, sregion; - dns_rdata_t *rdata; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(zconfig); - element != NULL; - element = cfg_list_next(element)) - { - const isc_sockaddr_t* sa; - isc_netaddr_t na; - const cfg_obj_t *address = cfg_listelt_value(element); - dns_rdatalist_t *rdatalist; - - sa = cfg_obj_assockaddr(address); - if (isc_sockaddr_getport(sa) != 0) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "port is not configurable for " - "static stub server-addresses"); - return (ISC_R_FAILURE); - } - isc_netaddr_fromsockaddr(&na, sa); - if (isc_netaddr_getzone(&na) != 0) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "scoped address is not allowed " - "for static stub " - "server-addresses"); - return (ISC_R_FAILURE); - } - - switch (na.family) { - case AF_INET: - region.length = sizeof(na.type.in); - rdatalist = rdatalist_a; - break; - default: - INSIST(na.family == AF_INET6); - region.length = sizeof(na.type.in6); - rdatalist = rdatalist_aaaa; - break; - } - - rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, &na.type, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - rdatalist->type, ®ion); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - } - - /* - * If no address is specified (unlikely in this context, but possible), - * there's nothing to do anymore. - */ - if (ISC_LIST_EMPTY(rdatalist_a->rdata) && - ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) { - return (ISC_R_SUCCESS); - } - - /* Add to the list an apex NS with the ns name being the origin name */ - dns_name_toregion(dns_zone_getorigin(zone), &sregion); - rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); - if (rdata == NULL) { - /* - * Already allocated data will be freed in the caller, so - * we can simply return here. - */ - return (ISC_R_NOMEMORY); - } - region.length = sregion.length; - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, sregion.base, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - dns_rdatatype_ns, ®ion); - ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link); - - return (result); -} - -/*% - * Configure an apex NS with an out-of-zone NS names for a static-stub zone. - * For example, for the zone named "example.com", something like the following - * RRs will be added to the zone DB: - * example.com. NS ns.example.net. - */ -static isc_result_t -configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone, - dns_rdatalist_t *rdatalist, const char *zname) -{ - const cfg_listelt_t *element; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_rdata_t *rdata; - isc_region_t sregion, region; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(zconfig); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed_name; - dns_name_t *nsname; - isc_buffer_t b; - - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - - nsname = dns_fixedname_initname(&fixed_name); - - isc_buffer_constinit(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "server-name '%s' is not a valid " - "name", str); - return (result); - } - if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "server-name '%s' must not be a " - "subdomain of zone name '%s'", - str, zname); - return (ISC_R_FAILURE); - } - - dns_name_toregion(nsname, &sregion); - rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - region.length = sregion.length; - region.base = (unsigned char *)(rdata + 1); - memmove(region.base, sregion.base, region.length); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, dns_zone_getclass(zone), - dns_rdatatype_ns, ®ion); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - } - - return (result); -} - -/*% - * Configure static-stub zone. - */ -static isc_result_t -configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone, - const char *zname, const char *dbtype) -{ - int i = 0; - const cfg_obj_t *obj; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_db_t *db = NULL; - dns_dbversion_t *dbversion = NULL; - dns_dbnode_t *apexnode = NULL; - dns_name_t apexname; - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa; - dns_rdatalist_t* rdatalists[] = { - &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL - }; - dns_rdata_t *rdata; - isc_region_t region; - - /* Create the DB beforehand */ - RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone), - dns_dbtype_stub, dns_zone_getclass(zone), - 0, NULL, &db)); - - dns_rdataset_init(&rdataset); - - dns_rdatalist_init(&rdatalist_ns); - rdatalist_ns.rdclass = dns_zone_getclass(zone); - rdatalist_ns.type = dns_rdatatype_ns; - rdatalist_ns.ttl = STATICSTUB_SERVER_TTL; - - dns_rdatalist_init(&rdatalist_a); - rdatalist_a.rdclass = dns_zone_getclass(zone); - rdatalist_a.type = dns_rdatatype_a; - rdatalist_a.ttl = STATICSTUB_SERVER_TTL; - - dns_rdatalist_init(&rdatalist_aaaa); - rdatalist_aaaa.rdclass = dns_zone_getclass(zone); - rdatalist_aaaa.type = dns_rdatatype_aaaa; - rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL; - - /* Prepare zone RRs from the configuration */ - obj = NULL; - result = cfg_map_get(zconfig, "server-addresses", &obj); - if (result == ISC_R_SUCCESS) { - INSIST(obj != NULL); - CHECK(configure_staticstub_serveraddrs(obj, zone, - &rdatalist_ns, - &rdatalist_a, - &rdatalist_aaaa)); - } - - obj = NULL; - result = cfg_map_get(zconfig, "server-names", &obj); - if (result == ISC_R_SUCCESS) { - INSIST(obj != NULL); - CHECK(configure_staticstub_servernames(obj, zone, - &rdatalist_ns, - zname)); - } - - /* - * Sanity check: there should be at least one NS RR at the zone apex - * to trigger delegation. - */ - if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "No NS record is configured for a " - "static-stub zone '%s'", zname); - result = ISC_R_FAILURE; - goto cleanup; - } - - /* - * Now add NS and glue A/AAAA RRsets to the zone DB. - * First open a new version for the add operation and get a pointer - * to the apex node (all RRs are of the apex name). - */ - CHECK(dns_db_newversion(db, &dbversion)); - - dns_name_init(&apexname, NULL); - dns_name_clone(dns_zone_getorigin(zone), &apexname); - CHECK(dns_db_findnode(db, &apexname, false, &apexnode)); - - /* Add NS RRset */ - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, - 0, NULL)); - dns_rdataset_disassociate(&rdataset); - - /* Add glue A RRset, if any */ - if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) { - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, - &rdataset, 0, NULL)); - dns_rdataset_disassociate(&rdataset); - } - - /* Add glue AAAA RRset, if any */ - if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) { - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa, - &rdataset) - == ISC_R_SUCCESS); - CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, - &rdataset, 0, NULL)); - dns_rdataset_disassociate(&rdataset); - } - - dns_db_closeversion(db, &dbversion, true); - dns_zone_setdb(zone, db); - - result = ISC_R_SUCCESS; - - cleanup: - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_disassociate(&rdataset); - } - if (apexnode != NULL) { - dns_db_detachnode(db, &apexnode); - } - if (dbversion != NULL) { - dns_db_closeversion(db, &dbversion, false); - } - if (db != NULL) { - dns_db_detach(&db); - } - for (i = 0; rdatalists[i] != NULL; i++) { - while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) { - ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link); - dns_rdata_toregion(rdata, ®ion); - isc_mem_put(mctx, rdata, - sizeof(*rdata) + region.length); - } - } - - INSIST(dbversion == NULL); - - return (result); -} - -/*% - * Convert a config file zone type into a server zone type. - */ -static inline dns_zonetype_t -zonetype_fromconfig(const cfg_obj_t *map) { - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = cfg_map_get(map, "type", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - return (ns_config_getzonetype(obj)); -} - -/*% - * Helper function for strtoargv(). Pardon the gratuitous recursion. - */ -static isc_result_t -strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, - char ***argvp, unsigned int n) -{ - isc_result_t result; - - /* Discard leading whitespace. */ - while (*s == ' ' || *s == '\t') - s++; - - if (*s == '\0') { - /* We have reached the end of the string. */ - *argcp = n; - *argvp = isc_mem_get(mctx, n * sizeof(char *)); - if (*argvp == NULL) - return (ISC_R_NOMEMORY); - } else { - char *p = s; - while (*p != ' ' && *p != '\t' && *p != '\0') - p++; - if (*p != '\0') - *p++ = '\0'; - - result = strtoargvsub(mctx, p, argcp, argvp, n + 1); - if (result != ISC_R_SUCCESS) - return (result); - (*argvp)[n] = s; - } - return (ISC_R_SUCCESS); -} - -/*% - * Tokenize the string "s" into whitespace-separated words, - * return the number of words in '*argcp' and an array - * of pointers to the words in '*argvp'. The caller - * must free the array using isc_mem_put(). The string - * is modified in-place. - */ -static isc_result_t -strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { - return (strtoargvsub(mctx, s, argcp, argvp, 0)); -} - -static void -checknames(dns_zonetype_t ztype, const cfg_obj_t **maps, - const cfg_obj_t **objp) -{ - const char *zone = NULL; - isc_result_t result; - - switch (ztype) { - case dns_zone_slave: zone = "slave"; break; - case dns_zone_master: zone = "master"; break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - result = ns_checknames_get(maps, zone, objp); - INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL); -} - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone, dns_zone_t *raw) -{ - isc_result_t result; - const char *zname; - dns_rdataclass_t zclass; - dns_rdataclass_t vclass; - const cfg_obj_t *maps[5]; - const cfg_obj_t *nodefault[4]; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *obj; - const char *filename = NULL; - const char *dupcheck; - dns_notifytype_t notifytype = dns_notifytype_yes; - uint32_t count; - unsigned int dbargc; - char **dbargv; - static char default_dbtype[] = "rbt"; - static char dlz_dbtype[] = "dlz"; - char *cpval = default_dbtype; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_dialuptype_t dialup = dns_dialuptype_no; - dns_zonetype_t ztype; - int i; - int32_t journal_size; - bool multi; - bool alt; - dns_view_t *view; - bool check = false, fail = false; - bool warn = false, ignore = false; - bool ixfrdiff; - dns_masterformat_t masterformat; - const dns_master_style_t *masterstyle = &dns_master_style_default; - isc_stats_t *zoneqrystats; - dns_stats_t *rcvquerystats; - dns_zonestat_level_t statlevel = dns_zonestat_none; - int seconds; - dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; - isc_dscp_t dscp; - - i = 0; - if (zconfig != NULL) { - zoptions = cfg_tuple_get(zconfig, "options"); - nodefault[i] = maps[i] = zoptions; - i++; - } - if (vconfig != NULL) { - nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options"); - i++; - } - if (config != NULL) { - (void)cfg_map_get(config, "options", &options); - if (options != NULL) { - nodefault[i] = maps[i] = options; - i++; - } - } - nodefault[i] = NULL; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - if (vconfig != NULL) - RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), - dns_rdataclass_in, &vclass)); - else - vclass = dns_rdataclass_in; - - /* - * Configure values common to all zone types. - */ - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - - RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - vclass, &zclass)); - dns_zone_setclass(zone, zclass); - if (raw != NULL) - dns_zone_setclass(raw, zclass); - - ztype = zonetype_fromconfig(zoptions); - if (raw != NULL) { - dns_zone_settype(raw, ztype); - dns_zone_settype(zone, dns_zone_master); - } else - dns_zone_settype(zone, ztype); - - obj = NULL; - result = cfg_map_get(zoptions, "database", &obj); - if (result == ISC_R_SUCCESS) - cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - if (cpval == NULL) - return(ISC_R_NOMEMORY); - - obj = NULL; - result = cfg_map_get(zoptions, "dlz", &obj); - if (result == ISC_R_SUCCESS) { - const char *dlzname = cfg_obj_asstring(obj); - size_t len; - - if (cpval != default_dbtype) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': both 'database' and 'dlz' " - "specified", zname); - return (ISC_R_FAILURE); - } - - len = strlen(dlzname) + 5; - cpval = isc_mem_allocate(mctx, len); - if (cpval == NULL) - return (ISC_R_NOMEMORY); - snprintf(cpval, len, "dlz %s", dlzname); - } - - result = strtoargv(mctx, cpval, &dbargc, &dbargv); - if (result != ISC_R_SUCCESS && cpval != default_dbtype) { - isc_mem_free(mctx, cpval); - return (result); - } - - /* - * ANSI C is strange here. There is no logical reason why (char **) - * cannot be promoted automatically to (const char * const *) by the - * compiler w/o generating a warning. - */ - result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); - isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); - if (cpval != default_dbtype && cpval != dlz_dbtype) - isc_mem_free(mctx, cpval); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(zoptions, "file", &obj); - if (result == ISC_R_SUCCESS) - filename = cfg_obj_asstring(obj); - - /* - * Unless we're using some alternative database, a master zone - * will be needing a master file. - */ - if (ztype == dns_zone_master && cpval == default_dbtype && - filename == NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - return (ISC_R_FAILURE); - } - - if (ztype == dns_zone_slave) - masterformat = dns_masterformat_raw; - else - masterformat = dns_masterformat_text; - obj = NULL; - result = ns_config_get(maps, "masterfile-format", &obj); - if (result == ISC_R_SUCCESS) { - const char *masterformatstr = cfg_obj_asstring(obj); - - if (strcasecmp(masterformatstr, "text") == 0) { - masterformat = dns_masterformat_text; - } else if (strcasecmp(masterformatstr, "raw") == 0) { - masterformat = dns_masterformat_raw; - } else if (strcasecmp(masterformatstr, "map") == 0) { - masterformat = dns_masterformat_map; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "masterfile-style", &obj); - if (result == ISC_R_SUCCESS) { - const char *masterstylestr = cfg_obj_asstring(obj); - - if (masterformat != dns_masterformat_text) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s': 'masterfile-style' " - "can only be used with " - "'masterfile-format text'", zname); - return (ISC_R_FAILURE); - } - - if (strcasecmp(masterstylestr, "full") == 0) { - masterstyle = &dns_master_style_full; - } else if (strcasecmp(masterstylestr, "relative") == 0) { - masterstyle = &dns_master_style_default; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "max-zone-ttl", &obj); - if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'max-zone-ttl' is not compatible " - "with 'masterfile-format map'", zname); - return (ISC_R_FAILURE); - } else if (result == ISC_R_SUCCESS) { - dns_ttl_t maxttl = 0; /* unlimited */ - - if (cfg_obj_isuint32(obj)) - maxttl = cfg_obj_asuint32(obj); - dns_zone_setmaxttl(zone, maxttl); - if (raw != NULL) - dns_zone_setmaxttl(raw, maxttl); - } - - obj = NULL; - result = ns_config_get(maps, "max-records", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxrecords(mayberaw, cfg_obj_asuint32(obj)); - if (zone != mayberaw) - dns_zone_setmaxrecords(zone, 0); - - if (raw != NULL && filename != NULL) { -#define SIGNED ".signed" - size_t signedlen = strlen(filename) + sizeof(SIGNED); - char *signedname; - - RETERR(dns_zone_setfile3(raw, filename, - masterformat, masterstyle)); - signedname = isc_mem_get(mctx, signedlen); - if (signedname == NULL) - return (ISC_R_NOMEMORY); - - (void)snprintf(signedname, signedlen, "%s" SIGNED, filename); - result = dns_zone_setfile3(zone, signedname, - dns_masterformat_raw, NULL); - isc_mem_put(mctx, signedname, signedlen); - if (result != ISC_R_SUCCESS) - return (result); - } else - RETERR(dns_zone_setfile3(zone, filename, - masterformat, masterstyle)); - - obj = NULL; - result = cfg_map_get(zoptions, "journal", &obj); - if (result == ISC_R_SUCCESS) - RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj))); - - /* - * Notify messages are processed by the raw zone if it exists. - */ - if (ztype == dns_zone_slave) - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_notify, ac, mayberaw, - dns_zone_setnotifyacl, - dns_zone_clearnotifyacl)); - - /* - * XXXAG This probably does not make sense for stubs. - */ - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_query, ac, zone, - dns_zone_setqueryacl, - dns_zone_clearqueryacl)); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_query_on, ac, zone, - dns_zone_setqueryonacl, - dns_zone_clearqueryonacl)); - - obj = NULL; - result = ns_config_get(maps, "dialup", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - dialup = dns_dialuptype_yes; - else - dialup = dns_dialuptype_no; - } else { - const char *dialupstr = cfg_obj_asstring(obj); - if (strcasecmp(dialupstr, "notify") == 0) { - dialup = dns_dialuptype_notify; - } else if (strcasecmp(dialupstr, "notify-passive") == 0) { - dialup = dns_dialuptype_notifypassive; - } else if (strcasecmp(dialupstr, "refresh") == 0) { - dialup = dns_dialuptype_refresh; - } else if (strcasecmp(dialupstr, "passive") == 0) { - dialup = dns_dialuptype_passive; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (raw != NULL) - dns_zone_setdialup(raw, dialup); - dns_zone_setdialup(zone, dialup); - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - statlevel = dns_zonestat_full; - else - statlevel = dns_zonestat_none; - } else { - const char *levelstr = cfg_obj_asstring(obj); - if (strcasecmp(levelstr, "full") == 0) { - statlevel = dns_zonestat_full; - } else if (strcasecmp(levelstr, "terse") == 0) { - statlevel = dns_zonestat_terse; - } else if (strcasecmp(levelstr, "none") == 0) { - statlevel = dns_zonestat_none; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - dns_zone_setstatlevel(zone, statlevel); - - zoneqrystats = NULL; - rcvquerystats = NULL; - if (statlevel == dns_zonestat_full) { - RETERR(isc_stats_create(mctx, &zoneqrystats, - dns_nsstatscounter_max)); - RETERR(dns_rdatatypestats_create(mctx, - &rcvquerystats)); - } - dns_zone_setrequeststats(zone, zoneqrystats); - dns_zone_setrcvquerystats(zone, rcvquerystats); - - if (zoneqrystats != NULL) - isc_stats_detach(&zoneqrystats); - - if(rcvquerystats != NULL) - dns_stats_detach(&rcvquerystats); - - /* - * Configure master functionality. This applies - * to primary masters (type "master") and slaves - * acting as masters (type "slave"), but not to stubs. - */ - if (ztype != dns_zone_stub && ztype != dns_zone_staticstub && - ztype != dns_zone_redirect) { - obj = NULL; - result = ns_config_get(maps, "notify", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - notifytype = dns_notifytype_yes; - else - notifytype = dns_notifytype_no; - } else { - const char *notifystr = cfg_obj_asstring(obj); - if (strcasecmp(notifystr, "explicit") == 0) { - notifytype = dns_notifytype_explicit; - } else if (strcasecmp(notifystr, "master-only") == 0) { - notifytype = dns_notifytype_masteronly; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - if (raw != NULL) - dns_zone_setnotifytype(raw, dns_notifytype_no); - dns_zone_setnotifytype(zone, notifytype); - - obj = NULL; - result = ns_config_get(maps, "also-notify", &obj); - if (result == ISC_R_SUCCESS && - (notifytype == dns_notifytype_yes || - notifytype == dns_notifytype_explicit || - (notifytype == dns_notifytype_masteronly && - ztype == dns_zone_master))) - { - dns_ipkeylist_t ipkl; - dns_ipkeylist_init(&ipkl); - - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &ipkl)); - result = dns_zone_setalsonotifydscpkeys(zone, - ipkl.addrs, - ipkl.dscps, - ipkl.keys, - ipkl.count); - dns_ipkeylist_clear(mctx, &ipkl); - RETERR(result); - } else - RETERR(dns_zone_setalsonotify(zone, NULL, 0)); - - obj = NULL; - result = ns_config_get(maps, "notify-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setnotifysrc4dscp(zone, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setnotifysrc6dscp(zone, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-to-soa", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA, - cfg_obj_asboolean(obj)); - - dns_zone_setisself(zone, ns_client_isself, NULL); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_transfer, ac, zone, - dns_zone_setxfracl, - dns_zone_clearxfracl)); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-out", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-out", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (raw != NULL) - dns_zone_setjournalsize(raw, -1); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" PRId64 "' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (uint32_t)value; - } - if (raw != NULL) - dns_zone_setjournalsize(raw, journal_size); - dns_zone_setjournalsize(zone, journal_size); - - obj = NULL; - result = ns_config_get(maps, "ixfr-from-differences", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (cfg_obj_isboolean(obj)) - ixfrdiff = cfg_obj_asboolean(obj); - else if (!strcasecmp(cfg_obj_asstring(obj), "master") && - ztype == dns_zone_master) - ixfrdiff = true; - else if (!strcasecmp(cfg_obj_asstring(obj), "slave") && - ztype == dns_zone_slave) - ixfrdiff = true; - else - ixfrdiff = false; - if (raw != NULL) { - dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS, - true); - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - false); - } else - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - ixfrdiff); - - obj = NULL; - result = ns_config_get(maps, "request-expire", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setrequestexpire(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "request-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - checknames(ztype, maps, &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - if (raw != NULL) { - dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES, - check); - dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL, - fail); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, - false); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, - false); - } else { - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, - check); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, - fail); - } - - obj = NULL; - result = ns_config_get(maps, "notify-delay", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-sibling", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-spf", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check); - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "nsec3-test-zone", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, - cfg_obj_asboolean(obj)); - } else if (ztype == dns_zone_redirect) { - dns_zone_setnotifytype(zone, dns_notifytype_no); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" PRId64 "' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (uint32_t)value; - } - dns_zone_setjournalsize(zone, journal_size); - } - - /* - * Configure update-related options. These apply to - * primary masters only. - */ - if (ztype == dns_zone_master) { - dns_acl_t *updateacl; - - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_update, ac, mayberaw, - dns_zone_setupdateacl, - dns_zone_clearupdateacl)); - - updateacl = dns_zone_getupdateacl(mayberaw); - if (updateacl != NULL && dns_acl_isinsecure(updateacl)) - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "zone '%s' allows unsigned updates " - "from remote hosts, which is insecure", - zname); - - RETERR(configure_zone_ssutable(zoptions, mayberaw, zname)); - } - - if (ztype == dns_zone_master || raw != NULL) { - const cfg_obj_t *validity, *resign; - bool allow = false, maint = false; - - obj = NULL; - result = ns_config_get(maps, "sig-validity-interval", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - - validity = cfg_tuple_get(obj, "validity"); - seconds = cfg_obj_asuint32(validity); - if (!ns_g_sigvalinsecs) { - seconds *= 86400; - } - dns_zone_setsigvalidityinterval(zone, seconds); - - resign = cfg_tuple_get(obj, "re-sign"); - if (cfg_obj_isvoid(resign)) { - seconds /= 4; - } else if (!ns_g_sigvalinsecs) { - if (seconds > 7 * 86400) { - seconds = cfg_obj_asuint32(resign) * 86400; - } else { - seconds = cfg_obj_asuint32(resign) * 3600; - } - } else { - seconds = cfg_obj_asuint32(resign); - } - dns_zone_setsigresigninginterval(zone, seconds); - - obj = NULL; - result = ns_config_get(maps, "key-directory", &obj); - if (result == ISC_R_SUCCESS) { - filename = cfg_obj_asstring(obj); - RETERR(dns_zone_setkeydirectory(zone, filename)); - } - - obj = NULL; - result = ns_config_get(maps, "sig-signing-signatures", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setsignatures(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "sig-signing-nodes", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setnodes(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "sig-signing-type", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "update-check-ksk", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setrefreshkeyinterval(zone, - cfg_obj_asuint32(obj))); - - obj = NULL; - result = cfg_map_get(zoptions, "auto-dnssec", &obj); - if (result == ISC_R_SUCCESS) { - const char *arg = cfg_obj_asstring(obj); - if (strcasecmp(arg, "allow") == 0) { - allow = true; - } else if (strcasecmp(arg, "maintain") == 0) { - allow = maint = true; - } else if (strcasecmp(arg, "off") == 0) { - /* Default */ - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow); - dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint); - } - } - - if (ztype == dns_zone_slave) { - RETERR(configure_zone_acl(zconfig, vconfig, config, - allow_update_forwarding, ac, - mayberaw, dns_zone_setforwardacl, - dns_zone_clearforwardacl)); - } - - /*% - * Primary master functionality. - */ - if (ztype == dns_zone_master) { - obj = NULL; - result = ns_config_get(maps, "check-wildcard", &obj); - if (result == ISC_R_SUCCESS) - check = cfg_obj_asboolean(obj); - else - check = false; - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check); - - /* - * With map files, the default is ignore duplicate - * records. With other master formats, the default is - * taken from the global configuration. - */ - obj = NULL; - if (masterformat != dns_masterformat_map) { - result = ns_config_get(maps, "check-dup-records", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dupcheck = cfg_obj_asstring(obj); - } else { - result = ns_config_get(nodefault, "check-dup-records", - &obj); - if (result == ISC_R_SUCCESS) - dupcheck = cfg_obj_asstring(obj); - else - dupcheck = "ignore"; - - } - if (strcasecmp(dupcheck, "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(dupcheck, "fail") == 0) { - fail = check = true; - } else if (strcasecmp(dupcheck, "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail); - - obj = NULL; - result = ns_config_get(maps, "check-mx", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = false; - check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = true; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = false; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail); - - /* - * With map files, the default is *not* to check - * integrity. With other master formats, the default is - * taken from the global configuration. - */ - obj = NULL; - if (masterformat != dns_masterformat_map) { - result = ns_config_get(maps, "check-integrity", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, - cfg_obj_asboolean(obj)); - } else { - check = false; - result = ns_config_get(nodefault, "check-integrity", - &obj); - if (result == ISC_R_SUCCESS) - check = cfg_obj_asboolean(obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, - check); - } - - obj = NULL; - result = ns_config_get(maps, "check-mx-cname", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = true; - ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = true; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore); - - obj = NULL; - result = ns_config_get(maps, "check-srv-cname", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = true; - ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = false; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = true; - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME, - ignore); - - obj = NULL; - result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = cfg_map_get(zoptions, "dnssec-update-mode", &obj); - if (result == ISC_R_SUCCESS) { - const char *arg = cfg_obj_asstring(obj); - if (strcasecmp(arg, "no-resign") == 0) { - dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN, - true); - } else if (strcasecmp(arg, "maintain") == 0) { - /* Default */ - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - } - - obj = NULL; - result = ns_config_get(maps, "serial-update-method", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0) - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_unixtime); - else if (strcasecmp(cfg_obj_asstring(obj), "date") == 0) - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_date); - else - dns_zone_setserialupdatemethod(zone, - dns_updatemethod_increment); - } - - /* - * Configure slave functionality. - */ - switch (ztype) { - case dns_zone_slave: - case dns_zone_stub: - case dns_zone_redirect: - count = 0; - obj = NULL; - (void)cfg_map_get(zoptions, "masters", &obj); - if (obj != NULL) { - dns_ipkeylist_t ipkl; - dns_ipkeylist_init(&ipkl); - - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &ipkl)); - result = dns_zone_setmasterswithkeys(mayberaw, - ipkl.addrs, - ipkl.keys, - ipkl.count); - count = ipkl.count; - dns_ipkeylist_clear(mctx, &ipkl); - RETERR(result); - } else - result = dns_zone_setmasters(mayberaw, NULL, 0); - RETERR(result); - - multi = false; - if (count > 1) { - obj = NULL; - result = ns_config_get(maps, "multi-master", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - multi = cfg_obj_asboolean(obj); - } - dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-in", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-in", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setxfrsource4(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setxfrsource6(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp)); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setaltxfrsource4(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS && obj != NULL); - RETERR(dns_zone_setaltxfrsource6(mayberaw, - cfg_obj_assockaddr(obj))); - dscp = cfg_obj_getdscp(obj); - if (dscp == -1) - dscp = ns_g_dscp; - RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp)); - - obj = NULL; - (void)ns_config_get(maps, "use-alt-transfer-source", &obj); - if (obj == NULL) { - /* - * Default off when views are in use otherwise - * on for BIND 8 compatibility. - */ - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_default") == 0) - alt = true; - else - alt = false; - } else - alt = cfg_obj_asboolean(obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt); - - obj = NULL; - (void)ns_config_get(maps, "try-tcp-refresh", &obj); - dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH, - cfg_obj_asboolean(obj)); - break; - - case dns_zone_staticstub: - RETERR(configure_staticstub(zoptions, zone, zname, - default_dbtype)); - break; - - default: - break; - } - - return (ISC_R_SUCCESS); -} - - -/* - * Set up a DLZ zone as writeable - */ -isc_result_t -ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, - dns_rdataclass_t rdclass, dns_name_t *name) -{ - dns_db_t *db = NULL; - isc_time_t now; - isc_result_t result; - - TIME_NOW(&now); - - dns_zone_settype(zone, dns_zone_dlz); - result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_zone_dlzpostload(zone, db); - dns_db_detach(&db); - return (result); -} - -bool -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *obj = NULL; - const char *cfilename; - const char *zfilename; - dns_zone_t *raw = NULL; - bool has_raw; - dns_zonetype_t ztype; - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * We always reconfigure a static-stub zone for simplicity, assuming - * the amount of data to be loaded is small. - */ - if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: staticstub"); - return (false); - } - - /* If there's a raw zone, use that for filename and type comparison */ - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - zfilename = dns_zone_getfile(raw); - ztype = dns_zone_gettype(raw); - dns_zone_detach(&raw); - has_raw = true; - } else { - zfilename = dns_zone_getfile(zone); - ztype = dns_zone_gettype(zone); - has_raw = false; - } - - obj = NULL; - (void)cfg_map_get(zoptions, "inline-signing", &obj); - if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: old zone was inline-signing"); - return (false); - } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: old zone was not inline-signing"); - return (false); - } - - if (zonetype_fromconfig(zoptions) != ztype) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: type mismatch"); - return (false); - } - - obj = NULL; - (void)cfg_map_get(zoptions, "file", &obj); - if (obj != NULL) - cfilename = cfg_obj_asstring(obj); - else - cfilename = NULL; - if (!((cfilename == NULL && zfilename == NULL) || - (cfilename != NULL && zfilename != NULL && - strcmp(cfilename, zfilename) == 0))) - { - dns_zone_log(zone, ISC_LOG_DEBUG(1), - "not reusable: filename mismatch"); - return (false); - } - - return (true); -} diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in index 5b022f2..3798a4f 100644 --- a/bin/named/Makefile.in +++ b/bin/named/Makefile.in @@ -45,10 +45,10 @@ DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ - ${MAXMINDDB_CFLAGS} \ + ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} ${MAXMINDDB_CFLAGS} \ @DST_OPENSSL_INC@ -CDEFINES = @USE_GSSAPI@ @CRYPTO@ +CDEFINES = @CONTRIB_DLZ@ @USE_PKCS11@ @PKCS11_ENGINE@ @CRYPTO@ CWARNINGS = @@ -72,11 +72,11 @@ DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ - @LIBS@ + ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ - @LIBS@ + ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ SUBDIRS = unix @@ -94,7 +94,8 @@ OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ zoneconf.@O@ \ lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ - lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ + lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \ + ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS} UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ @@ -112,7 +113,8 @@ SRCS = builtin.c client.c config.c control.c \ tkeyconf.c tsigconf.c update.c xfrout.c \ zoneconf.c \ lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ - lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c + lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \ + ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS} MANPAGES = named.8 lwresd.8 named.conf.5 @@ -120,12 +122,8 @@ HTMLPAGES = named.html lwresd.html named.conf.html MANOBJS = ${MANPAGES} ${HTMLPAGES} -EXT_CFLAGS = -fpie - @BIND9_MAKE_RULES@ -LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack - main.@O@: main.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ @@ -182,17 +180,12 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man5: named.conf.5 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man5 - -install-man8: named.8 lwresd.8 - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install-man: install-man5 install-man8 - -install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs install-man +install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named@EXEEXT@ ${DESTDIR}${sbindir} (cd ${DESTDIR}${sbindir}; rm -f lwresd@EXEEXT@; @LN@ named@EXEEXT@ lwresd@EXEEXT@) + ${INSTALL_DATA} ${srcdir}/named.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 uninstall:: rm -f ${DESTDIR}${mandir}/man5/named.conf.5 @@ -201,5 +194,7 @@ uninstall:: rm -f ${DESTDIR}${sbindir}/lwresd@EXEEXT@ ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/named@EXEEXT@ +@DLZ_DRIVER_RULES@ + named-symtbl.@O@: named-symtbl.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c named-symtbl.c diff --git a/bin/named/client.c b/bin/named/client.c index 4d140e8..4a50ad9 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -1768,8 +1768,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message, isc_buffer_init(&buf, cookie, sizeof(cookie)); isc_stdtime_get(&now); - nonce = ((isc_rng_random(ns_g_server->rngctx) << 16) | - isc_rng_random(ns_g_server->rngctx)); + isc_random_get(&nonce); compute_cookie(client, now, nonce, ns_g_server->secret, &buf); diff --git a/bin/named/config.c b/bin/named/config.c index d2cd3bc..fbd2f21 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -98,9 +97,7 @@ options {\n\ # pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\ port 53;\n\ prefetch 2 9;\n" -#if defined(ISC_PLATFORM_CRYPTORANDOM) -" random-device none;\n" -#elif defined(PATH_RANDOMDEV) +#ifdef PATH_RANDOMDEV " random-device \"" PATH_RANDOMDEV "\";\n" #endif " recursing-file \"named.recursing\";\n\ @@ -182,14 +179,13 @@ options {\n\ #ifdef HAVE_LMDB " lmdb-mapsize 32M;\n" #endif -" max-cache-size 90%;\n\ - max-acache-size 16M;\n\ +" max-acache-size 16M;\n\ + max-cache-size 90%;\n\ max-cache-ttl 604800; /* 1 week */\n\ max-clients-per-query 100;\n\ max-ncache-ttl 10800; /* 3 hours */\n\ max-recursion-depth 7;\n\ max-recursion-queries 100;\n\ - max-stale-ttl 604800; /* 1 week */\n\ message-compression yes;\n\ # min-roots ;\n\ minimal-any false;\n\ @@ -204,14 +200,10 @@ options {\n\ request-expire true;\n\ request-ixfr true;\n\ require-server-cookie no;\n\ - resolver-nonbackoff-tries 3;\n\ - resolver-retry-interval 800; /* in milliseconds */\n\ # rfc2308-type1 ;\n\ root-key-sentinel yes;\n\ servfail-ttl 1;\n\ # sortlist \n\ - stale-answer-enable false;\n\ - stale-answer-ttl 1; /* 1 second */\n\ # topology \n\ transfer-format many-answers;\n\ v6-bias 50;\n\ @@ -988,21 +980,6 @@ ns_config_getkeyalgorithm(const char *str, dns_name_t **name, return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits)); } -static inline int -algorithms_start() { -#ifndef PK11_MD5_DISABLE - if (!isc_md5_available()) { - int i = 0; - while (algorithms[i].str != NULL && - algorithms[i].hmac == hmacmd5) { - i++; - } - return i; - } -#endif - return 0; -} - isc_result_t ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, unsigned int *typep, uint16_t *digestbits) @@ -1012,7 +989,7 @@ ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, uint16_t bits; isc_result_t result; - for (i = algorithms_start(); algorithms[i].str != NULL; i++) { + for (i = 0; algorithms[i].str != NULL; i++) { len = strlen(algorithms[i].str); if (strncasecmp(algorithms[i].str, str, len) == 0 && (str[len] == '\0' || @@ -1035,12 +1012,7 @@ ns_config_getkeyalgorithm2(const char *str, dns_name_t **name, if (name != NULL) { switch (algorithms[i].hmac) { #ifndef PK11_MD5_DISABLE - case hmacmd5: - if (isc_md5_available()) { - *name = dns_tsig_hmacmd5_name; break; - } else { - return (ISC_R_NOTFOUND); - } + case hmacmd5: *name = dns_tsig_hmacmd5_name; break; #endif case hmacsha1: *name = dns_tsig_hmacsha1_name; break; case hmacsha224: *name = dns_tsig_hmacsha224_name; break; diff --git a/bin/named/control.c b/bin/named/control.c index 0756c73..23620b4 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -282,8 +282,6 @@ ns_control_docommand(isccc_sexpr_t *message, bool readonly, result = ns_server_validation(ns_g_server, lex, text); } else if (command_compare(command, NS_COMMAND_ZONESTATUS)) { result = ns_server_zonestatus(ns_g_server, lex, text); - } else if (command_compare(command, NS_COMMAND_SERVESTALE)) { - result = ns_server_servestale(ns_g_server, lex, text); } else { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 42128dc..9fdf49b 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -327,10 +327,9 @@ log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { static void control_recvmessage(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = NULL; - controllistener_t *listener = NULL; - ns_server_t *server = NULL; - controlkey_t *key = NULL; + controlconnection_t *conn; + controllistener_t *listener; + controlkey_t *key; isccc_sexpr_t *request = NULL; isccc_sexpr_t *response = NULL; uint32_t algorithm; @@ -341,17 +340,16 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) { isc_buffer_t *text; isc_result_t result; isc_result_t eresult; - isccc_sexpr_t *_ctrl = NULL; + isccc_sexpr_t *_ctrl; isccc_time_t sent; isccc_time_t exp; uint32_t nonce; - isccc_sexpr_t *data = NULL; + isccc_sexpr_t *data; REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); conn = event->ev_arg; listener = conn->listener; - server = listener->controls->server; algorithm = DST_ALG_UNKNOWN; secret.rstart = NULL; text = NULL; @@ -464,11 +462,8 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) { * Establish nonce. */ if (conn->nonce == 0) { - while (conn->nonce == 0) { - uint16_t r1 = isc_rng_random(server->rngctx); - uint16_t r2 = isc_rng_random(server->rngctx); - conn->nonce = (r1 << 16) | r2; - } + while (conn->nonce == 0) + isc_random_get(&conn->nonce); eresult = ISC_R_SUCCESS; } else eresult = ns_control_docommand(request, listener->readonly, &text); diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h index 37403f1..56bad8d 100644 --- a/bin/named/include/named/control.h +++ b/bin/named/include/named/control.h @@ -67,7 +67,6 @@ #define NS_COMMAND_MKEYS "managed-keys" #define NS_COMMAND_DNSTAPREOPEN "dnstap-reopen" #define NS_COMMAND_DNSTAP "dnstap" -#define NS_COMMAND_SERVESTALE "serve-stale" isc_result_t ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index b1756af..0d96a79 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -152,7 +152,7 @@ EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR EXTERN const char * ns_g_username INIT(NULL); -#if defined(USE_PKCS11) && !defined(PKCS11CRYPTO) +#if defined(USE_PKCS11) EXTERN const char * ns_g_engine INIT(PKCS11_ENGINE); #else EXTERN const char * ns_g_engine INIT(NULL); diff --git a/bin/named/include/named/log.h b/bin/named/include/named/log.h index 0d1d985..76e3a51 100644 --- a/bin/named/include/named/log.h +++ b/bin/named/include/named/log.h @@ -30,7 +30,6 @@ #define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) #define NS_LOGCATEGORY_QUERY_ERRORS (&ns_g_categories[7]) #define NS_LOGCATEGORY_TAT (&ns_g_categories[8]) -#define NS_LOGCATEGORY_SERVE_STALE (&ns_g_categories[9]) /* * Backwards compatibility. diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h index 53c052b..ef1b172 100644 --- a/bin/named/include/named/query.h +++ b/bin/named/include/named/query.h @@ -35,18 +35,6 @@ typedef struct ns_dbversion { ISC_LINK(struct ns_dbversion) link; } ns_dbversion_t; -/*% - * nameserver recursion parameters, to uniquely identify a recursion - * query; this is used to detect a recursion loop - */ -typedef struct ns_query_recparam { - dns_rdatatype_t qtype; - dns_name_t * qname; - dns_fixedname_t fqname; - dns_name_t * qdomain; - dns_fixedname_t fqdomain; -} ns_query_recparam_t; - /*% nameserver query structure */ struct ns_query { unsigned int attributes; @@ -75,7 +63,6 @@ struct ns_query { unsigned int dns64_aaaaoklen; unsigned int dns64_options; unsigned int dns64_ttl; - struct { dns_db_t * db; dns_zone_t * zone; @@ -89,8 +76,6 @@ struct ns_query { bool authoritative; bool is_zone; } redirect; - - ns_query_recparam_t recparam; dns_keytag_t root_key_sentinel_keyid; bool root_key_sentinel_is_ta; bool root_key_sentinel_not_ta; diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 08a02dc..4fd0194 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -136,7 +135,6 @@ struct ns_server { char * lockfile; uint16_t transfer_tcp_message_size; - isc_rng_t * rngctx; }; struct ns_altsecret { @@ -227,10 +225,7 @@ enum { dns_nsstatscounter_reclimitdropped = 58, - dns_nsstatscounter_trystale = 59, - dns_nsstatscounter_usedstale = 60, - - dns_nsstatscounter_max = 61 + dns_nsstatscounter_max = 59 }; /*% @@ -769,12 +764,4 @@ ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); isc_result_t ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text); - -/*% - * Control whether stale answers are served or not when configured in - * named.conf. - */ -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text); #endif /* NAMED_SERVER_H */ diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index e12fad9..93aac31 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/bin/named/log.c b/bin/named/log.c index ea6f114..acfa766 100644 --- a/bin/named/log.c +++ b/bin/named/log.c @@ -38,7 +38,6 @@ static isc_logcategory_t categories[] = { { "update-security", 0 }, { "query-errors", 0 }, { "trust-anchor-telemetry", 0 }, - { "serve-stale", 0 }, { NULL, 0 } }; diff --git a/bin/named/lwresd.docbook b/bin/named/lwresd.docbook index d1c3cdc..3595906 100644 --- a/bin/named/lwresd.docbook +++ b/bin/named/lwresd.docbook @@ -10,7 +10,7 @@ --> - + 2009-01-20 @@ -22,7 +22,7 @@ lwresd 8 - BIND9 + BIND9 diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index ed137f2..092ecf3 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -11,7 +11,7 @@ - + 2020-03-12 @@ -23,7 +23,7 @@ named.conf 5 - BIND9 + BIND9 diff --git a/bin/named/named.docbook b/bin/named/named.docbook index b95a26f..6e30a72 100644 --- a/bin/named/named.docbook +++ b/bin/named/named.docbook @@ -10,7 +10,7 @@ --> - + 2014-02-19 @@ -22,7 +22,7 @@ named 8 - BIND9 + BIND9 @@ -516,79 +516,6 @@
- NOTES - Red Hat SELinux BIND Security Profile - - - By default, Red Hat ships BIND with the most secure SELinux policy - that will not prevent normal BIND operation and will prevent exploitation - of all known BIND security vulnerabilities . See the selinux(8) man page - for information about SElinux. - - - - It is not necessary to run named in a chroot environment if the Red Hat - SELinux policy for named is enabled. When enabled, this policy is far - more secure than a chroot environment. Users are recommended to enable - SELinux and remove the bind-chroot package. - - - - With this extra security comes some restrictions: - - - - By default, the SELinux policy allows named to write any master - zone database files. Only the root user may create files in the $ROOTDIR/var/named - zone database file directory (the options { "directory" } option), where - $ROOTDIR is set in /etc/sysconfig/named. - - - - The "named" group must be granted read privelege to - these files in order for named to be enabled to read them. - - - - Any file created in the zone database file directory is automatically assigned - the SELinux file context named_zone_t . - - - - By default, SELinux prevents any role from modifying named_zone_t files; this - means that files in the zone database directory cannot be modified by dynamic - DNS (DDNS) updates or zone transfers. - - - - The Red Hat BIND distribution and SELinux policy creates three directories where - named is allowed to create and modify files: /var/named/slaves, /var/named/dynamic - /var/named/data. By placing files you want named to modify, such as - slave or DDNS updateable zone files and database / statistics dump files in - these directories, named will work normally and no further operator action is - required. Files in these directories are automatically assigned the 'named_cache_t' - file context, which SELinux allows named to write. - - - - Red Hat BIND SDB support - - - Red Hat ships named with compiled in Simplified Database Backend modules that ISC - provides in the "contrib/sdb" directory. Install bind-sdb package if you want use them. - - - - The SDB modules for LDAP, PostGreSQL, DirDB and SQLite are compiled into named-sdb. - - - - See the documentation for the various SDB modules in /usr/share/doc/bind-sdb-*/ . - - - - - SEE ALSO RFC 1033, diff --git a/bin/named/query.c b/bin/named/query.c index a95f5ad..3d196f1 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -149,14 +148,10 @@ last_cmpxchg(isc_stdtime_t *x, isc_stdtime_t *e, isc_stdtime_t r) { #define REDIRECT(c) (((c)->query.attributes & \ NS_QUERYATTR_REDIRECT) != 0) -/*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */ +/*% No QNAME Proof? */ #define NOQNAME(r) (((r)->attributes & \ DNS_RDATASETATTR_NOQNAME) != 0) -/*% Does the rdataset 'r' contain a stale answer? */ -#define STALE(r) (((r)->attributes & \ - DNS_RDATASETATTR_STALE) != 0) - #ifdef WANT_QUERYTRACE static inline void client_trace(ns_client_t *client, int level, const char *message) { @@ -245,10 +240,6 @@ static bool rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain); - /*% * Increment query statistics counters. */ @@ -502,7 +493,6 @@ query_reset(ns_client_t *client, bool everything) { client->query.isreferral = false; client->query.dns64_options = 0; client->query.dns64_ttl = UINT32_MAX; - recparam_update(&client->query.recparam, 0, NULL, NULL); client->query.root_key_sentinel_keyid = 0; client->query.root_key_sentinel_is_ta = false; client->query.root_key_sentinel_not_ta = false; @@ -4314,54 +4304,6 @@ log_quota(ns_client_t *client, isc_stdtime_t *last, isc_stdtime_t now, } } -/*% - * Check whether the recursion parameters in 'param' match the current query's - * recursion parameters provided in 'qtype', 'qname', and 'qdomain'. - */ -static bool -recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - REQUIRE(param != NULL); - - return (param->qtype == qtype && - param->qname != NULL && qname != NULL && - param->qdomain != NULL && qdomain != NULL && - dns_name_equal(param->qname, qname) && - dns_name_equal(param->qdomain, qdomain)); -} - -/*% - * Update 'param' with current query's recursion parameters provided in - * 'qtype', 'qname', and 'qdomain'. - */ -static void -recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, - const dns_name_t *qname, const dns_name_t *qdomain) -{ - isc_result_t result; - - REQUIRE(param != NULL); - - param->qtype = qtype; - - if (qname == NULL) { - param->qname = NULL; - } else { - param->qname = dns_fixedname_initname(¶m->fqname); - result = dns_name_copy(qname, param->qname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - if (qdomain == NULL) { - param->qdomain = NULL; - } else { - param->qdomain = dns_fixedname_initname(¶m->fqdomain); - result = dns_name_copy(qdomain, param->qdomain, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } -} - static isc_result_t query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, dns_name_t *qdomain, dns_rdataset_t *nameservers, @@ -4371,19 +4313,6 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, dns_rdataset_t *rdataset, *sigrdataset; isc_sockaddr_t *peeraddr; - /* - * Check recursion parameters from the previous query to see if they - * match. If not, update recursion parameters and proceed. - */ - if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "recursion loop detected"); - return (ISC_R_FAILURE); - } - - recparam_update(&client->query.recparam, qtype, qname, qdomain); - if (!resuming) inc_stats(client, dns_nsstatscounter_recursion); @@ -6891,7 +6820,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) int line = -1; bool dns64_exclude, dns64, rpz; bool nxrewrite = false; - bool want_stale = false; bool redirected = false; dns_clientinfomethods_t cm; dns_clientinfo_t ci; @@ -7201,7 +7129,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) type = qtype; restart: - // query_start CTRACE(ISC_LOG_DEBUG(3), "query_find: restart"); want_restart = false; authoritative = false; @@ -7346,7 +7273,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } db_find: - // query_lookup CTRACE(ISC_LOG_DEBUG(3), "query_find: db_find"); /* * We'll need some resources... @@ -7404,35 +7330,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (!is_zone) dns_cache_updatestats(client->view->cache, result); - if (want_stale) { - char namebuf[DNS_NAME_FORMATSIZE]; - bool success; - - client->query.dboptions &= ~DNS_DBFIND_STALEOK; - want_stale = false; - - if (dns_rdataset_isassociated(rdataset) && - dns_rdataset_count(rdataset) > 0 && - STALE(rdataset)) { - rdataset->ttl = client->view->staleanswerttl; - success = true; - } else { - success = false; - } - - dns_name_format(client->query.qname, - namebuf, sizeof(namebuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_SERVE_STALE, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s resolver failure, stale answer %s", - namebuf, success ? "used" : "unavailable"); - - if (!success) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - resume: CTRACE(ISC_LOG_DEBUG(3), "query_find: resume"); @@ -7778,7 +7675,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * The cache doesn't even have the root NS. Get them from * the hints DB. */ - // query_notfound INSIST(!is_zone); if (db != NULL) dns_db_detach(&db); @@ -7841,14 +7737,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) */ /* FALLTHROUGH */ case DNS_R_DELEGATION: - // query_delegation authoritative = false; if (is_zone) { /* * Look to see if we are authoritative for the * child zone if the query type is DS. */ - // query_zone_delegation if (!RECURSIONOK(client) && (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) { @@ -8235,7 +8129,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) false, true); } } - // query_nxdomain if (dns_rdataset_isassociated(rdataset)) { /* * If we've got a NSEC record, we need to save the @@ -8556,8 +8449,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * If we have a zero ttl from the cache refetch it. */ - // query_cname - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && + if (!is_zone && !resuming && rdataset->ttl == 0 && RECURSIONOK(client)) { if (dns_rdataset_isassociated(rdataset)) @@ -8783,11 +8675,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) "query_find: unexpected error after resuming: %s", isc_result_totext(result)); CTRACE(ISC_LOG_ERROR, errmsg); - if (resuming) { - want_stale = true; - } else { - QUERY_ERROR(DNS_R_SERVFAIL); - } + QUERY_ERROR(DNS_R_SERVFAIL); goto cleanup; } @@ -9043,7 +8931,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * If we have a zero ttl from the cache refetch it. */ - if (!is_zone && !resuming && !STALE(rdataset) && rdataset->ttl == 0 && + if (!is_zone && !resuming && rdataset->ttl == 0 && RECURSIONOK(client)) { if (dns_rdataset_isassociated(rdataset)) @@ -9054,7 +8942,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (node != NULL) dns_db_detachnode(db, &node); - // query_respond INSIST(!REDIRECT(client)); result = query_recurse(client, qtype, client->query.qname, @@ -9335,7 +9222,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) dns_fixedname_name(&wildcardname), true, false); cleanup: - // query_done CTRACE(ISC_LOG_DEBUG(3), "query_find: cleanup"); /* * General cleanup. @@ -9392,49 +9278,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) goto restart; } - if (want_stale) { - dns_ttl_t stale_ttl = 0; - isc_result_t result; - bool staleanswersok = false; - - /* - * Stale answers only make sense if stale_ttl > 0 but - * we want rndc to be able to control returning stale - * answers if they are configured. - */ - dns_db_attach(client->view->cachedb, &db); - result = dns_db_getservestalettl(db, &stale_ttl); - if (result == ISC_R_SUCCESS && stale_ttl > 0) { - switch (client->view->staleanswersok) { - case dns_stale_answer_yes: - staleanswersok = true; - break; - case dns_stale_answer_conf: - staleanswersok = - client->view->staleanswersenable; - break; - case dns_stale_answer_no: - staleanswersok = false; - break; - } - } else { - staleanswersok = false; - } - - if (staleanswersok) { - client->query.dboptions |= DNS_DBFIND_STALEOK; - inc_stats(client, dns_nsstatscounter_trystale); - if (client->query.fetch != NULL) - dns_resolver_destroyfetch( - &client->query.fetch); - goto db_find; - } - dns_db_detach(&db); - want_stale = false; - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (eresult != ISC_R_SUCCESS && (!PARTIALANSWER(client) || WANTRECURSION(client) || eresult == DNS_R_DROP)) { diff --git a/bin/named/server.c b/bin/named/server.c index 3a5ba91..30d38be 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -1545,12 +1544,12 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { r.length = strlen(r.base); result = dns_secalg_fromtext(&alg, &r); - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { + if (result != ISC_R_SUCCESS) { uint8_t ui; result = isc_parse_uint8(&ui, r.base, 10); alg = ui; } - if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) { + if (result != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), ns_g_lctx, ISC_LOG_ERROR, "invalid algorithm"); @@ -1720,8 +1719,7 @@ static bool cache_sharable(dns_view_t *originview, dns_view_t *view, bool new_zero_no_soattl, unsigned int new_cleaning_interval, - uint64_t new_max_cache_size, - uint32_t new_stale_ttl) + uint64_t new_max_cache_size) { /* * If the cache cannot even reused for the same view, it cannot be @@ -1736,7 +1734,6 @@ cache_sharable(dns_view_t *originview, dns_view_t *view, */ if (dns_cache_getcleaninginterval(originview->cache) != new_cleaning_interval || - dns_cache_getservestalettl(originview->cache) != new_stale_ttl || dns_cache_getcachesize(originview->cache) != new_max_cache_size) { return (false); } @@ -3292,7 +3289,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, size_t max_acache_size; size_t max_adb_size; uint32_t lame_ttl, fail_ttl; - uint32_t max_stale_ttl; dns_tsig_keyring_t *ring = NULL; dns_view_t *pview = NULL; /* Production view */ isc_mem_t *cmctx = NULL, *hmctx = NULL; @@ -3321,7 +3317,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, bool old_rpz_ok = false; isc_dscp_t dscp4 = -1, dscp6 = -1; dns_dyndbctx_t *dctx = NULL; - unsigned int resolver_param; REQUIRE(DNS_VIEW_VALID(view)); @@ -3736,24 +3731,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, if (view->maxncachettl > 7 * 24 * 3600) view->maxncachettl = 7 * 24 * 3600; - obj = NULL; - result = ns_config_get(maps, "max-stale-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - max_stale_ttl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "stale-answer-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswersenable = cfg_obj_asboolean(obj); - - result = dns_viewlist_find(&ns_g_server->viewlist, view->name, - view->rdclass, &pview); - if (result == ISC_R_SUCCESS) { - view->staleanswersok = pview->staleanswersok; - dns_view_detach(&pview); - } else - view->staleanswersok = dns_stale_answer_conf; - /* * Configure the view's cache. * @@ -3787,8 +3764,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, nsc = cachelist_find(cachelist, cachename, view->rdclass); if (nsc != NULL) { if (!cache_sharable(nsc->primaryview, view, zero_no_soattl, - cleaning_interval, max_cache_size, - max_stale_ttl)) { + cleaning_interval, max_cache_size)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "views %s and %s can't share the cache " @@ -3887,15 +3863,9 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, dns_cache_setcleaninginterval(cache, cleaning_interval); dns_cache_setcachesize(cache, max_cache_size); - dns_cache_setservestalettl(cache, max_stale_ttl); dns_cache_detach(&cache); - obj = NULL; - result = ns_config_get(maps, "stale-answer-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->staleanswerttl = ISC_MAX(cfg_obj_asuint32(obj), 1); - /* * Resolver. * @@ -4085,21 +4055,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, view->maxbits = maxbits; /* - * Set resolver retry parameters. - */ - obj = NULL; - CHECK(ns_config_get(maps, "resolver-retry-interval", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setretryinterval(view->resolver, resolver_param); - - obj = NULL; - CHECK(ns_config_get(maps, "resolver-nonbackoff-tries", &obj)); - resolver_param = cfg_obj_asuint32(obj); - if (resolver_param > 0) - dns_resolver_setnonbackofftries(view->resolver, resolver_param); - - /* * Set supported DNSSEC algorithms. */ dns_resolver_reset_algorithms(view->resolver); @@ -8323,32 +8278,17 @@ load_configuration(const char *filename, ns_server_t *server, * Open the source of entropy. */ if (first_time) { - const char *randomdev = NULL; - int level = ISC_LOG_ERROR; obj = NULL; result = ns_config_get(maps, "random-device", &obj); - if (result == ISC_R_SUCCESS) { - if (!cfg_obj_isvoid(obj)) { - level = ISC_LOG_INFO; - randomdev = cfg_obj_asstring(obj); - } - } - if (randomdev == NULL) { -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_entropy_usehook(ns_g_entropy, true); -#else - if ((obj != NULL) && !cfg_obj_isvoid(obj)) - level = ISC_LOG_INFO; + if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, level, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, "no source of entropy found"); - if ((obj == NULL) || cfg_obj_isvoid(obj)) { - CHECK(ISC_R_FAILURE); - } -#endif } else { + const char *randomdev = cfg_obj_asstring(obj); + int level = ISC_LOG_ERROR; result = isc_entropy_createfilesource(ns_g_entropy, - randomdev); + randomdev); #ifdef PATH_RANDOMDEV if (ns_g_fallbackentropy != NULL) { level = ISC_LOG_INFO; @@ -8359,8 +8299,8 @@ load_configuration(const char *filename, ns_server_t *server, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, level, - "could not open " - "entropy source %s: %s", + "could not open entropy source " + "%s: %s", randomdev, isc_result_totext(result)); } @@ -9151,7 +9091,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { server->in_roothints = NULL; server->blackholeacl = NULL; server->keepresporder = NULL; - server->rngctx = NULL; /* Must be first. */ CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, @@ -9178,9 +9117,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, &server->tkeyctx), "creating TKEY context"); - server->rngctx = NULL; - CHECKFATAL(isc_rng_create(ns_g_mctx, ns_g_entropy, &server->rngctx), - "creating random numbers context"); /* * Setup the server task, which is responsible for coordinating @@ -9387,8 +9323,7 @@ ns_server_destroy(ns_server_t **serverp) { if (server->zonemgr != NULL) dns_zonemgr_detach(&server->zonemgr); - if (server->rngctx != NULL) - isc_rng_detach(&server->rngctx); + if (server->tkeyctx != NULL) dns_tkeyctx_destroy(&server->tkeyctx); @@ -13425,10 +13360,10 @@ newzone_cfgctx_destroy(void **cfgp) { static isc_result_t generate_salt(unsigned char *salt, size_t saltlen) { - size_t i, n; + int i, n; union { unsigned char rnd[256]; - uint16_t rnd16[128]; + uint32_t rnd32[64]; } rnd; unsigned char text[512 + 1]; isc_region_t r; @@ -13438,10 +13373,9 @@ generate_salt(unsigned char *salt, size_t saltlen) { if (saltlen > 256U) return (ISC_R_RANGE); - n = (saltlen + sizeof(uint16_t) - 1) / sizeof(uint16_t); - for (i = 0; i < n; i++) { - rnd.rnd16[i] = isc_rng_random(ns_g_server->rngctx); - } + n = (int) (saltlen + sizeof(uint32_t) - 1) / sizeof(uint32_t); + for (i = 0; i < n; i++) + isc_random_get(&rnd.rnd32[i]); memmove(salt, rnd.rnd, saltlen); @@ -14603,132 +14537,3 @@ ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) { return (ISC_R_NOTIMPLEMENTED); #endif } - -isc_result_t -ns_server_servestale(ns_server_t *server, isc_lex_t *lex, - isc_buffer_t **text) -{ - char *ptr, *classtxt, *viewtxt = NULL; - char msg[128]; - dns_rdataclass_t rdclass = dns_rdataclass_in; - dns_view_t *view; - bool found = false; - dns_stale_answer_t staleanswersok = dns_stale_answer_conf; - bool wantstatus = false; - isc_result_t result = ISC_R_SUCCESS; - - /* Skip the command name. */ - ptr = next_token(lex, text); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - ptr = next_token(lex, NULL); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (strcasecmp(ptr, "on") == 0 || strcasecmp(ptr, "yes") == 0) { - staleanswersok = dns_stale_answer_yes; - } else if (strcasecmp(ptr, "off") == 0 || strcasecmp(ptr, "no") == 0) { - staleanswersok = dns_stale_answer_no; - } else if (strcasecmp(ptr, "reset") == 0) { - staleanswersok = dns_stale_answer_conf; - } else if (strcasecmp(ptr, "status") == 0) { - wantstatus = true; - } else - return (DNS_R_SYNTAX); - - /* Look for the optional class name. */ - classtxt = next_token(lex, text); - if (classtxt != NULL) { - /* Look for the optional view name. */ - viewtxt = next_token(lex, text); - } - - if (classtxt != NULL) { - isc_textregion_t r; - - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - if (viewtxt == NULL) { - viewtxt = classtxt; - classtxt = NULL; - result = ISC_R_SUCCESS; - } else { - snprintf(msg, sizeof(msg), - "unknown class '%s'", classtxt); - (void) putstr(text, msg); - goto cleanup; - } - } - } - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_ttl_t stale_ttl = 0; - dns_db_t *db = NULL; - - if (classtxt != NULL && rdclass != view->rdclass) - continue; - - if (viewtxt != NULL && strcmp(view->name, viewtxt) != 0) - continue; - - if (!wantstatus) { - view->staleanswersok = staleanswersok; - found = true; - continue; - } - - db = NULL; - dns_db_attach(view->cachedb, &db); - (void)dns_db_getservestalettl(db, &stale_ttl); - dns_db_detach(&db); - if (found) - CHECK(putstr(text, "\n")); - CHECK(putstr(text, view->name)); - CHECK(putstr(text, ": ")); - switch (view->staleanswersok) { - case dns_stale_answer_yes: - if (stale_ttl > 0) - CHECK(putstr(text, "on (rndc)")); - else - CHECK(putstr(text, "off (not-cached)")); - break; - case dns_stale_answer_no: - CHECK(putstr(text, "off (rndc)")); - break; - case dns_stale_answer_conf: - if (view->staleanswersenable && stale_ttl > 0) - CHECK(putstr(text, "on")); - else if (view->staleanswersenable) - CHECK(putstr(text, "off (not-cached)")); - else - CHECK(putstr(text, "off")); - break; - } - if (stale_ttl > 0) { - snprintf(msg, sizeof(msg), - " (stale-answer-ttl=%u max-stale-ttl=%u)", - view->staleanswerttl, stale_ttl); - CHECK(putstr(text, msg)); - } - found = true; - } - isc_task_endexclusive(ns_g_server->task); - - if (!found) - result = ISC_R_NOTFOUND; - -cleanup: - if (isc_buffer_usedlength(*text) > 0) - (void) putnull(text); - - return (result); -} diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 4938c03..12ab048 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -300,12 +300,6 @@ init_desc(void) { SET_NSSTATDESC(reclimitdropped, "queries dropped due to recursive client limit", "RecLimitDropped"); - SET_NSSTATDESC(trystale, - "attempts to use stale cache data after lookup failure", - "QryTryStale"); - SET_NSSTATDESC(usedstale, - "successful uses of stale cache data after lookup failure", - "QryUsedStale"); INSIST(i == dns_nsstatscounter_max); /* Initialize resolver statistics */ diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in index 1498222..025af9c 100644 --- a/bin/named/unix/Makefile.in +++ b/bin/named/unix/Makefile.in @@ -11,8 +11,6 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -EXT_CFLAGS = -fpie - @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 458aa76..4993265 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -278,8 +277,7 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { if (*ectx == NULL) { result = isc_entropy_create(mctx, ectx); if (result != ISC_R_SUCCESS) - fatal("could not create entropy object: %s", - isc_result_totext(result)); + fatal("could not create entropy object"); ISC_LIST_INIT(sources); } @@ -288,11 +286,6 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { randomfile = NULL; } -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(*ectx, true); - } -#endif result = isc_entropy_usebestsource(*ectx, &source, randomfile, usekeyboard); @@ -490,10 +483,9 @@ parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len, strlcpy(buf, hmacstr, ISC_MIN(len + 1, sizeof(buf))); #ifndef PK11_MD5_DISABLE - if (strcasecmp(buf, "hmac-md5") == 0 && isc_md5_available()) { + if (strcasecmp(buf, "hmac-md5") == 0) { *hmac = DNS_TSIG_HMACMD5_NAME; - } else if (strncasecmp(buf, "hmac-md5-", 9) == 0 && - isc_md5_available()) { + } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { *hmac = DNS_TSIG_HMACMD5_NAME; result = isc_parse_uint16(&digestbits, &buf[9], 10); if (result != ISC_R_SUCCESS || digestbits > 128) { @@ -606,10 +598,10 @@ setup_keystr(void) { exit(1); } } else { - hmacname = DNS_TSIG_HMACSHA256_NAME; #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) - hmacname = DNS_TSIG_HMACMD5_NAME; + hmacname = DNS_TSIG_HMACMD5_NAME; +#else + hmacname = DNS_TSIG_HMACSHA256_NAME; #endif name = keystr; n = s; @@ -746,8 +738,7 @@ setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) { switch (dst_key_alg(dstkey)) { #ifndef PK11_MD5_DISABLE case DST_ALG_HMACMD5: - if (isc_md5_available()) - hmacname = DNS_TSIG_HMACMD5_NAME; + hmacname = DNS_TSIG_HMACMD5_NAME; break; #endif case DST_ALG_HMACSHA1: @@ -995,11 +986,11 @@ setup_system(void) { } } - if (entropy == NULL) - setup_entropy(gmctx, NULL, &entropy); + setup_entropy(gmctx, NULL, &entropy); result = isc_hash_create(gmctx, entropy, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); + isc_hash_init(); result = dns_dispatchmgr_create(gmctx, entropy, &dispatchmgr); check_result(result, "dns_dispatchmgr_create"); @@ -1660,13 +1651,12 @@ evaluate_key(char *cmdline) { return (STATUS_SYNTAX); } namestr = n + 1; - } else { - hmacname = DNS_TSIG_HMACSHA256_NAME; + } else #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) - hmacname = DNS_TSIG_HMACMD5_NAME; + hmacname = DNS_TSIG_HMACMD5_NAME; +#else + hmacname = DNS_TSIG_HMACSHA256_NAME; #endif - } isc_buffer_init(&b, namestr, strlen(namestr)); isc_buffer_add(&b, strlen(namestr)); diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook index 0434077..f8f6147 100644 --- a/bin/nsupdate/nsupdate.docbook +++ b/bin/nsupdate/nsupdate.docbook @@ -10,7 +10,7 @@ --> - + 2014-04-18 @@ -22,7 +22,7 @@ nsupdate 1 - BIND9 + BIND9 nsupdate diff --git a/bin/pkcs11/Makefile.in b/bin/pkcs11/Makefile.in index 8223d5e..df8de24 100644 --- a/bin/pkcs11/Makefile.in +++ b/bin/pkcs11/Makefile.in @@ -13,13 +13,13 @@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ -CINCLUDES = ${ISC_PKCS11_INCLUDES} +CINCLUDES = ${ISC_INCLUDES} CDEFINES = -ISCLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ @ISC_OPENSSL_LIBS@ +ISCLIBS = ../../lib/isc/libisc.@A@ @ISC_OPENSSL_LIBS@ -ISCDEPLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ DEPLIBS = ${ISCDEPLIBS} @@ -69,10 +69,7 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man8: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install:: ${TARGETS} installdirs install-man8 +install:: ${TARGETS} installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-list@EXEEXT@ \ ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-destroy@EXEEXT@ \ @@ -81,6 +78,10 @@ install:: ${TARGETS} installdirs install-man8 ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-tokens@EXEEXT@ \ ${DESTDIR}${sbindir} + ${INSTALL_DATA} ${srcdir}/pkcs11-list.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/pkcs11-destroy.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/pkcs11-keygen.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/pkcs11-tokens.8 ${DESTDIR}${mandir}/man8 uninstall:: rm -f ${DESTDIR}${mandir}/man8/pkcs11-tokens.8 diff --git a/bin/pkcs11/pkcs11-destroy.docbook b/bin/pkcs11/pkcs11-destroy.docbook index f1dd96c..ef0e3ab 100644 --- a/bin/pkcs11/pkcs11-destroy.docbook +++ b/bin/pkcs11/pkcs11-destroy.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-15 @@ -22,7 +22,7 @@ pkcs11-destroy 8 - BIND9 + BIND9 diff --git a/bin/pkcs11/pkcs11-keygen.docbook b/bin/pkcs11/pkcs11-keygen.docbook index bddbe12..99743f5 100644 --- a/bin/pkcs11/pkcs11-keygen.docbook +++ b/bin/pkcs11/pkcs11-keygen.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-15 @@ -22,7 +22,7 @@ pkcs11-keygen 8 - BIND9 + BIND9 diff --git a/bin/pkcs11/pkcs11-list.docbook b/bin/pkcs11/pkcs11-list.docbook index 3a0e386..1142687 100644 --- a/bin/pkcs11/pkcs11-list.docbook +++ b/bin/pkcs11/pkcs11-list.docbook @@ -10,7 +10,7 @@ --> - + 2009-10-05 @@ -22,7 +22,7 @@ pkcs11-list 8 - BIND9 + BIND9 diff --git a/bin/pkcs11/pkcs11-tokens.docbook b/bin/pkcs11/pkcs11-tokens.docbook index 06e52dd..dcf8748 100644 --- a/bin/pkcs11/pkcs11-tokens.docbook +++ b/bin/pkcs11/pkcs11-tokens.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-15 @@ -22,7 +22,7 @@ pkcs11-tokens 8 - BIND9 + BIND9 diff --git a/bin/python/Makefile.in b/bin/python/Makefile.in index 1ba958f..25dc838 100644 --- a/bin/python/Makefile.in +++ b/bin/python/Makefile.in @@ -47,13 +47,13 @@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 -install-man8: ${MANPAGES} - ${INSTALL_DATA} $^ ${DESTDIR}${mandir}/man8 - -install:: ${TARGETS} installdirs install-man8 +install:: ${TARGETS} installdirs ${INSTALL_SCRIPT} dnssec-checkds ${DESTDIR}${sbindir} ${INSTALL_SCRIPT} dnssec-coverage ${DESTDIR}${sbindir} ${INSTALL_SCRIPT} dnssec-keymgr ${DESTDIR}${sbindir} + ${INSTALL_DATA} ${srcdir}/dnssec-checkds.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/dnssec-coverage.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/dnssec-keymgr.8 ${DESTDIR}${mandir}/man8 if test -n "${PYTHON}" ; then \ if test -n "${DESTDIR}" ; then \ ${PYTHON} ${srcdir}/setup.py install --root=${DESTDIR} --prefix=${prefix} @PYTHON_INSTALL_LIB@ ; \ diff --git a/bin/python/dnssec-checkds.docbook b/bin/python/dnssec-checkds.docbook index fbd3a17..e04eaea 100644 --- a/bin/python/dnssec-checkds.docbook +++ b/bin/python/dnssec-checkds.docbook @@ -10,7 +10,7 @@ --> - + 2013-01-01 @@ -22,7 +22,7 @@ dnssec-checkds 8 - BIND9 + BIND9 diff --git a/bin/python/dnssec-coverage.docbook b/bin/python/dnssec-coverage.docbook index 4eef3a8..d1b7770 100644 --- a/bin/python/dnssec-coverage.docbook +++ b/bin/python/dnssec-coverage.docbook @@ -10,7 +10,7 @@ --> - + 2014-01-11 @@ -22,7 +22,7 @@ dnssec-coverage 8 - BIND9 + BIND9 diff --git a/bin/python/dnssec-keymgr.docbook b/bin/python/dnssec-keymgr.docbook index c00aff3..94bc4e0 100644 --- a/bin/python/dnssec-keymgr.docbook +++ b/bin/python/dnssec-keymgr.docbook @@ -9,7 +9,7 @@ - information regarding copyright ownership. --> - + 2016-06-03 @@ -21,7 +21,7 @@ dnssec-keymgr 8 - BIND9 + BIND9 diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index 2c21c1d..93fa2d5 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -160,8 +159,6 @@ command is one of the following:\n\ scan Scan available network interfaces for changes.\n\ secroots [view ...]\n\ Write security roots to the secroots file.\n\ - serve-stale ( yes | no | reset ) [class [view]]\n\ - Control whether stale answers are returned\n\ showzone zone [class [view]]\n\ Print a zone's configuration.\n\ sign zone [class [view]]\n\ @@ -641,7 +638,7 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, algorithmstr = cfg_obj_asstring(algorithmobj); #ifndef PK11_MD5_DISABLE - if (strcasecmp(algorithmstr, "hmac-md5") == 0 && isc_md5_available()) + if (strcasecmp(algorithmstr, "hmac-md5") == 0) algorithm = ISCCC_ALG_HMACMD5; else #endif diff --git a/bin/rndc/rndc.conf.docbook b/bin/rndc/rndc.conf.docbook index e95726d..c247cc2 100644 --- a/bin/rndc/rndc.conf.docbook +++ b/bin/rndc/rndc.conf.docbook @@ -10,7 +10,7 @@ --> - + 2013-03-14 @@ -22,7 +22,7 @@ rndc.conf 5 - BIND9 + BIND9 diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook index 21f725e..159ded9 100644 --- a/bin/rndc/rndc.docbook +++ b/bin/rndc/rndc.docbook @@ -10,7 +10,7 @@ --> - + 2014-08-15 @@ -22,7 +22,7 @@ rndc 8 - BIND9 + BIND9 @@ -690,25 +690,6 @@ - serve-stale ( on | off | reset | status) class view - - - Enable, disable, or reset the serving of stale answers - as configured in named.conf. Serving of stale answers - will remain disabled across named.conf - reloads if disabled via rndc until it is reset via rndc. - - - Status will report whether serving of stale answers is - currently enabled, disabled or not configured for a - view. If serving of stale records is configured then - the values of stale-answer-ttl and max-stale-ttl are - reported. - - - - - secroots - view ... diff --git a/bin/sdb_tools/Makefile.in b/bin/sdb_tools/Makefile.in deleted file mode 100644 index 5059a17..0000000 --- a/bin/sdb_tools/Makefile.in +++ /dev/null @@ -1,71 +0,0 @@ -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -VERSION=@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \ - ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} - -CDEFINES = -DBIND9 - -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ - ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} ${DBDRIVER_LIBS} @LIBS@ - -TARGETS = zone2ldap@EXEEXT@ zonetodb@EXEEXT@ zone2sqlite@EXEEXT@ ldap2zone@EXEEXT@ - -OBJS = zone2ldap.@O@ zonetodb.@O@ zone2sqlite.@O@ ldap2zone.@O@ - -SRCS = zone2ldap.c zonetodb.c zone2sqlite.c ldap2zone.c - -MANPAGES = zone2ldap.1 - -EXT_CFLAGS = - -@BIND9_MAKE_RULES@ - -zone2ldap@EXEEXT@: zone2ldap.@O@ ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ zone2ldap.@O@ -lldap -llber ${LIBS} - -ldap2zone@EXEEXT@: ldap2zone.@O@ ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ldap2zone.@O@ -lldap -llber ${LIBS} - -zonetodb@EXEEXT@: zonetodb.@O@ ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ zonetodb.@O@ -lpq ${LIBS} - -zone2sqlite@EXEEXT@: zone2sqlite.@O@ ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ zone2sqlite.@O@ -lsqlite3 -lssl ${LIBS} - -clean distclean manclean maintainer-clean:: - rm -f ${TARGETS} ${OBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 - -install:: ${TARGETS} installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} zone2ldap@EXEEXT@ ${DESTDIR}${sbindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} zonetodb@EXEEXT@ ${DESTDIR}${sbindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} zone2sqlite@EXEEXT@ ${DESTDIR}${sbindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} ldap2zone@EXEEXT@ ${DESTDIR}${sbindir} - ${INSTALL_DATA} ${srcdir}/zone2ldap.1 ${DESTDIR}${mandir}/man1/zone2ldap.1 diff --git a/bin/sdb_tools/ldap2zone.c b/bin/sdb_tools/ldap2zone.c deleted file mode 100644 index 80e7919..0000000 --- a/bin/sdb_tools/ldap2zone.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Stig Venaas - * $Id: ldap2zone.c,v 1.1 2007/07/24 15:18:00 atkac Exp $ - * - * 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. - */ - -#define LDAP_DEPRECATED 1 - -#include -#include -#include -#include - -#include - -struct string { - void *data; - size_t len; -}; - -struct assstack_entry { - struct string key; - struct string val; - struct assstack_entry *next; -}; - -struct assstack_entry *assstack_find(struct assstack_entry *stack, struct string *key); -void assstack_push(struct assstack_entry **stack, struct assstack_entry *item); -void assstack_insertbottom(struct assstack_entry **stack, struct assstack_entry *item); -void printsoa(struct string *soa); -void printrrs(char *defaultttl, struct assstack_entry *item); -void print_zone(char *defaultttl, struct assstack_entry *stack); -void usage(char *name); -void err(char *name, const char *msg); -int putrr(struct assstack_entry **stack, struct berval *name, char *type, char *ttl, struct berval *val); - -struct assstack_entry *assstack_find(struct assstack_entry *stack, struct string *key) { - for (; stack; stack = stack->next) - if (stack->key.len == key->len && !memcmp(stack->key.data, key->data, key->len)) - return stack; - return NULL; -} - -void assstack_push(struct assstack_entry **stack, struct assstack_entry *item) { - item->next = *stack; - *stack = item; -} - -void assstack_insertbottom(struct assstack_entry **stack, struct assstack_entry *item) { - struct assstack_entry *p; - - item->next = NULL; - if (!*stack) { - *stack = item; - return; - } - /* find end, should keep track of end somewhere */ - /* really a queue, not a stack */ - p = *stack; - while (p->next) - p = p->next; - p->next = item; -} - -void printsoa(struct string *soa) { - char *s; - size_t i; - - s = (char *)soa->data; - i = 0; - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - printf("(\n\t\t\t\t"); - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - printf("; Serialnumber\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Refresh\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Retry\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Expire\n\t\t\t\t"); - while (i < soa->len) { - putchar(s[i++]); - } - printf(" )\t; Minimum TTL\n"); -} - -void printrrs(char *defaultttl, struct assstack_entry *item) { - struct assstack_entry *stack; - char *s; - int first; - size_t i; - char *ttl, *type; - int top; - - s = (char *)item->key.data; - - if (item->key.len == 1 && *s == '@') { - top = 1; - printf("@\t"); - } else { - top = 0; - for (i = 0; i < item->key.len; i++) - putchar(s[i]); - if (item->key.len < 8) - putchar('\t'); - putchar('\t'); - } - - first = 1; - for (stack = (struct assstack_entry *) item->val.data; stack; stack = stack->next) { - ttl = (char *)stack->key.data; - s = strchr(ttl, ' '); - *s++ = '\0'; - type = s; - - if (first) - first = 0; - else - printf("\t\t"); - - if (strcmp(defaultttl, ttl)) - printf("%s", ttl); - putchar('\t'); - - if (top) { - top = 0; - printf("IN\t%s\t", type); - /* Should always be SOA here */ - if (!strcmp(type, "SOA")) { - printsoa(&stack->val); - continue; - } - } else - printf("%s\t", type); - - s = (char *)stack->val.data; - for (i = 0; i < stack->val.len; i++) - putchar(s[i]); - putchar('\n'); - } -} - -void print_zone(char *defaultttl, struct assstack_entry *stack) { - printf("$TTL %s\n", defaultttl); - for (; stack; stack = stack->next) - printrrs(defaultttl, stack); -}; - -void usage(char *name) { - fprintf(stderr, "Usage:%s zone-name LDAP-URL default-ttl [serial]\n", name); - exit(1); -}; - -void err(char *name, const char *msg) { - fprintf(stderr, "%s: %s\n", name, msg); - exit(1); -}; - -int putrr(struct assstack_entry **stack, struct berval *name, char *type, char *ttl, struct berval *val) { - struct string key; - struct assstack_entry *rr, *rrdata; - - /* Do nothing if name or value have 0 length */ - if (!name->bv_len || !val->bv_len) - return 0; - - /* see if already have an entry for this name */ - key.len = name->bv_len; - key.data = name->bv_val; - - rr = assstack_find(*stack, &key); - if (!rr) { - /* Not found, create and push new entry */ - rr = (struct assstack_entry *) malloc(sizeof(struct assstack_entry)); - if (!rr) - return -1; - rr->key.len = name->bv_len; - rr->key.data = (void *) malloc(rr->key.len); - if (!rr->key.data) { - free(rr); - return -1; - } - memcpy(rr->key.data, name->bv_val, name->bv_len); - rr->val.len = sizeof(void *); - rr->val.data = NULL; - if (name->bv_len == 1 && *(char *)name->bv_val == '@') - assstack_push(stack, rr); - else - assstack_insertbottom(stack, rr); - } - - rrdata = (struct assstack_entry *) malloc(sizeof(struct assstack_entry)); - if (!rrdata) { - free(rr->key.data); - free(rr); - return -1; - } - rrdata->key.len = strlen(type) + strlen(ttl) + 1; - rrdata->key.data = (void *) malloc(rrdata->key.len); - if (!rrdata->key.data) { - free(rrdata); - free(rr->key.data); - free(rr); - return -1; - } - sprintf((char *)rrdata->key.data, "%s %s", ttl, type); - - rrdata->val.len = val->bv_len; - rrdata->val.data = (void *) malloc(val->bv_len); - if (!rrdata->val.data) { - free(rrdata->key.data); - free(rrdata); - free(rr->key.data); - free(rr); - return -1; - } - memcpy(rrdata->val.data, val->bv_val, val->bv_len); - - if (!strcmp(type, "SOA")) - assstack_push((struct assstack_entry **) &(rr->val.data), rrdata); - else - assstack_insertbottom((struct assstack_entry **) &(rr->val.data), rrdata); - return 0; -} - -int main(int argc, char **argv) { - char *s, *hostporturl, *base = NULL; - char *ttl, *defaultttl; - LDAP *ld; - char *fltr = NULL; - LDAPMessage *res, *e; - char *a, **ttlvals, **soavals, *serial; - struct berval **vals, **names; - char type[64]; - BerElement *ptr; - int i, j, rc, msgid; - struct assstack_entry *zone = NULL; - - if (argc < 4 || argc > 5) - usage(argv[0]); - - hostporturl = argv[2]; - - if (hostporturl != strstr( hostporturl, "ldap")) - err(argv[0], "Not an LDAP URL"); - - s = strchr(hostporturl, ':'); - - if (!s || strlen(s) < 3 || s[1] != '/' || s[2] != '/') - err(argv[0], "Not an LDAP URL"); - - s = strchr(s+3, '/'); - if (s) { - *s++ = '\0'; - base = s; - s = strchr(base, '?'); - if (s) - err(argv[0], "LDAP URL can only contain host, port and base"); - } - - defaultttl = argv[3]; - - rc = ldap_initialize(&ld, hostporturl); - if (rc != LDAP_SUCCESS) - err(argv[0], "ldap_initialize() failed"); - - if (argc == 5) { - /* serial number specified, check if different from one in SOA */ - fltr = (char *)malloc(strlen(argv[1]) + strlen("(&(relativeDomainName=@)(zoneName=))") + 1); - sprintf(fltr, "(&(relativeDomainName=@)(zoneName=%s))", argv[1]); - msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - if (msgid == -1) - err(argv[0], "ldap_search() failed"); - - while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { - /* not supporting continuation references at present */ - if (rc != LDAP_RES_SEARCH_ENTRY) - err(argv[0], "ldap_result() returned cont.ref? Exiting"); - - /* only one entry per result message */ - e = ldap_first_entry(ld, res); - if (e == NULL) { - ldap_msgfree(res); - err(argv[0], "ldap_first_entry() failed"); - } - - soavals = ldap_get_values(ld, e, "SOARecord"); - if (soavals) - break; - } - - ldap_msgfree(res); - if (!soavals) { - err(argv[0], "No SOA Record found"); - } - - /* We have a SOA, compare serial numbers */ - /* Only checkinf first value, should be only one */ - s = strchr(soavals[0], ' '); - s++; - s = strchr(s, ' '); - s++; - serial = s; - s = strchr(s, ' '); - *s = '\0'; - if (!strcmp(serial, argv[4])) { - ldap_value_free(soavals); - err(argv[0], "serial numbers match"); - } - ldap_value_free(soavals); - } - - if (!fltr) - fltr = (char *)malloc(strlen(argv[1]) + strlen("(zoneName=)") + 1); - if (!fltr) - err(argv[0], "Malloc failed"); - sprintf(fltr, "(zoneName=%s)", argv[1]); - - msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - if (msgid == -1) - err(argv[0], "ldap_search() failed"); - - while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { - /* not supporting continuation references at present */ - if (rc != LDAP_RES_SEARCH_ENTRY) - err(argv[0], "ldap_result() returned cont.ref? Exiting"); - - /* only one entry per result message */ - e = ldap_first_entry(ld, res); - if (e == NULL) { - ldap_msgfree(res); - err(argv[0], "ldap_first_entry() failed"); - } - - names = ldap_get_values_len(ld, e, "relativeDomainName"); - if (!names) - continue; - - ttlvals = ldap_get_values(ld, e, "dNSTTL"); - ttl = ttlvals ? ttlvals[0] : defaultttl; - - for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) { - char *s; - - for (s = a; *s; s++) - *s = toupper(*s); - s = strstr(a, "RECORD"); - if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) { - ldap_memfree(a); - continue; - } - - strncpy(type, a, s - a); - type[s - a] = '\0'; - vals = ldap_get_values_len(ld, e, a); - if (vals) { - for (i = 0; vals[i]; i++) - for (j = 0; names[j]; j++) - if (putrr(&zone, names[j], type, ttl, vals[i])) - err(argv[0], "malloc failed"); - ldap_value_free_len(vals); - } - ldap_memfree(a); - } - - if (ptr) - ber_free(ptr, 0); - if (ttlvals) - ldap_value_free(ttlvals); - ldap_value_free_len(names); - /* free this result */ - ldap_msgfree(res); - } - - /* free final result */ - ldap_msgfree(res); - - print_zone(defaultttl, zone); - return 0; -} diff --git a/bin/sdb_tools/zone2ldap.1 b/bin/sdb_tools/zone2ldap.1 deleted file mode 100644 index 5b1fb24..0000000 --- a/bin/sdb_tools/zone2ldap.1 +++ /dev/null @@ -1,64 +0,0 @@ -.TH zone2ldap 1 "8 March 2001" -.SH NAME -zone2ldap /- Load BIND 9 Zone files into LDAP Directory -.SH SYNOPSIS -zone2ldap [-D Bind DN] [-w Bind Password] [-b Base DN] [-z Zone] [-f Zone File ] [-h Ldap Host] [-cd] [-v] -.SH DESCRIPTION -zone2ldap will parse a complete BIND 9 format DNS zone file, and load -the contents into an LDAP directory, for use with the LDAP sdb back-end. - -If the zone already exists, zone2ldap will exit successfully. If the zone does not exists, or -partially exists, zone2ldap will attempt to add all/missing zone data. - -.SS Options -.TP --b -LDAP Base DN. LDAP systems require a "base dn", which is generally considered the LDAP Directory root. -If the zone you are loading is different from the base, then you will need to tell zone2ldap what your LDAP -base is. -.TP --v -Print version information, and immediately exit. -.TP --f -Zone file. Bind 9.1 compatible zone file, from which zone information will be read. -.TP --d -Dump debug information to standard out. -.TP --w -LDAP Bind password, corresponding the the value of "-b". -.TP --h -LDAP Directory host. This is the hostname of the LDAP system you wish to store zone information on. -An LDAP server should be listening on port 389 of the target system. This may be omitted, and will default -to "localhost". -.TP --c -This will create the zone portion of the DN you are importing. For instance, if you are creating a domain.com zone, -zone2ldap should first create "dc=domain,dc=com". This is useful if you are creating multiple domains. -.TP --z -This is the name of the zone specified in the SOA record. -.SH EXAMPLES -Following are brief examples of how to import a zone file into your LDAP DIT. -.SS Loading zone domain.com, with an LDAP Base DN of dc=domain,dc=com -zone2ldap -D dc=root -w secret -h localhost -z domain.com -f domain.com.zone - -This will add Resource Records into an ALREADY EXISTING dc=domain,dc=com. The final SOA DN in this case, will be -dc=@,dc=domain,dc=com - -.SS Loading customer.com, if your LDAP Base DN is dc=provider,dc=net. -zone2ldap -D dc=root -w secret -h localhost -z customer.com -b dc=provider,dc=net -f customer.com.zone -c - -This will create dc=customer,dc=com under dc=provider,dc=net, and add all necessary Resource Records. The final -root DN to the SOA will be dc=@,dc=customer,dc=com,dc=provider,dc=net. - -.SH "SEE ALSO" -named(8) ldap(3) -http://www.venaas.no/ldap/bind-sdb/ -.SH "BUGS" -Send all bug reports to Jeff McNeil -.SH AUTHOR -Jeff McNeil - diff --git a/bin/sdb_tools/zone2ldap.c b/bin/sdb_tools/zone2ldap.c deleted file mode 100644 index 739495d..0000000 --- a/bin/sdb_tools/zone2ldap.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright (C) 2001 Jeff McNeil - * - * 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. - * - * Change Log - * - * Tue May 1 19:19:54 EDT 2001 - Jeff McNeil - * Update to objectClass code, and add_to_rr_list function - * (I need to rename that) to support the dNSZone schema, - * ditched dNSDomain2 schema support. Version 0.3-ALPHA - */ - -#define LDAP_DEPRECATED 1 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LDAP_DEPRECATED 1 - -#include - -#define DNS_OBJECT 6 -#define DNS_TOP 2 - -#define VERSION "0.4-ALPHA" - -#define NO_SPEC 0 -#define WI_SPEC 1 - -/* Global Zone Pointer */ -char *gbl_zone = NULL; - -typedef struct LDAP_INFO -{ - char *dn; - LDAPMod **attrs; - struct LDAP_INFO *next; - int attrcnt; -} -ldap_info; - -/* usage Info */ -void usage (void); - -/* Add to the ldap dit */ -void add_ldap_values (ldap_info * ldinfo); - -/* Init an ldap connection */ -void init_ldap_conn (void); - -/* Ldap error checking */ -void ldap_result_check (const char *msg, const char *dn, int err); - -/* Put a hostname into a char ** array */ -char **hostname_to_dn_list (char *hostname, char *zone, unsigned int flags); - -/* Find out how many items are in a char ** array */ -int get_attr_list_size (char **tmp); - -/* Get a DN */ -char *build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag, char *zone); - -/* Free a DN list */ -static void -free_dc_list(char **dc_list); - -/* Add to RR list */ -void add_to_rr_list (char *dn, char *name, char *type, char *data, - unsigned int ttl, unsigned int flags); - -/* Error checking */ -void isc_result_check (isc_result_t res, const char *errorstr); - -/* Generate LDIF Format files */ -void generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, - unsigned int ttl); - -/* head pointer to the list */ -ldap_info *ldap_info_base = NULL; - -ldap_info * -locate_by_dn (char *dn); -void -init_ldap_conn (); -void usage(); - -static char *argzone, *ldapbase, *binddn, *bindpw = NULL; - -/* these are needed to placate gcc4's const-ness const-ernations : */ -static char localhost[] = "localhost"; -static char *ldapsystem=&(localhost[0]); -/* dnszone schema class names: */ -static char topClass [] ="top"; -static char dNSZoneClass[] ="dNSZone"; -static char objectClass [] ="objectClass"; -static char dcObjectClass[]="dcObject"; -/* dnszone schema attribute names: */ -static char relativeDomainName[]="relativeDomainName"; -static char dNSTTL []="dNSTTL"; -static char zoneName []="zoneName"; -static char dc []="dc"; -static char sameZone []="@"; -static char dot []="."; -/* LDAPMod mod_values: */ -static char *objectClasses []= { &(topClass[0]), &(dNSZoneClass[0]), NULL }; -static char *topObjectClasses []= { &(topClass[0]), &(dcObjectClass[0]), &(dNSZoneClass[0]), NULL }; -static char *dn_buffer [64]={NULL}; -LDAP *conn; -unsigned int debug = 0; - -#ifdef DEBUG -debug = 1; -#endif - -static void -fatal(const char *msg) { - perror(msg); - if (conn != NULL) - ldap_unbind_ext_s(conn, NULL, NULL); - exit(1); -} - -int -main (int argc, char **argv) -{ - isc_mem_t *mctx = NULL; - isc_entropy_t *ectx = NULL; - isc_result_t result; - char *basedn; - ldap_info *tmp; - LDAPMod *base_attrs[5]; - LDAPMod base, dcBase, znBase, rdnBase; - isc_buffer_t buff; - char *zonefile=0L; - char fullbasedn[1024]; - char *ctmp; - char *zn, *dcp[2], *znp[2], *rdn[2]; - dns_fixedname_t fixedzone, fixedname; - dns_rdataset_t rdataset; - char **dc_list; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatasetiter_t *riter; - dns_name_t *zone, *name; - dns_db_t *db = NULL; - dns_dbiterator_t *dbit = NULL; - dns_dbnode_t *node; - extern char *optarg; - extern int optind, opterr, optopt; - int create_base = 0; - int topt, dcn, zdn, znlen; - - if (argc < 2) - { - usage (); - exit (-1); - } - - while ((topt = getopt (argc, argv, "D:Ww:b:z:f:h:?dcv")) != -1) - { - switch (topt) - { - case 'v': - printf("%s\n", VERSION); - exit(0); - case 'c': - create_base++; - break; - case 'd': - debug++; - break; - case 'D': - binddn = strdup (optarg); - if (binddn == NULL) - fatal("strdup"); - break; - case 'w': - bindpw = strdup (optarg); - if (bindpw == NULL) - fatal("strdup"); - break; - case 'W': - bindpw = getpass("Enter LDAP Password: "); - break; - case 'b': - ldapbase = strdup (optarg); - if (ldapbase == NULL) - fatal("strdup"); - break; - case 'z': - argzone = strdup (optarg); - // We wipe argzone all to hell when we parse it for the DN */ - gbl_zone = strdup(argzone); - if (argzone == NULL || gbl_zone == NULL) - fatal("strdup"); - break; - case 'f': - zonefile = strdup (optarg); - if (zonefile == NULL) - fatal("strdup"); - break; - case 'h': - ldapsystem = strdup (optarg); - if (ldapsystem == NULL) - fatal("strdup"); - break; - case '?': - default: - usage (); - exit (0); - } - } - - if ((argzone == NULL) || (zonefile == NULL)) - { - usage (); - exit (-1); - } - - if (debug) - printf ("Initializing ISC Routines, parsing zone file\n"); - - result = isc_mem_create (0, 0, &mctx); - isc_result_check (result, "isc_mem_create"); - - result = isc_entropy_create(mctx, &ectx); - isc_result_check (result, "isc_entropy_create"); - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - isc_result_check (result, "isc_hash_create"); - - isc_buffer_init (&buff, argzone, strlen (argzone)); - isc_buffer_add (&buff, strlen (argzone)); - zone = dns_fixedname_initname(&fixedzone); - result = dns_name_fromtext (zone, &buff, dns_rootname, 0, NULL); - isc_result_check (result, "dns_name_fromtext"); - - result = dns_db_create (mctx, "rbt", zone, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - isc_result_check (result, "dns_db_create"); - - result = dns_db_load (db, zonefile); - isc_result_check (result, "Check Zone Syntax: dns_db_load"); - - result = dns_db_createiterator (db, 0, &dbit); - isc_result_check (result, "dns_db_createiterator"); - - result = dns_dbiterator_first (dbit); - isc_result_check (result, "dns_dbiterator_first"); - - name = dns_fixedname_initname(&fixedname); - dns_rdataset_init (&rdataset); - dns_rdata_init (&rdata); - - while (result == ISC_R_SUCCESS) - { - node = NULL; - result = dns_dbiterator_current (dbit, &node, name); - - if (result == ISC_R_NOMORE) - break; - - isc_result_check (result, "dns_dbiterator_current"); - - riter = NULL; - result = dns_db_allrdatasets (db, node, NULL, 0, &riter); - isc_result_check (result, "dns_db_allrdatasets"); - - result = dns_rdatasetiter_first (riter); - //isc_result_check(result, "dns_rdatasetiter_first"); - - while (result == ISC_R_SUCCESS) - { - dns_rdatasetiter_current (riter, &rdataset); - result = dns_rdataset_first (&rdataset); - isc_result_check (result, "dns_rdatasetiter_current"); - - while (result == ISC_R_SUCCESS) - { - dns_rdataset_current (&rdataset, &rdata); - generate_ldap (name, &rdata, rdataset.ttl); - dns_rdata_reset (&rdata); - result = dns_rdataset_next (&rdataset); - } - dns_rdataset_disassociate (&rdataset); - result = dns_rdatasetiter_next (riter); - - } - dns_rdatasetiter_destroy (&riter); - result = dns_dbiterator_next (dbit); - - } - - /* Initialize the LDAP Connection */ - if (debug) - printf ("Initializing LDAP Connection to %s as %s\n", ldapsystem, binddn); - - init_ldap_conn (); - - if (create_base) - { - if (debug) - printf ("Creating base zone DN %s\n", argzone); - - dc_list = hostname_to_dn_list (argzone, argzone, DNS_TOP); - basedn = build_dn_from_dc_list (dc_list, 0, NO_SPEC, argzone); - if (debug) - printf ("base DN %s\n", basedn); - - for (ctmp = &basedn[strlen (basedn)], dcn=0; ctmp >= &basedn[0]; ctmp--) - { - if ((*ctmp == ',') || (ctmp == &basedn[0])) - { - base.mod_op = LDAP_MOD_ADD; - base.mod_type = objectClass; - base.mod_values = (char**)topObjectClasses; - base_attrs[0] = (void*)&base; - - dcBase.mod_op = LDAP_MOD_ADD; - dcBase.mod_type = dc; - dcp[0]=dc_list[dcn]; - dcp[1]=0L; - dcBase.mod_values=dcp; - base_attrs[1] = (void*)&dcBase; - - znBase.mod_op = LDAP_MOD_ADD; - znBase.mod_type = zoneName; - for( zdn = dcn, znlen = 0; zdn >= 0; zdn-- ) - znlen += strlen(dc_list[zdn])+1; - znp[0] = (char*)malloc(znlen+1); - znp[1] = 0L; - for( zdn = dcn, zn=znp[0]; zdn >= 0; zdn-- ) - zn+=sprintf(zn,"%s%s",dc_list[zdn], - ((zdn > 0) && (*(dc_list[zdn-1])!='.')) ? "." : "" - ); - - znBase.mod_values = znp; - base_attrs[2] = (void*)&znBase; - - rdnBase.mod_op = LDAP_MOD_ADD; - rdnBase.mod_type = relativeDomainName; - rdn[0] = strdup(sameZone); - rdn[1] = 0L; - rdnBase.mod_values = rdn; - base_attrs[3] = (void*)&rdnBase; - - dcn++; - - base.mod_values = topObjectClasses; - base_attrs[4] = NULL; - - if (ldapbase) - { - if (ctmp != &basedn[0]) - sprintf (fullbasedn, "%s,%s", ctmp + 1, ldapbase); - else - sprintf (fullbasedn, "%s,%s", ctmp, ldapbase); - - } - else - { - if (ctmp != &basedn[0]) - sprintf (fullbasedn, "%s", ctmp + 1); - else - sprintf (fullbasedn, "%s", ctmp); - } - - if( debug ) - printf("Full base dn: %s\n", fullbasedn); - - result = ldap_add_s (conn, fullbasedn, base_attrs); - ldap_result_check ("initial ldap_add_s", fullbasedn, result); - } - - } - - free_dc_list(dc_list); - } - else - { - if (debug) - printf ("Skipping zone base dn creation for %s\n", argzone); - } - - for (tmp = ldap_info_base; tmp != NULL; tmp = tmp->next) - { - - if (debug) - printf ("Adding DN: %s\n", tmp->dn); - - add_ldap_values (tmp); - } - - if (debug) - printf("Operation Complete.\n"); - - /* Cleanup */ - isc_hash_destroy(); - isc_entropy_detach(&ectx); - isc_mem_destroy(&mctx); - if (zonefile) - free(zonefile); - - return 0; -} - - -/* Check the status of an isc_result_t after any isc routines. - * I should probably rename this function, as not to cause any - * confusion with the isc* routines. Will exit on error. */ -void -isc_result_check (isc_result_t res, const char *errorstr) -{ - if (res != ISC_R_SUCCESS) - { - fprintf (stderr, " %s: %s\n", errorstr, isc_result_totext (res)); - exit (-1); - } -} - - -/* Takes DNS information, in bind data structure format, and adds textual - * zone information to the LDAP run queue. */ -void -generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, unsigned int ttl) -{ - char name[DNS_NAME_MAXTEXT + 1]; - unsigned int len; - char type[20]; - char data[2048]; - char **dc_list; - char *dn; - size_t argzone_len; - bool omit_dot; - - isc_buffer_t buff; - isc_result_t result; - - isc_buffer_init (&buff, name, sizeof (name)); - result = dns_name_totext (dnsname, true, &buff); - argzone_len = strlen(argzone); - /* If argzone is absolute, output absolute name too */ - omit_dot = (!(argzone_len > 0 && argzone[argzone_len-1] == '.')); - result = dns_name_totext (dnsname, omit_dot, &buff); - isc_result_check (result, "dns_name_totext"); - name[isc_buffer_usedlength (&buff)] = 0; - - isc_buffer_init (&buff, type, sizeof (type)); - result = dns_rdatatype_totext (rdata->type, &buff); - isc_result_check (result, "dns_rdatatype_totext"); - type[isc_buffer_usedlength (&buff)] = 0; - - isc_buffer_init (&buff, data, sizeof (data)); - result = dns_rdata_totext (rdata, NULL, &buff); - isc_result_check (result, "dns_rdata_totext"); - data[isc_buffer_usedlength (&buff)] = 0; - - dc_list = hostname_to_dn_list ((char*)name, argzone, DNS_OBJECT); - len = (get_attr_list_size (dc_list) - 2); - dn = build_dn_from_dc_list (dc_list, ttl, WI_SPEC, argzone); - - if (debug) - printf ("Adding %s (%s %s) to run queue list.\n", dn, type, data); - - add_to_rr_list (dn, dc_list[len], (char*)type, (char*)data, ttl, DNS_OBJECT); - free_dc_list(dc_list); -} - - -/* Locate an item in the Run queue linked list, by DN. Used by functions - * which add items to the run queue. - */ -ldap_info * -locate_by_dn (char *dn) -{ - ldap_info *tmp; - for (tmp = ldap_info_base; tmp != (ldap_info *) NULL; tmp = tmp->next) - { - if (!strncmp (tmp->dn, dn, strlen (dn))) - return tmp; - } - return (ldap_info *) NULL; -} - - - -/* Take textual zone data, and add to the LDAP Run queue. This works like so: - * If locate_by_dn does not return, alloc a new ldap_info structure, and then - * calloc a LDAPMod array, fill in the default "everyone needs this" information, - * including object classes and dc's. If it locate_by_dn does return, then we'll - * realloc for more LDAPMod structs, and append the new data. If an LDAPMod exists - * for the parameter we're adding, then we'll realloc the mod_values array, and - * add the new value to the existing LDAPMod. Finnaly, it assures linkage exists - * within the Run queue linked ilst*/ - -void -add_to_rr_list (char *dn, char *name, char *type, - char *data, unsigned int ttl, unsigned int flags) -{ - int i; - int x; - ldap_info *tmp; - int attrlist; - char ldap_type_buffer[128]; - char charttl[64]; - char *zn; - int znlen; - - if ((tmp = locate_by_dn (dn)) == NULL) - { - - /* There wasn't one already there, so we need to allocate a new one, - * and stick it on the list */ - - tmp = (ldap_info *) malloc (sizeof (ldap_info)); - if (tmp == (ldap_info *) NULL) - fatal("malloc"); - - tmp->dn = strdup (dn); - if (tmp->dn == NULL) - fatal("strdup"); - - tmp->attrs = (LDAPMod **) calloc (sizeof (LDAPMod *), flags); - if (tmp->attrs == (LDAPMod **) NULL) - fatal("calloc"); - - tmp->attrs[0] = (LDAPMod *) malloc (sizeof (LDAPMod)); - if (tmp->attrs[0] == (LDAPMod *) NULL) - fatal("malloc"); - tmp->attrs[0]->mod_op = LDAP_MOD_ADD; - tmp->attrs[0]->mod_type = objectClass; - - if (flags == DNS_OBJECT) - tmp->attrs[0]->mod_values = objectClasses; - else - { - tmp->attrs[0]->mod_values = (char**)topObjectClasses; - tmp->attrs[1] = NULL; - tmp->attrcnt = 2; - tmp->next = ldap_info_base; - ldap_info_base = tmp; - return; - } - - for (i = 1; i < (int)flags-1; i++) - { - tmp->attrs[i] = (LDAPMod *) malloc (sizeof (LDAPMod)); - if (tmp->attrs[i] == (LDAPMod *) NULL) - fatal("malloc"); - } - tmp->attrs[i] = NULL; - - - tmp->attrs[1]->mod_op = LDAP_MOD_ADD; - tmp->attrs[1]->mod_type = relativeDomainName; - tmp->attrs[1]->mod_values = (char **) calloc (sizeof (char *), 3); - - if (tmp->attrs[1]->mod_values == (char **)NULL) - fatal("calloc"); - - tmp->attrs[1]->mod_values[0] = strdup (name); - tmp->attrs[1]->mod_values[2] = NULL; - - if (tmp->attrs[1]->mod_values[0] == NULL) - fatal("strdup"); - - sprintf (ldap_type_buffer, "%sRecord", type); - - tmp->attrs[2]->mod_op = LDAP_MOD_ADD; - tmp->attrs[2]->mod_type = strdup (ldap_type_buffer); - tmp->attrs[2]->mod_values = (char **) calloc (sizeof (char *), 2); - - if (tmp->attrs[2]->mod_type == NULL || - tmp->attrs[2]->mod_values == (char **)NULL) - fatal("strdup/calloc"); - - tmp->attrs[2]->mod_values[0] = strdup (data); - tmp->attrs[2]->mod_values[1] = NULL; - - if (tmp->attrs[2]->mod_values[0] == NULL) - fatal("strdup"); - - tmp->attrs[3]->mod_op = LDAP_MOD_ADD; - tmp->attrs[3]->mod_type = dNSTTL; - tmp->attrs[3]->mod_values = (char **) calloc (sizeof (char *), 2); - - if (tmp->attrs[3]->mod_values == (char **)NULL) - fatal("calloc"); - - sprintf (charttl, "%u", ttl); - tmp->attrs[3]->mod_values[0] = strdup (charttl); - tmp->attrs[3]->mod_values[1] = NULL; - - if (tmp->attrs[3]->mod_values[0] == NULL) - fatal("strdup"); - - znlen=strlen(gbl_zone); - if ( gbl_zone[znlen-1] == '.' ) - { /* ldapdb MUST search by relative zone name */ - zn = (char*)malloc(znlen); - memcpy(zn, gbl_zone, znlen-1); - zn[znlen-1]='\0'; - }else - { - zn = gbl_zone; - } - - tmp->attrs[4]->mod_op = LDAP_MOD_ADD; - tmp->attrs[4]->mod_type = zoneName; - tmp->attrs[4]->mod_values = (char **)calloc(sizeof(char *), 2); - - if (tmp->attrs[4]->mod_values == (char **)NULL) - fatal("calloc"); - - tmp->attrs[4]->mod_values[0] = zn; - tmp->attrs[4]->mod_values[1] = NULL; - - tmp->attrs[5] = NULL; - tmp->attrcnt = flags; - tmp->next = ldap_info_base; - ldap_info_base = tmp; - } - else - { - - for (i = 0; tmp->attrs[i] != NULL; i++) - { - sprintf (ldap_type_buffer, "%sRecord", type); - if (!strncmp - (ldap_type_buffer, tmp->attrs[i]->mod_type, - strlen (tmp->attrs[i]->mod_type))) - { - attrlist = get_attr_list_size (tmp->attrs[i]->mod_values); - tmp->attrs[i]->mod_values = - (char **) realloc (tmp->attrs[i]->mod_values, - sizeof (char *) * (attrlist + 1)); - - if (tmp->attrs[i]->mod_values == (char **) NULL) - fatal("realloc"); - - for (x = 0; tmp->attrs[i]->mod_values[x] != NULL; x++); - - tmp->attrs[i]->mod_values[x] = strdup (data); - if (tmp->attrs[i]->mod_values[x] == NULL) - fatal("strdup"); - tmp->attrs[i]->mod_values[x + 1] = NULL; - - return; - } - } - tmp->attrs = - (LDAPMod **) realloc (tmp->attrs, - sizeof (LDAPMod) * ++(tmp->attrcnt)); - if (tmp->attrs == NULL) - fatal("realloc"); - - for (x = 0; tmp->attrs[x] != NULL; x++); - tmp->attrs[x] = (LDAPMod *) malloc (sizeof (LDAPMod)); - if (tmp->attrs[x] == NULL) - fatal("malloc"); - tmp->attrs[x]->mod_op = LDAP_MOD_ADD; - tmp->attrs[x]->mod_type = strdup (ldap_type_buffer); - tmp->attrs[x]->mod_values = (char **) calloc (sizeof (char *), 2); - - if (tmp->attrs[x]->mod_type == NULL || - tmp->attrs[x]->mod_values == (char **)NULL) - fatal("strdup/calloc"); - - tmp->attrs[x]->mod_values[0] = strdup (data); - if (tmp->attrs[x]->mod_values[0] == NULL) - fatal("strdup"); - tmp->attrs[x]->mod_values[1] = NULL; - tmp->attrs[x + 1] = NULL; - } -} - -/* Size of a mod_values list, plus the terminating NULL field. */ -int -get_attr_list_size (char **tmp) -{ - int i = 0; - char **ftmp = tmp; - while (*ftmp != NULL) - { - i++; - ftmp++; - } - return ++i; -} - - -/* take a hostname, and split it into a char ** of the dc parts, - * example, we have www.domain.com, this function will return: - * array[0] = com, array[1] = domain, array[2] = www. */ - -char ** -hostname_to_dn_list (char *hostname, char *zone, unsigned int flags) -{ - char *tmp; - int i = 0; - int j = 0; - char *hname=0L, *last=0L; - int hlen=strlen(hostname), zlen=(strlen(zone)); - -/* printf("hostname: %s zone: %s\n",hostname, zone); */ - if(flags == DNS_OBJECT) - { - if(strcmp(hostname, zone) == 0) - { - hname= strdup(hostname); - last = strdup(sameZone); - }else - { - if( (hlen < zlen) - ||( strcmp( hostname + (hlen - zlen), zone ) != 0) - ) - { - hname=(char*)malloc( hlen + zlen + 1); - if( *zone == '.' ) - sprintf(hname, "%s%s", hostname, zone); - else - sprintf(hname,"%s",zone); - }else - { - hname = strdup(hostname); - } - last = hname; - } - }else - { /* flags == DNS_TOP */ - hname = strdup(zone); - last = hname; - } - - for (tmp = strrchr (hname, '.'); tmp != (char *) 0; - tmp = strrchr (hname, '.')) - { - tmp[0] = '\0'; - if( tmp[1] != '\0' ) - { - dn_buffer[i++] = ++tmp; - }else - { /* trailing '.' ! */ - dn_buffer[i++] = dot; - if( tmp == hname ) - break; - } - } - for (j=0; j 0; x--) - { - if (flag == WI_SPEC) - { - if (x == (size - 2) && (strncmp (dc_list[x], "@", 1) == 0) && (ttl)) - snprintf (tmp, sizeof(tmp), "zoneName=%s + relativeDomainName=%s,", zone, dc_list[x]); - else if (x == (size - 2)) - snprintf(tmp, sizeof(tmp), "zoneName=%s + relativeDomainName=%s,", zone, dc_list[x]); - else - snprintf(tmp, sizeof(tmp), "dc=%s,", dc_list[x]); - } - else - { - snprintf(tmp, sizeof(tmp), "dc=%s,", dc_list[x]); - } - - - strncat (dn, tmp, sizeof (dn) - strlen (dn)); - } - - sprintf (tmp, "dc=%s", dc_list[0]); - strncat (dn, tmp, sizeof (dn) - strlen (dn)); - - fflush(NULL); - return dn; -} - -static void -free_dc_list(char **dc_list) -{ - for (; *dc_list; dc_list++) { - free(*dc_list); - *dc_list=NULL; - } -} - -/* Initialize LDAP Conn */ -void -init_ldap_conn () -{ - int result; - conn = ldap_open (ldapsystem, LDAP_PORT); - if (conn == NULL) - { - fprintf (stderr, "Error opening Ldap connection: %s\n", - strerror (errno)); - exit (-1); - } - - result = ldap_simple_bind_s (conn, binddn, bindpw); - ldap_result_check ("ldap_simple_bind_s", "LDAP Bind", result); -} - -/* Like isc_result_check, only for LDAP */ -void -ldap_result_check (const char *msg, const char *dn, int err) -{ - if ((err != LDAP_SUCCESS) && (err != LDAP_ALREADY_EXISTS)) - { - fprintf(stderr, "Error while adding %s (%s):\n%s", - dn, msg, ldap_err2string(err)); - ldap_unbind_ext_s (conn, NULL, NULL); - exit (-1); - } -} - - - -/* For running the ldap_info run queue. */ -void -add_ldap_values (ldap_info * ldinfo) -{ - int result; - char dnbuffer[1024]; - - if (ldapbase != NULL) - sprintf (dnbuffer, "%s,%s", ldinfo->dn, ldapbase); - else - sprintf (dnbuffer, "%s", ldinfo->dn); - - result = ldap_add_s (conn, dnbuffer, ldinfo->attrs); - ldap_result_check ("ldap_add_s", dnbuffer, result); - -} - - - -/* name says it all */ -void -usage () -{ - fprintf (stderr, - "zone2ldap -D [BIND DN] [-w BIND PASSWORD | -W:prompt] -b [BASE DN] -z [ZONE] -f [ZONE FILE] -h [LDAP HOST] " - "[-c Create LDAP Base structure][-d Debug Output (lots !)] \n ");} diff --git a/bin/sdb_tools/zone2sqlite.c b/bin/sdb_tools/zone2sqlite.c deleted file mode 100644 index 86d577e..0000000 --- a/bin/sdb_tools/zone2sqlite.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2007, 2016 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef UNUSED -#define UNUSED(x) (x) = (x) -#endif - -/* - * Generate an SQLite table from a zone. - */ - -typedef struct _dbinfo { - sqlite3 *db; - char *filename; - char *table; -} dbinfo_t; - -dbinfo_t dbi = { NULL, NULL, NULL }; - - -static void -closeandexit(int status) -{ - if (dbi.db) { - sqlite3_close(dbi.db); - dbi.db = NULL; - } - exit(status); -} - -static void -check_result(isc_result_t result, const char *message) -{ - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "%s: %s\n", message, - isc_result_totext(result)); - closeandexit(1); - } -} - -static isc_result_t -db_connect(dbinfo_t *dbi) -{ - if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) { - return (ISC_R_SUCCESS); - } else { - /* a connection is returned even if the open fails */ - sqlite3_close(dbi->db); - dbi->db = NULL; - return (ISC_R_FAILURE); - } -} - -static int -add_rdata_cb(void *parm, int cc, char **cv, char **cn) -{ - UNUSED(parm); - UNUSED(cc); - UNUSED(cv); - UNUSED(cn); - - return 0; -} - - -static void -addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) -{ - unsigned char namearray[DNS_NAME_MAXTEXT + 1]; - unsigned char typearray[20]; - unsigned char dataarray[2048]; - isc_buffer_t b; - isc_result_t result; - char *sql; - char *errmsg = NULL; - int res; - - isc_buffer_init(&b, namearray, sizeof(namearray) - 1); - result = dns_name_totext(name, true, &b); - check_result(result, "dns_name_totext"); - namearray[isc_buffer_usedlength(&b)] = 0; - - isc_buffer_init(&b, typearray, sizeof(typearray) - 1); - result = dns_rdatatype_totext(rdata->type, &b); - check_result(result, "dns_rdatatype_totext"); - typearray[isc_buffer_usedlength(&b)] = 0; - - isc_buffer_init(&b, dataarray, sizeof(dataarray) - 1); - result = dns_rdata_totext(rdata, NULL, &b); - check_result(result, "dns_rdata_totext"); - dataarray[isc_buffer_usedlength(&b)] = 0; - - sql = sqlite3_mprintf( - "INSERT INTO %Q (NAME, TTL, RDTYPE, RDATA)" - " VALUES ('%q', %d, '%q', '%q') ", - dbi.table, - namearray, ttl, typearray, dataarray); - printf("%s\n", sql); - res = sqlite3_exec(dbi.db, sql, add_rdata_cb, NULL, &errmsg); - sqlite3_free(sql); - - if (res != SQLITE_OK) { - fprintf(stderr, "INSERT failed: %s\n", errmsg); - closeandexit(1); - } -} - -int -main(int argc, char *argv[]) -{ - char *sql; - int res; - char *errmsg = NULL; - char *porigin, *zonefile; - dns_fixedname_t forigin, fname; - dns_name_t *origin, *name; - dns_db_t *db = NULL; - dns_dbiterator_t *dbiter; - dns_dbnode_t *node; - dns_rdatasetiter_t *rdsiter; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_mem_t *mctx = NULL; - isc_entropy_t *ectx = NULL; - isc_buffer_t b; - isc_result_t result; - - if (argc != 5) { - printf("usage: %s \n", argv[0]); - exit(1); - } - - porigin = argv[1]; - zonefile = argv[2]; - - dbi.filename = argv[3]; - dbi.table = argv[4]; - - dns_result_register(); - - result = isc_mem_create(0, 0, &mctx); - check_result(result, "isc_mem_create"); - result = isc_entropy_create(mctx, &ectx); - check_result(result, "isc_entropy_create"); - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - check_result(result, "isc_hash_create"); - - isc_buffer_init(&b, porigin, strlen(porigin)); - isc_buffer_add(&b, strlen(porigin)); - origin = dns_fixedname_initname(&forigin); - result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL); - check_result(result, "dns_name_fromtext"); - - db = NULL; - result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - check_result(result, "dns_db_create"); - - result = dns_db_load(db, zonefile); - if (result == DNS_R_SEENINCLUDE) - result = ISC_R_SUCCESS; - check_result(result, "dns_db_load"); - - printf("Connecting to '%s'\n", dbi.filename); - - if ((result = db_connect(&dbi)) != ISC_R_SUCCESS) { - fprintf(stderr, "Connection to database '%s' failed\n", - dbi.filename); - closeandexit(1); - } - - sql = sqlite3_mprintf("DROP TABLE %Q ", dbi.table); - printf("%s\n", sql); - res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); - sqlite3_free(sql); -#if 0 - if (res != SQLITE_OK) { - fprintf(stderr, "DROP TABLE %s failed: %s\n", - dbi.table, errmsg); - } -#endif - -#if 0 - sql = sqlite3_mprintf(sql, "BEGIN TRANSACTION"); - printf("%s\n", sql); - res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); - sqlite3_free(sql); - if (res != SQLITE_OK) { - fprintf(stderr, "BEGIN TRANSACTION failed: %s\n", errmsg); - closeandexit(1); - } -#endif - - sql = sqlite3_mprintf( - "CREATE TABLE %Q " - "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT) ", - dbi.table); - printf("%s\n", sql); - res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); - sqlite3_free(sql); - if (res != SQLITE_OK) { - fprintf(stderr, "CREATE TABLE %s failed: %s\n", - dbi.table, errmsg); - closeandexit(1); - } - - dbiter = NULL; - result = dns_db_createiterator(db, 0, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first"); - - name = dns_fixedname_initname(&fname); - dns_rdataset_init(&rdataset); - dns_rdata_init(&rdata); - - while (result == ISC_R_SUCCESS) { - node = NULL; - result = dns_dbiterator_current(dbiter, &node, name); - if (result == ISC_R_NOMORE) - break; - check_result(result, "dns_dbiterator_current"); - - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets"); - - result = dns_rdatasetiter_first(rdsiter); - - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&rdataset, &rdata); - addrdata(name, rdataset.ttl, &rdata); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rdataset); - } - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(dbiter); - } - -#if 0 - sql = sqlite3_mprintf(sql, "COMMIT TRANSACTION "); - printf("%s\n", sql); - res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); - sqlite3_free(sql); - if (res != SQLITE_OK) { - fprintf(stderr, "COMMIT TRANSACTION failed: %s\n", errmsg); - closeandexit(1); - } -#endif - - dns_dbiterator_destroy(&dbiter); - dns_db_detach(&db); - isc_hash_destroy(); - isc_entropy_detach(&ectx); - isc_mem_destroy(&mctx); - - closeandexit(0); - - exit(0); -} diff --git a/bin/sdb_tools/zonetodb.c b/bin/sdb_tools/zonetodb.c deleted file mode 100644 index 7d8b8db..0000000 --- a/bin/sdb_tools/zonetodb.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Generate a PostgreSQL table from a zone. - * - * This is compiled this with something like the following (assuming bind9 has - * been installed): - * - * gcc -g `isc-config.sh --cflags isc dns` -c zonetodb.c - * gcc -g -o zonetodb zonetodb.o `isc-config.sh --libs isc dns` -lpq - */ - -PGconn *conn = NULL; -char *dbname, *dbtable; -char str[10240]; - -void -closeandexit(int status); - -void -closeandexit(int status) { - if (conn != NULL) - PQfinish(conn); - exit(status); -} - -void -check_result(isc_result_t result, const char *message); - -void -check_result(isc_result_t result, const char *message) { - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "%s: %s\n", message, - isc_result_totext(result)); - closeandexit(1); - } -} - -/* - * Canonicalize a string before writing it to the database. - * "dest" must be an array of at least size 2*strlen(source) + 1. - */ -static void -quotestring(const unsigned char *source, unsigned char *dest) { - while (*source != 0) { - if (*source == '\'') - *dest++ = '\''; - else if (*source == '\\') - *dest++ = '\\'; - *dest++ = *source++; - } - *dest++ = 0; -} -void -addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata); -void -addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { - unsigned char namearray[DNS_NAME_MAXTEXT + 1]; - unsigned char canonnamearray[2 * DNS_NAME_MAXTEXT + 1]; - unsigned char typearray[20]; - unsigned char canontypearray[40]; - unsigned char dataarray[2048]; - unsigned char canondataarray[4096]; - isc_buffer_t b; - isc_result_t result; - PGresult *res; - - isc_buffer_init(&b, namearray, sizeof(namearray) - 1); - result = dns_name_totext(name, true, &b); - check_result(result, "dns_name_totext"); - namearray[isc_buffer_usedlength(&b)] = 0; - quotestring((const unsigned char *)namearray, canonnamearray); - - isc_buffer_init(&b, typearray, sizeof(typearray) - 1); - result = dns_rdatatype_totext(rdata->type, &b); - check_result(result, "dns_rdatatype_totext"); - typearray[isc_buffer_usedlength(&b)] = 0; - quotestring((const unsigned char *)typearray, canontypearray); - - isc_buffer_init(&b, dataarray, sizeof(dataarray) - 1); - result = dns_rdata_totext(rdata, NULL, &b); - check_result(result, "dns_rdata_totext"); - dataarray[isc_buffer_usedlength(&b)] = 0; - quotestring((const unsigned char *)dataarray, canondataarray); - - snprintf(str, sizeof(str), - "INSERT INTO %s (NAME, TTL, RDTYPE, RDATA)" - " VALUES ('%s', %d, '%s', '%s')", - dbtable, canonnamearray, ttl, canontypearray, canondataarray); - printf("%s\n", str); - res = PQexec(conn, str); - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "INSERT INTO command failed: %s\n", - PQresultErrorMessage(res)); - PQclear(res); - closeandexit(1); - } - PQclear(res); -} - -int -main(int argc, char **argv) { - char *porigin, *zonefile; - dns_fixedname_t forigin, fname; - dns_name_t *origin, *name; - dns_db_t *db = NULL; - dns_dbiterator_t *dbiter; - dns_dbnode_t *node; - dns_rdatasetiter_t *rdsiter; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_mem_t *mctx = NULL; - isc_entropy_t *ectx = NULL; - isc_buffer_t b; - isc_result_t result; - PGresult *res; - - if (argc != 5) { - printf("usage: %s origin file dbname dbtable\n", argv[0]); - printf("Note that dbname must be an existing database.\n"); - exit(1); - } - - porigin = argv[1]; - zonefile = argv[2]; - dbname = argv[3]; - dbtable = argv[4]; - - dns_result_register(); - - mctx = NULL; - result = isc_mem_create(0, 0, &mctx); - check_result(result, "isc_mem_create"); - - result = isc_entropy_create(mctx, &ectx); - check_result(result, "isc_entropy_create"); - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - check_result(result, "isc_hash_create"); - - isc_buffer_init(&b, porigin, strlen(porigin)); - isc_buffer_add(&b, strlen(porigin)); - origin = dns_fixedname_initname(&forigin); - result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL); - check_result(result, "dns_name_fromtext"); - - db = NULL; - result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - check_result(result, "dns_db_create"); - - result = dns_db_load(db, zonefile); - if (result == DNS_R_SEENINCLUDE) - result = ISC_R_SUCCESS; - check_result(result, "dns_db_load"); - - printf("Connecting to '%s'\n", dbname); - conn = PQsetdb(NULL, NULL, NULL, NULL, dbname); - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr, "Connection to database '%s' failed: %s\n", - dbname, PQerrorMessage(conn)); - closeandexit(1); - } - - snprintf(str, sizeof(str), - "DROP TABLE %s", dbtable); - printf("%s\n", str); - res = PQexec(conn, str); - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) - fprintf(stderr, "DROP TABLE command failed: %s\n", - PQresultErrorMessage(res)); - PQclear(res); - - snprintf(str, sizeof(str), "BEGIN"); - printf("%s\n", str); - res = PQexec(conn, str); - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "BEGIN command failed: %s\n", - PQresultErrorMessage(res)); - PQclear(res); - closeandexit(1); - } - PQclear(res); - - snprintf(str, sizeof(str), - "CREATE TABLE %s " - "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT)", - dbtable); - printf("%s\n", str); - res = PQexec(conn, str); - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "CREATE TABLE command failed: %s\n", - PQresultErrorMessage(res)); - PQclear(res); - closeandexit(1); - } - PQclear(res); - - dbiter = NULL; - result = dns_db_createiterator(db, 0, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first"); - - name = dns_fixedname_initname(&fname); - dns_rdataset_init(&rdataset); - dns_rdata_init(&rdata); - - while (result == ISC_R_SUCCESS) { - node = NULL; - result = dns_dbiterator_current(dbiter, &node, name); - if (result == ISC_R_NOMORE) - break; - check_result(result, "dns_dbiterator_current"); - - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets"); - - result = dns_rdatasetiter_first(rdsiter); - - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&rdataset, &rdata); - addrdata(name, rdataset.ttl, &rdata); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rdataset); - } - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(dbiter); - } - - snprintf(str, sizeof(str), "COMMIT TRANSACTION"); - printf("%s\n", str); - res = PQexec(conn, str); - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "COMMIT command failed: %s\n", - PQresultErrorMessage(res)); - PQclear(res); - closeandexit(1); - } - PQclear(res); - dns_dbiterator_destroy(&dbiter); - dns_db_detach(&db); - isc_hash_destroy(); - isc_entropy_detach(&ectx); - isc_mem_destroy(&mctx); - closeandexit(0); - exit(0); -} diff --git a/bin/tests/makejournal.c b/bin/tests/makejournal.c index cd54c8d..68b5e5a 100644 --- a/bin/tests/makejournal.c +++ b/bin/tests/makejournal.c @@ -102,12 +102,12 @@ main(int argc, char **argv) { CHECK(isc_mem_create(0, 0, &mctx)); CHECK(isc_entropy_create(mctx, &ectx)); - CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING)); - dst_active = true; - CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); hash_active = true; + CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING)); + dst_active = true; + CHECK(isc_log_create(mctx, &lctx, &logconfig)); isc_log_registercategories(lctx, categories); isc_log_setcontext(lctx); diff --git a/bin/tests/optional/hash_test.c b/bin/tests/optional/hash_test.c index 99cacdd..edb6be4 100644 --- a/bin/tests/optional/hash_test.c +++ b/bin/tests/optional/hash_test.c @@ -90,47 +90,43 @@ main(int argc, char **argv) { print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) { - s = "abc"; - isc_md5_init(&md5); - memmove(buffer, s, strlen(s)); - isc_md5_update(&md5, buffer, strlen(s)); - isc_md5_final(&md5, digest); - print_digest(s, "md5", digest, 4); - - /* - * The 3 HMAC-MD5 examples from RFC2104 - */ - s = "Hi There"; - memset(key, 0x0b, 16); - isc_hmacmd5_init(&hmacmd5, key, 16); - memmove(buffer, s, strlen(s)); - isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); - isc_hmacmd5_sign(&hmacmd5, digest); - print_digest(s, "hmacmd5", digest, 4); - - s = "what do ya want for nothing?"; - strlcpy((char *)key, "Jefe", sizeof(key)); - isc_hmacmd5_init(&hmacmd5, key, 4); - memmove(buffer, s, strlen(s)); - isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); - isc_hmacmd5_sign(&hmacmd5, digest); - print_digest(s, "hmacmd5", digest, 4); - - s = "\335\335\335\335\335\335\335\335\335\335" - "\335\335\335\335\335\335\335\335\335\335" - "\335\335\335\335\335\335\335\335\335\335" - "\335\335\335\335\335\335\335\335\335\335" - "\335\335\335\335\335\335\335\335\335\335"; - memset(key, 0xaa, 16); - isc_hmacmd5_init(&hmacmd5, key, 16); - memmove(buffer, s, strlen(s)); - isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); - isc_hmacmd5_sign(&hmacmd5, digest); - print_digest(s, "hmacmd5", digest, 4); - } else { - fprintf(stderr, "Skipping disabled MD5 algorithm\n"); - } + s = "abc"; + isc_md5_init(&md5); + memmove(buffer, s, strlen(s)); + isc_md5_update(&md5, buffer, strlen(s)); + isc_md5_final(&md5, digest); + print_digest(s, "md5", digest, 4); + + /* + * The 3 HMAC-MD5 examples from RFC2104 + */ + s = "Hi There"; + memset(key, 0x0b, 16); + isc_hmacmd5_init(&hmacmd5, key, 16); + memmove(buffer, s, strlen(s)); + isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); + isc_hmacmd5_sign(&hmacmd5, digest); + print_digest(s, "hmacmd5", digest, 4); + + s = "what do ya want for nothing?"; + strlcpy((char *)key, "Jefe", sizeof(key)); + isc_hmacmd5_init(&hmacmd5, key, 4); + memmove(buffer, s, strlen(s)); + isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); + isc_hmacmd5_sign(&hmacmd5, digest); + print_digest(s, "hmacmd5", digest, 4); + + s = "\335\335\335\335\335\335\335\335\335\335" + "\335\335\335\335\335\335\335\335\335\335" + "\335\335\335\335\335\335\335\335\335\335" + "\335\335\335\335\335\335\335\335\335\335" + "\335\335\335\335\335\335\335\335\335\335"; + memset(key, 0xaa, 16); + isc_hmacmd5_init(&hmacmd5, key, 16); + memmove(buffer, s, strlen(s)); + isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); + isc_hmacmd5_sign(&hmacmd5, digest); + print_digest(s, "hmacmd5", digest, 4); #endif /* diff --git a/bin/tests/system/acl/ns2/named1.conf.in b/bin/tests/system/acl/ns2/named1.conf.in index e3f8d0e..9999ada 100644 --- a/bin/tests/system/acl/ns2/named1.conf.in +++ b/bin/tests/system/acl/ns2/named1.conf.in @@ -33,12 +33,12 @@ options { }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/acl/ns2/named2.conf.in b/bin/tests/system/acl/ns2/named2.conf.in index d2d6ad3..f8ec34e 100644 --- a/bin/tests/system/acl/ns2/named2.conf.in +++ b/bin/tests/system/acl/ns2/named2.conf.in @@ -33,12 +33,12 @@ options { }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/acl/ns2/named3.conf.in b/bin/tests/system/acl/ns2/named3.conf.in index 6a00344..2acb813 100644 --- a/bin/tests/system/acl/ns2/named3.conf.in +++ b/bin/tests/system/acl/ns2/named3.conf.in @@ -33,17 +33,17 @@ options { }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key three { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/acl/ns2/named4.conf.in b/bin/tests/system/acl/ns2/named4.conf.in index 5913420..bca3ee1 100644 --- a/bin/tests/system/acl/ns2/named4.conf.in +++ b/bin/tests/system/acl/ns2/named4.conf.in @@ -33,12 +33,12 @@ options { }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/acl/ns2/named5.conf.in b/bin/tests/system/acl/ns2/named5.conf.in index 5ae8d38..9ef8171 100644 --- a/bin/tests/system/acl/ns2/named5.conf.in +++ b/bin/tests/system/acl/ns2/named5.conf.in @@ -34,12 +34,12 @@ options { }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/acl/tests.sh b/bin/tests/system/acl/tests.sh index a73a54e..2ee34a0 100644 --- a/bin/tests/system/acl/tests.sh +++ b/bin/tests/system/acl/tests.sh @@ -22,14 +22,14 @@ echo_i "testing basic ACL processing" # key "one" should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } # any other key should be fine t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } copy_setports ns2/named2.conf.in ns2/named.conf @@ -39,18 +39,18 @@ sleep 5 # prefix 10/8 should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } # any other address should work, as long as it sends key "one" t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 127.0.0.1 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 127.0.0.1 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } echo_i "testing nested ACL processing" @@ -62,31 +62,31 @@ sleep 5 # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.2 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.2 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # but only one or the other should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 127.0.0.1 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } t=`expr $t + 1` @@ -97,7 +97,7 @@ grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $tt failed" ; status=1 # and other values? right out t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:three:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 127.0.0.1 axfr -y three:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } # now we only allow 10.53.0.1 *and* key one, or 10.53.0.2 *and* key two @@ -108,31 +108,31 @@ sleep 5 # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.2 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # should succeed t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; } # should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.2 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } # should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } # should fail t=`expr $t + 1` $DIG $DIGOPTS tsigzone. \ - @10.53.0.2 -b 10.53.0.3 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t} + @10.53.0.2 -b 10.53.0.3 axfr -y one:1234abcd8765 > dig.out.${t} grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; } echo_i "testing allow-query-on ACL processing" diff --git a/bin/tests/system/allow-query/ns2/named10.conf.in b/bin/tests/system/allow-query/ns2/named10.conf.in index 3b8f853..a579f32 100644 --- a/bin/tests/system/allow-query/ns2/named10.conf.in +++ b/bin/tests/system/allow-query/ns2/named10.conf.in @@ -12,7 +12,7 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named11.conf.in b/bin/tests/system/allow-query/ns2/named11.conf.in index 997ece9..166afa1 100644 --- a/bin/tests/system/allow-query/ns2/named11.conf.in +++ b/bin/tests/system/allow-query/ns2/named11.conf.in @@ -12,12 +12,12 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234efgh8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named12.conf.in b/bin/tests/system/allow-query/ns2/named12.conf.in index a9cb65d..25271a5 100644 --- a/bin/tests/system/allow-query/ns2/named12.conf.in +++ b/bin/tests/system/allow-query/ns2/named12.conf.in @@ -12,7 +12,7 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named30.conf.in b/bin/tests/system/allow-query/ns2/named30.conf.in index f165e65..c7c8254 100644 --- a/bin/tests/system/allow-query/ns2/named30.conf.in +++ b/bin/tests/system/allow-query/ns2/named30.conf.in @@ -12,7 +12,7 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named31.conf.in b/bin/tests/system/allow-query/ns2/named31.conf.in index 4fd2035..567bbcc 100644 --- a/bin/tests/system/allow-query/ns2/named31.conf.in +++ b/bin/tests/system/allow-query/ns2/named31.conf.in @@ -12,12 +12,12 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234efgh8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named32.conf.in b/bin/tests/system/allow-query/ns2/named32.conf.in index 7b254e6..b75161f 100644 --- a/bin/tests/system/allow-query/ns2/named32.conf.in +++ b/bin/tests/system/allow-query/ns2/named32.conf.in @@ -12,7 +12,7 @@ controls { /* empty */ }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/allow-query/ns2/named40.conf.in b/bin/tests/system/allow-query/ns2/named40.conf.in index 22f5001..9e17818 100644 --- a/bin/tests/system/allow-query/ns2/named40.conf.in +++ b/bin/tests/system/allow-query/ns2/named40.conf.in @@ -16,12 +16,12 @@ acl accept { 10.53.0.2; }; acl badaccept { 10.53.0.1; }; key one { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234abcd8765"; }; key two { - algorithm hmac-sha256; + algorithm hmac-md5; secret "1234efgh8765"; }; diff --git a/bin/tests/system/allow-query/tests.sh b/bin/tests/system/allow-query/tests.sh index 95cd971..791a1a4 100644 --- a/bin/tests/system/allow-query/tests.sh +++ b/bin/tests/system/allow-query/tests.sh @@ -190,7 +190,7 @@ rndc_reload echo_i "test $n: key allowed - query allowed" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -203,7 +203,7 @@ rndc_reload echo_i "test $n: key not allowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -216,7 +216,7 @@ rndc_reload echo_i "test $n: key disallowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -349,7 +349,7 @@ rndc_reload echo_i "test $n: views key allowed - query allowed" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -362,7 +362,7 @@ rndc_reload echo_i "test $n: views key not allowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -375,7 +375,7 @@ rndc_reload echo_i "test $n: views key disallowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -508,7 +508,7 @@ status=`expr $status + $ret` n=`expr $n + 1` echo_i "test $n: zone key allowed - query allowed" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.keyallow.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.keyallow.example a > dig.out.ns2.$n || ret=1 grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.keyallow.example' dig.out.ns2.$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -518,7 +518,7 @@ status=`expr $status + $ret` n=`expr $n + 1` echo_i "test $n: zone key not allowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.keyallow.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.keyallow.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.keyallow.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -528,7 +528,7 @@ status=`expr $status + $ret` n=`expr $n + 1` echo_i "test $n: zone key disallowed - query refused" ret=0 -$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.keydisallow.example a > dig.out.ns2.$n || ret=1 +$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.keydisallow.example a > dig.out.ns2.$n || ret=1 grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 grep '^a.keydisallow.example' dig.out.ns2.$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi diff --git a/bin/tests/system/catz/ns1/named.conf.in b/bin/tests/system/catz/ns1/named.conf.in index 0ac1fa3..6856ec7 100644 --- a/bin/tests/system/catz/ns1/named.conf.in +++ b/bin/tests/system/catz/ns1/named.conf.in @@ -61,5 +61,5 @@ zone "catalog4.example" { key tsig_key. { secret "LSAnCU+Z"; - algorithm hmac-sha256; + algorithm hmac-md5; }; diff --git a/bin/tests/system/catz/ns2/named.conf.in b/bin/tests/system/catz/ns2/named.conf.in index 77b8d96..dd3a9dc 100644 --- a/bin/tests/system/catz/ns2/named.conf.in +++ b/bin/tests/system/catz/ns2/named.conf.in @@ -70,5 +70,5 @@ zone "catalog4.example" { key tsig_key. { secret "LSAnCU+Z"; - algorithm hmac-sha256; + algorithm hmac-md5; }; diff --git a/bin/tests/system/chain/prereq.sh b/bin/tests/system/chain/prereq.sh index 43385de..23bedcd 100644 --- a/bin/tests/system/chain/prereq.sh +++ b/bin/tests/system/chain/prereq.sh @@ -48,10 +48,3 @@ else echo_i "This test requires the Net::DNS::Nameserver library." >&2 exit 1 fi -if $PERL -e 'use Net::DNS::Nameserver;' 2>/dev/null -then - : -else - echo "I:This test requires the Net::DNS::Nameserver library." >&2 - exit 1 -fi diff --git a/bin/tests/system/checkconf/bad-tsig.conf b/bin/tests/system/checkconf/bad-tsig.conf index 90cd424..338dddb 100644 --- a/bin/tests/system/checkconf/bad-tsig.conf +++ b/bin/tests/system/checkconf/bad-tsig.conf @@ -11,7 +11,7 @@ /* Bad secret */ key "badtsig" { - algorithm hmac-sha256; + algorithm hmac-md5; secret "jEdD+BPKg=="; }; diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf index 1359cf3..2282f87 100644 --- a/bin/tests/system/checkconf/good.conf +++ b/bin/tests/system/checkconf/good.conf @@ -159,6 +159,6 @@ dyndb "name" "library.so" { system; }; key "mykey" { - algorithm "hmac-sha256"; + algorithm "hmac-md5"; secret "qwertyuiopasdfgh"; }; diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index 31a0f7a..a4daa22 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -127,7 +127,7 @@ PARALLELDIRS="dnssec rpzrecurse \ reclimit redirect resolver rndc rootkeysentinel rpz \ rrchecker rrl rrsetorder rsabigexponent runtime \ sfcache smartsign sortlist \ - spf serve-stale staticstub statistics statschannel stub \ + spf staticstub statistics statschannel stub \ tcp tsig tsiggss \ unknown upforwd verify views wildcard \ xfer xferquota zero zonechecks" diff --git a/bin/tests/system/digdelv/ns2/example.db b/bin/tests/system/digdelv/ns2/example.db index 359b220..b66207a 100644 --- a/bin/tests/system/digdelv/ns2/example.db +++ b/bin/tests/system/digdelv/ns2/example.db @@ -38,15 +38,12 @@ foo SSHFP 2 1 123456789abcdef67890123456789abcdef67890 ;; ;; we are not testing DNSSEC behavior, so we don't care about the semantics ;; of the following records. -dnskey 300 DNSKEY 256 3 8 ( - AwEAAaWmCoDpj2K59zcpqnmnQM7IC/XbjS6jIP7uTBR4X7p1bdQJzAeo - EnMhnpnxPp0j+20eZm4847DB2U+HuHy79Mvqd3aozTmfBJvzjKs9qyba - zY/ZHn6BDYxNJiFfjSS/VJ1KuQPDbpCzhm2hbvT5s9nSOaG0WyRk+d+R - qEca11E7ZKkmmNiGlyzMAgfmTTBwgxWBAAhvd9nU1GqD6eQ6Z63hpTc/ - KDIHnFTo7pOcZ4z5urIKUMCMcFytedETlEoR5CIWGPdQq2eIEEMfn5ld - QqdEZRHVErD9og8aluJ2s767HZb8LzjCfYgBFoT9/n48T75oZLEKtSkG - /idCeeQlaLU= - ) +dnskey 300 DNSKEY 256 3 1 ( + AQPTpWyReB/e9Ii6mVGnakS8hX2zkh/iUYAg + +Ge4noWROpTWOIBvm76zeJPWs4Zfqa1IsswD + Ix5Mqeg0zwclz59uecKsKyx5w9IhtZ8plc4R + b9VIE5x7KNHAYTvTO5d4S8M= + ) ; TTL of 3 weeks weeks 1814400 A 10.53.0.2 diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index ded5557..2109001 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -155,7 +155,7 @@ if [ -x "$DIG" ] ; then echo_i "checking dig +rrcomments works for DNSKEY($n)" ret=0 $DIG $DIGOPTS +tcp @10.53.0.3 +rrcomments DNSKEY dnskey.example > dig.out.test$n || ret=1 - grep "; ZSK; alg = RSASHA256 ; key id = 36895$" < dig.out.test$n > /dev/null || ret=1 + grep "; ZSK; alg = RSAMD5 ; key id = 30795" < dig.out.test$n > /dev/null || ret=1 check_ttl_range dig.out.test$n "DNSKEY" 300 || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -164,7 +164,7 @@ if [ -x "$DIG" ] ; then echo_i "checking dig +short +rrcomments works for DNSKEY ($n)" ret=0 $DIG $DIGOPTS +tcp @10.53.0.3 +short +rrcomments DNSKEY dnskey.example > dig.out.test$n || ret=1 - grep "; ZSK; alg = RSASHA256 ; key id = 36895$" < dig.out.test$n > /dev/null || ret=1 + grep "; ZSK; alg = RSAMD5 ; key id = 30795" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -172,7 +172,7 @@ if [ -x "$DIG" ] ; then echo_i "checking dig +short +nosplit works($n)" ret=0 $DIG $DIGOPTS +tcp @10.53.0.3 +short +nosplit DNSKEY dnskey.example > dig.out.test$n || ret=1 - grep "T9/n48T75oZLEKtSkG/idCeeQlaLU=$" < dig.out.test$n > /dev/null || ret=1 + grep "Z8plc4Rb9VIE5x7KNHAYTvTO5d4S8M=$" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -180,7 +180,7 @@ if [ -x "$DIG" ] ; then echo_i "checking dig +short +rrcomments works($n)" ret=0 $DIG $DIGOPTS +tcp @10.53.0.3 +short +rrcomments DNSKEY dnskey.example > dig.out.test$n || ret=1 - grep "aLU= ; ZSK; alg = RSASHA256 ; key id = 36895$" < dig.out.test$n > /dev/null || ret=1 + grep "S8M= ; ZSK; alg = RSAMD5 ; key id = 30795$" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -197,7 +197,7 @@ if [ -x "$DIG" ] ; then echo_i "checking dig +short +rrcomments works($n)" ret=0 $DIG $DIGOPTS +tcp @10.53.0.3 +short +rrcomments DNSKEY dnskey.example > dig.out.test$n || ret=1 - grep "aLU= ; ZSK; alg = RSASHA256 ; key id = 36895$" < dig.out.test$n > /dev/null || ret=1 + grep "S8M= ; ZSK; alg = RSAMD5 ; key id = 30795$" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -827,7 +827,7 @@ if [ -x ${DELV} ] ; then echo_i "checking delv +rrcomments works for DNSKEY($n)" ret=0 $DELV $DELVOPTS +tcp @10.53.0.3 +rrcomments DNSKEY dnskey.example > delv.out.test$n || ret=1 - grep "; ZSK; alg = RSASHA256 ; key id = 36895" < delv.out.test$n > /dev/null || ret=1 + grep "; ZSK; alg = RSAMD5 ; key id = 30795" < delv.out.test$n > /dev/null || ret=1 check_ttl_range delv.out.test$n "DNSKEY" 300 || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -836,7 +836,7 @@ if [ -x ${DELV} ] ; then echo_i "checking delv +short +rrcomments works for DNSKEY ($n)" ret=0 $DELV $DELVOPTS +tcp @10.53.0.3 +short +rrcomments DNSKEY dnskey.example > delv.out.test$n || ret=1 - grep "; ZSK; alg = RSASHA256 ; key id = 36895" < delv.out.test$n > /dev/null || ret=1 + grep "; ZSK; alg = RSAMD5 ; key id = 30795" < delv.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -844,7 +844,7 @@ if [ -x ${DELV} ] ; then echo_i "checking delv +short +rrcomments works ($n)" ret=0 $DELV $DELVOPTS +tcp @10.53.0.3 +short +rrcomments DNSKEY dnskey.example > delv.out.test$n || ret=1 - grep "aLU= ; ZSK; alg = RSASHA256 ; key id = 36895$" < delv.out.test$n > /dev/null || ret=1 + grep "S8M= ; ZSK; alg = RSAMD5 ; key id = 30795$" < delv.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -852,7 +852,7 @@ if [ -x ${DELV} ] ; then echo_i "checking delv +short +nosplit works ($n)" ret=0 $DELV $DELVOPTS +tcp @10.53.0.3 +short +nosplit DNSKEY dnskey.example > delv.out.test$n || ret=1 - grep "T9/n48T75oZLEKtSkG/idCeeQlaLU=" < delv.out.test$n > /dev/null || ret=1 + grep "Z8plc4Rb9VIE5x7KNHAYTvTO5d4S8M=" < delv.out.test$n > /dev/null || ret=1 if test `wc -l < delv.out.test$n` != 1 ; then ret=1 ; fi f=`awk '{print NF}' < delv.out.test$n` test "${f:-0}" -eq 14 || ret=1 @@ -863,7 +863,7 @@ if [ -x ${DELV} ] ; then echo_i "checking delv +short +nosplit +norrcomments works ($n)" ret=0 $DELV $DELVOPTS +tcp @10.53.0.3 +short +nosplit +norrcomments DNSKEY dnskey.example > delv.out.test$n || ret=1 - grep "T9/n48T75oZLEKtSkG/idCeeQlaLU=$" < delv.out.test$n > /dev/null || ret=1 + grep "Z8plc4Rb9VIE5x7KNHAYTvTO5d4S8M=$" < delv.out.test$n > /dev/null || ret=1 if test `wc -l < delv.out.test$n` != 1 ; then ret=1 ; fi f=`awk '{print NF}' < delv.out.test$n` test "${f:-0}" -eq 4 || ret=1 diff --git a/bin/tests/system/dlv/ns1/sign.sh b/bin/tests/system/dlv/ns1/sign.sh index 3f522d0..14ca5db 100755 --- a/bin/tests/system/dlv/ns1/sign.sh +++ b/bin/tests/system/dlv/ns1/sign.sh @@ -23,8 +23,8 @@ infile=root.db.in zonefile=root.db outfile=root.signed -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile diff --git a/bin/tests/system/dlv/ns2/sign.sh b/bin/tests/system/dlv/ns2/sign.sh index b0ab372..d870798 100755 --- a/bin/tests/system/dlv/ns2/sign.sh +++ b/bin/tests/system/dlv/ns2/sign.sh @@ -24,8 +24,8 @@ zonefile=druz.db outfile=druz.pre dlvzone=utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile diff --git a/bin/tests/system/dlv/ns6/sign.sh b/bin/tests/system/dlv/ns6/sign.sh index f20a2dd..ba39f90 100755 --- a/bin/tests/system/dlv/ns6/sign.sh +++ b/bin/tests/system/dlv/ns6/sign.sh @@ -16,15 +16,13 @@ SYSTESTDIR=dlv echo_i "dlv/ns6/sign.sh" -bits=1024 - zone=grand.child1.utld. infile=child.db.in zonefile=grand.child1.utld.db outfile=grand.child1.signed -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -38,8 +36,8 @@ zonefile=grand.child3.utld.db outfile=grand.child3.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -53,8 +51,8 @@ zonefile=grand.child4.utld.db outfile=grand.child4.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -68,8 +66,8 @@ zonefile=grand.child5.utld.db outfile=grand.child5.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -83,8 +81,8 @@ zonefile=grand.child7.utld.db outfile=grand.child7.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -98,8 +96,8 @@ zonefile=grand.child8.utld.db outfile=grand.child8.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -113,8 +111,8 @@ zonefile=grand.child9.utld.db outfile=grand.child9.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -127,8 +125,8 @@ zonefile=grand.child10.utld.db outfile=grand.child10.signed dlvzone=dlv.utld. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -140,8 +138,8 @@ infile=child.db.in zonefile=grand.child1.druz.db outfile=grand.child1.druz.signed -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -155,8 +153,8 @@ zonefile=grand.child3.druz.db outfile=grand.child3.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -170,8 +168,8 @@ zonefile=grand.child4.druz.db outfile=grand.child4.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -185,8 +183,8 @@ zonefile=grand.child5.druz.db outfile=grand.child5.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -200,8 +198,8 @@ zonefile=grand.child7.druz.db outfile=grand.child7.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -215,8 +213,8 @@ zonefile=grand.child8.druz.db outfile=grand.child8.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -230,8 +228,8 @@ zonefile=grand.child9.druz.db outfile=grand.child9.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile @@ -244,8 +242,8 @@ zonefile=grand.child10.druz.db outfile=grand.child10.druz.signed dlvzone=dlv.druz. -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b $bits -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index 29c169b..e28b3f1 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -126,8 +126,8 @@ zone=in-addr.arpa. infile=in-addr.arpa.db.in zonefile=in-addr.arpa.db -keyname1=`$KEYGEN -q -r $RANDFILE -a DSA -b 1024 -n zone $zone` -keyname2=`$KEYGEN -q -r $RANDFILE -a DSA -b 1024 -n zone $zone` +keyname1=`$KEYGEN -q -r $RANDFILE -a DSA -b 768 -n zone $zone` +keyname2=`$KEYGEN -q -r $RANDFILE -a DSA -b 768 -n zone $zone` cat $infile $keyname1.key $keyname2.key >$zonefile $SIGNER -P -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null @@ -138,7 +138,7 @@ privzone=private.secure.example privinfile=private.secure.example.db.in privzonefile=private.secure.example.db -privkeyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $privzone` +privkeyname=`$KEYGEN -q -r $RANDFILE -a RSAMD5 -b 768 -n zone $privzone` cat $privinfile $privkeyname.key >$privzonefile @@ -152,7 +152,7 @@ dlvinfile=dlv.db.in dlvzonefile=dlv.db dlvsetfile=dlvset-${privzone}${TP} -dlvkeyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $dlvzone` +dlvkeyname=`$KEYGEN -q -r $RANDFILE -a RSAMD5 -b 768 -n zone $dlvzone` cat $dlvinfile $dlvkeyname.key $dlvsetfile > $dlvzonefile diff --git a/bin/tests/system/dnssec/ns5/trusted.conf.bad b/bin/tests/system/dnssec/ns5/trusted.conf.bad index b4d848c..75cf699 100644 --- a/bin/tests/system/dnssec/ns5/trusted.conf.bad +++ b/bin/tests/system/dnssec/ns5/trusted.conf.bad @@ -10,5 +10,5 @@ */ trusted-keys { - "." 256 3 8 "AwEAAarwAdjV4gIhpBCjXVAScRFEx3co7k8smJdxrnqoGsl5NB7EZ9jRdgvCXbJn6v8y9jlNWVHvaC8ilhfhLh0A1vLWiWv4ijd/12xcnrY7xpG7Cu3YkxUxaXJ7Jdg/Iw1+9mGgXF1v4UbCIcw/3U3cxyk7OxYg+VSb5KBAQSR0upxV"; + "." 256 3 1 "AQO6Cl+slAf+iuieDim9L3kujFHQD7s/IOj03ClMOpKYcTXtK4mRpuULVfvWxDi9Ew/gj0xLnnX7z9OJHIxLI+DSrAHd8Dm0XfBEAtVtJSn70GaPZgnLMw1rk5ap2DsEoWk="; }; diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 55ec806..fa49523 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3257,8 +3257,8 @@ do alg=`expr $alg + 1` continue;; 3) size="-b 512";; - 5) size="-b 1024";; - 6) size="-b 1024";; + 5) size="-b 512";; + 6) size="-b 512";; 7) size="-b 512";; 8) size="-b 512";; 10) size="-b 1024";; diff --git a/bin/tests/system/dyndb/driver/db.c b/bin/tests/system/dyndb/driver/db.c index a77c7de..02aa6ab 100644 --- a/bin/tests/system/dyndb/driver/db.c +++ b/bin/tests/system/dyndb/driver/db.c @@ -629,8 +629,6 @@ static dns_dbmethods_t sampledb_methods = { hashsize, NULL, NULL, - NULL, - NULL, }; /* Auxiliary driver functions. */ diff --git a/bin/tests/system/feature-test.c b/bin/tests/system/feature-test.c index b08692e..5e473ab 100644 --- a/bin/tests/system/feature-test.c +++ b/bin/tests/system/feature-test.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #ifdef WIN32 @@ -48,7 +47,6 @@ usage() { fprintf(stderr, "\t--have-geoip\n"); fprintf(stderr, "\t--have-libxml2\n"); fprintf(stderr, "\t--ipv6only=no\n"); - fprintf(stderr, "\t--md5\n"); fprintf(stderr, "\t--rpz-log-qtype-qclass\n"); fprintf(stderr, "\t--rpz-nsdname\n"); fprintf(stderr, "\t--rpz-nsip\n"); @@ -196,18 +194,6 @@ main(int argc, char **argv) { #endif } - if (strcmp(argv[1], "--md5") == 0) { -#ifdef PK11_MD5_DISABLE - return (1); -#else - if (isc_md5_available()) { - return (0); - } else { - return (1); - } -#endif - } - if (strcmp(argv[1], "--rpz-nsip") == 0) { #ifdef ENABLE_RPZ_NSIP return (0); diff --git a/bin/tests/system/filter-aaaa/ns1/sign.sh b/bin/tests/system/filter-aaaa/ns1/sign.sh index 4d4a765..479f98c 100755 --- a/bin/tests/system/filter-aaaa/ns1/sign.sh +++ b/bin/tests/system/filter-aaaa/ns1/sign.sh @@ -21,8 +21,8 @@ infile=signed.db.in zonefile=signed.db.signed outfile=signed.db.signed -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile diff --git a/bin/tests/system/filter-aaaa/ns4/sign.sh b/bin/tests/system/filter-aaaa/ns4/sign.sh index 4d4a765..479f98c 100755 --- a/bin/tests/system/filter-aaaa/ns4/sign.sh +++ b/bin/tests/system/filter-aaaa/ns4/sign.sh @@ -21,8 +21,8 @@ infile=signed.db.in zonefile=signed.db.signed outfile=signed.db.signed -keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 1024 -n zone $zone 2> /dev/null` +keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -r $RANDFILE -a DSA -b 768 -n zone $zone 2> /dev/null` cat $infile $keyname1.key $keyname2.key >$zonefile diff --git a/bin/tests/system/notify/ns5/named.conf.in b/bin/tests/system/notify/ns5/named.conf.in index b802288..157ef16 100644 --- a/bin/tests/system/notify/ns5/named.conf.in +++ b/bin/tests/system/notify/ns5/named.conf.in @@ -10,17 +10,17 @@ */ key "a" { - algorithm "hmac-sha256"; + algorithm "hmac-md5"; secret "aaaaaaaaaaaaaaaaaaaa"; }; key "b" { - algorithm "hmac-sha256"; + algorithm "hmac-md5"; secret "bbbbbbbbbbbbbbbbbbbb"; }; key "c" { - algorithm "hmac-sha256"; + algorithm "hmac-md5"; secret "cccccccccccccccccccc"; }; diff --git a/bin/tests/system/notify/tests.sh b/bin/tests/system/notify/tests.sh index 916af75..f9fd3f5 100644 --- a/bin/tests/system/notify/tests.sh +++ b/bin/tests/system/notify/tests.sh @@ -212,16 +212,16 @@ ret=0 $NSUPDATE << EOF server 10.53.0.5 ${PORT} zone x21 -key hmac-sha256:a aaaaaaaaaaaaaaaaaaaa +key a aaaaaaaaaaaaaaaaaaaa update add added.x21 0 in txt "test string" send EOF for i in 1 2 3 4 5 6 7 8 9 do - $DIG $DIGOPTS added.x21. -y hmac-sha256:b:bbbbbbbbbbbbbbbbbbbb @10.53.0.5 \ + $DIG $DIGOPTS added.x21. -y b:bbbbbbbbbbbbbbbbbbbb @10.53.0.5 \ txt > dig.out.b.ns5.test$n || ret=1 - $DIG $DIGOPTS added.x21. -y hmac-sha256:c:cccccccccccccccccccc @10.53.0.5 \ + $DIG $DIGOPTS added.x21. -y c:cccccccccccccccccccc @10.53.0.5 \ txt > dig.out.c.ns5.test$n || ret=1 grep "test string" dig.out.b.ns5.test$n > /dev/null && grep "test string" dig.out.c.ns5.test$n > /dev/null && diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in index cb80269..b0ded3a 100644 --- a/bin/tests/system/nsupdate/ns1/named.conf.in +++ b/bin/tests/system/nsupdate/ns1/named.conf.in @@ -32,7 +32,7 @@ controls { }; key altkey { - algorithm hmac-sha512; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/nsupdate/ns2/named.conf.in b/bin/tests/system/nsupdate/ns2/named.conf.in index b0a94e0..e6e2382 100644 --- a/bin/tests/system/nsupdate/ns2/named.conf.in +++ b/bin/tests/system/nsupdate/ns2/named.conf.in @@ -33,7 +33,7 @@ controls { }; key altkey { - algorithm hmac-sha512; + algorithm hmac-md5; secret "1234abcd8765"; }; diff --git a/bin/tests/system/nsupdate/setup.sh b/bin/tests/system/nsupdate/setup.sh index a712b17..6fbf1d7 100644 --- a/bin/tests/system/nsupdate/setup.sh +++ b/bin/tests/system/nsupdate/setup.sh @@ -53,12 +53,7 @@ EOF $DDNSCONFGEN -q -r $RANDFILE -z example.nil > ns1/ddns.key -if $FEATURETEST --md5; then - $DDNSCONFGEN -q -r $RANDFILE -a hmac-md5 -k md5-key -z keytests.nil > ns1/md5.key -else - echo -n > ns1/md5.key -fi - +$DDNSCONFGEN -q -r $RANDFILE -a hmac-md5 -k md5-key -z keytests.nil > ns1/md5.key $DDNSCONFGEN -q -r $RANDFILE -a hmac-sha1 -k sha1-key -z keytests.nil > ns1/sha1.key $DDNSCONFGEN -q -r $RANDFILE -a hmac-sha224 -k sha224-key -z keytests.nil > ns1/sha224.key $DDNSCONFGEN -q -r $RANDFILE -a hmac-sha256 -k sha256-key -z keytests.nil > ns1/sha256.key diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 96ad95e..6b2c8f6 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -788,14 +788,7 @@ fi n=`expr $n + 1` ret=0 echo_i "check TSIG key algorithms ($n)" -if $FEATURETEST --md5 -then - ALGS="md5 sha1 sha224 sha256 sha384 sha512" -else - ALGS="sha1 sha224 sha256 sha384 sha512" - echo_i "skipping disabled md5 algorithm" -fi -for alg in $ALGS; do +for alg in md5 sha1 sha224 sha256 sha384 sha512; do $NSUPDATE -k ns1/${alg}.key < /dev/null || ret=1 server 10.53.0.1 ${PORT} update add ${alg}.keytests.nil. 600 A 10.10.10.3 @@ -803,7 +796,7 @@ send END done sleep 2 -for alg in $ALGS; do +for alg in md5 sha1 sha224 sha256 sha384 sha512; do $DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.3 > /dev/null 2>&1 || ret=1 done if [ $ret -ne 0 ]; then diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index 7a81d4e..e16ec11 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -204,7 +204,6 @@ sendqueries(isc_task_t *task, isc_event_t *event) { int main(int argc, char *argv[]) { - char *randomfile = NULL; isc_sockaddr_t bind_any; struct in_addr inaddr; isc_result_t result; @@ -223,7 +222,7 @@ main(int argc, char *argv[]) { int c; isc_commandline_errprint = false; - while ((c = isc_commandline_parse(argc, argv, "p:r:")) != -1) { + while ((c = isc_commandline_parse(argc, argv, "p:")) != -1) { switch (c) { case 'p': result = isc_parse_uint16(&port, @@ -234,9 +233,6 @@ main(int argc, char *argv[]) { exit(1); } break; - case 'r': - randomfile = isc_commandline_argument; - break; case '?': fprintf(stderr, "%s: invalid argument '%c'", argv[0], c); @@ -279,16 +275,10 @@ main(int argc, char *argv[]) { ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(ectx, true); - } -#endif - if (randomfile != NULL) - RUNCHECK(isc_entropy_createfilesource(ectx, randomfile)); + RUNCHECK(isc_entropy_createfilesource(ectx, "../random.data")); + RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); - RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); @@ -341,8 +331,8 @@ main(int argc, char *argv[]) { isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); isc_entropy_detach(&ectx); isc_log_destroy(&lctx); diff --git a/bin/tests/system/pipelined/tests.sh b/bin/tests/system/pipelined/tests.sh index 0245527..c0a99a2 100644 --- a/bin/tests/system/pipelined/tests.sh +++ b/bin/tests/system/pipelined/tests.sh @@ -19,7 +19,7 @@ status=0 echo_i "check pipelined TCP queries" ret=0 -$PIPEQUERIES -p ${PORT} -r $RANDFILE < input > raw || ret=1 +$PIPEQUERIES -p ${PORT} < input > raw || ret=1 awk '{ print $1 " " $5 }' < raw > output sort < output > output-sorted $DIFF ref output-sorted || { ret=1 ; echo_i "diff sorted failed"; } @@ -43,7 +43,7 @@ status=`expr $status + $ret` echo_i "check keep-response-order" ret=0 -$PIPEQUERIES -p ${PORT} -r $RANDFILE ++ < inputb > rawb || ret=1 +$PIPEQUERIES -p ${PORT} ++ < inputb > rawb || ret=1 awk '{ print $1 " " $5 }' < rawb > outputb $DIFF refb outputb || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi diff --git a/bin/tests/system/rndc/setup.sh b/bin/tests/system/rndc/setup.sh index 36f5114..2eb2cd5 100644 --- a/bin/tests/system/rndc/setup.sh +++ b/bin/tests/system/rndc/setup.sh @@ -35,7 +35,7 @@ make_key () { sed 's/allow { 10.53.0.4/allow { any/' >> ns4/named.conf } -$FEATURETEST --md5 && make_key 1 ${EXTRAPORT1} hmac-md5 +make_key 1 ${EXTRAPORT1} hmac-md5 make_key 2 ${EXTRAPORT2} hmac-sha1 make_key 3 ${EXTRAPORT3} hmac-sha224 make_key 4 ${EXTRAPORT4} hmac-sha256 diff --git a/bin/tests/system/rndc/tests.sh b/bin/tests/system/rndc/tests.sh index cb8934c..4e25e51 100644 --- a/bin/tests/system/rndc/tests.sh +++ b/bin/tests/system/rndc/tests.sh @@ -348,20 +348,15 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -if $FEATURETEST --md5 -then - echo_i "testing rndc with hmac-md5 ($n)" - ret=0 - $RNDC -s 10.53.0.4 -p ${EXTRAPORT1} -c ns4/key1.conf status > /dev/null 2>&1 || ret=1 - for i in 2 3 4 5 6 - do - $RNDC -s 10.53.0.4 -p ${EXTRAPORT1} -c ns4/key${i}.conf status > /dev/null 2>&1 && ret=1 - done - if [ $ret != 0 ]; then echo_i "failed"; fi - status=`expr $status + $ret` -else - echo_i "skipping rndc with hmac-md5 ($n)" -fi +echo_i "testing rndc with hmac-md5 ($n)" +ret=0 +$RNDC -s 10.53.0.4 -p ${EXTRAPORT1} -c ns4/key1.conf status > /dev/null 2>&1 || ret=1 +for i in 2 3 4 5 6 +do + $RNDC -s 10.53.0.4 -p ${EXTRAPORT1} -c ns4/key${i}.conf status > /dev/null 2>&1 && ret=1 +done +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` n=`expr $n + 1` echo_i "testing rndc with hmac-sha1 ($n)" diff --git a/bin/tests/system/rsabigexponent/bigkey.c b/bin/tests/system/rsabigexponent/bigkey.c index fa5182c..abf12ed 100644 --- a/bin/tests/system/rsabigexponent/bigkey.c +++ b/bin/tests/system/rsabigexponent/bigkey.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -184,9 +183,6 @@ main(int argc, char **argv) { CHECK(isc_mem_create(0, 0, &mctx), "isc_mem_create()"); CHECK(isc_entropy_create(mctx, &ectx), "isc_entropy_create()"); -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_entropy_usehook(ectx, true); -#endif CHECK(isc_entropy_usebestsource(ectx, &source, "../random.data", ISC_ENTROPY_KEYBOARDNO), diff --git a/bin/tests/system/serve-stale/.gitignore b/bin/tests/system/serve-stale/.gitignore deleted file mode 100644 index 2272eef..0000000 --- a/bin/tests/system/serve-stale/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/ans2/ans.pid -/ans2/ans.pl -/dig.out* -/ns1/named.conf -/ns3/named.conf -/ns3/root.bk -/rndc.out* -named.lock -named.pid -named.port -named.run diff --git a/bin/tests/system/serve-stale/ans2/ans.pl.in b/bin/tests/system/serve-stale/ans2/ans.pl.in deleted file mode 100644 index 2b39eca..0000000 --- a/bin/tests/system/serve-stale/ans2/ans.pl.in +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use strict; -use warnings; - -use IO::File; -use IO::Socket; -use Getopt::Long; -use Net::DNS; -use Time::HiRes qw(usleep nanosleep); - -my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!"; -print $pidf "$$\n" or die "cannot write pid file: $!"; -$pidf->close or die "cannot close pid file: $!"; -sub rmpid { unlink "ans.pid"; exit 1; }; - -$SIG{INT} = \&rmpid; -$SIG{TERM} = \&rmpid; - -my $send_response = 1; - -my $localaddr = "10.53.0.2"; -my $localport = @PORT@; -my $udpsock = IO::Socket::INET->new(LocalAddr => "$localaddr", - LocalPort => $localport, Proto => "udp", Reuse => 1) or die "$!"; - -# -# Delegation -# -my $SOA = "example 300 IN SOA . . 0 0 0 0 300"; -my $NS = "example 300 IN NS ns.example"; -my $A = "ns.example 300 IN A $localaddr"; -# -# Records to be TTL stretched -# -my $TXT = "data.example 1 IN TXT \"A text record with a 1 second ttl\""; -my $negSOA = "example 1 IN SOA . . 0 0 0 0 300"; - -sub reply_handler { - my ($qname, $qclass, $qtype) = @_; - my ($rcode, @ans, @auth, @add); - - print ("request: $qname/$qtype\n"); - STDOUT->flush(); - - # Control whether we send a response or not. - # We always respond to control commands. - if ($qname eq "enable" ) { - if ($qtype eq "TXT") { - $send_response = 1; - my $rr = new Net::DNS::RR("$qname 0 $qclass TXT \"$send_response\""); - push @ans, $rr; - } - $rcode = "NOERROR"; - return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); - } elsif ($qname eq "disable" ) { - if ($qtype eq "TXT") { - $send_response = 0; - my $rr = new Net::DNS::RR("$qname 0 $qclass TXT \"$send_response\""); - push @ans, $rr; - } - $rcode = "NOERROR"; - return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); - } - - # If we are not responding to queries we are done. - return if (!$send_response); - - # Construct the response and send it. - if ($qname eq "ns.example" ) { - if ($qtype eq "A") { - my $rr = new Net::DNS::RR($A); - push @ans, $rr; - } else { - my $rr = new Net::DNS::RR($SOA); - push @auth, $rr; - } - $rcode = "NOERROR"; - } elsif ($qname eq "example") { - if ($qtype eq "NS") { - my $rr = new Net::DNS::RR($NS); - push @auth, $rr; - $rr = new Net::DNS::RR($A); - push @add, $rr; - } elsif ($qtype eq "SOA") { - my $rr = new Net::DNS::RR($SOA); - push @ans, $rr; - } else { - my $rr = new Net::DNS::RR($SOA); - push @auth, $rr; - } - $rcode = "NOERROR"; - } elsif ($qname eq "nodata.example") { - my $rr = new Net::DNS::RR($negSOA); - push @auth, $rr; - $rcode = "NOERROR"; - } elsif ($qname eq "data.example") { - if ($qtype eq "TXT") { - my $rr = new Net::DNS::RR($TXT); - push @ans, $rr; - } else { - my $rr = new Net::DNS::RR($negSOA); - push @auth, $rr; - } - $rcode = "NOERROR"; - } elsif ($qname eq "nxdomain.example") { - my $rr = new Net::DNS::RR($negSOA); - push @auth, $rr; - $rcode = "NXDOMAIN"; - } else { - my $rr = new Net::DNS::RR($SOA); - push @auth, $rr; - $rcode = "NXDOMAIN"; - } - - # mark the answer as authoritive (by setting the 'aa' flag - return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); -} - -GetOptions( - 'port=i' => \$localport, -); - -my $rin; -my $rout; - -for (;;) { - $rin = ''; - vec($rin, fileno($udpsock), 1) = 1; - - select($rout = $rin, undef, undef, undef); - - if (vec($rout, fileno($udpsock), 1)) { - my ($buf, $request, $err); - $udpsock->recv($buf, 512); - - if ($Net::DNS::VERSION > 0.68) { - $request = new Net::DNS::Packet(\$buf, 0); - $@ and die $@; - } else { - my $err; - ($request, $err) = new Net::DNS::Packet(\$buf, 0); - $err and die $err; - } - - my @questions = $request->question; - my $qname = $questions[0]->qname; - my $qclass = $questions[0]->qclass; - my $qtype = $questions[0]->qtype; - my $id = $request->header->id; - - my ($rcode, $ans, $auth, $add, $headermask) = reply_handler($qname, $qclass, $qtype); - - if (!defined($rcode)) { - print " Silently ignoring query\n"; - next; - } - - my $reply = Net::DNS::Packet->new(); - $reply->header->qr(1); - $reply->header->aa(1) if $headermask->{'aa'}; - $reply->header->id($id); - $reply->header->rcode($rcode); - $reply->push("question", @questions); - $reply->push("answer", @$ans) if $ans; - $reply->push("authority", @$auth) if $auth; - $reply->push("additional", @$add) if $add; - - my $num_chars = $udpsock->send($reply->data); - print " Sent $num_chars bytes via UDP\n"; - } -} diff --git a/bin/tests/system/serve-stale/clean.sh b/bin/tests/system/serve-stale/clean.sh deleted file mode 100644 index 2397326..0000000 --- a/bin/tests/system/serve-stale/clean.sh +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -rm -f test.output -rm -f dig.out.test* -rm -f ans2/ans.pl -rm -f ns3/root.bk -rm -f rndc.out.test* -rm -f ns*/named.memstats -rm -f ns*/managed-keys.bind -rm -f ns*/named.conf -rm -f ns*/named.run diff --git a/bin/tests/system/serve-stale/ns1/named1.conf.in b/bin/tests/system/serve-stale/ns1/named1.conf.in deleted file mode 100644 index 8a75a10..0000000 --- a/bin/tests/system/serve-stale/ns1/named1.conf.in +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -key rndc_key { - secret "1234abcd8765"; - algorithm hmac-sha256; -}; - -controls { - inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { none; }; - recursion yes; - max-stale-ttl 3600; - stale-answer-ttl 1; - stale-answer-enable yes; -}; - -zone "." { - type master; - file "root.db"; -}; diff --git a/bin/tests/system/serve-stale/ns1/named2.conf.in b/bin/tests/system/serve-stale/ns1/named2.conf.in deleted file mode 100644 index 072e6ec..0000000 --- a/bin/tests/system/serve-stale/ns1/named2.conf.in +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -key rndc_key { - secret "1234abcd8765"; - algorithm hmac-sha256; -}; - -controls { - inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { none; }; - recursion yes; - max-stale-ttl 7200; - stale-answer-ttl 2; - stale-answer-enable yes; -}; - -zone "." { - type master; - file "root.db"; -}; diff --git a/bin/tests/system/serve-stale/ns1/root.db b/bin/tests/system/serve-stale/ns1/root.db deleted file mode 100644 index eb9ad3e..0000000 --- a/bin/tests/system/serve-stale/ns1/root.db +++ /dev/null @@ -1,5 +0,0 @@ -. 300 SOA . . 0 0 0 0 0 -. 300 NS ns.nil. -ns.nil. 300 A 10.53.0.1 -example. 300 NS ns.example. -ns.example. 300 A 10.53.0.2 diff --git a/bin/tests/system/serve-stale/ns3/named.conf.in b/bin/tests/system/serve-stale/ns3/named.conf.in deleted file mode 100644 index 24a3293..0000000 --- a/bin/tests/system/serve-stale/ns3/named.conf.in +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -key rndc_key { - secret "1234abcd8765"; - algorithm hmac-sha256; -}; - -controls { - inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -options { - query-source address 10.53.0.3; - notify-source 10.53.0.3; - transfer-source 10.53.0.3; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.3; }; - listen-on-v6 { none; }; - recursion yes; - // max-stale-ttl 3600; - // stale-answer-ttl 3; -}; - -zone "." { - type slave; - masters { 10.53.0.1; }; - file "root.bk"; -}; diff --git a/bin/tests/system/serve-stale/prereq.sh b/bin/tests/system/serve-stale/prereq.sh deleted file mode 100644 index a3bbef8..0000000 --- a/bin/tests/system/serve-stale/prereq.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2011, 2012, 2014, 2016 Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SYSTEMTESTTOP=.. -. $SYSTEMTESTTOP/conf.sh - -if $PERL -e 'use Net::DNS;' 2>/dev/null -then - if $PERL -e 'use Net::DNS; die if ($Net::DNS::VERSION >= 0.69 && $Net::DNS::VERSION <= 0.74);' 2>/dev/null - then - : - else - echo "I:Net::DNS versions 0.69 to 0.74 have bugs that cause this test to fail: please update." >&2 - exit 1 - fi -else - echo "I:This test requires the Net::DNS library." >&2 - exit 1 -fi -if $PERL -e 'use Net::DNS::Nameserver;' 2>/dev/null -then - : -else - echo "I:This test requires the Net::DNS::Nameserver library." >&2 - exit 1 -fi -if $PERL -e 'use Time::HiRes;' 2>/dev/null -then - : -else - echo "I:This test requires the Time::HiRes library." >&2 - exit 1 -fi diff --git a/bin/tests/system/serve-stale/setup.sh b/bin/tests/system/serve-stale/setup.sh deleted file mode 100644 index 690f43c..0000000 --- a/bin/tests/system/serve-stale/setup.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SYSTEMTESTTOP=.. -. $SYSTEMTESTTOP/conf.sh - -copy_setports ns1/named1.conf.in ns1/named.conf -copy_setports ans2/ans.pl.in ans2/ans.pl -copy_setports ns3/named.conf.in ns3/named.conf diff --git a/bin/tests/system/serve-stale/tests.sh b/bin/tests/system/serve-stale/tests.sh deleted file mode 100755 index 201c996..0000000 --- a/bin/tests/system/serve-stale/tests.sh +++ /dev/null @@ -1,536 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2000, 2001, 2004, 2007, 2009-2016 Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SYSTEMTESTTOP=.. -. $SYSTEMTESTTOP/conf.sh - -while getopts "p:c:" flag; do - case "$flag" in - p) port=$OPTARG ;; - c) controlport=$OPTARG ;; - *) exit 1 ;; - esac -done - -RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s" - -echo "RNDCCMD: ${RNDCCMD}" - -status=0 -n=0 - -#echo "I:check ans.pl server ($n)" -#$DIG -p ${PORT} @10.53.0.2 example NS -#$DIG -p ${PORT} @10.53.0.2 example SOA -#$DIG -p ${PORT} @10.53.0.2 ns.example A -#$DIG -p ${PORT} @10.53.0.2 ns.example AAAA -#$DIG -p ${PORT} @10.53.0.2 txt enable -#$DIG -p ${PORT} @10.53.0.2 txt disable -#$DIG -p ${PORT} @10.53.0.2 ns.example AAAA -#$DIG -p ${PORT} @10.53.0.2 txt enable -#$DIG -p ${PORT} @10.53.0.2 ns.example AAAA -##$DIG -p ${PORT} @10.53.0.2 data.example TXT -#$DIG -p ${PORT} @10.53.0.2 nodata.example TXT -#$DIG -p ${PORT} @10.53.0.2 nxdomain.example TXT - -n=`expr $n + 1` -echo "I:prime cache data.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:prime cache nodata.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:prime cache nxdomain.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:disable responses from authoritative server ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.2 txt disable > dig.out.test$n -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "TXT.\"0\"" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -sleep 1 - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: on (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale off' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale off || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: off (rndc) (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example (serve-stale off) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example (serve-stale off) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example (serve-stale off) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale on' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale on || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: on (rndc) (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example (serve-stale on) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example (serve-stale on) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example (serve-stale on) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale no' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale no || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: off (rndc) (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example (serve-stale no) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example (serve-stale no) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example (serve-stale no) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale yes' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale yes || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: on (rndc) (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example (serve-stale yes) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example (serve-stale yes) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example (serve-stale yes) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale off' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale off || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale reset' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale reset || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: on (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale data.example (serve-stale reset) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nodata.example (serve-stale reset) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check stale nxdomain.example (serve-stale reset) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc serve-stale off' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale off || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: off (rndc) (stale-answer-ttl=1 max-stale-ttl=3600)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:updating ns1/named.conf ($n)" -ret=0 -sed -e "s/@PORT@/${PORT}/g;s/@CONTROLPORT@/${CONTROLPORT}/g" < ns1/named2.conf.in > ns1/named.conf -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:running 'rndc reload' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 reload > rndc.out.test$n 2>&1 || ret=1 -grep "server reload successful" rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: off (rndc) (stale-answer-ttl=2 max-stale-ttl=7200)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale > rndc.out.test$n 2>&1 && ret=1 -grep "unexpected end of input" rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale unknown' ($n)" -ret=0 -$RNDCCMD 10.53.0.1 serve-stale unknown > rndc.out.test$n 2>&1 && ret=1 -grep "syntax error" rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo_i "flush cache, re-enable serve-stale and query again ($n)" -ret=0 -$RNDCCMD 10.53.0.1 flushtree example > rndc.out.test$n.1 2>&1 || ret=1 -$RNDCCMD 10.53.0.1 serve-stale on > rndc.out.test$n.2 2>&1 || ret=1 -$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -ret=0 -$DIG -p ${PORT} @10.53.0.2 txt enable > dig.out.test$n -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "TXT.\"1\"" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:prime cache data.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:prime cache nodata.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:prime cache nxdomain.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:disable responses from authoritative server ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.2 txt disable > dig.out.test$n -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "TXT.\"0\"" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -sleep 1 - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.3 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: off (stale-answer-ttl=1 max-stale-ttl=604800)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check fail of data.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check fail of nodata.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check fail of nxdomain.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$n -grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale on' ($n)" -ret=0 -$RNDCCMD 10.53.0.3 serve-stale on > rndc.out.test$n 2>&1 || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check 'rndc serve-stale status' ($n)" -ret=0 -$RNDCCMD 10.53.0.3 serve-stale status > rndc.out.test$n 2>&1 || ret=1 -grep '_default: on (rndc) (stale-answer-ttl=1 max-stale-ttl=604800)' rndc.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check data.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check nodata.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$n -grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -n=`expr $n + 1` -echo "I:check nxdomain.example (max-stale-ttl default) ($n)" -ret=0 -$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$n -grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 -grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1 -grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -echo "I:exit status: $status" -[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index 4fa77b6..85b497f 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -143,8 +142,6 @@ sendquery(isc_task_t *task, isc_event_t *event) { static char keystr[] = "0123456789ab"; isc_event_free(&event); - if (!isc_md5_available()) - CHECK("MD5 was disabled", ISC_R_NOTIMPLEMENTED); result = ISC_R_FAILURE; if (inet_pton(AF_INET, "10.53.0.1", &inaddr) != 1) @@ -206,7 +203,6 @@ sendquery(isc_task_t *task, isc_event_t *event) { int main(int argc, char *argv[]) { char *ourkeyname; - char *randomfile; isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; @@ -226,21 +222,10 @@ main(int argc, char *argv[]) { RUNCHECK(isc_app_start()); - randomfile = NULL; - if (argc < 2) { fprintf(stderr, "I:no DH key provided\n"); exit(-1); } - if (strcmp(argv[1], "-r") == 0) { - if (argc < 4) { - fprintf(stderr, "I:no DH key provided\n"); - exit(-1); - } - randomfile = argv[2]; - argv += 2; - argc -= 2; - } ourkeyname = argv[1]; if (argc >= 3) @@ -254,20 +239,14 @@ main(int argc, char *argv[]) { ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(ectx, true); - } -#endif - if (randomfile != NULL) - RUNCHECK(isc_entropy_createfilesource(ectx, randomfile)); + RUNCHECK(isc_entropy_createfilesource(ectx, "../random.data")); + RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); log = NULL; logconfig = NULL; RUNCHECK(isc_log_create(mctx, &log, &logconfig)); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); - RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); @@ -346,8 +325,8 @@ main(int argc, char *argv[]) { isc_log_destroy(&log); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index 4d4e9ff..ea7a09b 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -137,7 +136,6 @@ sendquery(isc_task_t *task, isc_event_t *event) { int main(int argc, char **argv) { char *keyname; - char *randomfile; isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; @@ -158,22 +156,10 @@ main(int argc, char **argv) { RUNCHECK(isc_app_start()); - randomfile = NULL; - if (argc < 2) { fprintf(stderr, "I:no key to delete\n"); exit(-1); } - if (strcmp(argv[1], "-r") == 0) { - if (argc < 4) { - fprintf(stderr, "I:no DH key provided\n"); - exit(-1); - } - randomfile = argv[2]; - argv += 2; - argc -= 2; - POST(argc); - } keyname = argv[1]; dns_result_register(); @@ -183,20 +169,14 @@ main(int argc, char **argv) { ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (randomfile == NULL) { - isc_entropy_usehook(ectx, true); - } -#endif - if (randomfile != NULL) - RUNCHECK(isc_entropy_createfilesource(ectx, randomfile)); + RUNCHECK(isc_entropy_createfilesource(ectx, "../random.data")); + RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); log = NULL; logconfig = NULL; RUNCHECK(isc_log_create(mctx, &log, &logconfig)); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); - RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); @@ -245,17 +225,12 @@ main(int argc, char **argv) { result = dst_key_fromnamedfile(keyname, NULL, type, mctx, &dstkey); CHECK("dst_key_fromnamedfile", result); #ifndef PK11_MD5_DISABLE - if (isc_md5_available()) { - result = dns_tsigkey_createfromkey(dst_key_name(dstkey), - DNS_TSIG_HMACMD5_NAME, - dstkey, true, NULL, 0, 0, - mctx, ring, &tsigkey); - dst_key_free(&dstkey); - CHECK("dns_tsigkey_createfromkey", result); - } else { - dst_key_free(&dstkey); - CHECK("MD5 was disabled", ISC_R_NOTIMPLEMENTED); - } + result = dns_tsigkey_createfromkey(dst_key_name(dstkey), + DNS_TSIG_HMACMD5_NAME, + dstkey, true, NULL, 0, 0, + mctx, ring, &tsigkey); + dst_key_free(&dstkey); + CHECK("dns_tsigkey_createfromkey", result); #else dst_key_free(&dstkey); CHECK("MD5 was disabled", ISC_R_NOTIMPLEMENTED); @@ -284,8 +259,8 @@ main(int argc, char **argv) { isc_log_destroy(&log); - isc_hash_destroy(); dst_lib_destroy(); + isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); diff --git a/bin/tests/system/tkey/tests.sh b/bin/tests/system/tkey/tests.sh index bcd60a6..b265156 100644 --- a/bin/tests/system/tkey/tests.sh +++ b/bin/tests/system/tkey/tests.sh @@ -33,7 +33,7 @@ for owner in . foo.example. do echo_i "creating new key using owner name \"$owner\" ($n)" ret=0 - keyname=`$KEYCREATE -r $RANDFILE $dhkeyname $owner` || ret=1 + keyname=`$KEYCREATE $dhkeyname $owner` || ret=1 if [ $ret != 0 ]; then echo_i "failed" status=$((status+ret)) @@ -57,7 +57,7 @@ do echo_i "deleting new key ($n)" ret=0 - $KEYDELETE -r $RANDFILE $keyname || ret=1 + $KEYDELETE $keyname || ret=1 if [ $ret != 0 ]; then echo_i "failed" fi @@ -79,7 +79,7 @@ done echo_i "creating new key using owner name bar.example. ($n)" ret=0 -keyname=`$KEYCREATE -r $RANDFILE $dhkeyname bar.example.` || ret=1 +keyname=`$KEYCREATE $dhkeyname bar.example.` || ret=1 if [ $ret != 0 ]; then echo_i "failed" status=$((status+ret)) @@ -124,7 +124,7 @@ n=$((n+1)) echo_i "recreating the bar.example. key ($n)" ret=0 -keyname=`$KEYCREATE -r $RANDFILE $dhkeyname bar.example.` || ret=1 +keyname=`$KEYCREATE $dhkeyname bar.example.` || ret=1 if [ $ret != 0 ]; then echo_i "failed" status=$((status+ret)) diff --git a/bin/tests/system/tsig/ns1/named.conf.in b/bin/tests/system/tsig/ns1/named.conf.in index 958d9fb..4905ffd 100644 --- a/bin/tests/system/tsig/ns1/named.conf.in +++ b/bin/tests/system/tsig/ns1/named.conf.in @@ -21,7 +21,10 @@ options { notify no; }; -# md5 key appended by setup.sh at the end +key "md5" { + secret "97rnFx24Tfna4mHPfgnerA=="; + algorithm hmac-md5; +}; key "sha1" { secret "FrSt77yPTFx6hTs4i2tKLB9LmE0="; @@ -48,7 +51,10 @@ key "sha512" { algorithm hmac-sha512; }; -# md5-trunc key appended by setup.sh at the end +key "md5-trunc" { + secret "97rnFx24Tfna4mHPfgnerA=="; + algorithm hmac-md5-80; +}; key "sha1-trunc" { secret "FrSt77yPTFx6hTs4i2tKLB9LmE0="; diff --git a/bin/tests/system/tsig/setup.sh b/bin/tests/system/tsig/setup.sh index bfcf4a6..f42aa79 100644 --- a/bin/tests/system/tsig/setup.sh +++ b/bin/tests/system/tsig/setup.sh @@ -15,8 +15,3 @@ SYSTEMTESTTOP=.. copy_setports ns1/named.conf.in ns1/named.conf test -r $RANDFILE || $GENRANDOM $RANDOMSIZE $RANDFILE - -if $FEATURETEST --md5 -then - cat ns1/rndc5.conf.in >> ns1/named.conf -fi diff --git a/bin/tests/system/tsig/tests.sh b/bin/tests/system/tsig/tests.sh index 327fa50..e0c2903 100644 --- a/bin/tests/system/tsig/tests.sh +++ b/bin/tests/system/tsig/tests.sh @@ -26,25 +26,20 @@ sha512="jI/Pa4qRu96t76Pns5Z/Ndxbn3QCkwcxLOgt9vgvnJw5wqTRvNyk3FtD6yIMd1dWVlqZ+Y4f status=0 -if $FEATURETEST --md5 -then - echo_i "fetching using hmac-md5 (old form)" - ret=0 - $DIG $DIGOPTS example.nil. -y "md5:$md5" @10.53.0.1 soa > dig.out.md5.old || ret=1 - grep -i "md5.*TSIG.*NOERROR" dig.out.md5.old > /dev/null || ret=1 - if [ $ret -eq 1 ] ; then - echo_i "failed"; status=1 - fi +echo_i "fetching using hmac-md5 (old form)" +ret=0 +$DIG $DIGOPTS example.nil. -y "md5:$md5" @10.53.0.1 soa > dig.out.md5.old || ret=1 +grep -i "md5.*TSIG.*NOERROR" dig.out.md5.old > /dev/null || ret=1 +if [ $ret -eq 1 ] ; then + echo_i "failed"; status=1 +fi - echo_i "fetching using hmac-md5 (new form)" - ret=0 - $DIG $DIGOPTS example.nil. -y "hmac-md5:md5:$md5" @10.53.0.1 soa > dig.out.md5.new || ret=1 - grep -i "md5.*TSIG.*NOERROR" dig.out.md5.new > /dev/null || ret=1 - if [ $ret -eq 1 ] ; then - echo_i "failed"; status=1 - fi -else - echo_i "skipping using hmac-md5" +echo_i "fetching using hmac-md5 (new form)" +ret=0 +$DIG $DIGOPTS example.nil. -y "hmac-md5:md5:$md5" @10.53.0.1 soa > dig.out.md5.new || ret=1 +grep -i "md5.*TSIG.*NOERROR" dig.out.md5.new > /dev/null || ret=1 +if [ $ret -eq 1 ] ; then + echo_i "failed"; status=1 fi echo_i "fetching using hmac-sha1" @@ -92,17 +87,12 @@ fi # Truncated TSIG # # -if $FEATURETEST --md5 -then - echo_i "fetching using hmac-md5 (trunc)" - ret=0 - $DIG $DIGOPTS example.nil. -y "hmac-md5-80:md5-trunc:$md5" @10.53.0.1 soa > dig.out.md5.trunc || ret=1 - grep -i "md5-trunc.*TSIG.*NOERROR" dig.out.md5.trunc > /dev/null || ret=1 - if [ $ret -eq 1 ] ; then - echo_i "failed"; status=1 - fi -else - echo_i "skipping using hmac-md5 (trunc)" +echo_i "fetching using hmac-md5 (trunc)" +ret=0 +$DIG $DIGOPTS example.nil. -y "hmac-md5-80:md5-trunc:$md5" @10.53.0.1 soa > dig.out.md5.trunc || ret=1 +grep -i "md5-trunc.*TSIG.*NOERROR" dig.out.md5.trunc > /dev/null || ret=1 +if [ $ret -eq 1 ] ; then + echo_i "failed"; status=1 fi echo_i "fetching using hmac-sha1 (trunc)" @@ -151,17 +141,12 @@ fi # Check for bad truncation. # # -if $FEATURETEST --md5 -then - echo_i "fetching using hmac-md5-80 (BADTRUNC)" - ret=0 - $DIG $DIGOPTS example.nil. -y "hmac-md5-80:md5:$md5" @10.53.0.1 soa > dig.out.md5-80 || ret=1 - grep -i "md5.*TSIG.*BADTRUNC" dig.out.md5-80 > /dev/null || ret=1 - if [ $ret -eq 1 ] ; then - echo_i "failed"; status=1 - fi -else - echo_i "skipping using hmac-md5-80 (BADTRUNC)" +echo_i "fetching using hmac-md5-80 (BADTRUNC)" +ret=0 +$DIG $DIGOPTS example.nil. -y "hmac-md5-80:md5:$md5" @10.53.0.1 soa > dig.out.md5-80 || ret=1 +grep -i "md5.*TSIG.*BADTRUNC" dig.out.md5-80 > /dev/null || ret=1 +if [ $ret -eq 1 ] ; then + echo_i "failed"; status=1 fi echo_i "fetching using hmac-sha1-80 (BADTRUNC)" diff --git a/bin/tests/system/tsiggss/setup.sh b/bin/tests/system/tsiggss/setup.sh index 09da5f9..f04c907 100644 --- a/bin/tests/system/tsiggss/setup.sh +++ b/bin/tests/system/tsiggss/setup.sh @@ -16,5 +16,5 @@ test -r $RANDFILE || $GENRANDOM $RANDOMSIZE $RANDFILE copy_setports ns1/named.conf.in ns1/named.conf -key=`$KEYGEN -Cq -K ns1 -a DSA -b 1024 -r $RANDFILE -n HOST -T KEY key.example.nil.` +key=`$KEYGEN -Cq -K ns1 -a DSA -b 512 -r $RANDFILE -n HOST -T KEY key.example.nil.` cat ns1/example.nil.db.in ns1/${key}.key > ns1/example.nil.db diff --git a/bin/tests/system/upforwd/ns1/named.conf.in b/bin/tests/system/upforwd/ns1/named.conf.in index 238f52a..4ddd7a4 100644 --- a/bin/tests/system/upforwd/ns1/named.conf.in +++ b/bin/tests/system/upforwd/ns1/named.conf.in @@ -10,7 +10,7 @@ */ key "update.example." { - algorithm "hmac-sha256"; + algorithm "hmac-md5"; secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; }; diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh index f4c3216..1cf8d3b 100644 --- a/bin/tests/system/upforwd/tests.sh +++ b/bin/tests/system/upforwd/tests.sh @@ -68,7 +68,7 @@ if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "updating zone (signed) ($n)" ret=0 -$NSUPDATE -y hmac-sha256:update.example:c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K -- - < - + 2009-03-03 @@ -21,7 +21,7 @@ arpaname 1 - BIND9 + BIND9 diff --git a/bin/tools/dnstap-read.docbook b/bin/tools/dnstap-read.docbook index 10e6821..6a56a17 100644 --- a/bin/tools/dnstap-read.docbook +++ b/bin/tools/dnstap-read.docbook @@ -10,7 +10,7 @@ --> - + 2015-09-13 @@ -22,7 +22,7 @@ dnstap-read 1 - BIND9 + BIND9 diff --git a/bin/tools/genrandom.docbook b/bin/tools/genrandom.docbook index 04fa0bb..e6646a3 100644 --- a/bin/tools/genrandom.docbook +++ b/bin/tools/genrandom.docbook @@ -10,7 +10,7 @@ --> - + 2011-08-08 @@ -22,7 +22,7 @@ genrandom 8 - BIND9 + BIND9 diff --git a/bin/tools/isc-hmac-fixup.docbook b/bin/tools/isc-hmac-fixup.docbook index cfe3af5..1979425 100644 --- a/bin/tools/isc-hmac-fixup.docbook +++ b/bin/tools/isc-hmac-fixup.docbook @@ -10,7 +10,7 @@ --> - + 2013-04-28 @@ -22,7 +22,7 @@ isc-hmac-fixup 8 - BIND9 + BIND9 diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index fb34aa0..26fa609 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -2005,11 +2005,12 @@ main(int argc, char *argv[]) { ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); - RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); RUNCHECK(isc_entropy_getdata(ectx, cookie_secret, sizeof(cookie_secret), NULL, 0)); + RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); + ISC_LIST_INIT(queries); parse_args(false, argc, argv); if (server == NULL) diff --git a/bin/tools/mdig.docbook b/bin/tools/mdig.docbook index 26d887d..90f5b8d 100644 --- a/bin/tools/mdig.docbook +++ b/bin/tools/mdig.docbook @@ -12,7 +12,7 @@ --> - + 2015-01-05 @@ -23,7 +23,7 @@ mdig 1 - BIND9 + BIND9 mdig diff --git a/bin/tools/named-journalprint.docbook b/bin/tools/named-journalprint.docbook index d9179c4..798755a 100644 --- a/bin/tools/named-journalprint.docbook +++ b/bin/tools/named-journalprint.docbook @@ -10,7 +10,7 @@ --> - + 2009-12-04 @@ -22,7 +22,7 @@ named-journalprint 8 - BIND9 + BIND9 diff --git a/bin/tools/named-nzd2nzf.docbook b/bin/tools/named-nzd2nzf.docbook index b42f10f..6e778d4 100644 --- a/bin/tools/named-nzd2nzf.docbook +++ b/bin/tools/named-nzd2nzf.docbook @@ -12,7 +12,7 @@ - information regarding copyright ownership. --> - + May 5, 2016 @@ -20,7 +20,7 @@ named-nzd2nzf 8 - BIND9 + BIND9 diff --git a/bin/tools/named-rrchecker.docbook b/bin/tools/named-rrchecker.docbook index 0a803d2..979d673 100644 --- a/bin/tools/named-rrchecker.docbook +++ b/bin/tools/named-rrchecker.docbook @@ -10,7 +10,7 @@ --> - + 2013-11-12 @@ -21,7 +21,7 @@ named-rrchecker 1 - BIND9 + BIND9 named-rrchecker diff --git a/bin/tools/nsec3hash.docbook b/bin/tools/nsec3hash.docbook index b913ae6..2061b1a 100644 --- a/bin/tools/nsec3hash.docbook +++ b/bin/tools/nsec3hash.docbook @@ -10,7 +10,7 @@ --> - + 2009-03-02 @@ -22,7 +22,7 @@ nsec3hash 8 - BIND9 + BIND9 diff --git a/config.h.in b/config.h.in index 1efe70e..7ba5132 100644 --- a/config.h.in +++ b/config.h.in @@ -597,7 +597,7 @@ int sigwait(const unsigned int *set, int *sig); #undef PREFER_GOSTASN1 /* The size of `void *', as computed by sizeof. */ -/* #undef SIZEOF_VOID_P */ +#undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/configure b/configure index d5ffc87..0faca65 100755 --- a/configure +++ b/configure @@ -640,7 +640,6 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS -LIBDIR_SUFFIX BUILD_LIBS BUILD_LDFLAGS BUILD_CPPFLAGS @@ -824,7 +823,6 @@ LIBXML2_CFLAGS NZDTARGETS NZDSRCS NZD_TOOLS -ISC_PLATFORM_CRYPTORANDOM PKCS11_TEST PKCS11_ED25519 PKCS11_GOST @@ -1049,7 +1047,6 @@ with_eddsa with_aes enable_openssl_hash with_cc_alg -enable_crypto_rand with_lmdb with_libxml2 with_libjson @@ -1752,7 +1749,6 @@ Optional Features: --enable-threads enable multithreading --enable-native-pkcs11 use native PKCS11 for all crypto [default=no] --enable-openssl-hash use OpenSSL for hash functions [default=no] - --enable-crypto-rand use the crypto provider for random [default=yes] --enable-largefile 64-bit file support --enable-backtrace log stack backtrace on abort [default=yes] --enable-symtable use internal symbol table for backtrace @@ -17209,7 +17205,6 @@ case "$use_openssl" in $as_echo "disabled because of native PKCS11" >&6; } DST_OPENSSL_INC="" CRYPTO="-DPKCS11CRYPTO" - CRYPTOLIB="pkcs11" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -17224,7 +17219,6 @@ $as_echo "disabled because of native PKCS11" >&6; } $as_echo "no" >&6; } DST_OPENSSL_INC="" CRYPTO="" - CRYPTOLIB="" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -17237,7 +17231,6 @@ $as_echo "no" >&6; } auto) DST_OPENSSL_INC="" CRYPTO="" - CRYPTOLIB="" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -17247,7 +17240,7 @@ $as_echo "no" >&6; } OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" as_fn_error $? "OpenSSL was not found in any of $openssldirs; use --with-openssl=/path -If you do not want OpenSSL, use --without-openssl" "$LINENO" 5 +If you don't want OpenSSL, use --without-openssl" "$LINENO" 5 ;; *) if test "yes" = "$want_native_pkcs11" @@ -17278,7 +17271,6 @@ $as_echo "not found" >&6; } as_fn_error $? "\"$use_openssl/include/openssl/opensslv.h\" not found" "$LINENO" 5 fi CRYPTO='-DOPENSSL' - CRYPTOLIB="openssl" if test "/usr" = "$use_openssl" then DST_OPENSSL_INC="" @@ -17905,6 +17897,8 @@ fi # Use OpenSSL for hash functions # +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for using OpenSSL for hash functions" >&5 +$as_echo_n "checking for using OpenSSL for hash functions... " >&6; } ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH" case $want_openssl_hash in yes) @@ -18280,86 +18274,6 @@ if test "rt" = "$have_clock_gt"; then fi # -# Use the crypto provider (OpenSSL/PKCS#11) for random functions -# - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for using the crypto library (vs. builtin) for random functions" >&5 -$as_echo_n "checking for using the crypto library (vs. builtin) for random functions... " >&6; } -# Check whether --enable-crypto-rand was given. -if test "${enable_crypto_rand+set}" = set; then : - enableval=$enable_crypto_rand; want_crypto_rand="$enableval" -else - want_crypto_rand="auto" -fi - -if test "$want_crypto_rand" = "auto" -then - case "$CRYPTOLIB" in - "") - want_crypto_rand="no" - ;; - pkcs11) - want_crypto_rand="yes" - ;; - openssl) - saved_cflags="$CFLAGS" - saved_libs="$LIBS" - CFLAGS="$CFLAGS $DST_OPENSSL_INC" - LIBS="$LIBS $DST_OPENSSL_LIBS" - if test "$cross_compiling" = yes; then : - want_crypto_rand="yes" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include - -unsigned char buf[128]; - -int main() -{ - if (RAND_bytes(buf, 128) != 1) - return (1); - return (0); -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - want_crypto_rand="yes" -else - want_crypto_rand="no" -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - CFLAGS="$saved_cflags" - LIBS="$saved_libs" - ;; - *) - as_fn_error $? "Unknown crypto library define $CRYPTOLIB" "$LINENO" 5 - ;; - esac -fi -case $want_crypto_rand in - yes) - if test "$CRYPTOLIB" = "" - then - as_fn_error $? "No crypto library for random functions" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$CRYPTOLIB\"" >&5 -$as_echo "\"$CRYPTOLIB\"" >&6; } - ISC_PLATFORM_CRYPTORANDOM="#define ISC_PLATFORM_CRYPTORANDOM \"$CRYPTOLIB\"" - ;; - no) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ISC_PLATFORM_CRYPTORANDOM="#undef ISC_PLATFORM_CRYPTORANDOM" - ;; -esac - - -# # was --with-lmdb specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lmdb library" >&5 @@ -20635,12 +20549,9 @@ _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: size_t for buflen; int for flags" >&5 $as_echo "size_t for buflen; int for flags" >&6; } - # Changed to solve multilib conflict on Fedora - # AC_DEFINE(IRS_GETNAMEINFO_SOCKLEN_T, size_t) - # AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t) - $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T socklen_t" >>confdefs.h + $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T size_t" >>confdefs.h - $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T socklen_t" >>confdefs.h + $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T size_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_FLAGS_T int" >>confdefs.h @@ -21966,7 +21877,12 @@ ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM" ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM" ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM" if test "yes" = "$use_atomic"; then - # The cast to long int works around a bug in the HP C Compiler + have_atomic=yes # set default + case "$host" in + i[3456]86-*) + # XXX: some old x86 architectures actually do not support + # (some of) these operations. Do we need stricter checks? + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. @@ -21999,11 +21915,6 @@ cat >>confdefs.h <<_ACEOF _ACEOF - have_atomic=yes # set default - case "$host" in - i[3456]86-*) - # XXX: some old x86 architectures actually do not support - # (some of) these operations. Do we need stricter checks? if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes @@ -22012,6 +21923,39 @@ _ACEOF fi ;; x86_64-*|amd64-*) + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +$as_echo_n "checking size of void *... " >&6; } +if ${ac_cv_sizeof_void_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_void_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +$as_echo "$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes @@ -22042,10 +21986,6 @@ $as_echo_n "checking architecture type for atomic operations... " >&6; } $as_echo "$arch" >&6; } fi -if test ! "$arch" = "x86_64" -a "$have_xaddq" = "yes"; then - as_fn_error $? "XADDQ present but disabled by Fedora patch!" "$LINENO" 5 -fi - if test "yes" = "$have_atomic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for inline assembly code" >&5 $as_echo_n "checking compiler support for inline assembly code... " >&6; } @@ -24627,30 +24567,6 @@ CFLAGS="$CFLAGS $SO_CFLAGS" # dlzdir='${DLZ_DRIVER_DIR}' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for target libdir" >&5 -$as_echo_n "checking for target libdir... " >&6; } -if test "$cross_compiling" = yes; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run test program while cross compiling -See \`config.log' for more details" "$LINENO" 5; } -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int main(void) {exit((sizeof(void *) == 8) ? 0 : 1);} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - target_lib=lib64 -else - target_lib=lib -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$target_lib\"" >&5 -$as_echo "\"$target_lib\"" >&6; } - # # Private autoconf macro to simplify configuring drivers: # @@ -24981,11 +24897,11 @@ $as_echo "no" >&6; } $as_echo "using mysql with libs ${mysql_lib} and includes ${mysql_include}" >&6; } ;; *) - if test -d $use_dlz_mysql/${target_lib}/mysql + if test -d "$use_dlz_mysql/lib/mysql" then - mysql_lib=$use_dlz_mysql/${target_lib}/mysql + mysql_lib="$use_dlz_mysql/lib/mysql" else - mysql_lib=$use_dlz_mysql/${target_lib} + mysql_lib="$use_dlz_mysql/lib" fi CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_MYSQL" @@ -25070,7 +24986,7 @@ $as_echo "" >&6; } # Check other locations for includes. # Order is important (sigh). - bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /libdb /db" + bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /db" # include a blank element first for d in "" $bdb_incdirs do @@ -25095,9 +25011,57 @@ $as_echo "" >&6; } bdb_libnames="db53 db-5.3 db51 db-5.1 db48 db-4.8 db47 db-4.7 db46 db-4.6 db45 db-4.5 db44 db-4.4 db43 db-4.3 db42 db-4.2 db41 db-4.1 db" for d in $bdb_libnames do - if test -f "$dd/${target_lib}/lib${d}.so" + if test "$dd" = "/usr" + then + as_ac_Lib=`$as_echo "ac_cv_lib_$d''_db_create" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for db_create in -l$d" >&5 +$as_echo_n "checking for db_create in -l$d... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$d $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char db_create (); +int +main () +{ +return db_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + dlz_bdb_libs="-l${d}" +fi + + if test $dlz_bdb_libs != "yes" + then + break + fi + elif test -f "$dd/lib/lib${d}.so" then - dlz_bdb_libs="-L${dd}/${target_lib}/libdb -l${d}" + dlz_bdb_libs="-L${dd}/lib -l${d}" break fi done @@ -25256,10 +25220,10 @@ $as_echo "no" >&6; } DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES -I$use_dlz_ldap/include" DLZ_DRIVER_LDAP_INCLUDES="-I$use_dlz_ldap/include" fi - if test -n "-L$use_dlz_ldap/${target_lib} -lldap -llber" + if test -n "-L$use_dlz_ldap/lib -lldap -llber" then - DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS -L$use_dlz_ldap/${target_lib} -lldap -llber" - DLZ_DRIVER_LDAP_LIBS="-L$use_dlz_ldap/${target_lib} -lldap -llber" + DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS -L$use_dlz_ldap/lib -lldap -llber" + DLZ_DRIVER_LDAP_LIBS="-L$use_dlz_ldap/lib -lldap -llber" fi @@ -25345,11 +25309,11 @@ fi odbcdirs="/usr /usr/local /usr/pkg" for d in $odbcdirs do - if test -f $d/include/sql.h -a -f $d/${target_lib}/libodbc.a + if test -f $d/include/sql.h -a -f $d/lib/libodbc.a then use_dlz_odbc=$d dlz_odbc_include="-I$use_dlz_odbc/include" - dlz_odbc_libs="-L$use_dlz_odbc/${target_lib} -lodbc" + dlz_odbc_libs="-L$use_dlz_odbc/lib -lodbc" break fi done @@ -25624,8 +25588,6 @@ DNS_CRYPTO_LIBS="$NEWFLAGS" - - # # Commands to run at the end of config.status. # Don't just put these into configure, it won't work right if somebody @@ -28004,8 +27966,6 @@ report() { echo " IPv6 support (--enable-ipv6)" test "X$CRYPTO" = "X" -o "yes" = "$want_native_pkcs11" || \ echo " OpenSSL cryptography/DNSSEC (--with-openssl)" - test "no" = "$want_crypto_rand" || \ - echo " Crypto provider entropy source (--enable-crypto-rand)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$XMLSTATS" = "X" || echo " XML statistics (--with-libxml2)" test "X$JSONSTATS" = "X" || echo " JSON statistics (--with-libjson)" @@ -28046,8 +28006,6 @@ report() { echo " Very verbose query trace logging (--enable-querytrace)" test "no" = "$with_cmocka" || echo " CMocka Unit Testing Framework (--with-cmocka)" - echo " Cryptographic library for DNSSEC: $CRYPTOLIB" - echo " Dynamically loadable zone (DLZ) drivers:" test "no" = "$use_dlz_bdb" || \ echo " Berkeley DB (--with-dlz-bdb)" @@ -28095,8 +28053,6 @@ report() { echo " ECDSA algorithm support (--with-ecdsa)" test "X$CRYPTO" = "X" -o "yes" = "$OPENSSL_ED25519" -o "yes" = "$PKCS11_ED25519" || \ echo " EDDSA algorithm support (--with-eddsa)" - test "yes" = "$want_crypto_rand" || \ - echo " Crypto provider entropy source (--enable-crypto-rand)" test "yes" = "$enable_seccomp" || \ echo " Use libseccomp system call filtering (--enable-seccomp)" diff --git a/configure.ac b/configure.ac index 72d5adc..45a1524 100644 --- a/configure.ac +++ b/configure.ac @@ -1176,14 +1176,12 @@ AC_SUBST(USE_GSSAPI) AC_SUBST(DST_GSSAPI_INC) AC_SUBST(DNS_GSSAPI_LIBS) DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS" -DNS_CRYPTO_PK11_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_PK11_LIBS" # # Applications linking with libdns also need to link with these libraries. # AC_SUBST(DNS_CRYPTO_LIBS) -AC_SUBST(DNS_CRYPTO_PK11_LIBS) # # was --with-randomdev specified? @@ -1556,12 +1554,12 @@ AC_ARG_ENABLE(openssl-hash, AC_MSG_CHECKING(for OpenSSL library) OPENSSL_WARNING= openssldirs="/usr /usr/local /usr/local/ssl /opt/local /usr/pkg /usr/sfw" -#if test "yes" = "$want_native_pkcs11" -#then -# use_openssl="native_pkcs11" -# want_openssl_hash="no" -# AC_MSG_RESULT(use of native PKCS11 instead) -#fi +if test "yes" = "$want_native_pkcs11" +then + use_openssl="native_pkcs11" + want_openssl_hash="no" + AC_MSG_RESULT(use of native PKCS11 instead) +fi if test "auto" = "$use_openssl" then @@ -1574,7 +1572,6 @@ then fi done fi -CRYPTO_PK11="" OPENSSL_ECDSA="" OPENSSL_GOST="" OPENSSL_ED25519="" @@ -1596,11 +1593,11 @@ case "$with_gost" in ;; esac -if test "$want_native_pkcs11" = "yes" -then +case "$use_openssl" in + native_pkcs11) + AC_MSG_RESULT(disabled because of native PKCS11) DST_OPENSSL_INC="" - CRYPTO_PK11="-DPKCS11CRYPTO" - CRYPTOLIB="pkcs11" + CRYPTO="-DPKCS11CRYPTO" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -1609,14 +1606,11 @@ then OPENSSLGOSTLINKSRCS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" -fi - -case "$use_openssl" in + ;; no) AC_MSG_RESULT(no) DST_OPENSSL_INC="" CRYPTO="" - CRYPTOLIB="" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -1629,7 +1623,6 @@ case "$use_openssl" in auto) DST_OPENSSL_INC="" CRYPTO="" - CRYPTOLIB="" OPENSSLECDSALINKOBJS="" OPENSSLECDSALINKSRCS="" OPENSSLEDDSALINKOBJS="" @@ -1640,10 +1633,10 @@ case "$use_openssl" in OPENSSLLINKSRCS="" AC_MSG_ERROR( [OpenSSL was not found in any of $openssldirs; use --with-openssl=/path -If you do not want OpenSSL, use --without-openssl]) +If you don't want OpenSSL, use --without-openssl]) ;; *) - if false # test "yes" = "$want_native_pkcs11" + if test "yes" = "$want_native_pkcs11" then AC_MSG_RESULT() AC_MSG_ERROR([OpenSSL and native PKCS11 cannot be used together.]) @@ -1670,7 +1663,6 @@ If you do not want OpenSSL, use --without-openssl]) AC_MSG_ERROR(["$use_openssl/include/openssl/opensslv.h" not found]) fi CRYPTO='-DOPENSSL' - CRYPTOLIB="openssl" if test "/usr" = "$use_openssl" then DST_OPENSSL_INC="" @@ -2071,7 +2063,6 @@ AC_SUBST(OPENSSL_ED25519) AC_SUBST(OPENSSL_GOST) DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DST_OPENSSL_LIBS" -DNS_CRYPTO_PK11_LIBS="$DNS_CRYPTO_LIBS" ISC_PLATFORM_WANTAES="#undef ISC_PLATFORM_WANTAES" if test "yes" = "$with_aes" @@ -2108,6 +2099,7 @@ fi # Use OpenSSL for hash functions # +AC_MSG_CHECKING(for using OpenSSL for hash functions) ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH" case $want_openssl_hash in yes) @@ -2358,7 +2350,6 @@ esac AC_SUBST(PKCS11LINKOBJS) AC_SUBST(PKCS11LINKSRCS) AC_SUBST(CRYPTO) -AC_SUBST(CRYPTO_PK11) AC_SUBST(PKCS11_ECDSA) AC_SUBST(PKCS11_GOST) AC_SUBST(PKCS11_ED25519) @@ -2381,67 +2372,6 @@ if test "rt" = "$have_clock_gt"; then fi # -# Use the crypto provider (OpenSSL/PKCS#11) for random functions -# - -AC_MSG_CHECKING(for using the crypto library (vs. builtin) for random functions) -AC_ARG_ENABLE(crypto-rand, - [ --enable-crypto-rand use the crypto provider for random [[default=yes]]], - want_crypto_rand="$enableval", want_crypto_rand="auto") -if test "$want_crypto_rand" = "auto" -then - case "$CRYPTOLIB" in - "") - want_crypto_rand="no" - ;; - pkcs11) - want_crypto_rand="yes" - ;; - openssl) - saved_cflags="$CFLAGS" - saved_libs="$LIBS" - CFLAGS="$CFLAGS $DST_OPENSSL_INC" - LIBS="$LIBS $DST_OPENSSL_LIBS" - AC_TRY_RUN([ -#include - -unsigned char buf[128]; - -int main() -{ - if (RAND_bytes(buf, 128) != 1) - return (1); - return (0); -} -], - [want_crypto_rand="yes"], - [want_crypto_rand="no"], - [want_crypto_rand="yes"]) - CFLAGS="$saved_cflags" - LIBS="$saved_libs" - ;; - *) - AC_MSG_ERROR([Unknown crypto library define $CRYPTOLIB]) - ;; - esac -fi -case $want_crypto_rand in - yes) - if test "$CRYPTOLIB" = "" - then - AC_MSG_ERROR([No crypto library for random functions]) - fi - AC_MSG_RESULT(["$CRYPTOLIB"]) - ISC_PLATFORM_CRYPTORANDOM="#define ISC_PLATFORM_CRYPTORANDOM \"$CRYPTOLIB\"" - ;; - no) - AC_MSG_RESULT(no) - ISC_PLATFORM_CRYPTORANDOM="#undef ISC_PLATFORM_CRYPTORANDOM" - ;; -esac -AC_SUBST(ISC_PLATFORM_CRYPTORANDOM) - -# # was --with-lmdb specified? # AC_MSG_CHECKING(for lmdb library) @@ -2568,7 +2498,15 @@ case "$use_libjson" in auto|yes) for d in /usr /usr/local /opt/local do - if test -f "${d}/include/json-c/json.h" + if test -f "${d}/include/json/json.h" + then + if test ${d} != /usr + then + libjson_cflags="-I ${d}/include" + LIBS="$LIBS -L${d}/lib" + fi + have_libjson="yes" + elif test -f "${d}/include/json-c/json.h" then if test ${d} != /usr then @@ -2581,7 +2519,12 @@ case "$use_libjson" in done ;; *) - if test -f "${use_libjson}/include/json-c/json.h" + if test -f "${use_libjson}/include/json/json.h" + then + libjson_cflags="-I${use_libjson}/include" + LIBS="$LIBS -L${use_libjson}/lib" + have_libjson="yes" + elif test -f "${use_libjson}/include/json-c/json.h" then libjson_cflags="-I${use_libjson}/include" LIBS="$LIBS -L${use_libjson}/lib" @@ -4245,12 +4188,12 @@ ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM" ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM" ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM" if test "yes" = "$use_atomic"; then - AC_CHECK_SIZEOF([void *]) have_atomic=yes # set default case "$host" in [i[3456]86-*]) # XXX: some old x86 architectures actually do not support # (some of) these operations. Do we need stricter checks? + AC_CHECK_SIZEOF([void *]) if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes @@ -4259,6 +4202,7 @@ if test "yes" = "$use_atomic"; then fi ;; x86_64-*|amd64-*) + AC_CHECK_SIZEOF([void *]) if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes @@ -4287,10 +4231,6 @@ if test "yes" = "$use_atomic"; then AC_MSG_RESULT($arch) fi -if test ! "$arch" = "x86_64" -a "$have_xaddq" = "yes"; then - AC_MSG_ERROR([XADDQ present but disabled by Fedora patch!]) -fi - if test "yes" = "$have_atomic"; then AC_MSG_CHECKING([compiler support for inline assembly code]) @@ -5483,8 +5423,6 @@ AC_SUBST(BUILD_CPPFLAGS) AC_SUBST(BUILD_LDFLAGS) AC_SUBST(BUILD_LIBS) -AC_SUBST(LIBDIR_SUFFIX) - # # Commands to run at the end of config.status. # Don't just put these into configure, it won't work right if somebody @@ -5510,13 +5448,8 @@ AC_CONFIG_FILES([ bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile - bin/dnssec-pkcs11/Makefile bin/named/Makefile bin/named/unix/Makefile - bin/named-pkcs11/Makefile - bin/named-pkcs11/unix/Makefile - bin/named-sdb/Makefile - bin/named-sdb/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile @@ -5541,7 +5474,6 @@ AC_CONFIG_FILES([ bin/python/isc/tests/policy_test.py bin/python/isc/utils.py bin/rndc/Makefile - bin/sdb_tools/Makefile bin/tests/Makefile bin/tests/headerdep_test.sh bin/tests/optional/Makefile @@ -5590,11 +5522,6 @@ AC_CONFIG_FILES([ lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile - lib/dns-pkcs11/Makefile - lib/dns-pkcs11/include/Makefile - lib/dns-pkcs11/include/dns/Makefile - lib/dns-pkcs11/include/dst/Makefile - lib/dns-pkcs11/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile @@ -5619,24 +5546,6 @@ AC_CONFIG_FILES([ lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile - lib/isc-pkcs11/$arch/Makefile - lib/isc-pkcs11/$arch/include/Makefile - lib/isc-pkcs11/$arch/include/isc/Makefile - lib/isc-pkcs11/$thread_dir/Makefile - lib/isc-pkcs11/$thread_dir/include/Makefile - lib/isc-pkcs11/$thread_dir/include/isc/Makefile - lib/isc-pkcs11/Makefile - lib/isc-pkcs11/include/Makefile - lib/isc-pkcs11/include/isc/Makefile - lib/isc-pkcs11/include/isc/platform.h - lib/isc-pkcs11/include/pk11/Makefile - lib/isc-pkcs11/include/pkcs11/Makefile - lib/isc-pkcs11/tests/Makefile - lib/isc-pkcs11/nls/Makefile - lib/isc-pkcs11/unix/Makefile - lib/isc-pkcs11/unix/include/Makefile - lib/isc-pkcs11/unix/include/isc/Makefile - lib/isc-pkcs11/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile @@ -5720,8 +5629,6 @@ report() { echo " IPv6 support (--enable-ipv6)" test "X$CRYPTO" = "X" -o "yes" = "$want_native_pkcs11" || \ echo " OpenSSL cryptography/DNSSEC (--with-openssl)" - test "no" = "$want_crypto_rand" || \ - echo " Crypto provider entropy source (--enable-crypto-rand)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$XMLSTATS" = "X" || echo " XML statistics (--with-libxml2)" test "X$JSONSTATS" = "X" || echo " JSON statistics (--with-libjson)" @@ -5762,8 +5669,6 @@ report() { echo " Very verbose query trace logging (--enable-querytrace)" test "no" = "$with_cmocka" || echo " CMocka Unit Testing Framework (--with-cmocka)" - echo " Cryptographic library for DNSSEC: $CRYPTOLIB" - echo " Dynamically loadable zone (DLZ) drivers:" test "no" = "$use_dlz_bdb" || \ echo " Berkeley DB (--with-dlz-bdb)" @@ -5811,8 +5716,6 @@ report() { echo " ECDSA algorithm support (--with-ecdsa)" test "X$CRYPTO" = "X" -o "yes" = "$OPENSSL_ED25519" -o "yes" = "$PKCS11_ED25519" || \ echo " EDDSA algorithm support (--with-eddsa)" - test "yes" = "$want_crypto_rand" || \ - echo " Crypto provider entropy source (--enable-crypto-rand)" test "yes" = "$enable_seccomp" || \ echo " Use libseccomp system call filtering (--enable-seccomp)" diff --git a/contrib/dlz/config.dlz.in b/contrib/dlz/config.dlz.in index 8db79ef..f769cf1 100644 --- a/contrib/dlz/config.dlz.in +++ b/contrib/dlz/config.dlz.in @@ -17,13 +17,6 @@ # dlzdir='${DLZ_DRIVER_DIR}' -AC_MSG_CHECKING([for target libdir]) -AC_RUN_IFELSE([int main(void) {exit((sizeof(void *) == 8) ? 0 : 1);}], - [target_lib=lib64], - [target_lib=lib], -) -AC_MSG_RESULT(["$target_lib"]) - # # Private autoconf macro to simplify configuring drivers: # @@ -267,7 +260,7 @@ case "$use_dlz_bdb" in # Check other locations for includes. # Order is important (sigh). - bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /libdb /db" + bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /db" # include a blank element first for d in "" $bdb_incdirs do @@ -292,9 +285,16 @@ case "$use_dlz_bdb" in bdb_libnames="db53 db-5.3 db51 db-5.1 db48 db-4.8 db47 db-4.7 db46 db-4.6 db45 db-4.5 db44 db-4.4 db43 db-4.3 db42 db-4.2 db41 db-4.1 db" for d in $bdb_libnames do - if test -f "$dd/${target_lib}/lib${d}.so" + if test "$dd" = "/usr" + then + AC_CHECK_LIB($d, db_create, dlz_bdb_libs="-l${d}") + if test $dlz_bdb_libs != "yes" + then + break + fi + elif test -f "$dd/lib/lib${d}.so" then - dlz_bdb_libs="-L${dd}/${target_lib}/libdb -l${d}" + dlz_bdb_libs="-L${dd}/lib -l${d}" break fi done @@ -396,7 +396,7 @@ case "$use_dlz_ldap" in *) DLZ_ADD_DRIVER(LDAP, dlz_ldap_driver, [-I$use_dlz_ldap/include], - [-L$use_dlz_ldap/${target_lib} -lldap -llber]) + [-L$use_dlz_ldap/lib -lldap -llber]) AC_MSG_RESULT( [using LDAP from $use_dlz_ldap/lib and $use_dlz_ldap/include]) @@ -432,11 +432,11 @@ then odbcdirs="/usr /usr/local /usr/pkg" for d in $odbcdirs do - if test -f $d/include/sql.h -a -f $d/${target_lib}/libodbc.a + if test -f $d/include/sql.h -a -f $d/lib/libodbc.a then use_dlz_odbc=$d dlz_odbc_include="-I$use_dlz_odbc/include" - dlz_odbc_libs="-L$use_dlz_odbc/${target_lib} -lodbc" + dlz_odbc_libs="-L$use_dlz_odbc/lib -lodbc" break fi done diff --git a/contrib/sdb/bdb/bdb.c b/contrib/sdb/bdb/bdb.c index b4dcdc9..6dbc187 100644 --- a/contrib/sdb/bdb/bdb.c +++ b/contrib/sdb/bdb/bdb.c @@ -42,7 +42,7 @@ #include #include -#include "bdb.h" +#include #include #include diff --git a/contrib/sdb/ldap/ldapdb.c b/contrib/sdb/ldap/ldapdb.c index 62d3fb4..c43342c 100644 --- a/contrib/sdb/ldap/ldapdb.c +++ b/contrib/sdb/ldap/ldapdb.c @@ -25,7 +25,6 @@ /* Using LDAPv3 by default, change this if you want v2 */ #ifndef LDAPDB_LDAP_VERSION #define LDAPDB_LDAP_VERSION 3 -#define LDAP_DEPRECATED 1 #endif #include diff --git a/contrib/sdb/ldap/zone2ldap.c b/contrib/sdb/ldap/zone2ldap.c index e0e9207..23c99e9 100644 --- a/contrib/sdb/ldap/zone2ldap.c +++ b/contrib/sdb/ldap/zone2ldap.c @@ -13,8 +13,6 @@ * ditched dNSDomain2 schema support. Version 0.3-ALPHA */ -#define LDAP_DEPRECATED 1 - #include #include #include @@ -64,16 +62,16 @@ typedef struct LDAP_INFO ldap_info; /* usage Info */ -void usage (void); +void usage (); /* Add to the ldap dit */ void add_ldap_values (ldap_info * ldinfo); /* Init an ldap connection */ -void init_ldap_conn (void); +void init_ldap_conn (); /* Ldap error checking */ -void ldap_result_check (const char *msg, char *dn, int err); +void ldap_result_check (char *msg, char *dn, int err); /* Put a hostname into a char ** array */ char **hostname_to_dn_list (char *hostname, char *zone, unsigned int flags); @@ -89,7 +87,7 @@ void add_to_rr_list (char *dn, char *name, char *type, char *data, unsigned int ttl, unsigned int flags); /* Error checking */ -void isc_result_check (isc_result_t res, const char *errorstr); +void isc_result_check (isc_result_t res, char *errorstr); /* Generate LDIF Format files */ void generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, @@ -98,17 +96,11 @@ void generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, /* head pointer to the list */ ldap_info *ldap_info_base = NULL; -ldap_info * -locate_by_dn (char *dn); -void -init_ldap_conn (); -void usage(); - char *argzone, *ldapbase, *binddn, *bindpw = NULL; -const char *ldapsystem = "localhost"; -static const char *objectClasses[] = +char *ldapsystem = "localhost"; +static char *objectClasses[] = { "top", "dNSZone", NULL }; -static const char *topObjectClasses[] = { "top", NULL }; +static char *topObjectClasses[] = { "top", NULL }; LDAP *conn; unsigned int debug = 0; @@ -135,7 +127,7 @@ main (int argc, char **argv) LDAPMod *base_attrs[2]; LDAPMod base; isc_buffer_t buff; - char *zonefile=0L; + char *zonefile; char fullbasedn[1024]; char *ctmp; dns_fixedname_t fixedzone, fixedname; @@ -309,9 +301,9 @@ main (int argc, char **argv) if ((*ctmp == ',') || (ctmp == &basedn[0])) { base.mod_op = LDAP_MOD_ADD; - base.mod_type = (char*)"objectClass"; - base.mod_values = (char**)topObjectClasses; - base_attrs[0] = (void*)&base; + base.mod_type = "objectClass"; + base.mod_values = topObjectClasses; + base_attrs[0] = &base; base_attrs[1] = NULL; if (ldapbase) @@ -368,7 +360,7 @@ main (int argc, char **argv) * I should probably rename this function, as not to cause any * confusion with the isc* routines. Will exit on error. */ void -isc_result_check (isc_result_t res, const char *errorstr) +isc_result_check (isc_result_t res, char *errorstr) { if (res != ISC_R_SUCCESS) { @@ -475,20 +467,20 @@ add_to_rr_list (char *dn, char *name, char *type, if (tmp->attrs == (LDAPMod **) NULL) fatal("calloc"); - for (i = 0; i < (int)flags; i++) + for (i = 0; i < flags; i++) { tmp->attrs[i] = (LDAPMod *) malloc (sizeof (LDAPMod)); if (tmp->attrs[i] == (LDAPMod *) NULL) fatal("malloc"); } tmp->attrs[0]->mod_op = LDAP_MOD_ADD; - tmp->attrs[0]->mod_type = (char*)"objectClass"; + tmp->attrs[0]->mod_type = "objectClass"; if (flags == DNS_OBJECT) - tmp->attrs[0]->mod_values = (char**)objectClasses; + tmp->attrs[0]->mod_values = objectClasses; else { - tmp->attrs[0]->mod_values = (char**)topObjectClasses; + tmp->attrs[0]->mod_values = topObjectClasses; tmp->attrs[1] = NULL; tmp->attrcnt = 2; tmp->next = ldap_info_base; @@ -497,7 +489,7 @@ add_to_rr_list (char *dn, char *name, char *type, } tmp->attrs[1]->mod_op = LDAP_MOD_ADD; - tmp->attrs[1]->mod_type = (char*)"relativeDomainName"; + tmp->attrs[1]->mod_type = "relativeDomainName"; tmp->attrs[1]->mod_values = (char **) calloc (sizeof (char *), 2); if (tmp->attrs[1]->mod_values == (char **)NULL) @@ -526,7 +518,7 @@ add_to_rr_list (char *dn, char *name, char *type, fatal("strdup"); tmp->attrs[3]->mod_op = LDAP_MOD_ADD; - tmp->attrs[3]->mod_type = (char*)"dNSTTL"; + tmp->attrs[3]->mod_type = "dNSTTL"; tmp->attrs[3]->mod_values = (char **) calloc (sizeof (char *), 2); if (tmp->attrs[3]->mod_values == (char **)NULL) @@ -540,7 +532,7 @@ add_to_rr_list (char *dn, char *name, char *type, fatal("strdup"); tmp->attrs[4]->mod_op = LDAP_MOD_ADD; - tmp->attrs[4]->mod_type = (char*)"zoneName"; + tmp->attrs[4]->mod_type = "zoneName"; tmp->attrs[4]->mod_values = (char **)calloc(sizeof(char *), 2); if (tmp->attrs[4]->mod_values == (char **)NULL) @@ -653,7 +645,7 @@ hostname_to_dn_list (char *hostname, char *zone, unsigned int flags) zname = ++tmp; } else - hnamebuff = (char*)"@"; + hnamebuff = "@"; } else { @@ -732,12 +724,12 @@ init_ldap_conn () } result = ldap_simple_bind_s (conn, binddn, bindpw); - ldap_result_check ("ldap_simple_bind_s", (char*)"LDAP Bind", result); + ldap_result_check ("ldap_simple_bind_s", "LDAP Bind", result); } /* Like isc_result_check, only for LDAP */ void -ldap_result_check (const char *msg, char *dn, int err) +ldap_result_check (char *msg, char *dn, int err) { if ((err != LDAP_SUCCESS) && (err != LDAP_ALREADY_EXISTS)) { diff --git a/contrib/sdb/pgsql/pgsqldb.c b/contrib/sdb/pgsql/pgsqldb.c index e276912..9730f1c 100644 --- a/contrib/sdb/pgsql/pgsqldb.c +++ b/contrib/sdb/pgsql/pgsqldb.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/contrib/sdb/pgsql/zonetodb.c b/contrib/sdb/pgsql/zonetodb.c index 7d8b8db..e46b808 100644 --- a/contrib/sdb/pgsql/zonetodb.c +++ b/contrib/sdb/pgsql/zonetodb.c @@ -30,7 +30,7 @@ #include #include -#include +#include /* * Generate a PostgreSQL table from a zone. @@ -47,9 +47,6 @@ char *dbname, *dbtable; char str[10240]; void -closeandexit(int status); - -void closeandexit(int status) { if (conn != NULL) PQfinish(conn); @@ -57,9 +54,6 @@ closeandexit(int status) { } void -check_result(isc_result_t result, const char *message); - -void check_result(isc_result_t result, const char *message) { if (result != ISC_R_SUCCESS) { fprintf(stderr, "%s: %s\n", message, @@ -83,8 +77,7 @@ quotestring(const unsigned char *source, unsigned char *dest) { } *dest++ = 0; } -void -addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata); + void addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { unsigned char namearray[DNS_NAME_MAXTEXT + 1]; diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 5fbabfe..5790fb6 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -4336,9 +4336,6 @@ badresp:1,adberr:0,findfail:0,valfail:0] statement in the named.conf file: - [ max-stale-ttl number ; ] - [ stale-answer-enable yes_or_no ; ] - [ stale-answer-ttl number ; ]
<command>options</command> Statement Definition and @@ -4432,7 +4429,6 @@ badresp:1,adberr:0,findfail:0,valfail:0] <command>dnssec-validation</command>, <command>max-cache-ttl</command>, <command>max-ncache-ttl</command>, - <command>max-stale-ttl</command>, <command>max-cache-size</command>, and <command>zero-no-soa-ttl</command>. </para> @@ -5038,45 +5034,22 @@ badresp:1,adberr:0,findfail:0,valfail:0] <term><command>random-device</command></term> <listitem> <para> - Specifies a source of entropy to be used by the server. - This is a device or file from which to read entropy. - If it is a file, operations requiring entropy - will fail when the file has been exhausted. - </para> - <para> - Entropy is needed for cryptographic operations such as - TKEY transactions, dynamic update of signed zones, and - generation of TSIG session keys. It is also used for - seeding and stirring the pseudo-random number generator, - which is used for less critical functions requiring - randomness such as generation of DNS message transaction - ID's. - </para> - <para> - If <command>random-device</command> is not specified, or - if it is set to <literal>none</literal>, entropy will be - read from the random number generation function supplied - by the cryptographic library with which BIND was linked - (i.e. OpenSSL or a PKCS#11 provider). - </para> - <para> - The <command>random-device</command> option takes - effect during the initial configuration load at server - startup time and is ignored on subsequent reloads. - </para> - <para> - If BIND is built with - <command>configure --disable-crypto-rand</command>, then - entropy is <emphasis>not</emphasis> sourced from the - cryptographic library. In this case, if - <command>random-device</command> is not specified, the - default value is the system random device, - <filename>/dev/random</filename> or the equivalent. - This default can be overridden with - <command>configure --with-randomdev</command>. - If no system random device exists, then no entropy source - will be configured, and <command>named</command> will only - be able to use pseudo-random numbers. + This specifies a source of entropy to be used by the server. Entropy is + primarily needed + for DNSSEC operations, such as TKEY transactions and dynamic + update of signed + zones. This option specifies the device (or file) from which + to read + entropy. If it is a file, operations requiring entropy will + fail when the + file has been exhausted. If <command>random-device</command> is not specified, the default value + is + <filename>/dev/random</filename> + (or equivalent) when present, and none otherwise. The + <command>random-device</command> option takes + effect during + the initial configuration load at server startup time and + is ignored on subsequent reloads. </para> </listitem> </varlistentry> @@ -5442,6 +5415,7 @@ options { </listitem> </varlistentry> + <varlistentry> <term><command>max-zone-ttl</command></term> <listitem> @@ -5478,21 +5452,6 @@ options { </varlistentry> <varlistentry> - <term><command>stale-answer-ttl</command></term> - <listitem> - <para> - Specifies the TTL to be returned on stale answers. - The default is 1 second. The minimal allowed is - also 1 second; a value of 0 will be updated silently - to 1 second. For stale answers to be returned - <option>max-stale-ttl</option> must be set to a - non zero value and they must not have been disabled - by <command>rndc</command>. - </para> - </listitem> - </varlistentry> - - <varlistentry> <term><command>serial-update-method</command></term> <listitem> <para> @@ -6246,22 +6205,6 @@ options { </varlistentry> <varlistentry> - <term><command>serve-stale-enable</command></term> - <listitem> - <para> - Enable the returning of stale answers when the - nameservers for the zone are not answering. This - is off by default but can be enabled/disabled via - <command>rndc server-stale on</command> and - <command>rndc server-stale off</command> which - override the named.conf setting. <command>rndc - server-stale reset</command> will restore control - via named.conf. - </para> - </listitem> - </varlistentry> - - <varlistentry> <term><command>nocookie-udp-size</command></term> <listitem> <para> @@ -7483,19 +7426,13 @@ options { <term><command>resolver-query-timeout</command></term> <listitem> <para> - The amount of time in milliseconds that the resolver - will spend attempting to resolve a recursive - query before failing. The default and minimum - is <literal>10000</literal> and the maximum is - <literal>30000</literal>. Setting it to - <literal>0</literal> will result in the default - being used. - </para> - <para> - This value was originally specified in seconds. - Values less than or equal to 300 will be be treated - as seconds and converted to milliseconds before - applying the above limits. + This is the amount of time in seconds that the + resolver spends attempting to resolve a recursive + query before failing. The default and minimum + is <literal>10</literal> and the maximum is + <literal>30</literal>. Setting it to + <literal>0</literal> results in the default + being used. </para> </listitem> </varlistentry> @@ -9057,27 +8994,6 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; </varlistentry> <varlistentry> - <term><command>max-stale-ttl</command></term> - <listitem> - <para> - Sets the maximum time for which the server will - retain records past their normal expiry to - return them as stale records when the servers - for those records are not reachable. The default - is to not retain the record. - </para> - <para> - <command>rndc serve-stale</command> can be used - to disable and re-enable the serving of stale - records at runtime. Reloading or reconfiguring - <command>named</command> will not re-enable serving - of stale records if they have been disabled via - <command>rndc</command>. - </para> - </listitem> - </varlistentry> - - <varlistentry> <term><command>min-roots</command></term> <listitem> <para> diff --git a/doc/arm/logging-categories.xml b/doc/arm/logging-categories.xml index 098342b..56d05e8 100644 --- a/doc/arm/logging-categories.xml +++ b/doc/arm/logging-categories.xml @@ -313,17 +313,6 @@ </row> <row rowsep="0"> <entry colname="1"> - <para><command>serve-stale</command></para> - </entry> - <entry colname="2"> - <para> - Whether or not a stale answer is used - following a resolver failure. - </para> - </entry> - </row> - <row rowsep="0"> - <entry colname="1"> <para><command>spill</command></para> </entry> <entry colname="2"> diff --git a/doc/arm/notes-rh-changes.xml b/doc/arm/notes-rh-changes.xml deleted file mode 100644 index 80b7dee..0000000 --- a/doc/arm/notes-rh-changes.xml +++ /dev/null @@ -1,54 +0,0 @@ -<!-- - - Copyright (C) Internet Systems Consortium, Inc. ("ISC") - - - - This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. - - - - See the COPYRIGHT file distributed with this work for additional - - information regarding copyright ownership. ---> - -<section xml:id="relnotes_rh_changes"><info><title>Red Hat Specific Changes - - - - This version includes some features not present in releases by ISC. - - - By default, BIND now uses the random number generation functions - in the cryptographic library (i.e., OpenSSL or a PKCS#11 - provider) as a source of high-quality randomness rather than - /dev/random. This is suitable for virtual - machine environments, which may have limited entropy pools and - lack hardware random number generators. - - - This can be overridden by specifying another entropy source via - the random-device option in - named.conf, or via the -r - command line option. However, for functions requiring full - cryptographic strength, such as DNSSEC key generation, this - cannot be overridden. In particular, the - -r command line option no longer has any - effect on dnssec-keygen. - - - This can be disabled by building with - configure --disable-crypto-rand, in which - case /dev/random will be the default - entropy source. [RT #31459] [RT #46047] - - - When acting as a recursive resolver, named - can now continue returning answers whose TTLs have expired - when the authoritative server is under attack and unable to - respond. This is controlled by the - stale-answer-enable, - stale-answer-ttl and - max-stale-ttl options. [RT #44790] - - - -
- diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 3918d94..bf8842c 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -49,7 +49,6 @@ - diff --git a/doc/misc/options b/doc/misc/options index fde93c7..e11beed 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -225,7 +225,6 @@ options { max-refresh-time ; max-retry-time ; max-rsa-exponent-size ; - max-stale-ttl ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; @@ -299,9 +298,7 @@ options { request-sit ; // obsolete require-server-cookie ; reserved-sockets ; - resolver-nonbackoff-tries ; resolver-query-timeout ; - resolver-retry-interval ; response-policy { zone [ log ] [ max-policy-ttl ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ @@ -331,8 +328,6 @@ options { sit-secret ; // obsolete sortlist { ; ... }; stacksize ( default | unlimited | ); - stale-answer-enable ; - stale-answer-ttl ; startup-notify-rate ; statistics-file ; statistics-interval ; // not yet implemented @@ -544,7 +539,6 @@ view [ ] { max-recursion-queries ; max-refresh-time ; max-retry-time ; - max-stale-ttl ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; @@ -606,9 +600,7 @@ view [ ] { request-nsid ; request-sit ; // obsolete require-server-cookie ; - resolver-nonbackoff-tries ; resolver-query-timeout ; - resolver-retry-interval ; response-policy { zone [ log ] [ max-policy-ttl ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ @@ -663,8 +655,6 @@ view [ ] { sig-signing-type ; sig-validity-interval [ ]; sortlist { ; ... }; - stale-answer-enable ; - stale-answer-ttl ; suppress-initial-notify ; // not yet implemented topology { ; ... }; // not implemented transfer-format ( many-answers | one-answer ); diff --git a/isc-config.sh.in b/isc-config.sh.in index ca175dd..006b29c 100644 --- a/isc-config.sh.in +++ b/isc-config.sh.in @@ -13,19 +13,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set= includedir=@includedir@ -libdir_suffix=@LIBDIR_SUFFIX@ -arch=$(uname -m) - -case $arch in - x86_64 | amd64 | sparc64 | s390x | ppc64) - libdir=/usr/lib64${libdir_suffix} - sec_libdir=/usr/lib${libdir_suffix} - ;; - * ) - libdir=/usr/lib${libdir_suffix} - sec_libdir=/usr/lib64${libdir_suffix} - ;; -esac +libdir=@libdir@ usage() { @@ -144,16 +132,6 @@ if test x"$echo_libs" = x"true"; then if test x"${exec_prefix_set}" = x"true"; then libs="-L${exec_prefix}/lib" else - if [ ! -x $libdir/libisc.so ] ; then - if [ ! -x $sec_libdir/libisc.so ] ; then - echo "Error: ISC libs not found in $libdir" - if [ -d $sec_libdir ] ; then - echo "Error: ISC libs not found in $sec_libdir" - fi - exit 1 - fi - libdir=$sec_libdir - fi libs="-L${libdir}" fi if test x"$libirs" = x"true" ; then diff --git a/lib/Kyuafile b/lib/Kyuafile index eec9564..7c8bab0 100644 --- a/lib/Kyuafile +++ b/lib/Kyuafile @@ -2,10 +2,8 @@ syntax(2) test_suite('bind9') include('dns/Kyuafile') -include('dns-pkcs11/Kyuafile') include('irs/Kyuafile') include('isc/Kyuafile') -include('isc-pkcs11/Kyuafile') include('isccc/Kyuafile') include('isccfg/Kyuafile') include('lwres/Kyuafile') diff --git a/lib/Makefile.in b/lib/Makefile.in index 3ed939b..f089bea 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -15,7 +15,7 @@ top_srcdir = @top_srcdir@ # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: -SUBDIRS = isc isc-pkcs11 isccc dns dns-pkcs11 isccfg bind9 lwres irs samples +SUBDIRS = isc isccc dns isccfg bind9 lwres irs samples TARGETS = @BIND9_MAKE_RULES@ diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 6c57fa4..f990860 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -99,8 +98,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid class '%s'", r.base); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } @@ -113,8 +111,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid type '%s'", r.base); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } @@ -128,8 +125,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid name '%s'", str); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } @@ -138,16 +134,14 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { strcasecmp("order", cfg_obj_asstring(obj)) != 0) { cfg_obj_log(ent, logctx, ISC_LOG_ERROR, "rrset-order: keyword 'order' missing"); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } obj = cfg_tuple_get(ent, "ordering"); if (!cfg_obj_isstring(obj)) { cfg_obj_log(ent, logctx, ISC_LOG_ERROR, "rrset-order: missing ordering"); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } else if (strcasecmp(cfg_obj_asstring(obj), "fixed") == 0) { #if !DNS_RDATASET_FIXED cfg_obj_log(obj, logctx, ISC_LOG_WARNING, @@ -159,8 +153,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid order '%s'", cfg_obj_asstring(obj)); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } return (result); } @@ -180,7 +173,7 @@ check_order(const cfg_obj_t *options, isc_log_t *logctx) { element = cfg_list_next(element)) { tresult = check_orderent(cfg_listelt_value(element), logctx); - if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) result = tresult; } return (result); @@ -210,8 +203,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) { if (val > UINT16_MAX) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "port '%u' out of range", val); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_FAILURE; } } obj = cfg_tuple_get(alternates, "addresses"); @@ -231,8 +223,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) { if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad name '%s'", str); - if (result == ISC_R_SUCCESS) - result = tresult; + result = ISC_R_FAILURE; } obj = cfg_tuple_get(value, "port"); if (cfg_obj_isuint32(obj)) { @@ -240,8 +231,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) { if (val > UINT16_MAX) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "port '%u' out of range", val); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_FAILURE; } } } @@ -311,10 +301,6 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) { r.length = strlen(r.base); tresult = dns_secalg_fromtext(&alg, &r); - if (tresult == ISC_R_DISABLED) { - // Recognize disabled algorithms, disable it explicitly - tresult = ISC_R_SUCCESS; - } if (tresult != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), logctx, ISC_LOG_ERROR, "invalid algorithm '%s'", @@ -1280,8 +1266,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "auto-dnssec may only be activated at the " "zone level"); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } @@ -1301,7 +1286,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, { obj = cfg_listelt_value(element); tresult = mustbesecure(obj, symtab, logctx, mctx); - if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) result = tresult; } if (symtab != NULL) @@ -1320,8 +1305,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s: invalid name '%s'", server_contact[i], str); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } } @@ -1341,8 +1325,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "disable-empty-zone: invalid name '%s'", str); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } } @@ -1356,12 +1339,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, strlen(cfg_obj_asstring(obj)) > 1024U) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'server-id' too big (>1024 bytes)"); - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; + result = ISC_R_FAILURE; } tresult = check_dscp(options, logctx); - if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) result = tresult; obj = NULL; @@ -1371,13 +1353,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (lifetime > 604800) { /* 7 days */ cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'nta-lifetime' cannot exceed one week"); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_RANGE; } else if (lifetime == 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'nta-lifetime' may not be zero"); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_RANGE; } } @@ -1388,8 +1368,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (recheck > 604800) { /* 7 days */ cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'nta-recheck' cannot exceed one week"); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_RANGE; } if (recheck > lifetime) @@ -1407,8 +1386,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (strcasecmp(ccalg, "aes") == 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "cookie-algorithm: '%s' not supported", ccalg); - if (result == ISC_R_SUCCESS) - result = ISC_R_NOTIMPLEMENTED; + result = ISC_R_NOTIMPLEMENTED; } #endif @@ -1497,8 +1475,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s out of range (%u < %u)", fstrm[i].name, value, fstrm[i].min); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_RANGE; } if (strcmp(fstrm[i].name, "fstrm-set-input-queue-size") == 0) { @@ -1512,8 +1489,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, "%s '%u' not a power-of-2", fstrm[i].name, cfg_obj_asuint32(obj)); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + result = ISC_R_RANGE; } } } @@ -1531,8 +1507,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, "%" PRId64 "' " "is too small", mapsize); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + return (ISC_R_RANGE); } else if (mapsize > (1ULL << 40)) { /* 1 terabyte */ cfg_obj_log(obj, logctx, ISC_LOG_ERROR, @@ -1540,20 +1515,10 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, "%" PRId64 "' " "is too large", mapsize); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; + return (ISC_R_RANGE); } } - obj = NULL; - (void)cfg_map_get(options, "resolver-nonbackoff-tries", &obj); - if (obj != NULL && cfg_obj_asuint32(obj) == 0U) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "'resolver-nonbackoff-tries' must be >= 1"); - if (result == ISC_R_SUCCESS) - result = ISC_R_RANGE; - } - return (result); } @@ -2638,15 +2603,6 @@ bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) { } algorithm = cfg_obj_asstring(algobj); -#ifndef PK11_MD5_DISABLE - /* Skip hmac-md5* algorithms */ - if (!isc_md5_available() && - strncasecmp(algorithm, "hmac-md5", 8) == 0) { - cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, - "disabled algorithm '%s'", algorithm); - return (ISC_R_DISABLED); - } -#endif for (i = 0; algorithms[i].name != NULL; i++) { len = strlen(algorithms[i].name); if (strncasecmp(algorithms[i].name, algorithm, len) == 0 && diff --git a/lib/dns-pkcs11/Kyuafile b/lib/dns-pkcs11/Kyuafile deleted file mode 100644 index 0739e3a..0000000 --- a/lib/dns-pkcs11/Kyuafile +++ /dev/null @@ -1,4 +0,0 @@ -syntax(2) -test_suite('bind9') - -include('tests/Kyuafile') diff --git a/lib/dns-pkcs11/Makefile.in b/lib/dns-pkcs11/Makefile.in deleted file mode 100644 index 89e2f11..0000000 --- a/lib/dns-pkcs11/Makefile.in +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -# Attempt to disable parallel processing. -.NOTPARALLEL: -.NO_PARALLEL: - -VERSION=@BIND9_VERSION@ -@BIND9_MAJOR@ - -@LIBDNS_MAPAPI@ - -@LIBDNS_API@ - -@BIND9_MAKE_INCLUDES@ - -USE_ISC_SPNEGO = @USE_ISC_SPNEGO@ - -CINCLUDES = -I. -I${top_srcdir}/lib/dns-pkcs11 -Iinclude ${DNS_PKCS11_INCLUDES} \ - ${ISC_PKCS11_INCLUDES} ${MAXMINDDB_CFLAGS} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@ - -CDEFINES = -DUSE_MD5 @CRYPTO_PK11@ @USE_GSSAPI@ ${USE_ISC_SPNEGO} - -CWARNINGS = - -ISCLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ - -ISCDEPLIBS = ../../lib/isc-pkcs11/libisc-pkcs11.@A@ - -LIBS = ${MAXMINDDB_LIBS} @LIBS@ - -# Alphabetically - -OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ -OPENSSLECDSALINKOBJS = opensslecdsa_link.@O@ -OPENSSLEDDSALINKOBJS = openssleddsa_link.@O@ -OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - @OPENSSLECDSALINKOBJS@ @OPENSSLEDDSALINKOBJS@ \ - @OPENSSLGOSTLINKOBJS@ opensslrsa_link.@O@ - -PKCS11LINKOBJS = pkcs11dh_link.@O@ pkcs11dsa_link.@O@ pkcs11rsa_link.@O@ \ - pkcs11ecdsa_link.@O@ pkcs11eddsa_link.@O@ \ - pkcs11gost_link.@O@ pkcs11.@O@ - -DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ @PKCS11LINKOBJS@ \ - dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ - gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@ - -GEOIPLINKOBJS = geoip.@O@ -GEOIP2LINKOBJS = geoip2.@O@ - -DNSTAPOBJS = dnstap.@O@ dnstap.pb-c.@O@ - -# Alphabetically -DNSOBJS = acache.@O@ acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \ - cache.@O@ callbacks.@O@ catz.@O@ clientinfo.@O@ compress.@O@ \ - db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ - dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ \ - fixedname.@O@ forward.@O@ \ - ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \ - keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \ - master.@O@ masterdump.@O@ message.@O@ \ - name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \ - order.@O@ peer.@O@ portlist.@O@ private.@O@ \ - rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rcode.@O@ rdata.@O@ \ - rdatalist.@O@ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ \ - request.@O@ resolver.@O@ result.@O@ rootns.@O@ \ - rpz.@O@ rrl.@O@ rriterator.@O@ sdb.@O@ \ - sdlz.@O@ soa.@O@ ssu.@O@ ssu_external.@O@ \ - stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \ - tsec.@O@ tsig.@O@ ttl.@O@ update.@O@ validator.@O@ \ - version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@ -PORTDNSOBJS = client.@O@ ecdb.@O@ - -OBJS= @DNSTAPOBJS@ ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} \ - ${PORTDNSOBJS} @GEOIPLINKOBJS@ @GEOIP2LINKOBJS@ - - -# Alphabetically -OPENSSLGOSTLINKSRCS = opensslgost_link.c -OPENSSLECDSALINKSRCS = opensslecdsa_link.c -OPENSSLEDDSALINKSRCS = openssleddsa_link.c -OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - @OPENSSLECDSALINKSRCS@ @OPENSSLEDDSALINKSRCS@ \ - @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c - -PKCS11LINKSRCS = pkcs11dh_link.c pkcs11dsa_link.c pkcs11rsa_link.c \ - pkcs11ecdsa_link.c pkcs11eddsa_link.c \ - pkcs11gost_link.c pkcs11.c - -DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ @PKCS11LINKSRCS@ \ - dst_api.c dst_lib.c dst_parse.c \ - dst_result.c gssapi_link.c gssapictx.c \ - hmac_link.c key.c - -GEOIPLINKSRCS = geoip.c -GEOIPL2INKSRCS = geoip2.c - -DNSTAPSRCS = dnstap.c dnstap.pb-c.c - -DNSSRCS = acache.c acl.c adb.c badcache.c byaddr.c \ - cache.c callbacks.c clientinfo.c compress.c \ - db.c dbiterator.c dbtable.c diff.c dispatch.c \ - dlz.c dns64.c dnssec.c ds.c dyndb.c fixedname.c forward.c \ - ipkeylist.c iptable.c journal.c keydata.c keytable.c lib.c \ - log.c lookup.c master.c masterdump.c message.c \ - name.c ncache.c nsec.c nsec3.c nta.c \ - order.c peer.c portlist.c \ - rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \ - rdataset.c rdatasetiter.c rdataslab.c request.c \ - resolver.c result.c rootns.c rpz.c rrl.c rriterator.c \ - sdb.c sdlz.c soa.c ssu.c ssu_external.c \ - stats.c tcpmsg.c time.c timer.c tkey.c \ - tsec.c tsig.c ttl.c update.c validator.c \ - version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS} -PORTDNSSRCS = client.c ecdb.c - -SRCS = ${DSTSRCS} ${DNSSRCS} \ - ${PORTDNSSRCS} @DNSTAPSRCS@ @GEOIPLINKSRCS@ @GEOIP2LINKSRCS@ - -SUBDIRS = include -TARGETS = timestamp -TESTDIRS = @UNITTESTS@ - -DEPENDEXTRA = ./gen -F include/dns/rdatastruct.h \ - -s ${srcdir} -d >> Makefile ; - -@BIND9_MAKE_RULES@ - -PROTOC_C = @PROTOC_C@ - -version.@O@: version.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DMAJOR=\"${MAJOR}\" \ - -DMAPAPI=\"${MAPAPI}\" \ - -DLIBINTERFACE=${LIBINTERFACE} \ - -DLIBREVISION=${LIBREVISION} \ - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - -libdns-pkcs11.@SA@: ${OBJS} - ${AR} ${ARFLAGS} $@ ${OBJS} - ${RANLIB} $@ - -libdns-pkcs11.la: ${OBJS} - ${LIBTOOL_MODE_LINK} \ - ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns-pkcs11.la -rpath ${libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${ISCLIBS} @DNS_CRYPTO_PK11_LIBS@ ${LIBS} - -include: gen - ${MAKE} include/dns/enumtype.h - ${MAKE} include/dns/enumclass.h - ${MAKE} include/dns/rdatastruct.h - ${MAKE} code.h - -include/dns/enumtype.h: gen - ./gen -s ${srcdir} -t > $@ || { rm -f $@ ; exit 1; } - -include/dns/enumclass.h: gen - ./gen -s ${srcdir} -c > $@ || { rm -f $@ ; exit 1; } - -include/dns/rdatastruct.h: gen \ - ${srcdir}/rdata/rdatastructpre.h \ - ${srcdir}/rdata/rdatastructsuf.h - ./gen -s ${srcdir} -i \ - -P ${srcdir}/rdata/rdatastructpre.h \ - -S ${srcdir}/rdata/rdatastructsuf.h > $@ || \ - { rm -f $@ ; exit 1; } - -code.h: gen - ./gen -s ${srcdir} > code.h || { rm -f $@ ; exit 1; } - -gen: gen.c - ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \ - ${LFS_CFLAGS} ${LFS_LDFLAGS} \ - ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c \ - ${BUILD_LIBS} ${LFS_LIBS} - -timestamp: include libdns-pkcs11.@A@ - touch timestamp - -testdirs: libdns-pkcs11.@A@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} - -install:: timestamp installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libdns-pkcs11.@A@ ${DESTDIR}${libdir} - -uninstall:: - ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${libdir}/libdns-pkcs11.@A@ - -clean distclean:: - rm -f libdns-pkcs11.@A@ timestamp - rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h - rm -f include/dns/rdatastruct.h - rm -f dnstap.pb-c.c dnstap.pb-c.h - -newrr:: - rm -f code.h include/dns/enumtype.h include/dns/enumclass.h - rm -f include/dns/rdatastruct.h - -rdata.@O@: include - -rbtdb64.@O@: rbtdb64.c rbtdb.c - -depend: include @DNSTAPSRCS@ -subdirs: include -${OBJS}: include - -# dnstap -dnstap.@O@: dnstap.c dnstap.pb-c.c - -dnstap.pb-c.c dnstap.pb-c.h: dnstap.proto - $(PROTOC_C) --c_out=. --proto_path ${srcdir} dnstap.proto - -dnstap.pb-c.@O@: dnstap.pb-c.c - -spnego.@O@: spnego_asn1.c spnego.h diff --git a/lib/dns-pkcs11/acache.c b/lib/dns-pkcs11/acache.c deleted file mode 100644 index 99646d5..0000000 --- a/lib/dns-pkcs11/acache.c +++ /dev/null @@ -1,1835 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#endif - -#define ACACHE_MAGIC ISC_MAGIC('A', 'C', 'H', 'E') -#define DNS_ACACHE_VALID(acache) ISC_MAGIC_VALID(acache, ACACHE_MAGIC) - -#define ACACHEENTRY_MAGIC ISC_MAGIC('A', 'C', 'E', 'T') -#define DNS_ACACHEENTRY_VALID(entry) ISC_MAGIC_VALID(entry, ACACHEENTRY_MAGIC) - -#define DBBUCKETS 67 - -#if 0 -#define ATRACE(m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_DATABASE, \ - DNS_LOGMODULE_ACACHE, \ - ISC_LOG_DEBUG(3), \ - "acache %p: %s", acache, (m)) -#define AATRACE(a,m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_DATABASE, \ - DNS_LOGMODULE_ACACHE, \ - ISC_LOG_DEBUG(3), \ - "acache %p: %s", (a), (m)) -#else -#define ATRACE(m) -#define AATRACE(a, m) -#endif - -/* - * The following variables control incremental cleaning. - * MINSIZE is how many bytes is the floor for dns_acache_setcachesize(). - * CLEANERINCREMENT is how many entries are examined in one pass. - * (XXX simply derived from definitions in cache.c There may be better - * constants here.) - */ -#define DNS_ACACHE_MINSIZE 2097152U /* Bytes. 2097152 = 2 MB */ -#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ - -#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ - -#if defined(ISC_RWLOCK_USEATOMIC) && \ - ((defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_LONG_LOCK_FREE)) || \ - defined(ISC_PLATFORM_HAVEATOMICSTORE)) -#define ACACHE_USE_RWLOCK 1 -#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_LONG_LOCK_FREE)) -#define ACACHE_HAVESTDATOMIC 1 -#endif -#endif - -#ifdef ACACHE_USE_RWLOCK -#define ACACHE_INITLOCK(l) isc_rwlock_init((l), 0, 0) -#define ACACHE_DESTROYLOCK(l) isc_rwlock_destroy(l) -#define ACACHE_LOCK(l, t) RWLOCK((l), (t)) -#define ACACHE_UNLOCK(l, t) RWUNLOCK((l), (t)) - -#ifdef ACACHE_HAVESTDATOMIC -#define acache_storetime(entry, t) \ - atomic_store_explicit(&(entry)->lastused, (t), \ - memory_order_relaxed); -#else -#define acache_storetime(entry, t) \ - (isc_atomic_store((int32_t *)&(entry)->lastused, (t))) -#endif - -#else -#define ACACHE_INITLOCK(l) isc_mutex_init(l) -#define ACACHE_DESTROYLOCK(l) DESTROYLOCK(l) -#define ACACHE_LOCK(l, t) LOCK(l) -#define ACACHE_UNLOCK(l, t) UNLOCK(l) - -#define acache_storetime(entry, t) ((entry)->lastused = (t)) -#endif - -/* Locked by acache lock */ -typedef struct dbentry { - ISC_LINK(struct dbentry) link; - - dns_db_t *db; - ISC_LIST(dns_acacheentry_t) originlist; - ISC_LIST(dns_acacheentry_t) referlist; -} dbentry_t; - -typedef ISC_LIST(dbentry_t) dbentrylist_t; - -typedef struct acache_cleaner acache_cleaner_t; - -typedef enum { - cleaner_s_idle, /* Waiting for cleaning-interval to expire. */ - cleaner_s_busy, /* Currently cleaning. */ - cleaner_s_done /* Freed enough memory after being overmem. */ -} cleaner_state_t; - -/* - * Convenience macros for comprehensive assertion checking. - */ -#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ - (c)->resched_event != NULL) -#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ - (c)->resched_event == NULL) - -struct acache_cleaner { - isc_mutex_t lock; - /* - * Locks overmem_event, overmem. (See cache.c) - */ - - dns_acache_t *acache; - unsigned int cleaning_interval; /* The cleaning-interval - from named.conf, - in seconds. */ - - isc_stdtime_t last_cleanup_time; /* The time when the last - cleanup task completed */ - - isc_timer_t *cleaning_timer; - isc_event_t *resched_event; /* Sent by cleaner task to - itself to reschedule */ - isc_event_t *overmem_event; - - dns_acacheentry_t *current_entry; /* The bookmark entry to - restart the cleaning. - Locked by acache lock. */ - int increment; /* Number of entries to - clean in one increment */ - - unsigned long ncleaned; /* Number of entries cleaned - up (for logging purposes) */ - cleaner_state_t state; /* Idle/Busy/Done. */ - bool overmem; /* The acache is in an overmem - state. */ -}; - -struct dns_acachestats { -#ifdef ACACHE_HAVESTDATOMIC - _Atomic(unsigned int) hits; - _Atomic(unsigned int) queries; - _Atomic(unsigned int) misses; -#define ACACHE_INC(x) atomic_fetch_add(&(x), 1) -#define ACACHE_LOAD(x) atomic_load(&(x)) -#else - unsigned int hits; - unsigned int queries; - unsigned int misses; -#if defined(ISC_PLATFORM_HAVEXADD) -#define ACACHE_INC(x) isc_atomic_xadd((int32_t*)&(x), 1) -#define ACACHE_LOAD(x) isc_atomic_xadd((int32_t*)&(x), 0) -#else -#define ACACHE_INC(x) ((x)++) -#define ACACHE_LOAD(x) (x) -#endif -#endif - unsigned int adds; - unsigned int deleted; - unsigned int cleaned; - unsigned int cleaner_runs; - unsigned int overmem; - unsigned int overmem_nocreates; - unsigned int nomem; -}; - -/* - * The actual acache object. - */ - -struct dns_acache { - unsigned int magic; - - isc_mem_t *mctx; - isc_refcount_t refs; - -#ifdef ACACHE_USE_RWLOCK - isc_rwlock_t *entrylocks; -#else - isc_mutex_t *entrylocks; -#endif - - isc_mutex_t lock; - - int live_cleaners; - acache_cleaner_t cleaner; - ISC_LIST(dns_acacheentry_t) entries; - unsigned int dbentries; - dbentrylist_t dbbucket[DBBUCKETS]; - - bool shutting_down; - - isc_task_t *task; - isc_event_t cevent; - bool cevent_sent; - - dns_acachestats_t stats; -}; - -struct dns_acacheentry { - unsigned int magic; - - unsigned int locknum; - isc_refcount_t references; - - dns_acache_t *acache; - - /* Data for Management of cache entries */ - ISC_LINK(dns_acacheentry_t) link; - ISC_LINK(dns_acacheentry_t) olink; - ISC_LINK(dns_acacheentry_t) rlink; - - dns_db_t *origdb; /* reference to the DB - holding this entry */ - - /* Cache data */ - dns_zone_t *zone; /* zone this entry - belongs to */ - dns_db_t *db; /* DB this entry belongs to */ - dns_dbversion_t *version; /* the version of the DB */ - dns_dbnode_t *node; /* node this entry - belongs to */ - dns_name_t *foundname; /* corresponding DNS name - and rdataset */ - - /* Callback function and its argument */ - void (*callback)(dns_acacheentry_t *, void **); - void *cbarg; - - /* Timestamp of the last time this entry is referred to */ -#ifdef ACACHE_HAVESTDATOMIC - atomic_uint_fast32_t lastused; -#else - isc_stdtime_t lastused; -#endif -}; - -/* - * Internal functions (and prototypes). - */ -static inline bool check_noentry(dns_acache_t *acache); -static void destroy(dns_acache_t *acache); -static void shutdown_entries(dns_acache_t *acache); -static void shutdown_buckets(dns_acache_t *acache); -static void destroy_entry(dns_acacheentry_t *ent); -static inline void unlink_dbentries(dns_acache_t *acache, - dns_acacheentry_t *ent); -static inline isc_result_t finddbent(dns_acache_t *acache, - dns_db_t *db, dbentry_t **dbentryp); -static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry); -static isc_result_t acache_cleaner_init(dns_acache_t *acache, - isc_timermgr_t *timermgr, - acache_cleaner_t *cleaner); -static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event); -static void acache_incremental_cleaning_action(isc_task_t *task, - isc_event_t *event); -static void acache_overmem_cleaning_action(isc_task_t *task, - isc_event_t *event); -static void acache_cleaner_shutdown_action(isc_task_t *task, - isc_event_t *event); - -/* - * acache should be locked. If it is not, the stats can get out of whack, - * which is not a big deal for us since this is for debugging / stats - */ -static void -reset_stats(dns_acache_t *acache) { - acache->stats.hits = 0; - acache->stats.queries = 0; - acache->stats.misses = 0; - acache->stats.adds = 0; - acache->stats.deleted = 0; - acache->stats.cleaned = 0; - acache->stats.overmem = 0; - acache->stats.overmem_nocreates = 0; - acache->stats.nomem = 0; -} - -/* - * The acache must be locked before calling. - */ -static inline bool -check_noentry(dns_acache_t *acache) { - if (ISC_LIST_EMPTY(acache->entries) && acache->dbentries == 0) { - return (true); - } - - return (false); -} - -/* - * The acache must be locked before calling. - */ -static void -shutdown_entries(dns_acache_t *acache) { - dns_acacheentry_t *entry, *entry_next; - - REQUIRE(DNS_ACACHE_VALID(acache)); - INSIST(acache->shutting_down); - - /* - * Release the dependency of all entries, and detach them. - */ - for (entry = ISC_LIST_HEAD(acache->entries); - entry != NULL; - entry = entry_next) { - entry_next = ISC_LIST_NEXT(entry, link); - - ACACHE_LOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - /* - * If the cleaner holds this entry, it will be unlinked and - * freed in the cleaner later. - */ - if (acache->cleaner.current_entry != entry) - ISC_LIST_UNLINK(acache->entries, entry, link); - unlink_dbentries(acache, entry); - if (entry->callback != NULL) { - (entry->callback)(entry, &entry->cbarg); - entry->callback = NULL; - } - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - if (acache->cleaner.current_entry != entry) - dns_acache_detachentry(&entry); - } -} - -/* - * The acache must be locked before calling. - */ -static void -shutdown_buckets(dns_acache_t *acache) { - int i; - dbentry_t *dbent; - - REQUIRE(DNS_ACACHE_VALID(acache)); - INSIST(acache->shutting_down); - - for (i = 0; i < DBBUCKETS; i++) { - while ((dbent = ISC_LIST_HEAD(acache->dbbucket[i])) != NULL) { - INSIST(ISC_LIST_EMPTY(dbent->originlist) && - ISC_LIST_EMPTY(dbent->referlist)); - ISC_LIST_UNLINK(acache->dbbucket[i], dbent, link); - - dns_db_detach(&dbent->db); - - isc_mem_put(acache->mctx, dbent, sizeof(*dbent)); - - acache->dbentries--; - } - } - - INSIST(acache->dbentries == 0); -} - -static void -shutdown_task(isc_task_t *task, isc_event_t *ev) { - dns_acache_t *acache; - - UNUSED(task); - - acache = ev->ev_arg; - INSIST(DNS_ACACHE_VALID(acache)); - - isc_event_free(&ev); - - LOCK(&acache->lock); - - shutdown_entries(acache); - shutdown_buckets(acache); - - UNLOCK(&acache->lock); - - dns_acache_detach(&acache); -} - -/* The acache and the entry must be locked before calling. */ -static inline void -unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent) { - isc_result_t result; - dbentry_t *dbent; - - if (ISC_LINK_LINKED(ent, olink)) { - INSIST(ent->origdb != NULL); - dbent = NULL; - result = finddbent(acache, ent->origdb, &dbent); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_UNLINK(dbent->originlist, ent, olink); - } - if (ISC_LINK_LINKED(ent, rlink)) { - INSIST(ent->db != NULL); - dbent = NULL; - result = finddbent(acache, ent->db, &dbent); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_UNLINK(dbent->referlist, ent, rlink); - } -} - -/* There must not be a reference to this entry. */ -static void -destroy_entry(dns_acacheentry_t *entry) { - dns_acache_t *acache; - - REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - - acache = entry->acache; - REQUIRE(DNS_ACACHE_VALID(acache)); - - /* - * Since there is no reference to this entry, it is safe to call - * clear_entry() here. - */ - clear_entry(acache, entry); - - isc_mem_put(acache->mctx, entry, sizeof(*entry)); - - dns_acache_detach(&acache); -} - -static void -destroy(dns_acache_t *acache) { - int i; - - REQUIRE(DNS_ACACHE_VALID(acache)); - - ATRACE("destroy"); - - isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); - - if (acache->cleaner.overmem_event != NULL) - isc_event_free(&acache->cleaner.overmem_event); - - if (acache->cleaner.resched_event != NULL) - isc_event_free(&acache->cleaner.resched_event); - - if (acache->task != NULL) - isc_task_detach(&acache->task); - - for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) - ACACHE_DESTROYLOCK(&acache->entrylocks[i]); - isc_mem_put(acache->mctx, acache->entrylocks, - sizeof(*acache->entrylocks) * - DEFAULT_ACACHE_ENTRY_LOCK_COUNT); - - DESTROYLOCK(&acache->cleaner.lock); - - DESTROYLOCK(&acache->lock); - acache->magic = 0; - - isc_mem_putanddetach(&acache->mctx, acache, sizeof(*acache)); -} - -static inline isc_result_t -finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp) { - int bucket; - dbentry_t *dbentry; - - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(db != NULL); - REQUIRE(dbentryp != NULL && *dbentryp == NULL); - - /* - * The caller must be holding the acache lock. - */ - - bucket = isc_hash_function(&db, sizeof(db), true, NULL) % DBBUCKETS; - - for (dbentry = ISC_LIST_HEAD(acache->dbbucket[bucket]); - dbentry != NULL; - dbentry = ISC_LIST_NEXT(dbentry, link)) { - if (dbentry->db == db) - break; - } - - *dbentryp = dbentry; - - if (dbentry == NULL) - return (ISC_R_NOTFOUND); - else - return (ISC_R_SUCCESS); -} - -static inline void -clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry) { - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - - /* - * The caller must be holing the entry lock. - */ - - if (entry->foundname) { - dns_rdataset_t *rdataset, *rdataset_next; - - for (rdataset = ISC_LIST_HEAD(entry->foundname->list); - rdataset != NULL; - rdataset = rdataset_next) { - rdataset_next = ISC_LIST_NEXT(rdataset, link); - ISC_LIST_UNLINK(entry->foundname->list, - rdataset, link); - dns_rdataset_disassociate(rdataset); - isc_mem_put(acache->mctx, rdataset, sizeof(*rdataset)); - } - if (dns_name_dynamic(entry->foundname)) - dns_name_free(entry->foundname, acache->mctx); - isc_mem_put(acache->mctx, entry->foundname, - sizeof(*entry->foundname)); - entry->foundname = NULL; - } - - if (entry->node != NULL) { - INSIST(entry->db != NULL); - dns_db_detachnode(entry->db, &entry->node); - } - if (entry->version != NULL) { - INSIST(entry->db != NULL); - dns_db_closeversion(entry->db, &entry->version, false); - } - if (entry->db != NULL) - dns_db_detach(&entry->db); - if (entry->zone != NULL) - dns_zone_detach(&entry->zone); - - if (entry->origdb != NULL) - dns_db_detach(&entry->origdb); -} - -static isc_result_t -acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr, - acache_cleaner_t *cleaner) -{ - int result; - - ATRACE("acache cleaner init"); - - result = isc_mutex_init(&cleaner->lock); - if (result != ISC_R_SUCCESS) - goto fail; - - cleaner->increment = DNS_ACACHE_CLEANERINCREMENT; - cleaner->state = cleaner_s_idle; - cleaner->acache = acache; - cleaner->overmem = false; - - cleaner->cleaning_timer = NULL; - cleaner->resched_event = NULL; - cleaner->overmem_event = NULL; - cleaner->current_entry = NULL; - - if (timermgr != NULL) { - cleaner->acache->live_cleaners++; - - result = isc_task_onshutdown(acache->task, - acache_cleaner_shutdown_action, - acache); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "acache cleaner: " - "isc_task_onshutdown() failed: %s", - dns_result_totext(result)); - goto cleanup; - } - - cleaner->cleaning_interval = 0; /* Initially turned off. */ - isc_stdtime_get(&cleaner->last_cleanup_time); - result = isc_timer_create(timermgr, isc_timertype_inactive, - NULL, NULL, - acache->task, - acache_cleaning_timer_action, - cleaner, &cleaner->cleaning_timer); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timer_create() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - cleaner->resched_event = - isc_event_allocate(acache->mctx, cleaner, - DNS_EVENT_ACACHECLEAN, - acache_incremental_cleaning_action, - cleaner, sizeof(isc_event_t)); - if (cleaner->resched_event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - cleaner->overmem_event = - isc_event_allocate(acache->mctx, cleaner, - DNS_EVENT_ACACHEOVERMEM, - acache_overmem_cleaning_action, - cleaner, sizeof(isc_event_t)); - if (cleaner->overmem_event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - return (ISC_R_SUCCESS); - - cleanup: - if (cleaner->overmem_event != NULL) - isc_event_free(&cleaner->overmem_event); - if (cleaner->resched_event != NULL) - isc_event_free(&cleaner->resched_event); - if (cleaner->cleaning_timer != NULL) - isc_timer_detach(&cleaner->cleaning_timer); - cleaner->acache->live_cleaners--; - DESTROYLOCK(&cleaner->lock); - fail: - return (result); -} - -static void -begin_cleaning(acache_cleaner_t *cleaner) { - dns_acacheentry_t *head; - dns_acache_t *acache = cleaner->acache; - - /* - * This function does not have to lock the cleaner, since critical - * parameters (except current_entry, which is locked by acache lock,) - * are only used in a single task context. - */ - - REQUIRE(CLEANER_IDLE(cleaner)); - INSIST(DNS_ACACHE_VALID(acache)); - INSIST(cleaner->current_entry == NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), - "begin acache cleaning, mem inuse %lu", - (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); - - LOCK(&acache->lock); - - head = ISC_LIST_HEAD(acache->entries); - if (head != NULL) - dns_acache_attachentry(head, &cleaner->current_entry); - - UNLOCK(&acache->lock); - - if (cleaner->current_entry != NULL) { - cleaner->ncleaned = 0; - cleaner->state = cleaner_s_busy; - isc_task_send(acache->task, &cleaner->resched_event); - } - - return; -} - -static void -end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) { - dns_acache_t *acache = cleaner->acache; - - REQUIRE(CLEANER_BUSY(cleaner)); - REQUIRE(event != NULL); - REQUIRE(DNS_ACACHEENTRY_VALID(cleaner->current_entry)); - - /* No need to lock the cleaner (see begin_cleaning()). */ - - LOCK(&acache->lock); - - /* - * Even if the cleaner has the last reference to the entry, which means - * the entry has been unused, it may still be linked if unlinking the - * entry has been delayed due to the reference. - */ - if (isc_refcount_current(&cleaner->current_entry->references) == 1) { - INSIST(cleaner->current_entry->callback == NULL); - - if (ISC_LINK_LINKED(cleaner->current_entry, link)) { - ISC_LIST_UNLINK(acache->entries, - cleaner->current_entry, link); - } - } - dns_acache_detachentry(&cleaner->current_entry); - - if (cleaner->overmem) - acache->stats.overmem++; - acache->stats.cleaned += cleaner->ncleaned; - acache->stats.cleaner_runs++; - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, - ISC_LOG_NOTICE, - "acache %p stats: hits=%d misses=%d queries=%d " - "adds=%d deleted=%d " - "cleaned=%d cleaner_runs=%d overmem=%d " - "overmem_nocreates=%d nomem=%d", - acache, - ACACHE_LOAD(acache->stats.hits), - ACACHE_LOAD(acache->stats.misses), - ACACHE_LOAD(acache->stats.queries), - acache->stats.adds, acache->stats.deleted, - acache->stats.cleaned, acache->stats.cleaner_runs, - acache->stats.overmem, acache->stats.overmem_nocreates, - acache->stats.nomem); - reset_stats(acache); - - isc_stdtime_get(&cleaner->last_cleanup_time); - - UNLOCK(&acache->lock); - - dns_acache_setcleaninginterval(cleaner->acache, - cleaner->cleaning_interval); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, - ISC_LOG_DEBUG(1), "end acache cleaning, " - "%lu entries cleaned, mem inuse %lu", - cleaner->ncleaned, - (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); - - if (cleaner->overmem) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, - "acache is still in overmem state " - "after cleaning"); - } - - cleaner->ncleaned = 0; - cleaner->state = cleaner_s_idle; - cleaner->resched_event = event; -} - -/* - * This is run once for every acache-cleaning-interval as defined - * in named.conf. - */ -static void -acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event) { - acache_cleaner_t *cleaner = event->ev_arg; - - UNUSED(task); - - INSIST(event->ev_type == ISC_TIMEREVENT_TICK); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, - ISC_LOG_DEBUG(1), "acache cleaning timer fired, " - "cleaner state = %d", cleaner->state); - - if (cleaner->state == cleaner_s_idle) - begin_cleaning(cleaner); - - isc_event_free(&event); -} - -/* The caller must hold entry lock. */ -static inline bool -entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, - isc_stdtime_t now32, unsigned int interval) -{ - /* - * If the callback has been canceled, we definitely do not need the - * entry. - */ - if (entry->callback == NULL) - return (true); - - if (interval > cleaner->cleaning_interval) - interval = cleaner->cleaning_interval; - - if (entry->lastused + interval < now32) - return (true); - - /* - * If the acache is in the overmem state, probabilistically decide if - * the entry should be purged, based on the time passed from its last - * use and the cleaning interval. - */ - if (cleaner->overmem) { - unsigned int passed; - uint32_t val; - - if (isc_serial_ge(now32, entry->lastused)) - passed = now32 - entry->lastused; /* <= interval */ - else - passed = 0; - - if (passed > interval / 2) - return (true); - isc_random_get(&val); - if (passed > interval / 4) - return (val % 4 == 0); - return (val % 8 == 0); - } - - return (false); -} - -/* - * Do incremental cleaning. - */ -static void -acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { - acache_cleaner_t *cleaner = event->ev_arg; - dns_acache_t *acache = cleaner->acache; - dns_acacheentry_t *entry, *next = NULL; - int n_entries; - isc_stdtime_t now32, last32; - isc_stdtime_t now; - unsigned int interval; - - INSIST(DNS_ACACHE_VALID(acache)); - INSIST(task == acache->task); - INSIST(event->ev_type == DNS_EVENT_ACACHECLEAN); - - if (cleaner->state == cleaner_s_done) { - cleaner->state = cleaner_s_busy; - end_cleaning(cleaner, event); - return; - } - - INSIST(CLEANER_BUSY(cleaner)); - - n_entries = cleaner->increment; - - isc_stdtime_get(&now); - isc_stdtime_convert32(now, &now32); - - LOCK(&acache->lock); - - entry = cleaner->current_entry; - isc_stdtime_convert32(cleaner->last_cleanup_time, &last32); - if (isc_serial_ge(now32, last32)) - interval = now32 - last32; - else - interval = 0; - - while (n_entries-- > 0) { - bool is_stale = false; - - INSIST(entry != NULL); - - next = ISC_LIST_NEXT(entry, link); - - ACACHE_LOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - is_stale = entry_stale(cleaner, entry, now32, interval); - if (is_stale) { - ISC_LIST_UNLINK(acache->entries, entry, link); - unlink_dbentries(acache, entry); - if (entry->callback != NULL) - (entry->callback)(entry, &entry->cbarg); - entry->callback = NULL; - - cleaner->ncleaned++; - } - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - if (is_stale) - dns_acache_detachentry(&entry); - - if (next == NULL) { - if (cleaner->overmem) { - entry = ISC_LIST_HEAD(acache->entries); - if (entry != NULL) { - /* - * If we are still in the overmem - * state, keep cleaning. In case we - * exit from the loop immediately after - * this, reset next to the head entry - * as we'll expect it will be never - * NULL. - */ - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, - ISC_LOG_DEBUG(1), - "acache cleaner: " - "still overmem, " - "reset and try again"); - next = entry; - continue; - } - } - - UNLOCK(&acache->lock); - end_cleaning(cleaner, event); - return; - } - - entry = next; - } - - /* - * We have successfully performed a cleaning increment but have - * not gone through the entire cache. Remember the entry that will - * be the starting point in the next clean-up, and reschedule another - * batch. If it fails, just try to continue anyway. - */ - INSIST(next != NULL); - dns_acache_detachentry(&cleaner->current_entry); - dns_acache_attachentry(next, &cleaner->current_entry); - - UNLOCK(&acache->lock); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, - ISC_LOG_DEBUG(1), "acache cleaner: checked %d entries, " - "mem inuse %lu, sleeping", cleaner->increment, - (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); - - isc_task_send(task, &event); - INSIST(CLEANER_BUSY(cleaner)); - - return; -} - -/* - * This is called when the acache either surpasses its upper limit - * or shrinks beyond its lower limit. - */ -static void -acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event) { - acache_cleaner_t *cleaner = event->ev_arg; - bool want_cleaning = false; - - UNUSED(task); - - INSIST(event->ev_type == DNS_EVENT_ACACHEOVERMEM); - INSIST(cleaner->overmem_event == NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, - ISC_LOG_DEBUG(1), "overmem_cleaning_action called, " - "overmem = %d, state = %d", cleaner->overmem, - cleaner->state); - - LOCK(&cleaner->lock); - - if (cleaner->overmem) { - if (cleaner->state == cleaner_s_idle) - want_cleaning = true; - } else { - if (cleaner->state == cleaner_s_busy) - /* - * end_cleaning() can't be called here because - * then both cleaner->overmem_event and - * cleaner->resched_event will point to this - * event. Set the state to done, and then - * when the acache_incremental_cleaning_action() event - * is posted, it will handle the end_cleaning. - */ - cleaner->state = cleaner_s_done; - } - - cleaner->overmem_event = event; - - UNLOCK(&cleaner->lock); - - if (want_cleaning) - begin_cleaning(cleaner); -} - -static void -water(void *arg, int mark) { - dns_acache_t *acache = arg; - bool overmem = (mark == ISC_MEM_HIWATER); - - REQUIRE(DNS_ACACHE_VALID(acache)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), - "acache memory reaches %s watermark, mem inuse %lu", - overmem ? "high" : "low", - (unsigned long)isc_mem_inuse(acache->mctx)); - - LOCK(&acache->cleaner.lock); - - if (acache->cleaner.overmem != overmem) { - acache->cleaner.overmem = overmem; - - if (acache->cleaner.overmem_event != NULL) - isc_task_send(acache->task, - &acache->cleaner.overmem_event); - isc_mem_waterack(acache->mctx, mark); - } - - UNLOCK(&acache->cleaner.lock); -} - -/* - * The cleaner task is shutting down; do the necessary cleanup. - */ -static void -acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) { - dns_acache_t *acache = event->ev_arg; - bool should_free = false; - - INSIST(task == acache->task); - INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - INSIST(DNS_ACACHE_VALID(acache)); - - ATRACE("acache cleaner shutdown"); - - if (CLEANER_BUSY(&acache->cleaner)) - end_cleaning(&acache->cleaner, event); - else - isc_event_free(&event); - - LOCK(&acache->lock); - - acache->live_cleaners--; - INSIST(acache->live_cleaners == 0); - - if (isc_refcount_current(&acache->refs) == 0) { - INSIST(check_noentry(acache) == true); - should_free = true; - } - - /* - * By detaching the timer in the context of its task, - * we are guaranteed that there will be no further timer - * events. - */ - if (acache->cleaner.cleaning_timer != NULL) - isc_timer_detach(&acache->cleaner.cleaning_timer); - - /* Make sure we don't reschedule anymore. */ - (void)isc_task_purge(task, NULL, DNS_EVENT_ACACHECLEAN, NULL); - - UNLOCK(&acache->lock); - - if (should_free) - destroy(acache); -} - -/* - * Public functions. - */ - -isc_result_t -dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, - isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr) -{ - int i; - isc_result_t result; - dns_acache_t *acache; - - REQUIRE(acachep != NULL && *acachep == NULL); - REQUIRE(mctx != NULL); - REQUIRE(taskmgr != NULL); - - acache = isc_mem_get(mctx, sizeof(*acache)); - if (acache == NULL) - return (ISC_R_NOMEMORY); - - ATRACE("create"); - - result = isc_refcount_init(&acache->refs, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, acache, sizeof(*acache)); - return (result); - } - - result = isc_mutex_init(&acache->lock); - if (result != ISC_R_SUCCESS) { - isc_refcount_decrement(&acache->refs, NULL); - isc_refcount_destroy(&acache->refs); - isc_mem_put(mctx, acache, sizeof(*acache)); - return (result); - } - - acache->mctx = NULL; - isc_mem_attach(mctx, &acache->mctx); - ISC_LIST_INIT(acache->entries); - - acache->shutting_down = false; - - acache->task = NULL; - acache->entrylocks = NULL; - - result = isc_task_create(taskmgr, 1, &acache->task); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_task_create() failed(): %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - isc_task_setname(acache->task, "acachetask", acache); - ISC_EVENT_INIT(&acache->cevent, sizeof(acache->cevent), 0, NULL, - DNS_EVENT_ACACHECONTROL, shutdown_task, NULL, - NULL, NULL, NULL); - acache->cevent_sent = false; - - acache->dbentries = 0; - for (i = 0; i < DBBUCKETS; i++) - ISC_LIST_INIT(acache->dbbucket[i]); - - acache->entrylocks = isc_mem_get(mctx, sizeof(*acache->entrylocks) * - DEFAULT_ACACHE_ENTRY_LOCK_COUNT); - if (acache->entrylocks == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) { - result = ACACHE_INITLOCK(&acache->entrylocks[i]); - if (result != ISC_R_SUCCESS) { - while (i-- > 0) - ACACHE_DESTROYLOCK(&acache->entrylocks[i]); - isc_mem_put(mctx, acache->entrylocks, - sizeof(*acache->entrylocks) * - DEFAULT_ACACHE_ENTRY_LOCK_COUNT); - acache->entrylocks = NULL; - goto cleanup; - } - } - - acache->live_cleaners = 0; - result = acache_cleaner_init(acache, timermgr, &acache->cleaner); - if (result != ISC_R_SUCCESS) - goto cleanup; - - acache->stats.cleaner_runs = 0; - reset_stats(acache); - - acache->magic = ACACHE_MAGIC; - - *acachep = acache; - return (ISC_R_SUCCESS); - - cleanup: - if (acache->task != NULL) - isc_task_detach(&acache->task); - DESTROYLOCK(&acache->lock); - isc_refcount_decrement(&acache->refs, NULL); - isc_refcount_destroy(&acache->refs); - if (acache->entrylocks != NULL) { - for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) - ACACHE_DESTROYLOCK(&acache->entrylocks[i]); - isc_mem_put(mctx, acache->entrylocks, - sizeof(*acache->entrylocks) * - DEFAULT_ACACHE_ENTRY_LOCK_COUNT); - } - isc_mem_put(mctx, acache, sizeof(*acache)); - isc_mem_detach(&mctx); - - return (result); -} - -void -dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) { - REQUIRE(DNS_ACACHE_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - AATRACE(source, "attach"); - - isc_refcount_increment(&source->refs, NULL); - - *targetp = source; -} - -void -dns_acache_countquerymiss(dns_acache_t *acache) { - ACACHE_INC(acache->stats.misses); - ACACHE_INC(acache->stats.queries); -} - -void -dns_acache_detach(dns_acache_t **acachep) { - dns_acache_t *acache; - unsigned int refs; - bool should_free = false; - - REQUIRE(acachep != NULL && DNS_ACACHE_VALID(*acachep)); - acache = *acachep; - - ATRACE("detach"); - - isc_refcount_decrement(&acache->refs, &refs); - if (refs == 0) { - INSIST(check_noentry(acache) == true); - should_free = true; - } - - *acachep = NULL; - - /* - * If we're exiting and the cleaner task exists, let it free the cache. - */ - if (should_free && acache->live_cleaners > 0) { - isc_task_shutdown(acache->task); - should_free = false; - } - - if (should_free) - destroy(acache); -} - -void -dns_acache_shutdown(dns_acache_t *acache) { - REQUIRE(DNS_ACACHE_VALID(acache)); - - LOCK(&acache->lock); - - ATRACE("shutdown"); - - if (!acache->shutting_down) { - isc_event_t *event; - dns_acache_t *acache_evarg = NULL; - - INSIST(!acache->cevent_sent); - - acache->shutting_down = true; - - isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); - - /* - * Self attach the object in order to prevent it from being - * destroyed while waiting for the event. - */ - dns_acache_attach(acache, &acache_evarg); - event = &acache->cevent; - event->ev_arg = acache_evarg; - isc_task_send(acache->task, &event); - acache->cevent_sent = true; - } - - UNLOCK(&acache->lock); -} - -isc_result_t -dns_acache_setdb(dns_acache_t *acache, dns_db_t *db) { - int bucket; - dbentry_t *dbentry; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(db != NULL); - - ATRACE("setdb"); - - LOCK(&acache->lock); - - dbentry = NULL; - result = finddbent(acache, db, &dbentry); - if (result == ISC_R_SUCCESS) { - result = ISC_R_EXISTS; - goto end; - } - result = ISC_R_SUCCESS; - - dbentry = isc_mem_get(acache->mctx, sizeof(*dbentry)); - if (dbentry == NULL) { - result = ISC_R_NOMEMORY; - goto end; - } - - ISC_LINK_INIT(dbentry, link); - ISC_LIST_INIT(dbentry->originlist); - ISC_LIST_INIT(dbentry->referlist); - - dbentry->db = NULL; - dns_db_attach(db, &dbentry->db); - - bucket = isc_hash_function(&db, sizeof(db), true, NULL) % DBBUCKETS; - - ISC_LIST_APPEND(acache->dbbucket[bucket], dbentry, link); - - acache->dbentries++; - - end: - UNLOCK(&acache->lock); - - return (result); -} - -isc_result_t -dns_acache_putdb(dns_acache_t *acache, dns_db_t *db) { - int bucket; - isc_result_t result; - dbentry_t *dbentry; - dns_acacheentry_t *entry; - - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(db != NULL); - - ATRACE("putdb"); - - LOCK(&acache->lock); - - dbentry = NULL; - result = finddbent(acache, db, &dbentry); - if (result != ISC_R_SUCCESS) { - /* - * The entry may have not been created due to memory shortage. - */ - UNLOCK(&acache->lock); - return (ISC_R_NOTFOUND); - } - - /* - * Release corresponding cache entries: for each entry, release all - * links the entry has, and then callback to the entry holder (if any). - * If no other external references exist (this can happen if the - * original holder has canceled callback,) destroy it here. - */ - while ((entry = ISC_LIST_HEAD(dbentry->originlist)) != NULL) { - ACACHE_LOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - /* - * Releasing olink first would avoid finddbent() in - * unlink_dbentries(). - */ - ISC_LIST_UNLINK(dbentry->originlist, entry, olink); - if (acache->cleaner.current_entry != entry) - ISC_LIST_UNLINK(acache->entries, entry, link); - unlink_dbentries(acache, entry); - - if (entry->callback != NULL) - (entry->callback)(entry, &entry->cbarg); - entry->callback = NULL; - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - if (acache->cleaner.current_entry != entry) - dns_acache_detachentry(&entry); - } - while ((entry = ISC_LIST_HEAD(dbentry->referlist)) != NULL) { - ACACHE_LOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - ISC_LIST_UNLINK(dbentry->referlist, entry, rlink); - if (acache->cleaner.current_entry != entry) - ISC_LIST_UNLINK(acache->entries, entry, link); - unlink_dbentries(acache, entry); - - if (entry->callback != NULL) - (entry->callback)(entry, &entry->cbarg); - entry->callback = NULL; - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - if (acache->cleaner.current_entry != entry) - dns_acache_detachentry(&entry); - } - - INSIST(ISC_LIST_EMPTY(dbentry->originlist) && - ISC_LIST_EMPTY(dbentry->referlist)); - - bucket = isc_hash_function(&db, sizeof(db), true, NULL) % DBBUCKETS; - - ISC_LIST_UNLINK(acache->dbbucket[bucket], dbentry, link); - dns_db_detach(&dbentry->db); - - isc_mem_put(acache->mctx, dbentry, sizeof(*dbentry)); - - acache->dbentries--; - - acache->stats.deleted++; - - UNLOCK(&acache->lock); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, - void (*callback)(dns_acacheentry_t *, void **), - void *cbarg, dns_acacheentry_t **entryp) -{ - dns_acacheentry_t *newentry; - isc_result_t result; - uint32_t r; - isc_stdtime_t tmptime; - - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(entryp != NULL && *entryp == NULL); - REQUIRE(origdb != NULL); - - /* - * Should we exceed our memory limit for some reason (for - * example, if the cleaner does not run aggressively enough), - * then we will not create additional entries. - * - * XXXSK: It might be better to lock the acache->cleaner->lock, - * but locking may be an expensive bottleneck. If we misread - * the value, we will occasionally refuse to create a few - * cache entries, or create a few that we should not. I do not - * expect this to happen often, and it will not have very bad - * effects when it does. So no lock for now. - */ - if (acache->cleaner.overmem) { - acache->stats.overmem_nocreates++; /* XXXSK danger: unlocked! */ - return (ISC_R_NORESOURCES); - } - - newentry = isc_mem_get(acache->mctx, sizeof(*newentry)); - if (newentry == NULL) { - acache->stats.nomem++; /* XXXMLG danger: unlocked! */ - return (ISC_R_NOMEMORY); - } - - isc_random_get(&r); - newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT; - - result = isc_refcount_init(&newentry->references, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(acache->mctx, newentry, sizeof(*newentry)); - return (result); - }; - - ISC_LINK_INIT(newentry, link); - ISC_LINK_INIT(newentry, olink); - ISC_LINK_INIT(newentry, rlink); - - newentry->acache = NULL; - dns_acache_attach(acache, &newentry->acache); - - newentry->zone = NULL; - newentry->db = NULL; - newentry->version = NULL; - newentry->node = NULL; - newentry->foundname = NULL; - - newentry->callback = callback; - newentry->cbarg = cbarg; - newentry->origdb = NULL; - dns_db_attach(origdb, &newentry->origdb); - - isc_stdtime_get(&tmptime); - acache_storetime(newentry, tmptime); - - newentry->magic = ACACHEENTRY_MAGIC; - - *entryp = newentry; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, - dns_db_t **dbp, dns_dbversion_t **versionp, - dns_dbnode_t **nodep, dns_name_t *fname, - dns_message_t *msg, isc_stdtime_t now) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_rdataset_t *erdataset; - isc_stdtime_t now32; - dns_acache_t *acache; - int locknum; - - REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - REQUIRE(zonep == NULL || *zonep == NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(versionp != NULL && *versionp == NULL); - REQUIRE(nodep != NULL && *nodep == NULL); - REQUIRE(fname != NULL); - REQUIRE(msg != NULL); - acache = entry->acache; - REQUIRE(DNS_ACACHE_VALID(acache)); - - locknum = entry->locknum; - ACACHE_LOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); - - isc_stdtime_convert32(now, &now32); - acache_storetime(entry, now32); - - if (entry->zone != NULL && zonep != NULL) - dns_zone_attach(entry->zone, zonep); - - if (entry->db == NULL) { - *dbp = NULL; - *versionp = NULL; - } else { - dns_db_attach(entry->db, dbp); - dns_db_attachversion(entry->db, entry->version, versionp); - } - if (entry->node == NULL) - *nodep = NULL; - else { - dns_db_attachnode(entry->db, entry->node, nodep); - - INSIST(entry->foundname != NULL); - dns_name_copy(entry->foundname, fname, NULL); - for (erdataset = ISC_LIST_HEAD(entry->foundname->list); - erdataset != NULL; - erdataset = ISC_LIST_NEXT(erdataset, link)) { - dns_rdataset_t *ardataset; - - ardataset = NULL; - result = dns_message_gettemprdataset(msg, &ardataset); - if (result != ISC_R_SUCCESS) { - ACACHE_UNLOCK(&acache->entrylocks[locknum], - isc_rwlocktype_read); - goto fail; - } - - /* - * XXXJT: if we simply clone the rdataset, we'll get - * lost wrt cyclic ordering. We'll need an additional - * trick to get the latest counter from the original - * header. - */ - dns_rdataset_clone(erdataset, ardataset); - ISC_LIST_APPEND(fname->list, ardataset, link); - } - } - - ACACHE_INC(entry->acache->stats.hits); - ACACHE_INC(entry->acache->stats.queries); - - ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); - - return (result); - - fail: - while ((erdataset = ISC_LIST_HEAD(fname->list)) != NULL) { - ISC_LIST_UNLINK(fname->list, erdataset, link); - dns_rdataset_disassociate(erdataset); - dns_message_puttemprdataset(msg, &erdataset); - } - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - if (*versionp != NULL) - dns_db_closeversion(*dbp, versionp, false); - if (*dbp != NULL) - dns_db_detach(dbp); - if (zonep != NULL && *zonep != NULL) - dns_zone_detach(zonep); - - return (result); -} - -isc_result_t -dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, - dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *fname) -{ - isc_result_t result; - dbentry_t *odbent; - dbentry_t *rdbent = NULL; - bool close_version = false; - dns_acacheentry_t *dummy_entry = NULL; - - REQUIRE(DNS_ACACHE_VALID(acache)); - REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - - LOCK(&acache->lock); /* XXX: need to lock it here for ordering */ - ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); - - /* Set zone */ - if (zone != NULL) - dns_zone_attach(zone, &entry->zone); - /* Set DB */ - if (db != NULL) - dns_db_attach(db, &entry->db); - /* - * Set DB version. If the version is not given by the caller, - * which is the case for glue or cache DBs, use the current version. - */ - if (version == NULL) { - if (db != NULL) { - dns_db_currentversion(db, &version); - close_version = true; - } - } - if (version != NULL) { - INSIST(db != NULL); - dns_db_attachversion(db, version, &entry->version); - } - if (close_version) - dns_db_closeversion(db, &version, false); - /* Set DB node. */ - if (node != NULL) { - dns_rdataset_t *ardataset, *crdataset; - - INSIST(db != NULL); - dns_db_attachnode(db, node, &entry->node); - - /* - * Set list of the corresponding rdatasets, if - * given. To minimize the overhead and memory - * consumption, we'll do this for positive cache - * only, in which case the DB node is non NULL. We - * do not want to cache incomplete information, so - * give up the entire entry when a memory shortage - * happen during the process. - */ - entry->foundname = isc_mem_get(acache->mctx, - sizeof(*entry->foundname)); - - if (entry->foundname == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - dns_name_init(entry->foundname, NULL); - result = dns_name_dup(fname, acache->mctx, - entry->foundname); - if (result != ISC_R_SUCCESS) - goto fail; - - for (ardataset = ISC_LIST_HEAD(fname->list); - ardataset != NULL; - ardataset = ISC_LIST_NEXT(ardataset, link)) { - crdataset = isc_mem_get(acache->mctx, - sizeof(*crdataset)); - if (crdataset == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - - dns_rdataset_init(crdataset); - dns_rdataset_clone(ardataset, crdataset); - ISC_LIST_APPEND(entry->foundname->list, crdataset, - link); - } - } - - odbent = NULL; - result = finddbent(acache, entry->origdb, &odbent); - if (result != ISC_R_SUCCESS) - goto fail; - if (db != NULL) { - rdbent = NULL; - result = finddbent(acache, db, &rdbent); - if (result != ISC_R_SUCCESS) - goto fail; - } - - ISC_LIST_APPEND(acache->entries, entry, link); - ISC_LIST_APPEND(odbent->originlist, entry, olink); - if (rdbent != NULL) - ISC_LIST_APPEND(rdbent->referlist, entry, rlink); - - /* - * The additional cache needs an implicit reference to entries in its - * link. - */ - dns_acache_attachentry(entry, &dummy_entry); - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - - acache->stats.adds++; - UNLOCK(&acache->lock); - - return (ISC_R_SUCCESS); - - fail: - clear_entry(acache, entry); - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - UNLOCK(&acache->lock); - - return (result); -} - -bool -dns_acache_cancelentry(dns_acacheentry_t *entry) { - dns_acache_t *acache; - bool callback_active; - - REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - - acache = entry->acache; - - INSIST(DNS_ACACHE_VALID(entry->acache)); - - LOCK(&acache->lock); - ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); - - callback_active = (entry->cbarg != NULL); - - /* - * Release dependencies stored in this entry as much as possible. - * The main link cannot be released, since the acache object has - * a reference to this entry; the empty entry will be released in - * the next cleaning action. - */ - unlink_dbentries(acache, entry); - clear_entry(entry->acache, entry); - - entry->callback = NULL; - entry->cbarg = NULL; - - ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], - isc_rwlocktype_write); - UNLOCK(&acache->lock); - - return (callback_active); -} - -void -dns_acache_attachentry(dns_acacheentry_t *source, - dns_acacheentry_t **targetp) -{ - REQUIRE(DNS_ACACHEENTRY_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - isc_refcount_increment(&source->references, NULL); - - *targetp = source; -} - -void -dns_acache_detachentry(dns_acacheentry_t **entryp) { - dns_acacheentry_t *entry; - unsigned int refs; - - REQUIRE(entryp != NULL && DNS_ACACHEENTRY_VALID(*entryp)); - entry = *entryp; - - isc_refcount_decrement(&entry->references, &refs); - - /* - * If there are no references to the entry, the entry must have been - * unlinked and can be destroyed safely. - */ - if (refs == 0) { - INSIST(!ISC_LINK_LINKED(entry, link)); - (*entryp)->acache->stats.deleted++; - destroy_entry(entry); - } - - *entryp = NULL; -} - -void -dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t) { - isc_interval_t interval; - isc_result_t result; - - REQUIRE(DNS_ACACHE_VALID(acache)); - - ATRACE("dns_acache_setcleaninginterval"); - - LOCK(&acache->lock); - - /* - * It may be the case that the acache has already shut down. - * If so, it has no timer. (Not sure if this can really happen.) - */ - if (acache->cleaner.cleaning_timer == NULL) - goto unlock; - - acache->cleaner.cleaning_interval = t; - - if (t == 0) { - result = isc_timer_reset(acache->cleaner.cleaning_timer, - isc_timertype_inactive, - NULL, NULL, true); - } else { - isc_interval_set(&interval, acache->cleaner.cleaning_interval, - 0); - result = isc_timer_reset(acache->cleaner.cleaning_timer, - isc_timertype_ticker, - NULL, &interval, false); - } - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, ISC_LOG_WARNING, - "could not set acache cleaning interval: %s", - isc_result_totext(result)); - else - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, - "acache %p cleaning interval set to %d.", - acache, t); - - unlock: - UNLOCK(&acache->lock); -} - -/* - * This function was derived from cache.c:dns_cache_setcachesize(). See the - * function for more details about the logic. - */ -void -dns_acache_setcachesize(dns_acache_t *acache, size_t size) { - size_t hiwater, lowater; - - REQUIRE(DNS_ACACHE_VALID(acache)); - - if (size != 0U && size < DNS_ACACHE_MINSIZE) - size = DNS_ACACHE_MINSIZE; - - hiwater = size - (size >> 3); - lowater = size - (size >> 2); - - if (size == 0U || hiwater == 0U || lowater == 0U) - isc_mem_setwater(acache->mctx, water, acache, 0, 0); - else - isc_mem_setwater(acache->mctx, water, acache, - hiwater, lowater); -} diff --git a/lib/dns-pkcs11/acl.c b/lib/dns-pkcs11/acl.c deleted file mode 100644 index b5cb735..0000000 --- a/lib/dns-pkcs11/acl.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include - - -/* - * Create a new ACL, including an IP table and an array with room - * for 'n' ACL elements. The elements are uninitialized and the - * length is 0. - */ -isc_result_t -dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) { - isc_result_t result; - dns_acl_t *acl; - - /* - * Work around silly limitation of isc_mem_get(). - */ - if (n == 0) - n = 1; - - acl = isc_mem_get(mctx, sizeof(*acl)); - if (acl == NULL) - return (ISC_R_NOMEMORY); - - acl->mctx = NULL; - isc_mem_attach(mctx, &acl->mctx); - - acl->name = NULL; - - result = isc_refcount_init(&acl->refcount, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, acl, sizeof(*acl)); - return (result); - } - - result = dns_iptable_create(mctx, &acl->iptable); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, acl, sizeof(*acl)); - return (result); - } - - acl->elements = NULL; - acl->alloc = 0; - acl->length = 0; - acl->has_negatives = false; - - ISC_LINK_INIT(acl, nextincache); - /* - * Must set magic early because we use dns_acl_detach() to clean up. - */ - acl->magic = DNS_ACL_MAGIC; - - acl->elements = isc_mem_get(mctx, n * sizeof(dns_aclelement_t)); - if (acl->elements == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - acl->alloc = n; - memset(acl->elements, 0, n * sizeof(dns_aclelement_t)); - *target = acl; - return (ISC_R_SUCCESS); - - cleanup: - dns_acl_detach(&acl); - return (result); -} - -/* - * Create a new ACL and initialize it with the value "any" or "none", - * depending on the value of the "neg" parameter. - * "any" is a positive iptable entry with bit length 0. - * "none" is the same as "!any". - */ -static isc_result_t -dns_acl_anyornone(isc_mem_t *mctx, bool neg, dns_acl_t **target) { - isc_result_t result; - dns_acl_t *acl = NULL; - - result = dns_acl_create(mctx, 0, &acl); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_iptable_addprefix(acl->iptable, NULL, 0, !neg); - if (result != ISC_R_SUCCESS) { - dns_acl_detach(&acl); - return (result); - } - - *target = acl; - return (result); -} - -/* - * Create a new ACL that matches everything. - */ -isc_result_t -dns_acl_any(isc_mem_t *mctx, dns_acl_t **target) { - return (dns_acl_anyornone(mctx, false, target)); -} - -/* - * Create a new ACL that matches nothing. - */ -isc_result_t -dns_acl_none(isc_mem_t *mctx, dns_acl_t **target) { - return (dns_acl_anyornone(mctx, true, target)); -} - -/* - * If pos is true, test whether acl is set to "{ any; }" - * If pos is false, test whether acl is set to "{ none; }" - */ -static bool -dns_acl_isanyornone(dns_acl_t *acl, bool pos) -{ - /* Should never happen but let's be safe */ - if (acl == NULL || - acl->iptable == NULL || - acl->iptable->radix == NULL || - acl->iptable->radix->head == NULL || - acl->iptable->radix->head->prefix == NULL) - return (false); - - if (acl->length != 0 || dns_acl_node_count(acl) != 1) - return (false); - - if (acl->iptable->radix->head->prefix->bitlen == 0 && - acl->iptable->radix->head->data[0] != NULL && - acl->iptable->radix->head->data[0] == - acl->iptable->radix->head->data[1] && - *(bool *) (acl->iptable->radix->head->data[0]) == pos) - return (true); - - return (false); /* All others */ -} - -/* - * Test whether acl is set to "{ any; }" - */ -bool -dns_acl_isany(dns_acl_t *acl) -{ - return (dns_acl_isanyornone(acl, true)); -} - -/* - * Test whether acl is set to "{ none; }" - */ -bool -dns_acl_isnone(dns_acl_t *acl) -{ - return (dns_acl_isanyornone(acl, false)); -} - -/* - * Determine whether a given address or signer matches a given ACL. - * For a match with a positive ACL element or iptable radix entry, - * return with a positive value in match; for a match with a negated ACL - * element or radix entry, return with a negative value in match. - */ -isc_result_t -dns_acl_match(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const dns_acl_t *acl, - const dns_aclenv_t *env, - int *match, - const dns_aclelement_t **matchelt) -{ - return (dns_acl_match2(reqaddr, reqsigner, NULL, 0, NULL, acl, env, - match, matchelt)); -} - -isc_result_t -dns_acl_match2(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const isc_netaddr_t *ecs, - uint8_t ecslen, - uint8_t *scope, - const dns_acl_t *acl, - const dns_aclenv_t *env, - int *match, - const dns_aclelement_t **matchelt) -{ - uint16_t bitlen; - isc_prefix_t pfx; - isc_radix_node_t *node = NULL; - const isc_netaddr_t *addr = reqaddr; - isc_netaddr_t v4addr; - isc_result_t result; - int match_num = -1; - unsigned int i; - - REQUIRE(reqaddr != NULL); - REQUIRE(matchelt == NULL || *matchelt == NULL); - REQUIRE(ecs != NULL || scope == NULL); - - if (env != NULL && env->match_mapped && - addr->family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&addr->type.in6)) - { - isc_netaddr_fromv4mapped(&v4addr, addr); - addr = &v4addr; - } - - /* Always match with host addresses. */ - bitlen = (addr->family == AF_INET6) ? 128 : 32; - NETADDR_TO_PREFIX_T(addr, pfx, bitlen, false); - - /* Assume no match. */ - *match = 0; - - /* Search radix. */ - result = isc_radix_search(acl->iptable->radix, &node, &pfx); - - /* Found a match. */ - if (result == ISC_R_SUCCESS && node != NULL) { - int fam = ISC_RADIX_FAMILY(&pfx); - match_num = node->node_num[fam]; - if (*(bool *) node->data[fam]) { - *match = match_num; - } else { - *match = -match_num; - } - } - - isc_refcount_destroy(&pfx.refcount); - - /* - * If ecs is not NULL, we search the radix tree again to - * see if we find a better match on an ECS node - */ - if (ecs != NULL) { - node = NULL; - addr = ecs; - - if (env != NULL && env->match_mapped && - addr->family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&addr->type.in6)) - { - isc_netaddr_fromv4mapped(&v4addr, addr); - addr = &v4addr; - } - - NETADDR_TO_PREFIX_T(addr, pfx, ecslen, true); - - result = isc_radix_search(acl->iptable->radix, &node, &pfx); - if (result == ISC_R_SUCCESS && node != NULL) { - int off = ISC_RADIX_FAMILY(&pfx); - if (match_num == -1 || - node->node_num[off] < match_num) - { - match_num = node->node_num[off]; - if (scope != NULL) { - *scope = node->bit; - } - if (*(bool *) node->data[off]) { - *match = match_num; - } else { - *match = -match_num; - } - } - } - - isc_refcount_destroy(&pfx.refcount); - } - - /* Now search non-radix elements for a match with a lower node_num. */ - for (i = 0; i < acl->length; i++) { - dns_aclelement_t *e = &acl->elements[i]; - - /* Already found a better match? */ - if (match_num != -1 && match_num < e->node_num) { - break; - } - - if (dns_aclelement_match2(reqaddr, reqsigner, ecs, ecslen, - scope, e, env, matchelt)) - { - if (match_num == -1 || e->node_num < match_num) { - if (e->negative) - *match = -e->node_num; - else - *match = e->node_num; - } - break; - } - } - - return (ISC_R_SUCCESS); -} - -/* - * Merge the contents of one ACL into another. Call dns_iptable_merge() - * for the IP tables, then concatenate the element arrays. - * - * If pos is set to false, then the nested ACL is to be negated. This - * means reverse the sense of each *positive* element or IP table node, - * but leave negatives alone, so as to prevent a double-negative causing - * an unexpected positive match in the parent ACL. - */ -isc_result_t -dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, bool pos) -{ - isc_result_t result; - unsigned int newalloc, nelem, i; - int max_node = 0, nodes; - - /* Resize the element array if needed. */ - if (dest->length + source->length > dest->alloc) { - void *newmem; - - newalloc = dest->alloc + source->alloc; - if (newalloc < 4) - newalloc = 4; - - newmem = isc_mem_get(dest->mctx, - newalloc * sizeof(dns_aclelement_t)); - if (newmem == NULL) - return (ISC_R_NOMEMORY); - - /* Zero. */ - memset(newmem, 0, newalloc * sizeof(dns_aclelement_t)); - - /* Copy in the original elements */ - memmove(newmem, dest->elements, - dest->length * sizeof(dns_aclelement_t)); - - /* Release the memory for the old elements array */ - isc_mem_put(dest->mctx, dest->elements, - dest->alloc * sizeof(dns_aclelement_t)); - dest->elements = newmem; - dest->alloc = newalloc; - } - - /* - * Now copy in the new elements, increasing their node_num - * values so as to keep the new ACL consistent. If we're - * negating, then negate positive elements, but keep negative - * elements the same for security reasons. - */ - nelem = dest->length; - dest->length += source->length; - for (i = 0; i < source->length; i++) { - if (source->elements[i].node_num > max_node) - max_node = source->elements[i].node_num; - - /* Copy type. */ - dest->elements[nelem + i].type = source->elements[i].type; - - /* Adjust node numbering. */ - dest->elements[nelem + i].node_num = - source->elements[i].node_num + dns_acl_node_count(dest); - - /* Duplicate nested acl. */ - if (source->elements[i].type == dns_aclelementtype_nestedacl && - source->elements[i].nestedacl != NULL) - dns_acl_attach(source->elements[i].nestedacl, - &dest->elements[nelem + i].nestedacl); - - /* Duplicate key name. */ - if (source->elements[i].type == dns_aclelementtype_keyname) { - dns_name_init(&dest->elements[nelem+i].keyname, NULL); - result = dns_name_dup(&source->elements[i].keyname, - dest->mctx, - &dest->elements[nelem+i].keyname); - if (result != ISC_R_SUCCESS) - return result; - } - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - /* Duplicate GeoIP data */ - if (source->elements[i].type == dns_aclelementtype_geoip) { - dest->elements[nelem + i].geoip_elem = - source->elements[i].geoip_elem; - } -#endif - - /* reverse sense of positives if this is a negative acl */ - if (!pos && !source->elements[i].negative) { - dest->elements[nelem + i].negative = true; - } else { - dest->elements[nelem + i].negative = - source->elements[i].negative; - } - } - - /* - * Merge the iptables. Make sure the destination ACL's - * node_count value is set correctly afterward. - */ - nodes = max_node + dns_acl_node_count(dest); - result = dns_iptable_merge(dest->iptable, source->iptable, pos); - if (result != ISC_R_SUCCESS) - return (result); - if (nodes > dns_acl_node_count(dest)) - dns_acl_node_count(dest) = nodes; - - return (ISC_R_SUCCESS); -} - -/* - * Like dns_acl_match, but matches against the single ACL element 'e' - * rather than a complete ACL, and returns true iff it matched. - * - * To determine whether the match was positive or negative, the - * caller should examine e->negative. Since the element 'e' may be - * a reference to a named ACL or a nested ACL, a matching element - * returned through 'matchelt' is not necessarily 'e' itself. - */ -bool -dns_aclelement_match(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const dns_aclelement_t *e, - const dns_aclenv_t *env, - const dns_aclelement_t **matchelt) -{ - return (dns_aclelement_match2(reqaddr, reqsigner, NULL, 0, NULL, - e, env, matchelt)); -} - -bool -dns_aclelement_match2(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const isc_netaddr_t *ecs, - uint8_t ecslen, - uint8_t *scope, - const dns_aclelement_t *e, - const dns_aclenv_t *env, - const dns_aclelement_t **matchelt) -{ - dns_acl_t *inner = NULL; - int indirectmatch; - isc_result_t result; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - const isc_netaddr_t *addr = NULL; -#endif - - REQUIRE(ecs != NULL || scope == NULL); - - switch (e->type) { - case dns_aclelementtype_keyname: - if (reqsigner != NULL && - dns_name_equal(reqsigner, &e->keyname)) { - if (matchelt != NULL) - *matchelt = e; - return (true); - } else - return (false); - - case dns_aclelementtype_nestedacl: - inner = e->nestedacl; - break; - - case dns_aclelementtype_localhost: - if (env == NULL || env->localhost == NULL) - return (false); - inner = env->localhost; - break; - - case dns_aclelementtype_localnets: - if (env == NULL || env->localnets == NULL) - return (false); - inner = env->localnets; - break; - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - case dns_aclelementtype_geoip: - if (env == NULL || env->geoip == NULL) - return (false); - addr = (env->geoip_use_ecs && ecs != NULL) ? ecs : reqaddr; - return (dns_geoip_match(addr, scope, env->geoip, - &e->geoip_elem)); -#endif - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - result = dns_acl_match2(reqaddr, reqsigner, ecs, ecslen, scope, - inner, env, &indirectmatch, matchelt); - INSIST(result == ISC_R_SUCCESS); - - /* - * Treat negative matches in indirect ACLs as "no match". - * That way, a negated indirect ACL will never become a - * surprise positive match through double negation. - * XXXDCL this should be documented. - */ - if (indirectmatch > 0) { - if (matchelt != NULL) - *matchelt = e; - return (true); - } - - /* - * A negative indirect match may have set *matchelt, but we don't - * want it set when we return. - */ - if (matchelt != NULL) - *matchelt = NULL; - - return (false); -} - -void -dns_acl_attach(dns_acl_t *source, dns_acl_t **target) { - REQUIRE(DNS_ACL_VALID(source)); - - isc_refcount_increment(&source->refcount, NULL); - *target = source; -} - -static void -destroy(dns_acl_t *dacl) { - unsigned int i; - - INSIST(!ISC_LINK_LINKED(dacl, nextincache)); - - for (i = 0; i < dacl->length; i++) { - dns_aclelement_t *de = &dacl->elements[i]; - if (de->type == dns_aclelementtype_keyname) { - dns_name_free(&de->keyname, dacl->mctx); - } else if (de->type == dns_aclelementtype_nestedacl) { - dns_acl_detach(&de->nestedacl); - } - } - if (dacl->elements != NULL) - isc_mem_put(dacl->mctx, dacl->elements, - dacl->alloc * sizeof(dns_aclelement_t)); - if (dacl->name != NULL) - isc_mem_free(dacl->mctx, dacl->name); - if (dacl->iptable != NULL) - dns_iptable_detach(&dacl->iptable); - isc_refcount_destroy(&dacl->refcount); - dacl->magic = 0; - isc_mem_putanddetach(&dacl->mctx, dacl, sizeof(*dacl)); -} - -void -dns_acl_detach(dns_acl_t **aclp) { - dns_acl_t *acl = *aclp; - unsigned int refs; - - REQUIRE(DNS_ACL_VALID(acl)); - - *aclp = NULL; - - isc_refcount_decrement(&acl->refcount, &refs); - if (refs == 0) - destroy(acl); -} - - -static isc_once_t insecure_prefix_once = ISC_ONCE_INIT; -static isc_mutex_t insecure_prefix_lock; -static bool insecure_prefix_found; - -static void -initialize_action(void) { - RUNTIME_CHECK(isc_mutex_init(&insecure_prefix_lock) == ISC_R_SUCCESS); -} - -/* - * Called via isc_radix_process() to find IP table nodes that are - * insecure. - */ -static void -is_insecure(isc_prefix_t *prefix, void **data) { - /* - * If all nonexistent or negative then this node is secure. - */ - if ((data[0] == NULL || !* (bool *) data[0]) && - (data[1] == NULL || !* (bool *) data[1]) && - (data[2] == NULL || !* (bool *) data[2]) && - (data[3] == NULL || !* (bool *) data[3])) - return; - - /* - * If a loopback address found and the other family and - * ecs entry doesn't exist or is negative, return. - */ - if (prefix->bitlen == 32 && - htonl(prefix->add.sin.s_addr) == INADDR_LOOPBACK && - (data[1] == NULL || !* (bool *) data[1]) && - (data[2] == NULL || !* (bool *) data[2]) && - (data[3] == NULL || !* (bool *) data[3])) - return; - - if (prefix->bitlen == 128 && - IN6_IS_ADDR_LOOPBACK(&prefix->add.sin6) && - (data[0] == NULL || !* (bool *) data[0]) && - (data[2] == NULL || !* (bool *) data[2]) && - (data[3] == NULL || !* (bool *) data[3])) - return; - - /* Non-negated, non-loopback */ - insecure_prefix_found = true; /* LOCKED */ - return; -} - -/* - * Return true iff the acl 'a' is considered insecure, that is, - * if it contains IP addresses other than those of the local host. - * This is intended for applications such as printing warning - * messages for suspect ACLs; it is not intended for making access - * control decisions. We make no guarantee that an ACL for which - * this function returns false is safe. - */ -bool -dns_acl_isinsecure(const dns_acl_t *a) { - unsigned int i; - bool insecure; - - RUNTIME_CHECK(isc_once_do(&insecure_prefix_once, - initialize_action) == ISC_R_SUCCESS); - - /* - * Walk radix tree to find out if there are any non-negated, - * non-loopback prefixes. - */ - LOCK(&insecure_prefix_lock); - insecure_prefix_found = false; - isc_radix_process(a->iptable->radix, is_insecure); - insecure = insecure_prefix_found; - UNLOCK(&insecure_prefix_lock); - if (insecure) - return (true); - - /* Now check non-radix elements */ - for (i = 0; i < a->length; i++) { - dns_aclelement_t *e = &a->elements[i]; - - /* A negated match can never be insecure. */ - if (e->negative) - continue; - - switch (e->type) { - case dns_aclelementtype_keyname: - case dns_aclelementtype_localhost: - continue; - - case dns_aclelementtype_nestedacl: - if (dns_acl_isinsecure(e->nestedacl)) - return (true); - continue; - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - case dns_aclelementtype_geoip: -#endif - case dns_aclelementtype_localnets: - return (true); - - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } - - /* No insecure elements were found. */ - return (false); -} - -/* - * Initialize ACL environment, setting up localhost and localnets ACLs - */ -isc_result_t -dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) { - isc_result_t result; - - env->localhost = NULL; - env->localnets = NULL; - result = dns_acl_create(mctx, 0, &env->localhost); - if (result != ISC_R_SUCCESS) - goto cleanup_nothing; - result = dns_acl_create(mctx, 0, &env->localnets); - if (result != ISC_R_SUCCESS) - goto cleanup_localhost; - env->match_mapped = false; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - env->geoip = NULL; - env->geoip_use_ecs = false; -#endif - return (ISC_R_SUCCESS); - - cleanup_localhost: - dns_acl_detach(&env->localhost); - cleanup_nothing: - return (result); -} - -void -dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) { - dns_acl_detach(&t->localhost); - dns_acl_attach(s->localhost, &t->localhost); - dns_acl_detach(&t->localnets); - dns_acl_attach(s->localnets, &t->localnets); - t->match_mapped = s->match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - t->geoip_use_ecs = s->geoip_use_ecs; - t->geoip = s->geoip; -#endif -} - -void -dns_aclenv_destroy(dns_aclenv_t *env) { - dns_acl_detach(&env->localhost); - dns_acl_detach(&env->localnets); -} diff --git a/lib/dns-pkcs11/adb.c b/lib/dns-pkcs11/adb.c deleted file mode 100644 index e12c804..0000000 --- a/lib/dns-pkcs11/adb.c +++ /dev/null @@ -1,4841 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file - * - * \note - * In finds, if task == NULL, no events will be generated, and no events - * have been sent. If task != NULL but taskaction == NULL, an event has been - * posted but not yet freed. If neither are NULL, no event was posted. - * - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b') -#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC) -#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N') -#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC) -#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H') -#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC) -#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z') -#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC) -#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E') -#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC) -#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4') -#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC) -#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6') -#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC) - -/*! - * For type 3 negative cache entries, we will remember that the address is - * broken for this long. XXXMLG This is also used for actual addresses, too. - * The intent is to keep us from constantly asking about A/AAAA records - * if the zone has extremely low TTLs. - */ -#define ADB_CACHE_MINIMUM 10 /*%< seconds */ -#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */ -#define ADB_ENTRY_WINDOW 1800 /*%< seconds */ - -/*% - * The period in seconds after which an ADB name entry is regarded as stale - * and forced to be cleaned up. - * TODO: This should probably be configurable at run-time. - */ -#ifndef ADB_STALE_MARGIN -#define ADB_STALE_MARGIN 1800 -#endif - -#define FREE_ITEMS 64 /*%< free count for memory pools */ -#define FILL_COUNT 16 /*%< fill count for memory pools */ - -#define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */ - -#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */ - -typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; -typedef struct dns_adbnamehook dns_adbnamehook_t; -typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t; -typedef struct dns_adblameinfo dns_adblameinfo_t; -typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t; -typedef struct dns_adbfetch dns_adbfetch_t; -typedef struct dns_adbfetch6 dns_adbfetch6_t; - -/*% dns adb structure */ -struct dns_adb { - unsigned int magic; - - isc_mutex_t lock; - isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */ - isc_mutex_t overmemlock; /*%< Covers overmem */ - isc_mem_t *mctx; - dns_view_t *view; - - isc_taskmgr_t *taskmgr; - isc_task_t *task; - isc_task_t *excl; - - isc_interval_t tick_interval; - int next_cleanbucket; - - unsigned int irefcnt; - unsigned int erefcnt; - - isc_mutex_t mplock; - isc_mempool_t *nmp; /*%< dns_adbname_t */ - isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */ - isc_mempool_t *limp; /*%< dns_adblameinfo_t */ - isc_mempool_t *emp; /*%< dns_adbentry_t */ - isc_mempool_t *ahmp; /*%< dns_adbfind_t */ - isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */ - isc_mempool_t *afmp; /*%< dns_adbfetch_t */ - - /*! - * Bucketized locks and lists for names. - * - * XXXRTH Have a per-bucket structure that contains all of these? - */ - unsigned int nnames; - isc_mutex_t namescntlock; - unsigned int namescnt; - dns_adbnamelist_t *names; - dns_adbnamelist_t *deadnames; - isc_mutex_t *namelocks; - bool *name_sd; - unsigned int *name_refcnt; - - /*! - * Bucketized locks and lists for entries. - * - * XXXRTH Have a per-bucket structure that contains all of these? - */ - unsigned int nentries; - isc_mutex_t entriescntlock; - unsigned int entriescnt; - dns_adbentrylist_t *entries; - dns_adbentrylist_t *deadentries; - isc_mutex_t *entrylocks; - bool *entry_sd; /*%< shutting down */ - unsigned int *entry_refcnt; - - isc_event_t cevent; - bool cevent_out; - bool shutting_down; - isc_eventlist_t whenshutdown; - isc_event_t growentries; - bool growentries_sent; - isc_event_t grownames; - bool grownames_sent; - - uint32_t quota; - uint32_t atr_freq; - double atr_low; - double atr_high; - double atr_discount; -}; - -/* - * XXXMLG Document these structures. - */ - -/*% dns_adbname structure */ -struct dns_adbname { - unsigned int magic; - dns_name_t name; - dns_adb_t *adb; - unsigned int partial_result; - unsigned int flags; - int lock_bucket; - dns_name_t target; - isc_stdtime_t expire_target; - isc_stdtime_t expire_v4; - isc_stdtime_t expire_v6; - unsigned int chains; - dns_adbnamehooklist_t v4; - dns_adbnamehooklist_t v6; - dns_adbfetch_t *fetch_a; - dns_adbfetch_t *fetch_aaaa; - unsigned int fetch_err; - unsigned int fetch6_err; - dns_adbfindlist_t finds; - /* for LRU-based management */ - isc_stdtime_t last_used; - - ISC_LINK(dns_adbname_t) plink; -}; - -/*% The adbfetch structure */ -struct dns_adbfetch { - unsigned int magic; - dns_fetch_t *fetch; - dns_rdataset_t rdataset; - unsigned int depth; -}; - -/*% - * This is a small widget that dangles off a dns_adbname_t. It contains a - * pointer to the address information about this host, and a link to the next - * namehook that will contain the next address this host has. - */ -struct dns_adbnamehook { - unsigned int magic; - dns_adbentry_t *entry; - ISC_LINK(dns_adbnamehook_t) plink; -}; - -/*% - * This is a small widget that holds qname-specific information about an - * address. Currently limited to lameness, but could just as easily be - * extended to other types of information about zones. - */ -struct dns_adblameinfo { - unsigned int magic; - - dns_name_t qname; - dns_rdatatype_t qtype; - isc_stdtime_t lame_timer; - - ISC_LINK(dns_adblameinfo_t) plink; -}; - -/*% - * An address entry. It holds quite a bit of information about addresses, - * including edns state (in "flags"), rtt, and of course the address of - * the host. - */ -struct dns_adbentry { - unsigned int magic; - - int lock_bucket; - unsigned int refcnt; - unsigned int nh; - - unsigned int flags; - unsigned int srtt; - uint16_t udpsize; - unsigned int completed; - unsigned int timeouts; - unsigned char plain; - unsigned char plainto; - unsigned char edns; - unsigned char to4096; /* Our max. */ - - uint8_t mode; - uint32_t quota; - uint32_t active; - double atr; - - /* - * Allow for encapsulated IPv4/IPv6 UDP packet over ethernet. - * Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432. - */ - unsigned char to1432; /* Ethernet */ - unsigned char to1232; /* IPv6 nofrag */ - unsigned char to512; /* plain DNS */ - isc_sockaddr_t sockaddr; - unsigned char * cookie; - uint16_t cookielen; - - isc_stdtime_t expires; - isc_stdtime_t lastage; - /*%< - * A nonzero 'expires' field indicates that the entry should - * persist until that time. This allows entries found - * using dns_adb_findaddrinfo() to persist for a limited time - * even though they are not necessarily associated with a - * name. - */ - - ISC_LIST(dns_adblameinfo_t) lameinfo; - ISC_LINK(dns_adbentry_t) plink; -}; - -/* - * Internal functions (and prototypes). - */ -static inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *); -static inline void free_adbname(dns_adb_t *, dns_adbname_t **); -static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *, - dns_adbentry_t *); -static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **); -static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *, - dns_rdatatype_t); -static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **); -static inline dns_adbentry_t *new_adbentry(dns_adb_t *); -static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **); -static inline dns_adbfind_t *new_adbfind(dns_adb_t *); -static inline bool free_adbfind(dns_adb_t *, dns_adbfind_t **); -static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, - in_port_t); -static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *); -static inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **); -static inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *, - unsigned int, int *); -static inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *, - isc_sockaddr_t *, int *, - isc_stdtime_t); -static void dump_adb(dns_adb_t *, FILE *, bool debug, isc_stdtime_t); -static void print_dns_name(FILE *, dns_name_t *); -static void print_namehook_list(FILE *, const char *legend, - dns_adb_t *adb, - dns_adbnamehooklist_t *list, - bool debug, - isc_stdtime_t now); -static void print_find_list(FILE *, dns_adbname_t *); -static void print_fetch_list(FILE *, dns_adbname_t *); -static inline bool dec_adb_irefcnt(dns_adb_t *); -static inline void inc_adb_irefcnt(dns_adb_t *); -static inline void inc_adb_erefcnt(dns_adb_t *); -static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *, - bool); -static inline bool dec_entry_refcnt(dns_adb_t *, bool, - dns_adbentry_t *, bool); -static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *); -static bool clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *); -static void clean_target(dns_adb_t *, dns_name_t *); -static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int); -static bool check_expire_namehooks(dns_adbname_t *, isc_stdtime_t); -static bool check_expire_entry(dns_adb_t *, dns_adbentry_t **, - isc_stdtime_t); -static void cancel_fetches_at_name(dns_adbname_t *); -static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t, - dns_rdatatype_t); -static isc_result_t fetch_name(dns_adbname_t *, bool, - unsigned int, isc_counter_t *qc, - dns_rdatatype_t); -static inline void check_exit(dns_adb_t *); -static void destroy(dns_adb_t *); -static bool shutdown_names(dns_adb_t *); -static bool shutdown_entries(dns_adb_t *); -static inline void link_name(dns_adb_t *, int, dns_adbname_t *); -static inline bool unlink_name(dns_adb_t *, dns_adbname_t *); -static inline void link_entry(dns_adb_t *, int, dns_adbentry_t *); -static inline bool unlink_entry(dns_adb_t *, dns_adbentry_t *); -static bool kill_name(dns_adbname_t **, isc_eventtype_t); -static void water(void *, int); -static void dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *, - bool, isc_stdtime_t); -static void adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, - unsigned int factor, isc_stdtime_t now); -static void shutdown_task(isc_task_t *task, isc_event_t *ev); -static void log_quota(dns_adbentry_t *entry, const char *fmt, ...) - ISC_FORMAT_PRINTF(2, 3); - -/* - * MUST NOT overlap DNS_ADBFIND_* flags! - */ -#define FIND_EVENT_SENT 0x40000000 -#define FIND_EVENT_FREED 0x80000000 -#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0) -#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0) - -#define NAME_NEEDS_POKE 0x80000000 -#define NAME_IS_DEAD 0x40000000 -#define NAME_HINT_OK DNS_ADBFIND_HINTOK -#define NAME_GLUE_OK DNS_ADBFIND_GLUEOK -#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE -#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0) -#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0) -#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0) -#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0) - -/* - * Private flag(s) for entries. - * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0. - */ -#define ENTRY_IS_DEAD 0x00400000 - -/* - * To the name, address classes are all that really exist. If it has a - * V6 address it doesn't care if it came from a AAAA query. - */ -#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4)) -#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6)) -#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n)) - -/* - * Fetches are broken out into A and AAAA types. In some cases, - * however, it makes more sense to test for a particular class of fetches, - * like V4 or V6 above. - * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA - * are now equal to FETCH_V4 and FETCH_V6, respectively. - */ -#define NAME_FETCH_A(n) ((n)->fetch_a != NULL) -#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL) -#define NAME_FETCH_V4(n) (NAME_FETCH_A(n)) -#define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n)) -#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n)) - -/* - * Find options and tests to see if there are addresses on the list. - */ -#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0) -#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0) -#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0) -#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) != 0) -#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0) -#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0) -#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list)) -#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0) -#define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0) - -/* - * These are currently used on simple unsigned ints, so they are - * not really associated with any particular type. - */ -#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0) -#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0) - -#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now)) - -/* - * Find out if the flags on a name (nf) indicate if it is a hint or - * glue, and compare this to the appropriate bits set in o, to see if - * this is ok. - */ -#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0)) -#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0)) -#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o)) -#define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \ - ((o) & DNS_ADBFIND_STARTATZONE)) - -#define ENTER_LEVEL ISC_LOG_DEBUG(50) -#define EXIT_LEVEL ENTER_LEVEL -#define CLEAN_LEVEL ISC_LOG_DEBUG(100) -#define DEF_LEVEL ISC_LOG_DEBUG(5) -#define NCACHE_LEVEL ISC_LOG_DEBUG(20) - -#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \ - (r) == DNS_R_NCACHENXRRSET) -#define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || \ - (r) == DNS_R_NXRRSET) -#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \ - (r) == DNS_R_NCACHENXDOMAIN) -#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \ - (r) == DNS_R_NXRRSET || \ - (r) == DNS_R_HINTNXRRSET) - -/* - * Error state rankings. - */ - -#define FIND_ERR_SUCCESS 0 /* highest rank */ -#define FIND_ERR_CANCELED 1 -#define FIND_ERR_FAILURE 2 -#define FIND_ERR_NXDOMAIN 3 -#define FIND_ERR_NXRRSET 4 -#define FIND_ERR_UNEXPECTED 5 -#define FIND_ERR_NOTFOUND 6 -#define FIND_ERR_MAX 7 - -static const char *errnames[] = { - "success", - "canceled", - "failure", - "nxdomain", - "nxrrset", - "unexpected", - "not_found" -}; - -#define NEWERR(old, new) (ISC_MIN((old), (new))) - -static isc_result_t find_err_map[FIND_ERR_MAX] = { - ISC_R_SUCCESS, - ISC_R_CANCELED, - ISC_R_FAILURE, - DNS_R_NXDOMAIN, - DNS_R_NXRRSET, - ISC_R_UNEXPECTED, - ISC_R_NOTFOUND /* not YET found */ -}; - -static void -DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); - -static void -DP(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - level, format, args); - va_end(args); -} - -/*% - * Increment resolver-related statistics counters. - */ -static inline void -inc_stats(dns_adb_t *adb, isc_statscounter_t counter) { - if (adb->view->resstats != NULL) - isc_stats_increment(adb->view->resstats, counter); -} - -/*% - * Set adb-related statistics counters. - */ -static inline void -set_adbstat(dns_adb_t *adb, uint64_t val, isc_statscounter_t counter) { - if (adb->view->adbstats != NULL) - isc_stats_set(adb->view->adbstats, val, counter); -} - -static inline void -dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { - if (adb->view->adbstats != NULL) - isc_stats_decrement(adb->view->adbstats, counter); -} - -static inline void -inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { - if (adb->view->adbstats != NULL) - isc_stats_increment(adb->view->adbstats, counter); -} - -static inline dns_ttl_t -ttlclamp(dns_ttl_t ttl) { - if (ttl < ADB_CACHE_MINIMUM) - ttl = ADB_CACHE_MINIMUM; - if (ttl > ADB_CACHE_MAXIMUM) - ttl = ADB_CACHE_MAXIMUM; - - return (ttl); -} - -/* - * Hashing is most efficient if the number of buckets is prime. - * The sequence below is the closest previous primes to 2^n and - * 1.5 * 2^n, for values of n from 10 to 28. (The tables will - * no longer grow beyond 2^28 entries.) - */ -static const unsigned nbuckets[] = { 1021, 1531, 2039, 3067, 4093, 6143, - 8191, 12281, 16381, 24571, 32749, - 49193, 65521, 98299, 131071, 199603, - 262139, 393209, 524287, 768431, 1048573, - 1572853, 2097143, 3145721, 4194301, - 6291449, 8388593, 12582893, 16777213, - 25165813, 33554393, 50331599, 67108859, - 100663291, 134217689, 201326557, - 268535431, 0 }; - -static void -grow_entries(isc_task_t *task, isc_event_t *ev) { - dns_adb_t *adb; - dns_adbentry_t *e; - dns_adbentrylist_t *newdeadentries = NULL; - dns_adbentrylist_t *newentries = NULL; - bool *newentry_sd = NULL; - isc_mutex_t *newentrylocks = NULL; - isc_result_t result; - unsigned int *newentry_refcnt = NULL; - unsigned int i, n, bucket; - - adb = ev->ev_arg; - INSIST(DNS_ADB_VALID(adb)); - - isc_event_free(&ev); - - result = isc_task_beginexclusive(task); - if (result != ISC_R_SUCCESS) - goto check_exit; - - i = 0; - while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i]) - i++; - if (nbuckets[i] != 0) - n = nbuckets[i]; - else - goto done; - - DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n); - - /* - * Are we shutting down? - */ - for (i = 0; i < adb->nentries; i++) - if (adb->entry_sd[i]) - goto cleanup; - - /* - * Grab all the resources we need. - */ - newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n); - newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n); - newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n); - newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n); - newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n); - if (newentries == NULL || newdeadentries == NULL || - newentrylocks == NULL || newentry_sd == NULL || - newentry_refcnt == NULL) - goto cleanup; - - /* - * Initialise the new resources. - */ - result = isc_mutexblock_init(newentrylocks, n); - if (result != ISC_R_SUCCESS) - goto cleanup; - - for (i = 0; i < n; i++) { - ISC_LIST_INIT(newentries[i]); - ISC_LIST_INIT(newdeadentries[i]); - newentry_sd[i] = false; - newentry_refcnt[i] = 0; - adb->irefcnt++; - } - - /* - * Move entries to new arrays. - */ - for (i = 0; i < adb->nentries; i++) { - e = ISC_LIST_HEAD(adb->entries[i]); - while (e != NULL) { - ISC_LIST_UNLINK(adb->entries[i], e, plink); - bucket = isc_sockaddr_hash(&e->sockaddr, true) % n; - e->lock_bucket = bucket; - ISC_LIST_APPEND(newentries[bucket], e, plink); - INSIST(adb->entry_refcnt[i] > 0); - adb->entry_refcnt[i]--; - newentry_refcnt[bucket]++; - e = ISC_LIST_HEAD(adb->entries[i]); - } - e = ISC_LIST_HEAD(adb->deadentries[i]); - while (e != NULL) { - ISC_LIST_UNLINK(adb->deadentries[i], e, plink); - bucket = isc_sockaddr_hash(&e->sockaddr, true) % n; - e->lock_bucket = bucket; - ISC_LIST_APPEND(newdeadentries[bucket], e, plink); - INSIST(adb->entry_refcnt[i] > 0); - adb->entry_refcnt[i]--; - newentry_refcnt[bucket]++; - e = ISC_LIST_HEAD(adb->deadentries[i]); - } - INSIST(adb->entry_refcnt[i] == 0); - adb->irefcnt--; - } - - /* - * Cleanup old resources. - */ - DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); - isc_mem_put(adb->mctx, adb->entries, - sizeof(*adb->entries) * adb->nentries); - isc_mem_put(adb->mctx, adb->deadentries, - sizeof(*adb->deadentries) * adb->nentries); - isc_mem_put(adb->mctx, adb->entrylocks, - sizeof(*adb->entrylocks) * adb->nentries); - isc_mem_put(adb->mctx, adb->entry_sd, - sizeof(*adb->entry_sd) * adb->nentries); - isc_mem_put(adb->mctx, adb->entry_refcnt, - sizeof(*adb->entry_refcnt) * adb->nentries); - - /* - * Install new resources. - */ - adb->entries = newentries; - adb->deadentries = newdeadentries; - adb->entrylocks = newentrylocks; - adb->entry_sd = newentry_sd; - adb->entry_refcnt = newentry_refcnt; - adb->nentries = n; - - set_adbstat(adb, adb->nentries, dns_adbstats_nentries); - - /* - * Only on success do we set adb->growentries_sent to false. - * This will prevent us being continuously being called on error. - */ - adb->growentries_sent = false; - goto done; - - cleanup: - if (newentries != NULL) - isc_mem_put(adb->mctx, newentries, - sizeof(*newentries) * n); - if (newdeadentries != NULL) - isc_mem_put(adb->mctx, newdeadentries, - sizeof(*newdeadentries) * n); - if (newentrylocks != NULL) - isc_mem_put(adb->mctx, newentrylocks, - sizeof(*newentrylocks) * n); - if (newentry_sd != NULL) - isc_mem_put(adb->mctx, newentry_sd, - sizeof(*newentry_sd) * n); - if (newentry_refcnt != NULL) - isc_mem_put(adb->mctx, newentry_refcnt, - sizeof(*newentry_refcnt) * n); - done: - isc_task_endexclusive(task); - - check_exit: - LOCK(&adb->lock); - if (dec_adb_irefcnt(adb)) - check_exit(adb); - UNLOCK(&adb->lock); - DP(ISC_LOG_INFO, "adb: grow_entries finished"); -} - -static void -grow_names(isc_task_t *task, isc_event_t *ev) { - dns_adb_t *adb; - dns_adbname_t *name; - dns_adbnamelist_t *newdeadnames = NULL; - dns_adbnamelist_t *newnames = NULL; - bool *newname_sd = NULL; - isc_mutex_t *newnamelocks = NULL; - isc_result_t result; - unsigned int *newname_refcnt = NULL; - unsigned int i, n, bucket; - - adb = ev->ev_arg; - INSIST(DNS_ADB_VALID(adb)); - - isc_event_free(&ev); - - result = isc_task_beginexclusive(task); - if (result != ISC_R_SUCCESS) - goto check_exit; - - i = 0; - while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) - i++; - if (nbuckets[i] != 0) - n = nbuckets[i]; - else - goto done; - - DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n); - - /* - * Are we shutting down? - */ - for (i = 0; i < adb->nnames; i++) - if (adb->name_sd[i]) - goto cleanup; - - /* - * Grab all the resources we need. - */ - newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n); - newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n); - newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n); - newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n); - newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n); - if (newnames == NULL || newdeadnames == NULL || - newnamelocks == NULL || newname_sd == NULL || - newname_refcnt == NULL) - goto cleanup; - - /* - * Initialise the new resources. - */ - result = isc_mutexblock_init(newnamelocks, n); - if (result != ISC_R_SUCCESS) - goto cleanup; - - for (i = 0; i < n; i++) { - ISC_LIST_INIT(newnames[i]); - ISC_LIST_INIT(newdeadnames[i]); - newname_sd[i] = false; - newname_refcnt[i] = 0; - adb->irefcnt++; - } - - /* - * Move names to new arrays. - */ - for (i = 0; i < adb->nnames; i++) { - name = ISC_LIST_HEAD(adb->names[i]); - while (name != NULL) { - ISC_LIST_UNLINK(adb->names[i], name, plink); - bucket = dns_name_fullhash(&name->name, true) % n; - name->lock_bucket = bucket; - ISC_LIST_APPEND(newnames[bucket], name, plink); - INSIST(adb->name_refcnt[i] > 0); - adb->name_refcnt[i]--; - newname_refcnt[bucket]++; - name = ISC_LIST_HEAD(adb->names[i]); - } - name = ISC_LIST_HEAD(adb->deadnames[i]); - while (name != NULL) { - ISC_LIST_UNLINK(adb->deadnames[i], name, plink); - bucket = dns_name_fullhash(&name->name, true) % n; - name->lock_bucket = bucket; - ISC_LIST_APPEND(newdeadnames[bucket], name, plink); - INSIST(adb->name_refcnt[i] > 0); - adb->name_refcnt[i]--; - newname_refcnt[bucket]++; - name = ISC_LIST_HEAD(adb->deadnames[i]); - } - INSIST(adb->name_refcnt[i] == 0); - adb->irefcnt--; - } - - /* - * Cleanup old resources. - */ - DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); - isc_mem_put(adb->mctx, adb->names, - sizeof(*adb->names) * adb->nnames); - isc_mem_put(adb->mctx, adb->deadnames, - sizeof(*adb->deadnames) * adb->nnames); - isc_mem_put(adb->mctx, adb->namelocks, - sizeof(*adb->namelocks) * adb->nnames); - isc_mem_put(adb->mctx, adb->name_sd, - sizeof(*adb->name_sd) * adb->nnames); - isc_mem_put(adb->mctx, adb->name_refcnt, - sizeof(*adb->name_refcnt) * adb->nnames); - - /* - * Install new resources. - */ - adb->names = newnames; - adb->deadnames = newdeadnames; - adb->namelocks = newnamelocks; - adb->name_sd = newname_sd; - adb->name_refcnt = newname_refcnt; - adb->nnames = n; - - set_adbstat(adb, adb->nnames, dns_adbstats_nnames); - - /* - * Only on success do we set adb->grownames_sent to false. - * This will prevent us being continuously being called on error. - */ - adb->grownames_sent = false; - goto done; - - cleanup: - if (newnames != NULL) - isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n); - if (newdeadnames != NULL) - isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n); - if (newnamelocks != NULL) - isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n); - if (newname_sd != NULL) - isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n); - if (newname_refcnt != NULL) - isc_mem_put(adb->mctx, newname_refcnt, - sizeof(*newname_refcnt) * n); - done: - isc_task_endexclusive(task); - - check_exit: - LOCK(&adb->lock); - if (dec_adb_irefcnt(adb)) - check_exit(adb); - UNLOCK(&adb->lock); - DP(ISC_LOG_INFO, "adb: grow_names finished"); -} - -/* - * Requires the adbname bucket be locked and that no entry buckets be locked. - * - * This code handles A and AAAA rdatasets only. - */ -static isc_result_t -import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset, - isc_stdtime_t now) -{ - isc_result_t result; - dns_adb_t *adb; - dns_adbnamehook_t *nh; - dns_adbnamehook_t *anh; - dns_rdata_t rdata = DNS_RDATA_INIT; - struct in_addr ina; - struct in6_addr in6a; - isc_sockaddr_t sockaddr; - dns_adbentry_t *foundentry; /* NO CLEAN UP! */ - int addr_bucket; - bool new_addresses_added; - dns_rdatatype_t rdtype; - unsigned int findoptions; - dns_adbnamehooklist_t *hookhead; - - INSIST(DNS_ADBNAME_VALID(adbname)); - adb = adbname->adb; - INSIST(DNS_ADB_VALID(adb)); - - rdtype = rdataset->type; - INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa)); - if (rdtype == dns_rdatatype_a) - findoptions = DNS_ADBFIND_INET; - else - findoptions = DNS_ADBFIND_INET6; - - addr_bucket = DNS_ADB_INVALIDBUCKET; - new_addresses_added = false; - - nh = NULL; - result = dns_rdataset_first(rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - if (rdtype == dns_rdatatype_a) { - INSIST(rdata.length == 4); - memmove(&ina.s_addr, rdata.data, 4); - isc_sockaddr_fromin(&sockaddr, &ina, 0); - hookhead = &adbname->v4; - } else { - INSIST(rdata.length == 16); - memmove(in6a.s6_addr, rdata.data, 16); - isc_sockaddr_fromin6(&sockaddr, &in6a, 0); - hookhead = &adbname->v6; - } - - INSIST(nh == NULL); - nh = new_adbnamehook(adb, NULL); - if (nh == NULL) { - adbname->partial_result |= findoptions; - result = ISC_R_NOMEMORY; - goto fail; - } - - foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket, - now); - if (foundentry == NULL) { - dns_adbentry_t *entry; - - entry = new_adbentry(adb); - if (entry == NULL) { - adbname->partial_result |= findoptions; - result = ISC_R_NOMEMORY; - goto fail; - } - - entry->sockaddr = sockaddr; - entry->refcnt = 1; - entry->nh = 1; - - nh->entry = entry; - - link_entry(adb, addr_bucket, entry); - } else { - for (anh = ISC_LIST_HEAD(*hookhead); - anh != NULL; - anh = ISC_LIST_NEXT(anh, plink)) - if (anh->entry == foundentry) - break; - if (anh == NULL) { - foundentry->refcnt++; - foundentry->nh++; - nh->entry = foundentry; - } else - free_adbnamehook(adb, &nh); - } - - new_addresses_added = true; - if (nh != NULL) - ISC_LIST_APPEND(*hookhead, nh, plink); - nh = NULL; - result = dns_rdataset_next(rdataset); - } - - fail: - if (nh != NULL) - free_adbnamehook(adb, &nh); - - if (addr_bucket != DNS_ADB_INVALIDBUCKET) - UNLOCK(&adb->entrylocks[addr_bucket]); - - if (rdataset->trust == dns_trust_glue || - rdataset->trust == dns_trust_additional) - rdataset->ttl = ADB_CACHE_MINIMUM; - else if (rdataset->trust == dns_trust_ultimate) - rdataset->ttl = 0; - else - rdataset->ttl = ttlclamp(rdataset->ttl); - - if (rdtype == dns_rdatatype_a) { - DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset", - adbname->expire_v4, now + rdataset->ttl); - adbname->expire_v4 = ISC_MIN(adbname->expire_v4, - ISC_MIN(now + ADB_ENTRY_WINDOW, - now + rdataset->ttl)); - } else { - DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset", - adbname->expire_v6, now + rdataset->ttl); - adbname->expire_v6 = ISC_MIN(adbname->expire_v6, - ISC_MIN(now + ADB_ENTRY_WINDOW, - now + rdataset->ttl)); - } - - if (new_addresses_added) { - /* - * Lie a little here. This is more or less so code that cares - * can find out if any new information was added or not. - */ - return (ISC_R_SUCCESS); - } - - return (result); -} - -/* - * Requires the name's bucket be locked. - */ -static bool -kill_name(dns_adbname_t **n, isc_eventtype_t ev) { - dns_adbname_t *name; - bool result = false; - bool result4, result6; - int bucket; - dns_adb_t *adb; - - INSIST(n != NULL); - name = *n; - *n = NULL; - INSIST(DNS_ADBNAME_VALID(name)); - adb = name->adb; - INSIST(DNS_ADB_VALID(adb)); - - DP(DEF_LEVEL, "killing name %p", name); - - /* - * If we're dead already, just check to see if we should go - * away now or not. - */ - if (NAME_DEAD(name) && !NAME_FETCH(name)) { - result = unlink_name(adb, name); - free_adbname(adb, &name); - if (result) - result = dec_adb_irefcnt(adb); - return (result); - } - - /* - * Clean up the name's various lists. These two are destructive - * in that they will always empty the list. - */ - clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK); - result4 = clean_namehooks(adb, &name->v4); - result6 = clean_namehooks(adb, &name->v6); - clean_target(adb, &name->target); - result = (result4 || result6); - - /* - * If fetches are running, cancel them. If none are running, we can - * just kill the name here. - */ - if (!NAME_FETCH(name)) { - INSIST(result == false); - result = unlink_name(adb, name); - free_adbname(adb, &name); - if (result) - result = dec_adb_irefcnt(adb); - } else { - cancel_fetches_at_name(name); - if (!NAME_DEAD(name)) { - bucket = name->lock_bucket; - ISC_LIST_UNLINK(adb->names[bucket], name, plink); - ISC_LIST_APPEND(adb->deadnames[bucket], name, plink); - name->flags |= NAME_IS_DEAD; - } - } - return (result); -} - -/* - * Requires the name's bucket be locked and no entry buckets be locked. - */ -static bool -check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) { - dns_adb_t *adb; - bool result4 = false; - bool result6 = false; - - INSIST(DNS_ADBNAME_VALID(name)); - adb = name->adb; - INSIST(DNS_ADB_VALID(adb)); - - /* - * Check to see if we need to remove the v4 addresses - */ - if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) { - if (NAME_HAS_V4(name)) { - DP(DEF_LEVEL, "expiring v4 for name %p", name); - result4 = clean_namehooks(adb, &name->v4); - name->partial_result &= ~DNS_ADBFIND_INET; - } - name->expire_v4 = INT_MAX; - name->fetch_err = FIND_ERR_UNEXPECTED; - } - - /* - * Check to see if we need to remove the v6 addresses - */ - if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) { - if (NAME_HAS_V6(name)) { - DP(DEF_LEVEL, "expiring v6 for name %p", name); - result6 = clean_namehooks(adb, &name->v6); - name->partial_result &= ~DNS_ADBFIND_INET6; - } - name->expire_v6 = INT_MAX; - name->fetch6_err = FIND_ERR_UNEXPECTED; - } - - /* - * Check to see if we need to remove the alias target. - */ - if (EXPIRE_OK(name->expire_target, now)) { - clean_target(adb, &name->target); - name->expire_target = INT_MAX; - } - return (result4 || result6); -} - -/* - * Requires the name's bucket be locked. - */ -static inline void -link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) { - INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET); - - ISC_LIST_PREPEND(adb->names[bucket], name, plink); - name->lock_bucket = bucket; - adb->name_refcnt[bucket]++; -} - -/* - * Requires the name's bucket be locked. - */ -static inline bool -unlink_name(dns_adb_t *adb, dns_adbname_t *name) { - int bucket; - bool result = false; - - bucket = name->lock_bucket; - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - - if (NAME_DEAD(name)) - ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink); - else - ISC_LIST_UNLINK(adb->names[bucket], name, plink); - name->lock_bucket = DNS_ADB_INVALIDBUCKET; - INSIST(adb->name_refcnt[bucket] > 0); - adb->name_refcnt[bucket]--; - if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0) - result = true; - return (result); -} - -/* - * Requires the entry's bucket be locked. - */ -static inline void -link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) { - int i; - dns_adbentry_t *e; - - if (isc_mem_isovermem(adb->mctx)) { - for (i = 0; i < 2; i++) { - e = ISC_LIST_TAIL(adb->entries[bucket]); - if (e == NULL) - break; - if (e->refcnt == 0) { - unlink_entry(adb, e); - free_adbentry(adb, &e); - continue; - } - INSIST((e->flags & ENTRY_IS_DEAD) == 0); - e->flags |= ENTRY_IS_DEAD; - ISC_LIST_UNLINK(adb->entries[bucket], e, plink); - ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink); - } - } - - ISC_LIST_PREPEND(adb->entries[bucket], entry, plink); - entry->lock_bucket = bucket; - adb->entry_refcnt[bucket]++; -} - -/* - * Requires the entry's bucket be locked. - */ -static inline bool -unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) { - int bucket; - bool result = false; - - bucket = entry->lock_bucket; - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - - if ((entry->flags & ENTRY_IS_DEAD) != 0) - ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink); - else - ISC_LIST_UNLINK(adb->entries[bucket], entry, plink); - entry->lock_bucket = DNS_ADB_INVALIDBUCKET; - INSIST(adb->entry_refcnt[bucket] > 0); - adb->entry_refcnt[bucket]--; - if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0) - result = true; - return (result); -} - -static inline void -violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) { - if (isc_mutex_trylock(want) != ISC_R_SUCCESS) { - UNLOCK(have); - LOCK(want); - LOCK(have); - } -} - -/* - * The ADB _MUST_ be locked before calling. Also, exit conditions must be - * checked after calling this function. - */ -static bool -shutdown_names(dns_adb_t *adb) { - unsigned int bucket; - bool result = false; - dns_adbname_t *name; - dns_adbname_t *next_name; - - for (bucket = 0; bucket < adb->nnames; bucket++) { - LOCK(&adb->namelocks[bucket]); - adb->name_sd[bucket] = true; - - name = ISC_LIST_HEAD(adb->names[bucket]); - if (name == NULL) { - /* - * This bucket has no names. We must decrement the - * irefcnt ourselves, since it will not be - * automatically triggered by a name being unlinked. - */ - INSIST(result == false); - result = dec_adb_irefcnt(adb); - } else { - /* - * Run through the list. For each name, clean up finds - * found there, and cancel any fetches running. When - * all the fetches are canceled, the name will destroy - * itself. - */ - while (name != NULL) { - next_name = ISC_LIST_NEXT(name, plink); - INSIST(result == false); - result = kill_name(&name, - DNS_EVENT_ADBSHUTDOWN); - name = next_name; - } - } - - UNLOCK(&adb->namelocks[bucket]); - } - return (result); -} - -/* - * The ADB _MUST_ be locked before calling. Also, exit conditions must be - * checked after calling this function. - */ -static bool -shutdown_entries(dns_adb_t *adb) { - unsigned int bucket; - bool result = false; - dns_adbentry_t *entry; - dns_adbentry_t *next_entry; - - for (bucket = 0; bucket < adb->nentries; bucket++) { - LOCK(&adb->entrylocks[bucket]); - adb->entry_sd[bucket] = true; - - entry = ISC_LIST_HEAD(adb->entries[bucket]); - if (adb->entry_refcnt[bucket] == 0) { - /* - * This bucket has no entries. We must decrement the - * irefcnt ourselves, since it will not be - * automatically triggered by an entry being unlinked. - */ - result = dec_adb_irefcnt(adb); - } else { - /* - * Run through the list. Cleanup any entries not - * associated with names, and which are not in use. - */ - while (entry != NULL) { - next_entry = ISC_LIST_NEXT(entry, plink); - if (entry->refcnt == 0 && - entry->expires != 0) { - result = unlink_entry(adb, entry); - free_adbentry(adb, &entry); - if (result) - result = dec_adb_irefcnt(adb); - } - entry = next_entry; - } - } - - UNLOCK(&adb->entrylocks[bucket]); - } - return (result); -} - -/* - * Name bucket must be locked - */ -static void -cancel_fetches_at_name(dns_adbname_t *name) { - if (NAME_FETCH_A(name)) - dns_resolver_cancelfetch(name->fetch_a->fetch); - - if (NAME_FETCH_AAAA(name)) - dns_resolver_cancelfetch(name->fetch_aaaa->fetch); -} - -/* - * Assumes the name bucket is locked. - */ -static bool -clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { - dns_adbentry_t *entry; - dns_adbnamehook_t *namehook; - int addr_bucket; - bool result = false; - bool overmem = isc_mem_isovermem(adb->mctx); - - addr_bucket = DNS_ADB_INVALIDBUCKET; - namehook = ISC_LIST_HEAD(*namehooks); - while (namehook != NULL) { - INSIST(DNS_ADBNAMEHOOK_VALID(namehook)); - - /* - * Clean up the entry if needed. - */ - entry = namehook->entry; - if (entry != NULL) { - INSIST(DNS_ADBENTRY_VALID(entry)); - - if (addr_bucket != entry->lock_bucket) { - if (addr_bucket != DNS_ADB_INVALIDBUCKET) - UNLOCK(&adb->entrylocks[addr_bucket]); - addr_bucket = entry->lock_bucket; - INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET); - LOCK(&adb->entrylocks[addr_bucket]); - } - - entry->nh--; - result = dec_entry_refcnt(adb, overmem, entry, - false); - } - - /* - * Free the namehook - */ - namehook->entry = NULL; - ISC_LIST_UNLINK(*namehooks, namehook, plink); - free_adbnamehook(adb, &namehook); - - namehook = ISC_LIST_HEAD(*namehooks); - } - - if (addr_bucket != DNS_ADB_INVALIDBUCKET) - UNLOCK(&adb->entrylocks[addr_bucket]); - return (result); -} - -static void -clean_target(dns_adb_t *adb, dns_name_t *target) { - if (dns_name_countlabels(target) > 0) { - dns_name_free(target, adb->mctx); - dns_name_init(target, NULL); - } -} - -static isc_result_t -set_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname, - dns_rdataset_t *rdataset, dns_name_t *target) -{ - isc_result_t result; - dns_namereln_t namereln; - unsigned int nlabels; - int order; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_fixedname_t fixed1, fixed2; - dns_name_t *prefix, *new_target; - - REQUIRE(dns_name_countlabels(target) == 0); - - if (rdataset->type == dns_rdatatype_cname) { - dns_rdata_cname_t cname; - - /* - * Copy the CNAME's target into the target name. - */ - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_name_dup(&cname.cname, adb->mctx, target); - dns_rdata_freestruct(&cname); - if (result != ISC_R_SUCCESS) - return (result); - } else { - dns_rdata_dname_t dname; - - INSIST(rdataset->type == dns_rdatatype_dname); - namereln = dns_name_fullcompare(name, fname, &order, &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Get the target name of the DNAME. - */ - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dname, NULL); - if (result != ISC_R_SUCCESS) - return (result); - /* - * Construct the new target name. - */ - prefix = dns_fixedname_initname(&fixed1); - new_target = dns_fixedname_initname(&fixed2); - dns_name_split(name, nlabels, prefix, NULL); - result = dns_name_concatenate(prefix, &dname.dname, new_target, - NULL); - dns_rdata_freestruct(&dname); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_name_dup(new_target, adb->mctx, target); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (ISC_R_SUCCESS); -} - -/* - * Assumes nothing is locked, since this is called by the client. - */ -static void -event_free(isc_event_t *event) { - dns_adbfind_t *find; - - INSIST(event != NULL); - find = event->ev_destroy_arg; - INSIST(DNS_ADBFIND_VALID(find)); - - LOCK(&find->lock); - find->flags |= FIND_EVENT_FREED; - event->ev_destroy_arg = NULL; - UNLOCK(&find->lock); -} - -/* - * Assumes the name bucket is locked. - */ -static void -clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype, - unsigned int addrs) -{ - isc_event_t *ev; - isc_task_t *task; - dns_adbfind_t *find; - dns_adbfind_t *next_find; - bool process; - unsigned int wanted, notify; - - DP(ENTER_LEVEL, - "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", - name, evtype, addrs); - - find = ISC_LIST_HEAD(name->finds); - while (find != NULL) { - LOCK(&find->lock); - next_find = ISC_LIST_NEXT(find, plink); - - process = false; - wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; - notify = wanted & addrs; - - switch (evtype) { - case DNS_EVENT_ADBMOREADDRESSES: - DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES"); - if ((notify) != 0) { - find->flags &= ~addrs; - process = true; - } - break; - case DNS_EVENT_ADBNOMOREADDRESSES: - DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES"); - find->flags &= ~addrs; - wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; - if (wanted == 0) - process = true; - break; - default: - find->flags &= ~addrs; - process = true; - } - - if (process) { - DP(DEF_LEVEL, "cfan: processing find %p", find); - /* - * Unlink the find from the name, letting the caller - * call dns_adb_destroyfind() on it to clean it up - * later. - */ - ISC_LIST_UNLINK(name->finds, find, plink); - find->adbname = NULL; - find->name_bucket = DNS_ADB_INVALIDBUCKET; - - INSIST(!FIND_EVENTSENT(find)); - - ev = &find->event; - task = ev->ev_sender; - ev->ev_sender = find; - find->result_v4 = find_err_map[name->fetch_err]; - find->result_v6 = find_err_map[name->fetch6_err]; - ev->ev_type = evtype; - ev->ev_destroy = event_free; - ev->ev_destroy_arg = find; - - DP(DEF_LEVEL, - "sending event %p to task %p for find %p", - ev, task, find); - - isc_task_sendanddetach(&task, (isc_event_t **)&ev); - find->flags |= FIND_EVENT_SENT; - } else { - DP(DEF_LEVEL, "cfan: skipping find %p", find); - } - - UNLOCK(&find->lock); - find = next_find; - } - - DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name); -} - -static inline void -check_exit(dns_adb_t *adb) { - isc_event_t *event; - /* - * The caller must be holding the adb lock. - */ - if (adb->shutting_down) { - /* - * If there aren't any external references either, we're - * done. Send the control event to initiate shutdown. - */ - INSIST(!adb->cevent_out); /* Sanity check. */ - ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, - DNS_EVENT_ADBCONTROL, shutdown_task, adb, - adb, NULL, NULL); - event = &adb->cevent; - isc_task_send(adb->task, &event); - adb->cevent_out = true; - } -} - -static inline bool -dec_adb_irefcnt(dns_adb_t *adb) { - isc_event_t *event; - isc_task_t *etask; - bool result = false; - - LOCK(&adb->reflock); - - INSIST(adb->irefcnt > 0); - adb->irefcnt--; - - if (adb->irefcnt == 0) { - event = ISC_LIST_HEAD(adb->whenshutdown); - while (event != NULL) { - ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link); - etask = event->ev_sender; - event->ev_sender = adb; - isc_task_sendanddetach(&etask, &event); - event = ISC_LIST_HEAD(adb->whenshutdown); - } - } - - if (adb->irefcnt == 0 && adb->erefcnt == 0) - result = true; - UNLOCK(&adb->reflock); - return (result); -} - -static inline void -inc_adb_irefcnt(dns_adb_t *adb) { - LOCK(&adb->reflock); - adb->irefcnt++; - UNLOCK(&adb->reflock); -} - -static inline void -inc_adb_erefcnt(dns_adb_t *adb) { - LOCK(&adb->reflock); - adb->erefcnt++; - UNLOCK(&adb->reflock); -} - -static inline void -inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, bool lock) { - int bucket; - - bucket = entry->lock_bucket; - - if (lock) - LOCK(&adb->entrylocks[bucket]); - - entry->refcnt++; - - if (lock) - UNLOCK(&adb->entrylocks[bucket]); -} - -static inline bool -dec_entry_refcnt(dns_adb_t *adb, bool overmem, dns_adbentry_t *entry, - bool lock) -{ - int bucket; - bool destroy_entry; - bool result = false; - - bucket = entry->lock_bucket; - - if (lock) - LOCK(&adb->entrylocks[bucket]); - - INSIST(entry->refcnt > 0); - entry->refcnt--; - - destroy_entry = false; - if (entry->refcnt == 0 && - (adb->entry_sd[bucket] || entry->expires == 0 || overmem || - (entry->flags & ENTRY_IS_DEAD) != 0)) { - destroy_entry = true; - result = unlink_entry(adb, entry); - } - - if (lock) - UNLOCK(&adb->entrylocks[bucket]); - - if (!destroy_entry) - return (result); - - entry->lock_bucket = DNS_ADB_INVALIDBUCKET; - - free_adbentry(adb, &entry); - if (result) - result = dec_adb_irefcnt(adb); - - return (result); -} - -static inline dns_adbname_t * -new_adbname(dns_adb_t *adb, dns_name_t *dnsname) { - dns_adbname_t *name; - - name = isc_mempool_get(adb->nmp); - if (name == NULL) - return (NULL); - - dns_name_init(&name->name, NULL); - if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) { - isc_mempool_put(adb->nmp, name); - return (NULL); - } - dns_name_init(&name->target, NULL); - name->magic = DNS_ADBNAME_MAGIC; - name->adb = adb; - name->partial_result = 0; - name->flags = 0; - name->expire_v4 = INT_MAX; - name->expire_v6 = INT_MAX; - name->expire_target = INT_MAX; - name->chains = 0; - name->lock_bucket = DNS_ADB_INVALIDBUCKET; - ISC_LIST_INIT(name->v4); - ISC_LIST_INIT(name->v6); - name->fetch_a = NULL; - name->fetch_aaaa = NULL; - name->fetch_err = FIND_ERR_UNEXPECTED; - name->fetch6_err = FIND_ERR_UNEXPECTED; - ISC_LIST_INIT(name->finds); - ISC_LINK_INIT(name, plink); - - LOCK(&adb->namescntlock); - adb->namescnt++; - inc_adbstats(adb, dns_adbstats_namescnt); - if (!adb->grownames_sent && adb->excl != NULL && - adb->namescnt > (adb->nnames * 8)) - { - isc_event_t *event = &adb->grownames; - inc_adb_irefcnt(adb); - isc_task_send(adb->excl, &event); - adb->grownames_sent = true; - } - UNLOCK(&adb->namescntlock); - - return (name); -} - -static inline void -free_adbname(dns_adb_t *adb, dns_adbname_t **name) { - dns_adbname_t *n; - - INSIST(name != NULL && DNS_ADBNAME_VALID(*name)); - n = *name; - *name = NULL; - - INSIST(!NAME_HAS_V4(n)); - INSIST(!NAME_HAS_V6(n)); - INSIST(!NAME_FETCH(n)); - INSIST(ISC_LIST_EMPTY(n->finds)); - INSIST(!ISC_LINK_LINKED(n, plink)); - INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET); - INSIST(n->adb == adb); - - n->magic = 0; - dns_name_free(&n->name, adb->mctx); - - isc_mempool_put(adb->nmp, n); - LOCK(&adb->namescntlock); - adb->namescnt--; - dec_adbstats(adb, dns_adbstats_namescnt); - UNLOCK(&adb->namescntlock); -} - -static inline dns_adbnamehook_t * -new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) { - dns_adbnamehook_t *nh; - - nh = isc_mempool_get(adb->nhmp); - if (nh == NULL) - return (NULL); - - nh->magic = DNS_ADBNAMEHOOK_MAGIC; - nh->entry = entry; - ISC_LINK_INIT(nh, plink); - - return (nh); -} - -static inline void -free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) { - dns_adbnamehook_t *nh; - - INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook)); - nh = *namehook; - *namehook = NULL; - - INSIST(nh->entry == NULL); - INSIST(!ISC_LINK_LINKED(nh, plink)); - - nh->magic = 0; - isc_mempool_put(adb->nhmp, nh); -} - -static inline dns_adblameinfo_t * -new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) { - dns_adblameinfo_t *li; - - li = isc_mempool_get(adb->limp); - if (li == NULL) - return (NULL); - - dns_name_init(&li->qname, NULL); - if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) { - isc_mempool_put(adb->limp, li); - return (NULL); - } - li->magic = DNS_ADBLAMEINFO_MAGIC; - li->lame_timer = 0; - li->qtype = qtype; - ISC_LINK_INIT(li, plink); - - return (li); -} - -static inline void -free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) { - dns_adblameinfo_t *li; - - INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo)); - li = *lameinfo; - *lameinfo = NULL; - - INSIST(!ISC_LINK_LINKED(li, plink)); - - dns_name_free(&li->qname, adb->mctx); - - li->magic = 0; - - isc_mempool_put(adb->limp, li); -} - -static inline dns_adbentry_t * -new_adbentry(dns_adb_t *adb) { - dns_adbentry_t *e; - uint32_t r; - - e = isc_mempool_get(adb->emp); - if (e == NULL) - return (NULL); - - e->magic = DNS_ADBENTRY_MAGIC; - e->lock_bucket = DNS_ADB_INVALIDBUCKET; - e->refcnt = 0; - e->nh = 0; - e->flags = 0; - e->udpsize = 0; - e->edns = 0; - e->completed = 0; - e->timeouts = 0; - e->plain = 0; - e->plainto = 0; - e->to4096 = 0; - e->to1432 = 0; - e->to1232 = 0; - e->to512 = 0; - e->cookie = NULL; - e->cookielen = 0; - isc_random_get(&r); - e->srtt = (r & 0x1f) + 1; - e->lastage = 0; - e->expires = 0; - e->active = 0; - e->mode = 0; - e->quota = adb->quota; - e->atr = 0.0; - ISC_LIST_INIT(e->lameinfo); - ISC_LINK_INIT(e, plink); - LOCK(&adb->entriescntlock); - adb->entriescnt++; - inc_adbstats(adb, dns_adbstats_entriescnt); - if (!adb->growentries_sent && adb->excl != NULL && - adb->entriescnt > (adb->nentries * 8)) - { - isc_event_t *event = &adb->growentries; - inc_adb_irefcnt(adb); - isc_task_send(adb->excl, &event); - adb->growentries_sent = true; - } - UNLOCK(&adb->entriescntlock); - - return (e); -} - -static inline void -free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) { - dns_adbentry_t *e; - dns_adblameinfo_t *li; - - INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry)); - e = *entry; - *entry = NULL; - - INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET); - INSIST(e->refcnt == 0); - INSIST(!ISC_LINK_LINKED(e, plink)); - - e->magic = 0; - - if (e->cookie != NULL) - isc_mem_put(adb->mctx, e->cookie, e->cookielen); - - li = ISC_LIST_HEAD(e->lameinfo); - while (li != NULL) { - ISC_LIST_UNLINK(e->lameinfo, li, plink); - free_adblameinfo(adb, &li); - li = ISC_LIST_HEAD(e->lameinfo); - } - - isc_mempool_put(adb->emp, e); - LOCK(&adb->entriescntlock); - adb->entriescnt--; - dec_adbstats(adb, dns_adbstats_entriescnt); - UNLOCK(&adb->entriescntlock); -} - -static inline dns_adbfind_t * -new_adbfind(dns_adb_t *adb) { - dns_adbfind_t *h; - isc_result_t result; - - h = isc_mempool_get(adb->ahmp); - if (h == NULL) - return (NULL); - - /* - * Public members. - */ - h->magic = 0; - h->adb = adb; - h->partial_result = 0; - h->options = 0; - h->flags = 0; - h->result_v4 = ISC_R_UNEXPECTED; - h->result_v6 = ISC_R_UNEXPECTED; - ISC_LINK_INIT(h, publink); - ISC_LINK_INIT(h, plink); - ISC_LIST_INIT(h->list); - h->adbname = NULL; - h->name_bucket = DNS_ADB_INVALIDBUCKET; - - /* - * private members - */ - result = isc_mutex_init(&h->lock); - if (result != ISC_R_SUCCESS) { - isc_mempool_put(adb->ahmp, h); - return (NULL); - } - - ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL, - NULL, NULL, h); - - inc_adb_irefcnt(adb); - h->magic = DNS_ADBFIND_MAGIC; - return (h); -} - -static inline dns_adbfetch_t * -new_adbfetch(dns_adb_t *adb) { - dns_adbfetch_t *f; - - f = isc_mempool_get(adb->afmp); - if (f == NULL) - return (NULL); - - f->magic = 0; - f->fetch = NULL; - - dns_rdataset_init(&f->rdataset); - - f->magic = DNS_ADBFETCH_MAGIC; - - return (f); -} - -static inline void -free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) { - dns_adbfetch_t *f; - - INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch)); - f = *fetch; - *fetch = NULL; - - f->magic = 0; - - if (dns_rdataset_isassociated(&f->rdataset)) - dns_rdataset_disassociate(&f->rdataset); - - isc_mempool_put(adb->afmp, f); -} - -static inline bool -free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) { - dns_adbfind_t *find; - - INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp)); - find = *findp; - *findp = NULL; - - INSIST(!FIND_HAS_ADDRS(find)); - INSIST(!ISC_LINK_LINKED(find, publink)); - INSIST(!ISC_LINK_LINKED(find, plink)); - INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET); - INSIST(find->adbname == NULL); - - find->magic = 0; - - DESTROYLOCK(&find->lock); - isc_mempool_put(adb->ahmp, find); - return (dec_adb_irefcnt(adb)); -} - -/* - * Copy bits from the entry into the newly allocated addrinfo. The entry - * must be locked, and the reference count must be bumped up by one - * if this function returns a valid pointer. - */ -static inline dns_adbaddrinfo_t * -new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) { - dns_adbaddrinfo_t *ai; - - ai = isc_mempool_get(adb->aimp); - if (ai == NULL) - return (NULL); - - ai->magic = DNS_ADBADDRINFO_MAGIC; - ai->sockaddr = entry->sockaddr; - isc_sockaddr_setport(&ai->sockaddr, port); - ai->srtt = entry->srtt; - ai->flags = entry->flags; - ai->entry = entry; - ai->dscp = -1; - ISC_LINK_INIT(ai, publink); - - return (ai); -} - -static inline void -free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) { - dns_adbaddrinfo_t *ai; - - INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo)); - ai = *ainfo; - *ainfo = NULL; - - INSIST(ai->entry == NULL); - INSIST(!ISC_LINK_LINKED(ai, publink)); - - ai->magic = 0; - - isc_mempool_put(adb->aimp, ai); -} - -/* - * Search for the name. NOTE: The bucket is kept locked on both - * success and failure, so it must always be unlocked by the caller! - * - * On the first call to this function, *bucketp must be set to - * DNS_ADB_INVALIDBUCKET. - */ -static inline dns_adbname_t * -find_name_and_lock(dns_adb_t *adb, dns_name_t *name, - unsigned int options, int *bucketp) -{ - dns_adbname_t *adbname; - int bucket; - - bucket = dns_name_fullhash(name, false) % adb->nnames; - - if (*bucketp == DNS_ADB_INVALIDBUCKET) { - LOCK(&adb->namelocks[bucket]); - *bucketp = bucket; - } else if (*bucketp != bucket) { - UNLOCK(&adb->namelocks[*bucketp]); - LOCK(&adb->namelocks[bucket]); - *bucketp = bucket; - } - - adbname = ISC_LIST_HEAD(adb->names[bucket]); - while (adbname != NULL) { - if (!NAME_DEAD(adbname)) { - if (dns_name_equal(name, &adbname->name) - && GLUEHINT_OK(adbname, options) - && STARTATZONE_MATCHES(adbname, options)) - return (adbname); - } - adbname = ISC_LIST_NEXT(adbname, plink); - } - - return (NULL); -} - -/* - * Search for the address. NOTE: The bucket is kept locked on both - * success and failure, so it must always be unlocked by the caller. - * - * On the first call to this function, *bucketp must be set to - * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On - * later calls (within the same "lock path") it can be left alone, so - * if this function is called multiple times locking is only done if - * the bucket changes. - */ -static inline dns_adbentry_t * -find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp, - isc_stdtime_t now) -{ - dns_adbentry_t *entry, *entry_next; - int bucket; - - bucket = isc_sockaddr_hash(addr, true) % adb->nentries; - - if (*bucketp == DNS_ADB_INVALIDBUCKET) { - LOCK(&adb->entrylocks[bucket]); - *bucketp = bucket; - } else if (*bucketp != bucket) { - UNLOCK(&adb->entrylocks[*bucketp]); - LOCK(&adb->entrylocks[bucket]); - *bucketp = bucket; - } - - /* Search the list, while cleaning up expired entries. */ - for (entry = ISC_LIST_HEAD(adb->entries[bucket]); - entry != NULL; - entry = entry_next) { - entry_next = ISC_LIST_NEXT(entry, plink); - (void)check_expire_entry(adb, &entry, now); - if (entry != NULL && - (entry->expires == 0 || entry->expires > now) && - isc_sockaddr_equal(addr, &entry->sockaddr)) { - ISC_LIST_UNLINK(adb->entries[bucket], entry, plink); - ISC_LIST_PREPEND(adb->entries[bucket], entry, plink); - return (entry); - } - } - - return (NULL); -} - -/* - * Entry bucket MUST be locked! - */ -static bool -entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname, - dns_rdatatype_t qtype, isc_stdtime_t now) -{ - dns_adblameinfo_t *li, *next_li; - bool is_bad; - - is_bad = false; - - li = ISC_LIST_HEAD(entry->lameinfo); - if (li == NULL) - return (false); - while (li != NULL) { - next_li = ISC_LIST_NEXT(li, plink); - - /* - * Has the entry expired? - */ - if (li->lame_timer < now) { - ISC_LIST_UNLINK(entry->lameinfo, li, plink); - free_adblameinfo(adb, &li); - } - - /* - * Order tests from least to most expensive. - * - * We do not break out of the main loop here as - * we use the loop for house keeping. - */ - if (li != NULL && !is_bad && li->qtype == qtype && - dns_name_equal(qname, &li->qname)) - is_bad = true; - - li = next_li; - } - - return (is_bad); -} - -static void -log_quota(dns_adbentry_t *entry, const char *fmt, ...) { - va_list ap; - char msgbuf[2048]; - char addrbuf[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_t netaddr; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); - isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_INFO, "adb: quota %s (%u/%u): %s", - addrbuf, entry->active, entry->quota, msgbuf); -} - -static void -copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, - dns_rdatatype_t qtype, dns_adbname_t *name, - isc_stdtime_t now) -{ - dns_adbnamehook_t *namehook; - dns_adbaddrinfo_t *addrinfo; - dns_adbentry_t *entry; - int bucket; - - bucket = DNS_ADB_INVALIDBUCKET; - - if ((find->options & DNS_ADBFIND_INET) != 0) { - namehook = ISC_LIST_HEAD(name->v4); - while (namehook != NULL) { - entry = namehook->entry; - bucket = entry->lock_bucket; - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - LOCK(&adb->entrylocks[bucket]); - - if (entry->quota != 0 && - entry->active >= entry->quota) - { - find->options |= - (DNS_ADBFIND_LAMEPRUNED| - DNS_ADBFIND_OVERQUOTA); - goto nextv4; - } - - if (!FIND_RETURNLAME(find) - && entry_is_lame(adb, entry, qname, qtype, now)) { - find->options |= DNS_ADBFIND_LAMEPRUNED; - goto nextv4; - } - addrinfo = new_adbaddrinfo(adb, entry, find->port); - if (addrinfo == NULL) { - find->partial_result |= DNS_ADBFIND_INET; - goto out; - } - /* - * Found a valid entry. Add it to the find's list. - */ - inc_entry_refcnt(adb, entry, false); - ISC_LIST_APPEND(find->list, addrinfo, publink); - addrinfo = NULL; - nextv4: - UNLOCK(&adb->entrylocks[bucket]); - bucket = DNS_ADB_INVALIDBUCKET; - namehook = ISC_LIST_NEXT(namehook, plink); - } - } - - if ((find->options & DNS_ADBFIND_INET6) != 0) { - namehook = ISC_LIST_HEAD(name->v6); - while (namehook != NULL) { - entry = namehook->entry; - bucket = entry->lock_bucket; - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - LOCK(&adb->entrylocks[bucket]); - - if (entry->quota != 0 && - entry->active >= entry->quota) - { - find->options |= - (DNS_ADBFIND_LAMEPRUNED| - DNS_ADBFIND_OVERQUOTA); - goto nextv6; - } - - if (!FIND_RETURNLAME(find) - && entry_is_lame(adb, entry, qname, qtype, now)) { - find->options |= DNS_ADBFIND_LAMEPRUNED; - goto nextv6; - } - addrinfo = new_adbaddrinfo(adb, entry, find->port); - if (addrinfo == NULL) { - find->partial_result |= DNS_ADBFIND_INET6; - goto out; - } - /* - * Found a valid entry. Add it to the find's list. - */ - inc_entry_refcnt(adb, entry, false); - ISC_LIST_APPEND(find->list, addrinfo, publink); - addrinfo = NULL; - nextv6: - UNLOCK(&adb->entrylocks[bucket]); - bucket = DNS_ADB_INVALIDBUCKET; - namehook = ISC_LIST_NEXT(namehook, plink); - } - } - - out: - if (bucket != DNS_ADB_INVALIDBUCKET) - UNLOCK(&adb->entrylocks[bucket]); -} - -static void -shutdown_task(isc_task_t *task, isc_event_t *ev) { - dns_adb_t *adb; - - UNUSED(task); - - adb = ev->ev_arg; - INSIST(DNS_ADB_VALID(adb)); - - isc_event_free(&ev); - /* - * Wait for lock around check_exit() call to be released. - */ - LOCK(&adb->lock); - UNLOCK(&adb->lock); - destroy(adb); -} - -/* - * Name bucket must be locked; adb may be locked; no other locks held. - */ -static bool -check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) { - dns_adbname_t *name; - bool result = false; - - INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep)); - name = *namep; - - if (NAME_HAS_V4(name) || NAME_HAS_V6(name)) - return (result); - if (NAME_FETCH(name)) - return (result); - if (!EXPIRE_OK(name->expire_v4, now)) - return (result); - if (!EXPIRE_OK(name->expire_v6, now)) - return (result); - if (!EXPIRE_OK(name->expire_target, now)) - return (result); - - /* - * The name is empty. Delete it. - */ - result = kill_name(&name, DNS_EVENT_ADBEXPIRED); - *namep = NULL; - - /* - * Our caller, or one of its callers, will be calling check_exit() at - * some point, so we don't need to do it here. - */ - return (result); -} - -/*% - * Examine the tail entry of the LRU list to see if it expires or is stale - * (unused for some period); if so, the name entry will be freed. If the ADB - * is in the overmem condition, the tail and the next to tail entries - * will be unconditionally removed (unless they have an outstanding fetch). - * We don't care about a race on 'overmem' at the risk of causing some - * collateral damage or a small delay in starting cleanup, so we don't bother - * to lock ADB (if it's not locked). - * - * Name bucket must be locked; adb may be locked; no other locks held. - */ -static void -check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) { - int victims, max_victims; - dns_adbname_t *victim, *next_victim; - bool overmem = isc_mem_isovermem(adb->mctx); - int scans = 0; - - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - - max_victims = overmem ? 2 : 1; - - /* - * We limit the number of scanned entries to 10 (arbitrary choice) - * in order to avoid examining too many entries when there are many - * tail entries that have fetches (this should be rare, but could - * happen). - */ - victim = ISC_LIST_TAIL(adb->names[bucket]); - for (victims = 0; - victim != NULL && victims < max_victims && scans < 10; - victim = next_victim) { - INSIST(!NAME_DEAD(victim)); - scans++; - next_victim = ISC_LIST_PREV(victim, plink); - (void)check_expire_name(&victim, now); - if (victim == NULL) { - victims++; - goto next; - } - - if (!NAME_FETCH(victim) && - (overmem || victim->last_used + ADB_STALE_MARGIN <= now)) { - RUNTIME_CHECK(kill_name(&victim, - DNS_EVENT_ADBCANCELED) == - false); - victims++; - } - - next: - if (!overmem) - break; - } -} - -/* - * Entry bucket must be locked; adb may be locked; no other locks held. - */ -static bool -check_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now) -{ - dns_adbentry_t *entry; - bool result = false; - - INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp)); - entry = *entryp; - - if (entry->refcnt != 0) - return (result); - - if (entry->expires == 0 || entry->expires > now) - return (result); - - /* - * The entry is not in use. Delete it. - */ - DP(DEF_LEVEL, "killing entry %p", entry); - INSIST(ISC_LINK_LINKED(entry, plink)); - result = unlink_entry(adb, entry); - free_adbentry(adb, &entry); - if (result) - dec_adb_irefcnt(adb); - *entryp = NULL; - return (result); -} - -/* - * ADB must be locked, and no other locks held. - */ -static bool -cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) { - dns_adbname_t *name; - dns_adbname_t *next_name; - bool result = false; - - DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket); - - LOCK(&adb->namelocks[bucket]); - if (adb->name_sd[bucket]) { - UNLOCK(&adb->namelocks[bucket]); - return (result); - } - - name = ISC_LIST_HEAD(adb->names[bucket]); - while (name != NULL) { - next_name = ISC_LIST_NEXT(name, plink); - INSIST(result == false); - result = check_expire_namehooks(name, now); - if (!result) - result = check_expire_name(&name, now); - name = next_name; - } - UNLOCK(&adb->namelocks[bucket]); - return (result); -} - -/* - * ADB must be locked, and no other locks held. - */ -static bool -cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) { - dns_adbentry_t *entry, *next_entry; - bool result = false; - - DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket); - - LOCK(&adb->entrylocks[bucket]); - entry = ISC_LIST_HEAD(adb->entries[bucket]); - while (entry != NULL) { - next_entry = ISC_LIST_NEXT(entry, plink); - INSIST(result == false); - result = check_expire_entry(adb, &entry, now); - entry = next_entry; - } - UNLOCK(&adb->entrylocks[bucket]); - return (result); -} - -static void -destroy(dns_adb_t *adb) { - adb->magic = 0; - - isc_task_detach(&adb->task); - if (adb->excl != NULL) - isc_task_detach(&adb->excl); - - isc_mempool_destroy(&adb->nmp); - isc_mempool_destroy(&adb->nhmp); - isc_mempool_destroy(&adb->limp); - isc_mempool_destroy(&adb->emp); - isc_mempool_destroy(&adb->ahmp); - isc_mempool_destroy(&adb->aimp); - isc_mempool_destroy(&adb->afmp); - - DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); - isc_mem_put(adb->mctx, adb->entries, - sizeof(*adb->entries) * adb->nentries); - isc_mem_put(adb->mctx, adb->deadentries, - sizeof(*adb->deadentries) * adb->nentries); - isc_mem_put(adb->mctx, adb->entrylocks, - sizeof(*adb->entrylocks) * adb->nentries); - isc_mem_put(adb->mctx, adb->entry_sd, - sizeof(*adb->entry_sd) * adb->nentries); - isc_mem_put(adb->mctx, adb->entry_refcnt, - sizeof(*adb->entry_refcnt) * adb->nentries); - - DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); - isc_mem_put(adb->mctx, adb->names, - sizeof(*adb->names) * adb->nnames); - isc_mem_put(adb->mctx, adb->deadnames, - sizeof(*adb->deadnames) * adb->nnames); - isc_mem_put(adb->mctx, adb->namelocks, - sizeof(*adb->namelocks) * adb->nnames); - isc_mem_put(adb->mctx, adb->name_sd, - sizeof(*adb->name_sd) * adb->nnames); - isc_mem_put(adb->mctx, adb->name_refcnt, - sizeof(*adb->name_refcnt) * adb->nnames); - - DESTROYLOCK(&adb->reflock); - DESTROYLOCK(&adb->lock); - DESTROYLOCK(&adb->mplock); - DESTROYLOCK(&adb->overmemlock); - DESTROYLOCK(&adb->entriescntlock); - DESTROYLOCK(&adb->namescntlock); - - isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t)); -} - - -/* - * Public functions. - */ - -isc_result_t -dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, - isc_taskmgr_t *taskmgr, dns_adb_t **newadb) -{ - dns_adb_t *adb; - isc_result_t result; - unsigned int i; - - REQUIRE(mem != NULL); - REQUIRE(view != NULL); - REQUIRE(timermgr != NULL); /* this is actually unused */ - REQUIRE(taskmgr != NULL); - REQUIRE(newadb != NULL && *newadb == NULL); - - UNUSED(timermgr); - - adb = isc_mem_get(mem, sizeof(dns_adb_t)); - if (adb == NULL) - return (ISC_R_NOMEMORY); - - /* - * Initialize things here that cannot fail, and especially things - * that must be NULL for the error return to work properly. - */ - adb->magic = 0; - adb->erefcnt = 1; - adb->irefcnt = 0; - adb->nmp = NULL; - adb->nhmp = NULL; - adb->limp = NULL; - adb->emp = NULL; - adb->ahmp = NULL; - adb->aimp = NULL; - adb->afmp = NULL; - adb->task = NULL; - adb->excl = NULL; - adb->mctx = NULL; - adb->view = view; - adb->taskmgr = taskmgr; - adb->next_cleanbucket = 0; - ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), - 0, NULL, 0, NULL, NULL, NULL, NULL, NULL); - adb->cevent_out = false; - adb->shutting_down = false; - ISC_LIST_INIT(adb->whenshutdown); - - adb->nentries = nbuckets[0]; - adb->entriescnt = 0; - adb->entries = NULL; - adb->deadentries = NULL; - adb->entry_sd = NULL; - adb->entry_refcnt = NULL; - adb->entrylocks = NULL; - ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL, - DNS_EVENT_ADBGROWENTRIES, grow_entries, adb, - adb, NULL, NULL); - adb->growentries_sent = false; - - adb->quota = 0; - adb->atr_freq = 0; - adb->atr_low = 0.0; - adb->atr_high = 0.0; - adb->atr_discount = 0.0; - - adb->nnames = nbuckets[0]; - adb->namescnt = 0; - adb->names = NULL; - adb->deadnames = NULL; - adb->name_sd = NULL; - adb->name_refcnt = NULL; - adb->namelocks = NULL; - ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL, - DNS_EVENT_ADBGROWNAMES, grow_names, adb, - adb, NULL, NULL); - adb->grownames_sent = false; - - result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl); - if (result != ISC_R_SUCCESS) { - DP(DEF_LEVEL, "adb: task-exclusive mode unavailable, " - "initializing table sizes to %u\n", - nbuckets[11]); - adb->nentries = nbuckets[11]; - adb->nnames = nbuckets[11]; - } - - isc_mem_attach(mem, &adb->mctx); - - result = isc_mutex_init(&adb->lock); - if (result != ISC_R_SUCCESS) - goto fail0b; - - result = isc_mutex_init(&adb->mplock); - if (result != ISC_R_SUCCESS) - goto fail0c; - - result = isc_mutex_init(&adb->reflock); - if (result != ISC_R_SUCCESS) - goto fail0d; - - result = isc_mutex_init(&adb->overmemlock); - if (result != ISC_R_SUCCESS) - goto fail0e; - - result = isc_mutex_init(&adb->entriescntlock); - if (result != ISC_R_SUCCESS) - goto fail0f; - - result = isc_mutex_init(&adb->namescntlock); - if (result != ISC_R_SUCCESS) - goto fail0g; - -#define ALLOCENTRY(adb, el) \ - do { \ - (adb)->el = isc_mem_get((adb)->mctx, \ - sizeof(*(adb)->el) * (adb)->nentries); \ - if ((adb)->el == NULL) { \ - result = ISC_R_NOMEMORY; \ - goto fail1; \ - }\ - } while (0) - ALLOCENTRY(adb, entries); - ALLOCENTRY(adb, deadentries); - ALLOCENTRY(adb, entrylocks); - ALLOCENTRY(adb, entry_sd); - ALLOCENTRY(adb, entry_refcnt); -#undef ALLOCENTRY - -#define ALLOCNAME(adb, el) \ - do { \ - (adb)->el = isc_mem_get((adb)->mctx, \ - sizeof(*(adb)->el) * (adb)->nnames); \ - if ((adb)->el == NULL) { \ - result = ISC_R_NOMEMORY; \ - goto fail1; \ - }\ - } while (0) - ALLOCNAME(adb, names); - ALLOCNAME(adb, deadnames); - ALLOCNAME(adb, namelocks); - ALLOCNAME(adb, name_sd); - ALLOCNAME(adb, name_refcnt); -#undef ALLOCNAME - - /* - * Initialize the bucket locks for names and elements. - * May as well initialize the list heads, too. - */ - result = isc_mutexblock_init(adb->namelocks, adb->nnames); - if (result != ISC_R_SUCCESS) - goto fail1; - for (i = 0; i < adb->nnames; i++) { - ISC_LIST_INIT(adb->names[i]); - ISC_LIST_INIT(adb->deadnames[i]); - adb->name_sd[i] = false; - adb->name_refcnt[i] = 0; - adb->irefcnt++; - } - for (i = 0; i < adb->nentries; i++) { - ISC_LIST_INIT(adb->entries[i]); - ISC_LIST_INIT(adb->deadentries[i]); - adb->entry_sd[i] = false; - adb->entry_refcnt[i] = 0; - adb->irefcnt++; - } - result = isc_mutexblock_init(adb->entrylocks, adb->nentries); - if (result != ISC_R_SUCCESS) - goto fail2; - - /* - * Memory pools - */ -#define MPINIT(t, p, n) do { \ - result = isc_mempool_create(mem, sizeof(t), &(p)); \ - if (result != ISC_R_SUCCESS) \ - goto fail3; \ - isc_mempool_setfreemax((p), FREE_ITEMS); \ - isc_mempool_setfillcount((p), FILL_COUNT); \ - isc_mempool_setname((p), n); \ - isc_mempool_associatelock((p), &adb->mplock); \ -} while (0) - - MPINIT(dns_adbname_t, adb->nmp, "adbname"); - MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook"); - MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo"); - MPINIT(dns_adbentry_t, adb->emp, "adbentry"); - MPINIT(dns_adbfind_t, adb->ahmp, "adbfind"); - MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo"); - MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch"); - -#undef MPINIT - - /* - * Allocate an internal task. - */ - result = isc_task_create(adb->taskmgr, 0, &adb->task); - if (result != ISC_R_SUCCESS) - goto fail3; - - isc_task_setname(adb->task, "ADB", adb); - - result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max); - if (result != ISC_R_SUCCESS) - goto fail3; - - set_adbstat(adb, adb->nentries, dns_adbstats_nentries); - set_adbstat(adb, adb->nnames, dns_adbstats_nnames); - - /* - * Normal return. - */ - adb->magic = DNS_ADB_MAGIC; - *newadb = adb; - return (ISC_R_SUCCESS); - - fail3: - if (adb->task != NULL) - isc_task_detach(&adb->task); - - /* clean up entrylocks */ - DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); - - fail2: /* clean up namelocks */ - DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); - - fail1: /* clean up only allocated memory */ - if (adb->entries != NULL) - isc_mem_put(adb->mctx, adb->entries, - sizeof(*adb->entries) * adb->nentries); - if (adb->deadentries != NULL) - isc_mem_put(adb->mctx, adb->deadentries, - sizeof(*adb->deadentries) * adb->nentries); - if (adb->entrylocks != NULL) - isc_mem_put(adb->mctx, adb->entrylocks, - sizeof(*adb->entrylocks) * adb->nentries); - if (adb->entry_sd != NULL) - isc_mem_put(adb->mctx, adb->entry_sd, - sizeof(*adb->entry_sd) * adb->nentries); - if (adb->entry_refcnt != NULL) - isc_mem_put(adb->mctx, adb->entry_refcnt, - sizeof(*adb->entry_refcnt) * adb->nentries); - if (adb->names != NULL) - isc_mem_put(adb->mctx, adb->names, - sizeof(*adb->names) * adb->nnames); - if (adb->deadnames != NULL) - isc_mem_put(adb->mctx, adb->deadnames, - sizeof(*adb->deadnames) * adb->nnames); - if (adb->namelocks != NULL) - isc_mem_put(adb->mctx, adb->namelocks, - sizeof(*adb->namelocks) * adb->nnames); - if (adb->name_sd != NULL) - isc_mem_put(adb->mctx, adb->name_sd, - sizeof(*adb->name_sd) * adb->nnames); - if (adb->name_refcnt != NULL) - isc_mem_put(adb->mctx, adb->name_refcnt, - sizeof(*adb->name_refcnt) * adb->nnames); - if (adb->nmp != NULL) - isc_mempool_destroy(&adb->nmp); - if (adb->nhmp != NULL) - isc_mempool_destroy(&adb->nhmp); - if (adb->limp != NULL) - isc_mempool_destroy(&adb->limp); - if (adb->emp != NULL) - isc_mempool_destroy(&adb->emp); - if (adb->ahmp != NULL) - isc_mempool_destroy(&adb->ahmp); - if (adb->aimp != NULL) - isc_mempool_destroy(&adb->aimp); - if (adb->afmp != NULL) - isc_mempool_destroy(&adb->afmp); - - DESTROYLOCK(&adb->namescntlock); - fail0g: - DESTROYLOCK(&adb->entriescntlock); - fail0f: - DESTROYLOCK(&adb->overmemlock); - fail0e: - DESTROYLOCK(&adb->reflock); - fail0d: - DESTROYLOCK(&adb->mplock); - fail0c: - DESTROYLOCK(&adb->lock); - fail0b: - if (adb->excl != NULL) - isc_task_detach(&adb->excl); - isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t)); - - return (result); -} - -void -dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) { - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(adbx != NULL && *adbx == NULL); - - inc_adb_erefcnt(adb); - *adbx = adb; -} - -void -dns_adb_detach(dns_adb_t **adbx) { - dns_adb_t *adb; - bool need_exit_check; - - REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx)); - - adb = *adbx; - *adbx = NULL; - - LOCK(&adb->reflock); - INSIST(adb->erefcnt > 0); - adb->erefcnt--; - need_exit_check = (adb->erefcnt == 0 && adb->irefcnt == 0); - UNLOCK(&adb->reflock); - - if (need_exit_check) { - LOCK(&adb->lock); - INSIST(adb->shutting_down); - check_exit(adb); - UNLOCK(&adb->lock); - } -} - -void -dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) { - isc_task_t *tclone; - isc_event_t *event; - bool zeroirefcnt; - - /* - * Send '*eventp' to 'task' when 'adb' has shutdown. - */ - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(eventp != NULL); - - event = *eventp; - *eventp = NULL; - - LOCK(&adb->lock); - LOCK(&adb->reflock); - - zeroirefcnt = (adb->irefcnt == 0); - - if (adb->shutting_down && zeroirefcnt && - isc_mempool_getallocated(adb->ahmp) == 0) { - /* - * We're already shutdown. Send the event. - */ - event->ev_sender = adb; - isc_task_send(task, &event); - } else { - tclone = NULL; - isc_task_attach(task, &tclone); - event->ev_sender = tclone; - ISC_LIST_APPEND(adb->whenshutdown, event, ev_link); - } - - UNLOCK(&adb->reflock); - UNLOCK(&adb->lock); -} - -static void -shutdown_stage2(isc_task_t *task, isc_event_t *event) { - dns_adb_t *adb; - - UNUSED(task); - - adb = event->ev_arg; - INSIST(DNS_ADB_VALID(adb)); - - LOCK(&adb->lock); - INSIST(adb->shutting_down); - adb->cevent_out = false; - (void)shutdown_names(adb); - (void)shutdown_entries(adb); - if (dec_adb_irefcnt(adb)) - check_exit(adb); - UNLOCK(&adb->lock); -} - -void -dns_adb_shutdown(dns_adb_t *adb) { - isc_event_t *event; - - /* - * Shutdown 'adb'. - */ - - LOCK(&adb->lock); - - if (!adb->shutting_down) { - adb->shutting_down = true; - isc_mem_setwater(adb->mctx, water, adb, 0, 0); - /* - * Isolate shutdown_names and shutdown_entries calls. - */ - inc_adb_irefcnt(adb); - ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, - DNS_EVENT_ADBCONTROL, shutdown_stage2, adb, - adb, NULL, NULL); - adb->cevent_out = true; - event = &adb->cevent; - isc_task_send(adb->task, &event); - } - - UNLOCK(&adb->lock); -} - -isc_result_t -dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *qname, - dns_rdatatype_t qtype, unsigned int options, - isc_stdtime_t now, dns_name_t *target, - in_port_t port, dns_adbfind_t **findp) -{ - return (dns_adb_createfind2(adb, task, action, arg, name, - qname, qtype, options, now, - target, port, 0, NULL, findp)); -} - -isc_result_t -dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *qname, - dns_rdatatype_t qtype, unsigned int options, - isc_stdtime_t now, dns_name_t *target, - in_port_t port, unsigned int depth, isc_counter_t *qc, - dns_adbfind_t **findp) -{ - dns_adbfind_t *find; - dns_adbname_t *adbname; - int bucket; - bool want_event, start_at_zone, alias, have_address; - isc_result_t result; - unsigned int wanted_addresses; - unsigned int wanted_fetches; - unsigned int query_pending; - char namebuf[DNS_NAME_FORMATSIZE]; - - REQUIRE(DNS_ADB_VALID(adb)); - if (task != NULL) { - REQUIRE(action != NULL); - } - REQUIRE(name != NULL); - REQUIRE(qname != NULL); - REQUIRE(findp != NULL && *findp == NULL); - REQUIRE(target == NULL || dns_name_hasbuffer(target)); - - REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0); - - result = ISC_R_UNEXPECTED; - POST(result); - wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK); - wanted_fetches = 0; - query_pending = 0; - want_event = false; - start_at_zone = false; - alias = false; - - if (now == 0) - isc_stdtime_get(&now); - - /* - * XXXMLG Move this comment somewhere else! - * - * Look up the name in our internal database. - * - * Possibilities: Note that these are not always exclusive. - * - * No name found. In this case, allocate a new name header and - * an initial namehook or two. If any of these allocations - * fail, clean up and return ISC_R_NOMEMORY. - * - * Name found, valid addresses present. Allocate one addrinfo - * structure for each found and append it to the linked list - * of addresses for this header. - * - * Name found, queries pending. In this case, if a task was - * passed in, allocate a job id, attach it to the name's job - * list and remember to tell the caller that there will be - * more info coming later. - */ - - find = new_adbfind(adb); - if (find == NULL) - return (ISC_R_NOMEMORY); - - find->port = port; - - /* - * Remember what types of addresses we are interested in. - */ - find->options = options; - find->flags |= wanted_addresses; - if (FIND_WANTEVENT(find)) { - REQUIRE(task != NULL); - } - - if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) - dns_name_format(name, namebuf, sizeof(namebuf)); - else - namebuf[0] = 0; - - /* - * Try to see if we know anything about this name at all. - */ - bucket = DNS_ADB_INVALIDBUCKET; - adbname = find_name_and_lock(adb, name, find->options, &bucket); - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - if (adb->name_sd[bucket]) { - DP(DEF_LEVEL, - "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN"); - RUNTIME_CHECK(free_adbfind(adb, &find) == false); - result = ISC_R_SHUTTINGDOWN; - goto out; - } - - /* - * Nothing found. Allocate a new adbname structure for this name. - */ - if (adbname == NULL) { - /* - * See if there is any stale name at the end of list, and purge - * it if so. - */ - check_stale_name(adb, bucket, now); - - adbname = new_adbname(adb, name); - if (adbname == NULL) { - RUNTIME_CHECK(free_adbfind(adb, &find) == false); - result = ISC_R_NOMEMORY; - goto out; - } - link_name(adb, bucket, adbname); - if (FIND_HINTOK(find)) - adbname->flags |= NAME_HINT_OK; - if (FIND_GLUEOK(find)) - adbname->flags |= NAME_GLUE_OK; - if (FIND_STARTATZONE(find)) - adbname->flags |= NAME_STARTATZONE; - } else { - /* Move this name forward in the LRU list */ - ISC_LIST_UNLINK(adb->names[bucket], adbname, plink); - ISC_LIST_PREPEND(adb->names[bucket], adbname, plink); - } - adbname->last_used = now; - - /* - * Expire old entries, etc. - */ - RUNTIME_CHECK(check_expire_namehooks(adbname, now) == false); - - /* - * Do we know that the name is an alias? - */ - if (!EXPIRE_OK(adbname->expire_target, now)) { - /* - * Yes, it is. - */ - DP(DEF_LEVEL, - "dns_adb_createfind: name %s (%p) is an alias (cached)", - namebuf, adbname); - alias = true; - goto post_copy; - } - - /* - * Try to populate the name from the database and/or - * start fetches. First try looking for an A record - * in the database. - */ - if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) - && WANT_INET(wanted_addresses)) { - result = dbfind_name(adbname, now, dns_rdatatype_a); - if (result == ISC_R_SUCCESS) { - DP(DEF_LEVEL, - "dns_adb_createfind: found A for name %s (%p) in db", - namebuf, adbname); - goto v6; - } - - /* - * Did we get a CNAME or DNAME? - */ - if (result == DNS_R_ALIAS) { - DP(DEF_LEVEL, - "dns_adb_createfind: name %s (%p) is an alias", - namebuf, adbname); - alias = true; - goto post_copy; - } - - /* - * If the name doesn't exist at all, don't bother with - * v6 queries; they won't work. - * - * If the name does exist but we didn't get our data, go - * ahead and try AAAA. - * - * If the result is neither of these, try a fetch for A. - */ - if (NXDOMAIN_RESULT(result)) - goto fetch; - else if (NXRRSET_RESULT(result)) - goto v6; - - if (!NAME_FETCH_V4(adbname)) - wanted_fetches |= DNS_ADBFIND_INET; - } - - v6: - if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) - && WANT_INET6(wanted_addresses)) { - result = dbfind_name(adbname, now, dns_rdatatype_aaaa); - if (result == ISC_R_SUCCESS) { - DP(DEF_LEVEL, - "dns_adb_createfind: found AAAA for name %s (%p)", - namebuf, adbname); - goto fetch; - } - - /* - * Did we get a CNAME or DNAME? - */ - if (result == DNS_R_ALIAS) { - DP(DEF_LEVEL, - "dns_adb_createfind: name %s (%p) is an alias", - namebuf, adbname); - alias = true; - goto post_copy; - } - - /* - * Listen to negative cache hints, and don't start - * another query. - */ - if (NCACHE_RESULT(result) || AUTH_NX(result)) { - goto fetch; - } - - if (!NAME_FETCH_V6(adbname)) { - wanted_fetches |= DNS_ADBFIND_INET6; - } - } - - fetch: - if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) || - (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname))) - { - have_address = true; - } else { - have_address = false; - } - if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address) && - !FIND_NOFETCH(find)) - { - /* - * We're missing at least one address family. Either the - * caller hasn't instructed us to avoid fetches, or we don't - * know anything about any of the address families that would - * be acceptable so we have to launch fetches. - */ - - if (FIND_STARTATZONE(find)) { - start_at_zone = true; - } - - /* - * Start V4. - */ - if (WANT_INET(wanted_fetches) && - fetch_name(adbname, start_at_zone, depth, qc, - dns_rdatatype_a) == ISC_R_SUCCESS) { - DP(DEF_LEVEL, "dns_adb_createfind: " - "started A fetch for name %s (%p)", - namebuf, adbname); - } - - /* - * Start V6. - */ - if (WANT_INET6(wanted_fetches) && - fetch_name(adbname, start_at_zone, depth, qc, - dns_rdatatype_aaaa) == ISC_R_SUCCESS) { - DP(DEF_LEVEL, "dns_adb_createfind: " - "started AAAA fetch for name %s (%p)", - namebuf, adbname); - } - } - - /* - * Run through the name and copy out the bits we are - * interested in. - */ - copy_namehook_lists(adb, find, qname, qtype, adbname, now); - - post_copy: - if (NAME_FETCH_V4(adbname)) - query_pending |= DNS_ADBFIND_INET; - if (NAME_FETCH_V6(adbname)) - query_pending |= DNS_ADBFIND_INET6; - - /* - * Attach to the name's query list if there are queries - * already running, and we have been asked to. - */ - want_event = true; - if (!FIND_WANTEVENT(find)) - want_event = false; - if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find)) - want_event = false; - if ((wanted_addresses & query_pending) == 0) - want_event = false; - if (alias) - want_event = false; - if (want_event) { - find->adbname = adbname; - find->name_bucket = bucket; - ISC_LIST_APPEND(adbname->finds, find, plink); - find->query_pending = (query_pending & wanted_addresses); - find->flags &= ~DNS_ADBFIND_ADDRESSMASK; - find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK); - DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p", - find, adbname); - } else { - /* - * Remove the flag so the caller knows there will never - * be an event, and set internal flags to fake that - * the event was sent and freed, so dns_adb_destroyfind() will - * do the right thing. - */ - find->query_pending = (query_pending & wanted_addresses); - find->options &= ~DNS_ADBFIND_WANTEVENT; - find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED); - find->flags &= ~DNS_ADBFIND_ADDRESSMASK; - } - - find->partial_result |= (adbname->partial_result & wanted_addresses); - if (alias) { - if (target != NULL) { - result = dns_name_copy(&adbname->target, target, NULL); - if (result != ISC_R_SUCCESS) - goto out; - } - result = DNS_R_ALIAS; - } else - result = ISC_R_SUCCESS; - - /* - * Copy out error flags from the name structure into the find. - */ - find->result_v4 = find_err_map[adbname->fetch_err]; - find->result_v6 = find_err_map[adbname->fetch6_err]; - - out: - if (find != NULL) { - *findp = find; - - if (want_event) { - isc_task_t *taskp; - - INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0); - taskp = NULL; - isc_task_attach(task, &taskp); - find->event.ev_sender = taskp; - find->event.ev_action = action; - find->event.ev_arg = arg; - } - } - - UNLOCK(&adb->namelocks[bucket]); - - return (result); -} - -void -dns_adb_destroyfind(dns_adbfind_t **findp) { - dns_adbfind_t *find; - dns_adbentry_t *entry; - dns_adbaddrinfo_t *ai; - int bucket; - dns_adb_t *adb; - bool overmem; - - REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp)); - find = *findp; - *findp = NULL; - - LOCK(&find->lock); - - DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find); - - adb = find->adb; - REQUIRE(DNS_ADB_VALID(adb)); - - REQUIRE(FIND_EVENTFREED(find)); - - bucket = find->name_bucket; - INSIST(bucket == DNS_ADB_INVALIDBUCKET); - - UNLOCK(&find->lock); - - /* - * The find doesn't exist on any list, and nothing is locked. - * Return the find to the memory pool, and decrement the adb's - * reference count. - */ - overmem = isc_mem_isovermem(adb->mctx); - ai = ISC_LIST_HEAD(find->list); - while (ai != NULL) { - ISC_LIST_UNLINK(find->list, ai, publink); - entry = ai->entry; - ai->entry = NULL; - INSIST(DNS_ADBENTRY_VALID(entry)); - RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, true) == - false); - free_adbaddrinfo(adb, &ai); - ai = ISC_LIST_HEAD(find->list); - } - - /* - * WARNING: The find is freed with the adb locked. This is done - * to avoid a race condition where we free the find, some other - * thread tests to see if it should be destroyed, detects it should - * be, destroys it, and then we try to lock it for our check, but the - * lock is destroyed. - */ - LOCK(&adb->lock); - if (free_adbfind(adb, &find)) - check_exit(adb); - UNLOCK(&adb->lock); -} - -void -dns_adb_cancelfind(dns_adbfind_t *find) { - isc_event_t *ev; - isc_task_t *task; - dns_adb_t *adb; - int bucket; - int unlock_bucket; - - LOCK(&find->lock); - - DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find); - - adb = find->adb; - REQUIRE(DNS_ADB_VALID(adb)); - - REQUIRE(!FIND_EVENTFREED(find)); - REQUIRE(FIND_WANTEVENT(find)); - - bucket = find->name_bucket; - if (bucket == DNS_ADB_INVALIDBUCKET) - goto cleanup; - - /* - * We need to get the adbname's lock to unlink the find. - */ - unlock_bucket = bucket; - violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]); - bucket = find->name_bucket; - if (bucket != DNS_ADB_INVALIDBUCKET) { - ISC_LIST_UNLINK(find->adbname->finds, find, plink); - find->adbname = NULL; - find->name_bucket = DNS_ADB_INVALIDBUCKET; - } - UNLOCK(&adb->namelocks[unlock_bucket]); - bucket = DNS_ADB_INVALIDBUCKET; - POST(bucket); - - cleanup: - - if (!FIND_EVENTSENT(find)) { - ev = &find->event; - task = ev->ev_sender; - ev->ev_sender = find; - ev->ev_type = DNS_EVENT_ADBCANCELED; - ev->ev_destroy = event_free; - ev->ev_destroy_arg = find; - find->result_v4 = ISC_R_CANCELED; - find->result_v6 = ISC_R_CANCELED; - - DP(DEF_LEVEL, "sending event %p to task %p for find %p", - ev, task, find); - - isc_task_sendanddetach(&task, (isc_event_t **)&ev); - } - - UNLOCK(&find->lock); -} - -void -dns_adb_dump(dns_adb_t *adb, FILE *f) { - unsigned int i; - isc_stdtime_t now; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(f != NULL); - - /* - * Lock the adb itself, lock all the name buckets, then lock all - * the entry buckets. This should put the adb into a state where - * nothing can change, so we can iterate through everything and - * print at our leisure. - */ - - LOCK(&adb->lock); - isc_stdtime_get(&now); - - for (i = 0; i < adb->nnames; i++) - RUNTIME_CHECK(cleanup_names(adb, i, now) == false); - for (i = 0; i < adb->nentries; i++) - RUNTIME_CHECK(cleanup_entries(adb, i, now) == false); - - dump_adb(adb, f, false, now); - UNLOCK(&adb->lock); -} - -static void -dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) { - if (value == INT_MAX) - return; - fprintf(f, " [%s TTL %d]", legend, (int)(value - now)); -} - -static void -dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) { - unsigned int i; - dns_adbname_t *name; - dns_adbentry_t *entry; - - fprintf(f, ";\n; Address database dump\n;\n"); - fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/" - "512 timeout]\n"); - fprintf(f, "; [plain success/timeout]\n;\n"); - if (debug) - fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n", - adb, adb->erefcnt, adb->irefcnt, - isc_mempool_getallocated(adb->nhmp)); - - /* - * Dump the names - */ - for (i = 0; i < adb->nnames; i++) { - LOCK(&adb->namelocks[i]); - name = ISC_LIST_HEAD(adb->names[i]); - if (name == NULL) { - UNLOCK(&adb->namelocks[i]); - continue; - } - if (debug) - fprintf(f, "; bucket %u\n", i); - for (; - name != NULL; - name = ISC_LIST_NEXT(name, plink)) - { - if (debug) - fprintf(f, "; name %p (flags %08x)\n", - name, name->flags); - - fprintf(f, "; "); - print_dns_name(f, &name->name); - if (dns_name_countlabels(&name->target) > 0) { - fprintf(f, " alias "); - print_dns_name(f, &name->target); - } - - dump_ttl(f, "v4", name->expire_v4, now); - dump_ttl(f, "v6", name->expire_v6, now); - dump_ttl(f, "target", name->expire_target, now); - - fprintf(f, " [v4 %s] [v6 %s]", - errnames[name->fetch_err], - errnames[name->fetch6_err]); - - fprintf(f, "\n"); - - print_namehook_list(f, "v4", adb, - &name->v4, debug, now); - print_namehook_list(f, "v6", adb, - &name->v6, debug, now); - - if (debug) { - print_fetch_list(f, name); - print_find_list(f, name); - } - } - UNLOCK(&adb->namelocks[i]); - } - - fprintf(f, ";\n; Unassociated entries\n;\n"); - - for (i = 0; i < adb->nentries; i++) { - LOCK(&adb->entrylocks[i]); - entry = ISC_LIST_HEAD(adb->entries[i]); - while (entry != NULL) { - if (entry->nh == 0) - dump_entry(f, adb, entry, debug, now); - entry = ISC_LIST_NEXT(entry, plink); - } - UNLOCK(&adb->entrylocks[i]); - } -} - -static void -dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, - bool debug, isc_stdtime_t now) -{ - char addrbuf[ISC_NETADDR_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - isc_netaddr_t netaddr; - dns_adblameinfo_t *li; - - isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); - isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); - - if (debug) - fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt); - - fprintf(f, ";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] " - "[plain %u/%u]", addrbuf, entry->srtt, entry->flags, - entry->edns, entry->to4096, entry->to1432, entry->to1232, - entry->to512, entry->plain, entry->plainto); - if (entry->udpsize != 0U) - fprintf(f, " [udpsize %u]", entry->udpsize); - if (entry->cookie != NULL) { - unsigned int i; - fprintf(f, " [cookie="); - for (i = 0; i < entry->cookielen; i++) - fprintf(f, "%02x", entry->cookie[i]); - fprintf(f, "]"); - } - if (entry->expires != 0) - fprintf(f, " [ttl %d]", (int)(entry->expires - now)); - - if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) { - fprintf(f, " [atr %0.2f] [quota %u]", - entry->atr, entry->quota); - } - - fprintf(f, "\n"); - for (li = ISC_LIST_HEAD(entry->lameinfo); - li != NULL; - li = ISC_LIST_NEXT(li, plink)) - { - fprintf(f, ";\t\t"); - print_dns_name(f, &li->qname); - dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf)); - fprintf(f, " %s [lame TTL %d]\n", typebuf, - (int)(li->lame_timer - now)); - } -} - -void -dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) { - char tmp[512]; - const char *tmpp; - dns_adbaddrinfo_t *ai; - isc_sockaddr_t *sa; - - /* - * Not used currently, in the API Just In Case we - * want to dump out the name and/or entries too. - */ - - LOCK(&find->lock); - - fprintf(f, ";Find %p\n", find); - fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n", - find->query_pending, find->partial_result, - find->options, find->flags); - fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n", - find->name_bucket, find->adbname, find->event.ev_sender); - - ai = ISC_LIST_HEAD(find->list); - if (ai != NULL) - fprintf(f, "\tAddresses:\n"); - while (ai != NULL) { - sa = &ai->sockaddr; - switch (sa->type.sa.sa_family) { - case AF_INET: - tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, - tmp, sizeof(tmp)); - break; - case AF_INET6: - tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr, - tmp, sizeof(tmp)); - break; - default: - tmpp = "UnkFamily"; - } - - if (tmpp == NULL) - tmpp = "BadAddress"; - - fprintf(f, "\t\tentry %p, flags %08x" - " srtt %u addr %s\n", - ai->entry, ai->flags, ai->srtt, tmpp); - - ai = ISC_LIST_NEXT(ai, publink); - } - - UNLOCK(&find->lock); -} - -static void -print_dns_name(FILE *f, dns_name_t *name) { - char buf[DNS_NAME_FORMATSIZE]; - - INSIST(f != NULL); - - dns_name_format(name, buf, sizeof(buf)); - fprintf(f, "%s", buf); -} - -static void -print_namehook_list(FILE *f, const char *legend, - dns_adb_t *adb, dns_adbnamehooklist_t *list, - bool debug, isc_stdtime_t now) -{ - int addr_bucket = DNS_ADB_INVALIDBUCKET; - dns_adbnamehook_t *nh; - - for (nh = ISC_LIST_HEAD(*list); - nh != NULL; - nh = ISC_LIST_NEXT(nh, plink)) - { - if (debug) - fprintf(f, ";\tHook(%s) %p\n", legend, nh); - if (addr_bucket != nh->entry->lock_bucket) { - if (addr_bucket != DNS_ADB_INVALIDBUCKET) { - UNLOCK(&adb->entrylocks[addr_bucket]); - } - addr_bucket = nh->entry->lock_bucket; - INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET); - LOCK(&adb->entrylocks[addr_bucket]); - } - dump_entry(f, adb, nh->entry, debug, now); - } - if (addr_bucket != DNS_ADB_INVALIDBUCKET) { - UNLOCK(&adb->entrylocks[addr_bucket]); - } -} - -static inline void -print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) { - fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", - type, ft, ft->fetch); -} - -static void -print_fetch_list(FILE *f, dns_adbname_t *n) { - if (NAME_FETCH_A(n)) - print_fetch(f, n->fetch_a, "A"); - if (NAME_FETCH_AAAA(n)) - print_fetch(f, n->fetch_aaaa, "AAAA"); -} - -static void -print_find_list(FILE *f, dns_adbname_t *name) { - dns_adbfind_t *find; - - find = ISC_LIST_HEAD(name->finds); - while (find != NULL) { - dns_adb_dumpfind(find, f); - find = ISC_LIST_NEXT(find, plink); - } -} - -static isc_result_t -dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) -{ - isc_result_t result; - dns_rdataset_t rdataset; - dns_adb_t *adb; - dns_fixedname_t foundname; - dns_name_t *fname; - - INSIST(DNS_ADBNAME_VALID(adbname)); - adb = adbname->adb; - INSIST(DNS_ADB_VALID(adb)); - INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa); - - fname = dns_fixedname_initname(&foundname); - dns_rdataset_init(&rdataset); - - if (rdtype == dns_rdatatype_a) - adbname->fetch_err = FIND_ERR_UNEXPECTED; - else - adbname->fetch6_err = FIND_ERR_UNEXPECTED; - - /* - * We need to specify whether to search static-stub zones (if - * configured) depending on whether this is a "start at zone" lookup, - * i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which - * case NAME_STARTATZONE is set) we need to stop the search at any - * matching static-stub zone without looking into the cache to honor - * the configuration on which server we should send queries to. - */ - result = dns_view_find2(adb->view, &adbname->name, rdtype, now, - NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0, - NAME_HINTOK(adbname), - ((adbname->flags & NAME_STARTATZONE) != 0), - NULL, NULL, fname, &rdataset, NULL); - - /* XXXVIX this switch statement is too sparse to gen a jump table. */ - switch (result) { - case DNS_R_GLUE: - case DNS_R_HINT: - case ISC_R_SUCCESS: - /* - * Found in the database. Even if we can't copy out - * any information, return success, or else a fetch - * will be made, which will only make things worse. - */ - if (rdtype == dns_rdatatype_a) - adbname->fetch_err = FIND_ERR_SUCCESS; - else - adbname->fetch6_err = FIND_ERR_SUCCESS; - result = import_rdataset(adbname, &rdataset, now); - break; - case DNS_R_NXDOMAIN: - case DNS_R_NXRRSET: - /* - * We're authoritative and the data doesn't exist. - * Make up a negative cache entry so we don't ask again - * for a while. - * - * XXXRTH What time should we use? I'm putting in 30 seconds - * for now. - */ - if (rdtype == dns_rdatatype_a) { - adbname->expire_v4 = now + 30; - DP(NCACHE_LEVEL, - "adb name %p: Caching auth negative entry for A", - adbname); - if (result == DNS_R_NXDOMAIN) - adbname->fetch_err = FIND_ERR_NXDOMAIN; - else - adbname->fetch_err = FIND_ERR_NXRRSET; - } else { - DP(NCACHE_LEVEL, - "adb name %p: Caching auth negative entry for AAAA", - adbname); - adbname->expire_v6 = now + 30; - if (result == DNS_R_NXDOMAIN) - adbname->fetch6_err = FIND_ERR_NXDOMAIN; - else - adbname->fetch6_err = FIND_ERR_NXRRSET; - } - break; - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - /* - * We found a negative cache entry. Pull the TTL from it - * so we won't ask again for a while. - */ - rdataset.ttl = ttlclamp(rdataset.ttl); - if (rdtype == dns_rdatatype_a) { - adbname->expire_v4 = rdataset.ttl + now; - if (result == DNS_R_NCACHENXDOMAIN) - adbname->fetch_err = FIND_ERR_NXDOMAIN; - else - adbname->fetch_err = FIND_ERR_NXRRSET; - DP(NCACHE_LEVEL, - "adb name %p: Caching negative entry for A (ttl %u)", - adbname, rdataset.ttl); - } else { - DP(NCACHE_LEVEL, - "adb name %p: Caching negative entry for AAAA (ttl %u)", - adbname, rdataset.ttl); - adbname->expire_v6 = rdataset.ttl + now; - if (result == DNS_R_NCACHENXDOMAIN) - adbname->fetch6_err = FIND_ERR_NXDOMAIN; - else - adbname->fetch6_err = FIND_ERR_NXRRSET; - } - break; - case DNS_R_CNAME: - case DNS_R_DNAME: - /* - * Clear the hint and glue flags, so this will match - * more often. - */ - adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK); - - rdataset.ttl = ttlclamp(rdataset.ttl); - clean_target(adb, &adbname->target); - adbname->expire_target = INT_MAX; - result = set_target(adb, &adbname->name, fname, &rdataset, - &adbname->target); - if (result == ISC_R_SUCCESS) { - result = DNS_R_ALIAS; - DP(NCACHE_LEVEL, - "adb name %p: caching alias target", - adbname); - adbname->expire_target = rdataset.ttl + now; - } - if (rdtype == dns_rdatatype_a) - adbname->fetch_err = FIND_ERR_SUCCESS; - else - adbname->fetch6_err = FIND_ERR_SUCCESS; - break; - } - - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - - return (result); -} - -static void -fetch_callback(isc_task_t *task, isc_event_t *ev) { - dns_fetchevent_t *dev; - dns_adbname_t *name; - dns_adb_t *adb; - dns_adbfetch_t *fetch; - int bucket; - isc_eventtype_t ev_status; - isc_stdtime_t now; - isc_result_t result; - unsigned int address_type; - bool want_check_exit = false; - - UNUSED(task); - - INSIST(ev->ev_type == DNS_EVENT_FETCHDONE); - dev = (dns_fetchevent_t *)ev; - name = ev->ev_arg; - INSIST(DNS_ADBNAME_VALID(name)); - adb = name->adb; - INSIST(DNS_ADB_VALID(adb)); - - bucket = name->lock_bucket; - LOCK(&adb->namelocks[bucket]); - - INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name)); - address_type = 0; - if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) { - address_type = DNS_ADBFIND_INET; - fetch = name->fetch_a; - name->fetch_a = NULL; - } else if (NAME_FETCH_AAAA(name) - && (name->fetch_aaaa->fetch == dev->fetch)) { - address_type = DNS_ADBFIND_INET6; - fetch = name->fetch_aaaa; - name->fetch_aaaa = NULL; - } else - fetch = NULL; - - INSIST(address_type != 0 && fetch != NULL); - - dns_resolver_destroyfetch(&fetch->fetch); - dev->fetch = NULL; - - ev_status = DNS_EVENT_ADBNOMOREADDRESSES; - - /* - * Cleanup things we don't care about. - */ - if (dev->node != NULL) - dns_db_detachnode(dev->db, &dev->node); - if (dev->db != NULL) - dns_db_detach(&dev->db); - - /* - * If this name is marked as dead, clean up, throwing away - * potentially good data. - */ - if (NAME_DEAD(name)) { - free_adbfetch(adb, &fetch); - isc_event_free(&ev); - - want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED); - - UNLOCK(&adb->namelocks[bucket]); - - if (want_check_exit) { - LOCK(&adb->lock); - check_exit(adb); - UNLOCK(&adb->lock); - } - - return; - } - - isc_stdtime_get(&now); - - /* - * If we got a negative cache response, remember it. - */ - if (NCACHE_RESULT(dev->result)) { - dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl); - if (address_type == DNS_ADBFIND_INET) { - DP(NCACHE_LEVEL, "adb fetch name %p: " - "caching negative entry for A (ttl %u)", - name, dev->rdataset->ttl); - name->expire_v4 = ISC_MIN(name->expire_v4, - dev->rdataset->ttl + now); - if (dev->result == DNS_R_NCACHENXDOMAIN) - name->fetch_err = FIND_ERR_NXDOMAIN; - else - name->fetch_err = FIND_ERR_NXRRSET; - inc_stats(adb, dns_resstatscounter_gluefetchv4fail); - } else { - DP(NCACHE_LEVEL, "adb fetch name %p: " - "caching negative entry for AAAA (ttl %u)", - name, dev->rdataset->ttl); - name->expire_v6 = ISC_MIN(name->expire_v6, - dev->rdataset->ttl + now); - if (dev->result == DNS_R_NCACHENXDOMAIN) - name->fetch6_err = FIND_ERR_NXDOMAIN; - else - name->fetch6_err = FIND_ERR_NXRRSET; - inc_stats(adb, dns_resstatscounter_gluefetchv6fail); - } - goto out; - } - - /* - * Handle CNAME/DNAME. - */ - if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) { - dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl); - clean_target(adb, &name->target); - name->expire_target = INT_MAX; - result = set_target(adb, &name->name, - dns_fixedname_name(&dev->foundname), - dev->rdataset, - &name->target); - if (result == ISC_R_SUCCESS) { - DP(NCACHE_LEVEL, - "adb fetch name %p: caching alias target", - name); - name->expire_target = dev->rdataset->ttl + now; - } - goto check_result; - } - - /* - * Did we get back junk? If so, and there are no more fetches - * sitting out there, tell all the finds about it. - */ - if (dev->result != ISC_R_SUCCESS) { - char buf[DNS_NAME_FORMATSIZE]; - - dns_name_format(&name->name, buf, sizeof(buf)); - DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", - buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA", - dns_result_totext(dev->result)); - /* - * Don't record a failure unless this is the initial - * fetch of a chain. - */ - if (fetch->depth > 1) - goto out; - /* XXXMLG Don't pound on bad servers. */ - if (address_type == DNS_ADBFIND_INET) { - name->expire_v4 = ISC_MIN(name->expire_v4, now + 10); - name->fetch_err = FIND_ERR_FAILURE; - inc_stats(adb, dns_resstatscounter_gluefetchv4fail); - } else { - name->expire_v6 = ISC_MIN(name->expire_v6, now + 10); - name->fetch6_err = FIND_ERR_FAILURE; - inc_stats(adb, dns_resstatscounter_gluefetchv6fail); - } - goto out; - } - - /* - * We got something potentially useful. - */ - result = import_rdataset(name, &fetch->rdataset, now); - - check_result: - if (result == ISC_R_SUCCESS) { - ev_status = DNS_EVENT_ADBMOREADDRESSES; - if (address_type == DNS_ADBFIND_INET) - name->fetch_err = FIND_ERR_SUCCESS; - else - name->fetch6_err = FIND_ERR_SUCCESS; - } - - out: - free_adbfetch(adb, &fetch); - isc_event_free(&ev); - - clean_finds_at_name(name, ev_status, address_type); - - UNLOCK(&adb->namelocks[bucket]); -} - -static isc_result_t -fetch_name(dns_adbname_t *adbname, bool start_at_zone, - unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type) -{ - isc_result_t result; - dns_adbfetch_t *fetch = NULL; - dns_adb_t *adb; - dns_fixedname_t fixed; - dns_name_t *name; - dns_rdataset_t rdataset; - dns_rdataset_t *nameservers; - unsigned int options; - - INSIST(DNS_ADBNAME_VALID(adbname)); - adb = adbname->adb; - INSIST(DNS_ADB_VALID(adb)); - - INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) || - (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname))); - - adbname->fetch_err = FIND_ERR_NOTFOUND; - - name = NULL; - nameservers = NULL; - dns_rdataset_init(&rdataset); - - options = DNS_FETCHOPT_NOVALIDATE; - if (start_at_zone) { - DP(ENTER_LEVEL, - "fetch_name: starting at zone for name %p", - adbname); - name = dns_fixedname_initname(&fixed); - result = dns_view_findzonecut2(adb->view, &adbname->name, name, - 0, 0, true, false, - &rdataset, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_HINT) - goto cleanup; - nameservers = &rdataset; - options |= DNS_FETCHOPT_UNSHARED; - } - - fetch = new_adbfetch(adb); - if (fetch == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - fetch->depth = depth; - - result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name, - type, name, nameservers, NULL, - NULL, 0, options, depth, qc, - adb->task, fetch_callback, adbname, - &fetch->rdataset, NULL, - &fetch->fetch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (type == dns_rdatatype_a) { - adbname->fetch_a = fetch; - inc_stats(adb, dns_resstatscounter_gluefetchv4); - } else { - adbname->fetch_aaaa = fetch; - inc_stats(adb, dns_resstatscounter_gluefetchv6); - } - fetch = NULL; /* Keep us from cleaning this up below. */ - - cleanup: - if (fetch != NULL) - free_adbfetch(adb, &fetch); - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - - return (result); -} - -/* - * XXXMLG Needs to take a find argument and an address info, no zone or adb, - * since these can be extracted from the find itself. - */ -isc_result_t -dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, - dns_rdatatype_t qtype, isc_stdtime_t expire_time) -{ - dns_adblameinfo_t *li; - int bucket; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - REQUIRE(qname != NULL); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - li = ISC_LIST_HEAD(addr->entry->lameinfo); - while (li != NULL && - (li->qtype != qtype || !dns_name_equal(qname, &li->qname))) - li = ISC_LIST_NEXT(li, plink); - if (li != NULL) { - if (expire_time > li->lame_timer) - li->lame_timer = expire_time; - goto unlock; - } - li = new_adblameinfo(adb, qname, qtype); - if (li == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - - li->lame_timer = expire_time; - - ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink); - unlock: - UNLOCK(&adb->entrylocks[bucket]); - - return (result); -} - -void -dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned int rtt, unsigned int factor) -{ - int bucket; - isc_stdtime_t now = 0; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - REQUIRE(factor <= 10); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) - isc_stdtime_get(&now); - adjustsrtt(addr, rtt, factor, now); - - UNLOCK(&adb->entrylocks[bucket]); -} - -void -dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now); - - UNLOCK(&adb->entrylocks[bucket]); -} - -static void -adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor, - isc_stdtime_t now) -{ - uint64_t new_srtt; - - if (factor == DNS_ADB_RTTADJAGE) { - if (addr->entry->lastage != now) { - new_srtt = addr->entry->srtt; - new_srtt <<= 9; - new_srtt -= addr->entry->srtt; - new_srtt >>= 9; - addr->entry->lastage = now; - } else - new_srtt = addr->entry->srtt; - } else - new_srtt = ((uint64_t)addr->entry->srtt / 10 * factor) - + ((uint64_t)rtt / 10 * (10 - factor)); - - addr->entry->srtt = (unsigned int) new_srtt; - addr->srtt = (unsigned int) new_srtt; - - if (addr->entry->expires == 0) - addr->entry->expires = now + ADB_ENTRY_WINDOW; -} - -void -dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned int bits, unsigned int mask) -{ - int bucket; - isc_stdtime_t now; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - REQUIRE((bits & ENTRY_IS_DEAD) == 0); - REQUIRE((mask & ENTRY_IS_DEAD) == 0); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask); - if (addr->entry->expires == 0) { - isc_stdtime_get(&now); - addr->entry->expires = now + ADB_ENTRY_WINDOW; - } - - /* - * Note that we do not update the other bits in addr->flags with - * the most recent values from addr->entry->flags. - */ - addr->flags = (addr->flags & ~mask) | (bits & mask); - - UNLOCK(&adb->entrylocks[bucket]); -} - -/* - * The polynomial backoff curve (10000 / ((10 + n) / 10)^(3/2)) <0..99> drops - * fairly aggressively at first, then slows down and tails off at around 2-3%. - * - * These will be used to make quota adjustments. - */ -static int quota_adj[] = { - 10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, - 3818, 3536, 3286, 3065, 2867, 2690, 2530, 2385, 2254, - 2134, 2025, 1925, 1832, 1747, 1668, 1595, 1527, 1464, - 1405, 1350, 1298, 1250, 1205, 1162, 1121, 1083, 1048, - 1014, 981, 922, 894, 868, 843, 820, 797, 775, 755, - 735, 716, 698, 680, 664, 648, 632, 618, 603, 590, 577, - 564, 552, 540, 529, 518, 507, 497, 487, 477, 468, 459, - 450, 442, 434, 426, 418, 411, 404, 397, 390, 383, 377, - 370, 364, 358, 353, 347, 342, 336, 331, 326, 321, 316, - 312, 307, 303, 298, 294, 290, 286, 282, 278 -}; - -#define QUOTA_ADJ_SIZE (sizeof(quota_adj)/sizeof(quota_adj[0])) - -/* - * Caller must hold adbentry lock - */ -static void -maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - bool timeout) -{ - double tr; - - UNUSED(adb); - - if (adb->quota == 0 || adb->atr_freq == 0) - return; - - if (timeout) - addr->entry->timeouts++; - - if (addr->entry->completed++ <= adb->atr_freq) - return; - - /* - * Calculate an exponential rolling average of the timeout ratio - * - * XXX: Integer arithmetic might be better than floating point - */ - tr = (double) addr->entry->timeouts / addr->entry->completed; - addr->entry->timeouts = addr->entry->completed = 0; - INSIST(addr->entry->atr >= 0.0); - INSIST(addr->entry->atr <= 1.0); - INSIST(adb->atr_discount >= 0.0); - INSIST(adb->atr_discount <= 1.0); - addr->entry->atr *= 1.0 - adb->atr_discount; - addr->entry->atr += tr * adb->atr_discount; - addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0); - - if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) { - addr->entry->quota = adb->quota * - quota_adj[--addr->entry->mode] / 10000; - log_quota(addr->entry, "atr %0.2f, quota increased to %u", - addr->entry->atr, addr->entry->quota); - } else if (addr->entry->atr > adb->atr_high && - addr->entry->mode < (QUOTA_ADJ_SIZE - 1)) { - addr->entry->quota = adb->quota * - quota_adj[++addr->entry->mode] / 10000; - log_quota(addr->entry, "atr %0.2f, quota decreased to %u", - addr->entry->atr, addr->entry->quota); - } - - /* Ensure we don't drop to zero */ - if (addr->entry->quota == 0) - addr->entry->quota = 1; -} - -#define EDNSTOS 3U -bool -dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - bool noedns = false; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - if (addr->entry->edns == 0U && - (addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS)) { - if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) { - noedns = true; - } else { - /* - * Increment plain so we don't get stuck. - */ - addr->entry->plain++; - if (addr->entry->plain == 0xff) { - addr->entry->edns >>= 1; - addr->entry->to4096 >>= 1; - addr->entry->to1432 >>= 1; - addr->entry->to1232 >>= 1; - addr->entry->to512 >>= 1; - addr->entry->plain >>= 1; - addr->entry->plainto >>= 1; - } - } - } - UNLOCK(&adb->entrylocks[bucket]); - return (noedns); -} - -void -dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - maybe_adjust_quota(adb, addr, false); - - addr->entry->plain++; - if (addr->entry->plain == 0xff) { - addr->entry->edns >>= 1; - addr->entry->to4096 >>= 1; - addr->entry->to1432 >>= 1; - addr->entry->to1232 >>= 1; - addr->entry->to512 >>= 1; - addr->entry->plain >>= 1; - addr->entry->plainto >>= 1; - } - UNLOCK(&adb->entrylocks[bucket]); -} - -void -dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - maybe_adjust_quota(adb, addr, true); - - /* - * If we have not had a successful query then clear all - * edns timeout information. - */ - if (addr->entry->edns == 0 && addr->entry->plain == 0) { - addr->entry->to512 = 0; - addr->entry->to1232 = 0; - addr->entry->to1432 = 0; - addr->entry->to4096 = 0; - } else { - addr->entry->to512 >>= 1; - addr->entry->to1232 >>= 1; - addr->entry->to1432 >>= 1; - addr->entry->to4096 >>= 1; - } - - addr->entry->plainto++; - if (addr->entry->plainto == 0xff) { - addr->entry->edns >>= 1; - addr->entry->plain >>= 1; - addr->entry->plainto >>= 1; - } - UNLOCK(&adb->entrylocks[bucket]); -} - -void -dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - maybe_adjust_quota(adb, addr, true); - - if (size <= 512U) { - if (addr->entry->to512 <= EDNSTOS) { - addr->entry->to512++; - addr->entry->to1232++; - addr->entry->to1432++; - addr->entry->to4096++; - } - } else if (size <= 1232U) { - if (addr->entry->to1232 <= EDNSTOS) { - addr->entry->to1232++; - addr->entry->to1432++; - addr->entry->to4096++; - } - } else if (size <= 1432U) { - if (addr->entry->to1432 <= EDNSTOS) { - addr->entry->to1432++; - addr->entry->to4096++; - } - } else { - if (addr->entry->to4096 <= EDNSTOS) - addr->entry->to4096++; - } - - if (addr->entry->to4096 == 0xff) { - addr->entry->edns >>= 1; - addr->entry->to4096 >>= 1; - addr->entry->to1432 >>= 1; - addr->entry->to1232 >>= 1; - addr->entry->to512 >>= 1; - addr->entry->plain >>= 1; - addr->entry->plainto >>= 1; - } - UNLOCK(&adb->entrylocks[bucket]); -} - -void -dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - if (size < 512U) - size = 512U; - if (size > addr->entry->udpsize) - addr->entry->udpsize = size; - - maybe_adjust_quota(adb, addr, false); - - addr->entry->edns++; - if (addr->entry->edns == 0xff) { - addr->entry->edns >>= 1; - addr->entry->to4096 >>= 1; - addr->entry->to1432 >>= 1; - addr->entry->to1232 >>= 1; - addr->entry->to512 >>= 1; - addr->entry->plain >>= 1; - addr->entry->plainto >>= 1; - } - UNLOCK(&adb->entrylocks[bucket]); -} - -unsigned int -dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - unsigned int size; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - size = addr->entry->udpsize; - UNLOCK(&adb->entrylocks[bucket]); - - return (size); -} - -unsigned int -dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - return dns_adb_probesize2(adb, addr, 0); -} - -unsigned int -dns_adb_probesize2(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) { - int bucket; - unsigned int size; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - if (addr->entry->to1232 > EDNSTOS || lookups >= 2) - size = 512; - else if (addr->entry->to1432 > EDNSTOS || lookups >= 1) - size = 1232; - else if (addr->entry->to4096 > EDNSTOS) - size = 1432; - else - size = 4096; - /* - * Don't shrink probe size below what we have seen due to multiple - * lookups. - */ - if (lookups > 0 && - size < addr->entry->udpsize && addr->entry->udpsize < 4096) - size = addr->entry->udpsize; - UNLOCK(&adb->entrylocks[bucket]); - - return (size); -} - -void -dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - const unsigned char *cookie, size_t len) -{ - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - if (addr->entry->cookie != NULL && - (cookie == NULL || len != addr->entry->cookielen)) { - isc_mem_put(adb->mctx, addr->entry->cookie, - addr->entry->cookielen); - addr->entry->cookie = NULL; - addr->entry->cookielen = 0; - } - - if (addr->entry->cookie == NULL && cookie != NULL && len != 0U) { - addr->entry->cookie = isc_mem_get(adb->mctx, len); - if (addr->entry->cookie != NULL) - addr->entry->cookielen = (uint16_t)len; - } - - if (addr->entry->cookie != NULL) - memmove(addr->entry->cookie, cookie, len); - UNLOCK(&adb->entrylocks[bucket]); -} - -size_t -dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned char *cookie, size_t len) -{ - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - if (cookie != NULL && addr->entry->cookie != NULL && - len >= addr->entry->cookielen) - { - memmove(cookie, addr->entry->cookie, addr->entry->cookielen); - len = addr->entry->cookielen; - } else - len = 0; - UNLOCK(&adb->entrylocks[bucket]); - - return (len); -} - -isc_result_t -dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, - dns_adbaddrinfo_t **addrp, isc_stdtime_t now) -{ - int bucket; - dns_adbentry_t *entry; - dns_adbaddrinfo_t *addr; - isc_result_t result; - in_port_t port; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(addrp != NULL && *addrp == NULL); - - UNUSED(now); - - result = ISC_R_SUCCESS; - bucket = DNS_ADB_INVALIDBUCKET; - entry = find_entry_and_lock(adb, sa, &bucket, now); - INSIST(bucket != DNS_ADB_INVALIDBUCKET); - if (adb->entry_sd[bucket]) { - result = ISC_R_SHUTTINGDOWN; - goto unlock; - } - if (entry == NULL) { - /* - * We don't know anything about this address. - */ - entry = new_adbentry(adb); - if (entry == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - entry->sockaddr = *sa; - link_entry(adb, bucket, entry); - DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry); - } else - DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry); - - port = isc_sockaddr_getport(sa); - addr = new_adbaddrinfo(adb, entry, port); - if (addr == NULL) { - result = ISC_R_NOMEMORY; - } else { - inc_entry_refcnt(adb, entry, false); - *addrp = addr; - } - - unlock: - UNLOCK(&adb->entrylocks[bucket]); - - return (result); -} - -void -dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { - dns_adbaddrinfo_t *addr; - dns_adbentry_t *entry; - int bucket; - isc_stdtime_t now; - bool want_check_exit = false; - bool overmem; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(addrp != NULL); - addr = *addrp; - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - entry = addr->entry; - REQUIRE(DNS_ADBENTRY_VALID(entry)); - - *addrp = NULL; - overmem = isc_mem_isovermem(adb->mctx); - - bucket = addr->entry->lock_bucket; - LOCK(&adb->entrylocks[bucket]); - - if (entry->expires == 0) { - isc_stdtime_get(&now); - entry->expires = now + ADB_ENTRY_WINDOW; - } - - want_check_exit = dec_entry_refcnt(adb, overmem, entry, false); - - UNLOCK(&adb->entrylocks[bucket]); - - addr->entry = NULL; - free_adbaddrinfo(adb, &addr); - - if (want_check_exit) { - LOCK(&adb->lock); - check_exit(adb); - UNLOCK(&adb->lock); - } -} - -void -dns_adb_flush(dns_adb_t *adb) { - unsigned int i; - - INSIST(DNS_ADB_VALID(adb)); - - LOCK(&adb->lock); - - /* - * Call our cleanup routines. - */ - for (i = 0; i < adb->nnames; i++) - RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == false); - for (i = 0; i < adb->nentries; i++) - RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == false); - -#ifdef DUMP_ADB_AFTER_CLEANING - dump_adb(adb, stdout, true, INT_MAX); -#endif - - UNLOCK(&adb->lock); -} - -void -dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) { - dns_adbname_t *adbname; - dns_adbname_t *nextname; - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(name != NULL); - - LOCK(&adb->lock); - bucket = dns_name_hash(name, false) % adb->nnames; - LOCK(&adb->namelocks[bucket]); - adbname = ISC_LIST_HEAD(adb->names[bucket]); - while (adbname != NULL) { - nextname = ISC_LIST_NEXT(adbname, plink); - if (!NAME_DEAD(adbname) && - dns_name_equal(name, &adbname->name)) { - RUNTIME_CHECK(kill_name(&adbname, - DNS_EVENT_ADBCANCELED) == - false); - } - adbname = nextname; - } - UNLOCK(&adb->namelocks[bucket]); - UNLOCK(&adb->lock); -} - -void -dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name) { - dns_adbname_t *adbname, *nextname; - unsigned int i; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(name != NULL); - - LOCK(&adb->lock); - for (i = 0; i < adb->nnames; i++) { - LOCK(&adb->namelocks[i]); - adbname = ISC_LIST_HEAD(adb->names[i]); - while (adbname != NULL) { - bool ret; - nextname = ISC_LIST_NEXT(adbname, plink); - if (!NAME_DEAD(adbname) && - dns_name_issubdomain(&adbname->name, name)) - { - ret = kill_name(&adbname, - DNS_EVENT_ADBCANCELED); - RUNTIME_CHECK(ret == false); - } - adbname = nextname; - } - UNLOCK(&adb->namelocks[i]); - } - UNLOCK(&adb->lock); -} - -static void -water(void *arg, int mark) { - /* - * We're going to change the way to handle overmem condition: use - * isc_mem_isovermem() instead of storing the state via this callback, - * since the latter way tends to cause race conditions. - * To minimize the change, and in case we re-enable the callback - * approach, however, keep this function at the moment. - */ - - dns_adb_t *adb = arg; - bool overmem = (mark == ISC_MEM_HIWATER); - - REQUIRE(DNS_ADB_VALID(adb)); - - DP(ISC_LOG_DEBUG(1), - "adb reached %s water mark", overmem ? "high" : "low"); -} - -void -dns_adb_setadbsize(dns_adb_t *adb, size_t size) { - size_t hiwater, lowater; - - INSIST(DNS_ADB_VALID(adb)); - - if (size != 0U && size < DNS_ADB_MINADBSIZE) - size = DNS_ADB_MINADBSIZE; - - hiwater = size - (size >> 3); /* Approximately 7/8ths. */ - lowater = size - (size >> 2); /* Approximately 3/4ths. */ - - if (size == 0U || hiwater == 0U || lowater == 0U) - isc_mem_setwater(adb->mctx, water, adb, 0, 0); - else - isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater); -} - -void -dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, - double low, double high, double discount) -{ - REQUIRE(DNS_ADB_VALID(adb)); - - adb->quota = quota; - adb->atr_freq = freq; - adb->atr_low = low; - adb->atr_high = high; - adb->atr_discount = discount; -} - -bool -dns_adbentry_overquota(dns_adb_t *adb, dns_adbentry_t *entry) { - int bucket; - bool block; - - REQUIRE(DNS_ADBENTRY_VALID(entry)); - - bucket = entry->lock_bucket; - - LOCK(&adb->entrylocks[bucket]); - block = (entry->quota != 0 && entry->active >= entry->quota); - UNLOCK(&adb->entrylocks[bucket]); - - return (block); -} - -void -dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - - LOCK(&adb->entrylocks[bucket]); - addr->entry->active++; - UNLOCK(&adb->entrylocks[bucket]); -} - -void -dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { - int bucket; - - REQUIRE(DNS_ADB_VALID(adb)); - REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - - bucket = addr->entry->lock_bucket; - - LOCK(&adb->entrylocks[bucket]); - if (addr->entry->active > 0) - addr->entry->active--; - UNLOCK(&adb->entrylocks[bucket]); -} diff --git a/lib/dns-pkcs11/api b/lib/dns-pkcs11/api deleted file mode 100644 index 5a49714..0000000 --- a/lib/dns-pkcs11/api +++ /dev/null @@ -1,13 +0,0 @@ -# LIBINTERFACE ranges -# 9.6: 50-59, 110-119 -# 9.7: 60-79 -# 9.8: 80-89, 120-129 -# 9.9: 90-109, 170-179 -# 9.9-sub: 130-139, 150-159, 200-209 -# 9.10: 140-149, 190-199 -# 9.10-sub: 180-189 -# 9.11: 160-169,1100-1199 -# 9.12: 1200-1299 -LIBINTERFACE = 1112 -LIBREVISION = 2 -LIBAGE = 0 diff --git a/lib/dns-pkcs11/badcache.c b/lib/dns-pkcs11/badcache.c deleted file mode 100644 index c60f60e..0000000 --- a/lib/dns-pkcs11/badcache.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -typedef struct dns_bcentry dns_bcentry_t; - -struct dns_badcache { - unsigned int magic; - isc_mutex_t lock; - isc_mem_t *mctx; - - dns_bcentry_t **table; - unsigned int count; - unsigned int minsize; - unsigned int size; - unsigned int sweep; -}; - -#define BADCACHE_MAGIC ISC_MAGIC('B', 'd', 'C', 'a') -#define VALID_BADCACHE(m) ISC_MAGIC_VALID(m, BADCACHE_MAGIC) - -struct dns_bcentry { - dns_bcentry_t * next; - dns_rdatatype_t type; - isc_time_t expire; - uint32_t flags; - unsigned int hashval; - dns_name_t name; -}; - -static isc_result_t -badcache_resize(dns_badcache_t *bc, isc_time_t *now, bool grow); - -isc_result_t -dns_badcache_init(isc_mem_t *mctx, unsigned int size, dns_badcache_t **bcp) { - isc_result_t result; - dns_badcache_t *bc = NULL; - - REQUIRE(bcp != NULL && *bcp == NULL); - REQUIRE(mctx != NULL); - - bc = isc_mem_get(mctx, sizeof(dns_badcache_t)); - if (bc == NULL) - return (ISC_R_NOMEMORY); - memset(bc, 0, sizeof(dns_badcache_t)); - - isc_mem_attach(mctx, &bc->mctx); - result = isc_mutex_init(&bc->lock); - if (result != ISC_R_SUCCESS) - goto cleanup; - - bc->table = isc_mem_get(bc->mctx, sizeof(*bc->table) * size); - if (bc->table == NULL) { - result = ISC_R_NOMEMORY; - goto destroy_lock; - } - - bc->size = bc->minsize = size; - memset(bc->table, 0, bc->size * sizeof(dns_bcentry_t *)); - - bc->count = 0; - bc->sweep = 0; - bc->magic = BADCACHE_MAGIC; - - *bcp = bc; - return (ISC_R_SUCCESS); - - destroy_lock: - DESTROYLOCK(&bc->lock); - cleanup: - isc_mem_putanddetach(&bc->mctx, bc, sizeof(dns_badcache_t)); - return (result); -} - -void -dns_badcache_destroy(dns_badcache_t **bcp) { - dns_badcache_t *bc; - - REQUIRE(bcp != NULL && *bcp != NULL); - bc = *bcp; - - dns_badcache_flush(bc); - - bc->magic = 0; - DESTROYLOCK(&bc->lock); - isc_mem_put(bc->mctx, bc->table, sizeof(dns_bcentry_t *) * bc->size); - isc_mem_putanddetach(&bc->mctx, bc, sizeof(dns_badcache_t)); - *bcp = NULL; -} - -static isc_result_t -badcache_resize(dns_badcache_t *bc, isc_time_t *now, bool grow) { - dns_bcentry_t **newtable, *bad, *next; - unsigned int newsize, i; - - if (grow) - newsize = bc->size * 2 + 1; - else - newsize = (bc->size - 1) / 2; - - newtable = isc_mem_get(bc->mctx, sizeof(dns_bcentry_t *) * newsize); - if (newtable == NULL) - return (ISC_R_NOMEMORY); - memset(newtable, 0, sizeof(dns_bcentry_t *) * newsize); - - for (i = 0; bc->count > 0 && i < bc->size; i++) { - for (bad = bc->table[i]; bad != NULL; bad = next) { - next = bad->next; - if (isc_time_compare(&bad->expire, now) < 0) { - isc_mem_put(bc->mctx, bad, - sizeof(*bad) + bad->name.length); - bc->count--; - } else { - bad->next = newtable[bad->hashval % newsize]; - newtable[bad->hashval % newsize] = bad; - } - } - bc->table[i] = NULL; - } - - isc_mem_put(bc->mctx, bc->table, sizeof(*bc->table) * bc->size); - bc->size = newsize; - bc->table = newtable; - - return (ISC_R_SUCCESS); -} - -void -dns_badcache_add(dns_badcache_t *bc, dns_name_t *name, - dns_rdatatype_t type, bool update, - uint32_t flags, isc_time_t *expire) -{ - isc_result_t result; - unsigned int i, hashval; - dns_bcentry_t *bad, *prev, *next; - isc_time_t now; - - REQUIRE(VALID_BADCACHE(bc)); - REQUIRE(name != NULL); - REQUIRE(expire != NULL); - - LOCK(&bc->lock); - - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) - isc_time_settoepoch(&now); - - hashval = dns_name_hash(name, false); - i = hashval % bc->size; - prev = NULL; - for (bad = bc->table[i]; bad != NULL; bad = next) { - next = bad->next; - if (bad->type == type && dns_name_equal(name, &bad->name)) { - if (update) { - bad->expire = *expire; - bad->flags = flags; - } - break; - } - if (isc_time_compare(&bad->expire, &now) < 0) { - if (prev == NULL) - bc->table[i] = bad->next; - else - prev->next = bad->next; - isc_mem_put(bc->mctx, bad, - sizeof(*bad) + bad->name.length); - bc->count--; - } else - prev = bad; - } - - if (bad == NULL) { - isc_buffer_t buffer; - bad = isc_mem_get(bc->mctx, sizeof(*bad) + name->length); - if (bad == NULL) - goto cleanup; - bad->type = type; - bad->hashval = hashval; - bad->expire = *expire; - bad->flags = flags; - isc_buffer_init(&buffer, bad + 1, name->length); - dns_name_init(&bad->name, NULL); - dns_name_copy(name, &bad->name, &buffer); - bad->next = bc->table[i]; - bc->table[i] = bad; - bc->count++; - if (bc->count > bc->size * 8) - badcache_resize(bc, &now, true); - if (bc->count < bc->size * 2 && bc->size > bc->minsize) - badcache_resize(bc, &now, false); - } else - bad->expire = *expire; - - cleanup: - UNLOCK(&bc->lock); -} - -bool -dns_badcache_find(dns_badcache_t *bc, dns_name_t *name, - dns_rdatatype_t type, uint32_t *flagp, - isc_time_t *now) -{ - dns_bcentry_t *bad, *prev, *next; - bool answer = false; - unsigned int i; - - REQUIRE(VALID_BADCACHE(bc)); - REQUIRE(name != NULL); - REQUIRE(now != NULL); - - LOCK(&bc->lock); - - /* - * XXXMUKS: dns_name_equal() is expensive as it does a - * octet-by-octet comparison, and it can be made better in two - * ways here. First, lowercase the names (use - * dns_name_downcase() instead of dns_name_copy() in - * dns_badcache_add()) so that dns_name_caseequal() can be used - * which the compiler will emit as SIMD instructions. Second, - * don't put multiple copies of the same name in the chain (or - * multiple names will have to be matched for equality), but use - * name->link to store the type specific part. - */ - - if (bc->count == 0) - goto skip; - - i = dns_name_hash(name, false) % bc->size; - prev = NULL; - for (bad = bc->table[i]; bad != NULL; bad = next) { - next = bad->next; - /* - * Search the hash list. Clean out expired records as we go. - */ - if (isc_time_compare(&bad->expire, now) < 0) { - if (prev != NULL) - prev->next = bad->next; - else - bc->table[i] = bad->next; - - isc_mem_put(bc->mctx, bad, sizeof(*bad) + - bad->name.length); - bc->count--; - continue; - } - if (bad->type == type && dns_name_equal(name, &bad->name)) { - if (flagp != NULL) - *flagp = bad->flags; - answer = true; - break; - } - prev = bad; - } - skip: - - /* - * Slow sweep to clean out stale records. - */ - i = bc->sweep++ % bc->size; - bad = bc->table[i]; - if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) { - bc->table[i] = bad->next; - isc_mem_put(bc->mctx, bad, sizeof(*bad) + bad->name.length); - bc->count--; - } - - UNLOCK(&bc->lock); - return (answer); -} - -void -dns_badcache_flush(dns_badcache_t *bc) { - dns_bcentry_t *entry, *next; - unsigned int i; - - REQUIRE(VALID_BADCACHE(bc)); - - for (i = 0; bc->count > 0 && i < bc->size; i++) { - for (entry = bc->table[i]; entry != NULL; entry = next) { - next = entry->next; - isc_mem_put(bc->mctx, entry, sizeof(*entry) + - entry->name.length); - bc->count--; - } - bc->table[i] = NULL; - } -} - -void -dns_badcache_flushname(dns_badcache_t *bc, dns_name_t *name) { - dns_bcentry_t *bad, *prev, *next; - isc_result_t result; - isc_time_t now; - unsigned int i; - - REQUIRE(VALID_BADCACHE(bc)); - REQUIRE(name != NULL); - - LOCK(&bc->lock); - - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) - isc_time_settoepoch(&now); - i = dns_name_hash(name, false) % bc->size; - prev = NULL; - for (bad = bc->table[i]; bad != NULL; bad = next) { - int n; - next = bad->next; - n = isc_time_compare(&bad->expire, &now); - if (n < 0 || dns_name_equal(name, &bad->name)) { - if (prev == NULL) - bc->table[i] = bad->next; - else - prev->next = bad->next; - - isc_mem_put(bc->mctx, bad, sizeof(*bad) + - bad->name.length); - bc->count--; - } else - prev = bad; - } - - UNLOCK(&bc->lock); -} - -void -dns_badcache_flushtree(dns_badcache_t *bc, dns_name_t *name) { - dns_bcentry_t *bad, *prev, *next; - unsigned int i; - int n; - isc_time_t now; - isc_result_t result; - - REQUIRE(VALID_BADCACHE(bc)); - REQUIRE(name != NULL); - - LOCK(&bc->lock); - - result = isc_time_now(&now); - if (result != ISC_R_SUCCESS) - isc_time_settoepoch(&now); - - for (i = 0; bc->count > 0 && i < bc->size; i++) { - prev = NULL; - for (bad = bc->table[i]; bad != NULL; bad = next) { - next = bad->next; - n = isc_time_compare(&bad->expire, &now); - if (n < 0 || dns_name_issubdomain(&bad->name, name)) { - if (prev == NULL) - bc->table[i] = bad->next; - else - prev->next = bad->next; - - isc_mem_put(bc->mctx, bad, sizeof(*bad) + - bad->name.length); - bc->count--; - } else - prev = bad; - } - } - - UNLOCK(&bc->lock); -} - - -void -dns_badcache_print(dns_badcache_t *bc, const char *cachename, FILE *fp) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - dns_bcentry_t *bad, *next, *prev; - isc_time_t now; - unsigned int i; - uint64_t t; - - REQUIRE(VALID_BADCACHE(bc)); - REQUIRE(cachename != NULL); - REQUIRE(fp != NULL); - - LOCK(&bc->lock); - fprintf(fp, ";\n; %s\n;\n", cachename); - - TIME_NOW(&now); - for (i = 0; bc->count > 0 && i < bc->size; i++) { - prev = NULL; - for (bad = bc->table[i]; bad != NULL; bad = next) { - next = bad->next; - if (isc_time_compare(&bad->expire, &now) < 0) { - if (prev != NULL) - prev->next = bad->next; - else - bc->table[i] = bad->next; - - isc_mem_put(bc->mctx, bad, sizeof(*bad) + - bad->name.length); - bc->count--; - continue; - } - prev = bad; - dns_name_format(&bad->name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(bad->type, typebuf, - sizeof(typebuf)); - t = isc_time_microdiff(&bad->expire, &now); - t /= 1000; - fprintf(fp, "; %s/%s [ttl " - "%" PRIu64 "]\n", - namebuf, typebuf, t); - } - } - UNLOCK(&bc->lock); -} diff --git a/lib/dns-pkcs11/byaddr.c b/lib/dns-pkcs11/byaddr.c deleted file mode 100644 index e24be6e..0000000 --- a/lib/dns-pkcs11/byaddr.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * XXXRTH We could use a static event... - */ - -static char hex_digits[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -}; - -isc_result_t -dns_byaddr_createptrname(isc_netaddr_t *address, bool nibble, - dns_name_t *name) -{ - /* - * We dropped bitstring labels, so all lookups will use nibbles. - */ - UNUSED(nibble); - - return (dns_byaddr_createptrname2(address, - DNS_BYADDROPT_IPV6INT, name)); -} - -isc_result_t -dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, - dns_name_t *name) -{ - char textname[128]; - unsigned char *bytes; - int i; - char *cp; - isc_buffer_t buffer; - unsigned int len; - - REQUIRE(address != NULL); - - /* - * We create the text representation and then convert to a - * dns_name_t. This is not maximally efficient, but it keeps all - * of the knowledge of wire format in the dns_name_ routines. - */ - - bytes = (unsigned char *)(&address->type); - if (address->family == AF_INET) { - (void)snprintf(textname, sizeof(textname), - "%u.%u.%u.%u.in-addr.arpa.", - ((unsigned int)bytes[3] & 0xffU), - ((unsigned int)bytes[2] & 0xffU), - ((unsigned int)bytes[1] & 0xffU), - ((unsigned int)bytes[0] & 0xffU)); - } else if (address->family == AF_INET6) { - size_t remaining; - - cp = textname; - for (i = 15; i >= 0; i--) { - *cp++ = hex_digits[bytes[i] & 0x0f]; - *cp++ = '.'; - *cp++ = hex_digits[(bytes[i] >> 4) & 0x0f]; - *cp++ = '.'; - } - remaining = sizeof(textname) - (cp - textname); - if ((options & DNS_BYADDROPT_IPV6INT) != 0) { - strlcpy(cp, "ip6.int.", remaining); - } else { - strlcpy(cp, "ip6.arpa.", remaining); - } - } else - return (ISC_R_NOTIMPLEMENTED); - - len = (unsigned int)strlen(textname); - isc_buffer_init(&buffer, textname, len); - isc_buffer_add(&buffer, len); - return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL)); -} - -struct dns_byaddr { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_mutex_t lock; - dns_fixedname_t name; - /* Locked by lock. */ - unsigned int options; - dns_lookup_t * lookup; - isc_task_t * task; - dns_byaddrevent_t * event; - bool canceled; -}; - -#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd') -#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC) - -#define MAX_RESTARTS 16 - -static inline isc_result_t -copy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) { - isc_result_t result; - dns_name_t *name; - dns_rdata_t rdata = DNS_RDATA_INIT; - - /* - * The caller must be holding the byaddr's lock. - */ - - result = dns_rdataset_first(rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdata_ptr_t ptr; - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &ptr, NULL); - if (result != ISC_R_SUCCESS) - return (result); - name = isc_mem_get(byaddr->mctx, sizeof(*name)); - if (name == NULL) { - dns_rdata_freestruct(&ptr); - return (ISC_R_NOMEMORY); - } - dns_name_init(name, NULL); - result = dns_name_dup(&ptr.ptr, byaddr->mctx, name); - dns_rdata_freestruct(&ptr); - if (result != ISC_R_SUCCESS) { - isc_mem_put(byaddr->mctx, name, sizeof(*name)); - return (ISC_R_NOMEMORY); - } - ISC_LIST_APPEND(byaddr->event->names, name, link); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(rdataset); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - return (result); -} - -static void -lookup_done(isc_task_t *task, isc_event_t *event) { - dns_byaddr_t *byaddr = event->ev_arg; - dns_lookupevent_t *levent; - isc_result_t result; - - REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); - REQUIRE(VALID_BYADDR(byaddr)); - REQUIRE(byaddr->task == task); - - UNUSED(task); - - levent = (dns_lookupevent_t *)event; - - if (levent->result == ISC_R_SUCCESS) { - result = copy_ptr_targets(byaddr, levent->rdataset); - byaddr->event->result = result; - } else - byaddr->event->result = levent->result; - isc_event_free(&event); - isc_task_sendanddetach(&byaddr->task, (isc_event_t **)&byaddr->event); -} - -static void -bevent_destroy(isc_event_t *event) { - dns_byaddrevent_t *bevent; - dns_name_t *name, *next_name; - isc_mem_t *mctx; - - REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE); - mctx = event->ev_destroy_arg; - bevent = (dns_byaddrevent_t *)event; - - for (name = ISC_LIST_HEAD(bevent->names); - name != NULL; - name = next_name) { - next_name = ISC_LIST_NEXT(name, link); - ISC_LIST_UNLINK(bevent->names, name, link); - dns_name_free(name, mctx); - isc_mem_put(mctx, name, sizeof(*name)); - } - isc_mem_put(mctx, event, event->ev_size); -} - -isc_result_t -dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp) -{ - isc_result_t result; - dns_byaddr_t *byaddr; - isc_event_t *ievent; - - byaddr = isc_mem_get(mctx, sizeof(*byaddr)); - if (byaddr == NULL) - return (ISC_R_NOMEMORY); - byaddr->mctx = NULL; - isc_mem_attach(mctx, &byaddr->mctx); - byaddr->options = options; - - byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event)); - if (byaddr->event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_byaddr; - } - ISC_EVENT_INIT(byaddr->event, sizeof(*byaddr->event), 0, NULL, - DNS_EVENT_BYADDRDONE, action, arg, byaddr, - bevent_destroy, mctx); - byaddr->event->result = ISC_R_FAILURE; - ISC_LIST_INIT(byaddr->event->names); - - byaddr->task = NULL; - isc_task_attach(task, &byaddr->task); - - result = isc_mutex_init(&byaddr->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_event; - - dns_fixedname_init(&byaddr->name); - - result = dns_byaddr_createptrname2(address, options, - dns_fixedname_name(&byaddr->name)); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - byaddr->lookup = NULL; - result = dns_lookup_create(mctx, dns_fixedname_name(&byaddr->name), - dns_rdatatype_ptr, view, 0, task, - lookup_done, byaddr, &byaddr->lookup); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - byaddr->canceled = false; - byaddr->magic = BYADDR_MAGIC; - - *byaddrp = byaddr; - - return (ISC_R_SUCCESS); - - cleanup_lock: - DESTROYLOCK(&byaddr->lock); - - cleanup_event: - ievent = (isc_event_t *)byaddr->event; - isc_event_free(&ievent); - byaddr->event = NULL; - - isc_task_detach(&byaddr->task); - - cleanup_byaddr: - isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr)); - - return (result); -} - -void -dns_byaddr_cancel(dns_byaddr_t *byaddr) { - REQUIRE(VALID_BYADDR(byaddr)); - - LOCK(&byaddr->lock); - - if (!byaddr->canceled) { - byaddr->canceled = true; - if (byaddr->lookup != NULL) - dns_lookup_cancel(byaddr->lookup); - } - - UNLOCK(&byaddr->lock); -} - -void -dns_byaddr_destroy(dns_byaddr_t **byaddrp) { - dns_byaddr_t *byaddr; - - REQUIRE(byaddrp != NULL); - byaddr = *byaddrp; - REQUIRE(VALID_BYADDR(byaddr)); - REQUIRE(byaddr->event == NULL); - REQUIRE(byaddr->task == NULL); - dns_lookup_destroy(&byaddr->lookup); - - DESTROYLOCK(&byaddr->lock); - byaddr->magic = 0; - isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr)); - - *byaddrp = NULL; -} diff --git a/lib/dns-pkcs11/cache.c b/lib/dns-pkcs11/cache.c deleted file mode 100644 index 617737a..0000000 --- a/lib/dns-pkcs11/cache.c +++ /dev/null @@ -1,1607 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rbtdb.h" - -#define CACHE_MAGIC ISC_MAGIC('$', '$', '$', '$') -#define VALID_CACHE(cache) ISC_MAGIC_VALID(cache, CACHE_MAGIC) - -/*! - * Control incremental cleaning. - * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). - * See also DNS_CACHE_CLEANERINCREMENT - */ -#define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */ -/*! - * Control incremental cleaning. - * CLEANERINCREMENT is how many nodes are examined in one pass. - * See also DNS_CACHE_MINSIZE - */ -#define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */ - -/*** - *** Types - ***/ - -/* - * A cache_cleaner_t encapsulates the state of the periodic - * cache cleaning. - */ - -typedef struct cache_cleaner cache_cleaner_t; - -typedef enum { - cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */ - cleaner_s_busy, /*%< Currently cleaning. */ - cleaner_s_done /*%< Freed enough memory after being overmem. */ -} cleaner_state_t; - -/* - * Convenience macros for comprehensive assertion checking. - */ -#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ - (c)->resched_event != NULL) -#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ - (c)->iterator != NULL && \ - (c)->resched_event == NULL) - -/*% - * Accesses to a cache cleaner object are synchronized through - * task/event serialization, or locked from the cache object. - */ -struct cache_cleaner { - isc_mutex_t lock; - /*%< - * Locks overmem_event, overmem. Note: never allocate memory - * while holding this lock - that could lead to deadlock since - * the lock is take by water() which is called from the memory - * allocator. - */ - - dns_cache_t *cache; - isc_task_t *task; - unsigned int cleaning_interval; /*% The cleaning-interval from - named.conf, in seconds. */ - isc_timer_t *cleaning_timer; - isc_event_t *resched_event; /*% Sent by cleaner task to - itself to reschedule */ - isc_event_t *overmem_event; - - dns_dbiterator_t *iterator; - unsigned int increment; /*% Number of names to - clean in one increment */ - cleaner_state_t state; /*% Idle/Busy. */ - bool overmem; /*% The cache is in an overmem state. */ - bool replaceiterator; -}; - -/*% - * The actual cache object. - */ - -struct dns_cache { - /* Unlocked. */ - unsigned int magic; - isc_mutex_t lock; - isc_mutex_t filelock; - isc_mem_t *mctx; /* Main cache memory */ - isc_mem_t *hmctx; /* Heap memory */ - char *name; - - /* Locked by 'lock'. */ - int references; - int live_tasks; - dns_rdataclass_t rdclass; - dns_db_t *db; - cache_cleaner_t cleaner; - char *db_type; - int db_argc; - char **db_argv; - size_t size; - dns_ttl_t serve_stale_ttl; - isc_stats_t *stats; - - /* Locked by 'filelock'. */ - char *filename; - /* Access to the on-disk cache file is also locked by 'filelock'. */ -}; - -/*** - *** Functions - ***/ - -static isc_result_t -cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, cache_cleaner_t *cleaner); - -static void -cleaning_timer_action(isc_task_t *task, isc_event_t *event); - -static void -incremental_cleaning_action(isc_task_t *task, isc_event_t *event); - -static void -cleaner_shutdown_action(isc_task_t *task, isc_event_t *event); - -static void -overmem_cleaning_action(isc_task_t *task, isc_event_t *event); - -static inline isc_result_t -cache_create_db(dns_cache_t *cache, dns_db_t **db) { - isc_result_t result; - result = dns_db_create(cache->mctx, cache->db_type, dns_rootname, - dns_dbtype_cache, cache->rdclass, - cache->db_argc, cache->db_argv, db); - if (result == ISC_R_SUCCESS) - dns_db_setservestalettl(*db, cache->serve_stale_ttl); - return (result); -} - -isc_result_t -dns_cache_create(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *db_type, unsigned int db_argc, char **db_argv, - dns_cache_t **cachep) -{ - return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass, "", - db_type, db_argc, db_argv, cachep)); -} - -isc_result_t -dns_cache_create2(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *cachename, const char *db_type, - unsigned int db_argc, char **db_argv, dns_cache_t **cachep) -{ - return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass, - cachename, db_type, db_argc, db_argv, - cachep)); -} - -isc_result_t -dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *cachename, const char *db_type, - unsigned int db_argc, char **db_argv, dns_cache_t **cachep) -{ - isc_result_t result; - dns_cache_t *cache; - int i, extra = 0; - isc_task_t *dbtask; - - REQUIRE(cachep != NULL); - REQUIRE(*cachep == NULL); - REQUIRE(cmctx != NULL); - REQUIRE(hmctx != NULL); - REQUIRE(cachename != NULL); - - cache = isc_mem_get(cmctx, sizeof(*cache)); - if (cache == NULL) - return (ISC_R_NOMEMORY); - - cache->mctx = cache->hmctx = NULL; - isc_mem_attach(cmctx, &cache->mctx); - isc_mem_attach(hmctx, &cache->hmctx); - - cache->name = NULL; - if (cachename != NULL) { - cache->name = isc_mem_strdup(cmctx, cachename); - if (cache->name == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_mem; - } - } - - result = isc_mutex_init(&cache->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - - result = isc_mutex_init(&cache->filelock); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - cache->references = 1; - cache->live_tasks = 0; - cache->rdclass = rdclass; - cache->serve_stale_ttl = 0; - - cache->stats = NULL; - result = isc_stats_create(cmctx, &cache->stats, - dns_cachestatscounter_max); - if (result != ISC_R_SUCCESS) - goto cleanup_filelock; - - cache->db_type = isc_mem_strdup(cmctx, db_type); - if (cache->db_type == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_stats; - } - - /* - * For databases of type "rbt" we pass hmctx to dns_db_create() - * via cache->db_argv, followed by the rest of the arguments in - * db_argv (of which there really shouldn't be any). - */ - if (strcmp(cache->db_type, "rbt") == 0) - extra = 1; - - cache->db_argc = db_argc + extra; - cache->db_argv = NULL; - - if (cache->db_argc != 0) { - cache->db_argv = isc_mem_get(cmctx, - cache->db_argc * sizeof(char *)); - if (cache->db_argv == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_dbtype; - } - - for (i = 0; i < cache->db_argc; i++) - cache->db_argv[i] = NULL; - - cache->db_argv[0] = (char *) hmctx; - for (i = extra; i < cache->db_argc; i++) { - cache->db_argv[i] = isc_mem_strdup(cmctx, - db_argv[i - extra]); - if (cache->db_argv[i] == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_dbargv; - } - } - } - - /* - * Create the database - */ - cache->db = NULL; - result = cache_create_db(cache, &cache->db); - if (result != ISC_R_SUCCESS) - goto cleanup_dbargv; - if (taskmgr != NULL) { - dbtask = NULL; - result = isc_task_create(taskmgr, 1, &dbtask); - if (result != ISC_R_SUCCESS) - goto cleanup_db; - - isc_task_setname(dbtask, "cache_dbtask", NULL); - dns_db_settask(cache->db, dbtask); - isc_task_detach(&dbtask); - } - - cache->filename = NULL; - - cache->magic = CACHE_MAGIC; - - /* - * RBT-type cache DB has its own mechanism of cache cleaning and doesn't - * need the control of the generic cleaner. - */ - if (strcmp(db_type, "rbt") == 0) - result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner); - else { - result = cache_cleaner_init(cache, taskmgr, timermgr, - &cache->cleaner); - } - if (result != ISC_R_SUCCESS) - goto cleanup_db; - - result = dns_db_setcachestats(cache->db, cache->stats); - if (result != ISC_R_SUCCESS) - goto cleanup_db; - - - *cachep = cache; - return (ISC_R_SUCCESS); - - cleanup_db: - dns_db_detach(&cache->db); - cleanup_dbargv: - for (i = extra; i < cache->db_argc; i++) - if (cache->db_argv[i] != NULL) - isc_mem_free(cmctx, cache->db_argv[i]); - if (cache->db_argv != NULL) - isc_mem_put(cmctx, cache->db_argv, - cache->db_argc * sizeof(char *)); - cleanup_dbtype: - isc_mem_free(cmctx, cache->db_type); - cleanup_filelock: - DESTROYLOCK(&cache->filelock); - cleanup_stats: - isc_stats_detach(&cache->stats); - cleanup_lock: - DESTROYLOCK(&cache->lock); - cleanup_mem: - if (cache->name != NULL) - isc_mem_free(cmctx, cache->name); - isc_mem_detach(&cache->hmctx); - isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); - return (result); -} - -static void -cache_free(dns_cache_t *cache) { - int i; - - REQUIRE(VALID_CACHE(cache)); - REQUIRE(cache->references == 0); - - isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0); - - if (cache->cleaner.task != NULL) - isc_task_detach(&cache->cleaner.task); - - if (cache->cleaner.overmem_event != NULL) - isc_event_free(&cache->cleaner.overmem_event); - - if (cache->cleaner.resched_event != NULL) - isc_event_free(&cache->cleaner.resched_event); - - if (cache->cleaner.iterator != NULL) - dns_dbiterator_destroy(&cache->cleaner.iterator); - - DESTROYLOCK(&cache->cleaner.lock); - - if (cache->filename) { - isc_mem_free(cache->mctx, cache->filename); - cache->filename = NULL; - } - - if (cache->db != NULL) - dns_db_detach(&cache->db); - - if (cache->db_argv != NULL) { - /* - * We don't free db_argv[0] in "rbt" cache databases - * as it's a pointer to hmctx - */ - int extra = 0; - if (strcmp(cache->db_type, "rbt") == 0) - extra = 1; - for (i = extra; i < cache->db_argc; i++) - if (cache->db_argv[i] != NULL) - isc_mem_free(cache->mctx, cache->db_argv[i]); - isc_mem_put(cache->mctx, cache->db_argv, - cache->db_argc * sizeof(char *)); - } - - if (cache->db_type != NULL) - isc_mem_free(cache->mctx, cache->db_type); - - if (cache->name != NULL) - isc_mem_free(cache->mctx, cache->name); - - if (cache->stats != NULL) - isc_stats_detach(&cache->stats); - - DESTROYLOCK(&cache->lock); - DESTROYLOCK(&cache->filelock); - - cache->magic = 0; - isc_mem_detach(&cache->hmctx); - isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); -} - - -void -dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp) { - - REQUIRE(VALID_CACHE(cache)); - REQUIRE(targetp != NULL && *targetp == NULL); - - LOCK(&cache->lock); - cache->references++; - UNLOCK(&cache->lock); - - *targetp = cache; -} - -void -dns_cache_detach(dns_cache_t **cachep) { - dns_cache_t *cache; - bool free_cache = false; - - REQUIRE(cachep != NULL); - cache = *cachep; - REQUIRE(VALID_CACHE(cache)); - - LOCK(&cache->lock); - REQUIRE(cache->references > 0); - cache->references--; - if (cache->references == 0) { - cache->cleaner.overmem = false; - free_cache = true; - } - - *cachep = NULL; - - if (free_cache) { - /* - * When the cache is shut down, dump it to a file if one is - * specified. - */ - isc_result_t result = dns_cache_dump(cache); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "error dumping cache: %s ", - isc_result_totext(result)); - - /* - * If the cleaner task exists, let it free the cache. - */ - if (cache->live_tasks > 0) { - isc_task_shutdown(cache->cleaner.task); - free_cache = false; - } - } - - UNLOCK(&cache->lock); - - if (free_cache) - cache_free(cache); -} - -void -dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp) { - REQUIRE(VALID_CACHE(cache)); - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(cache->db != NULL); - - LOCK(&cache->lock); - dns_db_attach(cache->db, dbp); - UNLOCK(&cache->lock); - -} - -isc_result_t -dns_cache_setfilename(dns_cache_t *cache, const char *filename) { - char *newname; - - REQUIRE(VALID_CACHE(cache)); - REQUIRE(filename != NULL); - - newname = isc_mem_strdup(cache->mctx, filename); - if (newname == NULL) - return (ISC_R_NOMEMORY); - - LOCK(&cache->filelock); - if (cache->filename) - isc_mem_free(cache->mctx, cache->filename); - cache->filename = newname; - UNLOCK(&cache->filelock); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_cache_load(dns_cache_t *cache) { - isc_result_t result; - - REQUIRE(VALID_CACHE(cache)); - - if (cache->filename == NULL) - return (ISC_R_SUCCESS); - - LOCK(&cache->filelock); - result = dns_db_load(cache->db, cache->filename); - UNLOCK(&cache->filelock); - - return (result); -} - -isc_result_t -dns_cache_dump(dns_cache_t *cache) { - isc_result_t result; - - REQUIRE(VALID_CACHE(cache)); - - if (cache->filename == NULL) - return (ISC_R_SUCCESS); - - LOCK(&cache->filelock); - result = dns_master_dump(cache->mctx, cache->db, NULL, - &dns_master_style_cache, cache->filename); - UNLOCK(&cache->filelock); - return (result); - -} - -void -dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int t) { - isc_interval_t interval; - isc_result_t result; - - LOCK(&cache->lock); - - /* - * It may be the case that the cache has already shut down. - * If so, it has no timer. - */ - if (cache->cleaner.cleaning_timer == NULL) - goto unlock; - - cache->cleaner.cleaning_interval = t; - - if (t == 0) { - result = isc_timer_reset(cache->cleaner.cleaning_timer, - isc_timertype_inactive, - NULL, NULL, true); - } else { - isc_interval_set(&interval, cache->cleaner.cleaning_interval, - 0); - result = isc_timer_reset(cache->cleaner.cleaning_timer, - isc_timertype_ticker, - NULL, &interval, false); - } - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "could not set cache cleaning interval: %s", - isc_result_totext(result)); - - unlock: - UNLOCK(&cache->lock); -} - -unsigned int -dns_cache_getcleaninginterval(dns_cache_t *cache) { - unsigned int t; - - REQUIRE(VALID_CACHE(cache)); - - LOCK(&cache->lock); - t = cache->cleaner.cleaning_interval; - UNLOCK(&cache->lock); - - return (t); -} - -const char * -dns_cache_getname(dns_cache_t *cache) { - REQUIRE(VALID_CACHE(cache)); - - return (cache->name); -} - -/* - * Initialize the cache cleaner object at *cleaner. - * Space for the object must be allocated by the caller. - */ - -static isc_result_t -cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, cache_cleaner_t *cleaner) -{ - isc_result_t result; - - result = isc_mutex_init(&cleaner->lock); - if (result != ISC_R_SUCCESS) - goto fail; - - cleaner->increment = DNS_CACHE_CLEANERINCREMENT; - cleaner->state = cleaner_s_idle; - cleaner->cache = cache; - cleaner->iterator = NULL; - cleaner->overmem = false; - cleaner->replaceiterator = false; - - cleaner->task = NULL; - cleaner->cleaning_timer = NULL; - cleaner->resched_event = NULL; - cleaner->overmem_event = NULL; - cleaner->cleaning_interval = 0; /* Initially turned off. */ - - result = dns_db_createiterator(cleaner->cache->db, false, - &cleaner->iterator); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (taskmgr != NULL && timermgr != NULL) { - result = isc_task_create(taskmgr, 1, &cleaner->task); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_task_create() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - cleaner->cache->live_tasks++; - isc_task_setname(cleaner->task, "cachecleaner", cleaner); - - result = isc_task_onshutdown(cleaner->task, - cleaner_shutdown_action, cache); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "cache cleaner: " - "isc_task_onshutdown() failed: %s", - dns_result_totext(result)); - goto cleanup; - } - - result = isc_timer_create(timermgr, isc_timertype_inactive, - NULL, NULL, cleaner->task, - cleaning_timer_action, cleaner, - &cleaner->cleaning_timer); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timer_create() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - - cleaner->resched_event = - isc_event_allocate(cache->mctx, cleaner, - DNS_EVENT_CACHECLEAN, - incremental_cleaning_action, - cleaner, sizeof(isc_event_t)); - if (cleaner->resched_event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - cleaner->overmem_event = - isc_event_allocate(cache->mctx, cleaner, - DNS_EVENT_CACHEOVERMEM, - overmem_cleaning_action, - cleaner, sizeof(isc_event_t)); - if (cleaner->overmem_event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - return (ISC_R_SUCCESS); - - cleanup: - if (cleaner->overmem_event != NULL) - isc_event_free(&cleaner->overmem_event); - if (cleaner->resched_event != NULL) - isc_event_free(&cleaner->resched_event); - if (cleaner->cleaning_timer != NULL) - isc_timer_detach(&cleaner->cleaning_timer); - if (cleaner->task != NULL) - isc_task_detach(&cleaner->task); - if (cleaner->iterator != NULL) - dns_dbiterator_destroy(&cleaner->iterator); - DESTROYLOCK(&cleaner->lock); - fail: - return (result); -} - -static void -begin_cleaning(cache_cleaner_t *cleaner) { - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(CLEANER_IDLE(cleaner)); - - /* - * Create an iterator, if it does not already exist, and - * position it at the beginning of the cache. - */ - if (cleaner->iterator == NULL) - result = dns_db_createiterator(cleaner->cache->db, false, - &cleaner->iterator); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "cache cleaner could not create " - "iterator: %s", isc_result_totext(result)); - else { - dns_dbiterator_setcleanmode(cleaner->iterator, true); - result = dns_dbiterator_first(cleaner->iterator); - } - if (result != ISC_R_SUCCESS) { - /* - * If the result is ISC_R_NOMORE, the database is empty, - * so there is nothing to be cleaned. - */ - if (result != ISC_R_NOMORE && cleaner->iterator != NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "cache cleaner: " - "dns_dbiterator_first() failed: %s", - dns_result_totext(result)); - dns_dbiterator_destroy(&cleaner->iterator); - } else if (cleaner->iterator != NULL) { - result = dns_dbiterator_pause(cleaner->iterator); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - } else { - /* - * Pause the iterator to free its lock. - */ - result = dns_dbiterator_pause(cleaner->iterator); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "begin cache cleaning, mem inuse %lu", - (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); - cleaner->state = cleaner_s_busy; - isc_task_send(cleaner->task, &cleaner->resched_event); - } - - return; -} - -static void -end_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) { - isc_result_t result; - - REQUIRE(CLEANER_BUSY(cleaner)); - REQUIRE(event != NULL); - - result = dns_dbiterator_pause(cleaner->iterator); - if (result != ISC_R_SUCCESS) - dns_dbiterator_destroy(&cleaner->iterator); - - dns_cache_setcleaninginterval(cleaner->cache, - cleaner->cleaning_interval); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), "end cache cleaning, mem inuse %lu", - (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); - - cleaner->state = cleaner_s_idle; - cleaner->resched_event = event; -} - -/* - * This is run once for every cache-cleaning-interval as defined in named.conf. - */ -static void -cleaning_timer_action(isc_task_t *task, isc_event_t *event) { - cache_cleaner_t *cleaner = event->ev_arg; - - UNUSED(task); - - INSIST(task == cleaner->task); - INSIST(event->ev_type == ISC_TIMEREVENT_TICK); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), "cache cleaning timer fired, " - "cleaner state = %d", cleaner->state); - - if (cleaner->state == cleaner_s_idle) - begin_cleaning(cleaner); - - isc_event_free(&event); -} - -/* - * This is called when the cache either surpasses its upper limit - * or shrinks beyond its lower limit. - */ -static void -overmem_cleaning_action(isc_task_t *task, isc_event_t *event) { - cache_cleaner_t *cleaner = event->ev_arg; - bool want_cleaning = false; - - UNUSED(task); - - INSIST(task == cleaner->task); - INSIST(event->ev_type == DNS_EVENT_CACHEOVERMEM); - INSIST(cleaner->overmem_event == NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), "overmem_cleaning_action called, " - "overmem = %d, state = %d", cleaner->overmem, - cleaner->state); - - LOCK(&cleaner->lock); - - if (cleaner->overmem) { - if (cleaner->state == cleaner_s_idle) - want_cleaning = true; - } else { - if (cleaner->state == cleaner_s_busy) - /* - * end_cleaning() can't be called here because - * then both cleaner->overmem_event and - * cleaner->resched_event will point to this - * event. Set the state to done, and then - * when the incremental_cleaning_action() event - * is posted, it will handle the end_cleaning. - */ - cleaner->state = cleaner_s_done; - } - - cleaner->overmem_event = event; - - UNLOCK(&cleaner->lock); - - if (want_cleaning) - begin_cleaning(cleaner); -} - -/* - * Do incremental cleaning. - */ -static void -incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { - cache_cleaner_t *cleaner = event->ev_arg; - isc_result_t result; - unsigned int n_names; - isc_time_t start; - - UNUSED(task); - - INSIST(task == cleaner->task); - INSIST(event->ev_type == DNS_EVENT_CACHECLEAN); - - if (cleaner->state == cleaner_s_done) { - cleaner->state = cleaner_s_busy; - end_cleaning(cleaner, event); - LOCK(&cleaner->cache->lock); - LOCK(&cleaner->lock); - if (cleaner->replaceiterator) { - dns_dbiterator_destroy(&cleaner->iterator); - (void) dns_db_createiterator(cleaner->cache->db, - false, - &cleaner->iterator); - cleaner->replaceiterator = false; - } - UNLOCK(&cleaner->lock); - UNLOCK(&cleaner->cache->lock); - return; - } - - INSIST(CLEANER_BUSY(cleaner)); - - n_names = cleaner->increment; - - REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator)); - - isc_time_now(&start); - while (n_names-- > 0) { - dns_dbnode_t *node = NULL; - - result = dns_dbiterator_current(cleaner->iterator, &node, - NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "cache cleaner: dns_dbiterator_current() " - "failed: %s", dns_result_totext(result)); - - end_cleaning(cleaner, event); - return; - } - - /* - * The node was not needed, but was required by - * dns_dbiterator_current(). Give up its reference. - */ - dns_db_detachnode(cleaner->cache->db, &node); - - /* - * Step to the next node. - */ - result = dns_dbiterator_next(cleaner->iterator); - - if (result != ISC_R_SUCCESS) { - /* - * Either the end was reached (ISC_R_NOMORE) or - * some error was signaled. If the cache is still - * overmem and no error was encountered, - * keep trying to clean it, otherwise stop cleaning. - */ - if (result != ISC_R_NOMORE) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "cache cleaner: " - "dns_dbiterator_next() " - "failed: %s", - dns_result_totext(result)); - else if (cleaner->overmem) { - result = dns_dbiterator_first(cleaner-> - iterator); - if (result == ISC_R_SUCCESS) { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), - "cache cleaner: " - "still overmem, " - "reset and try again"); - continue; - } - } - - end_cleaning(cleaner, event); - return; - } - } - - /* - * We have successfully performed a cleaning increment but have - * not gone through the entire cache. Free the iterator locks - * and reschedule another batch. If it fails, just try to continue - * anyway. - */ - result = dns_dbiterator_pause(cleaner->iterator); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), "cache cleaner: checked %u nodes, " - "mem inuse %lu, sleeping", cleaner->increment, - (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); - - isc_task_send(task, &event); - INSIST(CLEANER_BUSY(cleaner)); - return; -} - -/* - * Do immediate cleaning. - */ -isc_result_t -dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now) { - isc_result_t result; - dns_dbiterator_t *iterator = NULL; - - REQUIRE(VALID_CACHE(cache)); - - result = dns_db_createiterator(cache->db, 0, &iterator); - if (result != ISC_R_SUCCESS) - return result; - - result = dns_dbiterator_first(iterator); - - while (result == ISC_R_SUCCESS) { - dns_dbnode_t *node = NULL; - result = dns_dbiterator_current(iterator, &node, - (dns_name_t *)NULL); - if (result != ISC_R_SUCCESS) - break; - - /* - * Check TTLs, mark expired rdatasets stale. - */ - result = dns_db_expirenode(cache->db, node, now); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "cache cleaner: dns_db_expirenode() " - "failed: %s", - dns_result_totext(result)); - /* - * Continue anyway. - */ - } - - /* - * This is where the actual freeing takes place. - */ - dns_db_detachnode(cache->db, &node); - - result = dns_dbiterator_next(iterator); - } - - dns_dbiterator_destroy(&iterator); - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - return (result); -} - -static void -water(void *arg, int mark) { - dns_cache_t *cache = arg; - bool overmem = (mark == ISC_MEM_HIWATER); - - REQUIRE(VALID_CACHE(cache)); - - LOCK(&cache->cleaner.lock); - - if (overmem != cache->cleaner.overmem) { - dns_db_overmem(cache->db, overmem); - cache->cleaner.overmem = overmem; - isc_mem_waterack(cache->mctx, mark); - } - - if (cache->cleaner.overmem_event != NULL) - isc_task_send(cache->cleaner.task, - &cache->cleaner.overmem_event); - - UNLOCK(&cache->cleaner.lock); -} - -void -dns_cache_setcachesize(dns_cache_t *cache, size_t size) { - size_t hiwater, lowater; - - REQUIRE(VALID_CACHE(cache)); - - /* - * Impose a minimum cache size; pathological things happen if there - * is too little room. - */ - if (size != 0U && size < DNS_CACHE_MINSIZE) - size = DNS_CACHE_MINSIZE; - - LOCK(&cache->lock); - cache->size = size; - UNLOCK(&cache->lock); - - hiwater = size - (size >> 3); /* Approximately 7/8ths. */ - lowater = size - (size >> 2); /* Approximately 3/4ths. */ - - /* - * If the cache was overmem and cleaning, but now with the new limits - * it is no longer in an overmem condition, then the next - * isc_mem_put for cache memory will do the right thing and trigger - * water(). - */ - - if (size == 0U || hiwater == 0U || lowater == 0U) - /* - * Disable cache memory limiting. - */ - isc_mem_setwater(cache->mctx, water, cache, 0, 0); - else - /* - * Establish new cache memory limits (either for the first - * time, or replacing other limits). - */ - isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater); -} - -size_t -dns_cache_getcachesize(dns_cache_t *cache) { - size_t size; - - REQUIRE(VALID_CACHE(cache)); - - LOCK(&cache->lock); - size = cache->size; - UNLOCK(&cache->lock); - - return (size); -} - -void -dns_cache_setservestalettl(dns_cache_t *cache, dns_ttl_t ttl) { - REQUIRE(VALID_CACHE(cache)); - - LOCK(&cache->lock); - cache->serve_stale_ttl = ttl; - UNLOCK(&cache->lock); - - (void)dns_db_setservestalettl(cache->db, ttl); -} - -dns_ttl_t -dns_cache_getservestalettl(dns_cache_t *cache) { - dns_ttl_t ttl; - isc_result_t result; - - REQUIRE(VALID_CACHE(cache)); - - /* - * Could get it straight from the dns_cache_t, but use db - * to confirm the value that the db is really using. - */ - result = dns_db_getservestalettl(cache->db, &ttl); - return result == ISC_R_SUCCESS ? ttl : 0; -} - -/* - * The cleaner task is shutting down; do the necessary cleanup. - */ -static void -cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) { - dns_cache_t *cache = event->ev_arg; - bool should_free = false; - - UNUSED(task); - - INSIST(task == cache->cleaner.task); - INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - - if (CLEANER_BUSY(&cache->cleaner)) - end_cleaning(&cache->cleaner, event); - else - isc_event_free(&event); - - LOCK(&cache->lock); - - cache->live_tasks--; - INSIST(cache->live_tasks == 0); - - if (cache->references == 0) - should_free = true; - - /* - * By detaching the timer in the context of its task, - * we are guaranteed that there will be no further timer - * events. - */ - if (cache->cleaner.cleaning_timer != NULL) - isc_timer_detach(&cache->cleaner.cleaning_timer); - - /* Make sure we don't reschedule anymore. */ - (void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL); - - UNLOCK(&cache->lock); - - if (should_free) - cache_free(cache); -} - -isc_result_t -dns_cache_flush(dns_cache_t *cache) { - dns_db_t *db = NULL, *olddb; - dns_dbiterator_t *dbiterator = NULL, *olddbiterator = NULL; - isc_result_t result; - - result = cache_create_db(cache, &db); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_createiterator(db, false, &dbiterator); - if (result != ISC_R_SUCCESS) { - dns_db_detach(&db); - return (result); - } - - LOCK(&cache->lock); - LOCK(&cache->cleaner.lock); - if (cache->cleaner.state == cleaner_s_idle) { - olddbiterator = cache->cleaner.iterator; - cache->cleaner.iterator = dbiterator; - dbiterator = NULL; - } else { - if (cache->cleaner.state == cleaner_s_busy) - cache->cleaner.state = cleaner_s_done; - cache->cleaner.replaceiterator = true; - } - olddb = cache->db; - cache->db = db; - dns_db_setcachestats(cache->db, cache->stats); - UNLOCK(&cache->cleaner.lock); - UNLOCK(&cache->lock); - - if (dbiterator != NULL) - dns_dbiterator_destroy(&dbiterator); - if (olddbiterator != NULL) - dns_dbiterator_destroy(&olddbiterator); - dns_db_detach(&olddb); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -clearnode(dns_db_t *db, dns_dbnode_t *node) { - isc_result_t result; - dns_rdatasetiter_t *iter = NULL; - - result = dns_db_allrdatasets(db, node, NULL, (isc_stdtime_t)0, &iter); - if (result != ISC_R_SUCCESS) - return (result); - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - dns_rdataset_t rdataset; - dns_rdataset_init(&rdataset); - - dns_rdatasetiter_current(iter, &rdataset); - result = dns_db_deleterdataset(db, node, NULL, - rdataset.type, rdataset.covers); - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) - break; - } - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - dns_rdatasetiter_destroy(&iter); - return (result); -} - -static isc_result_t -cleartree(dns_db_t *db, dns_name_t *name) { - isc_result_t result, answer = ISC_R_SUCCESS; - dns_dbiterator_t *iter = NULL; - dns_dbnode_t *node = NULL, *top = NULL; - dns_fixedname_t fnodename; - dns_name_t *nodename; - - /* - * Create the node if it doesn't exist so dns_dbiterator_seek() - * can find it. We will continue even if this fails. - */ - (void)dns_db_findnode(db, name, true, &top); - - nodename = dns_fixedname_initname(&fnodename); - - result = dns_db_createiterator(db, 0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_dbiterator_seek(iter, name); - if (result == DNS_R_PARTIALMATCH) - result = dns_dbiterator_next(iter); - if (result != ISC_R_SUCCESS) - goto cleanup; - - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(iter, &node, nodename); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * Are we done? - */ - if (! dns_name_issubdomain(nodename, name)) - goto cleanup; - - /* - * If clearnode fails record and move onto the next node. - */ - result = clearnode(db, node); - if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) - answer = result; - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(iter); - } - - cleanup: - if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) - answer = result; - if (node != NULL) - dns_db_detachnode(db, &node); - if (iter != NULL) - dns_dbiterator_destroy(&iter); - if (top != NULL) - dns_db_detachnode(db, &top); - - return (answer); -} - -isc_result_t -dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { - return (dns_cache_flushnode(cache, name, false)); -} - -isc_result_t -dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, - bool tree) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_db_t *db = NULL; - - if (tree && dns_name_equal(name, dns_rootname)) - return (dns_cache_flush(cache)); - - LOCK(&cache->lock); - if (cache->db != NULL) - dns_db_attach(cache->db, &db); - UNLOCK(&cache->lock); - if (db == NULL) - return (ISC_R_SUCCESS); - - if (tree) { - result = cleartree(cache->db, name); - } else { - result = dns_db_findnode(cache->db, name, false, &node); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_db; - } - if (result != ISC_R_SUCCESS) - goto cleanup_db; - result = clearnode(cache->db, node); - dns_db_detachnode(cache->db, &node); - } - - cleanup_db: - dns_db_detach(&db); - return (result); -} - -isc_stats_t * -dns_cache_getstats(dns_cache_t *cache) { - REQUIRE(VALID_CACHE(cache)); - return (cache->stats); -} - -void -dns_cache_updatestats(dns_cache_t *cache, isc_result_t result) { - REQUIRE(VALID_CACHE(cache)); - if (cache->stats == NULL) - return; - - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - case DNS_R_CNAME: - case DNS_R_DNAME: - case DNS_R_GLUE: - case DNS_R_ZONECUT: - isc_stats_increment(cache->stats, - dns_cachestatscounter_queryhits); - break; - default: - isc_stats_increment(cache->stats, - dns_cachestatscounter_querymisses); - } -} - -/* - * XXX: Much of the following code has been copied in from statschannel.c. - * We should refactor this into a generic function in stats.c that can be - * called from both places. - */ -typedef struct -cache_dumparg { - isc_statsformat_t type; - void *arg; /* type dependent argument */ - int ncounters; /* for general statistics */ - int *counterindices; /* for general statistics */ - uint64_t *countervalues; /* for general statistics */ - isc_result_t result; -} cache_dumparg_t; - -static void -getcounter(isc_statscounter_t counter, uint64_t val, void *arg) { - cache_dumparg_t *dumparg = arg; - - REQUIRE(counter < dumparg->ncounters); - dumparg->countervalues[counter] = val; -} - -static void -getcounters(isc_stats_t *stats, isc_statsformat_t type, int ncounters, - int *indices, uint64_t *values) -{ - cache_dumparg_t dumparg; - - memset(values, 0, sizeof(values[0]) * ncounters); - - dumparg.type = type; - dumparg.ncounters = ncounters; - dumparg.counterindices = indices; - dumparg.countervalues = values; - - isc_stats_dump(stats, getcounter, &dumparg, ISC_STATSDUMP_VERBOSE); -} - -void -dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) { - int indices[dns_cachestatscounter_max]; - uint64_t values[dns_cachestatscounter_max]; - - REQUIRE(VALID_CACHE(cache)); - - getcounters(cache->stats, isc_statsformat_file, - dns_cachestatscounter_max, indices, values); - - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_hits], - "cache hits"); - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_misses], - "cache misses"); - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_queryhits], - "cache hits (from query)"); - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_querymisses], - "cache misses (from query)"); - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_deletelru], - "cache records deleted due to memory exhaustion"); - fprintf(fp, "%20" PRIu64 " %s\n", - values[dns_cachestatscounter_deletettl], - "cache records deleted due to TTL expiration"); - fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db), - "cache database nodes"); - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) dns_db_hashsize(cache->db), - "cache database hash buckets"); - - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_total(cache->mctx), - "cache tree memory total"); - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_inuse(cache->mctx), - "cache tree memory in use"); - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_maxinuse(cache->mctx), - "cache tree highest memory in use"); - - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_total(cache->hmctx), - "cache heap memory total"); - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_inuse(cache->hmctx), - "cache heap memory in use"); - fprintf(fp, "%20" PRIu64 " %s\n", - (uint64_t) isc_mem_maxinuse(cache->hmctx), - "cache heap highest memory in use"); -} - -#ifdef HAVE_LIBXML2 -#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) -static int -renderstat(const char *name, uint64_t value, xmlTextWriterPtr writer) { - int xmlrc; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); - TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "name", ISC_XMLCHAR name)); - TRY0(xmlTextWriterWriteFormatString(writer, - "%" PRIu64, - value)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ - -error: - return (xmlrc); -} - -int -dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer) { - int indices[dns_cachestatscounter_max]; - uint64_t values[dns_cachestatscounter_max]; - int xmlrc; - - REQUIRE(VALID_CACHE(cache)); - - getcounters(cache->stats, isc_statsformat_file, - dns_cachestatscounter_max, indices, values); - TRY0(renderstat("CacheHits", - values[dns_cachestatscounter_hits], writer)); - TRY0(renderstat("CacheMisses", - values[dns_cachestatscounter_misses], writer)); - TRY0(renderstat("QueryHits", - values[dns_cachestatscounter_queryhits], writer)); - TRY0(renderstat("QueryMisses", - values[dns_cachestatscounter_querymisses], writer)); - TRY0(renderstat("DeleteLRU", - values[dns_cachestatscounter_deletelru], writer)); - TRY0(renderstat("DeleteTTL", - values[dns_cachestatscounter_deletettl], writer)); - - TRY0(renderstat("CacheNodes", dns_db_nodecount(cache->db), writer)); - TRY0(renderstat("CacheBuckets", dns_db_hashsize(cache->db), writer)); - - TRY0(renderstat("TreeMemTotal", isc_mem_total(cache->mctx), writer)); - TRY0(renderstat("TreeMemInUse", isc_mem_inuse(cache->mctx), writer)); - TRY0(renderstat("TreeMemMax", isc_mem_maxinuse(cache->mctx), writer)); - - TRY0(renderstat("HeapMemTotal", isc_mem_total(cache->hmctx), writer)); - TRY0(renderstat("HeapMemInUse", isc_mem_inuse(cache->hmctx), writer)); - TRY0(renderstat("HeapMemMax", isc_mem_maxinuse(cache->hmctx), writer)); -error: - return (xmlrc); -} -#endif - -#ifdef HAVE_JSON -#define CHECKMEM(m) do { \ - if (m == NULL) { \ - result = ISC_R_NOMEMORY;\ - goto error;\ - } \ -} while(0) - -isc_result_t -dns_cache_renderjson(dns_cache_t *cache, json_object *cstats) { - isc_result_t result = ISC_R_SUCCESS; - int indices[dns_cachestatscounter_max]; - uint64_t values[dns_cachestatscounter_max]; - json_object *obj; - - REQUIRE(VALID_CACHE(cache)); - - getcounters(cache->stats, isc_statsformat_file, - dns_cachestatscounter_max, indices, values); - - obj = json_object_new_int64(values[dns_cachestatscounter_hits]); - CHECKMEM(obj); - json_object_object_add(cstats, "CacheHits", obj); - - obj = json_object_new_int64(values[dns_cachestatscounter_misses]); - CHECKMEM(obj); - json_object_object_add(cstats, "CacheMisses", obj); - - obj = json_object_new_int64(values[dns_cachestatscounter_queryhits]); - CHECKMEM(obj); - json_object_object_add(cstats, "QueryHits", obj); - - obj = json_object_new_int64(values[dns_cachestatscounter_querymisses]); - CHECKMEM(obj); - json_object_object_add(cstats, "QueryMisses", obj); - - obj = json_object_new_int64(values[dns_cachestatscounter_deletelru]); - CHECKMEM(obj); - json_object_object_add(cstats, "DeleteLRU", obj); - - obj = json_object_new_int64(values[dns_cachestatscounter_deletettl]); - CHECKMEM(obj); - json_object_object_add(cstats, "DeleteTTL", obj); - - obj = json_object_new_int64(dns_db_nodecount(cache->db)); - CHECKMEM(obj); - json_object_object_add(cstats, "CacheNodes", obj); - - obj = json_object_new_int64(dns_db_hashsize(cache->db)); - CHECKMEM(obj); - json_object_object_add(cstats, "CacheBuckets", obj); - - obj = json_object_new_int64(isc_mem_total(cache->mctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "TreeMemTotal", obj); - - obj = json_object_new_int64(isc_mem_inuse(cache->mctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "TreeMemInUse", obj); - - obj = json_object_new_int64(isc_mem_maxinuse(cache->mctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "TreeMemMax", obj); - - obj = json_object_new_int64(isc_mem_total(cache->hmctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "HeapMemTotal", obj); - - obj = json_object_new_int64(isc_mem_inuse(cache->hmctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "HeapMemInUse", obj); - - obj = json_object_new_int64(isc_mem_maxinuse(cache->hmctx)); - CHECKMEM(obj); - json_object_object_add(cstats, "HeapMemMax", obj); - - result = ISC_R_SUCCESS; -error: - return (result); -} -#endif diff --git a/lib/dns-pkcs11/callbacks.c b/lib/dns-pkcs11/callbacks.c deleted file mode 100644 index f9c9be4..0000000 --- a/lib/dns-pkcs11/callbacks.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include - -static void -stdio_error_warn_callback(dns_rdatacallbacks_t *, const char *, ...) - ISC_FORMAT_PRINTF(2, 3); - -static void -isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) - ISC_FORMAT_PRINTF(2, 3); - -static void -isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) - ISC_FORMAT_PRINTF(2, 3); - -/* - * Private - */ - -static void -stdio_error_warn_callback(dns_rdatacallbacks_t *callbacks, - const char *fmt, ...) -{ - va_list ap; - - UNUSED(callbacks); - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void -isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { - va_list ap; - - UNUSED(callbacks); - - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, /* XXX */ - ISC_LOG_ERROR, fmt, ap); - va_end(ap); -} - -static void -isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { - va_list ap; - - UNUSED(callbacks); - - va_start(ap, fmt); - - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, /* XXX */ - ISC_LOG_WARNING, fmt, ap); - va_end(ap); -} - -static void -dns_rdatacallbacks_initcommon(dns_rdatacallbacks_t *callbacks) { - REQUIRE(callbacks != NULL); - - callbacks->magic = DNS_CALLBACK_MAGIC; - callbacks->add = NULL; - callbacks->rawdata = NULL; - callbacks->zone = NULL; - callbacks->add_private = NULL; - callbacks->error_private = NULL; - callbacks->warn_private = NULL; -} - -/* - * Public. - */ - -void -dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks) { - dns_rdatacallbacks_initcommon(callbacks); - callbacks->error = isclog_error_callback; - callbacks->warn = isclog_warn_callback; -} - -void -dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks) { - dns_rdatacallbacks_initcommon(callbacks); - callbacks->error = stdio_error_warn_callback; - callbacks->warn = stdio_error_warn_callback; -} - diff --git a/lib/dns-pkcs11/catz.c b/lib/dns-pkcs11/catz.c deleted file mode 100644 index 304b038..0000000 --- a/lib/dns-pkcs11/catz.c +++ /dev/null @@ -1,2066 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define DNS_CATZ_ZONE_MAGIC ISC_MAGIC('c', 'a', 't', 'z') -#define DNS_CATZ_ZONES_MAGIC ISC_MAGIC('c', 'a', 't', 's') -#define DNS_CATZ_ENTRY_MAGIC ISC_MAGIC('c', 'a', 't', 'e') - -#define DNS_CATZ_ZONE_VALID(catz) ISC_MAGIC_VALID(catz, DNS_CATZ_ZONE_MAGIC) -#define DNS_CATZ_ZONES_VALID(catzs) ISC_MAGIC_VALID(catzs, DNS_CATZ_ZONES_MAGIC) -#define DNS_CATZ_ENTRY_VALID(entry) ISC_MAGIC_VALID(entry, DNS_CATZ_ENTRY_MAGIC) - -/*% - * Single member zone in a catalog - */ -struct dns_catz_entry { - unsigned int magic; - dns_name_t name; - dns_catz_options_t opts; - isc_refcount_t refs; -}; - -/*% - * Catalog zone - */ -struct dns_catz_zone { - unsigned int magic; - dns_name_t name; - dns_catz_zones_t *catzs; - dns_rdata_t soa; - /* key in entries is 'mhash', not domain name! */ - isc_ht_t *entries; - /* - * defoptions are taken from named.conf - * zoneoptions are global options from zone - */ - dns_catz_options_t defoptions; - dns_catz_options_t zoneoptions; - isc_time_t lastupdated; - bool updatepending; - uint32_t version; - - dns_db_t *db; - dns_dbversion_t *dbversion; - - isc_timer_t *updatetimer; - isc_event_t updateevent; - - bool active; - bool db_registered; - - isc_refcount_t refs; -}; - -static isc_result_t -catz_process_zones_entry(dns_catz_zone_t *zone, dns_rdataset_t *value, - dns_label_t *mhash); -static isc_result_t -catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value, - dns_label_t *mhash, dns_name_t *name); - -/*% - * Collection of catalog zones for a view - */ -struct dns_catz_zones { - unsigned int magic; - isc_ht_t *zones; - isc_mem_t *mctx; - isc_refcount_t refs; - isc_mutex_t lock; - dns_catz_zonemodmethods_t *zmm; - isc_taskmgr_t *taskmgr; - isc_timermgr_t *timermgr; - dns_view_t *view; - isc_task_t *updater; -}; - -void -dns_catz_options_init(dns_catz_options_t *options) { - - REQUIRE(options != NULL); - - dns_ipkeylist_init(&options->masters); - - options->allow_query = NULL; - options->allow_transfer = NULL; - - options->allow_query = NULL; - options->allow_transfer = NULL; - - options->in_memory = false; - options->min_update_interval = 5; - options->zonedir = NULL; -} - -void -dns_catz_options_free(dns_catz_options_t *options, isc_mem_t *mctx) { - - REQUIRE(options != NULL); - REQUIRE(mctx != NULL); - - if (options->masters.count != 0) - dns_ipkeylist_clear(mctx, &options->masters); - if (options->zonedir != NULL) { - isc_mem_free(mctx, options->zonedir); - options->zonedir = NULL; - } - if (options->allow_query != NULL) - isc_buffer_free(&options->allow_query); - if (options->allow_transfer != NULL) - isc_buffer_free(&options->allow_transfer); -} - -isc_result_t -dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *src, - dns_catz_options_t *dst) -{ - REQUIRE(mctx != NULL); - REQUIRE(src != NULL); - REQUIRE(dst != NULL); - REQUIRE(dst->masters.count == 0); - REQUIRE(dst->allow_query == NULL); - REQUIRE(dst->allow_transfer == NULL); - - if (src->masters.count != 0) - dns_ipkeylist_copy(mctx, &src->masters, &dst->masters); - - if (dst->zonedir != NULL) { - isc_mem_free(mctx, dst->zonedir); - dst->zonedir = NULL; - } - - if (src->zonedir != NULL) - dst->zonedir = isc_mem_strdup(mctx, src->zonedir); - - if (src->allow_query != NULL) - isc_buffer_dup(mctx, &dst->allow_query, src->allow_query); - - if (src->allow_transfer != NULL) - isc_buffer_dup(mctx, &dst->allow_transfer, src->allow_transfer); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_catz_options_setdefault(isc_mem_t *mctx, const dns_catz_options_t *defaults, - dns_catz_options_t *opts) -{ - REQUIRE(mctx != NULL); - REQUIRE(defaults != NULL); - REQUIRE(opts != NULL); - - if (opts->masters.count == 0 && defaults->masters.count != 0) - dns_ipkeylist_copy(mctx, &defaults->masters, &opts->masters); - - if (defaults->zonedir != NULL) - opts->zonedir = isc_mem_strdup(mctx, defaults->zonedir); - - if (opts->allow_query == NULL && defaults->allow_query != NULL) - isc_buffer_dup(mctx, &opts->allow_query, defaults->allow_query); - if (opts->allow_transfer == NULL && defaults->allow_transfer != NULL) - isc_buffer_dup(mctx, &opts->allow_transfer, - defaults->allow_transfer); - - /* This option is always taken from config, so it's always 'default' */ - opts->in_memory = defaults->in_memory; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain, - dns_catz_entry_t **nentryp) -{ - dns_catz_entry_t *nentry; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(nentryp != NULL && *nentryp == NULL); - - nentry = isc_mem_get(mctx, sizeof(dns_catz_entry_t)); - if (nentry == NULL) - return (ISC_R_NOMEMORY); - - dns_name_init(&nentry->name, NULL); - if (domain != NULL) { - result = dns_name_dup(domain, mctx, &nentry->name); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - dns_catz_options_init(&nentry->opts); - isc_refcount_init(&nentry->refs, 1); - nentry->magic = DNS_CATZ_ENTRY_MAGIC; - *nentryp = nentry; - return (ISC_R_SUCCESS); - -cleanup: - isc_mem_put(mctx, nentry, sizeof(dns_catz_entry_t)); - return (result); -} - -dns_name_t * -dns_catz_entry_getname(dns_catz_entry_t *entry) { - REQUIRE(DNS_CATZ_ENTRY_VALID(entry)); - return (&entry->name); -} - -isc_result_t -dns_catz_entry_copy(dns_catz_zone_t *zone, const dns_catz_entry_t *entry, - dns_catz_entry_t **nentryp) -{ - isc_result_t result; - dns_catz_entry_t *nentry = NULL; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(DNS_CATZ_ENTRY_VALID(entry)); - REQUIRE(nentryp != NULL && *nentryp == NULL); - - result = dns_catz_entry_new(zone->catzs->mctx, &entry->name, &nentry); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_catz_options_copy(zone->catzs->mctx, &entry->opts, - &nentry->opts); - if (result != ISC_R_SUCCESS) - dns_catz_entry_detach(zone, &nentry); - - *nentryp = nentry; - return (result); -} - -void -dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp) { - REQUIRE(DNS_CATZ_ENTRY_VALID(entry)); - REQUIRE(entryp != NULL && *entryp == NULL); - - isc_refcount_increment(&entry->refs, NULL); - *entryp = entry; -} - -void -dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp) { - dns_catz_entry_t *entry; - isc_mem_t *mctx; - unsigned int refs; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(entryp != NULL && *entryp != NULL); - entry = *entryp; - REQUIRE(DNS_CATZ_ENTRY_VALID(entry)); - - *entryp = NULL; - - mctx = zone->catzs->mctx; - - isc_refcount_decrement(&entry->refs, &refs); - if (refs == 0) { - dns_catz_options_free(&entry->opts, mctx); - if (dns_name_dynamic(&entry->name)) - dns_name_free(&entry->name, mctx); - isc_refcount_destroy(&entry->refs); - isc_mem_put(mctx, entry, sizeof(dns_catz_entry_t)); - } -} - -bool -dns_catz_entry_validate(const dns_catz_entry_t *entry) { - REQUIRE(DNS_CATZ_ENTRY_VALID(entry)); - UNUSED(entry); - - return (true); -} - -bool -dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb) { - isc_region_t ra, rb; - - REQUIRE(DNS_CATZ_ENTRY_VALID(ea)); - REQUIRE(DNS_CATZ_ENTRY_VALID(eb)); - - if (ea == eb) - return (true); - - if (ea->opts.masters.count != eb->opts.masters.count) - return (false); - - if (memcmp(ea->opts.masters.addrs, eb->opts.masters.addrs, - ea->opts.masters.count * sizeof(isc_sockaddr_t))) - return (false); - - /* If one is NULL and the other isn't, the entries don't match */ - if ((ea->opts.allow_query == NULL) != (eb->opts.allow_query == NULL)) - return (false); - - /* If one is non-NULL, then they both are */ - if (ea->opts.allow_query != NULL) { - isc_buffer_usedregion(ea->opts.allow_query, &ra); - isc_buffer_usedregion(eb->opts.allow_query, &rb); - if (isc_region_compare(&ra, &rb)) - return (false); - } - - /* Repeat the above checks with allow_transfer */ - if ((ea->opts.allow_transfer == NULL) != - (eb->opts.allow_transfer == NULL)) - return (false); - - if (ea->opts.allow_transfer != NULL) { - isc_buffer_usedregion(ea->opts.allow_transfer, &ra); - isc_buffer_usedregion(eb->opts.allow_transfer, &rb); - if (isc_region_compare(&ra, &rb)) - return (false); - } - - /* xxxwpk TODO compare dscps/keys! */ - return (true); -} - -dns_name_t * -dns_catz_zone_getname(dns_catz_zone_t *zone) { - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - - return (&zone->name); -} - -dns_catz_options_t * -dns_catz_zone_getdefoptions(dns_catz_zone_t *zone) { - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - - return (&zone->defoptions); -} - -void -dns_catz_zone_resetdefoptions(dns_catz_zone_t *zone) { - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - - dns_catz_options_free(&zone->defoptions, zone->catzs->mctx); - dns_catz_options_init(&zone->defoptions); -} - -isc_result_t -dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { - isc_result_t result; - isc_ht_iter_t *iter1 = NULL, *iter2 = NULL; - isc_ht_iter_t *iteradd = NULL, *itermod = NULL; - isc_ht_t *toadd = NULL, *tomod = NULL; - bool delcur = false; - char czname[DNS_NAME_FORMATSIZE]; - char zname[DNS_NAME_FORMATSIZE]; - dns_catz_zoneop_fn_t addzone, modzone, delzone; - - REQUIRE(DNS_CATZ_ZONE_VALID(newzone)); - REQUIRE(DNS_CATZ_ZONE_VALID(target)); - - /* TODO verify the new zone first! */ - - addzone = target->catzs->zmm->addzone; - modzone = target->catzs->zmm->modzone; - delzone = target->catzs->zmm->delzone; - - /* Copy zoneoptions from newzone into target. */ - - dns_catz_options_free(&target->zoneoptions, target->catzs->mctx); - dns_catz_options_copy(target->catzs->mctx, &newzone->zoneoptions, - &target->zoneoptions); - dns_catz_options_setdefault(target->catzs->mctx, &target->defoptions, - &target->zoneoptions); - - dns_name_format(&target->name, czname, DNS_NAME_FORMATSIZE); - - result = isc_ht_init(&toadd, target->catzs->mctx, 16); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_ht_init(&tomod, target->catzs->mctx, 16); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_ht_iter_create(newzone->entries, &iter1); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_ht_iter_create(target->entries, &iter2); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * We can create those iterators now, even though toadd and tomod are - * empty - */ - result = isc_ht_iter_create(toadd, &iteradd); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_ht_iter_create(tomod, &itermod); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * First - walk the new zone and find all nodes that are not in the - * old zone, or are in both zones and are modified. - */ - for (result = isc_ht_iter_first(iter1); - result == ISC_R_SUCCESS; - result = delcur ? isc_ht_iter_delcurrent_next(iter1) : - isc_ht_iter_next(iter1)) - { - dns_catz_entry_t *nentry = NULL; - dns_catz_entry_t *oentry = NULL; - unsigned char * key = NULL; - size_t keysize; - delcur = false; - - isc_ht_iter_current(iter1, (void **) &nentry); - isc_ht_iter_currentkey(iter1, &key, &keysize); - - /* - * Spurious record that came from suboption without main - * record, removed. - * xxxwpk: make it a separate verification phase? - */ - if (dns_name_countlabels(&nentry->name) == 0) { - dns_catz_entry_detach(newzone, &nentry); - delcur = true; - continue; - } - - dns_name_format(&nentry->name, zname, DNS_NAME_FORMATSIZE); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), - "catz: iterating over '%s' from catalog '%s'", - zname, czname); - dns_catz_options_setdefault(target->catzs->mctx, - &target->zoneoptions, - &nentry->opts); - - result = isc_ht_find(target->entries, key, - (uint32_t)keysize, (void **) &oentry); - if (result != ISC_R_SUCCESS) { - result = isc_ht_add(toadd, key, (uint32_t)keysize, - nentry); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, - ISC_LOG_ERROR, - "catz: error adding zone '%s' " - "from catalog '%s' - %s", - zname, czname, - isc_result_totext(result)); - continue; - } - - if (dns_catz_entry_cmp(oentry, nentry) != true) { - result = isc_ht_add(tomod, key, (uint32_t)keysize, - nentry); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, - ISC_LOG_ERROR, - "catz: error modifying zone '%s' " - "from catalog '%s' - %s", - zname, czname, - isc_result_totext(result)); - } - dns_catz_entry_detach(target, &oentry); - result = isc_ht_delete(target->entries, key, - (uint32_t)keysize); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - RUNTIME_CHECK(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter1); - - /* - * Then - walk the old zone; only deleted entries should remain. - */ - for (result = isc_ht_iter_first(iter2); - result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(iter2)) - { - dns_catz_entry_t *entry = NULL; - isc_ht_iter_current(iter2, (void **) &entry); - - dns_name_format(&entry->name, zname, DNS_NAME_FORMATSIZE); - result = delzone(entry, target, target->catzs->view, - target->catzs->taskmgr, - target->catzs->zmm->udata); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "catz: deleting zone '%s' from catalog '%s' - %s", - zname, czname, isc_result_totext(result)); - dns_catz_entry_detach(target, &entry); - } - RUNTIME_CHECK(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter2); - /* At this moment target->entries has to be be empty. */ - INSIST(isc_ht_count(target->entries) == 0); - isc_ht_destroy(&target->entries); - - for (result = isc_ht_iter_first(iteradd); - result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(iteradd)) - { - dns_catz_entry_t *entry = NULL; - isc_ht_iter_current(iteradd, (void **) &entry); - - dns_name_format(&entry->name, zname, DNS_NAME_FORMATSIZE); - result = addzone(entry, target, target->catzs->view, - target->catzs->taskmgr, - target->catzs->zmm->udata); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "catz: adding zone '%s' from catalog " - "'%s' - %s", - zname, czname, - isc_result_totext(result)); - } - - for (result = isc_ht_iter_first(itermod); - result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(itermod)) - { - dns_catz_entry_t *entry = NULL; - isc_ht_iter_current(itermod, (void **) &entry); - - dns_name_format(&entry->name, zname, DNS_NAME_FORMATSIZE); - result = modzone(entry, target, target->catzs->view, - target->catzs->taskmgr, - target->catzs->zmm->udata); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "catz: modifying zone '%s' from catalog " - "'%s' - %s", - zname, czname, - isc_result_totext(result)); - } - - target->entries = newzone->entries; - newzone->entries = NULL; - - result = ISC_R_SUCCESS; - -cleanup: - if (iter1 != NULL) - isc_ht_iter_destroy(&iter1); - if (iter2 != NULL) - isc_ht_iter_destroy(&iter2); - if (iteradd != NULL) - isc_ht_iter_destroy(&iteradd); - if (itermod != NULL) - isc_ht_iter_destroy(&itermod); - if (toadd != NULL) - isc_ht_destroy(&toadd); - if (tomod != NULL) - isc_ht_destroy(&tomod); - return (result); -} - -isc_result_t -dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm, - isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr) -{ - dns_catz_zones_t *new_zones; - isc_result_t result; - - REQUIRE(catzsp != NULL && *catzsp == NULL); - REQUIRE(zmm != NULL); - - new_zones = isc_mem_get(mctx, sizeof(*new_zones)); - if (new_zones == NULL) - return (ISC_R_NOMEMORY); - memset(new_zones, 0, sizeof(*new_zones)); - - result = isc_mutex_init(&new_zones->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_newzones; - - result = isc_refcount_init(&new_zones->refs, 1); - if (result != ISC_R_SUCCESS) - goto cleanup_mutex; - - result = isc_ht_init(&new_zones->zones, mctx, 4); - if (result != ISC_R_SUCCESS) - goto cleanup_refcount; - - isc_mem_attach(mctx, &new_zones->mctx); - new_zones->zmm = zmm; - new_zones->timermgr = timermgr; - new_zones->taskmgr = taskmgr; - - result = isc_task_create(taskmgr, 0, &new_zones->updater); - if (result != ISC_R_SUCCESS) - goto cleanup_ht; - new_zones->magic = DNS_CATZ_ZONES_MAGIC; - - *catzsp = new_zones; - return (ISC_R_SUCCESS); - - cleanup_ht: - isc_ht_destroy(&new_zones->zones); - cleanup_refcount: - isc_refcount_destroy(&new_zones->refs); - cleanup_mutex: - isc_mutex_destroy(&new_zones->lock); - cleanup_newzones: - isc_mem_put(mctx, new_zones, sizeof(*new_zones)); - - return (result); -} - -void -dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view) { - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(view != NULL); - /* Either it's a new one or it's being reconfigured. */ - REQUIRE(catzs->view == NULL || !strcmp(catzs->view->name, view->name)); - - catzs->view = view; -} - -isc_result_t -dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep, - const dns_name_t *name) -{ - isc_result_t result; - dns_catz_zone_t *new_zone; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(zonep != NULL && *zonep == NULL); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - - new_zone = isc_mem_get(catzs->mctx, sizeof(*new_zone)); - if (new_zone == NULL) - return (ISC_R_NOMEMORY); - - memset(new_zone, 0, sizeof(*new_zone)); - - dns_name_init(&new_zone->name, NULL); - - result = dns_name_dup(name, catzs->mctx, &new_zone->name); - if (result != ISC_R_SUCCESS) - goto cleanup_newzone; - - result = isc_ht_init(&new_zone->entries, catzs->mctx, 4); - if (result != ISC_R_SUCCESS) - goto cleanup_name; - - new_zone->updatetimer = NULL; - result = isc_timer_create(catzs->timermgr, isc_timertype_inactive, - NULL, NULL, catzs->updater, - dns_catz_update_taskaction, - new_zone, &new_zone->updatetimer); - if (result != ISC_R_SUCCESS) - goto cleanup_ht; - - isc_time_settoepoch(&new_zone->lastupdated); - new_zone->updatepending = false; - new_zone->db = NULL; - new_zone->dbversion = NULL; - new_zone->catzs = catzs; - dns_catz_options_init(&new_zone->defoptions); - dns_catz_options_init(&new_zone->zoneoptions); - new_zone->active = true; - new_zone->db_registered = false; - new_zone->version = (uint32_t)(-1); - isc_refcount_init(&new_zone->refs, 1); - new_zone->magic = DNS_CATZ_ZONE_MAGIC; - - *zonep = new_zone; - - return (ISC_R_SUCCESS); - - cleanup_ht: - isc_ht_destroy(&new_zone->entries); - cleanup_name: - dns_name_free(&new_zone->name, catzs->mctx); - cleanup_newzone: - isc_mem_put(catzs->mctx, new_zone, sizeof(*new_zone)); - - return (result); -} - -isc_result_t -dns_catz_add_zone(dns_catz_zones_t *catzs, const dns_name_t *name, - dns_catz_zone_t **zonep) -{ - dns_catz_zone_t *new_zone = NULL; - isc_result_t result, tresult; - char zname[DNS_NAME_FORMATSIZE]; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - REQUIRE(zonep != NULL && *zonep == NULL); - - dns_name_format(name, zname, DNS_NAME_FORMATSIZE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), - "catz: dns_catz_add_zone %s", zname); - - LOCK(&catzs->lock); - - result = dns_catz_new_zone(catzs, &new_zone, name); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_ht_add(catzs->zones, new_zone->name.ndata, - new_zone->name.length, new_zone); - if (result != ISC_R_SUCCESS) { - dns_catz_zone_detach(&new_zone); - if (result != ISC_R_EXISTS) - goto cleanup; - } - - if (result == ISC_R_EXISTS) { - tresult = isc_ht_find(catzs->zones, name->ndata, - name->length, (void **) &new_zone); - INSIST(tresult == ISC_R_SUCCESS && !new_zone->active); - new_zone->active = true; - } - - *zonep = new_zone; - - cleanup: - UNLOCK(&catzs->lock); - - return (result); -} - -dns_catz_zone_t * -dns_catz_get_zone(dns_catz_zones_t *catzs, const dns_name_t *name) { - isc_result_t result; - dns_catz_zone_t *found = NULL; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - - result = isc_ht_find(catzs->zones, name->ndata, name->length, - (void **) &found); - if (result != ISC_R_SUCCESS) - return (NULL); - - return (found); -} - -void -dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp) { - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(catzsp != NULL && *catzsp == NULL); - - isc_refcount_increment(&catzs->refs, NULL); - *catzsp = catzs; -} - -void -dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep) { - REQUIRE(zonep != NULL && *zonep == NULL); - - isc_refcount_increment(&zone->refs, NULL); - *zonep = zone; -} - -void -dns_catz_zone_detach(dns_catz_zone_t **zonep) { - isc_result_t result; - dns_catz_zone_t *zone; - isc_ht_iter_t *iter = NULL; - unsigned int refs; - - REQUIRE(zonep != NULL && *zonep != NULL); - - zone = *zonep; - *zonep = NULL; - isc_refcount_decrement(&zone->refs, &refs); - if (refs == 0) { - isc_mem_t *mctx = zone->catzs->mctx; - if (zone->entries != NULL) { - result = isc_ht_iter_create(zone->entries, &iter); - INSIST(result == ISC_R_SUCCESS); - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(iter)) - { - dns_catz_entry_t *entry = NULL; - - isc_ht_iter_current(iter, (void **) &entry); - dns_catz_entry_detach(zone, &entry); - } - INSIST(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); - - /* The hashtable has to be empty now. */ - INSIST(isc_ht_count(zone->entries) == 0); - isc_ht_destroy(&zone->entries); - } - zone->magic = 0; - isc_timer_detach(&zone->updatetimer); - isc_refcount_destroy(&zone->refs); - if (zone->db_registered == true) { - result = dns_db_updatenotify_unregister(zone->db, - dns_catz_dbupdate_callback, - zone->catzs); - INSIST(result == ISC_R_SUCCESS); - } - if (zone->dbversion) - dns_db_closeversion(zone->db, &zone->dbversion, - false); - if (zone->db != NULL) - dns_db_detach(&zone->db); - - dns_name_free(&zone->name, mctx); - dns_catz_options_free(&zone->defoptions, mctx); - dns_catz_options_free(&zone->zoneoptions, mctx); - - zone->catzs = NULL; - isc_mem_put(mctx, zone, sizeof(dns_catz_zone_t)); - } -} - -void -dns_catz_catzs_detach(dns_catz_zones_t **catzsp) { - dns_catz_zones_t *catzs; - isc_ht_iter_t *iter = NULL; - isc_result_t result; - unsigned int refs; - - REQUIRE(catzsp != NULL); - catzs = *catzsp; - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - - *catzsp = NULL; - isc_refcount_decrement(&catzs->refs, &refs); - - if (refs == 0) { - catzs->magic = 0; - DESTROYLOCK(&catzs->lock); - if (catzs->zones != NULL) { - result = isc_ht_iter_create(catzs->zones, &iter); - INSIST(result == ISC_R_SUCCESS); - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS;) - { - dns_catz_zone_t *zone = NULL; - isc_ht_iter_current(iter, (void **) &zone); - result = isc_ht_iter_delcurrent_next(iter); - dns_catz_zone_detach(&zone); - } - INSIST(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); - INSIST(isc_ht_count(catzs->zones) == 0); - isc_ht_destroy(&catzs->zones); - } - isc_refcount_destroy(&catzs->refs); - isc_task_destroy(&catzs->updater); - isc_mem_putanddetach(&catzs->mctx, catzs, sizeof(*catzs)); - } -} - -typedef enum { - CATZ_OPT_NONE, - CATZ_OPT_ZONES, - CATZ_OPT_MASTERS, - CATZ_OPT_ALLOW_QUERY, - CATZ_OPT_ALLOW_TRANSFER, - CATZ_OPT_VERSION, -} catz_opt_t; - -static bool -catz_opt_cmp(const dns_label_t *option, const char *opt) { - unsigned int l = strlen(opt); - if (option->length - 1 == l && - memcmp(opt, option->base + 1, l - 1) == 0) - return (true); - else - return (false); -} - -static catz_opt_t -catz_get_option(const dns_label_t *option) { - if (catz_opt_cmp(option, "zones")) - return (CATZ_OPT_ZONES); - else if (catz_opt_cmp(option, "masters")) - return (CATZ_OPT_MASTERS); - else if (catz_opt_cmp(option, "allow-query")) - return (CATZ_OPT_ALLOW_QUERY); - else if (catz_opt_cmp(option, "allow-transfer")) - return (CATZ_OPT_ALLOW_TRANSFER); - else if (catz_opt_cmp(option, "version")) - return (CATZ_OPT_VERSION); - else - return (CATZ_OPT_NONE); -} - -static isc_result_t -catz_process_zones(dns_catz_zone_t *zone, dns_rdataset_t *value, - dns_name_t *name) -{ - dns_label_t mhash; - dns_name_t opt; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(DNS_RDATASET_VALID(value)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - - if (value->rdclass != dns_rdataclass_in) - return (ISC_R_FAILURE); - - if (name->labels == 0) - return (ISC_R_FAILURE); - - dns_name_getlabel(name, name->labels-1, &mhash); - - if (name->labels == 1) - return (catz_process_zones_entry(zone, value, &mhash)); - else { - dns_name_init(&opt, NULL); - dns_name_split(name, 1, &opt, NULL); - return (catz_process_zones_suboption(zone, value, &mhash, &opt)); - } -} - -static isc_result_t -catz_process_zones_entry(dns_catz_zone_t *zone, dns_rdataset_t *value, - dns_label_t *mhash) -{ - isc_result_t result; - dns_rdata_t rdata; - dns_rdata_ptr_t ptr; - dns_catz_entry_t *entry = NULL; - - /* - * We only take -first- value, as mhash must be - * different. - */ - if (value->type != dns_rdatatype_ptr) - return (ISC_R_FAILURE); - - result = dns_rdataset_first(value); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); - - result = dns_rdata_tostruct(&rdata, &ptr, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = isc_ht_find(zone->entries, mhash->base, - mhash->length, (void **) &entry); - if (result == ISC_R_SUCCESS) { - if (dns_name_countlabels(&entry->name) != 0) { - /* We have a duplicate. */ - dns_rdata_freestruct(&ptr); - return (ISC_R_FAILURE); - } else { - result = dns_name_dup(&ptr.ptr, zone->catzs->mctx, - &entry->name); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ptr); - return (result); - } - } - } else { - result = dns_catz_entry_new(zone->catzs->mctx, &ptr.ptr, - &entry); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ptr); - return (result); - } - - result = isc_ht_add(zone->entries, mhash->base, - mhash->length, entry); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ptr); - dns_catz_entry_detach(zone, &entry); - return (result); - } - } - - dns_rdata_freestruct(&ptr); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -catz_process_version(dns_catz_zone_t *zone, dns_rdataset_t *value) { - isc_result_t result; - dns_rdata_t rdata; - dns_rdata_txt_t rdatatxt; - dns_rdata_txt_string_t rdatastr; - uint32_t tversion; - char t[16]; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(DNS_RDATASET_VALID(value)); - - if (value->rdclass != dns_rdataclass_in || - value->type != dns_rdatatype_txt) - return (ISC_R_FAILURE); - - result = dns_rdataset_first(value); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); - - result = dns_rdata_tostruct(&rdata, &rdatatxt, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_rdata_txt_first(&rdatatxt); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rdata_txt_current(&rdatatxt, &rdatastr); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rdata_txt_next(&rdatatxt); - if (result != ISC_R_NOMORE) { - result = ISC_R_FAILURE; - goto cleanup; - } - if (rdatastr.length > 15) { - result = ISC_R_BADNUMBER; - goto cleanup; - } - memmove(t, rdatastr.data, rdatastr.length); - t[rdatastr.length] = 0; - result = isc_parse_uint32(&tversion, t, 10); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - zone->version = tversion; - result = ISC_R_SUCCESS; - -cleanup: - dns_rdata_freestruct(&rdatatxt); - return (result); -} - -static isc_result_t -catz_process_masters(dns_catz_zone_t *zone, dns_ipkeylist_t *ipkl, - dns_rdataset_t *value, dns_name_t *name) -{ - isc_result_t result; - dns_rdata_t rdata; - dns_rdata_in_a_t rdata_a; - dns_rdata_in_aaaa_t rdata_aaaa; - dns_rdata_txt_t rdata_txt; - dns_rdata_txt_string_t rdatastr; - dns_name_t *keyname = NULL; - isc_mem_t *mctx; - char keycbuf[DNS_NAME_FORMATSIZE]; - isc_buffer_t keybuf; - unsigned int rcount; - unsigned int i; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(ipkl != NULL); - REQUIRE(DNS_RDATASET_VALID(value)); - REQUIRE(dns_rdataset_isassociated(value)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - - mctx = zone->catzs->mctx; - memset(&rdata_a, 0, sizeof(rdata_a)); - memset(&rdata_aaaa, 0, sizeof(rdata_aaaa)); - memset(&rdata_txt, 0, sizeof(rdata_txt)); - isc_buffer_init(&keybuf, keycbuf, sizeof(keycbuf)); - - /* - * We have three possibilities here: - * - either empty name and IN A/IN AAAA record - * - label and IN A/IN AAAA - * - label and IN TXT - TSIG key name - */ - if (value->rdclass != dns_rdataclass_in) - return (ISC_R_FAILURE); - - if (name->labels > 0) { - isc_sockaddr_t sockaddr; - - /* - * We're pre-preparing the data once, we'll put it into - * the right spot in the masters array once we find it. - */ - result = dns_rdataset_first(value); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); - switch (value->type) { - case dns_rdatatype_a: - result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin(&sockaddr, &rdata_a.in_addr, 0); - break; - case dns_rdatatype_aaaa: - result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin6(&sockaddr, &rdata_aaaa.in6_addr, 0); - break; - case dns_rdatatype_txt: - result = dns_rdata_tostruct(&rdata, &rdata_txt, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_rdata_txt_first(&rdata_txt); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_rdata_txt_current(&rdata_txt, &rdatastr); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_rdata_txt_next(&rdata_txt); - if (result != ISC_R_NOMORE) - return (ISC_R_FAILURE); - - /* rdatastr.length < DNS_NAME_MAXTEXT */ - keyname = isc_mem_get(mctx, sizeof(dns_name_t)); - if (keyname == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(keyname, 0); - memmove(keycbuf, rdatastr.data, rdatastr.length); - keycbuf[rdatastr.length] = 0; - result = dns_name_fromstring(keyname, keycbuf, 0, mctx); - if (result != ISC_R_SUCCESS) { - dns_name_free(keyname, mctx); - isc_mem_put(mctx, keyname, sizeof(dns_name_t)); - return (result); - } - break; - default: - return (ISC_R_FAILURE); - } - - /* - * We have to find the appropriate labeled record in masters - * if it exists. - * In common case we'll have no more than 3-4 records here so - * no optimization. - */ - for (i = 0; i < ipkl->count; i++) { - if (ipkl->labels[i] != NULL && - !dns_name_compare(name, ipkl->labels[i])) - break; - } - - if (i < ipkl->count) { /* we have this record already */ - if (value->type == dns_rdatatype_txt) - ipkl->keys[i] = keyname; - else /* A/AAAA */ - memmove(&ipkl->addrs[i], &sockaddr, - sizeof(isc_sockaddr_t)); - } else { - result = dns_ipkeylist_resize(mctx, ipkl, - i+1); - if (result != ISC_R_SUCCESS) { - return (result); - } - - ipkl->labels[i] = isc_mem_get(mctx, sizeof(dns_name_t)); - if (ipkl->labels[i] == NULL) { - if (keyname != NULL) { - dns_name_free(keyname, mctx); - isc_mem_put(mctx, keyname, - sizeof(dns_name_t)); - } - return (ISC_R_NOMEMORY); - } - dns_name_init(ipkl->labels[i], NULL); - result = dns_name_dup(name, mctx, ipkl->labels[i]); - if (result != ISC_R_SUCCESS) { - if (keyname != NULL) { - dns_name_free(keyname, mctx); - isc_mem_put(mctx, keyname, - sizeof(dns_name_t)); - } - return (result); - } - - if (value->type == dns_rdatatype_txt) - ipkl->keys[i] = keyname; - else /* A/AAAA */ - memmove(&ipkl->addrs[i], &sockaddr, - sizeof(isc_sockaddr_t)); - ipkl->count++; - } - return (ISC_R_SUCCESS); - } - /* else - 'simple' case - without labels */ - - if (value->type != dns_rdatatype_a && - value->type != dns_rdatatype_aaaa) - return (ISC_R_FAILURE); - - rcount = dns_rdataset_count(value) + ipkl->count; - - result = dns_ipkeylist_resize(mctx, ipkl, rcount); - if (result != ISC_R_SUCCESS) { - return (result); - } - - for (result = dns_rdataset_first(value); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(value)) - { - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); - /* - * port 0 == take the default - */ - if (value->type == dns_rdatatype_a) { - result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin(&ipkl->addrs[ipkl->count], - &rdata_a.in_addr, 0); - } else { - result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin6(&ipkl->addrs[ipkl->count], - &rdata_aaaa.in6_addr, 0); - } - ipkl->keys[ipkl->count] = NULL; - ipkl->labels[ipkl->count] = NULL; - ipkl->count++; - dns_rdata_freestruct(&rdata_a); - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -catz_process_apl(dns_catz_zone_t *zone, isc_buffer_t **aclbp, - dns_rdataset_t *value) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_rdata_t rdata; - dns_rdata_in_apl_t rdata_apl; - dns_rdata_apl_ent_t apl_ent; - isc_netaddr_t addr; - isc_buffer_t *aclb = NULL; - unsigned char buf[256]; /* larger than INET6_ADDRSTRLEN */ - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(aclbp != NULL); - REQUIRE(*aclbp == NULL); - REQUIRE(DNS_RDATASET_VALID(value)); - REQUIRE(dns_rdataset_isassociated(value)); - - if (value->rdclass != dns_rdataclass_in || - value->type != dns_rdatatype_apl) - return (ISC_R_FAILURE); - - - if (dns_rdataset_count(value) > 1) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_WARNING, - "catz: more than one APL entry for member zone, " - "result is undefined"); - } - result = dns_rdataset_first(value); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); - result = dns_rdata_tostruct(&rdata, &rdata_apl, zone->catzs->mctx); - if (result != ISC_R_SUCCESS) - return (result); - result = isc_buffer_allocate(zone->catzs->mctx, &aclb, 16); - isc_buffer_setautorealloc(aclb, true); - if (result != ISC_R_SUCCESS) - goto cleanup; - for (result = dns_rdata_apl_first(&rdata_apl); - result == ISC_R_SUCCESS; - result = dns_rdata_apl_next(&rdata_apl)) { - result = dns_rdata_apl_current(&rdata_apl, &apl_ent); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - memset(buf, 0, sizeof(buf)); - if (apl_ent.data != NULL && apl_ent.length > 0) - memmove(buf, apl_ent.data, apl_ent.length); - if (apl_ent.family == 1) - isc_netaddr_fromin(&addr, (struct in_addr*) buf); - else if (apl_ent.family == 2) - isc_netaddr_fromin6(&addr, (struct in6_addr*) buf); - else - continue; /* xxxwpk log it or simply ignore? */ - if (apl_ent.negative) - isc_buffer_putuint8(aclb, '!'); - isc_buffer_reserve(&aclb, INET6_ADDRSTRLEN); - result = isc_netaddr_totext(&addr, aclb); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if ((apl_ent.family == 1 && apl_ent.prefix < 32) || - (apl_ent.family == 2 && apl_ent.prefix < 128)) { - isc_buffer_putuint8(aclb, '/'); - isc_buffer_putdecint(aclb, apl_ent.prefix); - } - isc_buffer_putstr(aclb, "; "); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - else - goto cleanup; - *aclbp = aclb; - aclb = NULL; -cleanup: - if (aclb != NULL) - isc_buffer_free(&aclb); - dns_rdata_freestruct(&rdata_apl); - return (result); -} - -static isc_result_t -catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value, - dns_label_t *mhash, dns_name_t *name) -{ - isc_result_t result; - dns_catz_entry_t *entry = NULL; - dns_label_t option; - dns_name_t prefix; - catz_opt_t opt; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(mhash != NULL); - REQUIRE(DNS_RDATASET_VALID(value)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - - if (name->labels == 0) - return (ISC_R_FAILURE); - dns_name_getlabel(name, name->labels - 1, &option); - opt = catz_get_option(&option); - - /* - * We're adding this entry now, in case the option is invalid we'll get - * rid of it in verification phase. - */ - result = isc_ht_find(zone->entries, mhash->base, mhash->length, - (void **) &entry); - if (result != ISC_R_SUCCESS) { - result = dns_catz_entry_new(zone->catzs->mctx, NULL, &entry); - if (result != ISC_R_SUCCESS) - return (result); - result = isc_ht_add(zone->entries, mhash->base, mhash->length, - entry); - if (result != ISC_R_SUCCESS) { - dns_catz_entry_detach(zone, &entry); - return (result); - } - } - - dns_name_init(&prefix, NULL); - dns_name_split(name, 1, &prefix, NULL); - switch (opt) { - case CATZ_OPT_MASTERS: - return (catz_process_masters(zone, &entry->opts.masters, value, - &prefix)); - case CATZ_OPT_ALLOW_QUERY: - if (prefix.labels != 0) - return (ISC_R_FAILURE); - return (catz_process_apl(zone, &entry->opts.allow_query, - value)); - case CATZ_OPT_ALLOW_TRANSFER: - if (prefix.labels != 0) - return (ISC_R_FAILURE); - return (catz_process_apl(zone, &entry->opts.allow_transfer, - value)); - default: - return (ISC_R_FAILURE); - } - - return (ISC_R_FAILURE); -} - -static isc_result_t -catz_process_value(dns_catz_zone_t *zone, dns_name_t *name, - dns_rdataset_t *rdataset) -{ - dns_label_t option; - dns_name_t prefix; - catz_opt_t opt; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC)); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - - dns_name_getlabel(name, name->labels - 1, &option); - opt = catz_get_option(&option); - dns_name_init(&prefix, NULL); - dns_name_split(name, 1, &prefix, NULL); - switch (opt) { - case CATZ_OPT_ZONES: - return (catz_process_zones(zone, rdataset, &prefix)); - case CATZ_OPT_MASTERS: - return (catz_process_masters(zone, &zone->zoneoptions.masters, - rdataset, &prefix)); - case CATZ_OPT_ALLOW_QUERY: - if (prefix.labels != 0) - return (ISC_R_FAILURE); - return (catz_process_apl(zone, &zone->zoneoptions.allow_query, - rdataset)); - case CATZ_OPT_ALLOW_TRANSFER: - if (prefix.labels != 0) - return (ISC_R_FAILURE); - return (catz_process_apl(zone, - &zone->zoneoptions.allow_transfer, - rdataset)); - case CATZ_OPT_VERSION: - if (prefix.labels != 0) - return (ISC_R_FAILURE); - return (catz_process_version(zone, rdataset)); - default: - return (ISC_R_FAILURE); - } -} - -isc_result_t -dns_catz_update_process(dns_catz_zones_t *catzs, dns_catz_zone_t *zone, - dns_name_t *src_name, dns_rdataset_t *rdataset) -{ - isc_result_t result; - int order; - unsigned int nlabels; - dns_namereln_t nrres; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - dns_name_t prefix; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(ISC_MAGIC_VALID(src_name, DNS_NAME_MAGIC)); - - nrres = dns_name_fullcompare(src_name, &zone->name, &order, &nlabels); - if (nrres == dns_namereln_equal) { - if (rdataset->type == dns_rdatatype_soa) { - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * xxxwpk TODO do we want to save something from SOA? - */ - return (result); - - } else if (rdataset->type == dns_rdatatype_ns) { - return (ISC_R_SUCCESS); - } else { - return (ISC_R_UNEXPECTED); - } - } else if (nrres != dns_namereln_subdomain) { - return (ISC_R_UNEXPECTED); - } - - dns_name_init(&prefix, NULL); - dns_name_split(src_name, zone->name.labels, &prefix, NULL); - result = catz_process_value(zone, &prefix, rdataset); - - return (result); -} - -isc_result_t -dns_catz_generate_masterfilename(dns_catz_zone_t *zone, dns_catz_entry_t *entry, - isc_buffer_t **buffer) -{ - isc_buffer_t *tbuf = NULL; - isc_sha256_t sha256; - isc_region_t r; - isc_result_t result; - size_t rlen; - bool special = false; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(entry != NULL); - REQUIRE(buffer != NULL && *buffer != NULL); - - result = isc_buffer_allocate(zone->catzs->mctx, &tbuf, - strlen(zone->catzs->view->name) + - 2 * DNS_NAME_FORMATSIZE + 2); - if (result != ISC_R_SUCCESS) - return (result); - INSIST(tbuf != NULL); - - isc_buffer_putstr(tbuf, zone->catzs->view->name); - isc_buffer_putstr(tbuf, "_"); - result = dns_name_totext(&zone->name, true, tbuf); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - isc_buffer_putstr(tbuf, "_"); - result = dns_name_totext(&entry->name, true, tbuf); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - /* - * Search for slash and other special characters in the view and - * zone names. Add a null terminator so we can use strpbrk(), then - * remove it. - */ - isc_buffer_putuint8(tbuf, 0); - if (strpbrk(isc_buffer_base(tbuf), "\\/:") != NULL) { - special = true; - } - isc_buffer_subtract(tbuf, 1); - - /* __catz__.db */ - rlen = ISC_SHA256_DIGESTSTRINGLENGTH + 12; - - /* optionally prepend with / */ - if (entry->opts.zonedir != NULL) { - rlen += strlen(entry->opts.zonedir) + 1; - } - - result = isc_buffer_reserve(buffer, (unsigned int)rlen); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - if (entry->opts.zonedir != NULL) { - isc_buffer_putstr(*buffer, entry->opts.zonedir); - isc_buffer_putstr(*buffer, "/"); - } - - isc_buffer_usedregion(tbuf, &r); - isc_buffer_putstr(*buffer, "__catz__"); - if (special || tbuf->used > ISC_SHA256_DIGESTSTRINGLENGTH) { - isc_sha256_init(&sha256); - isc_sha256_update(&sha256, r.base, r.length); - /* we can do that because digest string < 2 * DNS_NAME */ - isc_sha256_end(&sha256, (char *) r.base); - isc_buffer_putstr(*buffer, (char *) r.base); - } else { - isc_buffer_copyregion(*buffer, &r); - } - - isc_buffer_putstr(*buffer, ".db"); - result = ISC_R_SUCCESS; - -cleanup: - isc_buffer_free(&tbuf); - return (result); -} - -isc_result_t -dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry, - isc_buffer_t **buf) -{ - /* - * We have to generate a text buffer with regular zone config: - * zone "foo.bar" { - * type slave; - * masters [ dscp X ] { ip1 port port1; ip2 port port2; }; - * } - */ - isc_buffer_t *buffer = NULL; - isc_region_t region; - isc_result_t result; - uint32_t i; - isc_netaddr_t netaddr; - char pbuf[sizeof("65535")]; /* used both for port number and DSCP */ - char zname[DNS_NAME_FORMATSIZE]; - - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - REQUIRE(entry != NULL); - REQUIRE(buf != NULL && *buf == NULL); - - /* - * The buffer will be reallocated if something won't fit, - * ISC_BUFFER_INCR seems like a good start. - */ - result = isc_buffer_allocate(zone->catzs->mctx, &buffer, - ISC_BUFFER_INCR); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - isc_buffer_setautorealloc(buffer, true); - isc_buffer_putstr(buffer, "zone \""); - dns_name_totext(&entry->name, true, buffer); - isc_buffer_putstr(buffer, "\" { type slave; masters"); - - /* - * DSCP value has no default, but when it is specified, it is identical - * for all masters and cannot be overridden for a specific master IP, so - * use the DSCP value set for the first master - */ - if (entry->opts.masters.count > 0 && - entry->opts.masters.dscps[0] >= 0) - { - isc_buffer_putstr(buffer, " dscp "); - snprintf(pbuf, sizeof(pbuf), "%hd", - entry->opts.masters.dscps[0]); - isc_buffer_putstr(buffer, pbuf); - } - - isc_buffer_putstr(buffer, " { "); - for (i = 0; i < entry->opts.masters.count; i++) { - /* - * Every master must have an IP address assigned. - */ - switch (entry->opts.masters.addrs[i].type.sa.sa_family) { - case AF_INET: - case AF_INET6: - break; - default: - dns_name_format(&entry->name, zname, - DNS_NAME_FORMATSIZE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: zone '%s' uses an invalid master " - "(no IP address assigned)", - zname); - result = ISC_R_FAILURE; - goto cleanup; - } - isc_netaddr_fromsockaddr(&netaddr, - &entry->opts.masters.addrs[i]); - isc_buffer_reserve(&buffer, INET6_ADDRSTRLEN); - result = isc_netaddr_totext(&netaddr, buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_buffer_putstr(buffer, " port "); - snprintf(pbuf, sizeof(pbuf), "%u", - isc_sockaddr_getport(&entry->opts.masters.addrs[i])); - isc_buffer_putstr(buffer, pbuf); - - if (entry->opts.masters.keys[i] != NULL) { - isc_buffer_putstr(buffer, " key "); - result = dns_name_totext(entry->opts.masters.keys[i], - true, buffer); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - } - isc_buffer_putstr(buffer, "; "); - } - isc_buffer_putstr(buffer, "}; "); - if (entry->opts.in_memory == false) { - isc_buffer_putstr(buffer, "file \""); - result = dns_catz_generate_masterfilename(zone, entry, &buffer); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - isc_buffer_putstr(buffer, "\"; "); - - } - if (entry->opts.allow_query != NULL) { - isc_buffer_putstr(buffer, "allow-query { "); - isc_buffer_usedregion(entry->opts.allow_query, ®ion); - isc_buffer_copyregion(buffer, ®ion); - isc_buffer_putstr(buffer, "}; "); - } - if (entry->opts.allow_transfer != NULL) { - isc_buffer_putstr(buffer, "allow-transfer { "); - isc_buffer_usedregion(entry->opts.allow_transfer, ®ion); - isc_buffer_copyregion(buffer, ®ion); - isc_buffer_putstr(buffer, "}; "); - } - - isc_buffer_putstr(buffer, "};"); - *buf = buffer; - - return (ISC_R_SUCCESS); - -cleanup: - if (buffer != NULL) { - isc_buffer_free(&buffer); - } - return (result); -} - -void -dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_catz_zone_t * zone; - (void) task; - - REQUIRE(event != NULL); - zone = event->ev_arg; - REQUIRE(DNS_CATZ_ZONE_VALID(zone)); - - LOCK(&zone->catzs->lock); - zone->updatepending = false; - dns_catz_update_from_db(zone->db, zone->catzs); - result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive, - NULL, NULL, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_event_free(&event); - result = isc_time_now(&zone->lastupdated); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - UNLOCK(&zone->catzs->lock); -} - -isc_result_t -dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) { - dns_catz_zones_t *catzs; - dns_catz_zone_t *zone = NULL; - isc_time_t now; - uint64_t tdiff; - isc_result_t result = ISC_R_SUCCESS; - isc_region_t r; - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(fn_arg != NULL); - catzs = (dns_catz_zones_t *) fn_arg; - - dns_name_toregion(&db->origin, &r); - - LOCK(&catzs->lock); - result = isc_ht_find(catzs->zones, r.base, r.length, (void **) &zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* New zone came as AXFR */ - if (zone->db != NULL && zone->db != db) { - if (zone->dbversion != NULL) - dns_db_closeversion(zone->db, &zone->dbversion, - false); - dns_db_detach(&zone->db); - /* - * We're not registering db update callback, it will be - * registered at the end of update_from_db - */ - zone->db_registered = false; - } - if (zone->db == NULL) - dns_db_attach(db, &zone->db); - - if (zone->updatepending == false) { - zone->updatepending = true; - isc_time_now(&now); - tdiff = isc_time_microdiff(&now, &zone->lastupdated)/1000000; - if (tdiff < zone->defoptions.min_update_interval) { - isc_interval_t interval; - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "catz: new zone version came too soon, " - "deferring update"); - isc_interval_set(&interval, - zone->defoptions.min_update_interval - - (unsigned int)tdiff, 0); - dns_db_currentversion(db, &zone->dbversion); - result = isc_timer_reset(zone->updatetimer, - isc_timertype_once, - NULL, &interval, true); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else { - isc_event_t *event; - - dns_db_currentversion(db, &zone->dbversion); - ISC_EVENT_INIT(&zone->updateevent, - sizeof(zone->updateevent), 0, NULL, - DNS_EVENT_CATZUPDATED, - dns_catz_update_taskaction, - zone, zone, NULL, NULL); - event = &zone->updateevent; - isc_task_send(catzs->updater, &event); - } - } else { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), - "catz: update already queued"); - if (zone->dbversion != NULL) - dns_db_closeversion(zone->db, &zone->dbversion, - false); - dns_db_currentversion(zone->db, &zone->dbversion); - } - - cleanup: - UNLOCK(&catzs->lock); - - return (result); -} - -void -dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { - dns_catz_zone_t *oldzone = NULL, *newzone = NULL; - isc_result_t result; - isc_region_t r; - dns_dbnode_t *node = NULL; - dns_dbiterator_t *it = NULL; - dns_fixedname_t fixname; - dns_name_t *name; - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdataset_t rdataset; - char bname[DNS_NAME_FORMATSIZE]; - isc_buffer_t ibname; - uint32_t vers; - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - - /* - * Create a new catz in the same context as current catz. - */ - dns_name_toregion(&db->origin, &r); - result = isc_ht_find(catzs->zones, r.base, r.length, (void **)&oldzone); - if (result != ISC_R_SUCCESS) { - /* This can happen if we remove the zone in the meantime. */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: zone '%s' not in config", - bname); - return; - } - - isc_buffer_init(&ibname, bname, DNS_NAME_FORMATSIZE); - result = dns_name_totext(&db->origin, true, &ibname); - INSIST(result == ISC_R_SUCCESS); - - result = dns_db_getsoaserial(db, oldzone->dbversion, &vers); - if (result != ISC_R_SUCCESS) { - /* A zone without SOA record?!? */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: zone '%s' has no SOA record (%s)", - bname, isc_result_totext(result)); - return; - } - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "catz: updating catalog zone '%s' with serial %d", - bname, vers); - - result = dns_catz_new_zone(catzs, &newzone, &db->origin); - if (result != ISC_R_SUCCESS) { - dns_db_closeversion(db, &oldzone->dbversion, false); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: failed to create new zone - %s", - isc_result_totext(result)); - return; - } - - result = dns_db_createiterator(db, DNS_DB_NONSEC3, &it); - if (result != ISC_R_SUCCESS) { - dns_catz_zone_detach(&newzone); - dns_db_closeversion(db, &oldzone->dbversion, false); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: failed to create DB iterator - %s", - isc_result_totext(result)); - return; - } - - name = dns_fixedname_initname(&fixname); - - /* - * Iterate over database to fill the new zone. - */ - result = dns_dbiterator_first(it); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: failed to get db iterator - %s", - isc_result_totext(result)); - } - - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(it, &node, name); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: failed to get db iterator - %s", - isc_result_totext(result)); - break; - } - - result = dns_db_allrdatasets(db, node, oldzone->dbversion, 0, - &rdsiter); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, - "catz: failed to fetch rrdatasets - %s", - isc_result_totext(result)); - dns_db_detachnode(db, &node); - break; - } - - dns_rdataset_init(&rdataset); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - result = dns_catz_update_process(catzs, newzone, name, - &rdataset); - if (result != ISC_R_SUCCESS) { - char cname[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(name, cname, - DNS_NAME_FORMATSIZE); - dns_rdataclass_format(rdataset.rdclass, - classbuf, - sizeof(classbuf)); - dns_rdatatype_format(rdataset.type, typebuf, - sizeof(typebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, - ISC_LOG_WARNING, - "catz: unknown record in catalog " - "zone - %s %s %s(%s) - ignoring", - cname, classbuf, typebuf, - isc_result_totext(result)); - } - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) { - break; - } - result = dns_rdatasetiter_next(rdsiter); - } - - dns_rdatasetiter_destroy(&rdsiter); - - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(it); - } - - dns_dbiterator_destroy(&it); - dns_db_closeversion(db, &oldzone->dbversion, false); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), - "catz: update_from_db: iteration finished"); - - /* - * Finally merge new zone into old zone. - */ - result = dns_catz_zones_merge(oldzone, newzone); - dns_catz_zone_detach(&newzone); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, - ISC_LOG_ERROR, - "catz: failed merging zones: %s", - isc_result_totext(result)); - - return; - } - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), - "catz: update_from_db: new zone merged"); - - /* - * When we're doing reconfig and setting a new catalog zone - * from an existing zone we won't have a chance to set up - * update callback in zone_startload or axfr_makedb, but we will - * call onupdate() artificially so we can register the callback here. - */ - if (oldzone->db_registered == false) { - result = dns_db_updatenotify_register(db, - dns_catz_dbupdate_callback, - oldzone->catzs); - if (result == ISC_R_SUCCESS) - oldzone->db_registered = true; - } -} - -void -dns_catz_prereconfig(dns_catz_zones_t *catzs) { - isc_result_t result; - isc_ht_iter_t *iter = NULL; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - - result = isc_ht_iter_create(catzs->zones, &iter); - INSIST(result == ISC_R_SUCCESS); - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; - result = isc_ht_iter_next(iter)) - { - dns_catz_zone_t *zone = NULL; - isc_ht_iter_current(iter, (void **) &zone); - zone->active = false; - } - INSIST(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); -} - -void -dns_catz_postreconfig(dns_catz_zones_t *catzs) { - isc_result_t result; - dns_catz_zone_t *newzone = NULL; - isc_ht_iter_t *iter = NULL; - - REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); - - LOCK(&catzs->lock); - result = isc_ht_iter_create(catzs->zones, &iter); - INSIST(result == ISC_R_SUCCESS); - for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS;) - { - dns_catz_zone_t *zone = NULL; - - isc_ht_iter_current(iter, (void **) &zone); - if (zone->active == false) { - char cname[DNS_NAME_FORMATSIZE]; - dns_name_format(&zone->name, cname, - DNS_NAME_FORMATSIZE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, - ISC_LOG_WARNING, - "catz: removing catalog zone %s", cname); - - /* - * Merge the old zone with an empty one to remove - * all members. - */ - result = dns_catz_new_zone(catzs, &newzone, - &zone->name); - INSIST(result == ISC_R_SUCCESS); - dns_catz_zones_merge(zone, newzone); - dns_catz_zone_detach(&newzone); - - /* Make sure that we have an empty catalog zone. */ - INSIST(isc_ht_count(zone->entries) == 0); - result = isc_ht_iter_delcurrent_next(iter); - dns_catz_zone_detach(&zone); - } else { - result = isc_ht_iter_next(iter); - } - } - UNLOCK(&catzs->lock); - RUNTIME_CHECK(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); -} - -isc_result_t -dns_catz_get_iterator(dns_catz_zone_t *catz, isc_ht_iter_t **itp) { - REQUIRE(DNS_CATZ_ZONE_VALID(catz)); - return (isc_ht_iter_create(catz->entries, itp)); -} diff --git a/lib/dns-pkcs11/client.c b/lib/dns-pkcs11/client.c deleted file mode 100644 index c2dca94..0000000 --- a/lib/dns-pkcs11/client.c +++ /dev/null @@ -1,3277 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DNS_CLIENT_MAGIC ISC_MAGIC('D', 'N', 'S', 'c') -#define DNS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, DNS_CLIENT_MAGIC) - -#define RCTX_MAGIC ISC_MAGIC('R', 'c', 't', 'x') -#define RCTX_VALID(c) ISC_MAGIC_VALID(c, RCTX_MAGIC) - -#define REQCTX_MAGIC ISC_MAGIC('R', 'q', 'c', 'x') -#define REQCTX_VALID(c) ISC_MAGIC_VALID(c, REQCTX_MAGIC) - -#define UCTX_MAGIC ISC_MAGIC('U', 'c', 't', 'x') -#define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC) - -#define MAX_RESTARTS 16 - -#ifdef TUNE_LARGE -#define RESOLVER_NTASKS 523 -#else -#define RESOLVER_NTASKS 31 -#endif /* TUNE_LARGE */ - -/*% - * DNS client object - */ -struct dns_client { - /* Unlocked */ - unsigned int magic; - unsigned int attributes; - isc_mutex_t lock; - isc_mem_t *mctx; - isc_appctx_t *actx; - isc_taskmgr_t *taskmgr; - isc_task_t *task; - isc_socketmgr_t *socketmgr; - isc_timermgr_t *timermgr; - dns_dispatchmgr_t *dispatchmgr; - dns_dispatch_t *dispatchv4; - dns_dispatch_t *dispatchv6; - - unsigned int update_timeout; - unsigned int update_udptimeout; - unsigned int update_udpretries; - unsigned int find_timeout; - unsigned int find_udpretries; - - isc_refcount_t references; - - /* Locked */ - dns_viewlist_t viewlist; - ISC_LIST(struct resctx) resctxs; - ISC_LIST(struct reqctx) reqctxs; - ISC_LIST(struct updatectx) updatectxs; -}; - -/*% - * Timeout/retry constants for dynamic update borrowed from nsupdate - */ -#define DEF_UPDATE_TIMEOUT 300 -#define MIN_UPDATE_TIMEOUT 30 -#define DEF_UPDATE_UDPTIMEOUT 3 -#define DEF_UPDATE_UDPRETRIES 3 - -#define DEF_FIND_TIMEOUT 5 -#define DEF_FIND_UDPRETRIES 3 - -#define DNS_CLIENTATTR_OWNCTX 0x01 - -#define DNS_CLIENTVIEW_NAME "dnsclient" - -/*% - * Internal state for a single name resolution procedure - */ -typedef struct resctx { - /* Unlocked */ - unsigned int magic; - isc_mutex_t lock; - dns_client_t *client; - bool want_dnssec; - bool want_validation; - bool want_cdflag; - bool want_tcp; - - /* Locked */ - ISC_LINK(struct resctx) link; - isc_task_t *task; - dns_view_t *view; - unsigned int restarts; - dns_fixedname_t name; - dns_rdatatype_t type; - dns_fetch_t *fetch; - dns_namelist_t namelist; - isc_result_t result; - dns_clientresevent_t *event; - bool canceled; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; -} resctx_t; - -/*% - * Argument of an internal event for synchronous name resolution. - */ -typedef struct resarg { - /* Unlocked */ - isc_appctx_t *actx; - dns_client_t *client; - isc_mutex_t lock; - - /* Locked */ - isc_result_t result; - isc_result_t vresult; - dns_namelist_t *namelist; - dns_clientrestrans_t *trans; - bool canceled; -} resarg_t; - -/*% - * Internal state for a single DNS request - */ -typedef struct reqctx { - /* Unlocked */ - unsigned int magic; - isc_mutex_t lock; - dns_client_t *client; - unsigned int parseoptions; - - /* Locked */ - ISC_LINK(struct reqctx) link; - bool canceled; - dns_tsigkey_t *tsigkey; - dns_request_t *request; - dns_clientreqevent_t *event; -} reqctx_t; - -/*% - * Argument of an internal event for synchronous DNS request. - */ -typedef struct reqarg { - /* Unlocked */ - isc_appctx_t *actx; - dns_client_t *client; - isc_mutex_t lock; - - /* Locked */ - isc_result_t result; - dns_clientreqtrans_t *trans; - bool canceled; -} reqarg_t; - -/*% - * Argument of an internal event for synchronous name resolution. - */ -typedef struct updatearg { - /* Unlocked */ - isc_appctx_t *actx; - dns_client_t *client; - isc_mutex_t lock; - - /* Locked */ - isc_result_t result; - dns_clientupdatetrans_t *trans; - bool canceled; -} updatearg_t; - -/*% - * Internal state for a single dynamic update procedure - */ -typedef struct updatectx { - /* Unlocked */ - unsigned int magic; - isc_mutex_t lock; - dns_client_t *client; - bool want_tcp; - - /* Locked */ - dns_request_t *updatereq; - dns_request_t *soareq; - dns_clientrestrans_t *restrans; - dns_clientrestrans_t *restrans2; - bool canceled; - - /* Task Locked */ - ISC_LINK(struct updatectx) link; - dns_clientupdatestate_t state; - dns_rdataclass_t rdclass; - dns_view_t *view; - dns_message_t *updatemsg; - dns_message_t *soaquery; - dns_clientupdateevent_t *event; - dns_tsigkey_t *tsigkey; - dst_key_t *sig0key; - dns_name_t *firstname; - dns_name_t soaqname; - dns_fixedname_t zonefname; - dns_name_t *zonename; - isc_sockaddrlist_t servers; - unsigned int nservers; - isc_sockaddr_t *currentserver; - struct updatectx *bp4; - struct updatectx *bp6; -} updatectx_t; - -static isc_result_t request_soa(updatectx_t *uctx); -static void client_resfind(resctx_t *rctx, dns_fetchevent_t *event); -static isc_result_t send_update(updatectx_t *uctx); - -/* - * Try honoring the operating system's preferred ephemeral port range. - */ -static isc_result_t -setsourceports(isc_mem_t *mctx, dns_dispatchmgr_t *manager) { - isc_portset_t *v4portset = NULL, *v6portset = NULL; - in_port_t udpport_low, udpport_high; - isc_result_t result; - - result = isc_portset_create(mctx, &v4portset); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - result = isc_net_getudpportrange(AF_INET, &udpport_low, &udpport_high); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - isc_portset_addrange(v4portset, udpport_low, udpport_high); - - result = isc_portset_create(mctx, &v6portset); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - result = isc_net_getudpportrange(AF_INET6, &udpport_low, &udpport_high); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - isc_portset_addrange(v6portset, udpport_low, udpport_high); - - result = dns_dispatchmgr_setavailports(manager, v4portset, v6portset); - - cleanup: - if (v4portset != NULL) { - isc_portset_destroy(mctx, &v4portset); - } - if (v6portset != NULL) { - isc_portset_destroy(mctx, &v6portset); - } - - return (result); -} - -static isc_result_t -getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, - isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, - bool is_shared, dns_dispatch_t **dispp, - isc_sockaddr_t *localaddr) -{ - unsigned int attrs, attrmask; - dns_dispatch_t *disp; - unsigned buffersize, maxbuffers, maxrequests, buckets, increment; - isc_result_t result; - isc_sockaddr_t anyaddr; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (family) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - if (localaddr == NULL) { - localaddr = &anyaddr; - isc_sockaddr_anyofpf(localaddr, family); - } - - buffersize = 4096; - maxbuffers = is_shared ? 1000 : 8; - maxrequests = 32768; - buckets = is_shared ? 16411 : 3; - increment = is_shared ? 16433 : 5; - - disp = NULL; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, - taskmgr, localaddr, - buffersize, maxbuffers, maxrequests, - buckets, increment, - attrs, attrmask, &disp); - if (result == ISC_R_SUCCESS) - *dispp = disp; - - return (result); -} - -static isc_result_t -createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, - unsigned int options, isc_taskmgr_t *taskmgr, - unsigned int ntasks, isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, - dns_view_t **viewp) -{ - isc_result_t result; - dns_view_t *view = NULL; - const char *dbtype; - - result = dns_view_create(mctx, rdclass, DNS_CLIENTVIEW_NAME, &view); - if (result != ISC_R_SUCCESS) - return (result); - - /* Initialize view security roots */ - result = dns_view_initsecroots(view, mctx); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - return (result); - } - - result = dns_view_createresolver(view, taskmgr, ntasks, 1, - socketmgr, timermgr, 0, - dispatchmgr, dispatchv4, dispatchv6); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - return (result); - } - - /* - * Set cache DB. - * XXX: it may be better if specific DB implementations can be - * specified via some configuration knob. - */ - if ((options & DNS_CLIENTCREATEOPT_USECACHE) != 0) - dbtype = "rbt"; - else - dbtype = "ecdb"; - result = dns_db_create(mctx, dbtype, dns_rootname, dns_dbtype_cache, - rdclass, 0, NULL, &view->cachedb); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - return (result); - } - - *viewp = view; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_client_create(dns_client_t **clientp, unsigned int options) { - isc_result_t result; - isc_mem_t *mctx = NULL; - isc_appctx_t *actx = NULL; - isc_taskmgr_t *taskmgr = NULL; - isc_socketmgr_t *socketmgr = NULL; - isc_timermgr_t *timermgr = NULL; -#if 0 - /* XXXMPA add debug logging support */ - isc_log_t *lctx = NULL; - isc_logconfig_t *logconfig = NULL; - unsigned int logdebuglevel = 0; -#endif - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - result = isc_appctx_create(mctx, &actx); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = isc_app_ctxstart(actx); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = isc_socketmgr_createinctx(mctx, actx, &socketmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = isc_timermgr_createinctx(mctx, actx, &timermgr); - if (result != ISC_R_SUCCESS) - goto cleanup; -#if 0 - result = isc_log_create(mctx, &lctx, &logconfig); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_log_setcontext(lctx); - dns_log_init(lctx); - dns_log_setcontext(lctx); - result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_log_setdebuglevel(lctx, logdebuglevel); -#endif - result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr, - options, clientp); - if (result != ISC_R_SUCCESS) - goto cleanup; - - (*clientp)->attributes |= DNS_CLIENTATTR_OWNCTX; - - /* client has its own reference to mctx, so we can detach it here */ - isc_mem_detach(&mctx); - - return (ISC_R_SUCCESS); - - cleanup: - if (taskmgr != NULL) - isc_taskmgr_destroy(&taskmgr); - if (timermgr != NULL) - isc_timermgr_destroy(&timermgr); - if (socketmgr != NULL) - isc_socketmgr_destroy(&socketmgr); - if (actx != NULL) - isc_appctx_destroy(&actx); - isc_mem_detach(&mctx); - - return (result); -} - -isc_result_t -dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, - unsigned int options, dns_client_t **clientp) -{ - isc_result_t result; - result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr, - options, clientp, NULL, NULL); - return (result); -} - -isc_result_t -dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, - isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, unsigned int options, - dns_client_t **clientp, isc_sockaddr_t *localaddr4, - isc_sockaddr_t *localaddr6) -{ - dns_client_t *client; - isc_result_t result; - dns_dispatchmgr_t *dispatchmgr = NULL; - dns_dispatch_t *dispatchv4 = NULL; - dns_dispatch_t *dispatchv6 = NULL; - dns_view_t *view = NULL; - - REQUIRE(mctx != NULL); - REQUIRE(taskmgr != NULL); - REQUIRE(timermgr != NULL); - REQUIRE(socketmgr != NULL); - REQUIRE(clientp != NULL && *clientp == NULL); - - client = isc_mem_get(mctx, sizeof(*client)); - if (client == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&client->lock); - if (result != ISC_R_SUCCESS) { - goto cleanup_client; - } - - client->actx = actx; - client->taskmgr = taskmgr; - client->socketmgr = socketmgr; - client->timermgr = timermgr; - - client->task = NULL; - result = isc_task_create(client->taskmgr, 0, &client->task); - if (result != ISC_R_SUCCESS) { - goto cleanup_lock; - } - - result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); - if (result != ISC_R_SUCCESS) { - goto cleanup_task; - } - client->dispatchmgr = dispatchmgr; - (void)setsourceports(mctx, dispatchmgr); - - /* - * If only one address family is specified, use it. - * If neither family is specified, or if both are, use both. - */ - client->dispatchv4 = NULL; - if (localaddr4 != NULL || localaddr6 == NULL) { - result = getudpdispatch(AF_INET, dispatchmgr, socketmgr, - taskmgr, true, - &dispatchv4, localaddr4); - if (result == ISC_R_SUCCESS) { - client->dispatchv4 = dispatchv4; - } - } - - client->dispatchv6 = NULL; - if (localaddr6 != NULL || localaddr4 == NULL) { - result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr, - taskmgr, true, - &dispatchv6, localaddr6); - if (result == ISC_R_SUCCESS) { - client->dispatchv6 = dispatchv6; - } - } - - /* We need at least one of the dispatchers */ - if (dispatchv4 == NULL && dispatchv6 == NULL) { - INSIST(result != ISC_R_SUCCESS); - goto cleanup_dispatchmgr; - } - - result = isc_refcount_init(&client->references, 1); - if (result != ISC_R_SUCCESS) { - goto cleanup_dispatches; - } - - /* Create the default view for class IN */ - result = createview(mctx, dns_rdataclass_in, options, taskmgr, - RESOLVER_NTASKS, socketmgr, timermgr, - dispatchmgr, dispatchv4, dispatchv6, &view); - if (result != ISC_R_SUCCESS) { - goto cleanup_references; - } - - ISC_LIST_INIT(client->viewlist); - ISC_LIST_APPEND(client->viewlist, view, link); - - dns_view_freeze(view); /* too early? */ - - ISC_LIST_INIT(client->resctxs); - ISC_LIST_INIT(client->reqctxs); - ISC_LIST_INIT(client->updatectxs); - - client->mctx = NULL; - isc_mem_attach(mctx, &client->mctx); - - client->update_timeout = DEF_UPDATE_TIMEOUT; - client->update_udptimeout = DEF_UPDATE_UDPTIMEOUT; - client->update_udpretries = DEF_UPDATE_UDPRETRIES; - client->find_timeout = DEF_FIND_TIMEOUT; - client->find_udpretries = DEF_FIND_UDPRETRIES; - client->attributes = 0; - - client->magic = DNS_CLIENT_MAGIC; - - *clientp = client; - - return (ISC_R_SUCCESS); - - cleanup_references: - isc_refcount_decrement(&client->references, NULL); - isc_refcount_destroy(&client->references); - cleanup_dispatches: - if (dispatchv4 != NULL) - dns_dispatch_detach(&dispatchv4); - if (dispatchv6 != NULL) - dns_dispatch_detach(&dispatchv6); - cleanup_dispatchmgr: - dns_dispatchmgr_destroy(&dispatchmgr); - cleanup_task: - isc_task_detach(&client->task); - cleanup_lock: - DESTROYLOCK(&client->lock); - cleanup_client: - isc_mem_put(mctx, client, sizeof(*client)); - - return (result); -} - -static void -destroyclient(dns_client_t *client) { - dns_view_t *view; - - isc_refcount_destroy(&client->references); - - while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) { - ISC_LIST_UNLINK(client->viewlist, view, link); - dns_view_detach(&view); - } - - if (client->dispatchv4 != NULL) - dns_dispatch_detach(&client->dispatchv4); - if (client->dispatchv6 != NULL) - dns_dispatch_detach(&client->dispatchv6); - - dns_dispatchmgr_destroy(&client->dispatchmgr); - - isc_task_detach(&client->task); - - /* - * If the client has created its own running environments, - * destroy them. - */ - if ((client->attributes & DNS_CLIENTATTR_OWNCTX) != 0) { - isc_taskmgr_destroy(&client->taskmgr); - isc_timermgr_destroy(&client->timermgr); - isc_socketmgr_destroy(&client->socketmgr); - - isc_app_ctxfinish(client->actx); - isc_appctx_destroy(&client->actx); - } - - DESTROYLOCK(&client->lock); - client->magic = 0; - - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); -} - -void -dns_client_destroy(dns_client_t **clientp) { - dns_client_t *client; - uint32_t references; - - REQUIRE(clientp != NULL); - client = *clientp; - *clientp = NULL; - REQUIRE(DNS_CLIENT_VALID(client)); - - isc_refcount_decrement(&client->references, &references); - if (references == 0U) { - destroyclient(client); - } -} - -isc_result_t -dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *name_space, isc_sockaddrlist_t *addrs) -{ - isc_result_t result; - dns_view_t *view = NULL; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(addrs != NULL); - - if (name_space == NULL) - name_space = dns_rootname; - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - if (result != ISC_R_SUCCESS) { - UNLOCK(&client->lock); - return (result); - } - UNLOCK(&client->lock); - - result = dns_fwdtable_add(view->fwdtable, name_space, addrs, - dns_fwdpolicy_only); - - dns_view_detach(&view); - - return (result); -} - -isc_result_t -dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *name_space) -{ - isc_result_t result; - dns_view_t *view = NULL; - - REQUIRE(DNS_CLIENT_VALID(client)); - - if (name_space == NULL) - name_space = dns_rootname; - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - if (result != ISC_R_SUCCESS) { - UNLOCK(&client->lock); - return (result); - } - UNLOCK(&client->lock); - - result = dns_fwdtable_delete(view->fwdtable, name_space); - - dns_view_detach(&view); - - return (result); -} - -isc_result_t -dns_client_setdlv(dns_client_t *client, dns_rdataclass_t rdclass, - const char *dlvname) -{ - isc_result_t result; - isc_buffer_t b; - dns_view_t *view = NULL; - - REQUIRE(DNS_CLIENT_VALID(client)); - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - UNLOCK(&client->lock); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (dlvname == NULL) - view->dlv = NULL; - else { - dns_name_t *newdlv; - - isc_buffer_constinit(&b, dlvname, strlen(dlvname)); - isc_buffer_add(&b, strlen(dlvname)); - newdlv = dns_fixedname_name(&view->dlv_fixed); - result = dns_name_fromtext(newdlv, &b, dns_rootname, - DNS_NAME_DOWNCASE, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - view->dlv = dns_fixedname_name(&view->dlv_fixed); - } - - cleanup: - if (view != NULL) - dns_view_detach(&view); - - return (result); -} - -static isc_result_t -getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) { - dns_rdataset_t *rdataset; - - REQUIRE(mctx != NULL); - REQUIRE(rdatasetp != NULL && *rdatasetp == NULL); - - rdataset = isc_mem_get(mctx, sizeof(*rdataset)); - if (rdataset == NULL) - return (ISC_R_NOMEMORY); - - dns_rdataset_init(rdataset); - - *rdatasetp = rdataset; - - return (ISC_R_SUCCESS); -} - -static void -putrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) { - dns_rdataset_t *rdataset; - - REQUIRE(rdatasetp != NULL); - rdataset = *rdatasetp; - REQUIRE(rdataset != NULL); - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - isc_mem_put(mctx, rdataset, sizeof(*rdataset)); - - *rdatasetp = NULL; -} - -static void -fetch_done(isc_task_t *task, isc_event_t *event) { - resctx_t *rctx = event->ev_arg; - dns_fetchevent_t *fevent; - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - REQUIRE(RCTX_VALID(rctx)); - REQUIRE(rctx->task == task); - fevent = (dns_fetchevent_t *)event; - - client_resfind(rctx, fevent); -} - -static inline isc_result_t -start_fetch(resctx_t *rctx) { - isc_result_t result; - int fopts = 0; - - /* - * The caller must be holding the rctx's lock. - */ - - REQUIRE(rctx->fetch == NULL); - - if (!rctx->want_cdflag) - fopts |= DNS_FETCHOPT_NOCDFLAG; - if (!rctx->want_validation) - fopts |= DNS_FETCHOPT_NOVALIDATE; - if (rctx->want_tcp) - fopts |= DNS_FETCHOPT_TCP; - - result = dns_resolver_createfetch(rctx->view->resolver, - dns_fixedname_name(&rctx->name), - rctx->type, - NULL, NULL, NULL, fopts, - rctx->task, fetch_done, rctx, - rctx->rdataset, - rctx->sigrdataset, - &rctx->fetch); - - return (result); -} - -static isc_result_t -view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep, - dns_name_t *foundname) -{ - isc_result_t result; - dns_name_t *name = dns_fixedname_name(&rctx->name); - dns_rdatatype_t type; - - if (rctx->type == dns_rdatatype_rrsig) - type = dns_rdatatype_any; - else - type = rctx->type; - - result = dns_view_find(rctx->view, name, type, 0, 0, false, - dbp, nodep, foundname, rctx->rdataset, - rctx->sigrdataset); - - return (result); -} - -static void -client_resfind(resctx_t *rctx, dns_fetchevent_t *event) { - isc_mem_t *mctx; - isc_result_t tresult, result = ISC_R_SUCCESS; - isc_result_t vresult = ISC_R_SUCCESS; - bool want_restart; - bool send_event = false; - dns_name_t *name, *prefix; - dns_fixedname_t foundname, fixed; - dns_rdataset_t *trdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned int nlabels; - int order; - dns_namereln_t namereln; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - - REQUIRE(RCTX_VALID(rctx)); - - LOCK(&rctx->lock); - - mctx = rctx->view->mctx; - - name = dns_fixedname_name(&rctx->name); - - do { - dns_name_t *fname = NULL; - dns_name_t *ansname = NULL; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - - rctx->restarts++; - want_restart = false; - - if (event == NULL && !rctx->canceled) { - fname = dns_fixedname_initname(&foundname); - INSIST(!dns_rdataset_isassociated(rctx->rdataset)); - INSIST(rctx->sigrdataset == NULL || - !dns_rdataset_isassociated(rctx->sigrdataset)); - result = view_find(rctx, &db, &node, fname); - if (result == ISC_R_NOTFOUND) { - /* - * We don't know anything about the name. - * Launch a fetch. - */ - if (node != NULL) { - INSIST(db != NULL); - dns_db_detachnode(db, &node); - } - if (db != NULL) - dns_db_detach(&db); - result = start_fetch(rctx); - if (result != ISC_R_SUCCESS) { - putrdataset(mctx, &rctx->rdataset); - if (rctx->sigrdataset != NULL) - putrdataset(mctx, - &rctx->sigrdataset); - send_event = true; - } - goto done; - } - } else { - INSIST(event != NULL); - INSIST(event->fetch == rctx->fetch); - dns_resolver_destroyfetch(&rctx->fetch); - db = event->db; - node = event->node; - result = event->result; - vresult = event->vresult; - fname = dns_fixedname_name(&event->foundname); - INSIST(event->rdataset == rctx->rdataset); - INSIST(event->sigrdataset == rctx->sigrdataset); - } - - /* - * If we've been canceled, forget about the result. - */ - if (rctx->canceled) - result = ISC_R_CANCELED; - else { - /* - * Otherwise, get some resource for copying the - * result. - */ - dns_name_t *aname = dns_fixedname_name(&rctx->name); - - ansname = isc_mem_get(mctx, sizeof(*ansname)); - dns_name_init(ansname, NULL); - - (void)dns_name_dup(aname, mctx, ansname); - } - - switch (result) { - case ISC_R_SUCCESS: - send_event = true; - /* - * This case is handled in the main line below. - */ - break; - case DNS_R_CNAME: - /* - * Add the CNAME to the answer list. - */ - trdataset = rctx->rdataset; - ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); - rctx->rdataset = NULL; - if (rctx->sigrdataset != NULL) { - ISC_LIST_APPEND(ansname->list, - rctx->sigrdataset, link); - rctx->sigrdataset = NULL; - } - ISC_LIST_APPEND(rctx->namelist, ansname, link); - ansname = NULL; - - /* - * Copy the CNAME's target into the lookup's - * query name and start over. - */ - tresult = dns_rdataset_first(trdataset); - if (tresult != ISC_R_SUCCESS) - goto done; - dns_rdataset_current(trdataset, &rdata); - tresult = dns_rdata_tostruct(&rdata, &cname, NULL); - dns_rdata_reset(&rdata); - if (tresult != ISC_R_SUCCESS) - goto done; - tresult = dns_name_copy(&cname.cname, name, NULL); - dns_rdata_freestruct(&cname); - if (tresult == ISC_R_SUCCESS) - want_restart = true; - else - result = tresult; - goto done; - case DNS_R_DNAME: - /* - * Add the DNAME to the answer list. - */ - trdataset = rctx->rdataset; - ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); - rctx->rdataset = NULL; - if (rctx->sigrdataset != NULL) { - ISC_LIST_APPEND(ansname->list, - rctx->sigrdataset, link); - rctx->sigrdataset = NULL; - } - ISC_LIST_APPEND(rctx->namelist, ansname, link); - ansname = NULL; - - namereln = dns_name_fullcompare(name, fname, &order, - &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Get the target name of the DNAME. - */ - tresult = dns_rdataset_first(trdataset); - if (tresult != ISC_R_SUCCESS) { - result = tresult; - goto done; - } - dns_rdataset_current(trdataset, &rdata); - tresult = dns_rdata_tostruct(&rdata, &dname, NULL); - dns_rdata_reset(&rdata); - if (tresult != ISC_R_SUCCESS) { - result = tresult; - goto done; - } - /* - * Construct the new query name and start over. - */ - prefix = dns_fixedname_initname(&fixed); - dns_name_split(name, nlabels, prefix, NULL); - tresult = dns_name_concatenate(prefix, &dname.dname, - name, NULL); - dns_rdata_freestruct(&dname); - if (tresult == ISC_R_SUCCESS) - want_restart = true; - else - result = tresult; - goto done; - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); - ISC_LIST_APPEND(rctx->namelist, ansname, link); - ansname = NULL; - rctx->rdataset = NULL; - /* What about sigrdataset? */ - if (rctx->sigrdataset != NULL) - putrdataset(mctx, &rctx->sigrdataset); - send_event = true; - goto done; - default: - if (rctx->rdataset != NULL) - putrdataset(mctx, &rctx->rdataset); - if (rctx->sigrdataset != NULL) - putrdataset(mctx, &rctx->sigrdataset); - send_event = true; - goto done; - } - - if (rctx->type == dns_rdatatype_any) { - int n = 0; - dns_rdatasetiter_t *rdsiter = NULL; - - tresult = dns_db_allrdatasets(db, node, NULL, 0, - &rdsiter); - if (tresult != ISC_R_SUCCESS) { - result = tresult; - goto done; - } - - tresult = dns_rdatasetiter_first(rdsiter); - while (tresult == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, - rctx->rdataset); - if (rctx->rdataset->type != 0) { - ISC_LIST_APPEND(ansname->list, - rctx->rdataset, - link); - n++; - rctx->rdataset = NULL; - } else { - /* - * We're not interested in this - * rdataset. - */ - dns_rdataset_disassociate( - rctx->rdataset); - } - tresult = dns_rdatasetiter_next(rdsiter); - - if (tresult == ISC_R_SUCCESS && - rctx->rdataset == NULL) { - tresult = getrdataset(mctx, - &rctx->rdataset); - if (tresult != ISC_R_SUCCESS) { - result = tresult; - POST(result); - break; - } - } - } - if (rctx->rdataset != NULL) { - putrdataset(mctx, &rctx->rdataset); - } - if (rctx->sigrdataset != NULL) { - putrdataset(mctx, &rctx->sigrdataset); - } - if (n == 0) { - /* - * We didn't match any rdatasets (which means - * something went wrong in this - * implementation). - */ - result = DNS_R_SERVFAIL; /* better code? */ - POST(result); - } else { - ISC_LIST_APPEND(rctx->namelist, ansname, link); - ansname = NULL; - } - dns_rdatasetiter_destroy(&rdsiter); - if (tresult != ISC_R_NOMORE) - result = DNS_R_SERVFAIL; /* ditto */ - else - result = ISC_R_SUCCESS; - goto done; - } else { - /* - * This is the "normal" case -- an ordinary question - * to which we've got the answer. - */ - ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); - rctx->rdataset = NULL; - if (rctx->sigrdataset != NULL) { - ISC_LIST_APPEND(ansname->list, - rctx->sigrdataset, link); - rctx->sigrdataset = NULL; - } - ISC_LIST_APPEND(rctx->namelist, ansname, link); - ansname = NULL; - } - - done: - /* - * Free temporary resources - */ - if (ansname != NULL) { - dns_rdataset_t *rdataset; - - while ((rdataset = ISC_LIST_HEAD(ansname->list)) - != NULL) { - ISC_LIST_UNLINK(ansname->list, rdataset, link); - putrdataset(mctx, &rdataset); - } - dns_name_free(ansname, mctx); - isc_mem_put(mctx, ansname, sizeof(*ansname)); - } - - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - - /* - * Limit the number of restarts. - */ - if (want_restart && rctx->restarts == MAX_RESTARTS) { - want_restart = false; - result = ISC_R_QUOTA; - send_event = true; - } - - /* - * Prepare further find with new resources - */ - if (want_restart) { - INSIST(rctx->rdataset == NULL && - rctx->sigrdataset == NULL); - - result = getrdataset(mctx, &rctx->rdataset); - if (result == ISC_R_SUCCESS && rctx->want_dnssec) { - result = getrdataset(mctx, &rctx->sigrdataset); - if (result != ISC_R_SUCCESS) { - putrdataset(mctx, &rctx->rdataset); - } - } - - if (result != ISC_R_SUCCESS) { - want_restart = false; - send_event = true; - } - } - } while (want_restart); - - if (send_event) { - isc_task_t *task; - - while ((name = ISC_LIST_HEAD(rctx->namelist)) != NULL) { - ISC_LIST_UNLINK(rctx->namelist, name, link); - ISC_LIST_APPEND(rctx->event->answerlist, name, link); - } - - rctx->event->result = result; - rctx->event->vresult = vresult; - task = rctx->event->ev_sender; - rctx->event->ev_sender = rctx; - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&rctx->event)); - } - - UNLOCK(&rctx->lock); -} - -static void -suspend(isc_task_t *task, isc_event_t *event) { - isc_appctx_t *actx = event->ev_arg; - - UNUSED(task); - - isc_app_ctxsuspend(actx); - isc_event_free(&event); -} - -static void -resolve_done(isc_task_t *task, isc_event_t *event) { - resarg_t *resarg = event->ev_arg; - dns_clientresevent_t *rev = (dns_clientresevent_t *)event; - dns_name_t *name; - isc_result_t result; - - UNUSED(task); - - LOCK(&resarg->lock); - - resarg->result = rev->result; - resarg->vresult = rev->vresult; - while ((name = ISC_LIST_HEAD(rev->answerlist)) != NULL) { - ISC_LIST_UNLINK(rev->answerlist, name, link); - ISC_LIST_APPEND(*resarg->namelist, name, link); - } - - dns_client_destroyrestrans(&resarg->trans); - isc_event_free(&event); - - if (!resarg->canceled) { - UNLOCK(&resarg->lock); - - /* - * We may or may not be running. isc__appctx_onrun will - * fail if we are currently running otherwise we post a - * action to call isc_app_ctxsuspend when we do start - * running. - */ - result = isc_app_ctxonrun(resarg->actx, resarg->client->mctx, - task, suspend, resarg->actx); - if (result == ISC_R_ALREADYRUNNING) - isc_app_ctxsuspend(resarg->actx); - } else { - /* - * We have already exited from the loop (due to some - * unexpected event). Just clean the arg up. - */ - UNLOCK(&resarg->lock); - DESTROYLOCK(&resarg->lock); - isc_mem_put(resarg->client->mctx, resarg, sizeof(*resarg)); - } -} - -isc_result_t -dns_client_resolve(dns_client_t *client, dns_name_t *name, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int options, dns_namelist_t *namelist) -{ - isc_result_t result; - isc_appctx_t *actx; - resarg_t *resarg; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(namelist != NULL && ISC_LIST_EMPTY(*namelist)); - - if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && - (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) { - /* - * If the client is run under application's control, we need - * to create a new running (sub)environment for this - * particular resolution. - */ - return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ - } else - actx = client->actx; - - resarg = isc_mem_get(client->mctx, sizeof(*resarg)); - if (resarg == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&resarg->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(client->mctx, resarg, sizeof(*resarg)); - return (result); - } - - resarg->actx = actx; - resarg->client = client; - resarg->result = DNS_R_SERVFAIL; - resarg->namelist = namelist; - resarg->trans = NULL; - resarg->canceled = false; - result = dns_client_startresolve(client, name, rdclass, type, options, - client->task, resolve_done, resarg, - &resarg->trans); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&resarg->lock); - isc_mem_put(client->mctx, resarg, sizeof(*resarg)); - return (result); - } - - /* - * Start internal event loop. It blocks until the entire process - * is completed. - */ - result = isc_app_ctxrun(actx); - - LOCK(&resarg->lock); - if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) - result = resarg->result; - if (result != ISC_R_SUCCESS && resarg->vresult != ISC_R_SUCCESS) { - /* - * If this lookup failed due to some error in DNSSEC - * validation, return the validation error code. - * XXX: or should we pass the validation result separately? - */ - result = resarg->vresult; - } - if (resarg->trans != NULL) { - /* - * Unusual termination (perhaps due to signal). We need some - * tricky cleanup process. - */ - resarg->canceled = true; - dns_client_cancelresolve(resarg->trans); - - UNLOCK(&resarg->lock); - - /* resarg will be freed in the event handler. */ - } else { - UNLOCK(&resarg->lock); - - DESTROYLOCK(&resarg->lock); - isc_mem_put(client->mctx, resarg, sizeof(*resarg)); - } - - return (result); -} - -isc_result_t -dns_client_startresolve(dns_client_t *client, dns_name_t *name, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_clientrestrans_t **transp) -{ - dns_view_t *view = NULL; - dns_clientresevent_t *event = NULL; - resctx_t *rctx = NULL; - isc_task_t *tclone = NULL; - isc_mem_t *mctx; - isc_result_t result; - dns_rdataset_t *rdataset, *sigrdataset; - bool want_dnssec, want_validation, want_cdflag, want_tcp; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(transp != NULL && *transp == NULL); - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - UNLOCK(&client->lock); - if (result != ISC_R_SUCCESS) - return (result); - - mctx = client->mctx; - rdataset = NULL; - sigrdataset = NULL; - want_dnssec = ((options & DNS_CLIENTRESOPT_NODNSSEC) == 0); - want_validation = ((options & DNS_CLIENTRESOPT_NOVALIDATE) == 0); - want_cdflag = ((options & DNS_CLIENTRESOPT_NOCDFLAG) == 0); - want_tcp = ((options & DNS_CLIENTRESOPT_TCP) != 0); - - /* - * Prepare some intermediate resources - */ - tclone = NULL; - isc_task_attach(task, &tclone); - event = (dns_clientresevent_t *) - isc_event_allocate(mctx, tclone, DNS_EVENT_CLIENTRESDONE, - action, arg, sizeof(*event)); - if (event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - event->result = DNS_R_SERVFAIL; - ISC_LIST_INIT(event->answerlist); - - rctx = isc_mem_get(mctx, sizeof(*rctx)); - if (rctx == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } else { - result = isc_mutex_init(&rctx->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, rctx, sizeof(*rctx)); - rctx = NULL; - goto cleanup; - } - } - - result = getrdataset(mctx, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - rctx->rdataset = rdataset; - - if (want_dnssec) { - result = getrdataset(mctx, &sigrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - rctx->sigrdataset = sigrdataset; - - dns_fixedname_init(&rctx->name); - result = dns_name_copy(name, dns_fixedname_name(&rctx->name), NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rctx->client = client; - ISC_LINK_INIT(rctx, link); - rctx->canceled = false; - rctx->task = client->task; - rctx->type = type; - rctx->view = view; - rctx->restarts = 0; - rctx->fetch = NULL; - rctx->want_dnssec = want_dnssec; - rctx->want_validation = want_validation; - rctx->want_cdflag = want_cdflag; - rctx->want_tcp = want_tcp; - ISC_LIST_INIT(rctx->namelist); - rctx->event = event; - - rctx->magic = RCTX_MAGIC; - isc_refcount_increment(&client->references, NULL); - - LOCK(&client->lock); - ISC_LIST_APPEND(client->resctxs, rctx, link); - UNLOCK(&client->lock); - - *transp = (dns_clientrestrans_t *)rctx; - client_resfind(rctx, NULL); - - return (ISC_R_SUCCESS); - - cleanup: - if (rdataset != NULL) - putrdataset(client->mctx, &rdataset); - if (sigrdataset != NULL) - putrdataset(client->mctx, &sigrdataset); - if (rctx != NULL) { - DESTROYLOCK(&rctx->lock); - isc_mem_put(mctx, rctx, sizeof(*rctx)); - } - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - isc_task_detach(&tclone); - dns_view_detach(&view); - - return (result); -} - -void -dns_client_cancelresolve(dns_clientrestrans_t *trans) { - resctx_t *rctx; - - REQUIRE(trans != NULL); - rctx = (resctx_t *)trans; - REQUIRE(RCTX_VALID(rctx)); - - LOCK(&rctx->lock); - - if (!rctx->canceled) { - rctx->canceled = true; - if (rctx->fetch != NULL) - dns_resolver_cancelfetch(rctx->fetch); - } - - UNLOCK(&rctx->lock); -} - -void -dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist) { - dns_name_t *name; - dns_rdataset_t *rdataset; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(namelist != NULL); - - while ((name = ISC_LIST_HEAD(*namelist)) != NULL) { - ISC_LIST_UNLINK(*namelist, name, link); - while ((rdataset = ISC_LIST_HEAD(name->list)) != NULL) { - ISC_LIST_UNLINK(name->list, rdataset, link); - putrdataset(client->mctx, &rdataset); - } - dns_name_free(name, client->mctx); - isc_mem_put(client->mctx, name, sizeof(*name)); - } -} - -void -dns_client_destroyrestrans(dns_clientrestrans_t **transp) { - resctx_t *rctx; - isc_mem_t *mctx; - dns_client_t *client; - - REQUIRE(transp != NULL); - rctx = (resctx_t *)*transp; - *transp = NULL; - REQUIRE(RCTX_VALID(rctx)); - REQUIRE(rctx->fetch == NULL); - REQUIRE(rctx->event == NULL); - client = rctx->client; - REQUIRE(DNS_CLIENT_VALID(client)); - - mctx = client->mctx; - dns_view_detach(&rctx->view); - - /* - * Wait for the lock in client_resfind to be released before - * destroying the lock. - */ - LOCK(&rctx->lock); - UNLOCK(&rctx->lock); - - LOCK(&client->lock); - - INSIST(ISC_LINK_LINKED(rctx, link)); - ISC_LIST_UNLINK(client->resctxs, rctx, link); - - UNLOCK(&client->lock); - - INSIST(ISC_LIST_EMPTY(rctx->namelist)); - - DESTROYLOCK(&rctx->lock); - rctx->magic = 0; - - isc_mem_put(mctx, rctx, sizeof(*rctx)); - - dns_client_destroy(&client); - -} - -isc_result_t -dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *keyname, isc_buffer_t *keydatabuf) -{ - isc_result_t result; - dns_view_t *view = NULL; - dst_key_t *dstkey = NULL; - dns_keytable_t *secroots = NULL; - - REQUIRE(DNS_CLIENT_VALID(client)); - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - UNLOCK(&client->lock); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_view_getsecroots(view, &secroots); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dst_key_fromdns(keyname, rdclass, keydatabuf, client->mctx, - &dstkey); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_keytable_add(secroots, false, &dstkey); - - cleanup: - if (dstkey != NULL) - dst_key_free(&dstkey); - if (view != NULL) - dns_view_detach(&view); - if (secroots != NULL) - dns_keytable_detach(&secroots); - return (result); -} - -/*% - * Simple request routines - */ -static void -request_done(isc_task_t *task, isc_event_t *event) { - dns_requestevent_t *reqev = NULL; - dns_request_t *request; - isc_result_t result, eresult; - reqctx_t *ctx; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); - reqev = (dns_requestevent_t *)event; - request = reqev->request; - result = eresult = reqev->result; - ctx = reqev->ev_arg; - REQUIRE(REQCTX_VALID(ctx)); - - isc_event_free(&event); - - LOCK(&ctx->lock); - - if (eresult == ISC_R_SUCCESS) { - result = dns_request_getresponse(request, ctx->event->rmessage, - ctx->parseoptions); - } - - if (ctx->tsigkey != NULL) - dns_tsigkey_detach(&ctx->tsigkey); - - if (ctx->canceled) - ctx->event->result = ISC_R_CANCELED; - else - ctx->event->result = result; - task = ctx->event->ev_sender; - ctx->event->ev_sender = ctx; - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&ctx->event)); - - UNLOCK(&ctx->lock); -} - -static void -localrequest_done(isc_task_t *task, isc_event_t *event) { - reqarg_t *reqarg = event->ev_arg; - dns_clientreqevent_t *rev =(dns_clientreqevent_t *)event; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_CLIENTREQDONE); - - LOCK(&reqarg->lock); - - reqarg->result = rev->result; - dns_client_destroyreqtrans(&reqarg->trans); - isc_event_free(&event); - - if (!reqarg->canceled) { - UNLOCK(&reqarg->lock); - - /* Exit from the internal event loop */ - isc_app_ctxsuspend(reqarg->actx); - } else { - /* - * We have already exited from the loop (due to some - * unexpected event). Just clean the arg up. - */ - UNLOCK(&reqarg->lock); - DESTROYLOCK(&reqarg->lock); - isc_mem_put(reqarg->client->mctx, reqarg, sizeof(*reqarg)); - } -} - -isc_result_t -dns_client_request(dns_client_t *client, dns_message_t *qmessage, - dns_message_t *rmessage, isc_sockaddr_t *server, - unsigned int options, unsigned int parseoptions, - dns_tsec_t *tsec, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries) -{ - isc_appctx_t *actx; - reqarg_t *reqarg; - isc_result_t result; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(qmessage != NULL); - REQUIRE(rmessage != NULL); - - if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && - (options & DNS_CLIENTREQOPT_ALLOWRUN) == 0) { - /* - * If the client is run under application's control, we need - * to create a new running (sub)environment for this - * particular resolution. - */ - return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ - } else - actx = client->actx; - - reqarg = isc_mem_get(client->mctx, sizeof(*reqarg)); - if (reqarg == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&reqarg->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); - return (result); - } - - reqarg->actx = actx; - reqarg->client = client; - reqarg->trans = NULL; - reqarg->canceled = false; - - result = dns_client_startrequest(client, qmessage, rmessage, server, - options, parseoptions, tsec, timeout, - udptimeout, udpretries, - client->task, localrequest_done, - reqarg, &reqarg->trans); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&reqarg->lock); - isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); - return (result); - } - - /* - * Start internal event loop. It blocks until the entire process - * is completed. - */ - result = isc_app_ctxrun(actx); - - LOCK(&reqarg->lock); - if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) - result = reqarg->result; - if (reqarg->trans != NULL) { - /* - * Unusual termination (perhaps due to signal). We need some - * tricky cleanup process. - */ - reqarg->canceled = true; - dns_client_cancelresolve(reqarg->trans); - - UNLOCK(&reqarg->lock); - - /* reqarg will be freed in the event handler. */ - } else { - UNLOCK(&reqarg->lock); - - DESTROYLOCK(&reqarg->lock); - isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); - } - - return (result); -} - -isc_result_t -dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, - dns_message_t *rmessage, isc_sockaddr_t *server, - unsigned int options, unsigned int parseoptions, - dns_tsec_t *tsec, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_clientreqtrans_t **transp) -{ - isc_result_t result; - dns_view_t *view = NULL; - isc_task_t *tclone = NULL; - dns_clientreqevent_t *event = NULL; - reqctx_t *ctx = NULL; - dns_tsectype_t tsectype = dns_tsectype_none; - unsigned int reqoptions; - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(qmessage != NULL); - REQUIRE(rmessage != NULL); - REQUIRE(transp != NULL && *transp == NULL); - - if (tsec != NULL) { - tsectype = dns_tsec_gettype(tsec); - if (tsectype != dns_tsectype_tsig) - return (ISC_R_NOTIMPLEMENTED); /* XXX */ - } - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - qmessage->rdclass, &view); - UNLOCK(&client->lock); - if (result != ISC_R_SUCCESS) - return (result); - - reqoptions = 0; - if ((options & DNS_CLIENTREQOPT_TCP) != 0) - reqoptions |= DNS_REQUESTOPT_TCP; - - tclone = NULL; - isc_task_attach(task, &tclone); - event = (dns_clientreqevent_t *) - isc_event_allocate(client->mctx, tclone, - DNS_EVENT_CLIENTREQDONE, - action, arg, sizeof(*event)); - if (event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - ctx = isc_mem_get(client->mctx, sizeof(*ctx)); - if (ctx == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } else { - result = isc_mutex_init(&ctx->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(client->mctx, ctx, sizeof(*ctx)); - ctx = NULL; - goto cleanup; - } - } - - ctx->client = client; - ISC_LINK_INIT(ctx, link); - ctx->parseoptions = parseoptions; - ctx->canceled = false; - ctx->event = event; - ctx->event->rmessage = rmessage; - ctx->tsigkey = NULL; - if (tsec != NULL) - dns_tsec_getkey(tsec, &ctx->tsigkey); - - ctx->magic = REQCTX_MAGIC; - - LOCK(&client->lock); - ISC_LIST_APPEND(client->reqctxs, ctx, link); - isc_refcount_increment(&client->references, NULL); - UNLOCK(&client->lock); - - ctx->request = NULL; - result = dns_request_createvia3(view->requestmgr, qmessage, NULL, - server, reqoptions, ctx->tsigkey, - timeout, udptimeout, udpretries, - client->task, request_done, ctx, - &ctx->request); - if (result == ISC_R_SUCCESS) { - dns_view_detach(&view); - *transp = (dns_clientreqtrans_t *)ctx; - return (ISC_R_SUCCESS); - } - - isc_refcount_decrement(&client->references, NULL); - - cleanup: - if (ctx != NULL) { - LOCK(&client->lock); - ISC_LIST_UNLINK(client->reqctxs, ctx, link); - UNLOCK(&client->lock); - DESTROYLOCK(&ctx->lock); - isc_mem_put(client->mctx, ctx, sizeof(*ctx)); - } - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - isc_task_detach(&tclone); - dns_view_detach(&view); - - return (result); -} - -void -dns_client_cancelrequest(dns_clientreqtrans_t *trans) { - reqctx_t *ctx; - - REQUIRE(trans != NULL); - ctx = (reqctx_t *)trans; - REQUIRE(REQCTX_VALID(ctx)); - - LOCK(&ctx->lock); - - if (!ctx->canceled) { - ctx->canceled = true; - if (ctx->request != NULL) - dns_request_cancel(ctx->request); - } - - UNLOCK(&ctx->lock); -} - -void -dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) { - reqctx_t *ctx; - isc_mem_t *mctx; - dns_client_t *client; - - REQUIRE(transp != NULL); - ctx = (reqctx_t *)*transp; - *transp = NULL; - REQUIRE(REQCTX_VALID(ctx)); - client = ctx->client; - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(ctx->event == NULL); - REQUIRE(ctx->request != NULL); - - dns_request_destroy(&ctx->request); - mctx = client->mctx; - - LOCK(&client->lock); - - INSIST(ISC_LINK_LINKED(ctx, link)); - ISC_LIST_UNLINK(client->reqctxs, ctx, link); - - UNLOCK(&client->lock); - - DESTROYLOCK(&ctx->lock); - ctx->magic = 0; - - isc_mem_put(mctx, ctx, sizeof(*ctx)); - - dns_client_destroy(&client); -} - -/*% - * Dynamic update routines - */ -static isc_result_t -rcode2result(dns_rcode_t rcode) { - /* XXX: isn't there a similar function? */ - switch (rcode) { - case dns_rcode_formerr: - return (DNS_R_FORMERR); - case dns_rcode_servfail: - return (DNS_R_SERVFAIL); - case dns_rcode_nxdomain: - return (DNS_R_NXDOMAIN); - case dns_rcode_notimp: - return (DNS_R_NOTIMP); - case dns_rcode_refused: - return (DNS_R_REFUSED); - case dns_rcode_yxdomain: - return (DNS_R_YXDOMAIN); - case dns_rcode_yxrrset: - return (DNS_R_YXRRSET); - case dns_rcode_nxrrset: - return (DNS_R_NXRRSET); - case dns_rcode_notauth: - return (DNS_R_NOTAUTH); - case dns_rcode_notzone: - return (DNS_R_NOTZONE); - case dns_rcode_badvers: - return (DNS_R_BADVERS); - } - - return (ISC_R_FAILURE); -} - -static void -update_sendevent(updatectx_t *uctx, isc_result_t result) { - isc_task_t *task; - - dns_message_detach(&uctx->updatemsg); - if (uctx->tsigkey != NULL) - dns_tsigkey_detach(&uctx->tsigkey); - if (uctx->sig0key != NULL) - dst_key_free(&uctx->sig0key); - - if (uctx->canceled) - uctx->event->result = ISC_R_CANCELED; - else - uctx->event->result = result; - uctx->event->state = uctx->state; - task = uctx->event->ev_sender; - uctx->event->ev_sender = uctx; - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&uctx->event)); -} - -static void -update_done(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_requestevent_t *reqev = NULL; - dns_request_t *request; - dns_message_t *answer = NULL; - updatectx_t *uctx = event->ev_arg; - dns_client_t *client; - unsigned int timeout, reqoptions; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); - reqev = (dns_requestevent_t *)event; - request = reqev->request; - REQUIRE(UCTX_VALID(uctx)); - client = uctx->client; - REQUIRE(DNS_CLIENT_VALID(client)); - - result = reqev->result; - if (result != ISC_R_SUCCESS) - goto out; - - result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, - &answer); - if (result != ISC_R_SUCCESS) - goto out; - uctx->state = dns_clientupdatestate_done; - result = dns_request_getresponse(request, answer, - DNS_MESSAGEPARSE_PRESERVEORDER); - if (result == ISC_R_SUCCESS && answer->rcode != dns_rcode_noerror) - result = rcode2result(answer->rcode); - - out: - if (answer != NULL) - dns_message_detach(&answer); - isc_event_free(&event); - - LOCK(&uctx->lock); - uctx->currentserver = ISC_LIST_NEXT(uctx->currentserver, link); - dns_request_destroy(&uctx->updatereq); - /* - * Moving on to the next server shouldn't change the result - * for NXDOMAIN, YXDOMAIN, NXRRSET and YXRRSET as they - * indicate a prerequisite failure. REFUSED should also - * be consistent across all servers but often isn't as that - * is policy rather that zone content driven (slaves that - * aren't willing to forward should return NOTIMPL). NOTZONE - * indicates that we stuffed up the request construction so - * don't retry. - */ - if (result != ISC_R_SUCCESS && result != DNS_R_NXDOMAIN && - result != DNS_R_YXDOMAIN && result != DNS_R_YXRRSET && - result != DNS_R_NXRRSET && result != DNS_R_NOTZONE && - !uctx->canceled && uctx->currentserver != NULL) - { - dns_message_renderreset(uctx->updatemsg); - dns_message_settsigkey(uctx->updatemsg, NULL); - - timeout = client->update_timeout / uctx->nservers; - if (timeout < MIN_UPDATE_TIMEOUT) - timeout = MIN_UPDATE_TIMEOUT; - reqoptions = 0; - if (uctx->want_tcp) - reqoptions |= DNS_REQUESTOPT_TCP; - result = dns_request_createvia3(uctx->view->requestmgr, - uctx->updatemsg, - NULL, - uctx->currentserver, - reqoptions, - uctx->tsigkey, - timeout, - client->update_udptimeout, - client->update_udpretries, - client->task, - update_done, uctx, - &uctx->updatereq); - UNLOCK(&uctx->lock); - - if (result == ISC_R_SUCCESS) { - /* XXX: should we keep the 'done' state here? */ - uctx->state = dns_clientupdatestate_sent; - return; - } - } else - UNLOCK(&uctx->lock); - - update_sendevent(uctx, result); -} - -static isc_result_t -send_update(updatectx_t *uctx) { - isc_result_t result; - dns_name_t *name = NULL; - dns_rdataset_t *rdataset = NULL; - dns_client_t *client = uctx->client; - unsigned int timeout, reqoptions; - - REQUIRE(uctx->zonename != NULL && uctx->currentserver != NULL); - - result = dns_message_gettempname(uctx->updatemsg, &name); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(name, NULL); - dns_name_clone(uctx->zonename, name); - result = dns_message_gettemprdataset(uctx->updatemsg, &rdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(uctx->updatemsg, &name); - return (result); - } - dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa); - ISC_LIST_INIT(name->list); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(uctx->updatemsg, name, DNS_SECTION_ZONE); - if (uctx->tsigkey == NULL && uctx->sig0key != NULL) { - result = dns_message_setsig0key(uctx->updatemsg, - uctx->sig0key); - if (result != ISC_R_SUCCESS) - return (result); - } - timeout = client->update_timeout / uctx->nservers; - if (timeout < MIN_UPDATE_TIMEOUT) - timeout = MIN_UPDATE_TIMEOUT; - reqoptions = 0; - if (uctx->want_tcp) - reqoptions |= DNS_REQUESTOPT_TCP; - result = dns_request_createvia3(uctx->view->requestmgr, - uctx->updatemsg, - NULL, uctx->currentserver, - reqoptions, uctx->tsigkey, timeout, - client->update_udptimeout, - client->update_udpretries, - client->task, update_done, uctx, - &uctx->updatereq); - if (result == ISC_R_SUCCESS && - uctx->state == dns_clientupdatestate_prepare) { - uctx->state = dns_clientupdatestate_sent; - } - - return (result); -} - -static void -resolveaddr_done(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - int family; - dns_rdatatype_t qtype; - dns_clientresevent_t *rev = (dns_clientresevent_t *)event; - dns_name_t *name; - dns_rdataset_t *rdataset; - updatectx_t *uctx; - bool completed = false; - - UNUSED(task); - - REQUIRE(event->ev_arg != NULL); - uctx = *(updatectx_t **)event->ev_arg; - REQUIRE(UCTX_VALID(uctx)); - - if (event->ev_arg == &uctx->bp4) { - family = AF_INET; - qtype = dns_rdatatype_a; - LOCK(&uctx->lock); - dns_client_destroyrestrans(&uctx->restrans); - UNLOCK(&uctx->lock); - } else { - INSIST(event->ev_arg == &uctx->bp6); - family = AF_INET6; - qtype = dns_rdatatype_aaaa; - LOCK(&uctx->lock); - dns_client_destroyrestrans(&uctx->restrans2); - UNLOCK(&uctx->lock); - } - - result = rev->result; - if (result != ISC_R_SUCCESS) - goto done; - - for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; - name = ISC_LIST_NEXT(name, link)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (!dns_rdataset_isassociated(rdataset)) - continue; - if (rdataset->type != qtype) - continue; - - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata; - dns_rdata_in_a_t rdata_a; - dns_rdata_in_aaaa_t rdata_aaaa; - isc_sockaddr_t *sa; - - sa = isc_mem_get(uctx->client->mctx, - sizeof(*sa)); - if (sa == NULL) { - /* - * If we fail to get a sockaddr, - we simply move forward with the - * addresses we've got so far. - */ - goto done; - } - - dns_rdata_init(&rdata); - switch (family) { - case AF_INET: - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rdata_a, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin(sa, - &rdata_a.in_addr, - 53); - dns_rdata_freestruct(&rdata_a); - break; - case AF_INET6: - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rdata_aaaa, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_sockaddr_fromin6(sa, - &rdata_aaaa.in6_addr, - 53); - dns_rdata_freestruct(&rdata_aaaa); - break; - } - - ISC_LINK_INIT(sa, link); - ISC_LIST_APPEND(uctx->servers, sa, link); - uctx->nservers++; - } - } - } - - done: - dns_client_freeresanswer(uctx->client, &rev->answerlist); - isc_event_free(&event); - - LOCK(&uctx->lock); - if (uctx->restrans == NULL && uctx->restrans2 == NULL) - completed = true; - UNLOCK(&uctx->lock); - - if (completed) { - INSIST(uctx->currentserver == NULL); - uctx->currentserver = ISC_LIST_HEAD(uctx->servers); - if (uctx->currentserver != NULL && !uctx->canceled) - send_update(uctx); - else { - if (result == ISC_R_SUCCESS) - result = ISC_R_NOTFOUND; - update_sendevent(uctx, result); - } - } -} - -static isc_result_t -process_soa(updatectx_t *uctx, dns_rdataset_t *soaset, dns_name_t *soaname) { - isc_result_t result; - dns_rdata_t soarr = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - dns_name_t primary; - unsigned int resoptions; - - result = dns_rdataset_first(soaset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdata_init(&soarr); - dns_rdataset_current(soaset, &soarr); - result = dns_rdata_tostruct(&soarr, &soa, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - dns_name_init(&primary, NULL); - dns_name_clone(&soa.origin, &primary); - - if (uctx->zonename == NULL) { - uctx->zonename = dns_fixedname_name(&uctx->zonefname); - result = dns_name_copy(soaname, uctx->zonename, NULL); - if (result != ISC_R_SUCCESS) - goto out; - } - - if (uctx->currentserver != NULL) - result = send_update(uctx); - else { - /* - * Get addresses of the primary server. We don't use the ADB - * feature so that we could avoid caching data. - */ - LOCK(&uctx->lock); - uctx->bp4 = uctx; - resoptions = 0; - if (uctx->want_tcp) - resoptions |= DNS_CLIENTRESOPT_TCP; - result = dns_client_startresolve(uctx->client, &primary, - uctx->rdclass, - dns_rdatatype_a, - resoptions, - uctx->client->task, - resolveaddr_done, &uctx->bp4, - &uctx->restrans); - if (result == ISC_R_SUCCESS) { - uctx->bp6 = uctx; - result = dns_client_startresolve(uctx->client, - &primary, - uctx->rdclass, - dns_rdatatype_aaaa, - resoptions, - uctx->client->task, - resolveaddr_done, - &uctx->bp6, - &uctx->restrans2); - } - UNLOCK(&uctx->lock); - } - - out: - dns_rdata_freestruct(&soa); - - return (result); -} - -static void -receive_soa(isc_task_t *task, isc_event_t *event) { - dns_requestevent_t *reqev = NULL; - updatectx_t *uctx; - dns_client_t *client; - isc_result_t result, eresult; - dns_request_t *request; - dns_message_t *rcvmsg = NULL; - dns_section_t section; - dns_rdataset_t *soaset = NULL; - int pass = 0; - dns_name_t *name; - dns_message_t *soaquery = NULL; - isc_sockaddr_t *addr; - bool seencname = false; - bool droplabel = false; - dns_name_t tname; - unsigned int nlabels, reqoptions; - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); - reqev = (dns_requestevent_t *)event; - request = reqev->request; - result = eresult = reqev->result; - POST(result); - uctx = reqev->ev_arg; - client = uctx->client; - soaquery = uctx->soaquery; - addr = uctx->currentserver; - INSIST(addr != NULL); - - isc_event_free(&event); - - if (eresult != ISC_R_SUCCESS) { - result = eresult; - goto out; - } - - result = dns_message_create(uctx->client->mctx, - DNS_MESSAGE_INTENTPARSE, &rcvmsg); - if (result != ISC_R_SUCCESS) - goto out; - result = dns_request_getresponse(request, rcvmsg, - DNS_MESSAGEPARSE_PRESERVEORDER); - - if (result == DNS_R_TSIGERRORSET) { - dns_request_t *newrequest = NULL; - - /* Retry SOA request without TSIG */ - dns_message_detach(&rcvmsg); - dns_message_renderreset(uctx->soaquery); - reqoptions = 0; - if (uctx->want_tcp) - reqoptions |= DNS_REQUESTOPT_TCP; - result = dns_request_createvia3(uctx->view->requestmgr, - uctx->soaquery, NULL, addr, - reqoptions, NULL, - client->find_timeout * 20, - client->find_timeout, 3, - uctx->client->task, - receive_soa, uctx, - &newrequest); - if (result == ISC_R_SUCCESS) { - LOCK(&uctx->lock); - dns_request_destroy(&uctx->soareq); - uctx->soareq = newrequest; - UNLOCK(&uctx->lock); - - return; - } - goto out; - } - - section = DNS_SECTION_ANSWER; - POST(section); - - if (rcvmsg->rcode != dns_rcode_noerror && - rcvmsg->rcode != dns_rcode_nxdomain) { - result = rcode2result(rcvmsg->rcode); - goto out; - } - - lookforsoa: - if (pass == 0) - section = DNS_SECTION_ANSWER; - else if (pass == 1) - section = DNS_SECTION_AUTHORITY; - else { - droplabel = true; - goto out; - } - - result = dns_message_firstname(rcvmsg, section); - if (result != ISC_R_SUCCESS) { - pass++; - goto lookforsoa; - } - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(rcvmsg, section, &name); - soaset = NULL; - result = dns_message_findtype(name, dns_rdatatype_soa, 0, - &soaset); - if (result == ISC_R_SUCCESS) - break; - if (section == DNS_SECTION_ANSWER) { - dns_rdataset_t *tset = NULL; - if (dns_message_findtype(name, dns_rdatatype_cname, 0, - &tset) == ISC_R_SUCCESS - || - dns_message_findtype(name, dns_rdatatype_dname, 0, - &tset) == ISC_R_SUCCESS - ) - { - seencname = true; - break; - } - } - - result = dns_message_nextname(rcvmsg, section); - } - - if (soaset == NULL && !seencname) { - pass++; - goto lookforsoa; - } - - if (seencname) { - droplabel = true; - goto out; - } - - result = process_soa(uctx, soaset, name); - - out: - if (droplabel) { - result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - name = NULL; - dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); - nlabels = dns_name_countlabels(name); - if (nlabels == 1) - result = DNS_R_SERVFAIL; /* is there a better error? */ - else { - dns_name_init(&tname, NULL); - dns_name_getlabelsequence(name, 1, nlabels - 1, - &tname); - dns_name_clone(&tname, name); - dns_request_destroy(&request); - LOCK(&uctx->lock); - uctx->soareq = NULL; - UNLOCK(&uctx->lock); - dns_message_renderreset(soaquery); - dns_message_settsigkey(soaquery, NULL); - reqoptions = 0; - if (uctx->want_tcp) - reqoptions |= DNS_REQUESTOPT_TCP; - result = dns_request_createvia3(uctx->view->requestmgr, - soaquery, NULL, - uctx->currentserver, - reqoptions, - uctx->tsigkey, - client->find_timeout * - 20, - client->find_timeout, - 3, client->task, - receive_soa, uctx, - &uctx->soareq); - } - } - - if (!droplabel || result != ISC_R_SUCCESS) { - dns_message_detach(&uctx->soaquery); - LOCK(&uctx->lock); - dns_request_destroy(&uctx->soareq); - UNLOCK(&uctx->lock); - } - - if (rcvmsg != NULL) - dns_message_detach(&rcvmsg); - - if (result != ISC_R_SUCCESS) - update_sendevent(uctx, result); -} - -static isc_result_t -request_soa(updatectx_t *uctx) { - isc_result_t result; - dns_message_t *soaquery = uctx->soaquery; - dns_name_t *name = NULL; - dns_rdataset_t *rdataset = NULL; - unsigned int reqoptions; - - if (soaquery == NULL) { - result = dns_message_create(uctx->client->mctx, - DNS_MESSAGE_INTENTRENDER, - &soaquery); - if (result != ISC_R_SUCCESS) - return (result); - } - soaquery->flags |= DNS_MESSAGEFLAG_RD; - result = dns_message_gettempname(soaquery, &name); - if (result != ISC_R_SUCCESS) - goto fail; - result = dns_message_gettemprdataset(soaquery, &rdataset); - if (result != ISC_R_SUCCESS) - goto fail; - dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa); - dns_name_clone(uctx->firstname, name); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); - rdataset = NULL; - name = NULL; - reqoptions = 0; - if (uctx->want_tcp) - reqoptions |= DNS_REQUESTOPT_TCP; - - result = dns_request_createvia3(uctx->view->requestmgr, - soaquery, NULL, uctx->currentserver, - reqoptions, uctx->tsigkey, - uctx->client->find_timeout * 20, - uctx->client->find_timeout, 3, - uctx->client->task, receive_soa, uctx, - &uctx->soareq); - if (result == ISC_R_SUCCESS) { - uctx->soaquery = soaquery; - return (ISC_R_SUCCESS); - } - - fail: - if (rdataset != NULL) { - ISC_LIST_UNLINK(name->list, rdataset, link); /* for safety */ - dns_message_puttemprdataset(soaquery, &rdataset); - } - if (name != NULL) - dns_message_puttempname(soaquery, &name); - dns_message_detach(&soaquery); - - return (result); -} - -static void -resolvesoa_done(isc_task_t *task, isc_event_t *event) { - dns_clientresevent_t *rev = (dns_clientresevent_t *)event; - updatectx_t *uctx; - dns_name_t *name, tname; - dns_rdataset_t *rdataset = NULL; - isc_result_t result = rev->result; - unsigned int nlabels, resoptions; - - UNUSED(task); - - uctx = event->ev_arg; - REQUIRE(UCTX_VALID(uctx)); - - LOCK(&uctx->lock); - dns_client_destroyrestrans(&uctx->restrans); - UNLOCK(&uctx->lock); - - uctx = event->ev_arg; - if (result != ISC_R_SUCCESS && - result != DNS_R_NCACHENXDOMAIN && - result != DNS_R_NCACHENXRRSET) { - /* XXX: what about DNSSEC failure? */ - goto out; - } - - for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; - name = ISC_LIST_NEXT(name, link)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (dns_rdataset_isassociated(rdataset) && - rdataset->type == dns_rdatatype_soa) - break; - } - } - - if (rdataset == NULL) { - /* Drop one label and retry resolution. */ - nlabels = dns_name_countlabels(&uctx->soaqname); - if (nlabels == 1) { - result = DNS_R_SERVFAIL; /* is there a better error? */ - goto out; - } - dns_name_init(&tname, NULL); - dns_name_getlabelsequence(&uctx->soaqname, 1, nlabels - 1, - &tname); - dns_name_clone(&tname, &uctx->soaqname); - resoptions = 0; - if (uctx->want_tcp) - resoptions |= DNS_CLIENTRESOPT_TCP; - - result = dns_client_startresolve(uctx->client, &uctx->soaqname, - uctx->rdclass, - dns_rdatatype_soa, - resoptions, - uctx->client->task, - resolvesoa_done, uctx, - &uctx->restrans); - } else - result = process_soa(uctx, rdataset, &uctx->soaqname); - - out: - dns_client_freeresanswer(uctx->client, &rev->answerlist); - isc_event_free(&event); - - if (result != ISC_R_SUCCESS) - update_sendevent(uctx, result); -} - -static isc_result_t -copy_name(isc_mem_t *mctx, dns_message_t *msg, dns_name_t *name, - dns_name_t **newnamep) -{ - isc_result_t result; - dns_name_t *newname = NULL; - isc_region_t r; - isc_buffer_t *namebuf = NULL, *rdatabuf = NULL; - dns_rdatalist_t *rdatalist; - dns_rdataset_t *rdataset, *newrdataset; - dns_rdata_t rdata = DNS_RDATA_INIT, *newrdata; - - result = dns_message_gettempname(msg, &newname); - if (result != ISC_R_SUCCESS) - return (result); - result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - goto fail; - dns_name_init(newname, NULL); - dns_name_setbuffer(newname, namebuf); - dns_message_takebuffer(msg, &namebuf); - result = dns_name_copy(name, newname, NULL); - if (result != ISC_R_SUCCESS) - goto fail; - - for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - rdatalist = NULL; - result = dns_message_gettemprdatalist(msg, &rdatalist); - if (result != ISC_R_SUCCESS) - goto fail; - dns_rdatalist_init(rdatalist); - rdatalist->type = rdataset->type; - rdatalist->rdclass = rdataset->rdclass; - rdatalist->covers = rdataset->covers; - rdatalist->ttl = rdataset->ttl; - - result = dns_rdataset_first(rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - - newrdata = NULL; - result = dns_message_gettemprdata(msg, &newrdata); - if (result != ISC_R_SUCCESS) - goto fail; - dns_rdata_toregion(&rdata, &r); - rdatabuf = NULL; - result = isc_buffer_allocate(mctx, &rdatabuf, - r.length); - if (result != ISC_R_SUCCESS) - goto fail; - isc_buffer_putmem(rdatabuf, r.base, r.length); - isc_buffer_usedregion(rdatabuf, &r); - dns_rdata_init(newrdata); - dns_rdata_fromregion(newrdata, rdata.rdclass, - rdata.type, &r); - newrdata->flags = rdata.flags; - - ISC_LIST_APPEND(rdatalist->rdata, newrdata, link); - dns_message_takebuffer(msg, &rdatabuf); - - result = dns_rdataset_next(rdataset); - } - - newrdataset = NULL; - result = dns_message_gettemprdataset(msg, &newrdataset); - if (result != ISC_R_SUCCESS) - goto fail; - dns_rdatalist_tordataset(rdatalist, newrdataset); - - ISC_LIST_APPEND(newname->list, newrdataset, link); - } - - *newnamep = newname; - - return (ISC_R_SUCCESS); - - fail: - dns_message_puttempname(msg, &newname); - - return (result); - -} - -static void -internal_update_callback(isc_task_t *task, isc_event_t *event) { - updatearg_t *uarg = event->ev_arg; - dns_clientupdateevent_t *uev = (dns_clientupdateevent_t *)event; - - UNUSED(task); - - LOCK(&uarg->lock); - - uarg->result = uev->result; - - dns_client_destroyupdatetrans(&uarg->trans); - isc_event_free(&event); - - if (!uarg->canceled) { - UNLOCK(&uarg->lock); - - /* Exit from the internal event loop */ - isc_app_ctxsuspend(uarg->actx); - } else { - /* - * We have already exited from the loop (due to some - * unexpected event). Just clean the arg up. - */ - UNLOCK(&uarg->lock); - DESTROYLOCK(&uarg->lock); - isc_mem_put(uarg->client->mctx, uarg, sizeof(*uarg)); - } -} - -isc_result_t -dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *zonename, dns_namelist_t *prerequisites, - dns_namelist_t *updates, isc_sockaddrlist_t *servers, - dns_tsec_t *tsec, unsigned int options) -{ - isc_result_t result; - isc_appctx_t *actx; - updatearg_t *uarg; - - REQUIRE(DNS_CLIENT_VALID(client)); - - if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && - (options & DNS_CLIENTUPDOPT_ALLOWRUN) == 0) { - /* - * If the client is run under application's control, we need - * to create a new running (sub)environment for this - * particular update. - */ - return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ - } else - actx = client->actx; - - uarg = isc_mem_get(client->mctx, sizeof(*uarg)); - if (uarg == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&uarg->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(client->mctx, uarg, sizeof(*uarg)); - return (result); - } - - uarg->actx = actx; - uarg->client = client; - uarg->result = ISC_R_FAILURE; - uarg->trans = NULL; - uarg->canceled = false; - - result = dns_client_startupdate(client, rdclass, zonename, - prerequisites, updates, servers, - tsec, options, client->task, - internal_update_callback, uarg, - &uarg->trans); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&uarg->lock); - isc_mem_put(client->mctx, uarg, sizeof(*uarg)); - return (result); - } - - /* - * Start internal event loop. It blocks until the entire process - * is completed. - */ - result = isc_app_ctxrun(actx); - - LOCK(&uarg->lock); - if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) - result = uarg->result; - - if (uarg->trans != NULL) { - /* - * Unusual termination (perhaps due to signal). We need some - * tricky cleanup process. - */ - uarg->canceled = true; - dns_client_cancelupdate(uarg->trans); - - UNLOCK(&uarg->lock); - - /* uarg will be freed in the event handler. */ - } else { - UNLOCK(&uarg->lock); - - DESTROYLOCK(&uarg->lock); - isc_mem_put(client->mctx, uarg, sizeof(*uarg)); - } - - return (result); -} - -static void -startupdate(isc_task_t *task, isc_event_t *event) { - updatectx_t *uctx; - isc_result_t result; - unsigned int resoptions; - - REQUIRE(event != NULL); - - UNUSED(task); - - uctx = event->ev_arg; - - if (uctx->zonename != NULL && uctx->currentserver != NULL) { - result = send_update(uctx); - if (result != ISC_R_SUCCESS) - goto fail; - } else if (uctx->currentserver != NULL) { - result = request_soa(uctx); - if (result != ISC_R_SUCCESS) - goto fail; - } else { - resoptions = 0; - if (uctx->want_tcp) - resoptions |= DNS_CLIENTRESOPT_TCP; - dns_name_clone(uctx->firstname, &uctx->soaqname); - result = dns_client_startresolve(uctx->client, &uctx->soaqname, - uctx->rdclass, - dns_rdatatype_soa, resoptions, - uctx->client->task, - resolvesoa_done, uctx, - &uctx->restrans); - if (result != ISC_R_SUCCESS) - goto fail; - } - - isc_event_free(&event); - -fail: - if (result != ISC_R_SUCCESS) - update_sendevent(uctx, result); -} - -isc_result_t -dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *zonename, dns_namelist_t *prerequisites, - dns_namelist_t *updates, isc_sockaddrlist_t *servers, - dns_tsec_t *tsec, unsigned int options, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_clientupdatetrans_t **transp) -{ - dns_view_t *view = NULL; - isc_result_t result; - dns_name_t *name, *newname; - updatectx_t *uctx; - isc_task_t *tclone = NULL; - dns_section_t section = DNS_SECTION_UPDATE; - isc_sockaddr_t *server, *sa = NULL; - dns_tsectype_t tsectype = dns_tsectype_none; - bool want_tcp; - - UNUSED(options); - - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(transp != NULL && *transp == NULL); - REQUIRE(updates != NULL); - REQUIRE(task != NULL); - - if (tsec != NULL) { - tsectype = dns_tsec_gettype(tsec); - if (tsectype != dns_tsectype_tsig) - return (ISC_R_NOTIMPLEMENTED); /* XXX */ - } - - LOCK(&client->lock); - result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, - rdclass, &view); - UNLOCK(&client->lock); - if (result != ISC_R_SUCCESS) - return (result); - - want_tcp = ((options & DNS_CLIENTUPDOPT_TCP) != 0); - - /* - * Create a context and prepare some resources. - */ - - uctx = isc_mem_get(client->mctx, sizeof(*uctx)); - if (uctx == NULL) { - dns_view_detach(&view); - return (ISC_R_NOMEMORY); - } - - result = isc_mutex_init(&uctx->lock); - if (result != ISC_R_SUCCESS) { - dns_view_detach(&view); - isc_mem_put(client->mctx, uctx, sizeof(*uctx)); - return (ISC_R_NOMEMORY); - } - - tclone = NULL; - isc_task_attach(task, &tclone); - uctx->client = client; - ISC_LINK_INIT(uctx, link); - uctx->state = dns_clientupdatestate_prepare; - uctx->view = view; - uctx->rdclass = rdclass; - uctx->canceled = false; - uctx->updatemsg = NULL; - uctx->soaquery = NULL; - uctx->updatereq = NULL; - uctx->restrans = NULL; - uctx->restrans2 = NULL; - uctx->bp4 = NULL; - uctx->bp6 = NULL; - uctx->soareq = NULL; - uctx->event = NULL; - uctx->tsigkey = NULL; - uctx->sig0key = NULL; - uctx->zonename = NULL; - uctx->want_tcp = want_tcp; - dns_name_init(&uctx->soaqname, NULL); - ISC_LIST_INIT(uctx->servers); - uctx->nservers = 0; - uctx->currentserver = NULL; - dns_fixedname_init(&uctx->zonefname); - if (tsec != NULL) - dns_tsec_getkey(tsec, &uctx->tsigkey); - uctx->event = (dns_clientupdateevent_t *) - isc_event_allocate(client->mctx, tclone, DNS_EVENT_UPDATEDONE, - action, arg, sizeof(*uctx->event)); - if (uctx->event == NULL) - goto fail; - if (zonename != NULL) { - uctx->zonename = dns_fixedname_name(&uctx->zonefname); - result = dns_name_copy(zonename, uctx->zonename, NULL); - } - if (servers != NULL) { - for (server = ISC_LIST_HEAD(*servers); - server != NULL; - server = ISC_LIST_NEXT(server, link)) { - sa = isc_mem_get(client->mctx, sizeof(*sa)); - if (sa == NULL) - goto fail; - sa->type = server->type; - sa->length = server->length; - ISC_LINK_INIT(sa, link); - ISC_LIST_APPEND(uctx->servers, sa, link); - if (uctx->currentserver == NULL) - uctx->currentserver = sa; - uctx->nservers++; - } - } - - /* Make update message */ - result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER, - &uctx->updatemsg); - if (result != ISC_R_SUCCESS) - goto fail; - uctx->updatemsg->opcode = dns_opcode_update; - - if (prerequisites != NULL) { - for (name = ISC_LIST_HEAD(*prerequisites); name != NULL; - name = ISC_LIST_NEXT(name, link)) { - newname = NULL; - result = copy_name(client->mctx, uctx->updatemsg, - name, &newname); - if (result != ISC_R_SUCCESS) - goto fail; - dns_message_addname(uctx->updatemsg, newname, - DNS_SECTION_PREREQUISITE); - } - } - - for (name = ISC_LIST_HEAD(*updates); name != NULL; - name = ISC_LIST_NEXT(name, link)) { - newname = NULL; - result = copy_name(client->mctx, uctx->updatemsg, name, - &newname); - if (result != ISC_R_SUCCESS) - goto fail; - dns_message_addname(uctx->updatemsg, newname, - DNS_SECTION_UPDATE); - } - - uctx->firstname = NULL; - result = dns_message_firstname(uctx->updatemsg, section); - if (result == ISC_R_NOMORE) { - section = DNS_SECTION_PREREQUISITE; - result = dns_message_firstname(uctx->updatemsg, section); - } - if (result != ISC_R_SUCCESS) - goto fail; - dns_message_currentname(uctx->updatemsg, section, &uctx->firstname); - - uctx->magic = UCTX_MAGIC; - - LOCK(&client->lock); - ISC_LIST_APPEND(client->updatectxs, uctx, link); - isc_refcount_increment(&client->references, NULL); - UNLOCK(&client->lock); - - *transp = (dns_clientupdatetrans_t *)uctx; - result = isc_app_ctxonrun(client->actx, client->mctx, client->task, - startupdate, uctx); - if (result == ISC_R_ALREADYRUNNING) { - isc_event_t *event; - event = isc_event_allocate(client->mctx, dns_client_startupdate, - DNS_EVENT_STARTUPDATE, startupdate, - uctx, sizeof(*event)); - if (event != NULL) { - result = ISC_R_SUCCESS; - isc_task_send(task, &event); - } else - result = ISC_R_NOMEMORY; - } - if (result == ISC_R_SUCCESS) - return (result); - - isc_refcount_decrement(&client->references, NULL); - *transp = NULL; - - fail: - if (ISC_LINK_LINKED(uctx, link)) { - LOCK(&client->lock); - ISC_LIST_UNLINK(client->updatectxs, uctx, link); - UNLOCK(&client->lock); - } - if (uctx->updatemsg != NULL) - dns_message_detach(&uctx->updatemsg); - while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) { - ISC_LIST_UNLINK(uctx->servers, sa, link); - isc_mem_put(client->mctx, sa, sizeof(*sa)); - } - if (uctx->event != NULL) - isc_event_free(ISC_EVENT_PTR(&uctx->event)); - if (uctx->tsigkey != NULL) - dns_tsigkey_detach(&uctx->tsigkey); - isc_task_detach(&tclone); - DESTROYLOCK(&uctx->lock); - uctx->magic = 0; - isc_mem_put(client->mctx, uctx, sizeof(*uctx)); - dns_view_detach(&view); - - return (result); -} - -void -dns_client_cancelupdate(dns_clientupdatetrans_t *trans) { - updatectx_t *uctx; - - REQUIRE(trans != NULL); - uctx = (updatectx_t *)trans; - REQUIRE(UCTX_VALID(uctx)); - - LOCK(&uctx->lock); - - if (!uctx->canceled) { - uctx->canceled = true; - if (uctx->updatereq != NULL) - dns_request_cancel(uctx->updatereq); - if (uctx->soareq != NULL) - dns_request_cancel(uctx->soareq); - if (uctx->restrans != NULL) - dns_client_cancelresolve(uctx->restrans); - if (uctx->restrans2 != NULL) - dns_client_cancelresolve(uctx->restrans2); - } - - UNLOCK(&uctx->lock); -} - -void -dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) { - updatectx_t *uctx; - isc_mem_t *mctx; - dns_client_t *client; - isc_sockaddr_t *sa; - - REQUIRE(transp != NULL); - uctx = (updatectx_t *)*transp; - *transp = NULL; - REQUIRE(UCTX_VALID(uctx)); - client = uctx->client; - REQUIRE(DNS_CLIENT_VALID(client)); - REQUIRE(uctx->updatereq == NULL && uctx->updatemsg == NULL && - uctx->soareq == NULL && uctx->soaquery == NULL && - uctx->event == NULL && uctx->tsigkey == NULL && - uctx->sig0key == NULL); - - mctx = client->mctx; - dns_view_detach(&uctx->view); - while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) { - ISC_LIST_UNLINK(uctx->servers, sa, link); - isc_mem_put(mctx, sa, sizeof(*sa)); - } - - LOCK(&client->lock); - - INSIST(ISC_LINK_LINKED(uctx, link)); - ISC_LIST_UNLINK(client->updatectxs, uctx, link); - - UNLOCK(&client->lock); - - DESTROYLOCK(&uctx->lock); - uctx->magic = 0; - - isc_mem_put(mctx, uctx, sizeof(*uctx)); - - dns_client_destroy(&client); -} - -isc_mem_t * -dns_client_mctx(dns_client_t *client) { - - REQUIRE(DNS_CLIENT_VALID(client)); - return (client->mctx); -} - -typedef struct { - isc_buffer_t buffer; - dns_rdataset_t rdataset; - dns_rdatalist_t rdatalist; - dns_rdata_t rdata; - size_t size; - isc_mem_t * mctx; - unsigned char data[FLEXIBLE_ARRAY_MEMBER]; -} dns_client_updaterec_t; - -isc_result_t -dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner, - dns_rdatatype_t type, dns_rdata_t *source, - dns_ttl_t ttl, dns_name_t *target, - dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist, - dns_rdata_t *rdata, isc_mem_t *mctx) -{ - dns_client_updaterec_t *updaterec = NULL; - size_t size = offsetof(dns_client_updaterec_t, data); - - REQUIRE(op < updateop_max); - REQUIRE(owner != NULL); - REQUIRE((rdataset != NULL && rdatalist != NULL && rdata != NULL) || - (rdataset == NULL && rdatalist == NULL && rdata == NULL && - mctx != NULL)); - if (op == updateop_add) - REQUIRE(source != NULL); - if (source != NULL) { - REQUIRE(source->type == type); - REQUIRE(op == updateop_add || op == updateop_delete || - op == updateop_exist); - } - - size += owner->length; - if (source != NULL) - size += source->length; - - if (rdataset == NULL) { - updaterec = isc_mem_get(mctx, size); - if (updaterec == NULL) - return (ISC_R_NOMEMORY); - rdataset = &updaterec->rdataset; - rdatalist = &updaterec->rdatalist; - rdata = &updaterec->rdata; - dns_rdataset_init(rdataset); - dns_rdatalist_init(&updaterec->rdatalist); - dns_rdata_init(&updaterec->rdata); - isc_buffer_init(&updaterec->buffer, updaterec->data, - (unsigned int) - (size - - offsetof(dns_client_updaterec_t, data))); - dns_name_copy(owner, target, &updaterec->buffer); - if (source != NULL) { - isc_region_t r; - dns_rdata_clone(source, rdata); - dns_rdata_toregion(rdata, &r); - rdata->data = isc_buffer_used(&updaterec->buffer); - isc_buffer_copyregion(&updaterec->buffer, &r); - } - updaterec->mctx = NULL; - isc_mem_attach(mctx, &updaterec->mctx); - } else if (source != NULL) - dns_rdata_clone(source, rdata); - - switch (op) { - case updateop_add: - break; - case updateop_delete: - if (source != NULL) { - ttl = 0; - dns_rdata_makedelete(rdata); - } else - dns_rdata_deleterrset(rdata, type); - break; - case updateop_notexist: - dns_rdata_notexist(rdata, type); - break; - case updateop_exist: - if (source == NULL) { - ttl = 0; - dns_rdata_exists(rdata, type); - } - case updateop_none: - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - rdatalist->type = rdata->type; - rdatalist->rdclass = rdata->rdclass; - if (source != NULL) { - rdatalist->covers = dns_rdata_covers(rdata); - rdatalist->ttl = ttl; - } - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - dns_rdatalist_tordataset(rdatalist, rdataset); - ISC_LIST_APPEND(target->list, rdataset, link); - if (updaterec != NULL) { - target->attributes |= DNS_NAMEATTR_HASUPDATEREC; - dns_name_setbuffer(target, &updaterec->buffer); - } - if (op == updateop_add || op == updateop_delete) - target->attributes |= DNS_NAMEATTR_UPDATE; - else - target->attributes |= DNS_NAMEATTR_PREREQUISITE; - return (ISC_R_SUCCESS); -} - -void -dns_client_freeupdate(dns_name_t **namep) { - dns_client_updaterec_t *updaterec; - dns_rdatalist_t *rdatalist; - dns_rdataset_t *rdataset; - dns_rdata_t *rdata; - dns_name_t *name; - - REQUIRE(namep != NULL && *namep != NULL); - - name = *namep; - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_HEAD(name->list)) { - ISC_LIST_UNLINK(name->list, rdataset, link); - rdatalist = NULL; - dns_rdatalist_fromrdataset(rdataset, &rdatalist); - if (rdatalist == NULL) { - dns_rdataset_disassociate(rdataset); - continue; - } - for (rdata = ISC_LIST_HEAD(rdatalist->rdata); - rdata != NULL; - rdata = ISC_LIST_HEAD(rdatalist->rdata)) - ISC_LIST_UNLINK(rdatalist->rdata, rdata, link); - dns_rdataset_disassociate(rdataset); - } - - if ((name->attributes & DNS_NAMEATTR_HASUPDATEREC) != 0) { - updaterec = (dns_client_updaterec_t *)name->buffer; - INSIST(updaterec != NULL); - isc_mem_putanddetach(&updaterec->mctx, updaterec, - updaterec->size); - *namep = NULL; - } -} diff --git a/lib/dns-pkcs11/clientinfo.c b/lib/dns-pkcs11/clientinfo.c deleted file mode 100644 index 32f7edd..0000000 --- a/lib/dns-pkcs11/clientinfo.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include "config.h" - -#include - -void -dns_clientinfomethods_init(dns_clientinfomethods_t *methods, - dns_clientinfo_sourceip_t sourceip) -{ - methods->version = DNS_CLIENTINFOMETHODS_VERSION; - methods->age = DNS_CLIENTINFOMETHODS_AGE; - methods->sourceip = sourceip; -} - -void -dns_clientinfo_init(dns_clientinfo_t *ci, void *data, void *versionp) { - ci->version = DNS_CLIENTINFO_VERSION; - ci->data = data; - ci->dbversion = versionp; -} diff --git a/lib/dns-pkcs11/compress.c b/lib/dns-pkcs11/compress.c deleted file mode 100644 index 63da24e..0000000 --- a/lib/dns-pkcs11/compress.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#define DNS_NAME_USEINLINE 1 - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define CCTX_MAGIC ISC_MAGIC('C', 'C', 'T', 'X') -#define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC) - -#define DCTX_MAGIC ISC_MAGIC('D', 'C', 'T', 'X') -#define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC) - -#define TABLE_READY \ - do { \ - unsigned int i; \ - \ - if ((cctx->allowed & DNS_COMPRESS_READY) == 0) { \ - cctx->allowed |= DNS_COMPRESS_READY; \ - for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) \ - cctx->table[i] = NULL; \ - } \ - } while (0) - -/*** - *** Compression - ***/ - -isc_result_t -dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) { - REQUIRE(cctx != NULL); - REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */ - - cctx->edns = edns; - cctx->mctx = mctx; - cctx->count = 0; - cctx->allowed = DNS_COMPRESS_ENABLED; - cctx->magic = CCTX_MAGIC; - return (ISC_R_SUCCESS); -} - -void -dns_compress_invalidate(dns_compress_t *cctx) { - dns_compressnode_t *node; - unsigned int i; - - REQUIRE(VALID_CCTX(cctx)); - - if ((cctx->allowed & DNS_COMPRESS_READY) != 0) { - for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { - while (cctx->table[i] != NULL) { - node = cctx->table[i]; - cctx->table[i] = cctx->table[i]->next; - if ((node->offset & 0x8000) != 0) - isc_mem_put(cctx->mctx, node->r.base, - node->r.length); - if (node->count < DNS_COMPRESS_INITIALNODES) - continue; - isc_mem_put(cctx->mctx, node, sizeof(*node)); - } - } - } - cctx->magic = 0; - cctx->allowed = 0; - cctx->edns = -1; -} - -void -dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) { - REQUIRE(VALID_CCTX(cctx)); - - cctx->allowed &= ~DNS_COMPRESS_ALL; - cctx->allowed |= (allowed & DNS_COMPRESS_ALL); -} - -unsigned int -dns_compress_getmethods(dns_compress_t *cctx) { - REQUIRE(VALID_CCTX(cctx)); - return (cctx->allowed & DNS_COMPRESS_ALL); -} - -void -dns_compress_disable(dns_compress_t *cctx) { - REQUIRE(VALID_CCTX(cctx)); - cctx->allowed &= ~DNS_COMPRESS_ENABLED; -} - -void -dns_compress_setsensitive(dns_compress_t *cctx, bool sensitive) { - REQUIRE(VALID_CCTX(cctx)); - - if (sensitive) - cctx->allowed |= DNS_COMPRESS_CASESENSITIVE; - else - cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE; -} - -bool -dns_compress_getsensitive(dns_compress_t *cctx) { - REQUIRE(VALID_CCTX(cctx)); - - return (cctx->allowed & DNS_COMPRESS_CASESENSITIVE); -} - -int -dns_compress_getedns(dns_compress_t *cctx) { - REQUIRE(VALID_CCTX(cctx)); - return (cctx->edns); -} - -#define NODENAME(node, name) \ -do { \ - (name)->length = (node)->r.length; \ - (name)->labels = (node)->labels; \ - (name)->ndata = (node)->r.base; \ - (name)->attributes = DNS_NAMEATTR_ABSOLUTE; \ -} while (0) - -/* - * Find the longest match of name in the table. - * If match is found return true. prefix, suffix and offset are updated. - * If no match is found return false. - */ -bool -dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, - dns_name_t *prefix, uint16_t *offset) -{ - dns_name_t tname, nname; - dns_compressnode_t *node = NULL; - unsigned int labels, hash, n; - - REQUIRE(VALID_CCTX(cctx)); - REQUIRE(dns_name_isabsolute(name) == true); - REQUIRE(offset != NULL); - - if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) - return (false); - - TABLE_READY; - - if (cctx->count == 0) - return (false); - - labels = dns_name_countlabels(name); - INSIST(labels > 0); - - dns_name_init(&tname, NULL); - dns_name_init(&nname, NULL); - - for (n = 0; n < labels - 1; n++) { - dns_name_getlabelsequence(name, n, labels - n, &tname); - hash = dns_name_hash(&tname, false) % - DNS_COMPRESS_TABLESIZE; - for (node = cctx->table[hash]; node != NULL; node = node->next) - { - NODENAME(node, &nname); - if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) { - if (dns_name_caseequal(&nname, &tname)) - break; - } else { - if (dns_name_equal(&nname, &tname)) - break; - } - } - if (node != NULL) - break; - } - - /* - * If node == NULL, we found no match at all. - */ - if (node == NULL) - return (false); - - if (n == 0) - dns_name_reset(prefix); - else - dns_name_getlabelsequence(name, 0, n, prefix); - - *offset = (node->offset & 0x7fff); - return (true); -} - -static inline unsigned int -name_length(const dns_name_t *name) { - isc_region_t r; - dns_name_toregion(name, &r); - return (r.length); -} - -void -dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, - const dns_name_t *prefix, uint16_t offset) -{ - dns_name_t tname, xname; - unsigned int start; - unsigned int n; - unsigned int count; - unsigned int hash; - dns_compressnode_t *node; - unsigned int length; - unsigned int tlength; - uint16_t toffset; - unsigned char *tmp; - isc_region_t r; - - REQUIRE(VALID_CCTX(cctx)); - REQUIRE(dns_name_isabsolute(name)); - - if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) - return; - - TABLE_READY; - - if (offset >= 0x4000) - return; - dns_name_init(&tname, NULL); - dns_name_init(&xname, NULL); - - n = dns_name_countlabels(name); - count = dns_name_countlabels(prefix); - if (dns_name_isabsolute(prefix)) - count--; - if (count == 0) - return; - start = 0; - dns_name_toregion(name, &r); - length = r.length; - tmp = isc_mem_get(cctx->mctx, length); - if (tmp == NULL) - return; - /* - * Copy name data to 'tmp' and make 'r' use 'tmp'. - */ - memmove(tmp, r.base, r.length); - r.base = tmp; - dns_name_fromregion(&xname, &r); - - while (count > 0) { - dns_name_getlabelsequence(&xname, start, n, &tname); - hash = dns_name_hash(&tname, false) % - DNS_COMPRESS_TABLESIZE; - tlength = name_length(&tname); - toffset = (uint16_t)(offset + (length - tlength)); - if (toffset >= 0x4000) - break; - /* - * Create a new node and add it. - */ - if (cctx->count < DNS_COMPRESS_INITIALNODES) - node = &cctx->initialnodes[cctx->count]; - else { - node = isc_mem_get(cctx->mctx, - sizeof(dns_compressnode_t)); - if (node == NULL) - break; - } - node->count = cctx->count++; - /* - * 'node->r.base' becomes 'tmp' when start == 0. - * Record this by setting 0x8000 so it can be freed later. - */ - if (start == 0) - toffset |= 0x8000; - node->offset = toffset; - dns_name_toregion(&tname, &node->r); - node->labels = (uint8_t)dns_name_countlabels(&tname); - node->next = cctx->table[hash]; - cctx->table[hash] = node; - start++; - n--; - count--; - } - - if (start == 0) - isc_mem_put(cctx->mctx, tmp, length); -} - -void -dns_compress_rollback(dns_compress_t *cctx, uint16_t offset) { - unsigned int i; - dns_compressnode_t *node; - - REQUIRE(VALID_CCTX(cctx)); - - if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) - return; - - if ((cctx->allowed & DNS_COMPRESS_READY) == 0) - return; - - for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { - node = cctx->table[i]; - /* - * This relies on nodes with greater offsets being - * closer to the beginning of the list, and the - * items with the greatest offsets being at the end - * of the initialnodes[] array. - */ - while (node != NULL && (node->offset & 0x7fff) >= offset) { - cctx->table[i] = node->next; - if ((node->offset & 0x8000) != 0) - isc_mem_put(cctx->mctx, node->r.base, - node->r.length); - if (node->count >= DNS_COMPRESS_INITIALNODES) - isc_mem_put(cctx->mctx, node, sizeof(*node)); - cctx->count--; - node = cctx->table[i]; - } - } -} - -/*** - *** Decompression - ***/ - -void -dns_decompress_init(dns_decompress_t *dctx, int edns, - dns_decompresstype_t type) { - - REQUIRE(dctx != NULL); - REQUIRE(edns >= -1 && edns <= 255); - - dctx->allowed = DNS_COMPRESS_NONE; - dctx->edns = edns; - dctx->type = type; - dctx->magic = DCTX_MAGIC; -} - -void -dns_decompress_invalidate(dns_decompress_t *dctx) { - - REQUIRE(VALID_DCTX(dctx)); - - dctx->magic = 0; -} - -void -dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed) { - - REQUIRE(VALID_DCTX(dctx)); - - switch (dctx->type) { - case DNS_DECOMPRESS_ANY: - dctx->allowed = DNS_COMPRESS_ALL; - break; - case DNS_DECOMPRESS_NONE: - dctx->allowed = DNS_COMPRESS_NONE; - break; - case DNS_DECOMPRESS_STRICT: - dctx->allowed = allowed; - break; - } -} - -unsigned int -dns_decompress_getmethods(dns_decompress_t *dctx) { - - REQUIRE(VALID_DCTX(dctx)); - - return (dctx->allowed); -} - -int -dns_decompress_edns(dns_decompress_t *dctx) { - - REQUIRE(VALID_DCTX(dctx)); - - return (dctx->edns); -} - -dns_decompresstype_t -dns_decompress_type(dns_decompress_t *dctx) { - - REQUIRE(VALID_DCTX(dctx)); - - return (dctx->type); -} diff --git a/lib/dns-pkcs11/db.c b/lib/dns-pkcs11/db.c deleted file mode 100644 index c581646..0000000 --- a/lib/dns-pkcs11/db.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*** - *** Private Types - ***/ - -struct dns_dbimplementation { - const char * name; - dns_dbcreatefunc_t create; - isc_mem_t * mctx; - void * driverarg; - ISC_LINK(dns_dbimplementation_t) link; -}; - -/*** - *** Supported DB Implementations Registry - ***/ - -/* - * Built in database implementations are registered here. - */ - -#include "rbtdb.h" -#include "rbtdb64.h" - -static ISC_LIST(dns_dbimplementation_t) implementations; -static isc_rwlock_t implock; -static isc_once_t once = ISC_ONCE_INIT; - -static dns_dbimplementation_t rbtimp; -static dns_dbimplementation_t rbt64imp; - -static void -initialize(void) { - RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS); - - rbtimp.name = "rbt"; - rbtimp.create = dns_rbtdb_create; - rbtimp.mctx = NULL; - rbtimp.driverarg = NULL; - ISC_LINK_INIT(&rbtimp, link); - - rbt64imp.name = "rbt64"; - rbt64imp.create = dns_rbtdb64_create; - rbt64imp.mctx = NULL; - rbt64imp.driverarg = NULL; - ISC_LINK_INIT(&rbt64imp, link); - - ISC_LIST_INIT(implementations); - ISC_LIST_APPEND(implementations, &rbtimp, link); - ISC_LIST_APPEND(implementations, &rbt64imp, link); -} - -static inline dns_dbimplementation_t * -impfind(const char *name) { - dns_dbimplementation_t *imp; - - for (imp = ISC_LIST_HEAD(implementations); - imp != NULL; - imp = ISC_LIST_NEXT(imp, link)) - if (strcasecmp(name, imp->name) == 0) - return (imp); - return (NULL); -} - - -/*** - *** Basic DB Methods - ***/ - -isc_result_t -dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, - dns_dbtype_t type, dns_rdataclass_t rdclass, - unsigned int argc, char *argv[], dns_db_t **dbp) -{ - dns_dbimplementation_t *impinfo; - - RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); - - /* - * Create a new database using implementation 'db_type'. - */ - - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(dns_name_isabsolute(origin)); - - RWLOCK(&implock, isc_rwlocktype_read); - impinfo = impfind(db_type); - if (impinfo != NULL) { - isc_result_t result; - result = ((impinfo->create)(mctx, origin, type, - rdclass, argc, argv, - impinfo->driverarg, dbp)); - RWUNLOCK(&implock, isc_rwlocktype_read); - return (result); - } - - RWUNLOCK(&implock, isc_rwlocktype_read); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DB, ISC_LOG_ERROR, - "unsupported database type '%s'", db_type); - - return (ISC_R_NOTFOUND); -} - -void -dns_db_attach(dns_db_t *source, dns_db_t **targetp) { - - /* - * Attach *targetp to source. - */ - - REQUIRE(DNS_DB_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - (source->methods->attach)(source, targetp); - - ENSURE(*targetp == source); -} - -void -dns_db_detach(dns_db_t **dbp) { - - /* - * Detach *dbp from its database. - */ - - REQUIRE(dbp != NULL); - REQUIRE(DNS_DB_VALID(*dbp)); - - ((*dbp)->methods->detach)(dbp); - - ENSURE(*dbp == NULL); -} - -isc_result_t -dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp) -{ - REQUIRE(DNS_DB_VALID(db)); - - return (isc_ondestroy_register(&db->ondest, task, eventp)); -} - - -bool -dns_db_iscache(dns_db_t *db) { - - /* - * Does 'db' have cache semantics? - */ - - REQUIRE(DNS_DB_VALID(db)); - - if ((db->attributes & DNS_DBATTR_CACHE) != 0) - return (true); - - return (false); -} - -bool -dns_db_iszone(dns_db_t *db) { - - /* - * Does 'db' have zone semantics? - */ - - REQUIRE(DNS_DB_VALID(db)); - - if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0) - return (true); - - return (false); -} - -bool -dns_db_isstub(dns_db_t *db) { - - /* - * Does 'db' have stub semantics? - */ - - REQUIRE(DNS_DB_VALID(db)); - - if ((db->attributes & DNS_DBATTR_STUB) != 0) - return (true); - - return (false); -} - -bool -dns_db_isdnssec(dns_db_t *db) { - - /* - * Is 'db' secure or partially secure? - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - - if (db->methods->isdnssec != NULL) - return ((db->methods->isdnssec)(db)); - return ((db->methods->issecure)(db)); -} - -bool -dns_db_issecure(dns_db_t *db) { - - /* - * Is 'db' secure? - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - - return ((db->methods->issecure)(db)); -} - -bool -dns_db_ispersistent(dns_db_t *db) { - - /* - * Is 'db' persistent? - */ - - REQUIRE(DNS_DB_VALID(db)); - - return ((db->methods->ispersistent)(db)); -} - -dns_name_t * -dns_db_origin(dns_db_t *db) { - /* - * The origin of the database. - */ - - REQUIRE(DNS_DB_VALID(db)); - - return (&db->origin); -} - -dns_rdataclass_t -dns_db_class(dns_db_t *db) { - /* - * The class of the database. - */ - - REQUIRE(DNS_DB_VALID(db)); - - return (db->rdclass); -} - -isc_result_t -dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - /* - * Begin loading 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(DNS_CALLBACK_VALID(callbacks)); - - return ((db->methods->beginload)(db, callbacks)); -} - -isc_result_t -dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - dns_dbonupdatelistener_t *listener; - - /* - * Finish loading 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(DNS_CALLBACK_VALID(callbacks)); - REQUIRE(callbacks->add_private != NULL); - - for (listener = ISC_LIST_HEAD(db->update_listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - listener->onupdate(db, listener->onupdate_arg); - - return ((db->methods->endload)(db, callbacks)); -} - -isc_result_t -dns_db_load(dns_db_t *db, const char *filename) { - return (dns_db_load3(db, filename, dns_masterformat_text, 0)); -} - -isc_result_t -dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) { - return (dns_db_load3(db, filename, format, 0)); -} - -isc_result_t -dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format, - unsigned int options) -{ - isc_result_t result, eresult; - dns_rdatacallbacks_t callbacks; - - /* - * Load master file 'filename' into 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - - if ((db->attributes & DNS_DBATTR_CACHE) != 0) - options |= DNS_MASTER_AGETTL; - - dns_rdatacallbacks_init(&callbacks); - result = dns_db_beginload(db, &callbacks); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_master_loadfile2(filename, &db->origin, &db->origin, - db->rdclass, options, - &callbacks, db->mctx, format); - eresult = dns_db_endload(db, &callbacks); - /* - * We always call dns_db_endload(), but we only want to return its - * result if dns_master_loadfile() succeeded. If dns_master_loadfile() - * failed, we want to return the result code it gave us. - */ - if (eresult != ISC_R_SUCCESS && - (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) - result = eresult; - - return (result); -} - -isc_result_t -dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file) { - REQUIRE(DNS_DB_VALID(db)); - if (db->methods->serialize == NULL) - return (ISC_R_NOTIMPLEMENTED); - return ((db->methods->serialize)(db, version, file)); -} - -isc_result_t -dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { - return ((db->methods->dump)(db, version, filename, - dns_masterformat_text)); -} - -isc_result_t -dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat) { - /* - * Dump 'db' into master file 'filename' in the 'masterformat' format. - * XXXJT: is it okay to modify the interface to the existing "dump" - * method? - */ - - REQUIRE(DNS_DB_VALID(db)); - - return ((db->methods->dump)(db, version, filename, masterformat)); -} - -/*** - *** Version Methods - ***/ - -void -dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) { - - /* - * Open the current version for reading. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - REQUIRE(versionp != NULL && *versionp == NULL); - - (db->methods->currentversion)(db, versionp); -} - -isc_result_t -dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) { - - /* - * Open a new version for reading and writing. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - REQUIRE(versionp != NULL && *versionp == NULL); - - return ((db->methods->newversion)(db, versionp)); -} - -void -dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp) -{ - /* - * Attach '*targetp' to 'source'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - REQUIRE(source != NULL); - REQUIRE(targetp != NULL && *targetp == NULL); - - (db->methods->attachversion)(db, source, targetp); - - ENSURE(*targetp != NULL); -} - -void -dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, - bool commit) -{ - dns_dbonupdatelistener_t *listener; - - /* - * Close version '*versionp'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); - REQUIRE(versionp != NULL && *versionp != NULL); - - (db->methods->closeversion)(db, versionp, commit); - - if (commit == true) { - for (listener = ISC_LIST_HEAD(db->update_listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - listener->onupdate(db, listener->onupdate_arg); - } - - ENSURE(*versionp == NULL); -} - -/*** - *** Node Methods - ***/ - -isc_result_t -dns_db_findnode(dns_db_t *db, dns_name_t *name, - bool create, dns_dbnode_t **nodep) -{ - - /* - * Find the node with name 'name'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(nodep != NULL && *nodep == NULL); - - if (db->methods->findnode != NULL) - return ((db->methods->findnode)(db, name, create, nodep)); - else - return ((db->methods->findnodeext)(db, name, create, - NULL, NULL, nodep)); -} - -isc_result_t -dns_db_findnodeext(dns_db_t *db, dns_name_t *name, - bool create, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) -{ - /* - * Find the node with name 'name', passing 'arg' to the database - * implementation. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(nodep != NULL && *nodep == NULL); - - if (db->methods->findnodeext != NULL) - return ((db->methods->findnodeext)(db, name, create, - methods, clientinfo, nodep)); - else - return ((db->methods->findnode)(db, name, create, nodep)); -} - -isc_result_t -dns_db_findnsec3node(dns_db_t *db, dns_name_t *name, - bool create, dns_dbnode_t **nodep) -{ - - /* - * Find the node with name 'name'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(nodep != NULL && *nodep == NULL); - - return ((db->methods->findnsec3node)(db, name, create, nodep)); -} - -isc_result_t -dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - /* - * Find the best match for 'name' and 'type' in version 'version' - * of 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(type != dns_rdatatype_rrsig); - REQUIRE(nodep == NULL || *nodep == NULL); - REQUIRE(dns_name_hasbuffer(foundname)); - REQUIRE(rdataset == NULL || - (DNS_RDATASET_VALID(rdataset) && - ! dns_rdataset_isassociated(rdataset))); - REQUIRE(sigrdataset == NULL || - (DNS_RDATASET_VALID(sigrdataset) && - ! dns_rdataset_isassociated(sigrdataset))); - - if (db->methods->find != NULL) - return ((db->methods->find)(db, name, version, type, - options, now, nodep, foundname, - rdataset, sigrdataset)); - else - return ((db->methods->findext)(db, name, version, type, - options, now, nodep, foundname, - NULL, NULL, - rdataset, sigrdataset)); -} - -isc_result_t -dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - - /* - * Find the best match for 'name' and 'type' in version 'version' - * of 'db', passing in 'arg'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(type != dns_rdatatype_rrsig); - REQUIRE(nodep == NULL || *nodep == NULL); - REQUIRE(dns_name_hasbuffer(foundname)); - REQUIRE(rdataset == NULL || - (DNS_RDATASET_VALID(rdataset) && - ! dns_rdataset_isassociated(rdataset))); - REQUIRE(sigrdataset == NULL || - (DNS_RDATASET_VALID(sigrdataset) && - ! dns_rdataset_isassociated(sigrdataset))); - - if (db->methods->findext != NULL) - return ((db->methods->findext)(db, name, version, type, - options, now, nodep, foundname, - methods, clientinfo, - rdataset, sigrdataset)); - else - return ((db->methods->find)(db, name, version, type, - options, now, nodep, foundname, - rdataset, sigrdataset)); -} - -isc_result_t -dns_db_findzonecut(dns_db_t *db, dns_name_t *name, - unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - /* - * Find the deepest known zonecut which encloses 'name' in 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); - REQUIRE(nodep == NULL || *nodep == NULL); - REQUIRE(dns_name_hasbuffer(foundname)); - REQUIRE(sigrdataset == NULL || - (DNS_RDATASET_VALID(sigrdataset) && - ! dns_rdataset_isassociated(sigrdataset))); - - return ((db->methods->findzonecut)(db, name, options, now, nodep, - foundname, rdataset, sigrdataset)); -} - -void -dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { - - /* - * Attach *targetp to source. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(source != NULL); - REQUIRE(targetp != NULL && *targetp == NULL); - - (db->methods->attachnode)(db, source, targetp); -} - -void -dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) { - - /* - * Detach *nodep from its node. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(nodep != NULL && *nodep != NULL); - - (db->methods->detachnode)(db, nodep); - - ENSURE(*nodep == NULL); -} - -void -dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, - dns_dbnode_t **targetp) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(targetp != NULL && *targetp == NULL); - /* - * This doesn't check the implementation magic. If we find that - * we need such checks in future then this will be done in the - * method. - */ - REQUIRE(sourcep != NULL && *sourcep != NULL); - - UNUSED(db); - - if (db->methods->transfernode == NULL) { - *targetp = *sourcep; - *sourcep = NULL; - } else - (db->methods->transfernode)(db, sourcep, targetp); - - ENSURE(*sourcep == NULL); -} - -isc_result_t -dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { - - /* - * Mark as stale all records at 'node' which expire at or before 'now'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); - REQUIRE(node != NULL); - - return ((db->methods->expirenode)(db, node, now)); -} - -void -dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { - /* - * Print a textual representation of the contents of the node to - * 'out'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(node != NULL); - - (db->methods->printnode)(db, node, out); -} - -/*** - *** DB Iterator Creation - ***/ - -isc_result_t -dns_db_createiterator(dns_db_t *db, unsigned int flags, - dns_dbiterator_t **iteratorp) -{ - /* - * Create an iterator for version 'version' of 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(iteratorp != NULL && *iteratorp == NULL); - - return (db->methods->createiterator(db, flags, iteratorp)); -} - -/*** - *** Rdataset Methods - ***/ - -isc_result_t -dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(node != NULL); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(! dns_rdataset_isassociated(rdataset)); - REQUIRE(covers == 0 || type == dns_rdatatype_rrsig); - REQUIRE(type != dns_rdatatype_any); - REQUIRE(sigrdataset == NULL || - (DNS_RDATASET_VALID(sigrdataset) && - ! dns_rdataset_isassociated(sigrdataset))); - - return ((db->methods->findrdataset)(db, node, version, type, - covers, now, rdataset, - sigrdataset)); -} - -isc_result_t -dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) -{ - /* - * Make '*iteratorp' an rdataset iteratator for all rdatasets at - * 'node' in version 'version' of 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(iteratorp != NULL && *iteratorp == NULL); - - return ((db->methods->allrdatasets)(db, node, version, now, - iteratorp)); -} - -isc_result_t -dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, - unsigned int options, dns_rdataset_t *addedrdataset) -{ - /* - * Add 'rdataset' to 'node' in version 'version' of 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(node != NULL); - REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)|| - ((db->attributes & DNS_DBATTR_CACHE) != 0 && - version == NULL && (options & DNS_DBADD_MERGE) == 0)); - REQUIRE((options & DNS_DBADD_EXACT) == 0 || - (options & DNS_DBADD_MERGE) != 0); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(dns_rdataset_isassociated(rdataset)); - REQUIRE(rdataset->rdclass == db->rdclass); - REQUIRE(addedrdataset == NULL || - (DNS_RDATASET_VALID(addedrdataset) && - ! dns_rdataset_isassociated(addedrdataset))); - - return ((db->methods->addrdataset)(db, node, version, now, rdataset, - options, addedrdataset)); -} - -isc_result_t -dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_rdataset_t *rdataset, - unsigned int options, dns_rdataset_t *newrdataset) -{ - /* - * Remove any rdata in 'rdataset' from 'node' in version 'version' of - * 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(node != NULL); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(dns_rdataset_isassociated(rdataset)); - REQUIRE(rdataset->rdclass == db->rdclass); - REQUIRE(newrdataset == NULL || - (DNS_RDATASET_VALID(newrdataset) && - ! dns_rdataset_isassociated(newrdataset))); - - return ((db->methods->subtractrdataset)(db, node, version, rdataset, - options, newrdataset)); -} - -isc_result_t -dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_rdatatype_t type, - dns_rdatatype_t covers) -{ - /* - * Make it so that no rdataset of type 'type' exists at 'node' in - * version version 'version' of 'db'. - */ - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(node != NULL); - REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)|| - ((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL)); - - return ((db->methods->deleterdataset)(db, node, version, - type, covers)); -} - -void -dns_db_overmem(dns_db_t *db, bool overmem) { - - REQUIRE(DNS_DB_VALID(db)); - - (db->methods->overmem)(db, overmem); -} - -isc_result_t -dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, uint32_t *serialp) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t buffer; - - REQUIRE(dns_db_iszone(db) || dns_db_isstub(db)); - - result = dns_db_findnode(db, dns_db_origin(db), false, &node); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, - (isc_stdtime_t)0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto freenode; - - result = dns_rdataset_first(&rdataset); - if (result != ISC_R_SUCCESS) - goto freerdataset; - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdataset_next(&rdataset); - INSIST(result == ISC_R_NOMORE); - - INSIST(rdata.length > 20); - isc_buffer_init(&buffer, rdata.data, rdata.length); - isc_buffer_add(&buffer, rdata.length); - isc_buffer_forward(&buffer, rdata.length - 20); - *serialp = isc_buffer_getuint32(&buffer); - - result = ISC_R_SUCCESS; - - freerdataset: - dns_rdataset_disassociate(&rdataset); - - freenode: - dns_db_detachnode(db, &node); - return (result); -} - -unsigned int -dns_db_nodecount(dns_db_t *db) { - REQUIRE(DNS_DB_VALID(db)); - - return ((db->methods->nodecount)(db)); -} - -size_t -dns_db_hashsize(dns_db_t *db) { - REQUIRE(DNS_DB_VALID(db)); - - if (db->methods->hashsize == NULL) - return (0); - - return ((db->methods->hashsize)(db)); -} - -void -dns_db_settask(dns_db_t *db, isc_task_t *task) { - REQUIRE(DNS_DB_VALID(db)); - - (db->methods->settask)(db, task); -} - -isc_result_t -dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, - isc_mem_t *mctx, dns_dbimplementation_t **dbimp) -{ - dns_dbimplementation_t *imp; - - REQUIRE(name != NULL); - REQUIRE(dbimp != NULL && *dbimp == NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); - - RWLOCK(&implock, isc_rwlocktype_write); - imp = impfind(name); - if (imp != NULL) { - RWUNLOCK(&implock, isc_rwlocktype_write); - return (ISC_R_EXISTS); - } - - imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t)); - if (imp == NULL) { - RWUNLOCK(&implock, isc_rwlocktype_write); - return (ISC_R_NOMEMORY); - } - imp->name = name; - imp->create = create; - imp->mctx = NULL; - imp->driverarg = driverarg; - isc_mem_attach(mctx, &imp->mctx); - ISC_LINK_INIT(imp, link); - ISC_LIST_APPEND(implementations, imp, link); - RWUNLOCK(&implock, isc_rwlocktype_write); - - *dbimp = imp; - - return (ISC_R_SUCCESS); -} - -void -dns_db_unregister(dns_dbimplementation_t **dbimp) { - dns_dbimplementation_t *imp; - isc_mem_t *mctx; - - REQUIRE(dbimp != NULL && *dbimp != NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); - - imp = *dbimp; - *dbimp = NULL; - RWLOCK(&implock, isc_rwlocktype_write); - ISC_LIST_UNLINK(implementations, imp, link); - mctx = imp->mctx; - isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t)); - isc_mem_detach(&mctx); - RWUNLOCK(&implock, isc_rwlocktype_write); - ENSURE(*dbimp == NULL); -} - -isc_result_t -dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(dns_db_iszone(db) == true); - REQUIRE(nodep != NULL && *nodep == NULL); - - if (db->methods->getoriginnode != NULL) - return ((db->methods->getoriginnode)(db, nodep)); - - return (ISC_R_NOTFOUND); -} - -dns_stats_t * -dns_db_getrrsetstats(dns_db_t *db) { - REQUIRE(DNS_DB_VALID(db)); - - if (db->methods->getrrsetstats != NULL) - return ((db->methods->getrrsetstats)(db)); - - return (NULL); -} - -isc_result_t -dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats) { - REQUIRE(DNS_DB_VALID(db)); - - if (db->methods->setcachestats != NULL) - return ((db->methods->setcachestats)(db, stats)); - - return (ISC_R_NOTIMPLEMENTED); -} - -isc_result_t -dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, - dns_hash_t *hash, uint8_t *flags, - uint16_t *iterations, - unsigned char *salt, size_t *salt_length) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(dns_db_iszone(db) == true); - - if (db->methods->getnsec3parameters != NULL) - return ((db->methods->getnsec3parameters)(db, version, hash, - flags, iterations, - salt, salt_length)); - - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_db_getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records, - uint64_t *bytes) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(dns_db_iszone(db) == true); - - if (db->methods->getsize != NULL) - return ((db->methods->getsize)(db, version, records, bytes)); - - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, - isc_stdtime_t resign) -{ - if (db->methods->setsigningtime != NULL) - return ((db->methods->setsigningtime)(db, rdataset, resign)); - return (ISC_R_NOTIMPLEMENTED); -} - -isc_result_t -dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name) -{ - if (db->methods->getsigningtime != NULL) - return ((db->methods->getsigningtime)(db, rdataset, name)); - return (ISC_R_NOTFOUND); -} - -void -dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, - dns_dbversion_t *version) -{ - if (db->methods->resigned != NULL) - (db->methods->resigned)(db, rdataset, version); -} - -/* - * Attach a database to policy zone databases. - * This should only happen when the caller has already ensured that - * it is dealing with a database that understands response policy zones. - */ -void -dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { - REQUIRE(db->methods->rpz_attach != NULL); - (db->methods->rpz_attach)(db, rpzs, rpz_num); -} - -/* - * Finish loading a response policy zone. - */ -isc_result_t -dns_db_rpz_ready(dns_db_t *db) { - if (db->methods->rpz_ready == NULL) - return (ISC_R_SUCCESS); - return ((db->methods->rpz_ready)(db)); -} - -/** - * Attach a notify-on-update function the database - */ -isc_result_t -dns_db_updatenotify_register(dns_db_t *db, - dns_dbupdate_callback_t fn, - void *fn_arg) -{ - dns_dbonupdatelistener_t *listener; - - REQUIRE(db != NULL); - REQUIRE(fn != NULL); - - listener = isc_mem_get(db->mctx, sizeof(dns_dbonupdatelistener_t)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - listener->onupdate = fn; - listener->onupdate_arg = fn_arg; - - ISC_LINK_INIT(listener, link); - ISC_LIST_APPEND(db->update_listeners, listener, link); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_db_updatenotify_unregister(dns_db_t *db, - dns_dbupdate_callback_t fn, - void *fn_arg) -{ - dns_dbonupdatelistener_t *listener; - - REQUIRE(db != NULL); - - for (listener = ISC_LIST_HEAD(db->update_listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - { - if ((listener->onupdate == fn) && - (listener->onupdate_arg == fn_arg)) - { - ISC_LIST_UNLINK(db->update_listeners, listener, link); - isc_mem_put(db->mctx, listener, - sizeof(dns_dbonupdatelistener_t)); - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name) { - REQUIRE(db != NULL); - REQUIRE(node != NULL); - REQUIRE(name != NULL); - - if (db->methods->nodefullname == NULL) - return (ISC_R_NOTIMPLEMENTED); - return ((db->methods->nodefullname)(db, node, name)); -} - -isc_result_t -dns_db_setservestalettl(dns_db_t *db, dns_ttl_t ttl) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); - - if (db->methods->setservestalettl != NULL) - return ((db->methods->setservestalettl)(db, ttl)); - return (ISC_R_NOTIMPLEMENTED); -} - -isc_result_t -dns_db_getservestalettl(dns_db_t *db, dns_ttl_t *ttl) -{ - REQUIRE(DNS_DB_VALID(db)); - REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); - - if (db->methods->getservestalettl != NULL) - return ((db->methods->getservestalettl)(db, ttl)); - return (ISC_R_NOTIMPLEMENTED); -} diff --git a/lib/dns-pkcs11/dbiterator.c b/lib/dns-pkcs11/dbiterator.c deleted file mode 100644 index 528f801..0000000 --- a/lib/dns-pkcs11/dbiterator.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include - -#include -#include - -void -dns_dbiterator_destroy(dns_dbiterator_t **iteratorp) { - /* - * Destroy '*iteratorp'. - */ - - REQUIRE(iteratorp != NULL); - REQUIRE(DNS_DBITERATOR_VALID(*iteratorp)); - - (*iteratorp)->methods->destroy(iteratorp); - - ENSURE(*iteratorp == NULL); -} - -isc_result_t -dns_dbiterator_first(dns_dbiterator_t *iterator) { - /* - * Move the node cursor to the first node in the database (if any). - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->first(iterator)); -} - -isc_result_t -dns_dbiterator_last(dns_dbiterator_t *iterator) { - /* - * Move the node cursor to the first node in the database (if any). - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->last(iterator)); -} - -isc_result_t -dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { - /* - * Move the node cursor to the node with name 'name'. - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->seek(iterator, name)); -} - -isc_result_t -dns_dbiterator_prev(dns_dbiterator_t *iterator) { - /* - * Move the node cursor to the previous node in the database (if any). - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->prev(iterator)); -} - -isc_result_t -dns_dbiterator_next(dns_dbiterator_t *iterator) { - /* - * Move the node cursor to the next node in the database (if any). - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->next(iterator)); -} - -isc_result_t -dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, - dns_name_t *name) -{ - /* - * Return the current node. - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - REQUIRE(nodep != NULL && *nodep == NULL); - REQUIRE(name == NULL || dns_name_hasbuffer(name)); - - return (iterator->methods->current(iterator, nodep, name)); -} - -isc_result_t -dns_dbiterator_pause(dns_dbiterator_t *iterator) { - /* - * Pause iteration. - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - return (iterator->methods->pause(iterator)); -} - -isc_result_t -dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { - - /* - * Return the origin to which returned node names are relative. - */ - - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - REQUIRE(iterator->relative_names); - REQUIRE(dns_name_hasbuffer(name)); - - return (iterator->methods->origin(iterator, name)); -} - -void -dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, bool mode) { - REQUIRE(DNS_DBITERATOR_VALID(iterator)); - - iterator->cleaning = mode; -} diff --git a/lib/dns-pkcs11/dbtable.c b/lib/dns-pkcs11/dbtable.c deleted file mode 100644 index fc187c6..0000000 --- a/lib/dns-pkcs11/dbtable.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -struct dns_dbtable { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - dns_rdataclass_t rdclass; - isc_mutex_t lock; - isc_rwlock_t tree_lock; - /* Locked by lock. */ - unsigned int references; - /* Locked by tree_lock. */ - dns_rbt_t * rbt; - dns_db_t * default_db; -}; - -#define DBTABLE_MAGIC ISC_MAGIC('D', 'B', '-', '-') -#define VALID_DBTABLE(dbtable) ISC_MAGIC_VALID(dbtable, DBTABLE_MAGIC) - -static void -dbdetach(void *data, void *arg) { - dns_db_t *db = data; - - UNUSED(arg); - - dns_db_detach(&db); -} - -isc_result_t -dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, - dns_dbtable_t **dbtablep) -{ - dns_dbtable_t *dbtable; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(dbtablep != NULL && *dbtablep == NULL); - - dbtable = (dns_dbtable_t *)isc_mem_get(mctx, sizeof(*dbtable)); - if (dbtable == NULL) - return (ISC_R_NOMEMORY); - - dbtable->rbt = NULL; - result = dns_rbt_create(mctx, dbdetach, NULL, &dbtable->rbt); - if (result != ISC_R_SUCCESS) - goto clean1; - - result = isc_mutex_init(&dbtable->lock); - if (result != ISC_R_SUCCESS) - goto clean2; - - result = isc_rwlock_init(&dbtable->tree_lock, 0, 0); - if (result != ISC_R_SUCCESS) - goto clean3; - - dbtable->default_db = NULL; - dbtable->mctx = NULL; - isc_mem_attach(mctx, &dbtable->mctx); - dbtable->rdclass = rdclass; - dbtable->magic = DBTABLE_MAGIC; - dbtable->references = 1; - - *dbtablep = dbtable; - - return (ISC_R_SUCCESS); - - clean3: - DESTROYLOCK(&dbtable->lock); - - clean2: - dns_rbt_destroy(&dbtable->rbt); - - clean1: - isc_mem_putanddetach(&mctx, dbtable, sizeof(*dbtable)); - - return (result); -} - -static inline void -dbtable_free(dns_dbtable_t *dbtable) { - /* - * Caller must ensure that it is safe to call. - */ - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - if (dbtable->default_db != NULL) - dns_db_detach(&dbtable->default_db); - - dns_rbt_destroy(&dbtable->rbt); - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - isc_rwlock_destroy(&dbtable->tree_lock); - - dbtable->magic = 0; - - isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable)); -} - -void -dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp) { - REQUIRE(VALID_DBTABLE(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); - - UNLOCK(&source->lock); - - *targetp = source; -} - -void -dns_dbtable_detach(dns_dbtable_t **dbtablep) { - dns_dbtable_t *dbtable; - bool free_dbtable = false; - - REQUIRE(dbtablep != NULL); - dbtable = *dbtablep; - REQUIRE(VALID_DBTABLE(dbtable)); - - LOCK(&dbtable->lock); - - INSIST(dbtable->references > 0); - dbtable->references--; - if (dbtable->references == 0) - free_dbtable = true; - - UNLOCK(&dbtable->lock); - - if (free_dbtable) - dbtable_free(dbtable); - - *dbtablep = NULL; -} - -isc_result_t -dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db) { - isc_result_t result; - dns_db_t *dbclone; - - REQUIRE(VALID_DBTABLE(dbtable)); - REQUIRE(dns_db_class(db) == dbtable->rdclass); - - dbclone = NULL; - dns_db_attach(db, &dbclone); - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - result = dns_rbt_addname(dbtable->rbt, dns_db_origin(dbclone), dbclone); - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - return (result); -} - -void -dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db) { - dns_db_t *stored_data = NULL; - isc_result_t result; - dns_name_t *name; - - REQUIRE(VALID_DBTABLE(dbtable)); - - name = dns_db_origin(db); - - /* - * There is a requirement that the association of name with db - * be verified. With the current rbt.c this is expensive to do, - * because effectively two find operations are being done, but - * deletion is relatively infrequent. - * XXXDCL ... this could be cheaper now with dns_rbt_deletenode. - */ - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - result = dns_rbt_findname(dbtable->rbt, name, 0, NULL, - (void **) (void *)&stored_data); - - if (result == ISC_R_SUCCESS) { - INSIST(stored_data == db); - - (void)dns_rbt_deletename(dbtable->rbt, name, false); - } - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); -} - -void -dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db) { - REQUIRE(VALID_DBTABLE(dbtable)); - REQUIRE(dbtable->default_db == NULL); - REQUIRE(dns_name_compare(dns_db_origin(db), dns_rootname) == 0); - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - dbtable->default_db = NULL; - dns_db_attach(db, &dbtable->default_db); - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); -} - -void -dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **dbp) { - REQUIRE(VALID_DBTABLE(dbtable)); - REQUIRE(dbp != NULL && *dbp == NULL); - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); - - dns_db_attach(dbtable->default_db, dbp); - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); -} - -void -dns_dbtable_removedefault(dns_dbtable_t *dbtable) { - REQUIRE(VALID_DBTABLE(dbtable)); - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); - - dns_db_detach(&dbtable->default_db); - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); -} - -isc_result_t -dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, - unsigned int options, dns_db_t **dbp) -{ - dns_db_t *stored_data = NULL; - isc_result_t result; - unsigned int rbtoptions = 0; - - REQUIRE(dbp != NULL && *dbp == NULL); - - if ((options & DNS_DBTABLEFIND_NOEXACT) != 0) - rbtoptions |= DNS_RBTFIND_NOEXACT; - - RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); - - result = dns_rbt_findname(dbtable->rbt, name, rbtoptions, NULL, - (void **) (void *)&stored_data); - - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - dns_db_attach(stored_data, dbp); - else if (dbtable->default_db != NULL) { - dns_db_attach(dbtable->default_db, dbp); - result = DNS_R_PARTIALMATCH; - } else - result = ISC_R_NOTFOUND; - - RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); - - return (result); -} diff --git a/lib/dns-pkcs11/diff.c b/lib/dns-pkcs11/diff.c deleted file mode 100644 index 3a05912..0000000 --- a/lib/dns-pkcs11/diff.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define DIFF_COMMON_LOGARGS \ - dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DIFF - -static dns_rdatatype_t -rdata_covers(dns_rdata_t *rdata) { - return (rdata->type == dns_rdatatype_rrsig ? - dns_rdata_covers(rdata) : 0); -} - -isc_result_t -dns_difftuple_create(isc_mem_t *mctx, - dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, - dns_rdata_t *rdata, dns_difftuple_t **tp) -{ - dns_difftuple_t *t; - unsigned int size; - unsigned char *datap; - - REQUIRE(tp != NULL && *tp == NULL); - - /* - * Create a new tuple. The variable-size wire-format name data and - * rdata immediately follow the dns_difftuple_t structure - * in memory. - */ - size = sizeof(*t) + name->length + rdata->length; - t = isc_mem_allocate(mctx, size); - if (t == NULL) - return (ISC_R_NOMEMORY); - t->mctx = NULL; - isc_mem_attach(mctx, &t->mctx); - t->op = op; - - datap = (unsigned char *)(t + 1); - - memmove(datap, name->ndata, name->length); - dns_name_init(&t->name, NULL); - dns_name_clone(name, &t->name); - t->name.ndata = datap; - datap += name->length; - - t->ttl = ttl; - - dns_rdata_init(&t->rdata); - dns_rdata_clone(rdata, &t->rdata); - if (rdata->data != NULL) { - memmove(datap, rdata->data, rdata->length); - t->rdata.data = datap; - datap += rdata->length; - } else { - t->rdata.data = NULL; - INSIST(rdata->length == 0); - } - - ISC_LINK_INIT(&t->rdata, link); - ISC_LINK_INIT(t, link); - t->magic = DNS_DIFFTUPLE_MAGIC; - - INSIST(datap == (unsigned char *)t + size); - - *tp = t; - return (ISC_R_SUCCESS); -} - -void -dns_difftuple_free(dns_difftuple_t **tp) { - dns_difftuple_t *t = *tp; - isc_mem_t *mctx; - - REQUIRE(DNS_DIFFTUPLE_VALID(t)); - - dns_name_invalidate(&t->name); - t->magic = 0; - mctx = t->mctx; - isc_mem_free(mctx, t); - isc_mem_detach(&mctx); - *tp = NULL; -} - -isc_result_t -dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp) { - return (dns_difftuple_create(orig->mctx, orig->op, &orig->name, - orig->ttl, &orig->rdata, copyp)); -} - -void -dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff) { - diff->mctx = mctx; - ISC_LIST_INIT(diff->tuples); - diff->magic = DNS_DIFF_MAGIC; -} - -void -dns_diff_clear(dns_diff_t *diff) { - dns_difftuple_t *t; - REQUIRE(DNS_DIFF_VALID(diff)); - while ((t = ISC_LIST_HEAD(diff->tuples)) != NULL) { - ISC_LIST_UNLINK(diff->tuples, t, link); - dns_difftuple_free(&t); - } - ENSURE(ISC_LIST_EMPTY(diff->tuples)); -} - -void -dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep) -{ - ISC_LIST_APPEND(diff->tuples, *tuplep, link); - *tuplep = NULL; -} - -/* XXX this is O(N) */ - -void -dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) -{ - dns_difftuple_t *ot, *next_ot; - - REQUIRE(DNS_DIFF_VALID(diff)); - REQUIRE(DNS_DIFFTUPLE_VALID(*tuplep)); - - /* - * Look for an existing tuple with the same owner name, - * rdata, and TTL. If we are doing an addition and find a - * deletion or vice versa, remove both the old and the - * new tuple since they cancel each other out (assuming - * that we never delete nonexistent data or add existing - * data). - * - * If we find an old update of the same kind as - * the one we are doing, there must be a programming - * error. We report it but try to continue anyway. - */ - for (ot = ISC_LIST_HEAD(diff->tuples); ot != NULL; - ot = next_ot) - { - next_ot = ISC_LIST_NEXT(ot, link); - if (dns_name_caseequal(&ot->name, &(*tuplep)->name) && - dns_rdata_compare(&ot->rdata, &(*tuplep)->rdata) == 0 && - ot->ttl == (*tuplep)->ttl) - { - ISC_LIST_UNLINK(diff->tuples, ot, link); - if ((*tuplep)->op == ot->op) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unexpected non-minimal diff"); - } else { - dns_difftuple_free(tuplep); - } - dns_difftuple_free(&ot); - break; - } - } - - if (*tuplep != NULL) { - ISC_LIST_APPEND(diff->tuples, *tuplep, link); - *tuplep = NULL; - } - - ENSURE(*tuplep == NULL); -} - -static isc_stdtime_t -setresign(dns_rdataset_t *modified) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t sig; - int64_t when; - isc_result_t result; - - result = dns_rdataset_first(modified); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(modified, &rdata); - (void)dns_rdata_tostruct(&rdata, &sig, NULL); - if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) - when = 0; - else - when = dns_time64_from32(sig.timeexpire); - dns_rdata_reset(&rdata); - - result = dns_rdataset_next(modified); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(modified, &rdata); - (void)dns_rdata_tostruct(&rdata, &sig, NULL); - if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) { - goto next_rr; - } - if (when == 0 || dns_time64_from32(sig.timeexpire) < when) - when = dns_time64_from32(sig.timeexpire); - next_rr: - dns_rdata_reset(&rdata); - result = dns_rdataset_next(modified); - } - INSIST(result == ISC_R_NOMORE); - return ((isc_stdtime_t)when); -} - -static void -getownercase(dns_rdataset_t *rdataset, dns_name_t *name) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_getownercase(rdataset, name); -} - -static void -setownercase(dns_rdataset_t *rdataset, dns_name_t *name) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_setownercase(rdataset, name); -} - -static isc_result_t -diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, - bool warn) -{ - dns_difftuple_t *t; - dns_dbnode_t *node = NULL; - isc_result_t result; - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - REQUIRE(DNS_DIFF_VALID(diff)); - REQUIRE(DNS_DB_VALID(db)); - - t = ISC_LIST_HEAD(diff->tuples); - while (t != NULL) { - dns_name_t *name; - - INSIST(node == NULL); - name = &t->name; - /* - * Find the node. - * We create the node if it does not exist. - * This will cause an empty node to be created if the diff - * contains a deletion of an RR at a nonexistent name, - * but such diffs should never be created in the first - * place. - */ - - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_diffop_t op; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdataset_t ardataset; - unsigned int options; - - op = t->op; - type = t->rdata.type; - covers = rdata_covers(&t->rdata); - - /* - * Collect a contiguous set of updates with - * the same operation (add/delete) and RR type - * into a single rdatalist so that the - * database rrset merging/subtraction code - * can work more efficiently than if each - * RR were merged into / subtracted from - * the database separately. - * - * This is done by linking rdata structures from the - * diff into "rdatalist". This uses the rdata link - * field, not the diff link field, so the structure - * of the diff itself is not affected. - */ - - dns_rdatalist_init(&rdl); - rdl.type = type; - rdl.covers = covers; - rdl.rdclass = t->rdata.rdclass; - rdl.ttl = t->ttl; - - node = NULL; - if (type != dns_rdatatype_nsec3 && - covers != dns_rdatatype_nsec3) - CHECK(dns_db_findnode(db, name, true, - &node)); - else - CHECK(dns_db_findnsec3node(db, name, true, - &node)); - - while (t != NULL && - dns_name_equal(&t->name, name) && - t->op == op && - t->rdata.type == type && - rdata_covers(&t->rdata) == covers) - { - /* - * Remember the add name for - * dns_rdataset_setownercase. - */ - name = &t->name; - if (t->ttl != rdl.ttl && warn) { - dns_name_format(name, namebuf, - sizeof(namebuf)); - dns_rdatatype_format(t->rdata.type, - typebuf, - sizeof(typebuf)); - dns_rdataclass_format(t->rdata.rdclass, - classbuf, - sizeof(classbuf)); - isc_log_write(DIFF_COMMON_LOGARGS, - ISC_LOG_WARNING, - "'%s/%s/%s': TTL differs in " - "rdataset, adjusting " - "%lu -> %lu", - namebuf, typebuf, classbuf, - (unsigned long) t->ttl, - (unsigned long) rdl.ttl); - } - ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); - t = ISC_LIST_NEXT(t, link); - } - - /* - * Convert the rdatalist into a rdataset. - */ - dns_rdataset_init(&rds); - dns_rdataset_init(&ardataset); - CHECK(dns_rdatalist_tordataset(&rdl, &rds)); - rds.trust = dns_trust_ultimate; - - /* - * Merge the rdataset into the database. - */ - switch (op) { - case DNS_DIFFOP_ADD: - case DNS_DIFFOP_ADDRESIGN: - options = DNS_DBADD_MERGE | DNS_DBADD_EXACT | - DNS_DBADD_EXACTTTL; - result = dns_db_addrdataset(db, node, ver, - 0, &rds, options, - &ardataset); - break; - case DNS_DIFFOP_DEL: - case DNS_DIFFOP_DELRESIGN: - options = DNS_DBSUB_EXACT | DNS_DBSUB_WANTOLD; - result = dns_db_subtractrdataset(db, node, ver, - &rds, options, - &ardataset); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (result == ISC_R_SUCCESS) { - if (rds.type == dns_rdatatype_rrsig && - (op == DNS_DIFFOP_DELRESIGN || - op == DNS_DIFFOP_ADDRESIGN)) { - isc_stdtime_t resign; - resign = setresign(&ardataset); - dns_db_setsigningtime(db, &ardataset, - resign); - } - if (op == DNS_DIFFOP_ADD || - op == DNS_DIFFOP_ADDRESIGN) - setownercase(&ardataset, name); - if (op == DNS_DIFFOP_DEL || - op == DNS_DIFFOP_DELRESIGN) - getownercase(&ardataset, name); - } else if (result == DNS_R_UNCHANGED) { - /* - * This will not happen when executing a - * dynamic update, because that code will - * generate strictly minimal diffs. - * It may happen when receiving an IXFR - * from a server that is not as careful. - * Issue a warning and continue. - */ - if (warn) { - dns_name_format(dns_db_origin(db), - namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_db_class(db), - classbuf, - sizeof(classbuf)); - isc_log_write(DIFF_COMMON_LOGARGS, - ISC_LOG_WARNING, - "%s/%s: dns_diff_apply: " - "update with no effect", - namebuf, classbuf); - } - if (op == DNS_DIFFOP_ADD || - op == DNS_DIFFOP_ADDRESIGN) - setownercase(&ardataset, name); - if (op == DNS_DIFFOP_DEL || - op == DNS_DIFFOP_DELRESIGN) - getownercase(&ardataset, name); - } else if (result == DNS_R_NXRRSET) { - /* - * OK. - */ - if (op == DNS_DIFFOP_DEL || - op == DNS_DIFFOP_DELRESIGN) - getownercase(&ardataset, name); - if (dns_rdataset_isassociated(&ardataset)) - dns_rdataset_disassociate(&ardataset); - } else { - if (dns_rdataset_isassociated(&ardataset)) - dns_rdataset_disassociate(&ardataset); - CHECK(result); - } - dns_db_detachnode(db, &node); - if (dns_rdataset_isassociated(&ardataset)) - dns_rdataset_disassociate(&ardataset); - } - } - return (ISC_R_SUCCESS); - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -isc_result_t -dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) { - return (diff_apply(diff, db, ver, true)); -} - -isc_result_t -dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) { - return (diff_apply(diff, db, ver, false)); -} - -/* XXX this duplicates lots of code in diff_apply(). */ - -isc_result_t -dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc, - void *add_private) -{ - dns_difftuple_t *t; - isc_result_t result; - - REQUIRE(DNS_DIFF_VALID(diff)); - - t = ISC_LIST_HEAD(diff->tuples); - while (t != NULL) { - dns_name_t *name; - - name = &t->name; - while (t != NULL && dns_name_caseequal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_diffop_t op; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - - op = t->op; - type = t->rdata.type; - covers = rdata_covers(&t->rdata); - - dns_rdatalist_init(&rdl); - rdl.type = type; - rdl.covers = covers; - rdl.rdclass = t->rdata.rdclass; - rdl.ttl = t->ttl; - - while (t != NULL && dns_name_caseequal(&t->name, name) && - t->op == op && t->rdata.type == type && - rdata_covers(&t->rdata) == covers) - { - ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); - t = ISC_LIST_NEXT(t, link); - } - - /* - * Convert the rdatalist into a rdataset. - */ - dns_rdataset_init(&rds); - CHECK(dns_rdatalist_tordataset(&rdl, &rds)); - rds.trust = dns_trust_ultimate; - - INSIST(op == DNS_DIFFOP_ADD); - result = (*addfunc)(add_private, name, &rds); - if (result == DNS_R_UNCHANGED) { - isc_log_write(DIFF_COMMON_LOGARGS, - ISC_LOG_WARNING, - "dns_diff_load: " - "update with no effect"); - } else if (result == ISC_R_SUCCESS || - result == DNS_R_NXRRSET) { - /* - * OK. - */ - } else { - CHECK(result); - } - } - } - result = ISC_R_SUCCESS; - failure: - return (result); -} - -/* - * XXX uses qsort(); a merge sort would be more natural for lists, - * and perhaps safer wrt thread stack overflow. - */ -isc_result_t -dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare) { - unsigned int length = 0; - unsigned int i; - dns_difftuple_t **v; - dns_difftuple_t *p; - REQUIRE(DNS_DIFF_VALID(diff)); - - for (p = ISC_LIST_HEAD(diff->tuples); - p != NULL; - p = ISC_LIST_NEXT(p, link)) - length++; - if (length == 0) - return (ISC_R_SUCCESS); - v = isc_mem_get(diff->mctx, length * sizeof(dns_difftuple_t *)); - if (v == NULL) - return (ISC_R_NOMEMORY); - for (i = 0; i < length; i++) { - p = ISC_LIST_HEAD(diff->tuples); - v[i] = p; - ISC_LIST_UNLINK(diff->tuples, p, link); - } - INSIST(ISC_LIST_HEAD(diff->tuples) == NULL); - qsort(v, length, sizeof(v[0]), compare); - for (i = 0; i < length; i++) { - ISC_LIST_APPEND(diff->tuples, v[i], link); - } - isc_mem_put(diff->mctx, v, length * sizeof(dns_difftuple_t *)); - return (ISC_R_SUCCESS); -} - - -/* - * Create an rdataset containing the single RR of the given - * tuple. The caller must allocate the rdata, rdataset and - * an rdatalist structure for it to refer to. - */ - -static isc_result_t -diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata, - dns_rdatalist_t *rdl, dns_rdataset_t *rds) -{ - REQUIRE(DNS_DIFFTUPLE_VALID(t)); - REQUIRE(rdl != NULL); - REQUIRE(rds != NULL); - - dns_rdatalist_init(rdl); - rdl->type = t->rdata.type; - rdl->rdclass = t->rdata.rdclass; - rdl->ttl = t->ttl; - dns_rdataset_init(rds); - ISC_LINK_INIT(rdata, link); - dns_rdata_clone(&t->rdata, rdata); - ISC_LIST_APPEND(rdl->rdata, rdata, link); - return (dns_rdatalist_tordataset(rdl, rds)); -} - -isc_result_t -dns_diff_print(dns_diff_t *diff, FILE *file) { - isc_result_t result; - dns_difftuple_t *t; - char *mem = NULL; - unsigned int size = 2048; - const char *op = NULL; - - REQUIRE(DNS_DIFF_VALID(diff)); - - mem = isc_mem_get(diff->mctx, size); - if (mem == NULL) - return (ISC_R_NOMEMORY); - - for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_buffer_t buf; - isc_region_t r; - - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdata_t rd = DNS_RDATA_INIT; - - result = diff_tuple_tordataset(t, &rd, &rdl, &rds); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "diff_tuple_tordataset failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - again: - isc_buffer_init(&buf, mem, size); - result = dns_rdataset_totext(&rds, &t->name, - false, false, &buf); - - if (result == ISC_R_NOSPACE) { - isc_mem_put(diff->mctx, mem, size); - size += 1024; - mem = isc_mem_get(diff->mctx, size); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - goto again; - } - - if (result != ISC_R_SUCCESS) - goto cleanup; - /* - * Get rid of final newline. - */ - INSIST(buf.used >= 1 && - ((char *) buf.base)[buf.used-1] == '\n'); - buf.used--; - - isc_buffer_usedregion(&buf, &r); - switch (t->op) { - case DNS_DIFFOP_EXISTS: op = "exists"; break; - case DNS_DIFFOP_ADD: op = "add"; break; - case DNS_DIFFOP_DEL: op = "del"; break; - case DNS_DIFFOP_ADDRESIGN: op = "add re-sign"; break; - case DNS_DIFFOP_DELRESIGN: op = "del re-sign"; break; - } - if (file != NULL) - fprintf(file, "%s %.*s\n", op, (int) r.length, - (char *) r.base); - else - isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7), - "%s %.*s", op, (int) r.length, - (char *) r.base); - } - result = ISC_R_SUCCESS; - cleanup: - if (mem != NULL) - isc_mem_put(diff->mctx, mem, size); - return (result); -} diff --git a/lib/dns-pkcs11/dispatch.c b/lib/dns-pkcs11/dispatch.c deleted file mode 100644 index 0252803..0000000 --- a/lib/dns-pkcs11/dispatch.c +++ /dev/null @@ -1,3909 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef ISC_LIST(dns_dispentry_t) dns_displist_t; - -typedef struct dispsocket dispsocket_t; -typedef ISC_LIST(dispsocket_t) dispsocketlist_t; - -typedef struct dispportentry dispportentry_t; -typedef ISC_LIST(dispportentry_t) dispportlist_t; - -typedef struct dns_qid { - unsigned int magic; - unsigned int qid_nbuckets; /*%< hash table size */ - unsigned int qid_increment; /*%< id increment on collision */ - isc_mutex_t lock; - dns_displist_t *qid_table; /*%< the table itself */ - dispsocketlist_t *sock_table; /*%< socket table */ -} dns_qid_t; - -struct dns_dispatchmgr { - /* Unlocked. */ - unsigned int magic; - isc_mem_t *mctx; - dns_acl_t *blackhole; - dns_portlist_t *portlist; - isc_stats_t *stats; - isc_entropy_t *entropy; /*%< entropy source */ - - /* Locked by "lock". */ - isc_mutex_t lock; - unsigned int state; - ISC_LIST(dns_dispatch_t) list; - - /* Locked by rng_lock. */ - isc_mutex_t rng_lock; - isc_rng_t *rngctx; /*%< RNG context for QID */ - - /* locked by buffer_lock */ - dns_qid_t *qid; - isc_mutex_t buffer_lock; - unsigned int buffers; /*%< allocated buffers */ - unsigned int buffersize; /*%< size of each buffer */ - unsigned int maxbuffers; /*%< max buffers */ - - /* Locked internally. */ - isc_mutex_t depool_lock; - isc_mempool_t *depool; /*%< pool for dispatch events */ - isc_mutex_t rpool_lock; - isc_mempool_t *rpool; /*%< pool for replies */ - isc_mutex_t dpool_lock; - isc_mempool_t *dpool; /*%< dispatch allocations */ - isc_mutex_t bpool_lock; - isc_mempool_t *bpool; /*%< pool for buffers */ - isc_mutex_t spool_lock; - isc_mempool_t *spool; /*%< pool for dispsocks */ - - /*% - * Locked by qid->lock if qid exists; otherwise, can be used without - * being locked. - * Memory footprint considerations: this is a simple implementation of - * available ports, i.e., an ordered array of the actual port numbers. - * This will require about 256KB of memory in the worst case (128KB for - * each of IPv4 and IPv6). We could reduce it by representing it as a - * more sophisticated way such as a list (or array) of ranges that are - * searched to identify a specific port. Our decision here is the saved - * memory isn't worth the implementation complexity, considering the - * fact that the whole BIND9 process (which is mainly named) already - * requires a pretty large memory footprint. We may, however, have to - * revisit the decision when we want to use it as a separate module for - * an environment where memory requirement is severer. - */ - in_port_t *v4ports; /*%< available ports for IPv4 */ - unsigned int nv4ports; /*%< # of available ports for IPv4 */ - in_port_t *v6ports; /*%< available ports for IPv4 */ - unsigned int nv6ports; /*%< # of available ports for IPv4 */ -}; - -#define MGR_SHUTTINGDOWN 0x00000001U -#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0) - -#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0) - -struct dns_dispentry { - unsigned int magic; - dns_dispatch_t *disp; - dns_messageid_t id; - in_port_t port; - unsigned int bucket; - isc_sockaddr_t host; - isc_task_t *task; - isc_taskaction_t action; - void *arg; - bool item_out; - dispsocket_t *dispsocket; - ISC_LIST(dns_dispatchevent_t) items; - ISC_LINK(dns_dispentry_t) link; -}; - -/*% - * Maximum number of dispatch sockets that can be pooled for reuse. The - * appropriate value may vary, but experiments have shown a busy caching server - * may need more than 1000 sockets concurrently opened. The maximum allowable - * number of dispatch sockets (per manager) will be set to the double of this - * value. - */ -#ifndef DNS_DISPATCH_POOLSOCKS -#define DNS_DISPATCH_POOLSOCKS 2048 -#endif - -/*% - * Quota to control the number of dispatch sockets. If a dispatch has more - * than the quota of sockets, new queries will purge oldest ones, so that - * a massive number of outstanding queries won't prevent subsequent queries - * (especially if the older ones take longer time and result in timeout). - */ -#ifndef DNS_DISPATCH_SOCKSQUOTA -#define DNS_DISPATCH_SOCKSQUOTA 3072 -#endif - -struct dispsocket { - unsigned int magic; - isc_socket_t *socket; - dns_dispatch_t *disp; - isc_sockaddr_t host; - in_port_t localport; /* XXX: should be removed later */ - dispportentry_t *portentry; - dns_dispentry_t *resp; - isc_task_t *task; - ISC_LINK(dispsocket_t) link; - unsigned int bucket; - ISC_LINK(dispsocket_t) blink; -}; - -/*% - * A port table entry. We remember every port we first open in a table with a - * reference counter so that we can 'reuse' the same port (with different - * destination addresses) using the SO_REUSEADDR socket option. - */ -struct dispportentry { - in_port_t port; - unsigned int refs; - ISC_LINK(struct dispportentry) link; -}; - -#ifndef DNS_DISPATCH_PORTTABLESIZE -#define DNS_DISPATCH_PORTTABLESIZE 1024 -#endif - -#define INVALID_BUCKET (0xffffdead) - -/*% - * Number of tasks for each dispatch that use separate sockets for different - * transactions. This must be a power of 2 as it will divide 32 bit numbers - * to get an uniformly random tasks selection. See get_dispsocket(). - */ -#define MAX_INTERNAL_TASKS 64 - -struct dns_dispatch { - /* Unlocked. */ - unsigned int magic; /*%< magic */ - dns_dispatchmgr_t *mgr; /*%< dispatch manager */ - int ntasks; - /*% - * internal task buckets. We use multiple tasks to distribute various - * socket events well when using separate dispatch sockets. We use the - * 1st task (task[0]) for internal control events. - */ - isc_task_t *task[MAX_INTERNAL_TASKS]; - isc_socket_t *socket; /*%< isc socket attached to */ - isc_sockaddr_t local; /*%< local address */ - in_port_t localport; /*%< local UDP port */ - isc_sockaddr_t peer; /*%< peer address (TCP) */ - isc_dscp_t dscp; /*%< "listen-on" DSCP value */ - unsigned int maxrequests; /*%< max requests */ - isc_event_t *ctlevent; - - isc_mutex_t sepool_lock; - isc_mempool_t *sepool; /*%< pool for socket events */ - - /*% Locked by mgr->lock. */ - ISC_LINK(dns_dispatch_t) link; - - /* Locked by "lock". */ - isc_mutex_t lock; /*%< locks all below */ - isc_sockettype_t socktype; - unsigned int attributes; - unsigned int refcount; /*%< number of users */ - dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ - unsigned int shutting_down : 1, - shutdown_out : 1, - connected : 1, - tcpmsg_valid : 1, - recv_pending : 1; /*%< is a recv() pending? */ - isc_result_t shutdown_why; - ISC_LIST(dispsocket_t) activesockets; - ISC_LIST(dispsocket_t) inactivesockets; - unsigned int nsockets; - unsigned int requests; /*%< how many requests we have */ - unsigned int tcpbuffers; /*%< allocated buffers */ - dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ - dns_qid_t *qid; - isc_rng_t *rngctx; /*%< for QID/UDP port num */ - dispportlist_t *port_table; /*%< hold ports 'owned' by us */ - isc_mempool_t *portpool; /*%< port table entries */ -}; - -#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ') -#define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC) - -#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p') -#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC) - -#define DISPSOCK_MAGIC ISC_MAGIC('D', 's', 'o', 'c') -#define VALID_DISPSOCK(e) ISC_MAGIC_VALID((e), DISPSOCK_MAGIC) - -#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p') -#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC) - -#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r') -#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC) - -#define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \ - (disp)->qid : (disp)->mgr->qid -#define DISP_RNGCTX(disp) ((disp)->socktype == isc_sockettype_udp) ? \ - ((disp)->rngctx) : ((disp)->mgr->rngctx) - -/*% - * Locking a query port buffer is a bit tricky. We access the buffer without - * locking until qid is created. Technically, there is a possibility of race - * between the creation of qid and access to the port buffer; in practice, - * however, this should be safe because qid isn't created until the first - * dispatch is created and there should be no contending situation until then. - */ -#define PORTBUFLOCK(mgr) if ((mgr)->qid != NULL) LOCK(&((mgr)->qid->lock)) -#define PORTBUFUNLOCK(mgr) if ((mgr)->qid != NULL) UNLOCK((&(mgr)->qid->lock)) - -/* - * Statics. - */ -static dns_dispentry_t *entry_search(dns_qid_t *, isc_sockaddr_t *, - dns_messageid_t, in_port_t, unsigned int); -static bool destroy_disp_ok(dns_dispatch_t *); -static void destroy_disp(isc_task_t *task, isc_event_t *event); -static void destroy_dispsocket(dns_dispatch_t *, dispsocket_t **); -static void deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *); -static void udp_exrecv(isc_task_t *, isc_event_t *); -static void udp_shrecv(isc_task_t *, isc_event_t *); -static void udp_recv(isc_event_t *, dns_dispatch_t *, dispsocket_t *); -static void tcp_recv(isc_task_t *, isc_event_t *); -static isc_result_t startrecv(dns_dispatch_t *, dispsocket_t *); -static uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t, - in_port_t); -static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len); -static void *allocate_udp_buffer(dns_dispatch_t *disp); -static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev); -static inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp); -static void do_cancel(dns_dispatch_t *disp); -static dns_dispentry_t *linear_first(dns_qid_t *disp); -static dns_dispentry_t *linear_next(dns_qid_t *disp, - dns_dispentry_t *resp); -static void dispatch_free(dns_dispatch_t **dispp); -static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr, - dns_dispatch_t *disp, - isc_socketmgr_t *sockmgr, - isc_sockaddr_t *localaddr, - isc_socket_t **sockp, - isc_socket_t *dup_socket); -static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, - isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, - isc_sockaddr_t *localaddr, - unsigned int maxrequests, - unsigned int attributes, - dns_dispatch_t **dispp, - isc_socket_t *dup_socket); -static bool destroy_mgr_ok(dns_dispatchmgr_t *mgr); -static void destroy_mgr(dns_dispatchmgr_t **mgrp); -static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, - unsigned int increment, dns_qid_t **qidp, - bool needaddrtable); -static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp); -static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp, - isc_socket_t *dup_socket); -static bool portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_sockaddr_t *sockaddrp); - -#define LVL(x) ISC_LOG_DEBUG(x) - -static void -mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -static void -mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) { - char msgbuf[2048]; - va_list ap; - - if (! isc_log_wouldlog(dns_lctx, level)) - return; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, - level, "dispatchmgr %p: %s", mgr, msgbuf); -} - -static inline void -inc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) { - if (mgr->stats != NULL) - isc_stats_increment(mgr->stats, counter); -} - -static inline void -dec_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) { - if (mgr->stats != NULL) - isc_stats_decrement(mgr->stats, counter); -} - -static void -dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -static void -dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) { - char msgbuf[2048]; - va_list ap; - - if (! isc_log_wouldlog(dns_lctx, level)) - return; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, - level, "dispatch %p: %s", disp, msgbuf); -} - -static void -request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, - int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(4, 5); - -static void -request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, - int level, const char *fmt, ...) -{ - char msgbuf[2048]; - char peerbuf[256]; - va_list ap; - - if (! isc_log_wouldlog(dns_lctx, level)) - return; - - va_start(ap, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - va_end(ap); - - if (VALID_RESPONSE(resp)) { - isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, - DNS_LOGMODULE_DISPATCH, level, - "dispatch %p response %p %s: %s", disp, resp, - peerbuf, msgbuf); - } else { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, - DNS_LOGMODULE_DISPATCH, level, - "dispatch %p req/resp %p: %s", disp, resp, - msgbuf); - } -} - -/* - * Return a hash of the destination and message id. - */ -static uint32_t -dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id, - in_port_t port) -{ - uint32_t ret; - - ret = isc_sockaddr_hash(dest, true); - ret ^= ((uint32_t)id << 16) | port; - ret %= qid->qid_nbuckets; - - INSIST(ret < qid->qid_nbuckets); - - return (ret); -} - -/* - * Find the first entry in 'qid'. Returns NULL if there are no entries. - */ -static dns_dispentry_t * -linear_first(dns_qid_t *qid) { - dns_dispentry_t *ret; - unsigned int bucket; - - bucket = 0; - - while (bucket < qid->qid_nbuckets) { - ret = ISC_LIST_HEAD(qid->qid_table[bucket]); - if (ret != NULL) - return (ret); - bucket++; - } - - return (NULL); -} - -/* - * Find the next entry after 'resp' in 'qid'. Return NULL if there are - * no more entries. - */ -static dns_dispentry_t * -linear_next(dns_qid_t *qid, dns_dispentry_t *resp) { - dns_dispentry_t *ret; - unsigned int bucket; - - ret = ISC_LIST_NEXT(resp, link); - if (ret != NULL) - return (ret); - - bucket = resp->bucket; - bucket++; - while (bucket < qid->qid_nbuckets) { - ret = ISC_LIST_HEAD(qid->qid_table[bucket]); - if (ret != NULL) - return (ret); - bucket++; - } - - return (NULL); -} - -/* - * The dispatch must be locked. - */ -static bool -destroy_disp_ok(dns_dispatch_t *disp) -{ - if (disp->refcount != 0) - return (false); - - if (disp->recv_pending != 0) - return (false); - - if (!ISC_LIST_EMPTY(disp->activesockets)) - return (false); - - if (disp->shutting_down == 0) - return (false); - - return (true); -} - -/* - * Called when refcount reaches 0 (and safe to destroy). - * - * The dispatcher must be locked. - * The manager must not be locked. - */ -static void -destroy_disp(isc_task_t *task, isc_event_t *event) { - dns_dispatch_t *disp; - dns_dispatchmgr_t *mgr; - bool killmgr; - dispsocket_t *dispsocket; - int i; - - INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL); - - UNUSED(task); - - disp = event->ev_arg; - mgr = disp->mgr; - - LOCK(&mgr->lock); - ISC_LIST_UNLINK(mgr->list, disp, link); - - dispatch_log(disp, LVL(90), - "shutting down; detaching from sock %p, task %p", - disp->socket, disp->task[0]); /* XXXX */ - - if (disp->sepool != NULL) { - isc_mempool_destroy(&disp->sepool); - (void)isc_mutex_destroy(&disp->sepool_lock); - } - - if (disp->socket != NULL) - isc_socket_detach(&disp->socket); - while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) { - ISC_LIST_UNLINK(disp->inactivesockets, dispsocket, link); - destroy_dispsocket(disp, &dispsocket); - } - for (i = 0; i < disp->ntasks; i++) - isc_task_detach(&disp->task[i]); - isc_event_free(&event); - - dispatch_free(&disp); - - killmgr = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - if (killmgr) - destroy_mgr(&mgr); -} - -/*% - * Manipulate port table per dispatch: find an entry for a given port number, - * create a new entry, and decrement a given entry with possible clean-up. - */ -static dispportentry_t * -port_search(dns_dispatch_t *disp, in_port_t port) { - dispportentry_t *portentry; - - REQUIRE(disp->port_table != NULL); - - portentry = ISC_LIST_HEAD(disp->port_table[port % - DNS_DISPATCH_PORTTABLESIZE]); - while (portentry != NULL) { - if (portentry->port == port) - return (portentry); - portentry = ISC_LIST_NEXT(portentry, link); - } - - return (NULL); -} - -static dispportentry_t * -new_portentry(dns_dispatch_t *disp, in_port_t port) { - dispportentry_t *portentry; - dns_qid_t *qid; - - REQUIRE(disp->port_table != NULL); - - portentry = isc_mempool_get(disp->portpool); - if (portentry == NULL) - return (portentry); - - portentry->port = port; - portentry->refs = 1; - ISC_LINK_INIT(portentry, link); - qid = DNS_QID(disp); - LOCK(&qid->lock); - ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE], - portentry, link); - UNLOCK(&qid->lock); - - return (portentry); -} - -/*% - * The caller must hold the qid->lock. - */ -static void -deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { - dispportentry_t *portentry = *portentryp; - *portentryp = NULL; - - REQUIRE(disp->port_table != NULL); - REQUIRE(portentry != NULL && portentry->refs > 0); - - if (--portentry->refs == 0) { - ISC_LIST_UNLINK(disp->port_table[portentry->port % - DNS_DISPATCH_PORTTABLESIZE], - portentry, link); - isc_mempool_put(disp->portpool, portentry); - } -} - -/*% - * Find a dispsocket for socket address 'dest', and port number 'port'. - * Return NULL if no such entry exists. Requires qid->lock to be held. - */ -static dispsocket_t * -socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port, - unsigned int bucket) -{ - dispsocket_t *dispsock; - - REQUIRE(VALID_QID(qid)); - REQUIRE(bucket < qid->qid_nbuckets); - - dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]); - - while (dispsock != NULL) { - if (dispsock->portentry != NULL && - dispsock->portentry->port == port && - isc_sockaddr_equal(dest, &dispsock->host)) - return (dispsock); - dispsock = ISC_LIST_NEXT(dispsock, blink); - } - - return (NULL); -} - -/*% - * Make a new socket for a single dispatch with a random port number. - * The caller must hold the disp->lock - */ -static isc_result_t -get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp, - in_port_t *portp) -{ - int i; - uint32_t r; - dns_dispatchmgr_t *mgr = disp->mgr; - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_FAILURE; - in_port_t port; - isc_sockaddr_t localaddr; - unsigned int bucket = 0; - dispsocket_t *dispsock; - unsigned int nports; - in_port_t *ports; - unsigned int bindoptions; - dispportentry_t *portentry = NULL; - dns_qid_t *qid; - - if (isc_sockaddr_pf(&disp->local) == AF_INET) { - nports = disp->mgr->nv4ports; - ports = disp->mgr->v4ports; - } else { - nports = disp->mgr->nv6ports; - ports = disp->mgr->v6ports; - } - if (nports == 0) - return (ISC_R_ADDRNOTAVAIL); - - dispsock = ISC_LIST_HEAD(disp->inactivesockets); - if (dispsock != NULL) { - ISC_LIST_UNLINK(disp->inactivesockets, dispsock, link); - sock = dispsock->socket; - dispsock->socket = NULL; - } else { - dispsock = isc_mempool_get(mgr->spool); - if (dispsock == NULL) - return (ISC_R_NOMEMORY); - - disp->nsockets++; - dispsock->socket = NULL; - dispsock->disp = disp; - dispsock->resp = NULL; - dispsock->portentry = NULL; - isc_random_get(&r); - dispsock->task = NULL; - isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task); - ISC_LINK_INIT(dispsock, link); - ISC_LINK_INIT(dispsock, blink); - dispsock->magic = DISPSOCK_MAGIC; - } - - /* - * Pick up a random UDP port and open a new socket with it. Avoid - * choosing ports that share the same destination because it will be - * very likely to fail in bind(2) or connect(2). - */ - localaddr = disp->local; - qid = DNS_QID(disp); - - for (i = 0; i < 64; i++) { - port = ports[isc_rng_uniformrandom(DISP_RNGCTX(disp), nports)]; - isc_sockaddr_setport(&localaddr, port); - - LOCK(&qid->lock); - bucket = dns_hash(qid, dest, 0, port); - if (socket_search(qid, dest, port, bucket) != NULL) { - UNLOCK(&qid->lock); - continue; - } - UNLOCK(&qid->lock); - bindoptions = 0; - portentry = port_search(disp, port); - - if (portentry != NULL) - bindoptions |= ISC_SOCKET_REUSEADDRESS; - result = open_socket(sockmgr, &localaddr, bindoptions, &sock, - NULL); - if (result == ISC_R_SUCCESS) { - if (portentry == NULL) { - portentry = new_portentry(disp, port); - if (portentry == NULL) { - result = ISC_R_NOMEMORY; - break; - } - } else { - LOCK(&qid->lock); - portentry->refs++; - UNLOCK(&qid->lock); - } - break; - } else if (result == ISC_R_NOPERM) { - char buf[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&localaddr, buf, sizeof(buf)); - dispatch_log(disp, ISC_LOG_WARNING, - "open_socket(%s) -> %s: continuing", - buf, isc_result_totext(result)); - } else if (result != ISC_R_ADDRINUSE) - break; - } - - if (result == ISC_R_SUCCESS) { - dispsock->socket = sock; - dispsock->host = *dest; - dispsock->bucket = bucket; - LOCK(&qid->lock); - dispsock->portentry = portentry; - ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); - UNLOCK(&qid->lock); - *dispsockp = dispsock; - *portp = port; - } else { - /* - * We could keep it in the inactive list, but since this should - * be an exceptional case and might be resource shortage, we'd - * rather destroy it. - */ - if (sock != NULL) - isc_socket_detach(&sock); - destroy_dispsocket(disp, &dispsock); - } - - return (result); -} - -/*% - * Destroy a dedicated dispatch socket. - */ -static void -destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) { - dispsocket_t *dispsock; - dns_qid_t *qid = DNS_QID(disp); - - /* - * The dispatch must be locked. - */ - - REQUIRE(dispsockp != NULL && *dispsockp != NULL); - dispsock = *dispsockp; - REQUIRE(!ISC_LINK_LINKED(dispsock, link)); - - disp->nsockets--; - dispsock->magic = 0; - if (dispsock->portentry != NULL) { - /* socket_search() tests and dereferences portentry. */ - LOCK(&qid->lock); - deref_portentry(disp, &dispsock->portentry); - UNLOCK(&qid->lock); - } - if (dispsock->socket != NULL) { - isc_socket_detach(&dispsock->socket); - } - if (ISC_LINK_LINKED(dispsock, blink)) { - LOCK(&qid->lock); - ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock, - blink); - UNLOCK(&qid->lock); - } - if (dispsock->task != NULL) { - isc_task_detach(&dispsock->task); - } - isc_mempool_put(disp->mgr->spool, dispsock); - - *dispsockp = NULL; -} - -/*% - * Deactivate a dedicated dispatch socket. Move it to the inactive list for - * future reuse unless the total number of sockets are exceeding the maximum. - */ -static void -deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) { - isc_result_t result; - dns_qid_t *qid = DNS_QID(disp); - - /* - * The dispatch must be locked. - */ - ISC_LIST_UNLINK(disp->activesockets, dispsock, link); - if (dispsock->resp != NULL) { - INSIST(dispsock->resp->dispsocket == dispsock); - dispsock->resp->dispsocket = NULL; - } - - INSIST(dispsock->portentry != NULL); - /* socket_search() tests and dereferences portentry. */ - LOCK(&qid->lock); - deref_portentry(disp, &dispsock->portentry); - UNLOCK(&qid->lock); - - if (disp->nsockets > DNS_DISPATCH_POOLSOCKS) - destroy_dispsocket(disp, &dispsock); - else { - result = isc_socket_close(dispsock->socket); - - LOCK(&qid->lock); - ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock, - blink); - UNLOCK(&qid->lock); - - if (result == ISC_R_SUCCESS) - ISC_LIST_APPEND(disp->inactivesockets, dispsock, link); - else { - /* - * If the underlying system does not allow this - * optimization, destroy this temporary structure (and - * create a new one for a new transaction). - */ - INSIST(result == ISC_R_NOTIMPLEMENTED); - destroy_dispsocket(disp, &dispsock); - } - } -} - -/* - * Find an entry for query ID 'id', socket address 'dest', and port number - * 'port'. - * Return NULL if no such entry exists. - */ -static dns_dispentry_t * -entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id, - in_port_t port, unsigned int bucket) -{ - dns_dispentry_t *res; - - REQUIRE(VALID_QID(qid)); - REQUIRE(bucket < qid->qid_nbuckets); - - res = ISC_LIST_HEAD(qid->qid_table[bucket]); - - while (res != NULL) { - if (res->id == id && isc_sockaddr_equal(dest, &res->host) && - res->port == port) { - return (res); - } - res = ISC_LIST_NEXT(res, link); - } - - return (NULL); -} - -static void -free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { - isc_mempool_t *bpool; - INSIST(buf != NULL && len != 0); - - - switch (disp->socktype) { - case isc_sockettype_tcp: - INSIST(disp->tcpbuffers > 0); - disp->tcpbuffers--; - isc_mem_put(disp->mgr->mctx, buf, len); - break; - case isc_sockettype_udp: - LOCK(&disp->mgr->buffer_lock); - INSIST(disp->mgr->buffers > 0); - INSIST(len == disp->mgr->buffersize); - disp->mgr->buffers--; - bpool = disp->mgr->bpool; - UNLOCK(&disp->mgr->buffer_lock); - isc_mempool_put(bpool, buf); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void * -allocate_udp_buffer(dns_dispatch_t *disp) { - isc_mempool_t *bpool; - void *temp; - - LOCK(&disp->mgr->buffer_lock); - if (disp->mgr->buffers >= disp->mgr->maxbuffers) { - UNLOCK(&disp->mgr->buffer_lock); - return (NULL); - } - bpool = disp->mgr->bpool; - disp->mgr->buffers++; - UNLOCK(&disp->mgr->buffer_lock); - - temp = isc_mempool_get(bpool); - - if (temp == NULL) { - LOCK(&disp->mgr->buffer_lock); - disp->mgr->buffers--; - UNLOCK(&disp->mgr->buffer_lock); - } - - return (temp); -} - -static inline void -free_sevent(isc_event_t *ev) { - isc_mempool_t *pool = ev->ev_destroy_arg; - isc_socketevent_t *sev = (isc_socketevent_t *) ev; - isc_mempool_put(pool, sev); -} - -static inline isc_socketevent_t * -allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock, - isc_eventtype_t type, isc_taskaction_t action, const void *arg) -{ - isc_socketevent_t *ev; - void *deconst_arg; - - ev = isc_mempool_get(disp->sepool); - if (ev == NULL) - return (NULL); - DE_CONST(arg, deconst_arg); - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, - action, deconst_arg, sock, - free_sevent, disp->sepool); - ev->result = ISC_R_UNSET; - ISC_LINK_INIT(ev, ev_link); - ISC_LIST_INIT(ev->bufferlist); - ev->region.base = NULL; - ev->n = 0; - ev->offset = 0; - ev->attributes = 0; - - return (ev); -} - - -static inline void -free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { - if (disp->failsafe_ev == ev) { - INSIST(disp->shutdown_out == 1); - disp->shutdown_out = 0; - - return; - } - - isc_mempool_put(disp->mgr->depool, ev); -} - -static inline dns_dispatchevent_t * -allocate_devent(dns_dispatch_t *disp) { - dns_dispatchevent_t *ev; - - ev = isc_mempool_get(disp->mgr->depool); - if (ev == NULL) - return (NULL); - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, - NULL, NULL, NULL, NULL, NULL); - - return (ev); -} - -static void -udp_exrecv(isc_task_t *task, isc_event_t *ev) { - dispsocket_t *dispsock = ev->ev_arg; - - UNUSED(task); - - REQUIRE(VALID_DISPSOCK(dispsock)); - udp_recv(ev, dispsock->disp, dispsock); -} - -static void -udp_shrecv(isc_task_t *task, isc_event_t *ev) { - dns_dispatch_t *disp = ev->ev_arg; - - UNUSED(task); - - REQUIRE(VALID_DISPATCH(disp)); - udp_recv(ev, disp, NULL); -} - -/* - * General flow: - * - * If I/O result == CANCELED or error, free the buffer. - * - * If query, free the buffer, restart. - * - * If response: - * Allocate event, fill in details. - * If cannot allocate, free buffer, restart. - * find target. If not found, free buffer, restart. - * if event queue is not empty, queue. else, send. - * restart. - */ -static void -udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { - isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; - dns_messageid_t id; - isc_result_t dres; - isc_buffer_t source; - unsigned int flags; - dns_dispentry_t *resp = NULL; - dns_dispatchevent_t *rev; - unsigned int bucket; - bool killit; - bool queue_response; - dns_dispatchmgr_t *mgr; - dns_qid_t *qid; - isc_netaddr_t netaddr; - int match; - int result; - bool qidlocked = false; - - LOCK(&disp->lock); - - mgr = disp->mgr; - qid = mgr->qid; - - LOCK(&disp->mgr->buffer_lock); - dispatch_log(disp, LVL(90), - "got packet: requests %d, buffers %d, recvs %d", - disp->requests, disp->mgr->buffers, disp->recv_pending); - UNLOCK(&disp->mgr->buffer_lock); - - if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) { - /* - * Unless the receive event was imported from a listening - * interface, in which case the event type is - * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending. - */ - INSIST(disp->recv_pending != 0); - disp->recv_pending = 0; - } - - if (dispsock != NULL && - (ev->result == ISC_R_CANCELED || dispsock->resp == NULL)) { - /* - * dispsock->resp can be NULL if this transaction was canceled - * just after receiving a response. Since this socket is - * exclusively used and there should be at most one receive - * event the canceled event should have been no effect. So - * we can (and should) deactivate the socket right now. - */ - deactivate_dispsocket(disp, dispsock); - dispsock = NULL; - } - - if (disp->shutting_down) { - /* - * This dispatcher is shutting down. - */ - free_buffer(disp, ev->region.base, ev->region.length); - - isc_event_free(&ev_in); - ev = NULL; - - killit = destroy_disp_ok(disp); - UNLOCK(&disp->lock); - if (killit) - isc_task_send(disp->task[0], &disp->ctlevent); - - return; - } - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - if (dispsock != NULL) { - resp = dispsock->resp; - id = resp->id; - if (ev->result != ISC_R_SUCCESS) { - /* - * This is most likely a network error on a - * connected socket. It makes no sense to - * check the address or parse the packet, but it - * will help to return the error to the caller. - */ - goto sendresponse; - } - } else { - free_buffer(disp, ev->region.base, ev->region.length); - - isc_event_free(&ev_in); - UNLOCK(&disp->lock); - return; - } - } else if (ev->result != ISC_R_SUCCESS) { - free_buffer(disp, ev->region.base, ev->region.length); - - if (ev->result != ISC_R_CANCELED) - dispatch_log(disp, ISC_LOG_ERROR, - "odd socket result in udp_recv(): %s", - isc_result_totext(ev->result)); - - isc_event_free(&ev_in); - UNLOCK(&disp->lock); - return; - } - - /* - * If this is from a blackholed address, drop it. - */ - isc_netaddr_fromsockaddr(&netaddr, &ev->address); - if (disp->mgr->blackhole != NULL && - dns_acl_match(&netaddr, NULL, disp->mgr->blackhole, - NULL, &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - if (isc_log_wouldlog(dns_lctx, LVL(10))) { - char netaddrstr[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_format(&netaddr, netaddrstr, - sizeof(netaddrstr)); - dispatch_log(disp, LVL(10), - "blackholed packet from %s", - netaddrstr); - } - free_buffer(disp, ev->region.base, ev->region.length); - goto restart; - } - - /* - * Peek into the buffer to see what we can see. - */ - isc_buffer_init(&source, ev->region.base, ev->region.length); - isc_buffer_add(&source, ev->n); - dres = dns_message_peekheader(&source, &id, &flags); - if (dres != ISC_R_SUCCESS) { - free_buffer(disp, ev->region.base, ev->region.length); - dispatch_log(disp, LVL(10), "got garbage packet"); - goto restart; - } - - dispatch_log(disp, LVL(92), - "got valid DNS message header, /QR %c, id %u", - (((flags & DNS_MESSAGEFLAG_QR) != 0) ? '1' : '0'), id); - - /* - * Look at flags. If query, drop it. If response, - * look to see where it goes. - */ - if ((flags & DNS_MESSAGEFLAG_QR) == 0) { - /* query */ - free_buffer(disp, ev->region.base, ev->region.length); - goto restart; - } - - /* - * Search for the corresponding response. If we are using an exclusive - * socket, we've already identified it and we can skip the search; but - * the ID and the address must match the expected ones. - */ - if (resp == NULL) { - bucket = dns_hash(qid, &ev->address, id, disp->localport); - LOCK(&qid->lock); - qidlocked = true; - resp = entry_search(qid, &ev->address, id, disp->localport, - bucket); - dispatch_log(disp, LVL(90), - "search for response in bucket %d: %s", - bucket, (resp == NULL ? "not found" : "found")); - - } else if (resp->id != id || !isc_sockaddr_equal(&ev->address, - &resp->host)) { - dispatch_log(disp, LVL(90), - "response to an exclusive socket doesn't match"); - inc_stats(mgr, dns_resstatscounter_mismatch); - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - - if (resp == NULL) { - inc_stats(mgr, dns_resstatscounter_mismatch); - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - - /* - * Now that we have the original dispatch the query was sent - * from check that the address and port the response was - * sent to make sense. - */ - if (disp != resp->disp) { - isc_sockaddr_t a1; - isc_sockaddr_t a2; - - /* - * Check that the socket types and ports match. - */ - if (disp->socktype != resp->disp->socktype || - isc_sockaddr_getport(&disp->local) != - isc_sockaddr_getport(&resp->disp->local)) { - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - - /* - * If each dispatch is bound to a different address - * then fail. - * - * Note under Linux a packet can be sent out via IPv4 socket - * and the response be received via a IPv6 socket. - * - * Requests sent out via IPv6 should always come back in - * via IPv6. - */ - if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 && - isc_sockaddr_pf(&disp->local) != PF_INET6) { - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local)); - isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local)); - if (!isc_sockaddr_eqaddr(&disp->local, &resp->disp->local) && - !isc_sockaddr_eqaddr(&a1, &resp->disp->local) && - !isc_sockaddr_eqaddr(&a2, &disp->local)) { - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - } - - sendresponse: - queue_response = resp->item_out; - rev = allocate_devent(resp->disp); - if (rev == NULL) { - free_buffer(disp, ev->region.base, ev->region.length); - goto unlock; - } - - /* - * At this point, rev contains the event we want to fill in, and - * resp contains the information on the place to send it to. - * Send the event off. - */ - isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length); - isc_buffer_add(&rev->buffer, ev->n); - rev->result = ev->result; - rev->id = id; - rev->addr = ev->address; - rev->pktinfo = ev->pktinfo; - rev->attributes = ev->attributes; - if (queue_response) { - ISC_LIST_APPEND(resp->items, rev, ev_link); - } else { - ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, - DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - request_log(disp, resp, LVL(90), - "[a] Sent event %p buffer %p len %d to task %p", - rev, rev->buffer.base, rev->buffer.length, - resp->task); - resp->item_out = true; - isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); - } - unlock: - if (qidlocked) - UNLOCK(&qid->lock); - - /* - * Restart recv() to get the next packet. - */ - restart: - result = startrecv(disp, dispsock); - if (result != ISC_R_SUCCESS && dispsock != NULL) { - /* - * XXX: wired. There seems to be no recovery process other than - * deactivate this socket anyway (since we cannot start - * receiving, we won't be able to receive a cancel event - * from the user). - */ - deactivate_dispsocket(disp, dispsock); - } - isc_event_free(&ev_in); - UNLOCK(&disp->lock); -} - -/* - * General flow: - * - * If I/O result == CANCELED, EOF, or error, notify everyone as the - * various queues drain. - * - * If query, restart. - * - * If response: - * Allocate event, fill in details. - * If cannot allocate, restart. - * find target. If not found, restart. - * if event queue is not empty, queue. else, send. - * restart. - */ -static void -tcp_recv(isc_task_t *task, isc_event_t *ev_in) { - dns_dispatch_t *disp = ev_in->ev_arg; - dns_tcpmsg_t *tcpmsg = &disp->tcpmsg; - dns_messageid_t id; - isc_result_t dres; - unsigned int flags; - dns_dispentry_t *resp; - dns_dispatchevent_t *rev; - unsigned int bucket; - bool killit; - bool queue_response; - dns_qid_t *qid; - int level; - char buf[ISC_SOCKADDR_FORMATSIZE]; - - UNUSED(task); - - REQUIRE(VALID_DISPATCH(disp)); - - qid = disp->qid; - - LOCK(&disp->lock); - - dispatch_log(disp, LVL(90), - "got TCP packet: requests %d, buffers %d, recvs %d", - disp->requests, disp->tcpbuffers, disp->recv_pending); - - INSIST(disp->recv_pending != 0); - disp->recv_pending = 0; - - if (disp->refcount == 0) { - /* - * This dispatcher is shutting down. Force cancellation. - */ - tcpmsg->result = ISC_R_CANCELED; - } - - if (tcpmsg->result != ISC_R_SUCCESS) { - switch (tcpmsg->result) { - case ISC_R_CANCELED: - break; - - case ISC_R_EOF: - dispatch_log(disp, LVL(90), "shutting down on EOF"); - do_cancel(disp); - break; - - case ISC_R_CONNECTIONRESET: - level = ISC_LOG_INFO; - goto logit; - - default: - level = ISC_LOG_ERROR; - logit: - isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf)); - dispatch_log(disp, level, "shutting down due to TCP " - "receive error: %s: %s", buf, - isc_result_totext(tcpmsg->result)); - do_cancel(disp); - break; - } - - /* - * The event is statically allocated in the tcpmsg - * structure, and destroy_disp() frees the tcpmsg, so we must - * free the event *before* calling destroy_disp(). - */ - isc_event_free(&ev_in); - - disp->shutting_down = 1; - disp->shutdown_why = tcpmsg->result; - - /* - * If the recv() was canceled pass the word on. - */ - killit = destroy_disp_ok(disp); - UNLOCK(&disp->lock); - if (killit) - isc_task_send(disp->task[0], &disp->ctlevent); - return; - } - - dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p", - tcpmsg->result, - tcpmsg->buffer.length, tcpmsg->buffer.base); - - /* - * Peek into the buffer to see what we can see. - */ - dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags); - if (dres != ISC_R_SUCCESS) { - dispatch_log(disp, LVL(10), "got garbage packet"); - goto restart; - } - - dispatch_log(disp, LVL(92), - "got valid DNS message header, /QR %c, id %u", - (((flags & DNS_MESSAGEFLAG_QR) != 0) ? '1' : '0'), id); - - /* - * Allocate an event to send to the query or response client, and - * allocate a new buffer for our use. - */ - - /* - * Look at flags. If query, drop it. If response, - * look to see where it goes. - */ - if ((flags & DNS_MESSAGEFLAG_QR) == 0) { - /* - * Query. - */ - goto restart; - } - - /* - * Response. - */ - bucket = dns_hash(qid, &tcpmsg->address, id, disp->localport); - LOCK(&qid->lock); - resp = entry_search(qid, &tcpmsg->address, id, disp->localport, bucket); - dispatch_log(disp, LVL(90), - "search for response in bucket %d: %s", - bucket, (resp == NULL ? "not found" : "found")); - - if (resp == NULL) - goto unlock; - queue_response = resp->item_out; - rev = allocate_devent(disp); - if (rev == NULL) - goto unlock; - - /* - * At this point, rev contains the event we want to fill in, and - * resp contains the information on the place to send it to. - * Send the event off. - */ - dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer); - disp->tcpbuffers++; - rev->result = ISC_R_SUCCESS; - rev->id = id; - rev->addr = tcpmsg->address; - if (queue_response) { - ISC_LIST_APPEND(resp->items, rev, ev_link); - } else { - ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - request_log(disp, resp, LVL(90), - "[b] Sent event %p buffer %p len %d to task %p", - rev, rev->buffer.base, rev->buffer.length, - resp->task); - resp->item_out = true; - isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); - } - unlock: - UNLOCK(&qid->lock); - - /* - * Restart recv() to get the next packet. - */ - restart: - (void)startrecv(disp, NULL); - - isc_event_free(&ev_in); - UNLOCK(&disp->lock); -} - -/* - * disp must be locked. - */ -static isc_result_t -startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { - isc_result_t res; - isc_region_t region; - isc_socket_t *sock; - - if (disp->shutting_down == 1) - return (ISC_R_SUCCESS); - - if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) - return (ISC_R_SUCCESS); - - if (disp->recv_pending != 0 && dispsock == NULL) - return (ISC_R_SUCCESS); - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && - dispsock == NULL) - return (ISC_R_SUCCESS); - - if (dispsock != NULL) - sock = dispsock->socket; - else - sock = disp->socket; - INSIST(sock != NULL); - - switch (disp->socktype) { - /* - * UDP reads are always maximal. - */ - case isc_sockettype_udp: - region.length = disp->mgr->buffersize; - region.base = allocate_udp_buffer(disp); - if (region.base == NULL) - return (ISC_R_NOMEMORY); - if (dispsock != NULL) { - isc_task_t *dt = dispsock->task; - isc_socketevent_t *sev = - allocate_sevent(disp, sock, - ISC_SOCKEVENT_RECVDONE, - udp_exrecv, dispsock); - if (sev == NULL) { - free_buffer(disp, region.base, region.length); - return (ISC_R_NOMEMORY); - } - - res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); - if (res != ISC_R_SUCCESS) { - free_buffer(disp, region.base, region.length); - return (res); - } - } else { - isc_task_t *dt = disp->task[0]; - isc_socketevent_t *sev = - allocate_sevent(disp, sock, - ISC_SOCKEVENT_RECVDONE, - udp_shrecv, disp); - if (sev == NULL) { - free_buffer(disp, region.base, region.length); - return (ISC_R_NOMEMORY); - } - - res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); - if (res != ISC_R_SUCCESS) { - free_buffer(disp, region.base, region.length); - disp->shutdown_why = res; - disp->shutting_down = 1; - do_cancel(disp); - return (ISC_R_SUCCESS); /* recover by cancel */ - } - INSIST(disp->recv_pending == 0); - disp->recv_pending = 1; - } - break; - - case isc_sockettype_tcp: - res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task[0], - tcp_recv, disp); - if (res != ISC_R_SUCCESS) { - disp->shutdown_why = res; - disp->shutting_down = 1; - do_cancel(disp); - return (ISC_R_SUCCESS); /* recover by cancel */ - } - INSIST(disp->recv_pending == 0); - disp->recv_pending = 1; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - return (ISC_R_SUCCESS); -} - -/* - * Mgr must be locked when calling this function. - */ -static bool -destroy_mgr_ok(dns_dispatchmgr_t *mgr) { - mgr_log(mgr, LVL(90), - "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, " - "depool=%d, rpool=%d, dpool=%d", - MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list), - isc_mempool_getallocated(mgr->depool), - isc_mempool_getallocated(mgr->rpool), - isc_mempool_getallocated(mgr->dpool)); - if (!MGR_IS_SHUTTINGDOWN(mgr)) - return (false); - if (!ISC_LIST_EMPTY(mgr->list)) - return (false); - if (isc_mempool_getallocated(mgr->depool) != 0) - return (false); - if (isc_mempool_getallocated(mgr->rpool) != 0) - return (false); - if (isc_mempool_getallocated(mgr->dpool) != 0) - return (false); - - return (true); -} - -/* - * Mgr must be unlocked when calling this function. - */ -static void -destroy_mgr(dns_dispatchmgr_t **mgrp) { - isc_mem_t *mctx; - dns_dispatchmgr_t *mgr; - - mgr = *mgrp; - *mgrp = NULL; - - mctx = mgr->mctx; - - mgr->magic = 0; - mgr->mctx = NULL; - DESTROYLOCK(&mgr->lock); - mgr->state = 0; - - if (mgr->rngctx != NULL) - isc_rng_detach(&mgr->rngctx); - DESTROYLOCK(&mgr->rng_lock); - - isc_mempool_destroy(&mgr->depool); - isc_mempool_destroy(&mgr->rpool); - isc_mempool_destroy(&mgr->dpool); - if (mgr->bpool != NULL) - isc_mempool_destroy(&mgr->bpool); - if (mgr->spool != NULL) - isc_mempool_destroy(&mgr->spool); - - DESTROYLOCK(&mgr->spool_lock); - DESTROYLOCK(&mgr->bpool_lock); - DESTROYLOCK(&mgr->dpool_lock); - DESTROYLOCK(&mgr->rpool_lock); - DESTROYLOCK(&mgr->depool_lock); - - if (mgr->entropy != NULL) - isc_entropy_detach(&mgr->entropy); - if (mgr->qid != NULL) - qid_destroy(mctx, &mgr->qid); - - DESTROYLOCK(&mgr->buffer_lock); - - if (mgr->blackhole != NULL) - dns_acl_detach(&mgr->blackhole); - - if (mgr->stats != NULL) - isc_stats_detach(&mgr->stats); - - if (mgr->v4ports != NULL) { - isc_mem_put(mctx, mgr->v4ports, - mgr->nv4ports * sizeof(in_port_t)); - } - if (mgr->v6ports != NULL) { - isc_mem_put(mctx, mgr->v6ports, - mgr->nv6ports * sizeof(in_port_t)); - } - isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); - isc_mem_detach(&mctx); -} - -static isc_result_t -open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp, - isc_socket_t *dup_socket) -{ - isc_socket_t *sock; - isc_result_t result; - - sock = *sockp; - if (sock != NULL) { - result = isc_socket_open(sock); - if (result != ISC_R_SUCCESS) - return (result); - } else if (dup_socket != NULL) { - result = isc_socket_dup(dup_socket, &sock); - if (result != ISC_R_SUCCESS) - return (result); - - isc_socket_setname(sock, "dispatcher", NULL); - *sockp = sock; - return (ISC_R_SUCCESS); - } else { - result = isc_socket_create(mgr, isc_sockaddr_pf(local), - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) - return (result); - } - - isc_socket_setname(sock, "dispatcher", NULL); - -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(sock, true); -#endif - result = isc_socket_bind(sock, local, options); - if (result != ISC_R_SUCCESS) { - if (*sockp == NULL) - isc_socket_detach(&sock); - else { - isc_socket_close(sock); - } - return (result); - } - - *sockp = sock; - return (ISC_R_SUCCESS); -} - -/*% - * Create a temporary port list to set the initial default set of dispatch - * ports: [1024, 65535]. This is almost meaningless as the application will - * normally set the ports explicitly, but is provided to fill some minor corner - * cases. - */ -static isc_result_t -create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) { - isc_result_t result; - - result = isc_portset_create(mctx, portsetp); - if (result != ISC_R_SUCCESS) - return (result); - isc_portset_addrange(*portsetp, 1024, 65535); - - return (ISC_R_SUCCESS); -} - -/* - * Publics. - */ - -isc_result_t -dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, - dns_dispatchmgr_t **mgrp) -{ - dns_dispatchmgr_t *mgr; - isc_result_t result; - isc_portset_t *v4portset = NULL; - isc_portset_t *v6portset = NULL; - - REQUIRE(mctx != NULL); - REQUIRE(mgrp != NULL && *mgrp == NULL); - - mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t)); - if (mgr == NULL) - return (ISC_R_NOMEMORY); - - mgr->mctx = NULL; - isc_mem_attach(mctx, &mgr->mctx); - - mgr->blackhole = NULL; - mgr->stats = NULL; - mgr->rngctx = NULL; - - result = isc_mutex_init(&mgr->lock); - if (result != ISC_R_SUCCESS) - goto deallocate; - - result = isc_mutex_init(&mgr->rng_lock); - if (result != ISC_R_SUCCESS) - goto kill_lock; - - result = isc_mutex_init(&mgr->buffer_lock); - if (result != ISC_R_SUCCESS) - goto kill_rng_lock; - - result = isc_mutex_init(&mgr->depool_lock); - if (result != ISC_R_SUCCESS) - goto kill_buffer_lock; - - result = isc_mutex_init(&mgr->rpool_lock); - if (result != ISC_R_SUCCESS) - goto kill_depool_lock; - - result = isc_mutex_init(&mgr->dpool_lock); - if (result != ISC_R_SUCCESS) - goto kill_rpool_lock; - - result = isc_mutex_init(&mgr->bpool_lock); - if (result != ISC_R_SUCCESS) - goto kill_dpool_lock; - - result = isc_mutex_init(&mgr->spool_lock); - if (result != ISC_R_SUCCESS) - goto kill_bpool_lock; - - mgr->depool = NULL; - if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t), - &mgr->depool) != ISC_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto kill_spool_lock; - } - - mgr->rpool = NULL; - if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t), - &mgr->rpool) != ISC_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto kill_depool; - } - - mgr->dpool = NULL; - if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t), - &mgr->dpool) != ISC_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto kill_rpool; - } - - isc_mempool_setname(mgr->depool, "dispmgr_depool"); - isc_mempool_setmaxalloc(mgr->depool, 32768); - isc_mempool_setfreemax(mgr->depool, 32768); - isc_mempool_associatelock(mgr->depool, &mgr->depool_lock); - isc_mempool_setfillcount(mgr->depool, 32); - - isc_mempool_setname(mgr->rpool, "dispmgr_rpool"); - isc_mempool_setmaxalloc(mgr->rpool, 32768); - isc_mempool_setfreemax(mgr->rpool, 32768); - isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock); - isc_mempool_setfillcount(mgr->rpool, 32); - - isc_mempool_setname(mgr->dpool, "dispmgr_dpool"); - isc_mempool_setmaxalloc(mgr->dpool, 32768); - isc_mempool_setfreemax(mgr->dpool, 32768); - isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock); - isc_mempool_setfillcount(mgr->dpool, 32); - - mgr->buffers = 0; - mgr->buffersize = 0; - mgr->maxbuffers = 0; - mgr->bpool = NULL; - mgr->spool = NULL; - mgr->entropy = NULL; - mgr->qid = NULL; - mgr->state = 0; - ISC_LIST_INIT(mgr->list); - mgr->v4ports = NULL; - mgr->v6ports = NULL; - mgr->nv4ports = 0; - mgr->nv6ports = 0; - mgr->magic = DNS_DISPATCHMGR_MAGIC; - - result = create_default_portset(mctx, &v4portset); - if (result == ISC_R_SUCCESS) { - result = create_default_portset(mctx, &v6portset); - if (result == ISC_R_SUCCESS) { - result = dns_dispatchmgr_setavailports(mgr, - v4portset, - v6portset); - } - } - if (v4portset != NULL) - isc_portset_destroy(mctx, &v4portset); - if (v6portset != NULL) - isc_portset_destroy(mctx, &v6portset); - if (result != ISC_R_SUCCESS) - goto kill_dpool; - - if (entropy != NULL) - isc_entropy_attach(entropy, &mgr->entropy); - - result = isc_rng_create(mctx, mgr->entropy, &mgr->rngctx); - if (result != ISC_R_SUCCESS) - goto kill_dpool; - - *mgrp = mgr; - return (ISC_R_SUCCESS); - - kill_dpool: - isc_mempool_destroy(&mgr->dpool); - kill_rpool: - isc_mempool_destroy(&mgr->rpool); - kill_depool: - isc_mempool_destroy(&mgr->depool); - kill_spool_lock: - DESTROYLOCK(&mgr->spool_lock); - kill_bpool_lock: - DESTROYLOCK(&mgr->bpool_lock); - kill_dpool_lock: - DESTROYLOCK(&mgr->dpool_lock); - kill_rpool_lock: - DESTROYLOCK(&mgr->rpool_lock); - kill_depool_lock: - DESTROYLOCK(&mgr->depool_lock); - kill_buffer_lock: - DESTROYLOCK(&mgr->buffer_lock); - kill_rng_lock: - DESTROYLOCK(&mgr->rng_lock); - kill_lock: - DESTROYLOCK(&mgr->lock); - deallocate: - isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); - isc_mem_detach(&mctx); - - return (result); -} - -void -dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) { - REQUIRE(VALID_DISPATCHMGR(mgr)); - if (mgr->blackhole != NULL) - dns_acl_detach(&mgr->blackhole); - dns_acl_attach(blackhole, &mgr->blackhole); -} - -dns_acl_t * -dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) { - REQUIRE(VALID_DISPATCHMGR(mgr)); - return (mgr->blackhole); -} - -void -dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, - dns_portlist_t *portlist) -{ - REQUIRE(VALID_DISPATCHMGR(mgr)); - UNUSED(portlist); - - /* This function is deprecated: use dns_dispatchmgr_setavailports(). */ - return; -} - -dns_portlist_t * -dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) { - REQUIRE(VALID_DISPATCHMGR(mgr)); - return (NULL); /* this function is deprecated */ -} - -isc_result_t -dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, - isc_portset_t *v6portset) -{ - in_port_t *v4ports, *v6ports, p; - unsigned int nv4ports, nv6ports, i4, i6; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - - nv4ports = isc_portset_nports(v4portset); - nv6ports = isc_portset_nports(v6portset); - - v4ports = NULL; - if (nv4ports != 0) { - v4ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv4ports); - if (v4ports == NULL) - return (ISC_R_NOMEMORY); - } - v6ports = NULL; - if (nv6ports != 0) { - v6ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv6ports); - if (v6ports == NULL) { - if (v4ports != NULL) { - isc_mem_put(mgr->mctx, v4ports, - sizeof(in_port_t) * - isc_portset_nports(v4portset)); - } - return (ISC_R_NOMEMORY); - } - } - - p = 0; - i4 = 0; - i6 = 0; - do { - if (isc_portset_isset(v4portset, p)) { - INSIST(i4 < nv4ports); - v4ports[i4++] = p; - } - if (isc_portset_isset(v6portset, p)) { - INSIST(i6 < nv6ports); - v6ports[i6++] = p; - } - } while (p++ < 65535); - INSIST(i4 == nv4ports && i6 == nv6ports); - - PORTBUFLOCK(mgr); - if (mgr->v4ports != NULL) { - isc_mem_put(mgr->mctx, mgr->v4ports, - mgr->nv4ports * sizeof(in_port_t)); - } - mgr->v4ports = v4ports; - mgr->nv4ports = nv4ports; - - if (mgr->v6ports != NULL) { - isc_mem_put(mgr->mctx, mgr->v6ports, - mgr->nv6ports * sizeof(in_port_t)); - } - mgr->v6ports = v6ports; - mgr->nv6ports = nv6ports; - PORTBUFUNLOCK(mgr); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, - unsigned int buffersize, unsigned int maxbuffers, - unsigned int maxrequests, unsigned int buckets, - unsigned int increment) -{ - isc_result_t result; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); - REQUIRE(maxbuffers > 0); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); - - /* - * Keep some number of items around. This should be a config - * option. For now, keep 8, but later keep at least two even - * if the caller wants less. This allows us to ensure certain - * things, like an event can be "freed" and the next allocation - * will always succeed. - * - * Note that if limits are placed on anything here, we use one - * event internally, so the actual limit should be "wanted + 1." - * - * XXXMLG - */ - - if (maxbuffers < 8) - maxbuffers = 8; - - LOCK(&mgr->buffer_lock); - - /* Create or adjust buffer pool */ - if (mgr->bpool != NULL) { - /* - * We only increase the maxbuffers to avoid accidental buffer - * shortage. Ideally we'd separate the manager-wide maximum - * from per-dispatch limits and respect the latter within the - * global limit. But at this moment that's deemed to be - * overkilling and isn't worth additional implementation - * complexity. - */ - if (maxbuffers > mgr->maxbuffers) { - isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); - isc_mempool_setfreemax(mgr->bpool, maxbuffers); - mgr->maxbuffers = maxbuffers; - } - } else { - result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool); - if (result != ISC_R_SUCCESS) { - UNLOCK(&mgr->buffer_lock); - return (result); - } - isc_mempool_setname(mgr->bpool, "dispmgr_bpool"); - isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); - isc_mempool_setfreemax(mgr->bpool, maxbuffers); - isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock); - isc_mempool_setfillcount(mgr->bpool, 32); - } - - /* Create or adjust socket pool */ - if (mgr->spool != NULL) { - if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2) { - isc_mempool_setmaxalloc(mgr->spool, - DNS_DISPATCH_POOLSOCKS * 2); - isc_mempool_setfreemax(mgr->spool, - DNS_DISPATCH_POOLSOCKS * 2); - } - UNLOCK(&mgr->buffer_lock); - return (ISC_R_SUCCESS); - } - result = isc_mempool_create(mgr->mctx, sizeof(dispsocket_t), - &mgr->spool); - if (result != ISC_R_SUCCESS) - goto cleanup; - - isc_mempool_setname(mgr->spool, "dispmgr_spool"); - isc_mempool_setmaxalloc(mgr->spool, maxrequests); - isc_mempool_setfreemax(mgr->spool, maxrequests); - isc_mempool_associatelock(mgr->spool, &mgr->spool_lock); - isc_mempool_setfillcount(mgr->spool, 32); - - result = qid_allocate(mgr, buckets, increment, &mgr->qid, true); - if (result != ISC_R_SUCCESS) - goto cleanup; - - mgr->buffersize = buffersize; - mgr->maxbuffers = maxbuffers; - UNLOCK(&mgr->buffer_lock); - return (ISC_R_SUCCESS); - - cleanup: - isc_mempool_destroy(&mgr->bpool); - if (mgr->spool != NULL) - isc_mempool_destroy(&mgr->spool); - UNLOCK(&mgr->buffer_lock); - return (result); -} - -void -dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) { - dns_dispatchmgr_t *mgr; - bool killit; - - REQUIRE(mgrp != NULL); - REQUIRE(VALID_DISPATCHMGR(*mgrp)); - - mgr = *mgrp; - *mgrp = NULL; - - LOCK(&mgr->lock); - mgr->state |= MGR_SHUTTINGDOWN; - killit = destroy_mgr_ok(mgr); - UNLOCK(&mgr->lock); - - mgr_log(mgr, LVL(90), "destroy: killit=%d", killit); - - if (killit) - destroy_mgr(&mgr); -} - -void -dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) { - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(ISC_LIST_EMPTY(mgr->list)); - REQUIRE(mgr->stats == NULL); - - isc_stats_attach(stats, &mgr->stats); -} - -static int -port_cmp(const void *key, const void *ent) { - in_port_t p1 = *(const in_port_t *)key; - in_port_t p2 = *(const in_port_t *)ent; - - if (p1 < p2) - return (-1); - else if (p1 == p2) - return (0); - else - return (1); -} - -static bool -portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_sockaddr_t *sockaddrp) -{ - isc_sockaddr_t sockaddr; - isc_result_t result; - in_port_t *ports, port; - unsigned int nports; - bool available = false; - - REQUIRE(sock != NULL || sockaddrp != NULL); - - PORTBUFLOCK(mgr); - if (sock != NULL) { - sockaddrp = &sockaddr; - result = isc_socket_getsockname(sock, sockaddrp); - if (result != ISC_R_SUCCESS) - goto unlock; - } - - if (isc_sockaddr_pf(sockaddrp) == AF_INET) { - ports = mgr->v4ports; - nports = mgr->nv4ports; - } else { - ports = mgr->v6ports; - nports = mgr->nv6ports; - } - if (ports == NULL) - goto unlock; - - port = isc_sockaddr_getport(sockaddrp); - if (bsearch(&port, ports, nports, sizeof(in_port_t), port_cmp) != NULL) - available = true; - -unlock: - PORTBUFUNLOCK(mgr); - return (available); -} - -#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask))) - -static bool -local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) { - isc_sockaddr_t sockaddr; - isc_result_t result; - - REQUIRE(disp->socket != NULL); - - if (addr == NULL) - return (true); - - /* - * Don't match wildcard ports unless the port is available in the - * current configuration. - */ - if (isc_sockaddr_getport(addr) == 0 && - isc_sockaddr_getport(&disp->local) == 0 && - !portavailable(disp->mgr, disp->socket, NULL)) { - return (false); - } - - /* - * Check if we match the binding . - * Wildcard ports match/fail here. - */ - if (isc_sockaddr_equal(&disp->local, addr)) - return (true); - if (isc_sockaddr_getport(addr) == 0) - return (false); - - /* - * Check if we match a bound wildcard port . - */ - if (!isc_sockaddr_eqaddr(&disp->local, addr)) - return (false); - result = isc_socket_getsockname(disp->socket, &sockaddr); - if (result != ISC_R_SUCCESS) - return (false); - - return (isc_sockaddr_equal(&sockaddr, addr)); -} - -/* - * Requires mgr be locked. - * - * No dispatcher can be locked by this thread when calling this function. - * - * - * NOTE: - * If a matching dispatcher is found, it is locked after this function - * returns, and must be unlocked by the caller. - */ -static isc_result_t -dispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local, - unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp) -{ - dns_dispatch_t *disp; - isc_result_t result; - - /* - * Make certain that we will not match a private or exclusive dispatch. - */ - attributes &= ~(DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE); - mask |= (DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE); - - disp = ISC_LIST_HEAD(mgr->list); - while (disp != NULL) { - LOCK(&disp->lock); - if ((disp->shutting_down == 0) - && ATTRMATCH(disp->attributes, attributes, mask) - && local_addr_match(disp, local)) - break; - UNLOCK(&disp->lock); - disp = ISC_LIST_NEXT(disp, link); - } - - if (disp == NULL) { - result = ISC_R_NOTFOUND; - goto out; - } - - *dispp = disp; - result = ISC_R_SUCCESS; - out: - - return (result); -} - -static isc_result_t -qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, - unsigned int increment, dns_qid_t **qidp, - bool needsocktable) -{ - dns_qid_t *qid; - unsigned int i; - isc_result_t result; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); - REQUIRE(qidp != NULL && *qidp == NULL); - - qid = isc_mem_get(mgr->mctx, sizeof(*qid)); - if (qid == NULL) - return (ISC_R_NOMEMORY); - - qid->qid_table = isc_mem_get(mgr->mctx, - buckets * sizeof(dns_displist_t)); - if (qid->qid_table == NULL) { - isc_mem_put(mgr->mctx, qid, sizeof(*qid)); - return (ISC_R_NOMEMORY); - } - - qid->sock_table = NULL; - if (needsocktable) { - qid->sock_table = isc_mem_get(mgr->mctx, buckets * - sizeof(dispsocketlist_t)); - if (qid->sock_table == NULL) { - isc_mem_put(mgr->mctx, qid->qid_table, - buckets * sizeof(dns_displist_t)); - isc_mem_put(mgr->mctx, qid, sizeof(*qid)); - return (ISC_R_NOMEMORY); - } - } - - result = isc_mutex_init(&qid->lock); - if (result != ISC_R_SUCCESS) { - if (qid->sock_table != NULL) { - isc_mem_put(mgr->mctx, qid->sock_table, - buckets * sizeof(dispsocketlist_t)); - } - isc_mem_put(mgr->mctx, qid->qid_table, - buckets * sizeof(dns_displist_t)); - isc_mem_put(mgr->mctx, qid, sizeof(*qid)); - return (result); - } - - for (i = 0; i < buckets; i++) { - ISC_LIST_INIT(qid->qid_table[i]); - if (qid->sock_table != NULL) - ISC_LIST_INIT(qid->sock_table[i]); - } - - qid->qid_nbuckets = buckets; - qid->qid_increment = increment; - qid->magic = QID_MAGIC; - *qidp = qid; - return (ISC_R_SUCCESS); -} - -static void -qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) { - dns_qid_t *qid; - - REQUIRE(qidp != NULL); - qid = *qidp; - - REQUIRE(VALID_QID(qid)); - - *qidp = NULL; - qid->magic = 0; - isc_mem_put(mctx, qid->qid_table, - qid->qid_nbuckets * sizeof(dns_displist_t)); - if (qid->sock_table != NULL) { - isc_mem_put(mctx, qid->sock_table, - qid->qid_nbuckets * sizeof(dispsocketlist_t)); - } - DESTROYLOCK(&qid->lock); - isc_mem_put(mctx, qid, sizeof(*qid)); -} - -/* - * Allocate and set important limits. - */ -static isc_result_t -dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, - dns_dispatch_t **dispp) -{ - dns_dispatch_t *disp; - isc_result_t result; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(dispp != NULL && *dispp == NULL); - - /* - * Set up the dispatcher, mostly. Don't bother setting some of - * the options that are controlled by tcp vs. udp, etc. - */ - - disp = isc_mempool_get(mgr->dpool); - if (disp == NULL) - return (ISC_R_NOMEMORY); - - disp->magic = 0; - disp->mgr = mgr; - disp->maxrequests = maxrequests; - disp->attributes = 0; - ISC_LINK_INIT(disp, link); - disp->refcount = 1; - disp->recv_pending = 0; - memset(&disp->local, 0, sizeof(disp->local)); - memset(&disp->peer, 0, sizeof(disp->peer)); - disp->localport = 0; - disp->shutting_down = 0; - disp->shutdown_out = 0; - disp->connected = 0; - disp->tcpmsg_valid = 0; - disp->shutdown_why = ISC_R_UNEXPECTED; - disp->requests = 0; - disp->tcpbuffers = 0; - disp->qid = NULL; - ISC_LIST_INIT(disp->activesockets); - ISC_LIST_INIT(disp->inactivesockets); - disp->nsockets = 0; - disp->rngctx = NULL; - isc_rng_attach(mgr->rngctx, &disp->rngctx); - disp->port_table = NULL; - disp->portpool = NULL; - disp->dscp = -1; - - result = isc_mutex_init(&disp->lock); - if (result != ISC_R_SUCCESS) - goto deallocate; - - disp->failsafe_ev = allocate_devent(disp); - if (disp->failsafe_ev == NULL) { - result = ISC_R_NOMEMORY; - goto kill_lock; - } - - disp->magic = DISPATCH_MAGIC; - - *dispp = disp; - return (ISC_R_SUCCESS); - - /* - * error returns - */ - kill_lock: - DESTROYLOCK(&disp->lock); - deallocate: - if (disp->rngctx != NULL) - isc_rng_detach(&disp->rngctx); - isc_mempool_put(mgr->dpool, disp); - - return (result); -} - - -/* - * MUST be unlocked, and not used by anything. - */ -static void -dispatch_free(dns_dispatch_t **dispp) { - dns_dispatch_t *disp; - dns_dispatchmgr_t *mgr; - int i; - - REQUIRE(VALID_DISPATCH(*dispp)); - disp = *dispp; - *dispp = NULL; - - mgr = disp->mgr; - REQUIRE(VALID_DISPATCHMGR(mgr)); - - if (disp->tcpmsg_valid) { - dns_tcpmsg_invalidate(&disp->tcpmsg); - disp->tcpmsg_valid = 0; - } - - INSIST(disp->tcpbuffers == 0); - INSIST(disp->requests == 0); - INSIST(disp->recv_pending == 0); - INSIST(ISC_LIST_EMPTY(disp->activesockets)); - INSIST(ISC_LIST_EMPTY(disp->inactivesockets)); - - isc_mempool_put(mgr->depool, disp->failsafe_ev); - disp->failsafe_ev = NULL; - - if (disp->qid != NULL) - qid_destroy(mgr->mctx, &disp->qid); - - if (disp->port_table != NULL) { - for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) - INSIST(ISC_LIST_EMPTY(disp->port_table[i])); - isc_mem_put(mgr->mctx, disp->port_table, - sizeof(disp->port_table[0]) * - DNS_DISPATCH_PORTTABLESIZE); - } - - if (disp->portpool != NULL) - isc_mempool_destroy(&disp->portpool); - - if (disp->rngctx != NULL) - isc_rng_detach(&disp->rngctx); - - disp->mgr = NULL; - DESTROYLOCK(&disp->lock); - disp->magic = 0; - isc_mempool_put(mgr->dpool, disp); -} - -isc_result_t -dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_taskmgr_t *taskmgr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp) -{ - - attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */ - - return (dns_dispatch_createtcp2(mgr, sock, taskmgr, NULL, NULL, - buffersize, maxbuffers, maxrequests, - buckets, increment, attributes, - dispp)); -} - -isc_result_t -dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - isc_sockaddr_t *destaddr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp) -{ - isc_result_t result; - dns_dispatch_t *disp; - - UNUSED(maxbuffers); - UNUSED(buffersize); - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp); - REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0); - REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0); - - if (destaddr == NULL) - attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */ - - LOCK(&mgr->lock); - - /* - * dispatch_allocate() checks mgr for us. - * qid_allocate() checks buckets and increment for us. - */ - disp = NULL; - result = dispatch_allocate(mgr, maxrequests, &disp); - if (result != ISC_R_SUCCESS) { - UNLOCK(&mgr->lock); - return (result); - } - - result = qid_allocate(mgr, buckets, increment, &disp->qid, false); - if (result != ISC_R_SUCCESS) - goto deallocate_dispatch; - - disp->socktype = isc_sockettype_tcp; - disp->socket = NULL; - isc_socket_attach(sock, &disp->socket); - - disp->sepool = NULL; - - disp->ntasks = 1; - disp->task[0] = NULL; - result = isc_task_create(taskmgr, 0, &disp->task[0]); - if (result != ISC_R_SUCCESS) - goto kill_socket; - - disp->ctlevent = isc_event_allocate(mgr->mctx, disp, - DNS_EVENT_DISPATCHCONTROL, - destroy_disp, disp, - sizeof(isc_event_t)); - if (disp->ctlevent == NULL) { - result = ISC_R_NOMEMORY; - goto kill_task; - } - - isc_task_setname(disp->task[0], "tcpdispatch", disp); - - dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg); - disp->tcpmsg_valid = 1; - - disp->attributes = attributes; - - if (localaddr == NULL) { - if (destaddr != NULL) { - switch (isc_sockaddr_pf(destaddr)) { - case AF_INET: - isc_sockaddr_any(&disp->local); - break; - case AF_INET6: - isc_sockaddr_any6(&disp->local); - break; - } - } - } else - disp->local = *localaddr; - - if (destaddr != NULL) - disp->peer = *destaddr; - - /* - * Append it to the dispatcher list. - */ - ISC_LIST_APPEND(mgr->list, disp, link); - UNLOCK(&mgr->lock); - - mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp); - dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); - *dispp = disp; - - return (ISC_R_SUCCESS); - - /* - * Error returns. - */ - kill_task: - isc_task_detach(&disp->task[0]); - kill_socket: - isc_socket_detach(&disp->socket); - deallocate_dispatch: - dispatch_free(&disp); - - UNLOCK(&mgr->lock); - - return (result); -} - -isc_result_t -dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, - isc_sockaddr_t *localaddr, dns_dispatch_t **dispp) -{ - dns_dispatch_t *disp; - isc_result_t result; - isc_sockaddr_t peeraddr; - isc_sockaddr_t sockname; - unsigned int attributes, mask; - bool match = false; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(destaddr != NULL); - REQUIRE(dispp != NULL && *dispp == NULL); - - attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED; - mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE | - DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED; - - LOCK(&mgr->lock); - disp = ISC_LIST_HEAD(mgr->list); - while (disp != NULL && !match) { - LOCK(&disp->lock); - if ((disp->shutting_down == 0) && - ATTRMATCH(disp->attributes, attributes, mask) && - (localaddr == NULL || - isc_sockaddr_eqaddr(localaddr, &disp->local))) { - result = isc_socket_getsockname(disp->socket, - &sockname); - if (result == ISC_R_SUCCESS) - result = isc_socket_getpeername(disp->socket, - &peeraddr); - if (result == ISC_R_SUCCESS && - isc_sockaddr_equal(destaddr, &peeraddr) && - (localaddr == NULL || - isc_sockaddr_eqaddr(localaddr, &sockname))) { - /* attach */ - disp->refcount++; - *dispp = disp; - match = true; - } - } - UNLOCK(&disp->lock); - disp = ISC_LIST_NEXT(disp, link); - } - UNLOCK(&mgr->lock); - return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND); -} - -isc_result_t -dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, - isc_sockaddr_t *localaddr, bool *connected, - dns_dispatch_t **dispp) -{ - dns_dispatch_t *disp; - isc_result_t result; - isc_sockaddr_t peeraddr; - isc_sockaddr_t sockname; - unsigned int attributes, mask; - bool match = false; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(destaddr != NULL); - REQUIRE(dispp != NULL && *dispp == NULL); - REQUIRE(connected != NULL); - - /* First pass (same as dns_dispatch_gettcp()) */ - attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED; - mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE | - DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED; - - LOCK(&mgr->lock); - disp = ISC_LIST_HEAD(mgr->list); - while (disp != NULL && !match) { - LOCK(&disp->lock); - if ((disp->shutting_down == 0) && - ATTRMATCH(disp->attributes, attributes, mask) && - (localaddr == NULL || - isc_sockaddr_eqaddr(localaddr, &disp->local))) { - result = isc_socket_getsockname(disp->socket, - &sockname); - if (result == ISC_R_SUCCESS) - result = isc_socket_getpeername(disp->socket, - &peeraddr); - if (result == ISC_R_SUCCESS && - isc_sockaddr_equal(destaddr, &peeraddr) && - (localaddr == NULL || - isc_sockaddr_eqaddr(localaddr, &sockname))) { - /* attach */ - disp->refcount++; - *dispp = disp; - match = true; - *connected = true; - } - } - UNLOCK(&disp->lock); - disp = ISC_LIST_NEXT(disp, link); - } - if (match) { - UNLOCK(&mgr->lock); - return (ISC_R_SUCCESS); - } - - /* Second pass */ - attributes = DNS_DISPATCHATTR_TCP; - - disp = ISC_LIST_HEAD(mgr->list); - while (disp != NULL && !match) { - LOCK(&disp->lock); - if ((disp->shutting_down == 0) && - ATTRMATCH(disp->attributes, attributes, mask) && - (localaddr == NULL || - isc_sockaddr_eqaddr(localaddr, &disp->local)) && - isc_sockaddr_equal(destaddr, &disp->peer)) { - /* attach */ - disp->refcount++; - *dispp = disp; - match = true; - } - UNLOCK(&disp->lock); - disp = ISC_LIST_NEXT(disp, link); - } - UNLOCK(&mgr->lock); - return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND); -} - -isc_result_t -dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp, dns_dispatch_t *dup_dispatch) -{ - isc_result_t result; - dns_dispatch_t *disp = NULL; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(sockmgr != NULL); - REQUIRE(localaddr != NULL); - REQUIRE(taskmgr != NULL); - REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); - REQUIRE(maxbuffers > 0); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); - REQUIRE(dispp != NULL && *dispp == NULL); - REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0); - - result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers, - maxrequests, buckets, increment); - if (result != ISC_R_SUCCESS) - return (result); - - LOCK(&mgr->lock); - - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - REQUIRE(isc_sockaddr_getport(localaddr) == 0); - goto createudp; - } - - /* - * See if we have a dispatcher that matches. - */ - if (dup_dispatch == NULL) { - result = dispatch_find(mgr, localaddr, attributes, mask, &disp); - if (result == ISC_R_SUCCESS) { - disp->refcount++; - - if (disp->maxrequests < maxrequests) - disp->maxrequests = maxrequests; - - if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 - && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) - { - disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; - if (disp->recv_pending != 0) - isc_socket_cancel(disp->socket, - disp->task[0], - ISC_SOCKCANCEL_RECV); - } - - UNLOCK(&disp->lock); - UNLOCK(&mgr->lock); - - *dispp = disp; - - return (ISC_R_SUCCESS); - } - } - - createudp: - /* - * Nope, create one. - */ - result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, - maxrequests, attributes, &disp, - dup_dispatch == NULL - ? NULL - : dup_dispatch->socket); - - if (result != ISC_R_SUCCESS) { - UNLOCK(&mgr->lock); - return (result); - } - - UNLOCK(&mgr->lock); - *dispp = disp; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp) -{ - return (dns_dispatch_getudp_dup(mgr, sockmgr, taskmgr, localaddr, - buffersize, maxbuffers, maxrequests, - buckets, increment, attributes, - mask, dispp, NULL)); -} - -/* - * mgr should be locked. - */ - -#ifndef DNS_DISPATCH_HELD -#define DNS_DISPATCH_HELD 20U -#endif - -static isc_result_t -get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, - isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr, - isc_socket_t **sockp, isc_socket_t *dup_socket) -{ - unsigned int i, j; - isc_socket_t *held[DNS_DISPATCH_HELD]; - isc_sockaddr_t localaddr_bound; - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - bool anyport; - - INSIST(sockp != NULL && *sockp == NULL); - - localaddr_bound = *localaddr; - anyport = (isc_sockaddr_getport(localaddr) == 0); - - if (anyport) { - unsigned int nports; - in_port_t *ports; - - /* - * If no port is specified, we first try to pick up a random - * port by ourselves. - */ - if (isc_sockaddr_pf(localaddr) == AF_INET) { - nports = disp->mgr->nv4ports; - ports = disp->mgr->v4ports; - } else { - nports = disp->mgr->nv6ports; - ports = disp->mgr->v6ports; - } - if (nports == 0) - return (ISC_R_ADDRNOTAVAIL); - - for (i = 0; i < 1024; i++) { - in_port_t prt; - - prt = ports[isc_rng_uniformrandom(DISP_RNGCTX(disp), - nports)]; - isc_sockaddr_setport(&localaddr_bound, prt); - result = open_socket(sockmgr, &localaddr_bound, - 0, &sock, NULL); - /* - * Continue if the port chosen is already in use - * or the OS has reserved it. - */ - if (result == ISC_R_NOPERM || - result == ISC_R_ADDRINUSE) - continue; - disp->localport = prt; - *sockp = sock; - return (result); - } - - /* - * If this fails 1024 times, we then ask the kernel for - * choosing one. - */ - } else { - /* Allow to reuse address for non-random ports. */ - result = open_socket(sockmgr, localaddr, - ISC_SOCKET_REUSEADDRESS, &sock, - dup_socket); - - if (result == ISC_R_SUCCESS) - *sockp = sock; - - return (result); - } - - memset(held, 0, sizeof(held)); - i = 0; - - for (j = 0; j < 0xffffU; j++) { - result = open_socket(sockmgr, localaddr, 0, &sock, NULL); - if (result != ISC_R_SUCCESS) - goto end; - else if (portavailable(mgr, sock, NULL)) - break; - if (held[i] != NULL) - isc_socket_detach(&held[i]); - held[i++] = sock; - sock = NULL; - if (i == DNS_DISPATCH_HELD) - i = 0; - } - if (j == 0xffffU) { - mgr_log(mgr, ISC_LOG_ERROR, - "avoid-v%s-udp-ports: unable to allocate " - "an available port", - isc_sockaddr_pf(localaddr) == AF_INET ? "4" : "6"); - result = ISC_R_FAILURE; - goto end; - } - *sockp = sock; - -end: - for (i = 0; i < DNS_DISPATCH_HELD; i++) { - if (held[i] != NULL) - isc_socket_detach(&held[i]); - } - - return (result); -} - -static isc_result_t -dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, - isc_sockaddr_t *localaddr, - unsigned int maxrequests, - unsigned int attributes, - dns_dispatch_t **dispp, - isc_socket_t *dup_socket) -{ - isc_result_t result; - dns_dispatch_t *disp; - isc_socket_t *sock = NULL; - int i = 0; - - /* - * dispatch_allocate() checks mgr for us. - */ - disp = NULL; - result = dispatch_allocate(mgr, maxrequests, &disp); - if (result != ISC_R_SUCCESS) - return (result); - - disp->socktype = isc_sockettype_udp; - - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) { - result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock, - dup_socket); - if (result != ISC_R_SUCCESS) - goto deallocate_dispatch; - - if (isc_log_wouldlog(dns_lctx, 90)) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(localaddr, addrbuf, - ISC_SOCKADDR_FORMATSIZE); - mgr_log(mgr, LVL(90), "dns_dispatch_createudp: Created" - " UDP dispatch for %s with socket fd %d", - addrbuf, isc_socket_getfd(sock)); - } - - } else { - isc_sockaddr_t sa_any; - - /* - * For dispatches using exclusive sockets with a specific - * source address, we only check if the specified address is - * available on the system. Query sockets will be created later - * on demand. - */ - isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); - if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { - result = open_socket(sockmgr, localaddr, 0, &sock, NULL); - if (sock != NULL) - isc_socket_detach(&sock); - if (result != ISC_R_SUCCESS) - goto deallocate_dispatch; - } - - disp->port_table = isc_mem_get(mgr->mctx, - sizeof(disp->port_table[0]) * - DNS_DISPATCH_PORTTABLESIZE); - if (disp->port_table == NULL) - goto deallocate_dispatch; - for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) - ISC_LIST_INIT(disp->port_table[i]); - - result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t), - &disp->portpool); - if (result != ISC_R_SUCCESS) - goto deallocate_dispatch; - isc_mempool_setname(disp->portpool, "disp_portpool"); - isc_mempool_setfreemax(disp->portpool, 128); - } - disp->socket = sock; - disp->local = *localaddr; - - if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) - disp->ntasks = MAX_INTERNAL_TASKS; - else - disp->ntasks = 1; - for (i = 0; i < disp->ntasks; i++) { - disp->task[i] = NULL; - result = isc_task_create(taskmgr, 0, &disp->task[i]); - if (result != ISC_R_SUCCESS) { - while (--i >= 0) { - isc_task_shutdown(disp->task[i]); - isc_task_detach(&disp->task[i]); - } - goto kill_socket; - } - isc_task_setname(disp->task[i], "udpdispatch", disp); - } - - disp->ctlevent = isc_event_allocate(mgr->mctx, disp, - DNS_EVENT_DISPATCHCONTROL, - destroy_disp, disp, - sizeof(isc_event_t)); - if (disp->ctlevent == NULL) { - result = ISC_R_NOMEMORY; - goto kill_task; - } - - disp->sepool = NULL; - if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t), - &disp->sepool) != ISC_R_SUCCESS) - { - result = ISC_R_NOMEMORY; - goto kill_ctlevent; - } - - result = isc_mutex_init(&disp->sepool_lock); - if (result != ISC_R_SUCCESS) - goto kill_sepool; - - isc_mempool_setname(disp->sepool, "disp_sepool"); - isc_mempool_setmaxalloc(disp->sepool, 32768); - isc_mempool_setfreemax(disp->sepool, 32768); - isc_mempool_associatelock(disp->sepool, &disp->sepool_lock); - isc_mempool_setfillcount(disp->sepool, 16); - - attributes &= ~DNS_DISPATCHATTR_TCP; - attributes |= DNS_DISPATCHATTR_UDP; - disp->attributes = attributes; - - /* - * Append it to the dispatcher list. - */ - ISC_LIST_APPEND(mgr->list, disp, link); - - mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp); - dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */ - if (disp->socket != NULL) - dispatch_log(disp, LVL(90), "created socket %p", disp->socket); - - *dispp = disp; - - return (result); - - /* - * Error returns. - */ - kill_sepool: - isc_mempool_destroy(&disp->sepool); - kill_ctlevent: - isc_event_free(&disp->ctlevent); - kill_task: - for (i = 0; i < disp->ntasks; i++) - isc_task_detach(&disp->task[i]); - kill_socket: - if (disp->socket != NULL) - isc_socket_detach(&disp->socket); - deallocate_dispatch: - dispatch_free(&disp); - - return (result); -} - -void -dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) { - REQUIRE(VALID_DISPATCH(disp)); - REQUIRE(dispp != NULL && *dispp == NULL); - - LOCK(&disp->lock); - disp->refcount++; - UNLOCK(&disp->lock); - - *dispp = disp; -} - -/* - * It is important to lock the manager while we are deleting the dispatch, - * since dns_dispatch_getudp will call dispatch_find, which returns to - * the caller a dispatch but does not attach to it until later. _getudp - * locks the manager, however, so locking it here will keep us from attaching - * to a dispatcher that is in the process of going away. - */ -void -dns_dispatch_detach(dns_dispatch_t **dispp) { - dns_dispatch_t *disp; - dispsocket_t *dispsock; - bool killit; - - REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp)); - - disp = *dispp; - *dispp = NULL; - - LOCK(&disp->lock); - - INSIST(disp->refcount > 0); - disp->refcount--; - if (disp->refcount == 0) { - if (disp->recv_pending > 0) - isc_socket_cancel(disp->socket, disp->task[0], - ISC_SOCKCANCEL_RECV); - for (dispsock = ISC_LIST_HEAD(disp->activesockets); - dispsock != NULL; - dispsock = ISC_LIST_NEXT(dispsock, link)) { - isc_socket_cancel(dispsock->socket, dispsock->task, - ISC_SOCKCANCEL_RECV); - } - disp->shutting_down = 1; - } - - dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount); - - killit = destroy_disp_ok(disp); - UNLOCK(&disp->lock); - if (killit) - isc_task_send(disp->task[0], &disp->ctlevent); -} - -isc_result_t -dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_messageid_t *idp, dns_dispentry_t **resp, - isc_socketmgr_t *sockmgr) -{ - return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, - idp, resp, sockmgr)); -} - -isc_result_t -dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, - isc_sockaddr_t *dest, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_messageid_t *idp, dns_dispentry_t **resp, - isc_socketmgr_t *sockmgr) -{ - dns_dispentry_t *res; - unsigned int bucket; - in_port_t localport = 0; - dns_messageid_t id; - int i; - bool ok; - dns_qid_t *qid; - dispsocket_t *dispsocket = NULL; - isc_result_t result; - - REQUIRE(VALID_DISPATCH(disp)); - REQUIRE(task != NULL); - REQUIRE(dest != NULL); - REQUIRE(resp != NULL && *resp == NULL); - REQUIRE(idp != NULL); - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) - REQUIRE(sockmgr != NULL); - - LOCK(&disp->lock); - - if (disp->shutting_down == 1) { - UNLOCK(&disp->lock); - return (ISC_R_SHUTTINGDOWN); - } - - if (disp->requests >= disp->maxrequests) { - UNLOCK(&disp->lock); - return (ISC_R_QUOTA); - } - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && - disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) { - dispsocket_t *oldestsocket; - dns_dispentry_t *oldestresp; - dns_dispatchevent_t *rev; - - /* - * Kill oldest outstanding query if the number of sockets - * exceeds the quota to keep the room for new queries. - */ - oldestsocket = ISC_LIST_HEAD(disp->activesockets); - oldestresp = oldestsocket->resp; - if (oldestresp != NULL && !oldestresp->item_out) { - rev = allocate_devent(oldestresp->disp); - if (rev != NULL) { - rev->buffer.base = NULL; - rev->result = ISC_R_CANCELED; - rev->id = oldestresp->id; - ISC_EVENT_INIT(rev, sizeof(*rev), 0, - NULL, DNS_EVENT_DISPATCH, - oldestresp->action, - oldestresp->arg, oldestresp, - NULL, NULL); - oldestresp->item_out = true; - isc_task_send(oldestresp->task, - ISC_EVENT_PTR(&rev)); - inc_stats(disp->mgr, - dns_resstatscounter_dispabort); - } - } - - /* - * Move this entry to the tail so that it won't (easily) be - * examined before actually being canceled. - */ - ISC_LIST_UNLINK(disp->activesockets, oldestsocket, link); - ISC_LIST_APPEND(disp->activesockets, oldestsocket, link); - } - - qid = DNS_QID(disp); - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - /* - * Get a separate UDP socket with a random port number. - */ - result = get_dispsocket(disp, dest, sockmgr, &dispsocket, - &localport); - if (result != ISC_R_SUCCESS) { - UNLOCK(&disp->lock); - inc_stats(disp->mgr, dns_resstatscounter_dispsockfail); - return (result); - } - } else { - localport = disp->localport; - } - - /* - * Try somewhat hard to find an unique ID unless FIXEDID is set - * in which case we use the id passed in via *idp. - */ - LOCK(&qid->lock); - if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) - id = *idp; - else - id = (dns_messageid_t)isc_rng_random(DISP_RNGCTX(disp)); - ok = false; - i = 0; - do { - bucket = dns_hash(qid, dest, id, localport); - if (entry_search(qid, dest, id, localport, bucket) == NULL) { - ok = true; - break; - } - if ((disp->attributes & DNS_DISPATCHATTR_FIXEDID) != 0) - break; - id += qid->qid_increment; - id &= 0x0000ffff; - } while (i++ < 64); - UNLOCK(&qid->lock); - - if (!ok) { - UNLOCK(&disp->lock); - return (ISC_R_NOMORE); - } - - res = isc_mempool_get(disp->mgr->rpool); - if (res == NULL) { - if (dispsocket != NULL) - destroy_dispsocket(disp, &dispsocket); - UNLOCK(&disp->lock); - return (ISC_R_NOMEMORY); - } - - disp->refcount++; - disp->requests++; - res->task = NULL; - isc_task_attach(task, &res->task); - res->disp = disp; - res->id = id; - res->port = localport; - res->bucket = bucket; - res->host = *dest; - res->action = action; - res->arg = arg; - res->dispsocket = dispsocket; - if (dispsocket != NULL) - dispsocket->resp = res; - res->item_out = false; - ISC_LIST_INIT(res->items); - ISC_LINK_INIT(res, link); - res->magic = RESPONSE_MAGIC; - - LOCK(&qid->lock); - ISC_LIST_APPEND(qid->qid_table[bucket], res, link); - UNLOCK(&qid->lock); - - inc_stats(disp->mgr, (qid == disp->mgr->qid) ? - dns_resstatscounter_disprequdp : - dns_resstatscounter_dispreqtcp); - - request_log(disp, res, LVL(90), - "attached to task %p", res->task); - - if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) || - ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0)) { - result = startrecv(disp, dispsocket); - if (result != ISC_R_SUCCESS) { - LOCK(&qid->lock); - ISC_LIST_UNLINK(qid->qid_table[bucket], res, link); - UNLOCK(&qid->lock); - - if (dispsocket != NULL) - destroy_dispsocket(disp, &dispsocket); - - disp->refcount--; - disp->requests--; - - dec_stats(disp->mgr, (qid == disp->mgr->qid) ? - dns_resstatscounter_disprequdp : - dns_resstatscounter_dispreqtcp); - - UNLOCK(&disp->lock); - isc_task_detach(&res->task); - isc_mempool_put(disp->mgr->rpool, res); - return (result); - } - } - - if (dispsocket != NULL) - ISC_LIST_APPEND(disp->activesockets, dispsocket, link); - - UNLOCK(&disp->lock); - - *idp = id; - *resp = res; - - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) - INSIST(res->dispsocket != NULL); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_messageid_t *idp, dns_dispentry_t **resp) -{ - REQUIRE(VALID_DISPATCH(disp)); - REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); - - return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, - idp, resp, NULL)); -} - -void -dns_dispatch_starttcp(dns_dispatch_t *disp) { - - REQUIRE(VALID_DISPATCH(disp)); - - dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]); - - LOCK(&disp->lock); - if ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) == 0) { - disp->attributes |= DNS_DISPATCHATTR_CONNECTED; - (void)startrecv(disp, NULL); - } - UNLOCK(&disp->lock); -} - -isc_result_t -dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) { - dns_dispatch_t *disp; - dns_dispatchevent_t *ev; - - REQUIRE(VALID_RESPONSE(resp)); - REQUIRE(sockevent != NULL && *sockevent != NULL); - - disp = resp->disp; - REQUIRE(VALID_DISPATCH(disp)); - - ev = *sockevent; - *sockevent = NULL; - - LOCK(&disp->lock); - - REQUIRE(resp->item_out == true); - resp->item_out = false; - - if (ev->buffer.base != NULL) - free_buffer(disp, ev->buffer.base, ev->buffer.length); - free_devent(disp, ev); - - if (disp->shutting_down == 1) { - UNLOCK(&disp->lock); - return (ISC_R_SHUTTINGDOWN); - } - ev = ISC_LIST_HEAD(resp->items); - if (ev != NULL) { - ISC_LIST_UNLINK(resp->items, ev, ev_link); - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - request_log(disp, resp, LVL(90), - "[c] Sent event %p buffer %p len %d to task %p", - ev, ev->buffer.base, ev->buffer.length, - resp->task); - resp->item_out = true; - isc_task_send(resp->task, ISC_EVENT_PTR(&ev)); - } - UNLOCK(&disp->lock); - return (ISC_R_SUCCESS); -} - -void -dns_dispatch_removeresponse(dns_dispentry_t **resp, - dns_dispatchevent_t **sockevent) -{ - dns_dispatchmgr_t *mgr; - dns_dispatch_t *disp; - dns_dispentry_t *res; - dispsocket_t *dispsock; - dns_dispatchevent_t *ev; - unsigned int bucket; - bool killit; - unsigned int n; - isc_eventlist_t events; - dns_qid_t *qid; - - REQUIRE(resp != NULL); - REQUIRE(VALID_RESPONSE(*resp)); - - res = *resp; - *resp = NULL; - - disp = res->disp; - REQUIRE(VALID_DISPATCH(disp)); - mgr = disp->mgr; - REQUIRE(VALID_DISPATCHMGR(mgr)); - - qid = DNS_QID(disp); - - if (sockevent != NULL) { - REQUIRE(*sockevent != NULL); - ev = *sockevent; - *sockevent = NULL; - } else { - ev = NULL; - } - - LOCK(&disp->lock); - - INSIST(disp->requests > 0); - disp->requests--; - dec_stats(disp->mgr, (qid == disp->mgr->qid) ? - dns_resstatscounter_disprequdp : - dns_resstatscounter_dispreqtcp); - INSIST(disp->refcount > 0); - disp->refcount--; - if (disp->refcount == 0) { - if (disp->recv_pending > 0) - isc_socket_cancel(disp->socket, disp->task[0], - ISC_SOCKCANCEL_RECV); - for (dispsock = ISC_LIST_HEAD(disp->activesockets); - dispsock != NULL; - dispsock = ISC_LIST_NEXT(dispsock, link)) { - isc_socket_cancel(dispsock->socket, dispsock->task, - ISC_SOCKCANCEL_RECV); - } - disp->shutting_down = 1; - } - - bucket = res->bucket; - - LOCK(&qid->lock); - ISC_LIST_UNLINK(qid->qid_table[bucket], res, link); - UNLOCK(&qid->lock); - - if (ev == NULL && res->item_out) { - /* - * We've posted our event, but the caller hasn't gotten it - * yet. Take it back. - */ - ISC_LIST_INIT(events); - n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH, - NULL, &events); - /* - * We had better have gotten it back. - */ - INSIST(n == 1); - ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events); - } - - if (ev != NULL) { - REQUIRE(res->item_out == true); - res->item_out = false; - if (ev->buffer.base != NULL) - free_buffer(disp, ev->buffer.base, ev->buffer.length); - free_devent(disp, ev); - } - - request_log(disp, res, LVL(90), "detaching from task %p", res->task); - isc_task_detach(&res->task); - - if (res->dispsocket != NULL) { - isc_socket_cancel(res->dispsocket->socket, - res->dispsocket->task, ISC_SOCKCANCEL_RECV); - res->dispsocket->resp = NULL; - } - - /* - * Free any buffered responses as well - */ - ev = ISC_LIST_HEAD(res->items); - while (ev != NULL) { - ISC_LIST_UNLINK(res->items, ev, ev_link); - if (ev->buffer.base != NULL) - free_buffer(disp, ev->buffer.base, ev->buffer.length); - free_devent(disp, ev); - ev = ISC_LIST_HEAD(res->items); - } - res->magic = 0; - isc_mempool_put(disp->mgr->rpool, res); - if (disp->shutting_down == 1) - do_cancel(disp); - else - (void)startrecv(disp, NULL); - - killit = destroy_disp_ok(disp); - UNLOCK(&disp->lock); - if (killit) - isc_task_send(disp->task[0], &disp->ctlevent); -} - -/* - * disp must be locked. - */ -static void -do_cancel(dns_dispatch_t *disp) { - dns_dispatchevent_t *ev; - dns_dispentry_t *resp; - dns_qid_t *qid; - - if (disp->shutdown_out == 1) - return; - - qid = DNS_QID(disp); - - /* - * Search for the first response handler without packets outstanding - * unless a specific handler is given. - */ - LOCK(&qid->lock); - for (resp = linear_first(qid); - resp != NULL && resp->item_out; - /* Empty. */) - resp = linear_next(qid, resp); - - /* - * No one to send the cancel event to, so nothing to do. - */ - if (resp == NULL) - goto unlock; - - /* - * Send the shutdown failsafe event to this resp. - */ - ev = disp->failsafe_ev; - ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH, - resp->action, resp->arg, resp, NULL, NULL); - ev->result = disp->shutdown_why; - ev->buffer.base = NULL; - ev->buffer.length = 0; - disp->shutdown_out = 1; - request_log(disp, resp, LVL(10), - "cancel: failsafe event %p -> task %p", - ev, resp->task); - resp->item_out = true; - isc_task_send(resp->task, ISC_EVENT_PTR(&ev)); - unlock: - UNLOCK(&qid->lock); -} - -isc_socket_t * -dns_dispatch_getsocket(dns_dispatch_t *disp) { - REQUIRE(VALID_DISPATCH(disp)); - - return (disp->socket); -} - -isc_socket_t * -dns_dispatch_getentrysocket(dns_dispentry_t *resp) { - REQUIRE(VALID_RESPONSE(resp)); - - if (resp->dispsocket != NULL) - return (resp->dispsocket->socket); - else - return (NULL); -} - -isc_result_t -dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) { - - REQUIRE(VALID_DISPATCH(disp)); - REQUIRE(addrp != NULL); - - if (disp->socktype == isc_sockettype_udp) { - *addrp = disp->local; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTIMPLEMENTED); -} - -void -dns_dispatch_cancel(dns_dispatch_t *disp) { - REQUIRE(VALID_DISPATCH(disp)); - - LOCK(&disp->lock); - - if (disp->shutting_down == 1) { - UNLOCK(&disp->lock); - return; - } - - disp->shutdown_why = ISC_R_CANCELED; - disp->shutting_down = 1; - do_cancel(disp); - - UNLOCK(&disp->lock); - - return; -} - -unsigned int -dns_dispatch_getattributes(dns_dispatch_t *disp) { - REQUIRE(VALID_DISPATCH(disp)); - - /* - * We don't bother locking disp here; it's the caller's responsibility - * to use only non volatile flags. - */ - return (disp->attributes); -} - -void -dns_dispatch_changeattributes(dns_dispatch_t *disp, - unsigned int attributes, unsigned int mask) -{ - REQUIRE(VALID_DISPATCH(disp)); - /* Exclusive attribute can only be set on creation */ - REQUIRE((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); - /* Also, a dispatch with randomport specified cannot start listening */ - REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0 || - (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0); - - /* XXXMLG - * Should check for valid attributes here! - */ - - LOCK(&disp->lock); - - if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) { - if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 && - (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) { - disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN; - (void)startrecv(disp, NULL); - } else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) - == 0 && - (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) { - disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; - if (disp->recv_pending != 0) - isc_socket_cancel(disp->socket, disp->task[0], - ISC_SOCKCANCEL_RECV); - } - } - - disp->attributes &= ~mask; - disp->attributes |= (attributes & mask); - UNLOCK(&disp->lock); -} - -void -dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) { - void *buf; - isc_socketevent_t *sevent, *newsevent; - - REQUIRE(VALID_DISPATCH(disp)); - REQUIRE(event != NULL); - - if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) - return; - - sevent = (isc_socketevent_t *)event; - INSIST(sevent->n <= disp->mgr->buffersize); - - newsevent = (isc_socketevent_t *) - isc_event_allocate(disp->mgr->mctx, NULL, - DNS_EVENT_IMPORTRECVDONE, udp_shrecv, - disp, sizeof(isc_socketevent_t)); - if (newsevent == NULL) - return; - - buf = allocate_udp_buffer(disp); - if (buf == NULL) { - isc_event_free(ISC_EVENT_PTR(&newsevent)); - return; - } - memmove(buf, sevent->region.base, sevent->n); - newsevent->region.base = buf; - newsevent->region.length = disp->mgr->buffersize; - newsevent->n = sevent->n; - newsevent->result = sevent->result; - newsevent->address = sevent->address; - newsevent->timestamp = sevent->timestamp; - newsevent->pktinfo = sevent->pktinfo; - newsevent->attributes = sevent->attributes; - - isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent)); -} - -dns_dispatch_t * -dns_dispatchset_get(dns_dispatchset_t *dset) { - dns_dispatch_t *disp; - - /* check that dispatch set is configured */ - if (dset == NULL || dset->ndisp == 0) - return (NULL); - - LOCK(&dset->lock); - disp = dset->dispatches[dset->cur]; - dset->cur++; - if (dset->cur == dset->ndisp) - dset->cur = 0; - UNLOCK(&dset->lock); - - return (disp); -} - -isc_result_t -dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, dns_dispatch_t *source, - dns_dispatchset_t **dsetp, int n) -{ - isc_result_t result; - dns_dispatchset_t *dset; - dns_dispatchmgr_t *mgr; - int i, j; - - REQUIRE(VALID_DISPATCH(source)); - REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0); - REQUIRE(dsetp != NULL && *dsetp == NULL); - - mgr = source->mgr; - - dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t)); - if (dset == NULL) - return (ISC_R_NOMEMORY); - memset(dset, 0, sizeof(*dset)); - - result = isc_mutex_init(&dset->lock); - if (result != ISC_R_SUCCESS) - goto fail_alloc; - - dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n); - if (dset->dispatches == NULL) { - result = ISC_R_NOMEMORY; - goto fail_lock; - } - - isc_mem_attach(mctx, &dset->mctx); - dset->ndisp = n; - dset->cur = 0; - - dset->dispatches[0] = NULL; - dns_dispatch_attach(source, &dset->dispatches[0]); - - LOCK(&mgr->lock); - for (i = 1; i < n; i++) { - dset->dispatches[i] = NULL; - result = dispatch_createudp(mgr, sockmgr, taskmgr, - &source->local, - source->maxrequests, - source->attributes, - &dset->dispatches[i], - source->socket); - if (result != ISC_R_SUCCESS) - goto fail; - } - - UNLOCK(&mgr->lock); - *dsetp = dset; - - return (ISC_R_SUCCESS); - - fail: - UNLOCK(&mgr->lock); - - for (j = 0; j < i; j++) - dns_dispatch_detach(&(dset->dispatches[j])); - isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n); - if (dset->mctx == mctx) - isc_mem_detach(&dset->mctx); - - fail_lock: - DESTROYLOCK(&dset->lock); - - fail_alloc: - isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t)); - return (result); -} - -void -dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) { - int i; - - REQUIRE(dset != NULL); - - for (i = 0; i < dset->ndisp; i++) { - isc_socket_t *sock; - sock = dns_dispatch_getsocket(dset->dispatches[i]); - isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); - } -} - -void -dns_dispatchset_destroy(dns_dispatchset_t **dsetp) { - dns_dispatchset_t *dset; - int i; - - REQUIRE(dsetp != NULL && *dsetp != NULL); - - dset = *dsetp; - for (i = 0; i < dset->ndisp; i++) - dns_dispatch_detach(&(dset->dispatches[i])); - isc_mem_put(dset->mctx, dset->dispatches, - sizeof(dns_dispatch_t *) * dset->ndisp); - DESTROYLOCK(&dset->lock); - isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t)); - - *dsetp = NULL; -} - -void -dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp) { - REQUIRE(VALID_DISPATCH(disp)); - disp->dscp = dscp; -} - -isc_dscp_t -dns_dispatch_getdscp(dns_dispatch_t *disp) { - REQUIRE(VALID_DISPATCH(disp)); - return (disp->dscp); -} - -#if 0 -void -dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) { - dns_dispatch_t *disp; - char foo[1024]; - - disp = ISC_LIST_HEAD(mgr->list); - while (disp != NULL) { - isc_sockaddr_format(&disp->local, foo, sizeof(foo)); - printf("\tdispatch %p, addr %s\n", disp, foo); - disp = ISC_LIST_NEXT(disp, link); - } -} -#endif diff --git a/lib/dns-pkcs11/dlz.c b/lib/dns-pkcs11/dlz.c deleted file mode 100644 index 66434e6..0000000 --- a/lib/dns-pkcs11/dlz.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. - * - * 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 STICHTING NLNET - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * STICHTING NLNET 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. - * - * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was - * conceived and contributed by Rob Butler. - * - * 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 ROB BUTLER - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * ROB BUTLER 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. - */ - - -/*! \file */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include - -/*** - *** Supported DLZ DB Implementations Registry - ***/ - -static ISC_LIST(dns_dlzimplementation_t) dlz_implementations; -static isc_rwlock_t dlz_implock; -static isc_once_t once = ISC_ONCE_INIT; - -static void -dlz_initialize(void) { - RUNTIME_CHECK(isc_rwlock_init(&dlz_implock, 0, 0) == ISC_R_SUCCESS); - ISC_LIST_INIT(dlz_implementations); -} - -/*% - * Searches the dlz_implementations list for a driver matching name. - */ -static inline dns_dlzimplementation_t * -dlz_impfind(const char *name) { - dns_dlzimplementation_t *imp; - - for (imp = ISC_LIST_HEAD(dlz_implementations); - imp != NULL; - imp = ISC_LIST_NEXT(imp, link)) - if (strcasecmp(name, imp->name) == 0) - return (imp); - return (NULL); -} - -/*** - *** Basic DLZ Methods - ***/ - -isc_result_t -dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, - isc_sockaddr_t *clientaddr, dns_db_t **dbp) -{ - isc_result_t result = ISC_R_NOTFOUND; - dns_dlzallowzonexfr_t allowzonexfr; - dns_dlzdb_t *dlzdb; - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(name != NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - /* - * Find a driver in which the zone exists and transfer is supported - */ - for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); - dlzdb != NULL; - dlzdb = ISC_LIST_NEXT(dlzdb, link)) - { - REQUIRE(DNS_DLZ_VALID(dlzdb)); - - allowzonexfr = dlzdb->implementation->methods->allowzonexfr; - result = (*allowzonexfr)(dlzdb->implementation->driverarg, - dlzdb->dbdata, dlzdb->mctx, - view->rdclass, name, clientaddr, dbp); - - /* - * if ISC_R_NOPERM, we found the right database but - * the zone may not transfer. - */ - if (result == ISC_R_SUCCESS || result == ISC_R_NOPERM) - return (result); - } - - if (result == ISC_R_NOTIMPLEMENTED) - result = ISC_R_NOTFOUND; - - return (result); -} - -isc_result_t -dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, - unsigned int argc, char *argv[], dns_dlzdb_t **dbp) -{ - dns_dlzimplementation_t *impinfo; - isc_result_t result; - dns_dlzdb_t *db = NULL; - - /* - * initialize the dlz_implementations list, this is guaranteed - * to only really happen once. - */ - RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(dlzname != NULL); - REQUIRE(drivername != NULL); - REQUIRE(mctx != NULL); - - /* write log message */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_INFO, - "Loading '%s' using driver %s", dlzname, drivername); - - /* lock the dlz_implementations list so we can search it. */ - RWLOCK(&dlz_implock, isc_rwlocktype_read); - - /* search for the driver implementation */ - impinfo = dlz_impfind(drivername); - if (impinfo == NULL) { - RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, - "unsupported DLZ database driver '%s'." - " %s not loaded.", - drivername, dlzname); - - return (ISC_R_NOTFOUND); - } - - /* Allocate memory to hold the DLZ database driver */ - db = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); - if (db == NULL) { - RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - return (ISC_R_NOMEMORY); - } - - /* Make sure memory region is set to all 0's */ - memset(db, 0, sizeof(dns_dlzdb_t)); - - ISC_LINK_INIT(db, link); - db->implementation = impinfo; - if (dlzname != NULL) - db->dlzname = isc_mem_strdup(mctx, dlzname); - - /* Create a new database using implementation 'drivername'. */ - result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, - impinfo->driverarg, - &db->dbdata)); - - /* mark the DLZ driver as valid */ - if (result == ISC_R_SUCCESS) { - RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - db->magic = DNS_DLZ_MAGIC; - isc_mem_attach(mctx, &db->mctx); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), - "DLZ driver loaded successfully."); - *dbp = db; - return (ISC_R_SUCCESS); - } else { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, - "DLZ driver failed to load."); - } - - /* impinfo->methods->create failed. */ - RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - isc_mem_put(mctx, db, sizeof(dns_dlzdb_t)); - return (result); -} - -void -dns_dlzdestroy(dns_dlzdb_t **dbp) { - dns_dlzdestroy_t destroy; - dns_dlzdb_t *db; - - /* Write debugging message to log */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), - "Unloading DLZ driver."); - - /* - * Perform checks to make sure data is as we expect it to be. - */ - REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp)); - - db = *dbp; - *dbp = NULL; - - if (db->ssutable != NULL) - dns_ssutable_detach(&db->ssutable); - - /* call the drivers destroy method */ - if (db->dlzname != NULL) - isc_mem_free(db->mctx, db->dlzname); - destroy = db->implementation->methods->destroy; - (*destroy)(db->implementation->driverarg, db->dbdata); - /* return memory and detach */ - isc_mem_putanddetach(&db->mctx, db, sizeof(dns_dlzdb_t)); -} - -/*% - * Registers a DLZ driver. This basically just adds the dlz - * driver to the list of available drivers in the dlz_implementations list. - */ -isc_result_t -dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, - void *driverarg, isc_mem_t *mctx, - dns_dlzimplementation_t **dlzimp) -{ - - dns_dlzimplementation_t *dlz_imp; - - /* Write debugging message to log */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), - "Registering DLZ driver '%s'", drivername); - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(drivername != NULL); - REQUIRE(methods != NULL); - REQUIRE(methods->create != NULL); - REQUIRE(methods->destroy != NULL); - REQUIRE(methods->findzone != NULL); - REQUIRE(mctx != NULL); - REQUIRE(dlzimp != NULL && *dlzimp == NULL); - - /* - * initialize the dlz_implementations list, this is guaranteed - * to only really happen once. - */ - RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); - - /* lock the dlz_implementations list so we can modify it. */ - RWLOCK(&dlz_implock, isc_rwlocktype_write); - - /* - * check that another already registered driver isn't using - * the same name - */ - dlz_imp = dlz_impfind(drivername); - if (dlz_imp != NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), - "DLZ Driver '%s' already registered", - drivername); - RWUNLOCK(&dlz_implock, isc_rwlocktype_write); - return (ISC_R_EXISTS); - } - - /* - * Allocate memory for a dlz_implementation object. Error if - * we cannot. - */ - dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t)); - if (dlz_imp == NULL) { - RWUNLOCK(&dlz_implock, isc_rwlocktype_write); - return (ISC_R_NOMEMORY); - } - - /* Make sure memory region is set to all 0's */ - memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t)); - - /* Store the data passed into this method */ - dlz_imp->name = drivername; - dlz_imp->methods = methods; - dlz_imp->mctx = NULL; - dlz_imp->driverarg = driverarg; - - /* attach the new dlz_implementation object to a memory context */ - isc_mem_attach(mctx, &dlz_imp->mctx); - - /* - * prepare the dlz_implementation object to be put in a list, - * and append it to the list - */ - ISC_LINK_INIT(dlz_imp, link); - ISC_LIST_APPEND(dlz_implementations, dlz_imp, link); - - /* Unlock the dlz_implementations list. */ - RWUNLOCK(&dlz_implock, isc_rwlocktype_write); - - /* Pass back the dlz_implementation that we created. */ - *dlzimp = dlz_imp; - - return (ISC_R_SUCCESS); -} - -/*% - * Tokenize the string "s" into whitespace-separated words, - * return the number of words in '*argcp' and an array - * of pointers to the words in '*argvp'. The caller - * must free the array using isc_mem_put(). The string - * is modified in-place. - */ -isc_result_t -dns_dlzstrtoargv(isc_mem_t *mctx, char *s, - unsigned int *argcp, char ***argvp) -{ - return(isc_commandline_strtoargv(mctx, s, argcp, argvp, 0)); -} - -/*% - * Unregisters a DLZ driver. This basically just removes the dlz - * driver from the list of available drivers in the dlz_implementations list. - */ -void -dns_dlzunregister(dns_dlzimplementation_t **dlzimp) { - dns_dlzimplementation_t *dlz_imp; - isc_mem_t *mctx; - - /* Write debugging message to log */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), - "Unregistering DLZ driver."); - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(dlzimp != NULL && *dlzimp != NULL); - - /* - * initialize the dlz_implementations list, this is guaranteed - * to only really happen once. - */ - RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); - - dlz_imp = *dlzimp; - - /* lock the dlz_implementations list so we can modify it. */ - RWLOCK(&dlz_implock, isc_rwlocktype_write); - - /* remove the dlz_implementation object from the list */ - ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link); - mctx = dlz_imp->mctx; - - /* - * Return the memory back to the available memory pool and - * remove it from the memory context. - */ - isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t)); - isc_mem_detach(&mctx); - - /* Unlock the dlz_implementations list. */ - RWUNLOCK(&dlz_implock, isc_rwlocktype_write); -} - -/* - * Create a writeable DLZ zone. This can be called by DLZ drivers - * during configure() to create a zone that can be updated. The zone - * type is set to dns_zone_dlz, which is equivalent to a master zone - * - * This function uses a callback setup in dns_dlzconfigure() to call - * into the server zone code to setup the remaining pieces of server - * specific functionality on the zone - */ -isc_result_t -dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb, - const char *zone_name) -{ - dns_zone_t *zone = NULL; - dns_zone_t *dupzone = NULL; - isc_result_t result; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - - REQUIRE(DNS_DLZ_VALID(dlzdb)); - - REQUIRE(dlzdb->configure_callback != NULL); - - isc_buffer_constinit(&buffer, zone_name, strlen(zone_name)); - isc_buffer_add(&buffer, strlen(zone_name)); - dns_fixedname_init(&fixorigin); - result = dns_name_fromtext(dns_fixedname_name(&fixorigin), - &buffer, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - origin = dns_fixedname_name(&fixorigin); - - if (!dlzdb->search) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_WARNING, - "DLZ %s has 'search no;', but attempted to " - "register writeable zone %s.", - dlzdb->dlzname, zone_name); - result = ISC_R_SUCCESS; - goto cleanup; - } - - /* See if the zone already exists */ - result = dns_view_findzone(view, origin, &dupzone); - if (result == ISC_R_SUCCESS) { - dns_zone_detach(&dupzone); - result = ISC_R_EXISTS; - goto cleanup; - } - INSIST(dupzone == NULL); - - /* Create it */ - result = dns_zone_create(&zone, view->mctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_zone_setorigin(zone, origin); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_zone_setview(zone, view); - - dns_zone_setadded(zone, true); - - if (dlzdb->ssutable == NULL) { - result = dns_ssutable_createdlz(dlzdb->mctx, - &dlzdb->ssutable, dlzdb); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - dns_zone_setssutable(zone, dlzdb->ssutable); - - result = dlzdb->configure_callback(view, dlzdb, zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_view_addzone(view, zone); - - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - - return (result); -} - -/*% - * Configure a DLZ driver. This is optional, and if supplied gives - * the backend an opportunity to configure parameters related to DLZ. - */ -isc_result_t -dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb, - dlzconfigure_callback_t callback) -{ - dns_dlzimplementation_t *impl; - isc_result_t result; - - REQUIRE(DNS_DLZ_VALID(dlzdb)); - REQUIRE(dlzdb->implementation != NULL); - - impl = dlzdb->implementation; - - if (impl->methods->configure == NULL) - return (ISC_R_SUCCESS); - - dlzdb->configure_callback = callback; - - result = impl->methods->configure(impl->driverarg, dlzdb->dbdata, - view, dlzdb); - return (result); -} - -bool -dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *tcpaddr, - dns_rdatatype_t type, const dst_key_t *key) -{ - dns_dlzimplementation_t *impl; - bool r; - - REQUIRE(dlzdatabase != NULL); - REQUIRE(dlzdatabase->implementation != NULL); - REQUIRE(dlzdatabase->implementation->methods != NULL); - impl = dlzdatabase->implementation; - - if (impl->methods->ssumatch == NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_INFO, - "No ssumatch method for DLZ database"); - return (false); - } - - r = impl->methods->ssumatch(signer, name, tcpaddr, type, key, - impl->driverarg, dlzdatabase->dbdata); - return (r); -} diff --git a/lib/dns-pkcs11/dns64.c b/lib/dns-pkcs11/dns64.c deleted file mode 100644 index dd56757..0000000 --- a/lib/dns-pkcs11/dns64.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -struct dns_dns64 { - unsigned char bits[16]; /* - * Prefix + suffix bits. - */ - dns_acl_t * clients; /* - * Which clients get mapped - * addresses. - */ - dns_acl_t * mapped; /* - * IPv4 addresses to be mapped. - */ - dns_acl_t * excluded; /* - * IPv6 addresses that are - * treated as not existing. - */ - unsigned int prefixlen; /* - * Start of mapped address. - */ - unsigned int flags; - isc_mem_t * mctx; - ISC_LINK(dns_dns64_t) link; -}; - -isc_result_t -dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix, - unsigned int prefixlen, isc_netaddr_t *suffix, - dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded, - unsigned int flags, dns_dns64_t **dns64p) -{ - dns_dns64_t *dns64; - unsigned int nbytes = 16; - - REQUIRE(prefix != NULL && prefix->family == AF_INET6); - /* Legal prefix lengths from rfc6052.txt. */ - REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 || - prefixlen == 56 || prefixlen == 64 || prefixlen == 96); - REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS); - REQUIRE(dns64p != NULL && *dns64p == NULL); - - if (suffix != NULL) { - static const unsigned char zeros[16]; - REQUIRE(prefix->family == AF_INET6); - nbytes = prefixlen / 8 + 4; - /* Bits 64-71 are zeros. rfc6052.txt */ - if (prefixlen >= 32 && prefixlen <= 64) - nbytes++; - REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0); - } - - dns64 = isc_mem_get(mctx, sizeof(dns_dns64_t)); - if (dns64 == NULL) - return (ISC_R_NOMEMORY); - memset(dns64->bits, 0, sizeof(dns64->bits)); - memmove(dns64->bits, prefix->type.in6.s6_addr, prefixlen / 8); - if (suffix != NULL) - memmove(dns64->bits + nbytes, suffix->type.in6.s6_addr + nbytes, - 16 - nbytes); - dns64->clients = NULL; - if (clients != NULL) - dns_acl_attach(clients, &dns64->clients); - dns64->mapped = NULL; - if (mapped != NULL) - dns_acl_attach(mapped, &dns64->mapped); - dns64->excluded = NULL; - if (excluded != NULL) - dns_acl_attach(excluded, &dns64->excluded); - dns64->prefixlen = prefixlen; - dns64->flags = flags; - ISC_LINK_INIT(dns64, link); - dns64->mctx = NULL; - isc_mem_attach(mctx, &dns64->mctx); - *dns64p = dns64; - return (ISC_R_SUCCESS); -} - -void -dns_dns64_destroy(dns_dns64_t **dns64p) { - dns_dns64_t *dns64; - - REQUIRE(dns64p != NULL && *dns64p != NULL); - - dns64 = *dns64p; - *dns64p = NULL; - - REQUIRE(!ISC_LINK_LINKED(dns64, link)); - - if (dns64->clients != NULL) - dns_acl_detach(&dns64->clients); - if (dns64->mapped != NULL) - dns_acl_detach(&dns64->mapped); - if (dns64->excluded != NULL) - dns_acl_detach(&dns64->excluded); - isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64)); -} - -isc_result_t -dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, const dns_aclenv_t *env, - unsigned int flags, unsigned char *a, unsigned char *aaaa) -{ - unsigned int nbytes, i; - isc_result_t result; - int match; - - if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 && - (flags & DNS_DNS64_RECURSIVE) == 0) - return (DNS_R_DISALLOWED); - - if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 && - (flags & DNS_DNS64_DNSSEC) != 0) - return (DNS_R_DISALLOWED); - - if (dns64->clients != NULL) { - result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env, - &match, NULL); - if (result != ISC_R_SUCCESS) - return (result); - if (match <= 0) - return (DNS_R_DISALLOWED); - } - - if (dns64->mapped != NULL) { - struct in_addr ina; - isc_netaddr_t netaddr; - - memmove(&ina.s_addr, a, 4); - isc_netaddr_fromin(&netaddr, &ina); - result = dns_acl_match(&netaddr, NULL, dns64->mapped, env, - &match, NULL); - if (result != ISC_R_SUCCESS) - return (result); - if (match <= 0) - return (DNS_R_DISALLOWED); - } - - nbytes = dns64->prefixlen / 8; - INSIST(nbytes <= 12); - /* Copy prefix. */ - memmove(aaaa, dns64->bits, nbytes); - /* Bits 64-71 are zeros. rfc6052.txt */ - if (nbytes == 8) - aaaa[nbytes++] = 0; - /* Copy mapped address. */ - for (i = 0; i < 4U; i++) { - aaaa[nbytes++] = a[i]; - /* Bits 64-71 are zeros. rfc6052.txt */ - if (nbytes == 8) - aaaa[nbytes++] = 0; - } - /* Copy suffix. */ - memmove(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes); - return (ISC_R_SUCCESS); -} - -dns_dns64_t * -dns_dns64_next(dns_dns64_t *dns64) { - dns64 = ISC_LIST_NEXT(dns64, link); - return (dns64); -} - -void -dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) { - ISC_LIST_APPEND(*list, dns64, link); -} - -void -dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) { - ISC_LIST_UNLINK(*list, dns64, link); -} - -bool -dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, const dns_aclenv_t *env, - unsigned int flags, dns_rdataset_t *rdataset, - bool *aaaaok, size_t aaaaoklen) -{ - struct in6_addr in6; - isc_netaddr_t netaddr; - isc_result_t result; - int match; - bool answer = false; - bool found = false; - unsigned int i, ok; - - REQUIRE(rdataset != NULL); - REQUIRE(rdataset->type == dns_rdatatype_aaaa); - REQUIRE(rdataset->rdclass == dns_rdataclass_in); - if (aaaaok != NULL) - REQUIRE(aaaaoklen == dns_rdataset_count(rdataset)); - - for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) { - if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 && - (flags & DNS_DNS64_RECURSIVE) == 0) - continue; - - if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 && - (flags & DNS_DNS64_DNSSEC) != 0) - continue; - /* - * Work out if this dns64 structure applies to this client. - */ - if (dns64->clients != NULL) { - result = dns_acl_match(reqaddr, reqsigner, - dns64->clients, env, - &match, NULL); - if (result != ISC_R_SUCCESS) - continue; - if (match <= 0) - continue; - } - - if (!found && aaaaok != NULL) { - for (i = 0; i < aaaaoklen; i++) - aaaaok[i] = false; - } - found = true; - - /* - * If we are not excluding any addresses then any AAAA - * will do. - */ - if (dns64->excluded == NULL) { - answer = true; - if (aaaaok == NULL) - goto done; - for (i = 0; i < aaaaoklen; i++) - aaaaok[i] = true; - goto done; - } - - i = 0; ok = 0; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - if (aaaaok == NULL || !aaaaok[i]) { - - dns_rdataset_current(rdataset, &rdata); - memmove(&in6.s6_addr, rdata.data, 16); - isc_netaddr_fromin6(&netaddr, &in6); - - result = dns_acl_match(&netaddr, NULL, - dns64->excluded, - env, &match, NULL); - if (result == ISC_R_SUCCESS && match <= 0) { - answer = true; - if (aaaaok == NULL) - goto done; - aaaaok[i] = true; - ok++; - } - } else - ok++; - i++; - } - /* - * Are all addresses ok? - */ - if (aaaaok != NULL && ok == aaaaoklen) - goto done; - } - - done: - if (!found && aaaaok != NULL) { - for (i = 0; i < aaaaoklen; i++) - aaaaok[i] = true; - } - return (found ? answer : true); -} diff --git a/lib/dns-pkcs11/dnssec.c b/lib/dns-pkcs11/dnssec.c deleted file mode 100644 index b6b2405..0000000 --- a/lib/dns-pkcs11/dnssec.c +++ /dev/null @@ -1,2251 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for DNS_TSIG_FUDGE */ - -#include - -LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats; - -#define is_response(msg) ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - - -#define TYPE_SIGN 0 -#define TYPE_VERIFY 1 - -static isc_result_t -digest_callback(void *arg, isc_region_t *data); - -static int -rdata_compare_wrapper(const void *rdata1, const void *rdata2); - -static isc_result_t -rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, - dns_rdata_t **rdata, int *nrdata); - -static isc_result_t -digest_callback(void *arg, isc_region_t *data) { - dst_context_t *ctx = arg; - - return (dst_context_adddata(ctx, data)); -} - -static inline void -inc_stat(isc_statscounter_t counter) { - if (dns_dnssec_stats != NULL) - isc_stats_increment(dns_dnssec_stats, counter); -} - -/* - * Make qsort happy. - */ -static int -rdata_compare_wrapper(const void *rdata1, const void *rdata2) { - return (dns_rdata_compare((const dns_rdata_t *)rdata1, - (const dns_rdata_t *)rdata2)); -} - -/* - * Sort the rdataset into an array. - */ -static isc_result_t -rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, - dns_rdata_t **rdata, int *nrdata) -{ - isc_result_t ret; - int i = 0, n; - dns_rdata_t *data; - dns_rdataset_t rdataset; - - n = dns_rdataset_count(set); - - data = isc_mem_get(mctx, n * sizeof(dns_rdata_t)); - if (data == NULL) - return (ISC_R_NOMEMORY); - - dns_rdataset_init(&rdataset); - dns_rdataset_clone(set, &rdataset); - ret = dns_rdataset_first(&rdataset); - if (ret != ISC_R_SUCCESS) { - dns_rdataset_disassociate(&rdataset); - isc_mem_put(mctx, data, n * sizeof(dns_rdata_t)); - return (ret); - } - - /* - * Put them in the array. - */ - do { - dns_rdata_init(&data[i]); - dns_rdataset_current(&rdataset, &data[i++]); - } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS); - - /* - * Sort the array. - */ - qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper); - *rdata = data; - *nrdata = n; - dns_rdataset_disassociate(&rdataset); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, - dst_key_t **key) -{ - isc_buffer_t b; - isc_region_t r; - - INSIST(name != NULL); - INSIST(rdata != NULL); - INSIST(mctx != NULL); - INSIST(key != NULL); - INSIST(*key == NULL); - REQUIRE(rdata->type == dns_rdatatype_key || - rdata->type == dns_rdatatype_dnskey); - - dns_rdata_toregion(rdata, &r); - isc_buffer_init(&b, r.base, r.length); - isc_buffer_add(&b, r.length); - return (dst_key_fromdns(name, rdata->rdclass, &b, mctx, key)); -} - -static isc_result_t -digest_sig(dst_context_t *ctx, bool downcase, dns_rdata_t *sigrdata, - dns_rdata_rrsig_t *rrsig) -{ - isc_region_t r; - isc_result_t ret; - dns_fixedname_t fname; - - dns_rdata_toregion(sigrdata, &r); - INSIST(r.length >= 19); - - r.length = 18; - ret = dst_context_adddata(ctx, &r); - if (ret != ISC_R_SUCCESS) - return (ret); - if (downcase) { - dns_fixedname_init(&fname); - - RUNTIME_CHECK(dns_name_downcase(&rrsig->signer, - dns_fixedname_name(&fname), - NULL) == ISC_R_SUCCESS); - dns_name_toregion(dns_fixedname_name(&fname), &r); - } else - dns_name_toregion(&rrsig->signer, &r); - - return (dst_context_adddata(ctx, &r)); -} - -isc_result_t -dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - isc_stdtime_t *inception, isc_stdtime_t *expire, - isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata) -{ - dns_rdata_rrsig_t sig; - dns_rdata_t tmpsigrdata; - dns_rdata_t *rdatas; - int nrdatas, i; - isc_buffer_t sigbuf, envbuf; - isc_region_t r; - dst_context_t *ctx = NULL; - isc_result_t ret; - isc_buffer_t *databuf = NULL; - char data[256 + 8]; - uint32_t flags; - unsigned int sigsize; - dns_fixedname_t fnewname; - dns_fixedname_t fsigner; - - REQUIRE(name != NULL); - REQUIRE(dns_name_countlabels(name) <= 255); - REQUIRE(set != NULL); - REQUIRE(key != NULL); - REQUIRE(inception != NULL); - REQUIRE(expire != NULL); - REQUIRE(mctx != NULL); - REQUIRE(sigrdata != NULL); - - if (*inception >= *expire) - return (DNS_R_INVALIDTIME); - - /* - * Is the key allowed to sign data? - */ - flags = dst_key_flags(key); - if ((flags & DNS_KEYTYPE_NOAUTH) != 0) { - return (DNS_R_KEYUNAUTHORIZED); - } - if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) { - return (DNS_R_KEYUNAUTHORIZED); - } - - sig.mctx = mctx; - sig.common.rdclass = set->rdclass; - sig.common.rdtype = dns_rdatatype_rrsig; - ISC_LINK_INIT(&sig.common, link); - - /* - * Downcase signer. - */ - dns_name_init(&sig.signer, NULL); - dns_fixedname_init(&fsigner); - RUNTIME_CHECK(dns_name_downcase(dst_key_name(key), - dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS); - dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer); - - sig.covered = set->type; - sig.algorithm = dst_key_alg(key); - sig.labels = dns_name_countlabels(name) - 1; - if (dns_name_iswildcard(name)) - sig.labels--; - sig.originalttl = set->ttl; - sig.timesigned = *inception; - sig.timeexpire = *expire; - sig.keyid = dst_key_id(key); - ret = dst_key_sigsize(key, &sigsize); - if (ret != ISC_R_SUCCESS) - return (ret); - sig.siglen = sigsize; - /* - * The actual contents of sig.signature are not important yet, since - * they're not used in digest_sig(). - */ - sig.signature = isc_mem_get(mctx, sig.siglen); - if (sig.signature == NULL) - return (ISC_R_NOMEMORY); - - ret = isc_buffer_allocate(mctx, &databuf, sigsize + 256 + 18); - if (ret != ISC_R_SUCCESS) - goto cleanup_signature; - - dns_rdata_init(&tmpsigrdata); - ret = dns_rdata_fromstruct(&tmpsigrdata, sig.common.rdclass, - sig.common.rdtype, &sig, databuf); - if (ret != ISC_R_SUCCESS) - goto cleanup_databuf; - - ret = dst_context_create3(key, mctx, - DNS_LOGCATEGORY_DNSSEC, true, &ctx); - if (ret != ISC_R_SUCCESS) - goto cleanup_databuf; - - /* - * Digest the SIG rdata. - */ - ret = digest_sig(ctx, false, &tmpsigrdata, &sig); - if (ret != ISC_R_SUCCESS) - goto cleanup_context; - - dns_fixedname_init(&fnewname); - RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname), - NULL) == ISC_R_SUCCESS); - dns_name_toregion(dns_fixedname_name(&fnewname), &r); - - /* - * Create an envelope for each rdata: . - */ - isc_buffer_init(&envbuf, data, sizeof(data)); - memmove(data, r.base, r.length); - isc_buffer_add(&envbuf, r.length); - isc_buffer_putuint16(&envbuf, set->type); - isc_buffer_putuint16(&envbuf, set->rdclass); - isc_buffer_putuint32(&envbuf, set->ttl); - - ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas); - if (ret != ISC_R_SUCCESS) - goto cleanup_context; - isc_buffer_usedregion(&envbuf, &r); - - for (i = 0; i < nrdatas; i++) { - uint16_t len; - isc_buffer_t lenbuf; - isc_region_t lenr; - - /* - * Skip duplicates. - */ - if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0) - continue; - - /* - * Digest the envelope. - */ - ret = dst_context_adddata(ctx, &r); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - - /* - * Digest the length of the rdata. - */ - isc_buffer_init(&lenbuf, &len, sizeof(len)); - INSIST(rdatas[i].length < 65536); - isc_buffer_putuint16(&lenbuf, (uint16_t)rdatas[i].length); - isc_buffer_usedregion(&lenbuf, &lenr); - ret = dst_context_adddata(ctx, &lenr); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - - /* - * Digest the rdata. - */ - ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - } - - isc_buffer_init(&sigbuf, sig.signature, sig.siglen); - ret = dst_context_sign(ctx, &sigbuf); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - isc_buffer_usedregion(&sigbuf, &r); - if (r.length != sig.siglen) { - ret = ISC_R_NOSPACE; - goto cleanup_array; - } - - ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, - sig.common.rdtype, &sig, buffer); - -cleanup_array: - isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); -cleanup_context: - dst_context_destroy(&ctx); -cleanup_databuf: - isc_buffer_free(&databuf); -cleanup_signature: - isc_mem_put(mctx, sig.signature, sig.siglen); - - return (ret); -} - -isc_result_t -dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, isc_mem_t *mctx, - dns_rdata_t *sigrdata, dns_name_t *wild) -{ - return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx, - sigrdata, wild)); -} - -isc_result_t -dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, unsigned int maxbits, - isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) -{ - dns_rdata_rrsig_t sig; - dns_fixedname_t fnewname; - isc_region_t r; - isc_buffer_t envbuf; - dns_rdata_t *rdatas; - int nrdatas, i; - isc_stdtime_t now; - isc_result_t ret; - unsigned char data[300]; - dst_context_t *ctx = NULL; - int labels = 0; - uint32_t flags; - bool downcase = false; - - REQUIRE(name != NULL); - REQUIRE(set != NULL); - REQUIRE(key != NULL); - REQUIRE(mctx != NULL); - REQUIRE(sigrdata != NULL && sigrdata->type == dns_rdatatype_rrsig); - - ret = dns_rdata_tostruct(sigrdata, &sig, NULL); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (set->type != sig.covered) - return (DNS_R_SIGINVALID); - - if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGINVALID); - } - - if (!ignoretime) { - isc_stdtime_get(&now); - - /* - * Is SIG temporally valid? - */ - if (isc_serial_lt((uint32_t)now, sig.timesigned)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGFUTURE); - } else if (isc_serial_lt(sig.timeexpire, (uint32_t)now)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGEXPIRED); - } - } - - /* - * NS, SOA and DNSSKEY records are signed by their owner. - * DS records are signed by the parent. - */ - switch (set->type) { - case dns_rdatatype_ns: - case dns_rdatatype_soa: - case dns_rdatatype_dnskey: - if (!dns_name_equal(name, &sig.signer)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGINVALID); - } - break; - case dns_rdatatype_ds: - if (dns_name_equal(name, &sig.signer)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGINVALID); - } - /* FALLTHROUGH */ - default: - if (!dns_name_issubdomain(name, &sig.signer)) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_SIGINVALID); - } - break; - } - - /* - * Is the key allowed to sign data? - */ - flags = dst_key_flags(key); - if ((flags & DNS_KEYTYPE_NOAUTH) != 0) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_KEYUNAUTHORIZED); - } - if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) { - inc_stat(dns_dnssecstats_fail); - return (DNS_R_KEYUNAUTHORIZED); - } - - again: - ret = dst_context_create4(key, mctx, DNS_LOGCATEGORY_DNSSEC, - false, maxbits, &ctx); - if (ret != ISC_R_SUCCESS) - goto cleanup_struct; - - /* - * Digest the SIG rdata (not including the signature). - */ - ret = digest_sig(ctx, downcase, sigrdata, &sig); - if (ret != ISC_R_SUCCESS) - goto cleanup_context; - - /* - * If the name is an expanded wildcard, use the wildcard name. - */ - dns_fixedname_init(&fnewname); - labels = dns_name_countlabels(name) - 1; - RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname), - NULL) == ISC_R_SUCCESS); - if (labels - sig.labels > 0) - dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1, - NULL, dns_fixedname_name(&fnewname)); - - dns_name_toregion(dns_fixedname_name(&fnewname), &r); - - /* - * Create an envelope for each rdata: . - */ - isc_buffer_init(&envbuf, data, sizeof(data)); - if (labels - sig.labels > 0) { - isc_buffer_putuint8(&envbuf, 1); - isc_buffer_putuint8(&envbuf, '*'); - memmove(data + 2, r.base, r.length); - } - else - memmove(data, r.base, r.length); - isc_buffer_add(&envbuf, r.length); - isc_buffer_putuint16(&envbuf, set->type); - isc_buffer_putuint16(&envbuf, set->rdclass); - isc_buffer_putuint32(&envbuf, sig.originalttl); - - ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas); - if (ret != ISC_R_SUCCESS) - goto cleanup_context; - - isc_buffer_usedregion(&envbuf, &r); - - for (i = 0; i < nrdatas; i++) { - uint16_t len; - isc_buffer_t lenbuf; - isc_region_t lenr; - - /* - * Skip duplicates. - */ - if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0) - continue; - - /* - * Digest the envelope. - */ - ret = dst_context_adddata(ctx, &r); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - - /* - * Digest the rdata length. - */ - isc_buffer_init(&lenbuf, &len, sizeof(len)); - INSIST(rdatas[i].length < 65536); - isc_buffer_putuint16(&lenbuf, (uint16_t)rdatas[i].length); - isc_buffer_usedregion(&lenbuf, &lenr); - - /* - * Digest the rdata. - */ - ret = dst_context_adddata(ctx, &lenr); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx); - if (ret != ISC_R_SUCCESS) - goto cleanup_array; - } - - r.base = sig.signature; - r.length = sig.siglen; - ret = dst_context_verify2(ctx, maxbits, &r); - if (ret == ISC_R_SUCCESS && downcase) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, - DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), - "successfully validated after lower casing " - "signer '%s'", namebuf); - inc_stat(dns_dnssecstats_downcase); - } else if (ret == ISC_R_SUCCESS) - inc_stat(dns_dnssecstats_asis); - -cleanup_array: - isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); -cleanup_context: - dst_context_destroy(&ctx); - if (ret == DST_R_VERIFYFAILURE && !downcase) { - downcase = true; - goto again; - } -cleanup_struct: - dns_rdata_freestruct(&sig); - - if (ret == DST_R_VERIFYFAILURE) - ret = DNS_R_SIGINVALID; - - if (ret != ISC_R_SUCCESS) - inc_stat(dns_dnssecstats_fail); - - if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) { - if (wild != NULL) - RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, - dns_fixedname_name(&fnewname), - wild, NULL) == ISC_R_SUCCESS); - inc_stat(dns_dnssecstats_wildcard); - ret = DNS_R_FROMWILDCARD; - } - return (ret); -} - -isc_result_t -dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, isc_mem_t *mctx, - dns_rdata_t *sigrdata) -{ - isc_result_t result; - - result = dns_dnssec_verify2(name, set, key, ignoretime, mctx, - sigrdata, NULL); - if (result == DNS_R_FROMWILDCARD) - result = ISC_R_SUCCESS; - return (result); -} - -bool -dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) { - isc_result_t result; - isc_stdtime_t publish, active, revoke, inactive, deltime; - bool pubset = false, actset = false; - bool revset = false, inactset = false; - bool delset = false; - int major, minor; - - /* Is this an old-style key? */ - result = dst_key_getprivateformat(key, &major, &minor); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Smart signing started with key format 1.3; prior to that, all - * keys are assumed active - */ - if (major == 1 && minor <= 2) - return (true); - - result = dst_key_gettime(key, DST_TIME_PUBLISH, &publish); - if (result == ISC_R_SUCCESS) - pubset = true; - - result = dst_key_gettime(key, DST_TIME_ACTIVATE, &active); - if (result == ISC_R_SUCCESS) - actset = true; - - result = dst_key_gettime(key, DST_TIME_REVOKE, &revoke); - if (result == ISC_R_SUCCESS) - revset = true; - - result = dst_key_gettime(key, DST_TIME_INACTIVE, &inactive); - if (result == ISC_R_SUCCESS) - inactset = true; - - result = dst_key_gettime(key, DST_TIME_DELETE, &deltime); - if (result == ISC_R_SUCCESS) - delset = true; - - if ((inactset && inactive <= now) || (delset && deltime <= now)) - return (false); - - if (revset && revoke <= now && pubset && publish <= now) - return (true); - - if (actset && active <= now) - return (true); - - return (false); -} - -/*%< - * Indicate whether a key is scheduled to to have CDS/CDNSKEY records - * published now. - * - * Returns true iff. - * - SyncPublish is set and in the past, AND - * - SyncDelete is unset or in the future - */ -static bool -syncpublish(dst_key_t *key, isc_stdtime_t now) { - isc_result_t result; - isc_stdtime_t when; - int major, minor; - bool publish; - - /* - * Is this an old-style key? - */ - result = dst_key_getprivateformat(key, &major, &minor); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Smart signing started with key format 1.3 - */ - if (major == 1 && minor <= 2) - return (false); - - publish = false; - result = dst_key_gettime(key, DST_TIME_SYNCPUBLISH, &when); - if (result == ISC_R_SUCCESS && when <= now) { - publish = true; - } - result = dst_key_gettime(key, DST_TIME_SYNCDELETE, &when); - if (result == ISC_R_SUCCESS && when < now) { - publish = false; - } - return (publish); -} - -/*%< - * Indicate whether a key is scheduled to to have CDS/CDNSKEY records - * deleted now. - * - * Returns true iff. SyncDelete is set and in the past. - */ -static bool -syncdelete(dst_key_t *key, isc_stdtime_t now) { - isc_result_t result; - isc_stdtime_t when; - int major, minor; - - /* - * Is this an old-style key? - */ - result = dst_key_getprivateformat(key, &major, &minor); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Smart signing started with key format 1.3. - */ - if (major == 1 && minor <= 2) - return (false); - - result = dst_key_gettime(key, DST_TIME_SYNCDELETE, &when); - if (result != ISC_R_SUCCESS) - return (false); - if (when <= now) - return (true); - return (false); -} - -#define is_zone_key(key) ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) \ - == DNS_KEYOWNER_ZONE) - -isc_result_t -dns_dnssec_findzonekeys3(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_stdtime_t now, - isc_mem_t *mctx, unsigned int maxkeys, - dst_key_t **keys, unsigned int *nkeys) -{ - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dst_key_t *pubkey = NULL; - unsigned int count = 0; - - REQUIRE(nkeys != NULL); - REQUIRE(keys != NULL); - - *nkeys = 0; - memset(keys, 0, sizeof(*keys) * maxkeys); - dns_rdataset_init(&rdataset); - RETERR(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, - &rdataset, NULL)); - RETERR(dns_rdataset_first(&rdataset)); - while (result == ISC_R_SUCCESS && count < maxkeys) { - pubkey = NULL; - dns_rdataset_current(&rdataset, &rdata); - RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); - dst_key_setttl(pubkey, rdataset.ttl); - - if (!is_zone_key(pubkey) || - (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) - goto next; - /* Corrupted .key file? */ - if (!dns_name_equal(name, dst_key_name(pubkey))) - goto next; - keys[count] = NULL; - result = dst_key_fromfile(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - directory, - mctx, &keys[count]); - - /* - * If the key was revoked and the private file - * doesn't exist, maybe it was revoked internally - * by named. Try loading the unrevoked version. - */ - if (result == ISC_R_FILENOTFOUND) { - uint32_t flags; - flags = dst_key_flags(pubkey); - if ((flags & DNS_KEYFLAG_REVOKE) != 0) { - dst_key_setflags(pubkey, - flags & ~DNS_KEYFLAG_REVOKE); - result = dst_key_fromfile(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - DST_TYPE_PUBLIC| - DST_TYPE_PRIVATE, - directory, - mctx, &keys[count]); - if (result == ISC_R_SUCCESS && - dst_key_pubcompare(pubkey, keys[count], - false)) { - dst_key_setflags(keys[count], flags); - } - dst_key_setflags(pubkey, flags); - } - } - - if (result != ISC_R_SUCCESS) { - char filename[DNS_NAME_FORMATSIZE + - DNS_SECALG_FORMATSIZE + - sizeof("key file for //65535")]; - isc_result_t result2; - isc_buffer_t buf; - - isc_buffer_init(&buf, filename, NAME_MAX); - result2 = dst_key_getfilename(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - (DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE), - directory, mctx, - &buf); - if (result2 != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - char algbuf[DNS_SECALG_FORMATSIZE]; - - dns_name_format(dst_key_name(pubkey), - namebuf, sizeof(namebuf)); - dns_secalg_format(dst_key_alg(pubkey), - algbuf, sizeof(algbuf)); - snprintf(filename, sizeof(filename) - 1, - "key file for %s/%s/%d", - namebuf, algbuf, dst_key_id(pubkey)); - } - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, - "dns_dnssec_findzonekeys2: error " - "reading %s: %s", - filename, isc_result_totext(result)); - } - - if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { - keys[count] = pubkey; - pubkey = NULL; - count++; - goto next; - } - - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * If a key is marked inactive, skip it - */ - if (!dns_dnssec_keyactive(keys[count], now)) { - dst_key_setinactive(pubkey, true); - dst_key_free(&keys[count]); - keys[count] = pubkey; - pubkey = NULL; - count++; - goto next; - } - - /* - * Whatever the key's default TTL may have - * been, the rdataset TTL takes priority. - */ - dst_key_setttl(keys[count], rdataset.ttl); - - if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) { - /* We should never get here. */ - dst_key_free(&keys[count]); - goto next; - } - count++; - next: - if (pubkey != NULL) - dst_key_free(&pubkey); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rdataset); - } - if (result != ISC_R_NOMORE) - goto failure; - if (count == 0) - result = ISC_R_NOTFOUND; - else - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (pubkey != NULL) - dst_key_free(&pubkey); - if (result != ISC_R_SUCCESS) - while (count > 0) - dst_key_free(&keys[--count]); - *nkeys = count; - return (result); -} - -isc_result_t -dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys) -{ - isc_stdtime_t now; - - isc_stdtime_get(&now); - return (dns_dnssec_findzonekeys3(db, ver, node, name, directory, now, - mctx, maxkeys, keys, nkeys)); -} - -isc_result_t -dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys) -{ - isc_stdtime_t now; - - isc_stdtime_get(&now); - return (dns_dnssec_findzonekeys3(db, ver, node, name, NULL, now, - mctx, maxkeys, keys, nkeys)); -} - -isc_result_t -dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) { - dns_rdata_sig_t sig; /* SIG(0) */ - unsigned char data[512]; - unsigned char header[DNS_MESSAGE_HEADERLEN]; - isc_buffer_t headerbuf, databuf, sigbuf; - unsigned int sigsize; - isc_buffer_t *dynbuf = NULL; - dns_rdata_t *rdata; - dns_rdatalist_t *datalist; - dns_rdataset_t *dataset; - isc_region_t r; - isc_stdtime_t now; - dst_context_t *ctx = NULL; - isc_mem_t *mctx; - isc_result_t result; - bool signeedsfree = true; - - REQUIRE(msg != NULL); - REQUIRE(key != NULL); - - if (is_response(msg)) - REQUIRE(msg->query.base != NULL); - - mctx = msg->mctx; - - memset(&sig, 0, sizeof(sig)); - - sig.mctx = mctx; - sig.common.rdclass = dns_rdataclass_any; - sig.common.rdtype = dns_rdatatype_sig; /* SIG(0) */ - ISC_LINK_INIT(&sig.common, link); - - sig.covered = 0; - sig.algorithm = dst_key_alg(key); - sig.labels = 0; /* the root name */ - sig.originalttl = 0; - - isc_stdtime_get(&now); - sig.timesigned = now - DNS_TSIG_FUDGE; - sig.timeexpire = now + DNS_TSIG_FUDGE; - - sig.keyid = dst_key_id(key); - - dns_name_init(&sig.signer, NULL); - dns_name_clone(dst_key_name(key), &sig.signer); - - sig.siglen = 0; - sig.signature = NULL; - - isc_buffer_init(&databuf, data, sizeof(data)); - - RETERR(dst_context_create3(key, mctx, - DNS_LOGCATEGORY_DNSSEC, true, &ctx)); - - /* - * Digest the fields of the SIG - we can cheat and use - * dns_rdata_fromstruct. Since siglen is 0, the digested data - * is identical to dns format. - */ - RETERR(dns_rdata_fromstruct(NULL, dns_rdataclass_any, - dns_rdatatype_sig /* SIG(0) */, - &sig, &databuf)); - isc_buffer_usedregion(&databuf, &r); - RETERR(dst_context_adddata(ctx, &r)); - - /* - * If this is a response, digest the query. - */ - if (is_response(msg)) - RETERR(dst_context_adddata(ctx, &msg->query)); - - /* - * Digest the header. - */ - isc_buffer_init(&headerbuf, header, sizeof(header)); - dns_message_renderheader(msg, &headerbuf); - isc_buffer_usedregion(&headerbuf, &r); - RETERR(dst_context_adddata(ctx, &r)); - - /* - * Digest the remainder of the message. - */ - isc_buffer_usedregion(msg->buffer, &r); - isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); - RETERR(dst_context_adddata(ctx, &r)); - - RETERR(dst_key_sigsize(key, &sigsize)); - sig.siglen = sigsize; - sig.signature = (unsigned char *) isc_mem_get(mctx, sig.siglen); - if (sig.signature == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - - isc_buffer_init(&sigbuf, sig.signature, sig.siglen); - RETERR(dst_context_sign(ctx, &sigbuf)); - dst_context_destroy(&ctx); - - rdata = NULL; - RETERR(dns_message_gettemprdata(msg, &rdata)); - RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024)); - RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any, - dns_rdatatype_sig /* SIG(0) */, - &sig, dynbuf)); - - isc_mem_put(mctx, sig.signature, sig.siglen); - signeedsfree = false; - - dns_message_takebuffer(msg, &dynbuf); - - datalist = NULL; - RETERR(dns_message_gettemprdatalist(msg, &datalist)); - datalist->rdclass = dns_rdataclass_any; - datalist->type = dns_rdatatype_sig; /* SIG(0) */ - ISC_LIST_APPEND(datalist->rdata, rdata, link); - dataset = NULL; - RETERR(dns_message_gettemprdataset(msg, &dataset)); - RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); - msg->sig0 = dataset; - - return (ISC_R_SUCCESS); - -failure: - if (dynbuf != NULL) - isc_buffer_free(&dynbuf); - if (signeedsfree) - isc_mem_put(mctx, sig.signature, sig.siglen); - if (ctx != NULL) - dst_context_destroy(&ctx); - - return (result); -} - -isc_result_t -dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, - dst_key_t *key) -{ - dns_rdata_sig_t sig; /* SIG(0) */ - unsigned char header[DNS_MESSAGE_HEADERLEN]; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_region_t r, source_r, sig_r, header_r; - isc_stdtime_t now; - dst_context_t *ctx = NULL; - isc_mem_t *mctx; - isc_result_t result; - uint16_t addcount, addcount_n; - bool signeedsfree = false; - - REQUIRE(source != NULL); - REQUIRE(msg != NULL); - REQUIRE(key != NULL); - - mctx = msg->mctx; - - msg->verify_attempted = 1; - msg->verified_sig = 0; - msg->sig0status = dns_tsigerror_badsig; - - if (is_response(msg)) { - if (msg->query.base == NULL) - return (DNS_R_UNEXPECTEDTSIG); - } - - isc_buffer_usedregion(source, &source_r); - - RETERR(dns_rdataset_first(msg->sig0)); - dns_rdataset_current(msg->sig0, &rdata); - - RETERR(dns_rdata_tostruct(&rdata, &sig, NULL)); - signeedsfree = true; - - if (sig.labels != 0) { - result = DNS_R_SIGINVALID; - goto failure; - } - - if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { - result = DNS_R_SIGINVALID; - msg->sig0status = dns_tsigerror_badtime; - goto failure; - } - - isc_stdtime_get(&now); - if (isc_serial_lt((uint32_t)now, sig.timesigned)) { - result = DNS_R_SIGFUTURE; - msg->sig0status = dns_tsigerror_badtime; - goto failure; - } - else if (isc_serial_lt(sig.timeexpire, (uint32_t)now)) { - result = DNS_R_SIGEXPIRED; - msg->sig0status = dns_tsigerror_badtime; - goto failure; - } - - if (!dns_name_equal(dst_key_name(key), &sig.signer)) { - result = DNS_R_SIGINVALID; - msg->sig0status = dns_tsigerror_badkey; - goto failure; - } - - RETERR(dst_context_create3(key, mctx, - DNS_LOGCATEGORY_DNSSEC, false, &ctx)); - - /* - * Digest the SIG(0) record, except for the signature. - */ - dns_rdata_toregion(&rdata, &r); - r.length -= sig.siglen; - RETERR(dst_context_adddata(ctx, &r)); - - /* - * If this is a response, digest the query. - */ - if (is_response(msg)) - RETERR(dst_context_adddata(ctx, &msg->query)); - - /* - * Extract the header. - */ - memmove(header, source_r.base, DNS_MESSAGE_HEADERLEN); - - /* - * Decrement the additional field counter. - */ - memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); - addcount_n = ntohs(addcount); - addcount = htons((uint16_t)(addcount_n - 1)); - memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); - - /* - * Digest the modified header. - */ - header_r.base = (unsigned char *) header; - header_r.length = DNS_MESSAGE_HEADERLEN; - RETERR(dst_context_adddata(ctx, &header_r)); - - /* - * Digest all non-SIG(0) records. - */ - r.base = source_r.base + DNS_MESSAGE_HEADERLEN; - r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; - RETERR(dst_context_adddata(ctx, &r)); - - sig_r.base = sig.signature; - sig_r.length = sig.siglen; - result = dst_context_verify(ctx, &sig_r); - if (result != ISC_R_SUCCESS) { - msg->sig0status = dns_tsigerror_badsig; - goto failure; - } - - msg->verified_sig = 1; - msg->sig0status = dns_rcode_noerror; - - dst_context_destroy(&ctx); - dns_rdata_freestruct(&sig); - - return (ISC_R_SUCCESS); - -failure: - if (signeedsfree) - dns_rdata_freestruct(&sig); - if (ctx != NULL) - dst_context_destroy(&ctx); - - return (result); -} - -/*% - * Does this key ('rdata') self sign the rrset ('rdataset')? - */ -bool -dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - bool ignoretime, isc_mem_t *mctx) -{ - INSIST(rdataset->type == dns_rdatatype_key || - rdataset->type == dns_rdatatype_dnskey); - if (rdataset->type == dns_rdatatype_key) { - INSIST(sigrdataset->type == dns_rdatatype_sig); - INSIST(sigrdataset->covers == dns_rdatatype_key); - } else { - INSIST(sigrdataset->type == dns_rdatatype_rrsig); - INSIST(sigrdataset->covers == dns_rdatatype_dnskey); - } - - return (dns_dnssec_signs(rdata, name, rdataset, sigrdataset, - ignoretime, mctx)); - -} - -bool -dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - bool ignoretime, isc_mem_t *mctx) -{ - dst_key_t *dstkey = NULL; - dns_keytag_t keytag; - dns_rdata_dnskey_t key; - dns_rdata_rrsig_t sig; - dns_rdata_t sigrdata = DNS_RDATA_INIT; - isc_result_t result; - - INSIST(sigrdataset->type == dns_rdatatype_rrsig); - if (sigrdataset->covers != rdataset->type) - return (false); - - result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey); - if (result != ISC_R_SUCCESS) - return (false); - result = dns_rdata_tostruct(rdata, &key, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - keytag = dst_key_id(dstkey); - for (result = dns_rdataset_first(sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(sigrdataset)) - { - dns_rdata_reset(&sigrdata); - dns_rdataset_current(sigrdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &sig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (sig.algorithm == key.algorithm && - sig.keyid == keytag) { - result = dns_dnssec_verify2(name, rdataset, dstkey, - ignoretime, mctx, - &sigrdata, NULL); - if (result == ISC_R_SUCCESS) { - dst_key_free(&dstkey); - return (true); - } - } - } - dst_key_free(&dstkey); - return (false); -} - -isc_result_t -dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey, - dns_dnsseckey_t **dkp) -{ - isc_result_t result; - dns_dnsseckey_t *dk; - int major, minor; - - REQUIRE(dkp != NULL && *dkp == NULL); - dk = isc_mem_get(mctx, sizeof(dns_dnsseckey_t)); - if (dk == NULL) - return (ISC_R_NOMEMORY); - - dk->key = *dstkey; - *dstkey = NULL; - dk->force_publish = false; - dk->force_sign = false; - dk->hint_publish = false; - dk->hint_sign = false; - dk->hint_remove = false; - dk->first_sign = false; - dk->is_active = false; - dk->prepublish = 0; - dk->source = dns_keysource_unknown; - dk->index = 0; - - /* KSK or ZSK? */ - dk->ksk = ((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0); - - /* Is this an old-style key? */ - result = dst_key_getprivateformat(dk->key, &major, &minor); - INSIST(result == ISC_R_SUCCESS); - - /* Smart signing started with key format 1.3 */ - dk->legacy = (major == 1 && minor <= 2); - - ISC_LINK_INIT(dk, link); - *dkp = dk; - return (ISC_R_SUCCESS); -} - -void -dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) { - dns_dnsseckey_t *dk; - - REQUIRE(dkp != NULL && *dkp != NULL); - dk = *dkp; - if (dk->key != NULL) - dst_key_free(&dk->key); - isc_mem_put(mctx, dk, sizeof(dns_dnsseckey_t)); - *dkp = NULL; -} - -static void -get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) { - isc_result_t result; - isc_stdtime_t publish, active, revoke, inactive, deltime; - bool pubset = false, actset = false; - bool revset = false, inactset = false; - bool delset = false; - - REQUIRE(key != NULL && key->key != NULL); - - result = dst_key_gettime(key->key, DST_TIME_PUBLISH, &publish); - if (result == ISC_R_SUCCESS) - pubset = true; - - result = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active); - if (result == ISC_R_SUCCESS) - actset = true; - - result = dst_key_gettime(key->key, DST_TIME_REVOKE, &revoke); - if (result == ISC_R_SUCCESS) - revset = true; - - result = dst_key_gettime(key->key, DST_TIME_INACTIVE, &inactive); - if (result == ISC_R_SUCCESS) - inactset = true; - - result = dst_key_gettime(key->key, DST_TIME_DELETE, &deltime); - if (result == ISC_R_SUCCESS) - delset = true; - - /* Metadata says publish (but possibly not activate) */ - if (pubset && publish <= now) - key->hint_publish = true; - - /* Metadata says activate (so we must also publish) */ - if (actset && active <= now) { - key->hint_sign = true; - - /* Only publish if publish time has already passed. */ - if (pubset && publish <= now) - key->hint_publish = true; - } - - /* - * Activation date is set (maybe in the future), but - * publication date isn't. Most likely the user wants to - * publish now and activate later. - */ - if (actset && !pubset) - key->hint_publish = true; - - /* - * If activation date is in the future, make note of how far off - */ - if (key->hint_publish && actset && active > now) { - key->prepublish = active - now; - } - - /* - * Key has been marked inactive: we can continue publishing, - * but don't sign. - */ - if (key->hint_publish && inactset && inactive <= now) { - key->hint_sign = false; - } - - /* - * Metadata says revoke. If the key is published, - * we *have to* sign with it per RFC5011--even if it was - * not active before. - * - * If it hasn't already been done, we should also revoke it now. - */ - if (key->hint_publish && (revset && revoke <= now)) { - uint32_t flags; - key->hint_sign = true; - flags = dst_key_flags(key->key); - if ((flags & DNS_KEYFLAG_REVOKE) == 0) { - flags |= DNS_KEYFLAG_REVOKE; - dst_key_setflags(key->key, flags); - } - } - - /* - * Metadata says delete, so don't publish this key or sign with it. - */ - if (delset && deltime <= now) { - key->hint_publish = false; - key->hint_sign = false; - key->hint_remove = true; - } -} - -/*% - * Get a list of DNSSEC keys from the key repository - */ -isc_result_t -dns_dnssec_findmatchingkeys2(dns_name_t *origin, const char *directory, - isc_stdtime_t now, isc_mem_t *mctx, - dns_dnsseckeylist_t *keylist) -{ - isc_result_t result = ISC_R_SUCCESS; - bool dir_open = false; - dns_dnsseckeylist_t list; - isc_dir_t dir; - dns_dnsseckey_t *key = NULL; - dst_key_t *dstkey = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - isc_buffer_t b; - unsigned int len, i, alg; - - REQUIRE(keylist != NULL); - ISC_LIST_INIT(list); - isc_dir_init(&dir); - - isc_buffer_init(&b, namebuf, sizeof(namebuf) - 1); - RETERR(dns_name_tofilenametext(origin, false, &b)); - len = isc_buffer_usedlength(&b); - namebuf[len] = '\0'; - - if (directory == NULL) - directory = "."; - RETERR(isc_dir_open(&dir, directory)); - dir_open = true; - - while (isc_dir_read(&dir) == ISC_R_SUCCESS) { - if (dir.entry.name[0] != 'K' || - dir.entry.length < len + 1 || - dir.entry.name[len + 1] != '+' || - strncasecmp(dir.entry.name + 1, namebuf, len) != 0) - continue; - - alg = 0; - for (i = len + 1 + 1; i < dir.entry.length ; i++) { - if (dir.entry.name[i] < '0' || dir.entry.name[i] > '9') - break; - alg *= 10; - alg += dir.entry.name[i] - '0'; - } - - /* - * Did we not read exactly 3 digits? - * Did we overflow? - * Did we correctly terminate? - */ - if (i != len + 1 + 1 + 3 || i >= dir.entry.length || - dir.entry.name[i] != '+') - continue; - - for (i++ ; i < dir.entry.length ; i++) - if (dir.entry.name[i] < '0' || dir.entry.name[i] > '9') - break; - - /* - * Did we not read exactly 5 more digits? - * Did we overflow? - * Did we correctly terminate? - */ - if (i != len + 1 + 1 + 3 + 1 + 5 || i >= dir.entry.length || - strcmp(dir.entry.name + i, ".private") != 0) - continue; - - dstkey = NULL; - result = dst_key_fromnamedfile(dir.entry.name, - directory, - DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE, - mctx, &dstkey); - - switch (alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_HMACMD5: -#endif - case DST_ALG_HMACSHA1: - case DST_ALG_HMACSHA224: - case DST_ALG_HMACSHA256: - case DST_ALG_HMACSHA384: - case DST_ALG_HMACSHA512: - if (result == DST_R_BADKEYTYPE) - continue; - } - - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_DNSSEC, - ISC_LOG_WARNING, - "dns_dnssec_findmatchingkeys: " - "error reading key file %s: %s", - dir.entry.name, - isc_result_totext(result)); - continue; - } - - RETERR(dns_dnsseckey_create(mctx, &dstkey, &key)); - key->source = dns_keysource_repository; - get_hints(key, now); - - if (key->legacy) { - dns_dnsseckey_destroy(mctx, &key); - } else { - ISC_LIST_APPEND(list, key, link); - key = NULL; - } - } - - if (!ISC_LIST_EMPTY(list)) { - result = ISC_R_SUCCESS; - ISC_LIST_APPENDLIST(*keylist, list, link); - } else - result = ISC_R_NOTFOUND; - - failure: - if (dir_open) - isc_dir_close(&dir); - INSIST(key == NULL); - while ((key = ISC_LIST_HEAD(list)) != NULL) { - ISC_LIST_UNLINK(list, key, link); - INSIST(key->key != NULL); - dst_key_free(&key->key); - dns_dnsseckey_destroy(mctx, &key); - } - if (dstkey != NULL) - dst_key_free(&dstkey); - return (result); -} - -isc_result_t -dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, - isc_mem_t *mctx, dns_dnsseckeylist_t *keylist) -{ - isc_stdtime_t now; - - isc_stdtime_get(&now); - return (dns_dnssec_findmatchingkeys2(origin, directory, now, mctx, - keylist)); -} - -/*% - * Add 'newkey' to 'keylist' if it's not already there. - * - * If 'savekeys' is true, then we need to preserve all - * the keys in the keyset, regardless of whether they have - * metadata indicating they should be deactivated or removed. - */ -static isc_result_t -addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey, - bool savekeys, isc_mem_t *mctx) -{ - dns_dnsseckey_t *key; - isc_result_t result; - - /* Skip duplicates */ - for (key = ISC_LIST_HEAD(*keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - if (dst_key_id(key->key) == dst_key_id(*newkey) && - dst_key_alg(key->key) == dst_key_alg(*newkey) && - dns_name_equal(dst_key_name(key->key), - dst_key_name(*newkey))) - break; - } - - if (key != NULL) { - /* - * Found a match. If the old key was only public and the - * new key is private, replace the old one; otherwise - * leave it. But either way, mark the key as having - * been found in the zone. - */ - if (dst_key_isprivate(key->key)) { - dst_key_free(newkey); - } else if (dst_key_isprivate(*newkey)) { - dst_key_free(&key->key); - key->key = *newkey; - } - - key->source = dns_keysource_zoneapex; - return (ISC_R_SUCCESS); - } - - result = dns_dnsseckey_create(mctx, newkey, &key); - if (result != ISC_R_SUCCESS) - return (result); - if (key->legacy || savekeys) { - key->force_publish = true; - key->force_sign = dst_key_isprivate(key->key); - } - key->source = dns_keysource_zoneapex; - ISC_LIST_APPEND(*keylist, key, link); - *newkey = NULL; - return (ISC_R_SUCCESS); -} - - -/*% - * Mark all keys which signed the DNSKEY/SOA RRsets as "active", - * for future reference. - */ -static isc_result_t -mark_active_keys(dns_dnsseckeylist_t *keylist, dns_rdataset_t *rrsigs) { - isc_result_t result = ISC_R_SUCCESS; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t sigs; - dns_dnsseckey_t *key; - - REQUIRE(rrsigs != NULL && dns_rdataset_isassociated(rrsigs)); - - dns_rdataset_init(&sigs); - dns_rdataset_clone(rrsigs, &sigs); - for (key = ISC_LIST_HEAD(*keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - uint16_t keyid, sigid; - dns_secalg_t keyalg, sigalg; - keyid = dst_key_id(key->key); - keyalg = dst_key_alg(key->key); - - for (result = dns_rdataset_first(&sigs); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&sigs)) { - dns_rdata_rrsig_t sig; - - dns_rdata_reset(&rdata); - dns_rdataset_current(&sigs, &rdata); - result = dns_rdata_tostruct(&rdata, &sig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - sigalg = sig.algorithm; - sigid = sig.keyid; - if (keyid == sigid && keyalg == sigalg) { - key->is_active = true; - break; - } - } - } - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - if (dns_rdataset_isassociated(&sigs)) - dns_rdataset_disassociate(&sigs); - return (result); -} - -/*% - * Add the contents of a DNSKEY rdataset 'keyset' to 'keylist'. - */ -isc_result_t -dns_dnssec_keylistfromrdataset(dns_name_t *origin, - const char *directory, isc_mem_t *mctx, - dns_rdataset_t *keyset, dns_rdataset_t *keysigs, - dns_rdataset_t *soasigs, bool savekeys, - bool publickey, - dns_dnsseckeylist_t *keylist) -{ - dns_rdataset_t keys; - dns_rdata_t rdata = DNS_RDATA_INIT; - dst_key_t *pubkey = NULL, *privkey = NULL; - isc_result_t result; - - REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset)); - - dns_rdataset_init(&keys); - - dns_rdataset_clone(keyset, &keys); - for (result = dns_rdataset_first(&keys); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keys)) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&keys, &rdata); - - REQUIRE(rdata.type == dns_rdatatype_key || - rdata.type == dns_rdatatype_dnskey); - REQUIRE(rdata.length > 3); - - /* Skip unsupported algorithms */ - if (!dst_algorithm_supported(rdata.data[3])) - goto skip; - - RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey)); - dst_key_setttl(pubkey, keys.ttl); - - if (!is_zone_key(pubkey) || - (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) - goto skip; - - /* Corrupted .key file? */ - if (!dns_name_equal(origin, dst_key_name(pubkey))) - goto skip; - - if (publickey) { - RETERR(addkey(keylist, &pubkey, savekeys, mctx)); - goto skip; - } - - result = dst_key_fromfile(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, - directory, mctx, &privkey); - - /* - * If the key was revoked and the private file - * doesn't exist, maybe it was revoked internally - * by named. Try loading the unrevoked version. - */ - if (result == ISC_R_FILENOTFOUND) { - uint32_t flags; - flags = dst_key_flags(pubkey); - if ((flags & DNS_KEYFLAG_REVOKE) != 0) { - dst_key_setflags(pubkey, - flags & ~DNS_KEYFLAG_REVOKE); - result = dst_key_fromfile(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - DST_TYPE_PUBLIC| - DST_TYPE_PRIVATE, - directory, - mctx, &privkey); - if (result == ISC_R_SUCCESS && - dst_key_pubcompare(pubkey, privkey, - false)) { - dst_key_setflags(privkey, flags); - } - dst_key_setflags(pubkey, flags); - } - } - - if (result != ISC_R_SUCCESS) { - char filename[DNS_NAME_FORMATSIZE + - DNS_SECALG_FORMATSIZE + - sizeof("key file for //65535")]; - isc_result_t result2; - isc_buffer_t buf; - - isc_buffer_init(&buf, filename, NAME_MAX); - result2 = dst_key_getfilename(dst_key_name(pubkey), - dst_key_id(pubkey), - dst_key_alg(pubkey), - (DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE), - directory, mctx, - &buf); - if (result2 != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - char algbuf[DNS_SECALG_FORMATSIZE]; - - dns_name_format(dst_key_name(pubkey), - namebuf, sizeof(namebuf)); - dns_secalg_format(dst_key_alg(pubkey), - algbuf, sizeof(algbuf)); - snprintf(filename, sizeof(filename) - 1, - "key file for %s/%s/%d", - namebuf, algbuf, dst_key_id(pubkey)); - } - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, - "dns_dnssec_keylistfromrdataset: error " - "reading %s: %s", - filename, isc_result_totext(result)); - } - - if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { - RETERR(addkey(keylist, &pubkey, savekeys, mctx)); - goto skip; - } - RETERR(result); - - /* This should never happen. */ - if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0) - goto skip; - - /* - * Whatever the key's default TTL may have - * been, the rdataset TTL takes priority. - */ - dst_key_setttl(privkey, dst_key_getttl(pubkey)); - - RETERR(addkey(keylist, &privkey, savekeys, mctx)); - skip: - if (pubkey != NULL) - dst_key_free(&pubkey); - if (privkey != NULL) - dst_key_free(&privkey); - } - - if (result != ISC_R_NOMORE) - RETERR(result); - - if (keysigs != NULL && dns_rdataset_isassociated(keysigs)) - RETERR(mark_active_keys(keylist, keysigs)); - - if (soasigs != NULL && dns_rdataset_isassociated(soasigs)) - RETERR(mark_active_keys(keylist, soasigs)); - - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&keys)) - dns_rdataset_disassociate(&keys); - if (pubkey != NULL) - dst_key_free(&pubkey); - if (privkey != NULL) - dst_key_free(&privkey); - return (result); -} - -static isc_result_t -make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, - dns_rdata_t *target) -{ - isc_result_t result; - isc_buffer_t b; - isc_region_t r; - - isc_buffer_init(&b, buf, bufsize); - result = dst_key_todns(key, &b); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdata_reset(target); - isc_buffer_usedregion(&b, &r); - dns_rdata_fromregion(target, dst_key_class(key), - dns_rdatatype_dnskey, &r); - return (ISC_R_SUCCESS); -} - -static isc_result_t -addrdata(dns_rdata_t *rdata, dns_diff_t *diff, dns_name_t *origin, - dns_ttl_t ttl, isc_mem_t *mctx) -{ - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_ADD, origin, ttl, - rdata, &tuple)); - dns_diff_appendminimal(diff, &tuple); - - failure: - return (result); -} - -static isc_result_t -delrdata(dns_rdata_t *rdata, dns_diff_t *diff, dns_name_t *origin, - dns_ttl_t ttl, isc_mem_t *mctx) -{ - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_DEL, origin, ttl, - rdata, &tuple)); - dns_diff_appendminimal(diff, &tuple); - - failure: - return (result); -} - -static isc_result_t -publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin, - dns_ttl_t ttl, isc_mem_t *mctx, bool allzsk, - void (*report)(const char *, ...)) -{ - isc_result_t result; - unsigned char buf[DST_KEY_MAXSIZE]; - dns_rdata_t dnskey = DNS_RDATA_INIT; - char alg[80]; - - dns_rdata_reset(&dnskey); - RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey)); - - dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg)); - report("Fetching %s %d/%s from key %s.", - key->ksk ? (allzsk ? "KSK/ZSK" : "KSK") : "ZSK", - dst_key_id(key->key), alg, - key->source == dns_keysource_user ? "file" : "repository"); - - if (key->prepublish && ttl > key->prepublish) { - char keystr[DST_KEY_FORMATSIZE]; - isc_stdtime_t now; - - dst_key_format(key->key, keystr, sizeof(keystr)); - report("Key %s: Delaying activation to match the DNSKEY TTL.", - keystr, ttl); - - isc_stdtime_get(&now); - dst_key_settime(key->key, DST_TIME_ACTIVATE, now + ttl); - } - - /* publish key */ - result = addrdata(&dnskey, diff, origin, ttl, mctx); - - failure: - return (result); -} - -static isc_result_t -remove_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin, - dns_ttl_t ttl, isc_mem_t *mctx, const char *reason, - void (*report)(const char *, ...)) -{ - isc_result_t result; - unsigned char buf[DST_KEY_MAXSIZE]; - dns_rdata_t dnskey = DNS_RDATA_INIT; - char alg[80]; - - dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg)); - report("Removing %s key %d/%s from DNSKEY RRset.", - reason, dst_key_id(key->key), alg); - - RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey)); - result = delrdata(&dnskey, diff, origin, ttl, mctx); - - failure: - return (result); -} - -static bool -exists(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - isc_result_t result; - dns_rdataset_t trdataset; - - dns_rdataset_init(&trdataset); - dns_rdataset_clone(rdataset, &trdataset); - for (result = dns_rdataset_first(&trdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&trdataset)) { - dns_rdata_t current = DNS_RDATA_INIT; - - dns_rdataset_current(&trdataset, ¤t); - if (dns_rdata_compare(rdata, ¤t) == 0) { - dns_rdataset_disassociate(&trdataset); - return (true); - } - } - dns_rdataset_disassociate(&trdataset); - return (false); -} - -isc_result_t -dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, - dns_rdataset_t *cds, dns_rdataset_t *cdnskey, - isc_stdtime_t now, dns_ttl_t ttl, dns_diff_t *diff, - isc_mem_t *mctx) -{ - unsigned char dsbuf1[DNS_DS_BUFFERSIZE]; - unsigned char dsbuf2[DNS_DS_BUFFERSIZE]; - unsigned char keybuf[DST_KEY_MAXSIZE]; - isc_result_t result; - dns_dnsseckey_t *key; - - for (key = ISC_LIST_HEAD(*keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - dns_rdata_t cdsrdata1 = DNS_RDATA_INIT; - dns_rdata_t cdsrdata2 = DNS_RDATA_INIT; - dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; - dns_name_t *origin = dst_key_name(key->key); - - RETERR(make_dnskey(key->key, keybuf, sizeof(keybuf), - &cdnskeyrdata)); - - /* - * XXXMPA we need to be able to specify the DS algorithms - * to be used here and below with rmkeys. - */ - RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, - DNS_DSDIGEST_SHA1, dsbuf1, - &cdsrdata1)); - RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, - DNS_DSDIGEST_SHA256, dsbuf2, - &cdsrdata2)); - - /* - * Now that the we have created the DS records convert - * the rdata to CDNSKEY and CDS for comparison. - */ - cdnskeyrdata.type = dns_rdatatype_cdnskey; - cdsrdata1.type = dns_rdatatype_cds; - cdsrdata2.type = dns_rdatatype_cds; - - if (syncpublish(key->key, now)) { - if (!dns_rdataset_isassociated(cdnskey) || - !exists(cdnskey, &cdnskeyrdata)) - { - RETERR(addrdata(&cdnskeyrdata, diff, origin, - ttl, mctx)); - } - if (!dns_rdataset_isassociated(cds) || - !exists(cds, &cdsrdata1)) - { - RETERR(addrdata(&cdsrdata1, diff, origin, - ttl, mctx)); - } - if (!dns_rdataset_isassociated(cds) || - !exists(cds, &cdsrdata2)) - { - RETERR(addrdata(&cdsrdata2, diff, origin, - ttl, mctx)); - } - } - - if (dns_rdataset_isassociated(cds) && - syncdelete(key->key, now)) { - if (exists(cds, &cdsrdata1)) - RETERR(delrdata(&cdsrdata1, diff, origin, - cds->ttl, mctx)); - if (exists(cds, &cdsrdata2)) - RETERR(delrdata(&cdsrdata2, diff, origin, - cds->ttl, mctx)); - } - - if (dns_rdataset_isassociated(cdnskey) && - syncdelete(key->key, now)) { - if (exists(cdnskey, &cdnskeyrdata)) - RETERR(delrdata(&cdnskeyrdata, diff, origin, - cdnskey->ttl, mctx)); - } - } - - if (!dns_rdataset_isassociated(cds) && - !dns_rdataset_isassociated(cdnskey)) - return (ISC_R_SUCCESS); - - /* - * Unconditionally remove CDS/DNSKEY records for removed keys. - */ - for (key = ISC_LIST_HEAD(*rmkeys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - dns_rdata_t cdsrdata1 = DNS_RDATA_INIT; - dns_rdata_t cdsrdata2 = DNS_RDATA_INIT; - dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; - dns_name_t *origin = dst_key_name(key->key); - - RETERR(make_dnskey(key->key, keybuf, sizeof(keybuf), - &cdnskeyrdata)); - - if (dns_rdataset_isassociated(cds)) { - RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, - DNS_DSDIGEST_SHA1, dsbuf1, - &cdsrdata1)); - RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, - DNS_DSDIGEST_SHA256, dsbuf2, - &cdsrdata2)); - if (exists(cds, &cdsrdata1)) - RETERR(delrdata(&cdsrdata1, diff, origin, - cds->ttl, mctx)); - if (exists(cds, &cdsrdata2)) - RETERR(delrdata(&cdsrdata2, diff, origin, - cds->ttl, mctx)); - } - - if (dns_rdataset_isassociated(cdnskey)) { - if (exists(cdnskey, &cdnskeyrdata)) - RETERR(delrdata(&cdnskeyrdata, diff, origin, - cdnskey->ttl, mctx)); - } - } - - result = ISC_R_SUCCESS; - - failure: - return (result); -} - -/* - * Update 'keys' with information from 'newkeys'. - * - * If 'removed' is not NULL, any keys that are being removed from - * the zone will be added to the list for post-removal processing. - */ -isc_result_t -dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, - dns_dnsseckeylist_t *removed, dns_name_t *origin, - dns_ttl_t hint_ttl, dns_diff_t *diff, - bool allzsk, isc_mem_t *mctx, - void (*report)(const char *, ...)) -{ - isc_result_t result; - dns_dnsseckey_t *key, *key1, *key2, *next; - bool found_ttl = false; - dns_ttl_t ttl = hint_ttl; - - /* - * First, look through the existing key list to find keys - * supplied from the command line which are not in the zone. - * Update the zone to include them. - * - * Also, if there are keys published in the zone already, - * use their TTL for all subsequent published keys. - */ - for (key = ISC_LIST_HEAD(*keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - if (key->source == dns_keysource_user && - (key->hint_publish || key->force_publish)) { - RETERR(publish_key(diff, key, origin, ttl, - mctx, allzsk, report)); - } - if (key->source == dns_keysource_zoneapex) { - ttl = dst_key_getttl(key->key); - found_ttl = true; - } - } - - /* - * If there were no existing keys, use the smallest nonzero - * TTL of the keys found in the repository. - */ - if (!found_ttl && !ISC_LIST_EMPTY(*newkeys)) { - dns_ttl_t shortest = 0; - - for (key = ISC_LIST_HEAD(*newkeys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) { - dns_ttl_t thisttl = dst_key_getttl(key->key); - if (thisttl != 0 && - (shortest == 0 || thisttl < shortest)) - shortest = thisttl; - } - - if (shortest != 0) - ttl = shortest; - } - - /* - * Second, scan the list of newly found keys looking for matches - * with known keys, and update accordingly. - */ - for (key1 = ISC_LIST_HEAD(*newkeys); key1 != NULL; key1 = next) { - bool key_revoked = false; - - next = ISC_LIST_NEXT(key1, link); - - for (key2 = ISC_LIST_HEAD(*keys); - key2 != NULL; - key2 = ISC_LIST_NEXT(key2, link)) { - int f1 = dst_key_flags(key1->key); - int f2 = dst_key_flags(key2->key); - int nr1 = f1 & ~DNS_KEYFLAG_REVOKE; - int nr2 = f2 & ~DNS_KEYFLAG_REVOKE; - if (nr1 == nr2 && - dst_key_alg(key1->key) == dst_key_alg(key2->key) && - dst_key_pubcompare(key1->key, key2->key, - true)) { - int r1, r2; - r1 = dst_key_flags(key1->key) & - DNS_KEYFLAG_REVOKE; - r2 = dst_key_flags(key2->key) & - DNS_KEYFLAG_REVOKE; - key_revoked = (r1 != r2); - break; - } - } - - /* No match found in keys; add the new key. */ - if (key2 == NULL) { - ISC_LIST_UNLINK(*newkeys, key1, link); - ISC_LIST_APPEND(*keys, key1, link); - - if (key1->source != dns_keysource_zoneapex && - (key1->hint_publish || key1->force_publish)) { - RETERR(publish_key(diff, key1, origin, ttl, - mctx, allzsk, report)); - if (key1->hint_sign || key1->force_sign) - key1->first_sign = true; - } - - continue; - } - - /* Match found: remove or update it as needed */ - if (key1->hint_remove) { - RETERR(remove_key(diff, key2, origin, ttl, mctx, - "expired", report)); - ISC_LIST_UNLINK(*keys, key2, link); - if (removed != NULL) - ISC_LIST_APPEND(*removed, key2, link); - else - dns_dnsseckey_destroy(mctx, &key2); - } else if (key_revoked && - (dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE) != 0) { - - /* - * A previously valid key has been revoked. - * We need to remove the old version and pull - * in the new one. - */ - RETERR(remove_key(diff, key2, origin, ttl, mctx, - "revoked", report)); - ISC_LIST_UNLINK(*keys, key2, link); - if (removed != NULL) - ISC_LIST_APPEND(*removed, key2, link); - else - dns_dnsseckey_destroy(mctx, &key2); - - RETERR(publish_key(diff, key1, origin, ttl, - mctx, allzsk, report)); - ISC_LIST_UNLINK(*newkeys, key1, link); - ISC_LIST_APPEND(*keys, key1, link); - - /* - * XXX: The revoke flag is only defined for trust - * anchors. Setting the flag on a non-KSK is legal, - * but not defined in any RFC. It seems reasonable - * to treat it the same as a KSK: keep it in the - * zone, sign the DNSKEY set with it, but not - * sign other records with it. - */ - key1->ksk = true; - continue; - } else { - if (!key2->is_active && - (key1->hint_sign || key1->force_sign)) - key2->first_sign = true; - key2->hint_sign = key1->hint_sign; - key2->hint_publish = key1->hint_publish; - } - } - - /* Free any leftover keys in newkeys */ - while (!ISC_LIST_EMPTY(*newkeys)) { - key1 = ISC_LIST_HEAD(*newkeys); - ISC_LIST_UNLINK(*newkeys, key1, link); - dns_dnsseckey_destroy(mctx, &key1); - } - - result = ISC_R_SUCCESS; - - failure: - return (result); -} diff --git a/lib/dns-pkcs11/dnstap.c b/lib/dns-pkcs11/dnstap.c deleted file mode 100644 index fad1e3b..0000000 --- a/lib/dns-pkcs11/dnstap.c +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (c) 2013-2014, Farsight Security, Inc. - * 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. - */ - -/*! \file */ - -#include - -#ifndef HAVE_DNSTAP -#error DNSTAP not configured. -#endif /* HAVE_DNSTAP */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "dnstap.pb-c.h" - -#define DTENV_MAGIC ISC_MAGIC('D', 't', 'n', 'v') -#define VALID_DTENV(env) ISC_MAGIC_VALID(env, DTENV_MAGIC) - -#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" -#define DNSTAP_INITIAL_BUF_SIZE 256 - -struct dns_dtmsg { - void *buf; - size_t len; - Dnstap__Dnstap d; - Dnstap__Message m; -}; - -struct dns_dthandle { - dns_dtmode_t mode; - struct fstrm_reader *reader; - isc_mem_t *mctx; -}; - -struct dns_dtenv { - unsigned int magic; - isc_refcount_t refcount; - - isc_mem_t *mctx; - - struct fstrm_iothr *iothr; - struct fstrm_iothr_options *fopt; - - isc_region_t identity; - isc_region_t version; - char *path; - dns_dtmode_t mode; - isc_stats_t *stats; -}; - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static isc_mutex_t dt_mutex; -static bool dt_initialized = false; -static isc_thread_key_t dt_key; -static isc_once_t mutex_once = ISC_ONCE_INIT; -static isc_mem_t *dt_mctx = NULL; - -/* - * Change under task exclusive. - */ -static unsigned int generation; - -static void -mutex_init(void) { - RUNTIME_CHECK(isc_mutex_init(&dt_mutex) == ISC_R_SUCCESS); -} - -static void -dtfree(void *arg) { - free(arg); - isc_thread_key_setspecific(dt_key, NULL); -} - -static isc_result_t -dt_init(void) { - isc_result_t result; - - result = isc_once_do(&mutex_once, mutex_init); - if (result != ISC_R_SUCCESS) - return (result); - - if (dt_initialized) - return (ISC_R_SUCCESS); - - LOCK(&dt_mutex); - if (!dt_initialized) { - int ret; - - if (dt_mctx == NULL) - result = isc_mem_create2(0, 0, &dt_mctx, 0); - if (result != ISC_R_SUCCESS) - goto unlock; - isc_mem_setname(dt_mctx, "dt", NULL); - isc_mem_setdestroycheck(dt_mctx, false); - - ret = isc_thread_key_create(&dt_key, dtfree); - if (ret == 0) - dt_initialized = true; - else - result = ISC_R_FAILURE; - } -unlock: - UNLOCK(&dt_mutex); - - return (result); -} - -isc_result_t -dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path, - struct fstrm_iothr_options **foptp, dns_dtenv_t **envp) -{ - isc_result_t result = ISC_R_SUCCESS; - fstrm_res res; - struct fstrm_unix_writer_options *fuwopt = NULL; - struct fstrm_file_options *ffwopt = NULL; - struct fstrm_writer_options *fwopt = NULL; - struct fstrm_writer *fw = NULL; - dns_dtenv_t *env = NULL; - - REQUIRE(path != NULL); - REQUIRE(envp != NULL && *envp == NULL); - REQUIRE(foptp!= NULL && *foptp != NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO, - "opening dnstap destination '%s'", path); - - generation++; - - env = isc_mem_get(mctx, sizeof(dns_dtenv_t)); - if (env == NULL) - CHECK(ISC_R_NOMEMORY); - - memset(env, 0, sizeof(dns_dtenv_t)); - - CHECK(isc_refcount_init(&env->refcount, 1)); - CHECK(isc_stats_create(mctx, &env->stats, dns_dnstapcounter_max)); - env->path = isc_mem_strdup(mctx, path); - if (env->path == NULL) - CHECK(ISC_R_NOMEMORY); - - fwopt = fstrm_writer_options_init(); - if (fwopt == NULL) - CHECK(ISC_R_NOMEMORY); - - res = fstrm_writer_options_add_content_type(fwopt, - DNSTAP_CONTENT_TYPE, - sizeof(DNSTAP_CONTENT_TYPE) - 1); - if (res != fstrm_res_success) - CHECK(ISC_R_FAILURE); - - if (mode == dns_dtmode_file) { - ffwopt = fstrm_file_options_init(); - if (ffwopt != NULL) { - fstrm_file_options_set_file_path(ffwopt, env->path); - fw = fstrm_file_writer_init(ffwopt, fwopt); - } - } else if (mode == dns_dtmode_unix) { - fuwopt = fstrm_unix_writer_options_init(); - if (fuwopt != NULL) { - fstrm_unix_writer_options_set_socket_path(fuwopt, - env->path); - fw = fstrm_unix_writer_init(fuwopt, fwopt); - } - } else - CHECK(ISC_R_FAILURE); - - if (fw == NULL) - CHECK(ISC_R_FAILURE); - - env->iothr = fstrm_iothr_init(*foptp, &fw); - if (env->iothr == NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_WARNING, - "unable to initialize dnstap I/O thread"); - fstrm_writer_destroy(&fw); - CHECK(ISC_R_FAILURE); - } - env->mode = mode; - env->fopt = *foptp; - *foptp = NULL; - - isc_mem_attach(mctx, &env->mctx); - - env->magic = DTENV_MAGIC; - *envp = env; - - cleanup: - if (ffwopt != NULL) - fstrm_file_options_destroy(&ffwopt); - - if (fuwopt != NULL) - fstrm_unix_writer_options_destroy(&fuwopt); - - if (fwopt != NULL) - fstrm_writer_options_destroy(&fwopt); - - if (result != ISC_R_SUCCESS) { - if (env != NULL) { - if (env->mctx != NULL) - isc_mem_detach(&env->mctx); - if (env->path != NULL) - isc_mem_free(mctx, env->path); - if (env->stats != NULL) - isc_stats_detach(&env->stats); - isc_mem_put(mctx, env, sizeof(dns_dtenv_t)); - } - } - - return (result); -} - -isc_result_t -dns_dt_reopen(dns_dtenv_t *env, int roll) { - isc_result_t result = ISC_R_SUCCESS; - fstrm_res res; - isc_logfile_t file; - struct fstrm_unix_writer_options *fuwopt = NULL; - struct fstrm_file_options *ffwopt = NULL; - struct fstrm_writer_options *fwopt = NULL; - struct fstrm_writer *fw = NULL; - - REQUIRE(VALID_DTENV(env)); - - /* - * Check that we can create a new fw object. - */ - fwopt = fstrm_writer_options_init(); - if (fwopt == NULL) - return (ISC_R_NOMEMORY); - - res = fstrm_writer_options_add_content_type(fwopt, - DNSTAP_CONTENT_TYPE, - sizeof(DNSTAP_CONTENT_TYPE) - 1); - if (res != fstrm_res_success) - CHECK(ISC_R_FAILURE); - - if (env->mode == dns_dtmode_file) { - ffwopt = fstrm_file_options_init(); - if (ffwopt != NULL) { - fstrm_file_options_set_file_path(ffwopt, env->path); - fw = fstrm_file_writer_init(ffwopt, fwopt); - } - } else if (env->mode == dns_dtmode_unix) { - fuwopt = fstrm_unix_writer_options_init(); - if (fuwopt != NULL) { - fstrm_unix_writer_options_set_socket_path(fuwopt, - env->path); - fw = fstrm_unix_writer_init(fuwopt, fwopt); - } - } else - CHECK(ISC_R_NOTIMPLEMENTED); - - if (fw == NULL) - CHECK(ISC_R_FAILURE); - - /* - * We are committed here. - */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO, - "%s dnstap destination '%s'", - (roll < 0) ? "reopening" : "rolling", - env->path); - - generation++; - - if (env->iothr != NULL) - fstrm_iothr_destroy(&env->iothr); - - if (env->mode == dns_dtmode_file && roll >= 0) { - /* - * Create a temporary isc_logfile_t structure so we can - * take advantage of the logfile rolling facility. - */ - char *filename = isc_mem_strdup(env->mctx, env->path); - file.name = filename; - file.stream = NULL; - file.versions = roll != 0 ? roll : ISC_LOG_ROLLINFINITE; - file.maximum_size = 0; - file.maximum_reached = false; - result = isc_logfile_roll(&file); - isc_mem_free(env->mctx, filename); - CHECK(result); - } - - env->iothr = fstrm_iothr_init(env->fopt, &fw); - if (env->iothr == NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_WARNING, - "unable to initialize dnstap I/O thread"); - CHECK(ISC_R_FAILURE); - } - - cleanup: - if (ffwopt != NULL) - fstrm_file_options_destroy(&ffwopt); - - if (fw != NULL) - fstrm_writer_destroy(&fw); - - if (fwopt != NULL) - fstrm_writer_options_destroy(&fwopt); - - if (fuwopt != NULL) - fstrm_unix_writer_options_destroy(&fuwopt); - - return (result); -} - -static isc_result_t -toregion(dns_dtenv_t *env, isc_region_t *r, const char *str) { - unsigned char *p = NULL; - - REQUIRE(r != NULL); - - if (str != NULL) { - p = (unsigned char *) isc_mem_strdup(env->mctx, str); - if (p == NULL) - return (ISC_R_NOMEMORY); - } - - if (r->base != NULL) { - isc_mem_free(env->mctx, r->base); - r->length = 0; - } - - if (p != NULL) { - r->base = p; - r->length = strlen((char *) p); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dt_setidentity(dns_dtenv_t *env, const char *identity) { - REQUIRE(VALID_DTENV(env)); - - return (toregion(env, &env->identity, identity)); -} - -isc_result_t -dns_dt_setversion(dns_dtenv_t *env, const char *version) { - REQUIRE(VALID_DTENV(env)); - - return (toregion(env, &env->version, version)); -} - -static struct fstrm_iothr_queue * -dt_queue(dns_dtenv_t *env) { - isc_result_t result; - struct ioq { - unsigned int generation; - struct fstrm_iothr_queue *ioq; - } *ioq; - - REQUIRE(VALID_DTENV(env)); - - if (env->iothr == NULL) - return (NULL); - - result = dt_init(); - if (result != ISC_R_SUCCESS) - return (NULL); - - ioq = (struct ioq *)isc_thread_key_getspecific(dt_key); - if (ioq != NULL && ioq->generation != generation) { - result = isc_thread_key_setspecific(dt_key, NULL); - if (result != ISC_R_SUCCESS) - return (NULL); - free(ioq); - ioq = NULL; - } - if (ioq == NULL) { - ioq = malloc(sizeof(*ioq)); - if (ioq == NULL) - return (NULL); - ioq->generation = generation; - ioq->ioq = fstrm_iothr_get_input_queue(env->iothr); - if (ioq->ioq == NULL) { - free(ioq); - return (NULL); - } - result = isc_thread_key_setspecific(dt_key, ioq); - if (result != ISC_R_SUCCESS) { - free(ioq); - return (NULL); - } - } - - return (ioq->ioq); -} - -void -dns_dt_attach(dns_dtenv_t *source, dns_dtenv_t **destp) { - REQUIRE(VALID_DTENV(source)); - REQUIRE(destp != NULL && *destp == NULL); - - isc_refcount_increment(&source->refcount, NULL); - *destp = source; -} - -isc_result_t -dns_dt_getstats(dns_dtenv_t *env, isc_stats_t **statsp) { - REQUIRE(VALID_DTENV(env)); - REQUIRE(statsp != NULL && *statsp == NULL); - - if (env->stats == NULL) - return (ISC_R_NOTFOUND); - isc_stats_attach(env->stats, statsp); - return (ISC_R_SUCCESS); -} - -static void -destroy(dns_dtenv_t *env) { - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO, - "closing dnstap"); - env->magic = 0; - - generation++; - - if (env->iothr != NULL) - fstrm_iothr_destroy(&env->iothr); - if (env->fopt != NULL) - fstrm_iothr_options_destroy(&env->fopt); - - if (env->identity.base != NULL) { - isc_mem_free(env->mctx, env->identity.base); - env->identity.length = 0; - } - if (env->version.base != NULL) { - isc_mem_free(env->mctx, env->version.base); - env->version.length = 0; - } - if (env->path != NULL) - isc_mem_free(env->mctx, env->path); - if (env->stats != NULL) - isc_stats_detach(&env->stats); - - isc_mem_putanddetach(&env->mctx, env, sizeof(*env)); -} - -void -dns_dt_detach(dns_dtenv_t **envp) { - unsigned int refs; - dns_dtenv_t *env; - - REQUIRE(envp != NULL && VALID_DTENV(*envp)); - - env = *envp; - *envp = NULL; - - isc_refcount_decrement(&env->refcount, &refs); - if (refs == 0) - destroy(env); -} - -static isc_result_t -pack_dt(const Dnstap__Dnstap *d, void **buf, size_t *sz) { - ProtobufCBufferSimple sbuf; - - REQUIRE(d != NULL); - REQUIRE(sz != NULL); - - memset(&sbuf, 0, sizeof(sbuf)); - sbuf.base.append = protobuf_c_buffer_simple_append; - sbuf.len = 0; - sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE; - - /* Need to use malloc() here because protobuf uses free() */ - sbuf.data = malloc(sbuf.alloced); - if (sbuf.data == NULL) - return (ISC_R_NOMEMORY); - sbuf.must_free_data = 1; - - *sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf); - if (sbuf.data == NULL) - return (ISC_R_FAILURE); - *buf = sbuf.data; - - return (ISC_R_SUCCESS); -} - -static void -send_dt(dns_dtenv_t *env, void *buf, size_t len) { - struct fstrm_iothr_queue *ioq; - fstrm_res res; - - REQUIRE(env != NULL); - - if (buf == NULL) - return; - - ioq = dt_queue(env); - if (ioq == NULL) { - free(buf); - return; - } - - res = fstrm_iothr_submit(env->iothr, ioq, buf, len, - fstrm_free_wrapper, NULL); - if (res != fstrm_res_success) { - if (env->stats != NULL) - isc_stats_increment(env->stats, - dns_dnstapcounter_drop); - free(buf); - } else { - if (env->stats != NULL) - isc_stats_increment(env->stats, - dns_dnstapcounter_success); - } -} - -static void -init_msg(dns_dtenv_t *env, dns_dtmsg_t *dm, Dnstap__Message__Type mtype) { - memset(dm, 0, sizeof(*dm)); - dm->d.base.descriptor = &dnstap__dnstap__descriptor; - dm->m.base.descriptor = &dnstap__message__descriptor; - dm->d.type = DNSTAP__DNSTAP__TYPE__MESSAGE; - dm->d.message = &dm->m; - dm->m.type = mtype; - - if (env->identity.length != 0) { - dm->d.identity.data = env->identity.base; - dm->d.identity.len = env->identity.length; - dm->d.has_identity = true; - } - - if (env->version.length != 0) { - dm->d.version.data = env->version.base; - dm->d.version.len = env->version.length; - dm->d.has_version = true; - } -} - -static Dnstap__Message__Type -dnstap_type(dns_dtmsgtype_t msgtype) { - switch (msgtype) { - case DNS_DTTYPE_SQ: - return (DNSTAP__MESSAGE__TYPE__STUB_QUERY); - case DNS_DTTYPE_SR: - return (DNSTAP__MESSAGE__TYPE__STUB_RESPONSE); - case DNS_DTTYPE_CQ: - return (DNSTAP__MESSAGE__TYPE__CLIENT_QUERY); - case DNS_DTTYPE_CR: - return (DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE); - case DNS_DTTYPE_AQ: - return (DNSTAP__MESSAGE__TYPE__AUTH_QUERY); - case DNS_DTTYPE_AR: - return (DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE); - case DNS_DTTYPE_RQ: - return (DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY); - case DNS_DTTYPE_RR: - return (DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE); - case DNS_DTTYPE_FQ: - return (DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY); - case DNS_DTTYPE_FR: - return (DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE); - case DNS_DTTYPE_TQ: - return (DNSTAP__MESSAGE__TYPE__TOOL_QUERY); - case DNS_DTTYPE_TR: - return (DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void -cpbuf(isc_buffer_t *buf, ProtobufCBinaryData *p, protobuf_c_boolean *has) { - p->data = isc_buffer_base(buf); - p->len = isc_buffer_usedlength(buf); - *has = 1; -} - -static void -setaddr(dns_dtmsg_t *dm, isc_sockaddr_t *sa, bool tcp, - ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr, - uint32_t *port, protobuf_c_boolean *has_port) -{ - int family = isc_sockaddr_pf(sa); - - if (family != AF_INET6 && family != AF_INET) - return; - - if (family == AF_INET6) { - dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6; - addr->data = sa->type.sin6.sin6_addr.s6_addr; - addr->len = 16; - *port = ntohs(sa->type.sin6.sin6_port); - } else { - dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET; - addr->data = (uint8_t *) &sa->type.sin.sin_addr.s_addr; - addr->len = 4; - *port = ntohs(sa->type.sin.sin_port); - } - - if (tcp) - dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP; - else - dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP; - - dm->m.has_socket_protocol = 1; - dm->m.has_socket_family = 1; - *has_addr = 1; - *has_port = 1; -} - -void -dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, - isc_sockaddr_t *qaddr, isc_sockaddr_t *raddr, - bool tcp, isc_region_t *zone, isc_time_t *qtime, - isc_time_t *rtime, isc_buffer_t *buf) -{ - isc_time_t now, *t; - dns_dtmsg_t dm; - - REQUIRE(DNS_VIEW_VALID(view)); - - if ((msgtype & view->dttypes) == 0) - return; - - if (view->dtenv == NULL) - return; - - REQUIRE(VALID_DTENV(view->dtenv)); - - TIME_NOW(&now); - t = &now; - - init_msg(view->dtenv, &dm, dnstap_type(msgtype)); - - /* Query/response times */ - switch (msgtype) { - case DNS_DTTYPE_AR: - case DNS_DTTYPE_CR: - case DNS_DTTYPE_RR: - case DNS_DTTYPE_FR: - case DNS_DTTYPE_SR: - case DNS_DTTYPE_TR: - if (rtime != NULL) - t = rtime; - - dm.m.response_time_sec = isc_time_seconds(t); - dm.m.has_response_time_sec = 1; - dm.m.response_time_nsec = isc_time_nanoseconds(t); - dm.m.has_response_time_nsec = 1; - - cpbuf(buf, &dm.m.response_message, &dm.m.has_response_message); - - /* Types RR and FR get both query and response times */ - if (msgtype == DNS_DTTYPE_CR || msgtype == DNS_DTTYPE_AR) - break; - - /* FALLTHROUGH */ - case DNS_DTTYPE_AQ: - case DNS_DTTYPE_CQ: - case DNS_DTTYPE_FQ: - case DNS_DTTYPE_RQ: - case DNS_DTTYPE_SQ: - case DNS_DTTYPE_TQ: - if (qtime != NULL) - t = qtime; - - dm.m.query_time_sec = isc_time_seconds(t); - dm.m.has_query_time_sec = 1; - dm.m.query_time_nsec = isc_time_nanoseconds(t); - dm.m.has_query_time_nsec = 1; - - cpbuf(buf, &dm.m.query_message, &dm.m.has_query_message); - break; - default: - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP, - DNS_LOGMODULE_DNSTAP, ISC_LOG_ERROR, - "invalid dnstap message type %d", msgtype); - return; - } - - /* Zone/bailiwick */ - switch (msgtype) { - case DNS_DTTYPE_AR: - case DNS_DTTYPE_RQ: - case DNS_DTTYPE_RR: - case DNS_DTTYPE_FQ: - case DNS_DTTYPE_FR: - if (zone != NULL && zone->base != NULL && zone->length != 0) { - dm.m.query_zone.data = zone->base; - dm.m.query_zone.len = zone->length; - dm.m.has_query_zone = 1; - } - break; - default: - break; - } - - if (qaddr != NULL) { - setaddr(&dm, qaddr, tcp, - &dm.m.query_address, &dm.m.has_query_address, - &dm.m.query_port, &dm.m.has_query_port); - } - if (raddr != NULL) { - setaddr(&dm, raddr, tcp, - &dm.m.response_address, &dm.m.has_response_address, - &dm.m.response_port, &dm.m.has_response_port); - } - - if (pack_dt(&dm.d, &dm.buf, &dm.len) == ISC_R_SUCCESS) - send_dt(view->dtenv, dm.buf, dm.len); -} - -void -dns_dt_shutdown() { - if (dt_mctx != NULL) - isc_mem_detach(&dt_mctx); -} - -static isc_result_t -putstr(isc_buffer_t **b, const char *str) { - isc_result_t result; - - result = isc_buffer_reserve(b, strlen(str)); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOSPACE); - - isc_buffer_putstr(*b, str); - return (ISC_R_SUCCESS); -} - -static isc_result_t -putaddr(isc_buffer_t **b, isc_region_t *ip) { - char buf[64]; - - if (ip->length == 4) { - if (!inet_ntop(AF_INET, ip->base, buf, sizeof(buf))) - return (ISC_R_FAILURE); - } else if (ip->length == 16) { - if (!inet_ntop(AF_INET6, ip->base, buf, sizeof(buf))) - return (ISC_R_FAILURE); - } else - return (ISC_R_BADADDRESSFORM); - - return (putstr(b, buf)); -} - -static bool -dnstap_file(struct fstrm_reader *r) { - fstrm_res res; - const struct fstrm_control *control = NULL; - const uint8_t *rtype = NULL; - size_t dlen = strlen(DNSTAP_CONTENT_TYPE), rlen = 0; - size_t n = 0; - - res = fstrm_reader_get_control(r, FSTRM_CONTROL_START, &control); - if (res != fstrm_res_success) - return (false); - - res = fstrm_control_get_num_field_content_type(control, &n); - if (res != fstrm_res_success) - return (false); - if (n > 0) { - res = fstrm_control_get_field_content_type(control, 0, - &rtype, &rlen); - if (res != fstrm_res_success) - return (false); - - if (rlen != dlen) - return (false); - - if (memcmp(DNSTAP_CONTENT_TYPE, rtype, dlen) == 0) - return (true); - } - - return (false); -} - -isc_result_t -dns_dt_open(const char *filename, dns_dtmode_t mode, isc_mem_t *mctx, - dns_dthandle_t **handlep) -{ - isc_result_t result; - struct fstrm_file_options *fopt = NULL; - fstrm_res res; - dns_dthandle_t *handle; - - REQUIRE(handlep != NULL && *handlep == NULL); - - handle = isc_mem_get(mctx, sizeof(*handle)); - if (handle == NULL) - CHECK(ISC_R_NOMEMORY); - - handle->mode = mode; - handle->mctx = NULL; - - switch(mode) { - case dns_dtmode_file: - fopt = fstrm_file_options_init(); - if (fopt == NULL) - CHECK(ISC_R_NOMEMORY); - - fstrm_file_options_set_file_path(fopt, filename); - - handle->reader = fstrm_file_reader_init(fopt, NULL); - if (handle->reader == NULL) - CHECK(ISC_R_NOMEMORY); - - res = fstrm_reader_open(handle->reader); - if (res != fstrm_res_success) - CHECK(ISC_R_FAILURE); - - if (!dnstap_file(handle->reader)) - CHECK(DNS_R_BADDNSTAP); - break; - case dns_dtmode_unix: - return (ISC_R_NOTIMPLEMENTED); - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_mem_attach(mctx, &handle->mctx); - result = ISC_R_SUCCESS; - *handlep = handle; - handle = NULL; - - cleanup: - if (result != ISC_R_SUCCESS && - handle != NULL && handle->reader != NULL) - { - fstrm_reader_destroy(&handle->reader); - handle->reader = NULL; - } - if (fopt != NULL) - fstrm_file_options_destroy(&fopt); - if (handle != NULL) - isc_mem_put(mctx, handle, sizeof(*handle)); - return (result); -} - -isc_result_t -dns_dt_getframe(dns_dthandle_t *handle, uint8_t **bufp, size_t *sizep) { - const uint8_t *data; - fstrm_res res; - - REQUIRE(handle != NULL); - REQUIRE(bufp != NULL); - REQUIRE(sizep != NULL); - - data = (const uint8_t *) *bufp; - - res = fstrm_reader_read(handle->reader, &data, sizep); - switch (res) { - case fstrm_res_success: - if (data == NULL) - return (ISC_R_FAILURE); - DE_CONST(data, *bufp); - return (ISC_R_SUCCESS); - case fstrm_res_stop: - return (ISC_R_NOMORE); - default: - return (ISC_R_FAILURE); - } -} - -void -dns_dt_close(dns_dthandle_t **handlep) { - dns_dthandle_t *handle; - - REQUIRE(handlep != NULL && *handlep != NULL); - - handle = *handlep; - *handlep = NULL; - - if (handle->reader != NULL) { - fstrm_reader_destroy(&handle->reader); - handle->reader = NULL; - } - isc_mem_putanddetach(&handle->mctx, handle, sizeof(*handle)); -} - -isc_result_t -dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) { - isc_result_t result; - Dnstap__Dnstap *frame; - Dnstap__Message *m; - dns_dtdata_t *d = NULL; - isc_buffer_t b; - - REQUIRE(src != NULL); - REQUIRE(destp != NULL && *destp == NULL); - - d = isc_mem_get(mctx, sizeof(*d)); - if (d == NULL) - return (ISC_R_NOMEMORY); - - memset(d, 0, sizeof(*d)); - isc_mem_attach(mctx, &d->mctx); - - d->frame = dnstap__dnstap__unpack(NULL, src->length, src->base); - if (d->frame == NULL) - CHECK(ISC_R_NOMEMORY); - - frame = (Dnstap__Dnstap *)d->frame; - - if (frame->type != DNSTAP__DNSTAP__TYPE__MESSAGE) - CHECK(DNS_R_BADDNSTAP); - - m = frame->message; - - /* Message type */ - switch (m->type) { - case DNSTAP__MESSAGE__TYPE__AUTH_QUERY: - d->type = DNS_DTTYPE_AQ; - break; - case DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE: - d->type = DNS_DTTYPE_AR; - break; - case DNSTAP__MESSAGE__TYPE__CLIENT_QUERY: - d->type = DNS_DTTYPE_CQ; - break; - case DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE: - d->type = DNS_DTTYPE_CR; - break; - case DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY: - d->type = DNS_DTTYPE_FQ; - break; - case DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE: - d->type = DNS_DTTYPE_FR; - break; - case DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY: - d->type = DNS_DTTYPE_RQ; - break; - case DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE: - d->type = DNS_DTTYPE_RR; - break; - case DNSTAP__MESSAGE__TYPE__STUB_QUERY: - d->type = DNS_DTTYPE_SQ; - break; - case DNSTAP__MESSAGE__TYPE__STUB_RESPONSE: - d->type = DNS_DTTYPE_SR; - break; - case DNSTAP__MESSAGE__TYPE__TOOL_QUERY: - d->type = DNS_DTTYPE_TQ; - break; - case DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE: - d->type = DNS_DTTYPE_TR; - break; - default: - CHECK(DNS_R_BADDNSTAP); - } - - /* Query? */ - if ((d->type & DNS_DTTYPE_QUERY) != 0) - d->query = true; - else - d->query = false; - - /* Parse DNS message */ - if (d->query && m->has_query_message) { - d->msgdata.base = m->query_message.data; - d->msgdata.length = m->query_message.len; - } else if (!d->query && m->has_response_message) { - d->msgdata.base = m->response_message.data; - d->msgdata.length = m->response_message.len; - } - - isc_buffer_init(&b, d->msgdata.base, d->msgdata.length); - isc_buffer_add(&b, d->msgdata.length); - CHECK(dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &d->msg)); - result = dns_message_parse(d->msg, &b, 0); - if (result != ISC_R_SUCCESS) { - if (result != DNS_R_RECOVERABLE) - dns_message_detach(&d->msg); - result = ISC_R_SUCCESS; - } - - /* Timestamp */ - if (d->query) { - if (m->has_query_time_sec && m->has_query_time_nsec) - isc_time_set(&d->qtime, m->query_time_sec, - m->query_time_nsec); - } else { - if (m->has_response_time_sec && m->has_response_time_nsec) - isc_time_set(&d->rtime, m->response_time_sec, - m->response_time_nsec); - } - - /* Peer address */ - if (m->has_query_address) { - d->qaddr.base = m->query_address.data; - d->qaddr.length = m->query_address.len; - } - if (m->has_query_port) { - d->qport = m->query_port; - } - - if (m->has_response_address) { - d->raddr.base = m->response_address.data; - d->raddr.length = m->response_address.len; - } - if (m->has_response_port) { - d->rport = m->response_port; - } - - /* Socket protocol */ - if (m->has_socket_protocol) { - const ProtobufCEnumValue *type = - protobuf_c_enum_descriptor_get_value( - &dnstap__socket_protocol__descriptor, - m->socket_protocol); - if (type != NULL && - type->value == DNSTAP__SOCKET_PROTOCOL__TCP) - d->tcp = true; - else - d->tcp = false; - } - - /* Query tuple */ - if (d->msg != NULL) { - dns_name_t *name = NULL; - dns_rdataset_t *rdataset; - - CHECK(dns_message_firstname(d->msg, DNS_SECTION_QUESTION)); - dns_message_currentname(d->msg, DNS_SECTION_QUESTION, &name); - rdataset = ISC_LIST_HEAD(name->list); - - dns_name_format(name, d->namebuf, sizeof(d->namebuf)); - dns_rdatatype_format(rdataset->type, d->typebuf, - sizeof(d->typebuf)); - dns_rdataclass_format(rdataset->rdclass, d->classbuf, - sizeof(d->classbuf)); - } - - *destp = d; - - cleanup: - if (result != ISC_R_SUCCESS) - dns_dtdata_free(&d); - - return (result); -} - -isc_result_t -dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest) { - isc_result_t result; - char buf[100]; - - REQUIRE(d != NULL); - REQUIRE(dest != NULL && *dest != NULL); - - memset(buf, 0, sizeof(buf)); - - /* Timestamp */ - if (d->query && !isc_time_isepoch(&d->qtime)) - isc_time_formattimestamp(&d->qtime, buf, sizeof(buf)); - else if (!d->query && !isc_time_isepoch(&d->rtime)) - isc_time_formattimestamp(&d->rtime, buf, sizeof(buf)); - - if (buf[0] == '\0') - CHECK(putstr(dest, "???\?-?\?-?? ??:??:??.??? ")); - else { - CHECK(putstr(dest, buf)); - CHECK(putstr(dest, " ")); - } - - /* Type mnemonic */ - switch (d->type) { - case DNS_DTTYPE_AQ: - CHECK(putstr(dest, "AQ ")); - break; - case DNS_DTTYPE_AR: - CHECK(putstr(dest, "AR ")); - break; - case DNS_DTTYPE_CQ: - CHECK(putstr(dest, "CQ ")); - break; - case DNS_DTTYPE_CR: - CHECK(putstr(dest, "CR ")); - break; - case DNS_DTTYPE_FQ: - CHECK(putstr(dest, "FQ ")); - break; - case DNS_DTTYPE_FR: - CHECK(putstr(dest, "FR ")); - break; - case DNS_DTTYPE_RQ: - CHECK(putstr(dest, "RQ ")); - break; - case DNS_DTTYPE_RR: - CHECK(putstr(dest, "RR ")); - break; - case DNS_DTTYPE_SQ: - CHECK(putstr(dest, "SQ ")); - break; - case DNS_DTTYPE_SR: - CHECK(putstr(dest, "SR ")); - break; - case DNS_DTTYPE_TQ: - CHECK(putstr(dest, "TQ ")); - break; - case DNS_DTTYPE_TR: - CHECK(putstr(dest, "TR ")); - break; - default: - return (DNS_R_BADDNSTAP); - } - - /* Query and response addresses */ - if (d->qaddr.length != 0) { - CHECK(putaddr(dest, &d->qaddr)); - snprintf(buf, sizeof(buf), ":%u", d->qport); - CHECK(putstr(dest, buf)); - } else { - CHECK(putstr(dest, "?")); - } - if ((d->type & DNS_DTTYPE_QUERY) != 0) { - CHECK(putstr(dest, " -> ")); - } else { - CHECK(putstr(dest, " <- ")); - } - if (d->raddr.length != 0) { - CHECK(putaddr(dest, &d->raddr)); - snprintf(buf, sizeof(buf), ":%u", d->rport); - CHECK(putstr(dest, buf)); - } else { - CHECK(putstr(dest, "?")); - } - - CHECK(putstr(dest, " ")); - - /* Protocol */ - if (d->tcp) - CHECK(putstr(dest, "TCP ")); - else - CHECK(putstr(dest, "UDP ")); - - /* Message size */ - if (d->msgdata.base != NULL) { - snprintf(buf, sizeof(buf), "%zub ", (size_t) d->msgdata.length); - CHECK(putstr(dest, buf)); - } else - CHECK(putstr(dest, "0b ")); - - /* Query tuple */ - if (d->namebuf[0] == '\0') - CHECK(putstr(dest, "?/")); - else { - CHECK(putstr(dest, d->namebuf)); - CHECK(putstr(dest, "/")); - } - - if (d->classbuf[0] == '\0') - CHECK(putstr(dest, "?/")); - else { - CHECK(putstr(dest, d->classbuf)); - CHECK(putstr(dest, "/")); - } - - if (d->typebuf[0] == '\0') - CHECK(putstr(dest, "?")); - else - CHECK(putstr(dest, d->typebuf)); - - CHECK(isc_buffer_reserve(dest, 1)); - isc_buffer_putuint8(*dest, 0); - - cleanup: - return (result); -} - -void -dns_dtdata_free(dns_dtdata_t **dp) { - dns_dtdata_t *d; - - REQUIRE(dp != NULL && *dp != NULL); - - d = *dp; - - if (d->msg != NULL) - dns_message_detach(&d->msg); - if (d->frame != NULL) - dnstap__dnstap__free_unpacked(d->frame, NULL); - - isc_mem_putanddetach(&d->mctx, d, sizeof(*d)); - - *dp = NULL; -} diff --git a/lib/dns-pkcs11/dnstap.proto b/lib/dns-pkcs11/dnstap.proto deleted file mode 100644 index 22784cd..0000000 --- a/lib/dns-pkcs11/dnstap.proto +++ /dev/null @@ -1,268 +0,0 @@ -// dnstap: flexible, structured event replication format for DNS software -// -// This file contains the protobuf schemas for the "dnstap" structured event -// replication format for DNS software. - -// Written in 2013-2014 by Farsight Security, Inc. -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this file to the public -// domain worldwide. This file is distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along -// with this file. If not, see: -// -// . - -package dnstap; - -// "Dnstap": this is the top-level dnstap type, which is a "union" type that -// contains other kinds of dnstap payloads, although currently only one type -// of dnstap payload is defined. -// See: https://developers.google.com/protocol-buffers/docs/techniques#union -message Dnstap { - // DNS server identity. - // If enabled, this is the identity string of the DNS server which generated - // this message. Typically this would be the same string as returned by an - // "NSID" (RFC 5001) query. - optional bytes identity = 1; - - // DNS server version. - // If enabled, this is the version string of the DNS server which generated - // this message. Typically this would be the same string as returned by a - // "version.bind" query. - optional bytes version = 2; - - // Extra data for this payload. - // This field can be used for adding an arbitrary byte-string annotation to - // the payload. No encoding or interpretation is applied or enforced. - optional bytes extra = 3; - - // Identifies which field below is filled in. - enum Type { - MESSAGE = 1; - } - required Type type = 15; - - // One of the following will be filled in. - optional Message message = 14; -} - -// SocketFamily: the network protocol family of a socket. This specifies how -// to interpret "network address" fields. -enum SocketFamily { - INET = 1; // IPv4 (RFC 791) - INET6 = 2; // IPv6 (RFC 2460) -} - -// SocketProtocol: the transport protocol of a socket. This specifies how to -// interpret "transport port" fields. -enum SocketProtocol { - UDP = 1; // User Datagram Protocol (RFC 768) - TCP = 2; // Transmission Control Protocol (RFC 793) -} - -// Message: a wire-format (RFC 1035 section 4) DNS message and associated -// metadata. Applications generating "Message" payloads should follow -// certain requirements based on the MessageType, see below. -message Message { - - // There are eight types of "Message" defined that correspond to the - // four arrows in the following diagram, slightly modified from RFC 1035 - // section 2: - - // +---------+ +----------+ +--------+ - // | | query | | query | | - // | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. | - // | Resolver| | Server | | Name | - // | |<-SR--------CR-| |<-RR----AR-| Server | - // +---------+ response | | response | | - // +----------+ +--------+ - - // Each arrow has two Type values each, one for each "end" of each arrow, - // because these are considered to be distinct events. Each end of each - // arrow on the diagram above has been marked with a two-letter Type - // mnemonic. Clockwise from upper left, these mnemonic values are: - // - // SQ: STUB_QUERY - // CQ: CLIENT_QUERY - // RQ: RESOLVER_QUERY - // AQ: AUTH_QUERY - // AR: AUTH_RESPONSE - // RR: RESOLVER_RESPONSE - // CR: CLIENT_RESPONSE - // SR: STUB_RESPONSE - - // Two additional types of "Message" have been defined for the - // "forwarding" case where an upstream DNS server is responsible for - // further recursion. These are not shown on the diagram above, but have - // the following mnemonic values: - - // FQ: FORWARDER_QUERY - // FR: FORWARDER_RESPONSE - - // The "Message" Type values are defined below. - - enum Type { - // AUTH_QUERY is a DNS query message received from a resolver by an - // authoritative name server, from the perspective of the authoritative - // name server. - AUTH_QUERY = 1; - - // AUTH_RESPONSE is a DNS response message sent from an authoritative - // name server to a resolver, from the perspective of the authoritative - // name server. - AUTH_RESPONSE = 2; - - // RESOLVER_QUERY is a DNS query message sent from a resolver to an - // authoritative name server, from the perspective of the resolver. - // Resolvers typically clear the RD (recursion desired) bit when - // sending queries. - RESOLVER_QUERY = 3; - - // RESOLVER_RESPONSE is a DNS response message received from an - // authoritative name server by a resolver, from the perspective of - // the resolver. - RESOLVER_RESPONSE = 4; - - // CLIENT_QUERY is a DNS query message sent from a client to a DNS - // server which is expected to perform further recursion, from the - // perspective of the DNS server. The client may be a stub resolver or - // forwarder or some other type of software which typically sets the RD - // (recursion desired) bit when querying the DNS server. The DNS server - // may be a simple forwarding proxy or it may be a full recursive - // resolver. - CLIENT_QUERY = 5; - - // CLIENT_RESPONSE is a DNS response message sent from a DNS server to - // a client, from the perspective of the DNS server. The DNS server - // typically sets the RA (recursion available) bit when responding. - CLIENT_RESPONSE = 6; - - // FORWARDER_QUERY is a DNS query message sent from a downstream DNS - // server to an upstream DNS server which is expected to perform - // further recursion, from the perspective of the downstream DNS - // server. - FORWARDER_QUERY = 7; - - // FORWARDER_RESPONSE is a DNS response message sent from an upstream - // DNS server performing recursion to a downstream DNS server, from the - // perspective of the downstream DNS server. - FORWARDER_RESPONSE = 8; - - // STUB_QUERY is a DNS query message sent from a stub resolver to a DNS - // server, from the perspective of the stub resolver. - STUB_QUERY = 9; - - // STUB_RESPONSE is a DNS response message sent from a DNS server to a - // stub resolver, from the perspective of the stub resolver. - STUB_RESPONSE = 10; - - // TOOL_QUERY is a DNS query message sent from a DNS software tool to a - // DNS server, from the perspective of the tool. - TOOL_QUERY = 11; - - // TOOL_RESPONSE is a DNS response message received by a DNS software - // tool from a DNS server, from the perspective of the tool. - TOOL_RESPONSE = 12; - } - - // One of the Type values described above. - required Type type = 1; - - // One of the SocketFamily values described above. - optional SocketFamily socket_family = 2; - - // One of the SocketProtocol values described above. - optional SocketProtocol socket_protocol = 3; - - // The network address of the message initiator. - // For SocketFamily INET, this field is 4 octets (IPv4 address). - // For SocketFamily INET6, this field is 16 octets (IPv6 address). - optional bytes query_address = 4; - - // The network address of the message responder. - // For SocketFamily INET, this field is 4 octets (IPv4 address). - // For SocketFamily INET6, this field is 16 octets (IPv6 address). - optional bytes response_address = 5; - - // The transport port of the message initiator. - // This is a 16-bit UDP or TCP port number, depending on SocketProtocol. - optional uint32 query_port = 6; - - // The transport port of the message responder. - // This is a 16-bit UDP or TCP port number, depending on SocketProtocol. - optional uint32 response_port = 7; - - // The time at which the DNS query message was sent or received, depending - // on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY. - // This is the number of seconds since the UNIX epoch. - optional uint64 query_time_sec = 8; - - // The time at which the DNS query message was sent or received. - // This is the seconds fraction, expressed as a count of nanoseconds. - optional fixed32 query_time_nsec = 9; - - // The initiator's original wire-format DNS query message, verbatim. - optional bytes query_message = 10; - - // The "zone" or "bailiwick" pertaining to the DNS query message. - // This is a wire-format DNS domain name. - optional bytes query_zone = 11; - - // The time at which the DNS response message was sent or received, - // depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or - // CLIENT_RESPONSE. - // This is the number of seconds since the UNIX epoch. - optional uint64 response_time_sec = 12; - - // The time at which the DNS response message was sent or received. - // This is the seconds fraction, expressed as a count of nanoseconds. - optional fixed32 response_time_nsec = 13; - - // The responder's original wire-format DNS response message, verbatim. - optional bytes response_message = 14; -} - -// All fields except for 'type' in the Message schema are optional. -// It is recommended that at least the following fields be filled in for -// particular types of Messages. - -// AUTH_QUERY: -// socket_family, socket_protocol -// query_address, query_port -// query_message -// query_time_sec, query_time_nsec - -// AUTH_RESPONSE: -// socket_family, socket_protocol -// query_address, query_port -// query_time_sec, query_time_nsec -// response_message -// response_time_sec, response_time_nsec - -// RESOLVER_QUERY: -// socket_family, socket_protocol -// query_message -// query_time_sec, query_time_nsec -// query_zone -// response_address, response_port - -// RESOLVER_RESPONSE: -// socket_family, socket_protocol -// query_time_sec, query_time_nsec -// query_zone -// response_address, response_port -// response_message -// response_time_sec, response_time_nsec - -// CLIENT_QUERY: -// socket_family, socket_protocol -// query_message -// query_time_sec, query_time_nsec - -// CLIENT_RESPONSE: -// socket_family, socket_protocol -// query_time_sec, query_time_nsec -// response_message -// response_time_sec, response_time_nsec diff --git a/lib/dns-pkcs11/ds.c b/lib/dns-pkcs11/ds.c deleted file mode 100644 index 30518f4..0000000 --- a/lib/dns-pkcs11/ds.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) -#include "dst_gost.h" -#endif - -isc_result_t -dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, - dns_dsdigest_t digest_type, unsigned char *buffer, - dns_rdata_t *rdata) -{ - dns_fixedname_t fname; - dns_name_t *name; - unsigned char digest[ISC_SHA384_DIGESTLENGTH]; - isc_region_t r; - isc_buffer_t b; - dns_rdata_ds_t ds; - isc_sha1_t sha1; - isc_sha256_t sha256; - isc_sha384_t sha384; -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - isc_gost_t gost; -#endif - - REQUIRE(key != NULL); - REQUIRE(key->type == dns_rdatatype_dnskey); - - if (!dst_ds_digest_supported(digest_type)) - return (ISC_R_NOTIMPLEMENTED); - - name = dns_fixedname_initname(&fname); - (void)dns_name_downcase(owner, name, NULL); - - memset(buffer, 0, DNS_DS_BUFFERSIZE); - isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); - - switch (digest_type) { - case DNS_DSDIGEST_SHA1: - isc_sha1_init(&sha1); - dns_name_toregion(name, &r); - isc_sha1_update(&sha1, r.base, r.length); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - isc_sha1_update(&sha1, r.base, r.length); - isc_sha1_final(&sha1, digest); - break; - -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) -#define RETERR(x) do { \ - isc_result_t ret = (x); \ - if (ret != ISC_R_SUCCESS) { \ - isc_gost_invalidate(&gost); \ - return (ret); \ - } \ -} while (0) - - case DNS_DSDIGEST_GOST: - RETERR(isc_gost_init(&gost)); - dns_name_toregion(name, &r); - RETERR(isc_gost_update(&gost, r.base, r.length)); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - RETERR(isc_gost_update(&gost, r.base, r.length)); - RETERR(isc_gost_final(&gost, digest)); - break; -#endif - - case DNS_DSDIGEST_SHA384: - isc_sha384_init(&sha384); - dns_name_toregion(name, &r); - isc_sha384_update(&sha384, r.base, r.length); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - isc_sha384_update(&sha384, r.base, r.length); - isc_sha384_final(digest, &sha384); - break; - - case DNS_DSDIGEST_SHA256: - isc_sha256_init(&sha256); - dns_name_toregion(name, &r); - isc_sha256_update(&sha256, r.base, r.length); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - isc_sha256_update(&sha256, r.base, r.length); - isc_sha256_final(digest, &sha256); - break; - - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - ds.mctx = NULL; - ds.common.rdclass = key->rdclass; - ds.common.rdtype = dns_rdatatype_ds; - ds.algorithm = r.base[3]; - ds.key_tag = dst_region_computeid(&r, ds.algorithm); - ds.digest_type = digest_type; - switch (digest_type) { - case DNS_DSDIGEST_SHA1: - ds.length = ISC_SHA1_DIGESTLENGTH; - break; - -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - case DNS_DSDIGEST_GOST: - ds.length = ISC_GOST_DIGESTLENGTH; - break; -#endif - - case DNS_DSDIGEST_SHA384: - ds.length = ISC_SHA384_DIGESTLENGTH; - break; - - case DNS_DSDIGEST_SHA256: - default: - ds.length = ISC_SHA256_DIGESTLENGTH; - break; - } - ds.digest = digest; - - return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, - &ds, &b)); -} diff --git a/lib/dns-pkcs11/dst_api.c b/lib/dns-pkcs11/dst_api.c deleted file mode 100644 index 2156384..0000000 --- a/lib/dns-pkcs11/dst_api.c +++ /dev/null @@ -1,2063 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DST_KEY_INTERNAL - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" - -#define DST_AS_STR(t) ((t).value.as_textregion.base) - -static dst_func_t *dst_t_func[DST_MAX_ALGS]; -static isc_entropy_t *dst_entropy_pool = NULL; -static unsigned int dst_entropy_flags = 0; - -static bool dst_initialized = false; - -void gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); - -LIBDNS_EXTERNAL_DATA isc_mem_t *dst__memory_pool = NULL; - -/* - * Static functions. - */ -static dst_key_t * get_key_struct(dns_name_t *name, - unsigned int alg, - unsigned int flags, - unsigned int protocol, - unsigned int bits, - dns_rdataclass_t rdclass, - dns_ttl_t ttl, - isc_mem_t *mctx); -static isc_result_t write_public_key(const dst_key_t *key, int type, - const char *directory); -static isc_result_t buildfilename(dns_name_t *name, - dns_keytag_t id, - unsigned int alg, - unsigned int type, - const char *directory, - isc_buffer_t *out); -static isc_result_t computeid(dst_key_t *key); -static isc_result_t frombuffer(dns_name_t *name, - unsigned int alg, - unsigned int flags, - unsigned int protocol, - dns_rdataclass_t rdclass, - isc_buffer_t *source, - isc_mem_t *mctx, - dst_key_t **keyp); - -static isc_result_t algorithm_status(unsigned int alg); - -static isc_result_t addsuffix(char *filename, int len, - const char *dirname, const char *ofilename, - const char *suffix); - -#define RETERR(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto out; \ - } while (0) - -#define CHECKALG(alg) \ - do { \ - isc_result_t _r; \ - _r = algorithm_status(alg); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0); \ - -#if defined(OPENSSL) -static void * -default_memalloc(void *arg, size_t size) { - UNUSED(arg); - if (size == 0U) - size = 1; - /* cppcheck-suppress leakNoVarFunctionCall */ - return (malloc(size)); -} - -static void -default_memfree(void *arg, void *ptr) { - UNUSED(arg); - free(ptr); -} -#endif - -isc_result_t -dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { - return (dst_lib_init2(mctx, ectx, NULL, eflags)); -} - -isc_result_t -dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, - const char *engine, unsigned int eflags) { - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(dst_initialized == false); - -#if !defined(OPENSSL) && !defined(PKCS11CRYPTO) - UNUSED(engine); -#endif - - dst__memory_pool = NULL; - -#if defined(OPENSSL) - UNUSED(mctx); - /* - * When using --with-openssl, there seems to be no good way of not - * leaking memory due to the openssl error handling mechanism. - * Avoid assertions by using a local memory context and not checking - * for leaks on exit. Note: as there are leaks we cannot use - * ISC_MEMFLAG_INTERNAL as it will free up memory still being used - * by libcrypto. - */ - result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, - NULL, &dst__memory_pool, 0); - if (result != ISC_R_SUCCESS) - return (result); - isc_mem_setname(dst__memory_pool, "dst", NULL); -#ifndef OPENSSL_LEAKS - isc_mem_setdestroycheck(dst__memory_pool, false); -#endif -#else /* OPENSSL */ - isc_mem_attach(mctx, &dst__memory_pool); -#endif /* OPENSSL */ - if (ectx != NULL) { - isc_entropy_attach(ectx, &dst_entropy_pool); - dst_entropy_flags = eflags; - } - - dst_result_register(); - - memset(dst_t_func, 0, sizeof(dst_t_func)); - -#ifdef OPENSSL - RETERR(dst__openssl_init(engine)); -#elif PKCS11CRYPTO - RETERR(dst__pkcs11_init(mctx, engine)); -#endif -#ifndef PK11_MD5_DISABLE - RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); -#endif - RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); - RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); - RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256])); - RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); - RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); -#ifdef OPENSSL -#ifndef PK11_MD5_DISABLE - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5], - DST_ALG_RSAMD5)); -#endif - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1], - DST_ALG_RSASHA1)); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], - DST_ALG_NSEC3RSASHA1)); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256], - DST_ALG_RSASHA256)); - RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512], - DST_ALG_RSASHA512)); -#if defined(HAVE_OPENSSL_DSA) && !defined(PK11_DSA_DISABLE) - RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA])); - RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); -#endif -#ifndef PK11_DH_DISABLE - RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH])); -#endif -#ifdef HAVE_OPENSSL_GOST - RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST])); -#endif -#ifdef HAVE_OPENSSL_ECDSA - RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); - RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); -#endif -#ifdef HAVE_OPENSSL_ED25519 - RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED25519])); -#endif -#ifdef HAVE_OPENSSL_ED448 - RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED448])); -#endif -#elif PKCS11CRYPTO -#ifndef PK11_MD5_DISABLE - RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5], - DST_ALG_RSAMD5)); -#endif - RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1], - DST_ALG_RSASHA1)); - RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], - DST_ALG_NSEC3RSASHA1)); - RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256], - DST_ALG_RSASHA256)); - RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512], - DST_ALG_RSASHA512)); -#ifndef PK11_DSA_DISABLE - RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA])); - RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); -#endif -#ifndef PK11_DH_DISABLE - RETERR(dst__pkcs11dh_init(&dst_t_func[DST_ALG_DH])); -#endif -#ifdef HAVE_PKCS11_ECDSA - RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); - RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); -#endif -#ifdef HAVE_PKCS11_ED25519 - RETERR(dst__pkcs11eddsa_init(&dst_t_func[DST_ALG_ED25519])); -#endif -#ifdef HAVE_PKCS11_ED448 - RETERR(dst__pkcs11eddsa_init(&dst_t_func[DST_ALG_ED448])); -#endif -#ifdef HAVE_PKCS11_GOST - RETERR(dst__pkcs11gost_init(&dst_t_func[DST_ALG_ECCGOST])); -#endif -#endif /* if OPENSSL, elif PKCS11CRYPTO */ -#ifdef GSSAPI - RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); -#endif -#if defined(OPENSSL) || defined(PKCS11CRYPTO) -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (dst_entropy_pool != NULL) - isc_entropy_sethook(dst_random_getdata); -#endif -#endif /* defined(OPENSSL) || defined(PKCS11CRYPTO) */ - dst_initialized = true; - return (ISC_R_SUCCESS); - - out: - /* avoid immediate crash! */ - dst_initialized = true; - dst_lib_destroy(); - return (result); -} - -void -dst_lib_destroy(void) { - int i; - RUNTIME_CHECK(dst_initialized == true); - dst_initialized = false; - - for (i = 0; i < DST_MAX_ALGS; i++) - if (dst_t_func[i] != NULL && dst_t_func[i]->cleanup != NULL) - dst_t_func[i]->cleanup(); -#if defined(OPENSSL) || defined(PKCS11CRYPTO) -#ifdef ISC_PLATFORM_CRYPTORANDOM - if (dst_entropy_pool != NULL) { - isc_entropy_usehook(dst_entropy_pool, false); - isc_entropy_sethook(NULL); - } -#endif -#ifdef OPENSSL - dst__openssl_destroy(); -#elif PKCS11CRYPTO - (void) dst__pkcs11_destroy(); -#endif /* if OPENSSL, elif PKCS11CRYPTO */ -#endif /* defined(OPENSSL) || defined(PKCS11CRYPTO) */ - if (dst__memory_pool != NULL) - isc_mem_detach(&dst__memory_pool); - if (dst_entropy_pool != NULL) - isc_entropy_detach(&dst_entropy_pool); -} - -bool -dst_algorithm_supported(unsigned int alg) { - REQUIRE(dst_initialized == true); - - if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) - return (false); - return (true); -} - -bool -dst_ds_digest_supported(unsigned int digest_type) { - return (digest_type == DNS_DSDIGEST_SHA1 || - digest_type == DNS_DSDIGEST_SHA256 || -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - digest_type == DNS_DSDIGEST_GOST || -#endif - digest_type == DNS_DSDIGEST_SHA384); -} - -isc_result_t -dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { - return (dst_context_create4(key, mctx, DNS_LOGCATEGORY_GENERAL, - true, 0, dctxp)); -} - -isc_result_t -dst_context_create2(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, dst_context_t **dctxp) -{ - return (dst_context_create4(key, mctx, category, true, 0, dctxp)); -} - -isc_result_t -dst_context_create3(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, bool useforsigning, - dst_context_t **dctxp) -{ - return (dst_context_create4(key, mctx, category, - useforsigning, 0, dctxp)); -} - -isc_result_t -dst_context_create4(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, bool useforsigning, - int maxbits, dst_context_t **dctxp) -{ - dst_context_t *dctx; - isc_result_t result; - - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(mctx != NULL); - REQUIRE(dctxp != NULL && *dctxp == NULL); - - if (key->func->createctx == NULL && - key->func->createctx2 == NULL) - return (DST_R_UNSUPPORTEDALG); - if (key->keydata.generic == NULL) - return (DST_R_NULLKEY); - - dctx = isc_mem_get(mctx, sizeof(dst_context_t)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - memset(dctx, 0, sizeof(*dctx)); - dst_key_attach(key, &dctx->key); - isc_mem_attach(mctx, &dctx->mctx); - dctx->category = category; - if (useforsigning) - dctx->use = DO_SIGN; - else - dctx->use = DO_VERIFY; - if (key->func->createctx2 != NULL) - result = key->func->createctx2(key, maxbits, dctx); - else - result = key->func->createctx(key, dctx); - if (result != ISC_R_SUCCESS) { - if (dctx->key != NULL) - dst_key_free(&dctx->key); - isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(dst_context_t)); - return (result); - } - dctx->magic = CTX_MAGIC; - *dctxp = dctx; - return (ISC_R_SUCCESS); -} - -void -dst_context_destroy(dst_context_t **dctxp) { - dst_context_t *dctx; - - REQUIRE(dctxp != NULL && VALID_CTX(*dctxp)); - - dctx = *dctxp; - INSIST(dctx->key->func->destroyctx != NULL); - dctx->key->func->destroyctx(dctx); - if (dctx->key != NULL) - dst_key_free(&dctx->key); - dctx->magic = 0; - isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(dst_context_t)); - *dctxp = NULL; -} - -isc_result_t -dst_context_adddata(dst_context_t *dctx, const isc_region_t *data) { - REQUIRE(VALID_CTX(dctx)); - REQUIRE(data != NULL); - INSIST(dctx->key->func->adddata != NULL); - - return (dctx->key->func->adddata(dctx, data)); -} - -isc_result_t -dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_key_t *key; - - REQUIRE(VALID_CTX(dctx)); - REQUIRE(sig != NULL); - - key = dctx->key; - CHECKALG(key->key_alg); - if (key->keydata.generic == NULL) - return (DST_R_NULLKEY); - - if (key->func->sign == NULL) - return (DST_R_NOTPRIVATEKEY); - if (key->func->isprivate == NULL || - key->func->isprivate(key) == false) - return (DST_R_NOTPRIVATEKEY); - - return (key->func->sign(dctx, sig)); -} - -isc_result_t -dst_context_verify(dst_context_t *dctx, isc_region_t *sig) { - REQUIRE(VALID_CTX(dctx)); - REQUIRE(sig != NULL); - - CHECKALG(dctx->key->key_alg); - if (dctx->key->keydata.generic == NULL) - return (DST_R_NULLKEY); - if (dctx->key->func->verify == NULL) - return (DST_R_NOTPUBLICKEY); - - return (dctx->key->func->verify(dctx, sig)); -} - -isc_result_t -dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, - isc_region_t *sig) -{ - REQUIRE(VALID_CTX(dctx)); - REQUIRE(sig != NULL); - - CHECKALG(dctx->key->key_alg); - if (dctx->key->keydata.generic == NULL) - return (DST_R_NULLKEY); - if (dctx->key->func->verify == NULL && - dctx->key->func->verify2 == NULL) - return (DST_R_NOTPUBLICKEY); - - return (dctx->key->func->verify2 != NULL ? - dctx->key->func->verify2(dctx, maxbits, sig) : - dctx->key->func->verify(dctx, sig)); -} - -isc_result_t -dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, - isc_buffer_t *secret) -{ - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(pub) && VALID_KEY(priv)); - REQUIRE(secret != NULL); - - CHECKALG(pub->key_alg); - CHECKALG(priv->key_alg); - - if (pub->keydata.generic == NULL || priv->keydata.generic == NULL) - return (DST_R_NULLKEY); - - if (pub->key_alg != priv->key_alg || - pub->func->computesecret == NULL || - priv->func->computesecret == NULL) - return (DST_R_KEYCANNOTCOMPUTESECRET); - - if (dst_key_isprivate(priv) == false) - return (DST_R_NOTPRIVATEKEY); - - return (pub->func->computesecret(pub, priv, secret)); -} - -isc_result_t -dst_key_tofile(const dst_key_t *key, int type, const char *directory) { - isc_result_t ret = ISC_R_SUCCESS; - - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); - - CHECKALG(key->key_alg); - - if (key->func->tofile == NULL) - return (DST_R_UNSUPPORTEDALG); - - if ((type & DST_TYPE_PUBLIC) != 0) { - ret = write_public_key(key, type, directory); - if (ret != ISC_R_SUCCESS) - return (ret); - } - - if (((type & DST_TYPE_PRIVATE) != 0) && - (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) - return (key->func->tofile(key, directory)); - else - return (ret); -} - -void -dst_key_setexternal(dst_key_t *key, bool value) { - key->external = value; -} - -bool -dst_key_isexternal(dst_key_t *key) { - return (key->external); -} - -isc_result_t -dst_key_getfilename(dns_name_t *name, dns_keytag_t id, - unsigned int alg, int type, const char *directory, - isc_mem_t *mctx, isc_buffer_t *buf) -{ - isc_result_t result; - - REQUIRE(dst_initialized == true); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); - REQUIRE(mctx != NULL); - REQUIRE(buf != NULL); - - CHECKALG(alg); - - result = buildfilename(name, id, alg, type, directory, buf); - if (result == ISC_R_SUCCESS) { - if (isc_buffer_availablelength(buf) > 0) - isc_buffer_putuint8(buf, 0); - else - result = ISC_R_NOSPACE; - } - - return (result); -} - -isc_result_t -dst_key_fromfile(dns_name_t *name, dns_keytag_t id, - unsigned int alg, int type, const char *directory, - isc_mem_t *mctx, dst_key_t **keyp) -{ - isc_result_t result; - char filename[NAME_MAX]; - isc_buffer_t buf; - dst_key_t *key; - - REQUIRE(dst_initialized == true); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - - CHECKALG(alg); - - key = NULL; - - isc_buffer_init(&buf, filename, NAME_MAX); - result = dst_key_getfilename(name, id, alg, type, NULL, mctx, &buf); - if (result != ISC_R_SUCCESS) - goto out; - - result = dst_key_fromnamedfile(filename, directory, type, mctx, &key); - if (result != ISC_R_SUCCESS) - goto out; - - result = computeid(key); - if (result != ISC_R_SUCCESS) - goto out; - - if (!dns_name_equal(name, key->key_name) || id != key->key_id || - alg != key->key_alg) { - result = DST_R_INVALIDPRIVATEKEY; - goto out; - } - - *keyp = key; - result = ISC_R_SUCCESS; - - out: - if ((key != NULL) && (result != ISC_R_SUCCESS)) - dst_key_free(&key); - - return (result); -} - -isc_result_t -dst_key_fromnamedfile(const char *filename, const char *dirname, - int type, isc_mem_t *mctx, dst_key_t **keyp) -{ - isc_result_t result; - dst_key_t *pubkey = NULL, *key = NULL; - char *newfilename = NULL; - int newfilenamelen = 0; - isc_lex_t *lex = NULL; - - REQUIRE(dst_initialized == true); - REQUIRE(filename != NULL); - REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - - /* If an absolute path is specified, don't use the key directory */ -#ifndef WIN32 - if (filename[0] == '/') - dirname = NULL; -#else /* WIN32 */ - if (filename[0] == '/' || filename[0] == '\\') - dirname = NULL; -#endif - - newfilenamelen = strlen(filename) + 5; - if (dirname != NULL) - newfilenamelen += strlen(dirname) + 1; - newfilename = isc_mem_get(mctx, newfilenamelen); - if (newfilename == NULL) - return (ISC_R_NOMEMORY); - result = addsuffix(newfilename, newfilenamelen, - dirname, filename, ".key"); - INSIST(result == ISC_R_SUCCESS); - - result = dst_key_read_public(newfilename, type, mctx, &pubkey); - isc_mem_put(mctx, newfilename, newfilenamelen); - newfilename = NULL; - RETERR(result); - - if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || - (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { - result = computeid(pubkey); - if (result != ISC_R_SUCCESS) { - dst_key_free(&pubkey); - return (result); - } - - *keyp = pubkey; - return (ISC_R_SUCCESS); - } - - result = algorithm_status(pubkey->key_alg); - if (result != ISC_R_SUCCESS) { - dst_key_free(&pubkey); - return (result); - } - - key = get_key_struct(pubkey->key_name, pubkey->key_alg, - pubkey->key_flags, pubkey->key_proto, 0, - pubkey->key_class, pubkey->key_ttl, mctx); - if (key == NULL) { - dst_key_free(&pubkey); - return (ISC_R_NOMEMORY); - } - - if (key->func->parse == NULL) - RETERR(DST_R_UNSUPPORTEDALG); - - newfilenamelen = strlen(filename) + 9; - if (dirname != NULL) - newfilenamelen += strlen(dirname) + 1; - newfilename = isc_mem_get(mctx, newfilenamelen); - if (newfilename == NULL) - RETERR(ISC_R_NOMEMORY); - result = addsuffix(newfilename, newfilenamelen, - dirname, filename, ".private"); - INSIST(result == ISC_R_SUCCESS); - - RETERR(isc_lex_create(mctx, 1500, &lex)); - RETERR(isc_lex_openfile(lex, newfilename)); - isc_mem_put(mctx, newfilename, newfilenamelen); - - RETERR(key->func->parse(key, lex, pubkey)); - isc_lex_destroy(&lex); - - RETERR(computeid(key)); - - if (pubkey->key_id != key->key_id) - RETERR(DST_R_INVALIDPRIVATEKEY); - dst_key_free(&pubkey); - - *keyp = key; - return (ISC_R_SUCCESS); - - out: - if (pubkey != NULL) - dst_key_free(&pubkey); - if (newfilename != NULL) - isc_mem_put(mctx, newfilename, newfilenamelen); - if (lex != NULL) - isc_lex_destroy(&lex); - if (key != NULL) - dst_key_free(&key); - return (result); -} - -isc_result_t -dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(target != NULL); - - CHECKALG(key->key_alg); - - if (key->func->todns == NULL) - return (DST_R_UNSUPPORTEDALG); - - if (isc_buffer_availablelength(target) < 4) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(target, (uint16_t)(key->key_flags & 0xffff)); - isc_buffer_putuint8(target, (uint8_t)key->key_proto); - isc_buffer_putuint8(target, (uint8_t)key->key_alg); - - if ((key->key_flags & DNS_KEYFLAG_EXTENDED) != 0) { - if (isc_buffer_availablelength(target) < 2) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(target, - (uint16_t)((key->key_flags >> 16) - & 0xffff)); - } - - if (key->keydata.generic == NULL) /*%< NULL KEY */ - return (ISC_R_SUCCESS); - - return (key->func->todns(key, target)); -} - -isc_result_t -dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, - isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) -{ - uint8_t alg, proto; - uint32_t flags, extflags; - dst_key_t *key = NULL; - dns_keytag_t id, rid; - isc_region_t r; - isc_result_t result; - - REQUIRE(dst_initialized); - - isc_buffer_remainingregion(source, &r); - - if (isc_buffer_remaininglength(source) < 4) - return (DST_R_INVALIDPUBLICKEY); - flags = isc_buffer_getuint16(source); - proto = isc_buffer_getuint8(source); - alg = isc_buffer_getuint8(source); - - id = dst_region_computeid(&r, alg); - rid = dst_region_computerid(&r, alg); - - if ((flags & DNS_KEYFLAG_EXTENDED) != 0) { - if (isc_buffer_remaininglength(source) < 2) - return (DST_R_INVALIDPUBLICKEY); - extflags = isc_buffer_getuint16(source); - flags |= (extflags << 16); - } - - result = frombuffer(name, alg, flags, proto, rdclass, source, - mctx, &key); - if (result != ISC_R_SUCCESS) - return (result); - key->key_id = id; - key->key_rid = rid; - - *keyp = key; - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_frombuffer(dns_name_t *name, unsigned int alg, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) -{ - dst_key_t *key = NULL; - isc_result_t result; - - REQUIRE(dst_initialized); - - result = frombuffer(name, alg, flags, protocol, rdclass, source, - mctx, &key); - if (result != ISC_R_SUCCESS) - return (result); - - result = computeid(key); - if (result != ISC_R_SUCCESS) { - dst_key_free(&key); - return (result); - } - - *keyp = key; - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(target != NULL); - - CHECKALG(key->key_alg); - - if (key->func->todns == NULL) - return (DST_R_UNSUPPORTEDALG); - - return (key->func->todns(key, target)); -} - -isc_result_t -dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) { - isc_lex_t *lex = NULL; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(!dst_key_isprivate(key)); - REQUIRE(buffer != NULL); - - if (key->func->parse == NULL) - RETERR(DST_R_UNSUPPORTEDALG); - - RETERR(isc_lex_create(key->mctx, 1500, &lex)); - RETERR(isc_lex_openbuffer(lex, buffer)); - RETERR(key->func->parse(key, lex, NULL)); - out: - if (lex != NULL) - isc_lex_destroy(&lex); - return (result); -} - -gss_ctx_id_t -dst_key_getgssctx(const dst_key_t *key) -{ - REQUIRE(key != NULL); - - return (key->keydata.gssctx); -} - -isc_result_t -dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, - dst_key_t **keyp, isc_region_t *intoken) -{ - dst_key_t *key; - isc_result_t result; - - REQUIRE(gssctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - - key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC, - 0, dns_rdataclass_in, 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - if (intoken != NULL) { - /* - * Keep the token for use by external ssu rules. They may need - * to examine the PAC in the kerberos ticket. - */ - RETERR(isc_buffer_allocate(key->mctx, &key->key_tkeytoken, - intoken->length)); - RETERR(isc_buffer_copyregion(key->key_tkeytoken, intoken)); - } - - key->keydata.gssctx = gssctx; - *keyp = key; - result = ISC_R_SUCCESS; -out: - if (result != ISC_R_SUCCESS) { - dst_key_free(&key); - } - return result; -} - -isc_result_t -dst_key_buildinternal(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - void *data, isc_mem_t *mctx, dst_key_t **keyp) -{ - dst_key_t *key; - isc_result_t result; - - REQUIRE(dst_initialized == true); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - REQUIRE(data != NULL); - - CHECKALG(alg); - - key = get_key_struct(name, alg, flags, protocol, bits, rdclass, - 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - key->keydata.generic = data; - - result = computeid(key); - if (result != ISC_R_SUCCESS) { - dst_key_free(&key); - return (result); - } - - *keyp = key; - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - const char *engine, const char *label, const char *pin, - isc_mem_t *mctx, dst_key_t **keyp) -{ - dst_key_t *key; - isc_result_t result; - - REQUIRE(dst_initialized == true); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - REQUIRE(label != NULL); - - CHECKALG(alg); - - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - if (key->func->fromlabel == NULL) { - dst_key_free(&key); - return (DST_R_UNSUPPORTEDALG); - } - - result = key->func->fromlabel(key, engine, label, pin); - if (result != ISC_R_SUCCESS) { - dst_key_free(&key); - return (result); - } - - result = computeid(key); - if (result != ISC_R_SUCCESS) { - dst_key_free(&key); - return (result); - } - - *keyp = key; - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_generate(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int param, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_mem_t *mctx, dst_key_t **keyp) -{ - return (dst_key_generate2(name, alg, bits, param, flags, protocol, - rdclass, mctx, keyp, NULL)); -} - -isc_result_t -dst_key_generate2(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int param, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_mem_t *mctx, dst_key_t **keyp, - void (*callback)(int)) -{ - dst_key_t *key; - isc_result_t ret; - - REQUIRE(dst_initialized == true); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - - CHECKALG(alg); - - key = get_key_struct(name, alg, flags, protocol, bits, - rdclass, 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - if (bits == 0) { /*%< NULL KEY */ - key->key_flags |= DNS_KEYTYPE_NOKEY; - *keyp = key; - return (ISC_R_SUCCESS); - } - - if (key->func->generate == NULL) { - dst_key_free(&key); - return (DST_R_UNSUPPORTEDALG); - } - - ret = key->func->generate(key, param, callback); - if (ret != ISC_R_SUCCESS) { - dst_key_free(&key); - return (ret); - } - - ret = computeid(key); - if (ret != ISC_R_SUCCESS) { - dst_key_free(&key); - return (ret); - } - - *keyp = key; - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep) -{ - REQUIRE(VALID_KEY(key)); - REQUIRE(valuep != NULL); - REQUIRE(type <= DST_MAX_NUMERIC); - if (!key->numset[type]) - return (ISC_R_NOTFOUND); - *valuep = key->nums[type]; - return (ISC_R_SUCCESS); -} - -void -dst_key_setnum(dst_key_t *key, int type, uint32_t value) -{ - REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_NUMERIC); - key->nums[type] = value; - key->numset[type] = true; -} - -void -dst_key_unsetnum(dst_key_t *key, int type) -{ - REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_NUMERIC); - key->numset[type] = false; -} - -isc_result_t -dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) { - REQUIRE(VALID_KEY(key)); - REQUIRE(timep != NULL); - REQUIRE(type <= DST_MAX_TIMES); - if (!key->timeset[type]) - return (ISC_R_NOTFOUND); - *timep = key->times[type]; - return (ISC_R_SUCCESS); -} - -void -dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) { - REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_TIMES); - key->times[type] = when; - key->timeset[type] = true; -} - -void -dst_key_unsettime(dst_key_t *key, int type) { - REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_TIMES); - key->timeset[type] = false; -} - -isc_result_t -dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp) { - REQUIRE(VALID_KEY(key)); - REQUIRE(majorp != NULL); - REQUIRE(minorp != NULL); - *majorp = key->fmt_major; - *minorp = key->fmt_minor; - return (ISC_R_SUCCESS); -} - -void -dst_key_setprivateformat(dst_key_t *key, int major, int minor) { - REQUIRE(VALID_KEY(key)); - key->fmt_major = major; - key->fmt_minor = minor; -} - -static bool -comparekeys(const dst_key_t *key1, const dst_key_t *key2, - bool match_revoked_key, - bool (*compare)(const dst_key_t *key1, - const dst_key_t *key2)) -{ - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key1)); - REQUIRE(VALID_KEY(key2)); - - if (key1 == key2) - return (true); - - if (key1->key_alg != key2->key_alg) - return (false); - - if (key1->key_id != key2->key_id) { - if (!match_revoked_key) - return (false); -#ifndef PK11_MD5_DISABLE - if (key1->key_alg == DST_ALG_RSAMD5) - return (false); -#endif - if ((key1->key_flags & DNS_KEYFLAG_REVOKE) == - (key2->key_flags & DNS_KEYFLAG_REVOKE)) - return (false); - if (key1->key_id != key2->key_rid && - key1->key_rid != key2->key_id) - return (false); - } - - if (compare != NULL) - return (compare(key1, key2)); - else - return (false); -} - - -/* - * Compares only the public portion of two keys, by converting them - * both to wire format and comparing the results. - */ -static bool -pub_compare(const dst_key_t *key1, const dst_key_t *key2) { - isc_result_t result; - unsigned char buf1[DST_KEY_MAXSIZE], buf2[DST_KEY_MAXSIZE]; - isc_buffer_t b1, b2; - isc_region_t r1, r2; - - isc_buffer_init(&b1, buf1, sizeof(buf1)); - result = dst_key_todns(key1, &b1); - if (result != ISC_R_SUCCESS) - return (false); - /* Zero out flags. */ - buf1[0] = buf1[1] = 0; - if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) - isc_buffer_subtract(&b1, 2); - - isc_buffer_init(&b2, buf2, sizeof(buf2)); - result = dst_key_todns(key2, &b2); - if (result != ISC_R_SUCCESS) - return (false); - /* Zero out flags. */ - buf2[0] = buf2[1] = 0; - if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) - isc_buffer_subtract(&b2, 2); - - isc_buffer_usedregion(&b1, &r1); - /* Remove extended flags. */ - if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) { - memmove(&buf1[4], &buf1[6], r1.length - 6); - r1.length -= 2; - } - - isc_buffer_usedregion(&b2, &r2); - /* Remove extended flags. */ - if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) { - memmove(&buf2[4], &buf2[6], r2.length - 6); - r2.length -= 2; - } - return (isc_region_compare(&r1, &r2) == 0); -} - -bool -dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) { - return (comparekeys(key1, key2, false, key1->func->compare)); -} - -bool -dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2, - bool match_revoked_key) -{ - return (comparekeys(key1, key2, match_revoked_key, pub_compare)); -} - - -bool -dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key1)); - REQUIRE(VALID_KEY(key2)); - - if (key1 == key2) - return (true); - if (key1->key_alg == key2->key_alg && - key1->func->paramcompare != NULL && - key1->func->paramcompare(key1, key2) == true) - return (true); - else - return (false); -} - -void -dst_key_attach(dst_key_t *source, dst_key_t **target) { - - REQUIRE(dst_initialized == true); - REQUIRE(target != NULL && *target == NULL); - REQUIRE(VALID_KEY(source)); - - isc_refcount_increment(&source->refs, NULL); - *target = source; -} - -void -dst_key_free(dst_key_t **keyp) { - isc_mem_t *mctx; - dst_key_t *key; - unsigned int refs; - - REQUIRE(dst_initialized == true); - REQUIRE(keyp != NULL && VALID_KEY(*keyp)); - - key = *keyp; - mctx = key->mctx; - - isc_refcount_decrement(&key->refs, &refs); - if (refs != 0) - return; - - isc_refcount_destroy(&key->refs); - if (key->keydata.generic != NULL) { - INSIST(key->func->destroy != NULL); - key->func->destroy(key); - } - if (key->engine != NULL) - isc_mem_free(mctx, key->engine); - if (key->label != NULL) - isc_mem_free(mctx, key->label); - dns_name_free(key->key_name, mctx); - isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); - if (key->key_tkeytoken) { - isc_buffer_free(&key->key_tkeytoken); - } - isc_safe_memwipe(key, sizeof(*key)); - isc_mem_putanddetach(&mctx, key, sizeof(*key)); - *keyp = NULL; -} - -bool -dst_key_isprivate(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - INSIST(key->func->isprivate != NULL); - return (key->func->isprivate(key)); -} - -isc_result_t -dst_key_buildfilename(const dst_key_t *key, int type, - const char *directory, isc_buffer_t *out) { - - REQUIRE(VALID_KEY(key)); - REQUIRE(type == DST_TYPE_PRIVATE || type == DST_TYPE_PUBLIC || - type == 0); - - return (buildfilename(key->key_name, key->key_id, key->key_alg, - type, directory, out)); -} - -isc_result_t -dst_key_sigsize(const dst_key_t *key, unsigned int *n) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(n != NULL); - - /* XXXVIX this switch statement is too sparse to gen a jump table. */ - switch (key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - case DST_ALG_RSASHA256: - case DST_ALG_RSASHA512: - *n = (key->key_size + 7) / 8; - break; -#ifndef PK11_DSA_DISABLE - case DST_ALG_DSA: - case DST_ALG_NSEC3DSA: - *n = DNS_SIG_DSASIGSIZE; - break; -#endif - case DST_ALG_ECCGOST: - *n = DNS_SIG_GOSTSIGSIZE; - break; - case DST_ALG_ECDSA256: - *n = DNS_SIG_ECDSA256SIZE; - break; - case DST_ALG_ECDSA384: - *n = DNS_SIG_ECDSA384SIZE; - break; - case DST_ALG_ED25519: - *n = DNS_SIG_ED25519SIZE; - break; - case DST_ALG_ED448: - *n = DNS_SIG_ED448SIZE; - break; -#ifndef PK11_MD5_DISABLE - case DST_ALG_HMACMD5: - *n = 16; - break; -#endif - case DST_ALG_HMACSHA1: - *n = ISC_SHA1_DIGESTLENGTH; - break; - case DST_ALG_HMACSHA224: - *n = ISC_SHA224_DIGESTLENGTH; - break; - case DST_ALG_HMACSHA256: - *n = ISC_SHA256_DIGESTLENGTH; - break; - case DST_ALG_HMACSHA384: - *n = ISC_SHA384_DIGESTLENGTH; - break; - case DST_ALG_HMACSHA512: - *n = ISC_SHA512_DIGESTLENGTH; - break; - case DST_ALG_GSSAPI: - *n = 128; /*%< XXX */ - break; -#ifndef PK11_DH_DISABLE - case DST_ALG_DH: -#endif - default: - return (DST_R_UNSUPPORTEDALG); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -dst_key_secretsize(const dst_key_t *key, unsigned int *n) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - REQUIRE(n != NULL); - -#ifndef PK11_DH_DISABLE - if (key->key_alg == DST_ALG_DH) - *n = (key->key_size + 7) / 8; - else -#endif - return (DST_R_UNSUPPORTEDALG); -#ifndef PK11_DH_DISABLE - return (ISC_R_SUCCESS); -#endif -} - -/*% - * Set the flags on a key, then recompute the key ID - */ -isc_result_t -dst_key_setflags(dst_key_t *key, uint32_t flags) { - REQUIRE(VALID_KEY(key)); - key->key_flags = flags; - return (computeid(key)); -} - -void -dst_key_format(const dst_key_t *key, char *cp, unsigned int size) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_NAME_FORMATSIZE]; - - dns_name_format(dst_key_name(key), namestr, sizeof(namestr)); - dns_secalg_format((dns_secalg_t) dst_key_alg(key), algstr, - sizeof(algstr)); - snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key)); -} - -isc_result_t -dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { - - REQUIRE(buffer != NULL && *buffer == NULL); - REQUIRE(length != NULL && *length == 0); - REQUIRE(VALID_KEY(key)); - - if (key->func->dump == NULL) - return (ISC_R_NOTIMPLEMENTED); - return (key->func->dump(key, mctx, buffer, length)); -} - -isc_result_t -dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - isc_mem_t *mctx, const char *keystr, dst_key_t **keyp) -{ - isc_result_t result; - dst_key_t *key; - - REQUIRE(dst_initialized == true); - REQUIRE(keyp != NULL && *keyp == NULL); - - if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) - return (DST_R_UNSUPPORTEDALG); - - if (dst_t_func[alg]->restore == NULL) - return (ISC_R_NOTIMPLEMENTED); - - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - result = (dst_t_func[alg]->restore)(key, keystr); - if (result == ISC_R_SUCCESS) - *keyp = key; - else - dst_key_free(&key); - - return (result); -} - -/*** - *** Static methods - ***/ - -/*% - * Allocates a key structure and fills in some of the fields. - */ -static dst_key_t * -get_key_struct(dns_name_t *name, unsigned int alg, - unsigned int flags, unsigned int protocol, - unsigned int bits, dns_rdataclass_t rdclass, - dns_ttl_t ttl, isc_mem_t *mctx) -{ - dst_key_t *key; - isc_result_t result; - int i; - - key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t)); - if (key == NULL) - return (NULL); - - memset(key, 0, sizeof(dst_key_t)); - - key->key_name = isc_mem_get(mctx, sizeof(dns_name_t)); - if (key->key_name == NULL) { - isc_mem_put(mctx, key, sizeof(dst_key_t)); - return (NULL); - } - - dns_name_init(key->key_name, NULL); - result = dns_name_dup(name, mctx, key->key_name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); - isc_mem_put(mctx, key, sizeof(dst_key_t)); - return (NULL); - } - - result = isc_refcount_init(&key->refs, 1); - if (result != ISC_R_SUCCESS) { - dns_name_free(key->key_name, mctx); - isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); - isc_mem_put(mctx, key, sizeof(dst_key_t)); - return (NULL); - } - isc_mem_attach(mctx, &key->mctx); - key->key_alg = alg; - key->key_flags = flags; - key->key_proto = protocol; - key->keydata.generic = NULL; - key->key_size = bits; - key->key_class = rdclass; - key->key_ttl = ttl; - key->func = dst_t_func[alg]; - key->fmt_major = 0; - key->fmt_minor = 0; - for (i = 0; i < (DST_MAX_TIMES + 1); i++) { - key->times[i] = 0; - key->timeset[i] = false; - } - key->inactive = false; - key->magic = KEY_MAGIC; - return (key); -} - -bool -dst_key_inactive(const dst_key_t *key) { - - REQUIRE(VALID_KEY(key)); - - return (key->inactive); -} - -void -dst_key_setinactive(dst_key_t *key, bool inactive) { - - REQUIRE(VALID_KEY(key)); - - key->inactive = inactive; -} - -/*% - * Reads a public key from disk - */ -isc_result_t -dst_key_read_public(const char *filename, int type, - isc_mem_t *mctx, dst_key_t **keyp) -{ - u_char rdatabuf[DST_KEY_MAXSIZE]; - isc_buffer_t b; - dns_fixedname_t name; - isc_lex_t *lex = NULL; - isc_token_t token; - isc_result_t ret; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned int opt = ISC_LEXOPT_DNSMULTILINE; - dns_rdataclass_t rdclass = dns_rdataclass_in; - isc_lexspecials_t specials; - uint32_t ttl = 0; - isc_result_t result; - dns_rdatatype_t keytype; - - /* - * Open the file and read its formatted contents - * File format: - * domain.name [ttl] [class] [KEY|DNSKEY] - */ - - /* 1500 should be large enough for any key */ - ret = isc_lex_create(mctx, 1500, &lex); - if (ret != ISC_R_SUCCESS) - goto cleanup; - - memset(specials, 0, sizeof(specials)); - specials['('] = 1; - specials[')'] = 1; - specials['"'] = 1; - isc_lex_setspecials(lex, specials); - isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); - - ret = isc_lex_openfile(lex, filename); - if (ret != ISC_R_SUCCESS) - goto cleanup; - -#define NEXTTOKEN(lex, opt, token) { \ - ret = isc_lex_gettoken(lex, opt, token); \ - if (ret != ISC_R_SUCCESS) \ - goto cleanup; \ - } - -#define BADTOKEN() { \ - ret = ISC_R_UNEXPECTEDTOKEN; \ - goto cleanup; \ - } - - /* Read the domain name */ - NEXTTOKEN(lex, opt, &token); - if (token.type != isc_tokentype_string) - BADTOKEN(); - - /* - * We don't support "@" in .key files. - */ - if (!strcmp(DST_AS_STR(token), "@")) - BADTOKEN(); - - dns_fixedname_init(&name); - isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token))); - isc_buffer_add(&b, strlen(DST_AS_STR(token))); - ret = dns_name_fromtext(dns_fixedname_name(&name), &b, dns_rootname, - 0, NULL); - if (ret != ISC_R_SUCCESS) - goto cleanup; - - /* Read the next word: either TTL, class, or 'KEY' */ - NEXTTOKEN(lex, opt, &token); - - if (token.type != isc_tokentype_string) - BADTOKEN(); - - /* If it's a TTL, read the next one */ - result = dns_ttl_fromtext(&token.value.as_textregion, &ttl); - if (result == ISC_R_SUCCESS) - NEXTTOKEN(lex, opt, &token); - - if (token.type != isc_tokentype_string) - BADTOKEN(); - - ret = dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion); - if (ret == ISC_R_SUCCESS) - NEXTTOKEN(lex, opt, &token); - - if (token.type != isc_tokentype_string) - BADTOKEN(); - - if (strcasecmp(DST_AS_STR(token), "DNSKEY") == 0) - keytype = dns_rdatatype_dnskey; - else if (strcasecmp(DST_AS_STR(token), "KEY") == 0) - keytype = dns_rdatatype_key; /*%< SIG(0), TKEY */ - else - BADTOKEN(); - - if (((type & DST_TYPE_KEY) != 0 && keytype != dns_rdatatype_key) || - ((type & DST_TYPE_KEY) == 0 && keytype != dns_rdatatype_dnskey)) { - ret = DST_R_BADKEYTYPE; - goto cleanup; - } - - isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf)); - ret = dns_rdata_fromtext(&rdata, rdclass, keytype, lex, NULL, - false, mctx, &b, NULL); - if (ret != ISC_R_SUCCESS) - goto cleanup; - - ret = dst_key_fromdns(dns_fixedname_name(&name), rdclass, &b, mctx, - keyp); - if (ret != ISC_R_SUCCESS) - goto cleanup; - - dst_key_setttl(*keyp, ttl); - - cleanup: - if (lex != NULL) - isc_lex_destroy(&lex); - return (ret); -} - -static bool -issymmetric(const dst_key_t *key) { - REQUIRE(dst_initialized == true); - REQUIRE(VALID_KEY(key)); - - /* XXXVIX this switch statement is too sparse to gen a jump table. */ - switch (key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - case DST_ALG_RSASHA256: - case DST_ALG_RSASHA512: -#ifndef PK11_DSA_DISABLE - case DST_ALG_DSA: - case DST_ALG_NSEC3DSA: -#endif -#ifndef PK11_DH_DISABLE - case DST_ALG_DH: -#endif - case DST_ALG_ECCGOST: - case DST_ALG_ECDSA256: - case DST_ALG_ECDSA384: - case DST_ALG_ED25519: - case DST_ALG_ED448: - return (false); -#ifndef PK11_MD5_DISABLE - case DST_ALG_HMACMD5: -#endif - case DST_ALG_HMACSHA1: - case DST_ALG_HMACSHA224: - case DST_ALG_HMACSHA256: - case DST_ALG_HMACSHA384: - case DST_ALG_HMACSHA512: - case DST_ALG_GSSAPI: - return (true); - default: - return (false); - } -} - -/*% - * Write key timing metadata to a file pointer, preceded by 'tag' - */ -static void -printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) { - isc_result_t result; -#ifdef ISC_PLATFORM_USETHREADS - char output[26]; /* Minimum buffer as per ctime_r() specification. */ -#else - const char *output; -#endif - isc_stdtime_t when; - time_t t; - char utc[sizeof("YYYYMMDDHHSSMM")]; - isc_buffer_t b; - isc_region_t r; - - result = dst_key_gettime(key, type, &when); - if (result == ISC_R_NOTFOUND) - return; - - /* time_t and isc_stdtime_t might be different sizes */ - t = when; -#ifdef ISC_PLATFORM_USETHREADS -#ifdef WIN32 - if (ctime_s(output, sizeof(output), &t) != 0) - goto error; -#else - if (ctime_r(&t, output) == NULL) - goto error; -#endif -#else - output = ctime(&t); -#endif - - isc_buffer_init(&b, utc, sizeof(utc)); - result = dns_time32_totext(when, &b); - if (result != ISC_R_SUCCESS) - goto error; - - isc_buffer_usedregion(&b, &r); - fprintf(stream, "%s: %.*s (%.*s)\n", tag, (int)r.length, r.base, - (int)strlen(output) - 1, output); - return; - - error: - fprintf(stream, "%s: (set, unable to display)\n", tag); -} - -/*% - * Writes a public key to disk in DNS format. - */ -static isc_result_t -write_public_key(const dst_key_t *key, int type, const char *directory) { - FILE *fp; - isc_buffer_t keyb, textb, fileb, classb; - isc_region_t r; - char filename[NAME_MAX]; - unsigned char key_array[DST_KEY_MAXSIZE]; - char text_array[DST_KEY_MAXTEXTSIZE]; - char class_array[10]; - isc_result_t ret; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_fsaccess_t access; - - REQUIRE(VALID_KEY(key)); - - isc_buffer_init(&keyb, key_array, sizeof(key_array)); - isc_buffer_init(&textb, text_array, sizeof(text_array)); - isc_buffer_init(&classb, class_array, sizeof(class_array)); - - ret = dst_key_todns(key, &keyb); - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_usedregion(&keyb, &r); - dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r); - - ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); - if (ret != ISC_R_SUCCESS) - return (DST_R_INVALIDPUBLICKEY); - - ret = dns_rdataclass_totext(key->key_class, &classb); - if (ret != ISC_R_SUCCESS) - return (DST_R_INVALIDPUBLICKEY); - - /* - * Make the filename. - */ - isc_buffer_init(&fileb, filename, sizeof(filename)); - ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb); - if (ret != ISC_R_SUCCESS) - return (ret); - - /* - * Create public key file. - */ - if ((fp = fopen(filename, "w")) == NULL) - return (DST_R_WRITEERROR); - - if (issymmetric(key)) { - access = 0; - isc_fsaccess_add(ISC_FSACCESS_OWNER, - ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, - &access); - (void)isc_fsaccess_set(filename, access); - } - - /* Write key information in comments */ - if ((type & DST_TYPE_KEY) == 0) { - fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ", - (key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ? - "revoked " : - "", - (key->key_flags & DNS_KEYFLAG_KSK) != 0 ? - "key" : - "zone", - key->key_id); - ret = dns_name_print(key->key_name, fp); - if (ret != ISC_R_SUCCESS) { - fclose(fp); - return (ret); - } - fputc('\n', fp); - - printtime(key, DST_TIME_CREATED, "; Created", fp); - printtime(key, DST_TIME_PUBLISH, "; Publish", fp); - printtime(key, DST_TIME_ACTIVATE, "; Activate", fp); - printtime(key, DST_TIME_REVOKE, "; Revoke", fp); - printtime(key, DST_TIME_INACTIVE, "; Inactive", fp); - printtime(key, DST_TIME_DELETE, "; Delete", fp); - printtime(key, DST_TIME_SYNCPUBLISH , "; SyncPublish", fp); - printtime(key, DST_TIME_SYNCDELETE , "; SyncDelete", fp); - } - - /* Now print the actual key */ - ret = dns_name_print(key->key_name, fp); - fprintf(fp, " "); - - if (key->key_ttl != 0) - fprintf(fp, "%u ", key->key_ttl); - - isc_buffer_usedregion(&classb, &r); - if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) - ret = DST_R_WRITEERROR; - - if ((type & DST_TYPE_KEY) != 0) - fprintf(fp, " KEY "); - else - fprintf(fp, " DNSKEY "); - - isc_buffer_usedregion(&textb, &r); - if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) - ret = DST_R_WRITEERROR; - - fputc('\n', fp); - fflush(fp); - if (ferror(fp)) - ret = DST_R_WRITEERROR; - fclose(fp); - - return (ret); -} - -static isc_result_t -buildfilename(dns_name_t *name, dns_keytag_t id, - unsigned int alg, unsigned int type, - const char *directory, isc_buffer_t *out) -{ - const char *suffix = ""; - unsigned int len; - isc_result_t result; - - REQUIRE(out != NULL); - if ((type & DST_TYPE_PRIVATE) != 0) - suffix = ".private"; - else if (type == DST_TYPE_PUBLIC) - suffix = ".key"; - if (directory != NULL) { - if (isc_buffer_availablelength(out) < strlen(directory)) - return (ISC_R_NOSPACE); - isc_buffer_putstr(out, directory); - if (strlen(directory) > 0U && - directory[strlen(directory) - 1] != '/') - isc_buffer_putstr(out, "/"); - } - if (isc_buffer_availablelength(out) < 1) - return (ISC_R_NOSPACE); - isc_buffer_putstr(out, "K"); - result = dns_name_tofilenametext(name, false, out); - if (result != ISC_R_SUCCESS) - return (result); - len = 1 + 3 + 1 + 5 + strlen(suffix) + 1; - if (isc_buffer_availablelength(out) < len) - return (ISC_R_NOSPACE); - snprintf((char *) isc_buffer_used(out), - (int)isc_buffer_availablelength(out), - "+%03u+%05d%s", alg, id, suffix); - isc_buffer_add(out, len); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -computeid(dst_key_t *key) { - isc_buffer_t dnsbuf; - unsigned char dns_array[DST_KEY_MAXSIZE]; - isc_region_t r; - isc_result_t ret; - - isc_buffer_init(&dnsbuf, dns_array, sizeof(dns_array)); - ret = dst_key_todns(key, &dnsbuf); - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_usedregion(&dnsbuf, &r); - key->key_id = dst_region_computeid(&r, key->key_alg); - key->key_rid = dst_region_computerid(&r, key->key_alg); - return (ISC_R_SUCCESS); -} - -static isc_result_t -frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) -{ - dst_key_t *key; - isc_result_t ret; - - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(source != NULL); - REQUIRE(mctx != NULL); - REQUIRE(keyp != NULL && *keyp == NULL); - - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); - if (key == NULL) - return (ISC_R_NOMEMORY); - - if (isc_buffer_remaininglength(source) > 0) { - ret = algorithm_status(alg); - if (ret != ISC_R_SUCCESS) { - dst_key_free(&key); - return (ret); - } - if (key->func->fromdns == NULL) { - dst_key_free(&key); - return (DST_R_UNSUPPORTEDALG); - } - - ret = key->func->fromdns(key, source); - if (ret != ISC_R_SUCCESS) { - dst_key_free(&key); - return (ret); - } - } - - *keyp = key; - return (ISC_R_SUCCESS); -} - -static isc_result_t -algorithm_status(unsigned int alg) { - REQUIRE(dst_initialized == true); - - if (dst_algorithm_supported(alg)) - return (ISC_R_SUCCESS); -#if !defined(OPENSSL) && !defined(PKCS11CRYPTO) - if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || - alg == DST_ALG_DSA || alg == DST_ALG_DH || - alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || - alg == DST_ALG_NSEC3RSASHA1 || - alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 || - alg == DST_ALG_ECCGOST || - alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384 || - alg == DST_ALG_ED25519 || alg == DST_ALG_ED448) - return (DST_R_NOCRYPTO); -#endif - return (DST_R_UNSUPPORTEDALG); -} - -static isc_result_t -addsuffix(char *filename, int len, const char *odirname, - const char *ofilename, const char *suffix) -{ - int olen = strlen(ofilename); - int n; - - if (olen > 1 && ofilename[olen - 1] == '.') - olen -= 1; - else if (olen > 8 && strcmp(ofilename + olen - 8, ".private") == 0) - olen -= 8; - else if (olen > 4 && strcmp(ofilename + olen - 4, ".key") == 0) - olen -= 4; - - if (odirname == NULL) - n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix); - else - n = snprintf(filename, len, "%s/%.*s%s", - odirname, olen, ofilename, suffix); - if (n < 0) - return (ISC_R_FAILURE); - if (n >= len) - return (ISC_R_NOSPACE); - return (ISC_R_SUCCESS); -} - -isc_result_t -dst__entropy_getdata(void *buf, unsigned int len, bool pseudo) { - unsigned int flags = dst_entropy_flags; - - if (dst_entropy_pool == NULL) - return (ISC_R_FAILURE); - - if (len == 0) - return (ISC_R_SUCCESS); - -#ifdef PKCS11CRYPTO - UNUSED(pseudo); - UNUSED(flags); - return (pk11_rand_bytes(buf, len)); -#else /* PKCS11CRYPTO */ - if (pseudo) - flags &= ~ISC_ENTROPY_GOODONLY; - else - flags |= ISC_ENTROPY_BLOCKING; -#ifdef ISC_PLATFORM_CRYPTORANDOM - /* get entropy directly from crypto provider */ - return (dst_random_getdata(buf, len, NULL, flags)); -#else - /* get entropy from entropy source or hook function */ - return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags)); -#endif /* ISC_PLATFORM_CRYPTORANDOM */ -#endif /* PKCS11CRYPTO */ -} - -unsigned int -dst__entropy_status(void) { -#if !defined(PKCS11CRYPTO) && !defined(ISC_PLATFORM_CRYPTORANDOM) -#ifdef GSSAPI - unsigned int flags = dst_entropy_flags; - isc_result_t ret; - unsigned char buf[32]; - static bool first = true; - - if (dst_entropy_pool == NULL) - return (0); - - if (first) { - /* Someone believes RAND_status() initializes the PRNG */ - flags &= ~ISC_ENTROPY_GOODONLY; - ret = isc_entropy_getdata(dst_entropy_pool, buf, - sizeof(buf), NULL, flags); - INSIST(ret == ISC_R_SUCCESS); - isc_entropy_putdata(dst_entropy_pool, buf, - sizeof(buf), 2 * sizeof(buf)); - first = false; - } -#endif - return (isc_entropy_status(dst_entropy_pool)); -#else - /* Doesn't matter as it is not used in this case. */ - return (0); -#endif -} - -isc_buffer_t * -dst_key_tkeytoken(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_tkeytoken); -} diff --git a/lib/dns-pkcs11/dst_gost.h b/lib/dns-pkcs11/dst_gost.h deleted file mode 100644 index 6363074..0000000 --- a/lib/dns-pkcs11/dst_gost.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DST_GOST_H -#define DST_GOST_H 1 - -#include -#include -#include - -#define ISC_GOST_DIGESTLENGTH 32U - -#ifdef HAVE_OPENSSL_GOST -#include - -typedef struct { - EVP_MD_CTX *ctx; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - EVP_MD_CTX _ctx; -#endif -} isc_gost_t; - -#endif -#ifdef HAVE_PKCS11_GOST -#include - -typedef pk11_context_t isc_gost_t; -#endif - -ISC_LANG_BEGINDECLS - -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - -isc_result_t -isc_gost_init(isc_gost_t *ctx); - -void -isc_gost_invalidate(isc_gost_t *ctx); - -isc_result_t -isc_gost_update(isc_gost_t *ctx, const unsigned char *data, unsigned int len); - -isc_result_t -isc_gost_final(isc_gost_t *ctx, unsigned char *digest); - -ISC_LANG_ENDDECLS - -#endif /* HAVE_OPENSSL_GOST || HAVE_PKCS11_GOST */ - -#endif /* DST_GOST_H */ diff --git a/lib/dns-pkcs11/dst_internal.h b/lib/dns-pkcs11/dst_internal.h deleted file mode 100644 index 30468e6..0000000 --- a/lib/dns-pkcs11/dst_internal.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - - -#ifndef DST_DST_INTERNAL_H -#define DST_DST_INTERNAL_H 1 - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#ifdef OPENSSL -#ifndef PK11_DH_DISABLE -#include -#endif -#ifndef PK11_DSA_DISABLE -#include -#endif -#include -#include -#include -#include -#endif -#if PKCS11CRYPTO -#include -#endif - -ISC_LANG_BEGINDECLS - -#define KEY_MAGIC ISC_MAGIC('D','S','T','K') -#define CTX_MAGIC ISC_MAGIC('D','S','T','C') - -#define VALID_KEY(x) ISC_MAGIC_VALID(x, KEY_MAGIC) -#define VALID_CTX(x) ISC_MAGIC_VALID(x, CTX_MAGIC) - -LIBDNS_EXTERNAL_DATA extern isc_mem_t *dst__memory_pool; - -/*** - *** Types - ***/ - -typedef struct dst_func dst_func_t; - -#ifndef PK11_MD5_DISABLE -typedef struct dst_hmacmd5_key dst_hmacmd5_key_t; -#endif -typedef struct dst_hmacsha1_key dst_hmacsha1_key_t; -typedef struct dst_hmacsha224_key dst_hmacsha224_key_t; -typedef struct dst_hmacsha256_key dst_hmacsha256_key_t; -typedef struct dst_hmacsha384_key dst_hmacsha384_key_t; -typedef struct dst_hmacsha512_key dst_hmacsha512_key_t; - -/*% - * Indicate whether a DST context will be used for signing - * or for verification - */ -typedef enum { DO_SIGN, DO_VERIFY } dst_use_t; - -/*% DST Key Structure */ -struct dst_key { - unsigned int magic; - isc_refcount_t refs; - dns_name_t * key_name; /*%< name of the key */ - unsigned int key_size; /*%< size of the key in bits */ - unsigned int key_proto; /*%< protocols this key is used for */ - unsigned int key_alg; /*%< algorithm of the key */ - uint32_t key_flags; /*%< flags of the public key */ - uint16_t key_id; /*%< identifier of the key */ - uint16_t key_rid; /*%< identifier of the key when - revoked */ - uint16_t key_bits; /*%< hmac digest bits */ - dns_rdataclass_t key_class; /*%< class of the key record */ - dns_ttl_t key_ttl; /*%< default/initial dnskey ttl */ - isc_mem_t *mctx; /*%< memory context */ - char *engine; /*%< engine name (HSM) */ - char *label; /*%< engine label (HSM) */ - union { - void *generic; - gss_ctx_id_t gssctx; -#ifdef OPENSSL -#if !defined(USE_EVP) || !USE_EVP - RSA *rsa; -#endif -#ifndef PK11_DSA_DISABLE - DSA *dsa; -#endif -#ifndef PK11_DH_DISABLE - DH *dh; -#endif - EVP_PKEY *pkey; -#elif PKCS11CRYPTO - pk11_object_t *pkey; -#endif -#ifndef PK11_MD5_DISABLE - dst_hmacmd5_key_t *hmacmd5; -#endif - dst_hmacsha1_key_t *hmacsha1; - dst_hmacsha224_key_t *hmacsha224; - dst_hmacsha256_key_t *hmacsha256; - dst_hmacsha384_key_t *hmacsha384; - dst_hmacsha512_key_t *hmacsha512; - - } keydata; /*%< pointer to key in crypto pkg fmt */ - - isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< timing metadata */ - bool timeset[DST_MAX_TIMES + 1]; /*%< data set? */ - isc_stdtime_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */ - bool numset[DST_MAX_NUMERIC + 1]; /*%< data set? */ - bool inactive; /*%< private key not present as it is - inactive */ - bool external; /*%< external key */ - - int fmt_major; /*%< private key format, major version */ - int fmt_minor; /*%< private key format, minor version */ - - dst_func_t * func; /*%< crypto package specific functions */ - isc_buffer_t *key_tkeytoken; /*%< TKEY token data */ -}; - -struct dst_context { - unsigned int magic; - dst_use_t use; - dst_key_t *key; - isc_mem_t *mctx; - isc_logcategory_t *category; - union { - void *generic; - dst_gssapi_signverifyctx_t *gssctx; -#ifndef PK11_MD5_DISABLE - isc_md5_t *md5ctx; -#endif - isc_sha1_t *sha1ctx; - isc_sha256_t *sha256ctx; - isc_sha512_t *sha512ctx; -#ifndef PK11_MD5_DISABLE - isc_hmacmd5_t *hmacmd5ctx; -#endif - isc_hmacsha1_t *hmacsha1ctx; - isc_hmacsha224_t *hmacsha224ctx; - isc_hmacsha256_t *hmacsha256ctx; - isc_hmacsha384_t *hmacsha384ctx; - isc_hmacsha512_t *hmacsha512ctx; -#ifdef OPENSSL - EVP_MD_CTX *evp_md_ctx; -#elif PKCS11CRYPTO - pk11_context_t *pk11_ctx; -#endif - } ctxdata; -}; - -struct dst_func { - /* - * Context functions - */ - isc_result_t (*createctx)(dst_key_t *key, dst_context_t *dctx); - isc_result_t (*createctx2)(dst_key_t *key, int maxbits, - dst_context_t *dctx); - void (*destroyctx)(dst_context_t *dctx); - isc_result_t (*adddata)(dst_context_t *dctx, const isc_region_t *data); - - /* - * Key operations - */ - isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig); - isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig); - isc_result_t (*verify2)(dst_context_t *dctx, int maxbits, - const isc_region_t *sig); - isc_result_t (*computesecret)(const dst_key_t *pub, - const dst_key_t *priv, - isc_buffer_t *secret); - bool (*compare)(const dst_key_t *key1, const dst_key_t *key2); - bool (*paramcompare)(const dst_key_t *key1, - const dst_key_t *key2); - isc_result_t (*generate)(dst_key_t *key, int parms, - void (*callback)(int)); - bool (*isprivate)(const dst_key_t *key); - void (*destroy)(dst_key_t *key); - - /* conversion functions */ - isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data); - isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data); - isc_result_t (*tofile)(const dst_key_t *key, const char *directory); - isc_result_t (*parse)(dst_key_t *key, - isc_lex_t *lexer, - dst_key_t *pub); - - /* cleanup */ - void (*cleanup)(void); - - isc_result_t (*fromlabel)(dst_key_t *key, const char *engine, - const char *label, const char *pin); - isc_result_t (*dump)(dst_key_t *key, isc_mem_t *mctx, char **buffer, - int *length); - isc_result_t (*restore)(dst_key_t *key, const char *keystr); -}; - -/*% - * Initializers - */ -isc_result_t dst__openssl_init(const char *engine); -#define dst__pkcs11_init pk11_initialize - -#ifndef PK11_MD5_DISABLE -isc_result_t dst__hmacmd5_init(struct dst_func **funcp); -#endif -isc_result_t dst__hmacsha1_init(struct dst_func **funcp); -isc_result_t dst__hmacsha224_init(struct dst_func **funcp); -isc_result_t dst__hmacsha256_init(struct dst_func **funcp); -isc_result_t dst__hmacsha384_init(struct dst_func **funcp); -isc_result_t dst__hmacsha512_init(struct dst_func **funcp); -isc_result_t dst__opensslrsa_init(struct dst_func **funcp, - unsigned char algorithm); -isc_result_t dst__pkcs11rsa_init(struct dst_func **funcp, - unsigned char algorithm); -#ifndef PK11_DSA_DISABLE -isc_result_t dst__openssldsa_init(struct dst_func **funcp); -isc_result_t dst__pkcs11dsa_init(struct dst_func **funcp); -#endif -#ifndef PK11_DH_DISABLE -isc_result_t dst__openssldh_init(struct dst_func **funcp); -isc_result_t dst__pkcs11dh_init(struct dst_func **funcp); -#endif -isc_result_t dst__gssapi_init(struct dst_func **funcp); -#ifdef HAVE_OPENSSL_ECDSA -isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); -#endif -#if defined(HAVE_OPENSSL_ED25519) || defined(HAVE_OPENSSL_ED448) -isc_result_t dst__openssleddsa_init(struct dst_func **funcp); -#endif -#ifdef HAVE_PKCS11_ECDSA -isc_result_t dst__pkcs11ecdsa_init(struct dst_func **funcp); -#endif -#if defined(HAVE_PKCS11_ED25519) || defined(HAVE_PKCS11_ED448) -isc_result_t dst__pkcs11eddsa_init(struct dst_func **funcp); -#endif -#ifdef HAVE_OPENSSL_GOST -isc_result_t dst__opensslgost_init(struct dst_func **funcp); -#endif -#ifdef HAVE_PKCS11_GOST -isc_result_t dst__pkcs11gost_init(struct dst_func **funcp); -#endif - -/*% - * Destructors - */ -void dst__openssl_destroy(void); -#define dst__pkcs11_destroy pk11_finalize - -/*% - * Memory allocators using the DST memory pool. - */ -void * dst__mem_alloc(size_t size); -void dst__mem_free(void *ptr); -void * dst__mem_realloc(void *ptr, size_t size); - -/*% - * Entropy retriever using the DST entropy pool. - */ -isc_result_t dst__entropy_getdata(void *buf, unsigned int len, - bool pseudo); - -/* - * Entropy status hook. - */ -unsigned int dst__entropy_status(void); - -ISC_LANG_ENDDECLS - -#endif /* DST_DST_INTERNAL_H */ -/*! \file */ diff --git a/lib/dns-pkcs11/dst_lib.c b/lib/dns-pkcs11/dst_lib.c deleted file mode 100644 index 52beafb..0000000 --- a/lib/dns-pkcs11/dst_lib.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include - -#include - -/*** - *** Globals - ***/ - -LIBDNS_EXTERNAL_DATA isc_msgcat_t * dst_msgcat = NULL; - - -/*** - *** Private - ***/ - -static isc_once_t msgcat_once = ISC_ONCE_INIT; - - -/*** - *** Functions - ***/ - -static void -open_msgcat(void) { - isc_msgcat_open("libdst.cat", &dst_msgcat); -} - -void -dst_lib_initmsgcat(void) { - - /* - * Initialize the DST library's message catalog, dst_msgcat, if it - * has not already been initialized. - */ - - RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); -} diff --git a/lib/dns-pkcs11/dst_openssl.h b/lib/dns-pkcs11/dst_openssl.h deleted file mode 100644 index 2b2dcc7..0000000 --- a/lib/dns-pkcs11/dst_openssl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DST_OPENSSL_H -#define DST_OPENSSL_H 1 - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -/* - * These are new in OpenSSL 1.1.0. BN_GENCB _cb needs to be declared in - * the function like this before the BN_GENCB_new call: - * - * #if OPENSSL_VERSION_NUMBER < 0x10100000L - * _cb; - * #endif - */ -#define BN_GENCB_free(x) ((void)0) -#define BN_GENCB_new() (&_cb) -#define BN_GENCB_get_arg(x) ((x)->arg) -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L -/* - * EVP_dss1() is a version of EVP_sha1() that was needed prior to - * 1.1.0 because there was a link between digests and signing algorithms; - * the link has been eliminated and EVP_sha1() can be used now instead. - */ -#define EVP_dss1 EVP_sha1 -#endif - -ISC_LANG_BEGINDECLS - -isc_result_t -dst__openssl_toresult(isc_result_t fallback); - -isc_result_t -dst__openssl_toresult2(const char *funcname, isc_result_t fallback); - -isc_result_t -dst__openssl_toresult3(isc_logcategory_t *category, - const char *funcname, isc_result_t fallback); - -#if !defined(OPENSSL_NO_ENGINE) -ENGINE * -dst__openssl_getengine(const char *engine); -#else -#define dst__openssl_getengine(x) NULL -#endif - -ISC_LANG_ENDDECLS - -#endif /* DST_OPENSSL_H */ -/*! \file */ diff --git a/lib/dns-pkcs11/dst_parse.c b/lib/dns-pkcs11/dst_parse.c deleted file mode 100644 index 42cdd4c..0000000 --- a/lib/dns-pkcs11/dst_parse.c +++ /dev/null @@ -1,866 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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 - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst/result.h" - -#define DST_AS_STR(t) ((t).value.as_textregion.base) - -#define PRIVATE_KEY_STR "Private-key-format:" -#define ALGORITHM_STR "Algorithm:" - -#define TIMING_NTAGS (DST_MAX_TIMES + 1) -static const char *timetags[TIMING_NTAGS] = { - "Created:", - "Publish:", - "Activate:", - "Revoke:", - "Inactive:", - "Delete:", - "DSPublish:", - "SyncPublish:", - "SyncDelete:" -}; - -#define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1) -static const char *numerictags[NUMERIC_NTAGS] = { - "Predecessor:", - "Successor:", - "MaxTTL:", - "RollPeriod:" -}; - -struct parse_map { - const int value; - const char *tag; -}; - -static struct parse_map map[] = { - {TAG_RSA_MODULUS, "Modulus:"}, - {TAG_RSA_PUBLICEXPONENT, "PublicExponent:"}, - {TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"}, - {TAG_RSA_PRIME1, "Prime1:"}, - {TAG_RSA_PRIME2, "Prime2:"}, - {TAG_RSA_EXPONENT1, "Exponent1:"}, - {TAG_RSA_EXPONENT2, "Exponent2:"}, - {TAG_RSA_COEFFICIENT, "Coefficient:"}, - {TAG_RSA_ENGINE, "Engine:" }, - {TAG_RSA_LABEL, "Label:" }, - -#ifndef PK11_DH_DISABLE - {TAG_DH_PRIME, "Prime(p):"}, - {TAG_DH_GENERATOR, "Generator(g):"}, - {TAG_DH_PRIVATE, "Private_value(x):"}, - {TAG_DH_PUBLIC, "Public_value(y):"}, -#endif - -#ifndef PK11_DSA_DISABLE - {TAG_DSA_PRIME, "Prime(p):"}, - {TAG_DSA_SUBPRIME, "Subprime(q):"}, - {TAG_DSA_BASE, "Base(g):"}, - {TAG_DSA_PRIVATE, "Private_value(x):"}, - {TAG_DSA_PUBLIC, "Public_value(y):"}, -#endif - - {TAG_GOST_PRIVASN1, "GostAsn1:"}, - {TAG_GOST_PRIVRAW, "PrivateKey:"}, - - {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"}, - {TAG_ECDSA_ENGINE, "Engine:" }, - {TAG_ECDSA_LABEL, "Label:" }, - - {TAG_EDDSA_PRIVATEKEY, "PrivateKey:"}, - {TAG_EDDSA_ENGINE, "Engine:" }, - {TAG_EDDSA_LABEL, "Label:" }, - -#ifndef PK11_MD5_DISABLE - {TAG_HMACMD5_KEY, "Key:"}, - {TAG_HMACMD5_BITS, "Bits:"}, -#endif - - {TAG_HMACSHA1_KEY, "Key:"}, - {TAG_HMACSHA1_BITS, "Bits:"}, - - {TAG_HMACSHA224_KEY, "Key:"}, - {TAG_HMACSHA224_BITS, "Bits:"}, - - {TAG_HMACSHA256_KEY, "Key:"}, - {TAG_HMACSHA256_BITS, "Bits:"}, - - {TAG_HMACSHA384_KEY, "Key:"}, - {TAG_HMACSHA384_BITS, "Bits:"}, - - {TAG_HMACSHA512_KEY, "Key:"}, - {TAG_HMACSHA512_BITS, "Bits:"}, - - {0, NULL} -}; - -static int -find_value(const char *s, const unsigned int alg) { - int i; - - for (i = 0; map[i].tag != NULL; i++) { - if (strcasecmp(s, map[i].tag) == 0 && - (TAG_ALG(map[i].value) == alg)) - return (map[i].value); - } - return (-1); -} - -static const char * -find_tag(const int value) { - int i; - - for (i = 0; ; i++) { - if (map[i].tag == NULL) - return (NULL); - else if (value == map[i].value) - return (map[i].tag); - } -} - -static int -find_metadata(const char *s, const char *tags[], int ntags) { - int i; - - for (i = 0; i < ntags; i++) { - if (tags[i] != NULL && strcasecmp(s, tags[i]) == 0) - return (i); - } - - return (-1); -} - -static int -find_timedata(const char *s) { - return (find_metadata(s, timetags, TIMING_NTAGS)); -} - -static int -find_numericdata(const char *s) { - return (find_metadata(s, numerictags, NUMERIC_NTAGS)); -} - -static int -check_rsa(const dst_private_t *priv, bool external) { - int i, j; - bool have[RSA_NTAGS]; - bool ok; - unsigned int mask; - - if (external) - return ((priv->nelements == 0) ? 0 : -1); - - for (i = 0; i < RSA_NTAGS; i++) - have[i] = false; - - for (j = 0; j < priv->nelements; j++) { - for (i = 0; i < RSA_NTAGS; i++) - if (priv->elements[j].tag == TAG(DST_ALG_RSAMD5, i)) - break; - if (i == RSA_NTAGS) - return (-1); - have[i] = true; - } - - mask = (1ULL << TAG_SHIFT) - 1; - - if (have[TAG_RSA_ENGINE & mask]) - ok = have[TAG_RSA_MODULUS & mask] && - have[TAG_RSA_PUBLICEXPONENT & mask] && - have[TAG_RSA_LABEL & mask]; - else - ok = have[TAG_RSA_MODULUS & mask] && - have[TAG_RSA_PUBLICEXPONENT & mask] && - have[TAG_RSA_PRIVATEEXPONENT & mask] && - have[TAG_RSA_PRIME1 & mask] && - have[TAG_RSA_PRIME2 & mask] && - have[TAG_RSA_EXPONENT1 & mask] && - have[TAG_RSA_EXPONENT2 & mask] && - have[TAG_RSA_COEFFICIENT & mask]; - return (ok ? 0 : -1 ); -} - -#ifndef PK11_DH_DISABLE -static int -check_dh(const dst_private_t *priv) { - int i, j; - if (priv->nelements != DH_NTAGS) - return (-1); - for (i = 0; i < DH_NTAGS; i++) { - for (j = 0; j < priv->nelements; j++) - if (priv->elements[j].tag == TAG(DST_ALG_DH, i)) - break; - if (j == priv->nelements) - return (-1); - } - return (0); -} -#endif - -#ifndef PK11_DSA_DISABLE -static int -check_dsa(const dst_private_t *priv, bool external) { - int i, j; - - if (external) - return ((priv->nelements == 0)? 0 : -1); - - if (priv->nelements != DSA_NTAGS) - return (-1); - - for (i = 0; i < DSA_NTAGS; i++) { - for (j = 0; j < priv->nelements; j++) - if (priv->elements[j].tag == TAG(DST_ALG_DSA, i)) - break; - if (j == priv->nelements) - return (-1); - } - return (0); -} -#endif - -static int -check_gost(const dst_private_t *priv, bool external) { - - if (external) - return ((priv->nelements == 0)? 0 : -1); - - if (priv->nelements != GOST_NTAGS) - return (-1); - if ((priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0)) && - (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 1))) - return (-1); - return (0); -} - -static int -check_ecdsa(const dst_private_t *priv, bool external) { - int i, j; - bool have[ECDSA_NTAGS]; - bool ok; - unsigned int mask; - - if (external) - return ((priv->nelements == 0) ? 0 : -1); - - for (i = 0; i < ECDSA_NTAGS; i++) - have[i] = false; - for (j = 0; j < priv->nelements; j++) { - for (i = 0; i < ECDSA_NTAGS; i++) - if (priv->elements[j].tag == TAG(DST_ALG_ECDSA256, i)) - break; - if (i == ECDSA_NTAGS) - return (-1); - have[i] = true; - } - - mask = (1ULL << TAG_SHIFT) - 1; - - if (have[TAG_ECDSA_ENGINE & mask]) - ok = have[TAG_ECDSA_LABEL & mask]; - else - ok = have[TAG_ECDSA_PRIVATEKEY & mask]; - return (ok ? 0 : -1 ); -} - -static int -check_eddsa(const dst_private_t *priv, bool external) { - int i, j; - bool have[EDDSA_NTAGS]; - bool ok; - unsigned int mask; - - if (external) - return ((priv->nelements == 0) ? 0 : -1); - - for (i = 0; i < EDDSA_NTAGS; i++) - have[i] = false; - for (j = 0; j < priv->nelements; j++) { - for (i = 0; i < EDDSA_NTAGS; i++) - if (priv->elements[j].tag == TAG(DST_ALG_ED25519, i)) - break; - if (i == EDDSA_NTAGS) - return (-1); - have[i] = true; - } - - mask = (1ULL << TAG_SHIFT) - 1; - - if (have[TAG_EDDSA_ENGINE & mask]) - ok = have[TAG_EDDSA_LABEL & mask]; - else - ok = have[TAG_EDDSA_PRIVATEKEY & mask]; - return (ok ? 0 : -1 ); -} - -#ifndef PK11_MD5_DISABLE -static int -check_hmac_md5(const dst_private_t *priv, bool old) { - int i, j; - - if (priv->nelements != HMACMD5_NTAGS) { - /* - * If this is a good old format and we are accepting - * the old format return success. - */ - if (old && priv->nelements == OLD_HMACMD5_NTAGS && - priv->elements[0].tag == TAG_HMACMD5_KEY) - return (0); - return (-1); - } - /* - * We must be new format at this point. - */ - for (i = 0; i < HMACMD5_NTAGS; i++) { - for (j = 0; j < priv->nelements; j++) - if (priv->elements[j].tag == TAG(DST_ALG_HMACMD5, i)) - break; - if (j == priv->nelements) - return (-1); - } - return (0); -} -#endif - -static int -check_hmac_sha(const dst_private_t *priv, unsigned int ntags, - unsigned int alg) -{ - unsigned int i, j; - if (priv->nelements != ntags) - return (-1); - for (i = 0; i < ntags; i++) { - for (j = 0; j < priv->nelements; j++) - if (priv->elements[j].tag == TAG(alg, i)) - break; - if (j == priv->nelements) - return (-1); - } - return (0); -} - -static int -check_data(const dst_private_t *priv, const unsigned int alg, - bool old, bool external) -{ -#ifdef PK11_MD5_DISABLE - UNUSED(old); -#endif - /* XXXVIX this switch statement is too sparse to gen a jump table. */ - switch (alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (isc_md5_available()) - return (check_rsa(priv, external)); - else - return (DST_R_UNSUPPORTEDALG); -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - case DST_ALG_RSASHA256: - case DST_ALG_RSASHA512: - return (check_rsa(priv, external)); -#ifndef PK11_DH_DISABLE - case DST_ALG_DH: - return (check_dh(priv)); -#endif -#ifndef PK11_DSA_DISABLE - case DST_ALG_DSA: - case DST_ALG_NSEC3DSA: - return (check_dsa(priv, external)); -#endif - case DST_ALG_ECCGOST: - return (check_gost(priv, external)); - case DST_ALG_ECDSA256: - case DST_ALG_ECDSA384: - return (check_ecdsa(priv, external)); - case DST_ALG_ED25519: - case DST_ALG_ED448: - return (check_eddsa(priv, external)); -#ifndef PK11_MD5_DISABLE - case DST_ALG_HMACMD5: - if (isc_md5_available()) - return (check_hmac_md5(priv, old)); - else - return (DST_R_UNSUPPORTEDALG); -#endif - case DST_ALG_HMACSHA1: - return (check_hmac_sha(priv, HMACSHA1_NTAGS, alg)); - case DST_ALG_HMACSHA224: - return (check_hmac_sha(priv, HMACSHA224_NTAGS, alg)); - case DST_ALG_HMACSHA256: - return (check_hmac_sha(priv, HMACSHA256_NTAGS, alg)); - case DST_ALG_HMACSHA384: - return (check_hmac_sha(priv, HMACSHA384_NTAGS, alg)); - case DST_ALG_HMACSHA512: - return (check_hmac_sha(priv, HMACSHA512_NTAGS, alg)); - default: - return (DST_R_UNSUPPORTEDALG); - } -} - -void -dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) { - int i; - - if (priv == NULL) - return; - for (i = 0; i < priv->nelements; i++) { - if (priv->elements[i].data == NULL) - continue; - memset(priv->elements[i].data, 0, MAXFIELDSIZE); - isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE); - } - priv->nelements = 0; -} - -isc_result_t -dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, - isc_mem_t *mctx, dst_private_t *priv) -{ - int n = 0, major, minor, check; - isc_buffer_t b; - isc_token_t token; - unsigned char *data = NULL; - unsigned int opt = ISC_LEXOPT_EOL; - isc_stdtime_t when; - isc_result_t ret; - bool external = false; - - REQUIRE(priv != NULL); - - priv->nelements = 0; - memset(priv->elements, 0, sizeof(priv->elements)); - -#define NEXTTOKEN(lex, opt, token) \ - do { \ - ret = isc_lex_gettoken(lex, opt, token); \ - if (ret != ISC_R_SUCCESS) \ - goto fail; \ - } while (0) - -#define READLINE(lex, opt, token) \ - do { \ - ret = isc_lex_gettoken(lex, opt, token); \ - if (ret == ISC_R_EOF) \ - break; \ - else if (ret != ISC_R_SUCCESS) \ - goto fail; \ - } while ((*token).type != isc_tokentype_eol) - - /* - * Read the description line. - */ - NEXTTOKEN(lex, opt, &token); - if (token.type != isc_tokentype_string || - strcmp(DST_AS_STR(token), PRIVATE_KEY_STR) != 0) - { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - NEXTTOKEN(lex, opt, &token); - if (token.type != isc_tokentype_string || - (DST_AS_STR(token))[0] != 'v') - { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - if (sscanf(DST_AS_STR(token), "v%d.%d", &major, &minor) != 2) - { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - if (major > DST_MAJOR_VERSION) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - /* - * Store the private key format version number - */ - dst_key_setprivateformat(key, major, minor); - - READLINE(lex, opt, &token); - - /* - * Read the algorithm line. - */ - NEXTTOKEN(lex, opt, &token); - if (token.type != isc_tokentype_string || - strcmp(DST_AS_STR(token), ALGORITHM_STR) != 0) - { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); - if (token.type != isc_tokentype_number || - token.value.as_ulong != (unsigned long) dst_key_alg(key)) - { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - READLINE(lex, opt, &token); - - /* - * Read the key data. - */ - for (n = 0; n < MAXFIELDS; n++) { - int tag; - isc_region_t r; - do { - ret = isc_lex_gettoken(lex, opt, &token); - if (ret == ISC_R_EOF) - goto done; - if (ret != ISC_R_SUCCESS) - goto fail; - } while (token.type == isc_tokentype_eol); - - if (token.type != isc_tokentype_string) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - if (strcmp(DST_AS_STR(token), "External:") == 0) { - external = true; - goto next; - } - - /* Numeric metadata */ - tag = find_numericdata(DST_AS_STR(token)); - if (tag >= 0) { - INSIST(tag < NUMERIC_NTAGS); - - NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); - if (token.type != isc_tokentype_number) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - dst_key_setnum(key, tag, token.value.as_ulong); - goto next; - } - - /* Timing metadata */ - tag = find_timedata(DST_AS_STR(token)); - if (tag >= 0) { - INSIST(tag < TIMING_NTAGS); - - NEXTTOKEN(lex, opt, &token); - if (token.type != isc_tokentype_string) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - ret = dns_time32_fromtext(DST_AS_STR(token), &when); - if (ret != ISC_R_SUCCESS) - goto fail; - - dst_key_settime(key, tag, when); - - goto next; - } - - /* Key data */ - tag = find_value(DST_AS_STR(token), alg); - if (tag < 0 && minor > DST_MINOR_VERSION) - goto next; - else if (tag < 0) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - - priv->elements[n].tag = tag; - - data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE); - if (data == NULL) - goto fail; - - isc_buffer_init(&b, data, MAXFIELDSIZE); - ret = isc_base64_tobuffer(lex, &b, -1); - if (ret != ISC_R_SUCCESS) - goto fail; - - isc_buffer_usedregion(&b, &r); - priv->elements[n].length = r.length; - priv->elements[n].data = r.base; - priv->nelements++; - - next: - READLINE(lex, opt, &token); - data = NULL; - } - - done: - if (external && priv->nelements != 0) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } - -#ifdef PK11_MD5_DISABLE - if (alg == DST_ALG_RSA) - alg = DST_ALG_RSASHA1; -#else - if (!isc_md5_available() && alg == DST_ALG_RSA) - alg = DST_ALG_RSASHA1; -#endif - check = check_data(priv, alg, true, external); - if (check < 0) { - ret = DST_R_INVALIDPRIVATEKEY; - goto fail; - } else if (check != ISC_R_SUCCESS) { - ret = check; - goto fail; - } - - key->external = external; - - return (ISC_R_SUCCESS); - -fail: - dst__privstruct_free(priv, mctx); - if (data != NULL) - isc_mem_put(mctx, data, MAXFIELDSIZE); - - return (ret); -} - -isc_result_t -dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, - const char *directory) -{ - FILE *fp; - isc_result_t result; - char filename[NAME_MAX]; - char buffer[MAXFIELDSIZE * 2]; - isc_fsaccess_t access; - isc_stdtime_t when; - uint32_t value; - isc_buffer_t b; - isc_region_t r; - int major, minor; - mode_t mode; - int i, ret; - - REQUIRE(priv != NULL); - - ret = check_data(priv, dst_key_alg(key), false, key->external); - if (ret < 0) - return (DST_R_INVALIDPRIVATEKEY); - else if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, filename, sizeof(filename)); - result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_file_mode(filename, &mode); - if (result == ISC_R_SUCCESS && mode != 0600) { - /* File exists; warn that we are changing its permissions */ - int level; - -#ifdef _WIN32 - /* Windows security model is pretty different, - * e.g., there is no umask... */ - level = ISC_LOG_NOTICE; -#else - level = ISC_LOG_WARNING; -#endif - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_DNSSEC, level, - "Permissions on the file %s " - "have changed from 0%o to 0600 as " - "a result of this operation.", - filename, (unsigned int)mode); - } - - if ((fp = fopen(filename, "w")) == NULL) - return (DST_R_WRITEERROR); - - access = 0; - isc_fsaccess_add(ISC_FSACCESS_OWNER, - ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, - &access); - (void)isc_fsaccess_set(filename, access); - - dst_key_getprivateformat(key, &major, &minor); - if (major == 0 && minor == 0) { - major = DST_MAJOR_VERSION; - minor = DST_MINOR_VERSION; - } - - /* XXXDCL return value should be checked for full filesystem */ - fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, major, minor); - - fprintf(fp, "%s %u ", ALGORITHM_STR, dst_key_alg(key)); - - /* XXXVIX this switch statement is too sparse to gen a jump table. */ - switch (dst_key_alg(key)) { - case DST_ALG_RSAMD5: - fprintf(fp, "(RSA)\n"); - break; - case DST_ALG_DH: - fprintf(fp, "(DH)\n"); - break; - case DST_ALG_DSA: - fprintf(fp, "(DSA)\n"); - break; - case DST_ALG_RSASHA1: - fprintf(fp, "(RSASHA1)\n"); - break; - case DST_ALG_NSEC3RSASHA1: - fprintf(fp, "(NSEC3RSASHA1)\n"); - break; - case DST_ALG_NSEC3DSA: - fprintf(fp, "(NSEC3DSA)\n"); - break; - case DST_ALG_RSASHA256: - fprintf(fp, "(RSASHA256)\n"); - break; - case DST_ALG_RSASHA512: - fprintf(fp, "(RSASHA512)\n"); - break; - case DST_ALG_ECCGOST: - fprintf(fp, "(ECC-GOST)\n"); - break; - case DST_ALG_ECDSA256: - fprintf(fp, "(ECDSAP256SHA256)\n"); - break; - case DST_ALG_ECDSA384: - fprintf(fp, "(ECDSAP384SHA384)\n"); - break; - case DST_ALG_ED25519: - fprintf(fp, "(ED25519)\n"); - break; - case DST_ALG_ED448: - fprintf(fp, "(ED448)\n"); - break; - case DST_ALG_HMACMD5: - fprintf(fp, "(HMAC_MD5)\n"); - break; - case DST_ALG_HMACSHA1: - fprintf(fp, "(HMAC_SHA1)\n"); - break; - case DST_ALG_HMACSHA224: - fprintf(fp, "(HMAC_SHA224)\n"); - break; - case DST_ALG_HMACSHA256: - fprintf(fp, "(HMAC_SHA256)\n"); - break; - case DST_ALG_HMACSHA384: - fprintf(fp, "(HMAC_SHA384)\n"); - break; - case DST_ALG_HMACSHA512: - fprintf(fp, "(HMAC_SHA512)\n"); - break; - default: - fprintf(fp, "(?)\n"); - break; - } - - for (i = 0; i < priv->nelements; i++) { - const char *s; - - s = find_tag(priv->elements[i].tag); - - r.base = priv->elements[i].data; - r.length = priv->elements[i].length; - isc_buffer_init(&b, buffer, sizeof(buffer)); - result = isc_base64_totext(&r, sizeof(buffer), "", &b); - if (result != ISC_R_SUCCESS) { - fclose(fp); - return (DST_R_INVALIDPRIVATEKEY); - } - isc_buffer_usedregion(&b, &r); - - fprintf(fp, "%s %.*s\n", s, (int)r.length, r.base); - } - - if (key->external) - fprintf(fp, "External:\n"); - - /* Add the metadata tags */ - if (major > 1 || (major == 1 && minor >= 3)) { - for (i = 0; i < NUMERIC_NTAGS; i++) { - result = dst_key_getnum(key, i, &value); - if (result != ISC_R_SUCCESS) - continue; - fprintf(fp, "%s %u\n", numerictags[i], value); - } - for (i = 0; i < TIMING_NTAGS; i++) { - result = dst_key_gettime(key, i, &when); - if (result != ISC_R_SUCCESS) - continue; - - isc_buffer_init(&b, buffer, sizeof(buffer)); - result = dns_time32_totext(when, &b); - if (result != ISC_R_SUCCESS) { - fclose(fp); - return (DST_R_INVALIDPRIVATEKEY); - } - - isc_buffer_usedregion(&b, &r); - - fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length, - r.base); - } - } - - fflush(fp); - result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; - fclose(fp); - return (result); -} - -/*! \file */ diff --git a/lib/dns-pkcs11/dst_parse.h b/lib/dns-pkcs11/dst_parse.h deleted file mode 100644 index 5121356..0000000 --- a/lib/dns-pkcs11/dst_parse.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - - -/*! \file */ -#ifndef DST_DST_PARSE_H -#define DST_DST_PARSE_H 1 - -#include - -#include - -#define MAXFIELDSIZE 512 - -/* - * Maximum number of fields in a private file is 18 (12 algorithm- - * specific fields for RSA, plus 6 generic fields). - */ -#define MAXFIELDS 12+6 - -#define TAG_SHIFT 4 -#define TAG_ALG(tag) ((unsigned int)(tag) >> TAG_SHIFT) -#define TAG(alg, off) (((alg) << TAG_SHIFT) + (off)) - -/* These are used by both RSA-MD5 and RSA-SHA1 */ -#define RSA_NTAGS 11 -#define TAG_RSA_MODULUS ((DST_ALG_RSAMD5 << TAG_SHIFT) + 0) -#define TAG_RSA_PUBLICEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 1) -#define TAG_RSA_PRIVATEEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 2) -#define TAG_RSA_PRIME1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 3) -#define TAG_RSA_PRIME2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 4) -#define TAG_RSA_EXPONENT1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 5) -#define TAG_RSA_EXPONENT2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 6) -#define TAG_RSA_COEFFICIENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 7) -#define TAG_RSA_ENGINE ((DST_ALG_RSAMD5 << TAG_SHIFT) + 8) -#define TAG_RSA_LABEL ((DST_ALG_RSAMD5 << TAG_SHIFT) + 9) - -#define DH_NTAGS 4 -#define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0) -#define TAG_DH_GENERATOR ((DST_ALG_DH << TAG_SHIFT) + 1) -#define TAG_DH_PRIVATE ((DST_ALG_DH << TAG_SHIFT) + 2) -#define TAG_DH_PUBLIC ((DST_ALG_DH << TAG_SHIFT) + 3) - -#define DSA_NTAGS 5 -#define TAG_DSA_PRIME ((DST_ALG_DSA << TAG_SHIFT) + 0) -#define TAG_DSA_SUBPRIME ((DST_ALG_DSA << TAG_SHIFT) + 1) -#define TAG_DSA_BASE ((DST_ALG_DSA << TAG_SHIFT) + 2) -#define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3) -#define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4) - -#define GOST_NTAGS 1 -#define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0) -#define TAG_GOST_PRIVRAW ((DST_ALG_ECCGOST << TAG_SHIFT) + 1) - -#define ECDSA_NTAGS 4 -#define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0) -#define TAG_ECDSA_ENGINE ((DST_ALG_ECDSA256 << TAG_SHIFT) + 1) -#define TAG_ECDSA_LABEL ((DST_ALG_ECDSA256 << TAG_SHIFT) + 2) - -#define EDDSA_NTAGS 4 -#define TAG_EDDSA_PRIVATEKEY ((DST_ALG_ED25519 << TAG_SHIFT) + 0) -#define TAG_EDDSA_ENGINE ((DST_ALG_ED25519 << TAG_SHIFT) + 1) -#define TAG_EDDSA_LABEL ((DST_ALG_ED25519 << TAG_SHIFT) + 2) - -#define OLD_HMACMD5_NTAGS 1 -#define HMACMD5_NTAGS 2 -#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) -#define TAG_HMACMD5_BITS ((DST_ALG_HMACMD5 << TAG_SHIFT) + 1) - -#define HMACSHA1_NTAGS 2 -#define TAG_HMACSHA1_KEY ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 0) -#define TAG_HMACSHA1_BITS ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 1) - -#define HMACSHA224_NTAGS 2 -#define TAG_HMACSHA224_KEY ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 0) -#define TAG_HMACSHA224_BITS ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 1) - -#define HMACSHA256_NTAGS 2 -#define TAG_HMACSHA256_KEY ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 0) -#define TAG_HMACSHA256_BITS ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 1) - -#define HMACSHA384_NTAGS 2 -#define TAG_HMACSHA384_KEY ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 0) -#define TAG_HMACSHA384_BITS ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 1) - -#define HMACSHA512_NTAGS 2 -#define TAG_HMACSHA512_KEY ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 0) -#define TAG_HMACSHA512_BITS ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 1) - -struct dst_private_element { - unsigned short tag; - unsigned short length; - unsigned char *data; -}; - -typedef struct dst_private_element dst_private_element_t; - -struct dst_private { - unsigned short nelements; - dst_private_element_t elements[MAXFIELDS]; -}; - -typedef struct dst_private dst_private_t; - -ISC_LANG_BEGINDECLS - -void -dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx); - -isc_result_t -dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, - isc_mem_t *mctx, dst_private_t *priv); - -isc_result_t -dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, - const char *directory); - -ISC_LANG_ENDDECLS - -#endif /* DST_DST_PARSE_H */ diff --git a/lib/dns-pkcs11/dst_pkcs11.h b/lib/dns-pkcs11/dst_pkcs11.h deleted file mode 100644 index 0d12563..0000000 --- a/lib/dns-pkcs11/dst_pkcs11.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DST_PKCS11_H -#define DST_PKCS11_H 1 - -#include -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dst__pkcs11_toresult(const char *funcname, const char *file, int line, - isc_result_t fallback, CK_RV rv); - -#define PK11_CALL(func, args, fallback) \ - ((void) (((rv = (func) args) == CKR_OK) || \ - ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ - fallback, rv)), 0))) - -#define PK11_RET(func, args, fallback) \ - ((void) (((rv = (func) args) == CKR_OK) || \ - ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ - fallback, rv)), 0))); \ - if (rv != CKR_OK) goto err; - -ISC_LANG_ENDDECLS - -#endif /* DST_PKCS11_H */ diff --git a/lib/dns-pkcs11/dst_result.c b/lib/dns-pkcs11/dst_result.c deleted file mode 100644 index 603fae8..0000000 --- a/lib/dns-pkcs11/dst_result.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include - -static const char *text[DST_R_NRESULTS] = { - "algorithm is unsupported", /*%< 0 */ - "crypto failure", /*%< 1 */ - "built with no crypto support", /*%< 2 */ - "illegal operation for a null key", /*%< 3 */ - "public key is invalid", /*%< 4 */ - "private key is invalid", /*%< 5 */ - "external key", /*%< 6 */ - "error occurred writing key to disk", /*%< 7 */ - "invalid algorithm specific parameter", /*%< 8 */ - "UNUSED9", /*%< 9 */ - "UNUSED10", /*%< 10 */ - "sign failure", /*%< 11 */ - "UNUSED12", /*%< 12 */ - "UNUSED13", /*%< 13 */ - "verify failure", /*%< 14 */ - "not a public key", /*%< 15 */ - "not a private key", /*%< 16 */ - "not a key that can compute a secret", /*%< 17 */ - "failure computing a shared secret", /*%< 18 */ - "no randomness available", /*%< 19 */ - "bad key type", /*%< 20 */ - "no engine", /*%< 21 */ - "illegal operation for an external key",/*%< 22 */ -}; - -static const char *ids[DST_R_NRESULTS] = { - "DST_R_UNSUPPORTEDALG", - "DST_R_CRYPTOFAILURE", - "DST_R_NOCRYPTO", - "DST_R_NULLKEY", - "DST_R_INVALIDPUBLICKEY", - "DST_R_INVALIDPRIVATEKEY", - "UNUSED", - "DST_R_WRITEERROR", - "DST_R_INVALIDPARAM", - "UNUSED", - "UNUSED", - "DST_R_SIGNFAILURE", - "UNUSED", - "UNUSED", - "DST_R_VERIFYFAILURE", - "DST_R_NOTPUBLICKEY", - "DST_R_NOTPRIVATEKEY", - "DST_R_KEYCANNOTCOMPUTESECRET", - "DST_R_COMPUTESECRETFAILURE", - "DST_R_NORANDOMNESS", - "DST_R_BADKEYTYPE", - "DST_R_NOENGINE", - "DST_R_EXTERNALKEY", -}; - -#define DST_RESULT_RESULTSET 2 - -static isc_once_t once = ISC_ONCE_INIT; - -static void -initialize_action(void) { - isc_result_t result; - - result = isc_result_register(ISC_RESULTCLASS_DST, DST_R_NRESULTS, - text, dst_msgcat, DST_RESULT_RESULTSET); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_result_register() failed: %u", result); - result = isc_result_registerids(ISC_RESULTCLASS_DST, DST_R_NRESULTS, - ids, dst_msgcat, DST_RESULT_RESULTSET); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_result_registerids() failed: %u", result); -} - -static void -initialize(void) { - dst_lib_initmsgcat(); - RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); -} - -const char * -dst_result_totext(isc_result_t result) { - initialize(); - - return (isc_result_totext(result)); -} - -void -dst_result_register(void) { - initialize(); -} - -/*! \file */ diff --git a/lib/dns-pkcs11/dyndb.c b/lib/dns-pkcs11/dyndb.c deleted file mode 100644 index 35c5aaa..0000000 --- a/lib/dns-pkcs11/dyndb.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#if HAVE_DLFCN_H -#include -#elif _WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - - -typedef struct dyndb_implementation dyndb_implementation_t; -struct dyndb_implementation { - isc_mem_t *mctx; - void *handle; - dns_dyndb_register_t *register_func; - dns_dyndb_destroy_t *destroy_func; - char *name; - void *inst; - LINK(dyndb_implementation_t) link; -}; - -/* - * List of dyndb implementations. Locked by dyndb_lock. - * - * These are stored here so they can be cleaned up on shutdown. - * (The order in which they are stored is not important.) - */ -static LIST(dyndb_implementation_t) dyndb_implementations; - -/* Locks dyndb_implementations. */ -static isc_mutex_t dyndb_lock; -static isc_once_t once = ISC_ONCE_INIT; - -static void -dyndb_initialize(void) { - RUNTIME_CHECK(isc_mutex_init(&dyndb_lock) == ISC_R_SUCCESS); - INIT_LIST(dyndb_implementations); -} - -static dyndb_implementation_t * -impfind(const char *name) { - dyndb_implementation_t *imp; - - for (imp = ISC_LIST_HEAD(dyndb_implementations); - imp != NULL; - imp = ISC_LIST_NEXT(imp, link)) - if (strcasecmp(name, imp->name) == 0) - return (imp); - return (NULL); -} - -#if HAVE_DLFCN_H && HAVE_DLOPEN -static isc_result_t -load_symbol(void *handle, const char *filename, - const char *symbol_name, void **symbolp) -{ - const char *errmsg; - void *symbol; - - REQUIRE(handle != NULL); - REQUIRE(symbolp != NULL && *symbolp == NULL); - - symbol = dlsym(handle, symbol_name); - if (symbol == NULL) { - errmsg = dlerror(); - if (errmsg == NULL) - errmsg = "returned function pointer is NULL"; - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "failed to lookup symbol %s in " - "dyndb module '%s': %s", - symbol_name, filename, errmsg); - return (ISC_R_FAILURE); - } - dlerror(); - - *symbolp = symbol; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, const char *instname, - dyndb_implementation_t **impp) -{ - isc_result_t result; - void *handle = NULL; - dyndb_implementation_t *imp = NULL; - dns_dyndb_register_t *register_func = NULL; - dns_dyndb_destroy_t *destroy_func = NULL; - dns_dyndb_version_t *version_func = NULL; - int version, flags; - - REQUIRE(impp != NULL && *impp == NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_INFO, - "loading DynDB instance '%s' driver '%s'", - instname, filename); - - flags = RTLD_NOW|RTLD_LOCAL; -#if 0 - /* Shared global namespace is required for dns-pkcs11 library */ -#if defined(RTLD_DEEPBIND) && !__SANITIZE_ADDRESS__ - flags |= RTLD_DEEPBIND; -#endif -#endif - - handle = dlopen(filename, flags); - if (handle == NULL) - CHECK(ISC_R_FAILURE); - - /* Clear dlerror */ - dlerror(); - - CHECK(load_symbol(handle, filename, "dyndb_version", - (void **)&version_func)); - - version = version_func(NULL); - if (version < (DNS_DYNDB_VERSION - DNS_DYNDB_AGE) || - version > DNS_DYNDB_VERSION) - { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "driver API version mismatch: %d/%d", - version, DNS_DYNDB_VERSION); - CHECK(ISC_R_FAILURE); - } - - CHECK(load_symbol(handle, filename, "dyndb_init", - (void **)®ister_func)); - CHECK(load_symbol(handle, filename, "dyndb_destroy", - (void **)&destroy_func)); - - imp = isc_mem_get(mctx, sizeof(dyndb_implementation_t)); - if (imp == NULL) - CHECK(ISC_R_NOMEMORY); - - imp->mctx = NULL; - isc_mem_attach(mctx, &imp->mctx); - imp->handle = handle; - imp->register_func = register_func; - imp->destroy_func = destroy_func; - imp->name = isc_mem_strdup(mctx, instname); - if (imp->name == NULL) - CHECK(ISC_R_NOMEMORY); - - imp->inst = NULL; - INIT_LINK(imp, link); - - *impp = imp; - imp = NULL; - -cleanup: - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "failed to dynamically load instance '%s' " - "driver '%s': %s (%s)", instname, filename, - dlerror(), isc_result_totext(result)); - if (imp != NULL) - isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); - if (result != ISC_R_SUCCESS && handle != NULL) - dlclose(handle); - - return (result); -} - -static void -unload_library(dyndb_implementation_t **impp) { - dyndb_implementation_t *imp; - - REQUIRE(impp != NULL && *impp != NULL); - - imp = *impp; - - isc_mem_free(imp->mctx, imp->name); - isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); - - *impp = NULL; -} -#elif _WIN32 -static isc_result_t -load_symbol(HMODULE handle, const char *filename, - const char *symbol_name, void **symbolp) -{ - void *symbol; - - REQUIRE(handle != NULL); - REQUIRE(symbolp != NULL && *symbolp == NULL); - - symbol = GetProcAddress(handle, symbol_name); - if (symbol == NULL) { - int errstatus = GetLastError(); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "failed to lookup symbol %s in " - "dyndb module '%s': %d", - symbol_name, filename, errstatus); - return (ISC_R_FAILURE); - } - - *symbolp = symbol; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, const char *instname, - dyndb_implementation_t **impp) -{ - isc_result_t result; - HMODULE handle; - dyndb_implementation_t *imp = NULL; - dns_dyndb_register_t *register_func = NULL; - dns_dyndb_destroy_t *destroy_func = NULL; - dns_dyndb_version_t *version_func = NULL; - int version; - - REQUIRE(impp != NULL && *impp == NULL); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_INFO, - "loading DynDB instance '%s' driver '%s'", - instname, filename); - - handle = LoadLibraryA(filename); - if (handle == NULL) - CHECK(ISC_R_FAILURE); - - CHECK(load_symbol(handle, filename, "dyndb_version", - (void **)&version_func)); - - version = version_func(NULL); - if (version < (DNS_DYNDB_VERSION - DNS_DYNDB_AGE) || - version > DNS_DYNDB_VERSION) - { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "driver API version mismatch: %d/%d", - version, DNS_DYNDB_VERSION); - CHECK(ISC_R_FAILURE); - } - - CHECK(load_symbol(handle, filename, "dyndb_init", - (void **)®ister_func)); - CHECK(load_symbol(handle, filename, "dyndb_destroy", - (void **)&destroy_func)); - - imp = isc_mem_get(mctx, sizeof(dyndb_implementation_t)); - if (imp == NULL) - CHECK(ISC_R_NOMEMORY); - - imp->mctx = NULL; - isc_mem_attach(mctx, &imp->mctx); - imp->handle = handle; - imp->register_func = register_func; - imp->destroy_func = destroy_func; - imp->name = isc_mem_strdup(mctx, instname); - if (imp->name == NULL) - CHECK(ISC_R_NOMEMORY); - - imp->inst = NULL; - INIT_LINK(imp, link); - - *impp = imp; - imp = NULL; - -cleanup: - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, - "failed to dynamically load instance '%s' " - "driver '%s': %d (%s)", instname, filename, - GetLastError(), isc_result_totext(result)); - if (imp != NULL) - isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); - if (result != ISC_R_SUCCESS && handle != NULL) - FreeLibrary(handle); - - return (result); -} - -static void -unload_library(dyndb_implementation_t **impp) { - dyndb_implementation_t *imp; - - REQUIRE(impp != NULL && *impp != NULL); - - imp = *impp; - - isc_mem_free(imp->mctx, imp->name); - isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); - - *impp = NULL; -} -#else /* HAVE_DLFCN_H || _WIN32 */ -static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, const char *instname, - dyndb_implementation_t **impp) -{ - UNUSED(mctx); - UNUSED(filename); - UNUSED(instname); - UNUSED(impp); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DYNDB, - ISC_LOG_ERROR, - "dynamic database support is not implemented"); - - return (ISC_R_NOTIMPLEMENTED); -} - -static void -unload_library(dyndb_implementation_t **impp) -{ - UNUSED(impp); -} -#endif /* HAVE_DLFCN_H */ - -isc_result_t -dns_dyndb_load(const char *libname, const char *name, const char *parameters, - const char *file, unsigned long line, isc_mem_t *mctx, - const dns_dyndbctx_t *dctx) -{ - isc_result_t result; - dyndb_implementation_t *implementation = NULL; - - REQUIRE(DNS_DYNDBCTX_VALID(dctx)); - REQUIRE(name != NULL); - - RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS); - - LOCK(&dyndb_lock); - - /* duplicate instance names are not allowed */ - if (impfind(name) != NULL) - CHECK(ISC_R_EXISTS); - - CHECK(load_library(mctx, libname, name, &implementation)); - CHECK(implementation->register_func(mctx, name, parameters, file, line, - dctx, &implementation->inst)); - - APPEND(dyndb_implementations, implementation, link); - result = ISC_R_SUCCESS; - -cleanup: - if (result != ISC_R_SUCCESS) - if (implementation != NULL) - unload_library(&implementation); - - UNLOCK(&dyndb_lock); - return (result); -} - -void -dns_dyndb_cleanup(bool exiting) { - dyndb_implementation_t *elem; - dyndb_implementation_t *prev; - - RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS); - - LOCK(&dyndb_lock); - elem = TAIL(dyndb_implementations); - while (elem != NULL) { - prev = PREV(elem, link); - UNLINK(dyndb_implementations, elem, link); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DYNDB, ISC_LOG_INFO, - "unloading DynDB instance '%s'", elem->name); - elem->destroy_func(&elem->inst); - ENSURE(elem->inst == NULL); - unload_library(&elem); - elem = prev; - } - UNLOCK(&dyndb_lock); - - if (exiting == true) - isc_mutex_destroy(&dyndb_lock); -} - -isc_result_t -dns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx, - dns_view_t *view, dns_zonemgr_t *zmgr, isc_task_t *task, - isc_timermgr_t *tmgr, dns_dyndbctx_t **dctxp) -{ - dns_dyndbctx_t *dctx; - - REQUIRE(dctxp != NULL && *dctxp == NULL); - - dctx = isc_mem_get(mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - memset(dctx, 0, sizeof(*dctx)); - if (view != NULL) - dns_view_attach(view, &dctx->view); - if (zmgr != NULL) - dns_zonemgr_attach(zmgr, &dctx->zmgr); - if (task != NULL) - isc_task_attach(task, &dctx->task); - dctx->timermgr = tmgr; - dctx->hashinit = hashinit; - dctx->lctx = lctx; - dctx->refvar = &isc_bind9; - - isc_mem_attach(mctx, &dctx->mctx); - dctx->magic = DNS_DYNDBCTX_MAGIC; - - *dctxp = dctx; - - return (ISC_R_SUCCESS); -} - -void -dns_dyndb_destroyctx(dns_dyndbctx_t **dctxp) { - dns_dyndbctx_t *dctx; - - REQUIRE(dctxp != NULL && DNS_DYNDBCTX_VALID(*dctxp)); - - dctx = *dctxp; - *dctxp = NULL; - - dctx->magic = 0; - - if (dctx->view != NULL) - dns_view_detach(&dctx->view); - if (dctx->zmgr != NULL) - dns_zonemgr_detach(&dctx->zmgr); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - dctx->timermgr = NULL; - dctx->lctx = NULL; - - isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx)); -} diff --git a/lib/dns-pkcs11/ecdb.c b/lib/dns-pkcs11/ecdb.c deleted file mode 100644 index 76d0417..0000000 --- a/lib/dns-pkcs11/ecdb.c +++ /dev/null @@ -1,838 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include "config.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B') -#define VALID_ECDB(db) ((db) != NULL && \ - (db)->common.impmagic == ECDB_MAGIC) - -#define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N') -#define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC) - -/*% - * The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides - * temporary storage for ongoing name resolution with the common DB interfaces. - * It actually doesn't cache anything. The implementation expects any stored - * data is released within a short period, and does not care about the - * scalability in terms of the number of nodes. - */ - -typedef struct dns_ecdb { - /* Unlocked */ - dns_db_t common; - isc_mutex_t lock; - - /* Locked */ - unsigned int references; - ISC_LIST(struct dns_ecdbnode) nodes; -} dns_ecdb_t; - -typedef struct dns_ecdbnode { - /* Unlocked */ - unsigned int magic; - isc_mutex_t lock; - dns_ecdb_t *ecdb; - dns_name_t name; - ISC_LINK(struct dns_ecdbnode) link; - - /* Locked */ - ISC_LIST(struct rdatasetheader) rdatasets; - unsigned int references; -} dns_ecdbnode_t; - -typedef struct rdatasetheader { - dns_rdatatype_t type; - dns_ttl_t ttl; - dns_trust_t trust; - dns_rdatatype_t covers; - unsigned int attributes; - - ISC_LINK(struct rdatasetheader) link; -} rdatasetheader_t; - -/* Copied from rbtdb.c */ -#define RDATASET_ATTR_NXDOMAIN 0x0010 -#define RDATASET_ATTR_NEGATIVE 0x0100 -#define NXDOMAIN(header) \ - (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) -#define NEGATIVE(header) \ - (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0) - -static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, - dns_dbtype_t type, - dns_rdataclass_t rdclass, - unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp); - -static void rdataset_disassociate(dns_rdataset_t *rdataset); -static isc_result_t rdataset_first(dns_rdataset_t *rdataset); -static isc_result_t rdataset_next(dns_rdataset_t *rdataset); -static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); -static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); -static unsigned int rdataset_count(dns_rdataset_t *rdataset); -static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); - -static dns_rdatasetmethods_t rdataset_methods = { - rdataset_disassociate, - rdataset_first, - rdataset_next, - rdataset_current, - rdataset_clone, - rdataset_count, - NULL, /* addnoqname */ - NULL, /* getnoqname */ - NULL, /* addclosest */ - NULL, /* getclosest */ - NULL, /* getadditional */ - NULL, /* setadditional */ - NULL, /* putadditional */ - rdataset_settrust, /* settrust */ - NULL, /* expire */ - NULL, /* clearprefetch */ - NULL, /* setownercase */ - NULL /* getownercase */ -}; - -typedef struct ecdb_rdatasetiter { - dns_rdatasetiter_t common; - rdatasetheader_t *current; -} ecdb_rdatasetiter_t; - -static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); -static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); -static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); -static void rdatasetiter_current(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset); - -static dns_rdatasetitermethods_t rdatasetiter_methods = { - rdatasetiter_destroy, - rdatasetiter_first, - rdatasetiter_next, - rdatasetiter_current -}; - -isc_result_t -dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) { - REQUIRE(mctx != NULL); - REQUIRE(dbimp != NULL && *dbimp == NULL); - - return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp)); -} - -void -dns_ecdb_unregister(dns_dbimplementation_t **dbimp) { - REQUIRE(dbimp != NULL && *dbimp != NULL); - - dns_db_unregister(dbimp); -} - -/*% - * DB routines - */ - -static void -attach(dns_db_t *source, dns_db_t **targetp) { - dns_ecdb_t *ecdb = (dns_ecdb_t *)source; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(targetp != NULL && *targetp == NULL); - - LOCK(&ecdb->lock); - ecdb->references++; - UNLOCK(&ecdb->lock); - - *targetp = source; -} - -static void -destroy_ecdb(dns_ecdb_t **ecdbp) { - dns_ecdb_t *ecdb = *ecdbp; - isc_mem_t *mctx = ecdb->common.mctx; - - if (dns_name_dynamic(&ecdb->common.origin)) - dns_name_free(&ecdb->common.origin, mctx); - - DESTROYLOCK(&ecdb->lock); - - ecdb->common.impmagic = 0; - ecdb->common.magic = 0; - - isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb)); - - *ecdbp = NULL; -} - -static void -detach(dns_db_t **dbp) { - dns_ecdb_t *ecdb; - bool need_destroy = false; - - REQUIRE(dbp != NULL); - ecdb = (dns_ecdb_t *)*dbp; - REQUIRE(VALID_ECDB(ecdb)); - - LOCK(&ecdb->lock); - ecdb->references--; - if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes)) - need_destroy = true; - UNLOCK(&ecdb->lock); - - if (need_destroy) - destroy_ecdb(&ecdb); - - *dbp = NULL; -} - -static void -attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - dns_ecdbnode_t *node = (dns_ecdbnode_t *)source; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(VALID_ECDBNODE(node)); - REQUIRE(targetp != NULL && *targetp == NULL); - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references++; - INSIST(node->references != 0); /* Catch overflow. */ - UNLOCK(&node->lock); - - *targetp = node; -} - -static void -destroynode(dns_ecdbnode_t *node) { - isc_mem_t *mctx; - dns_ecdb_t *ecdb = node->ecdb; - bool need_destroydb = false; - rdatasetheader_t *header; - - mctx = ecdb->common.mctx; - - LOCK(&ecdb->lock); - ISC_LIST_UNLINK(ecdb->nodes, node, link); - if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes)) - need_destroydb = true; - UNLOCK(&ecdb->lock); - - dns_name_free(&node->name, mctx); - - while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) { - unsigned int headersize; - - ISC_LIST_UNLINK(node->rdatasets, header, link); - headersize = - dns_rdataslab_size((unsigned char *)header, - sizeof(*header)); - isc_mem_put(mctx, header, headersize); - } - - DESTROYLOCK(&node->lock); - - node->magic = 0; - isc_mem_put(mctx, node, sizeof(*node)); - - if (need_destroydb) - destroy_ecdb(&ecdb); -} - -static void -detachnode(dns_db_t *db, dns_dbnode_t **nodep) { - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - dns_ecdbnode_t *node; - bool need_destroy = false; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(nodep != NULL); - node = (dns_ecdbnode_t *)*nodep; - REQUIRE(VALID_ECDBNODE(node)); - - UNUSED(ecdb); /* in case REQUIRE() is empty */ - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - need_destroy = true; - UNLOCK(&node->lock); - - if (need_destroy) - destroynode(node); - - *nodep = NULL; -} - -static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - - REQUIRE(VALID_ECDB(ecdb)); - - UNUSED(name); - UNUSED(version); - UNUSED(type); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - return (ISC_R_NOTFOUND); -} - -static isc_result_t -findzonecut(dns_db_t *db, dns_name_t *name, - unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - - REQUIRE(VALID_ECDB(ecdb)); - - UNUSED(name); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - return (ISC_R_NOTFOUND); -} - -static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, bool create, - dns_dbnode_t **nodep) -{ - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - isc_mem_t *mctx; - dns_ecdbnode_t *node; - isc_result_t result; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(nodep != NULL && *nodep == NULL); - - UNUSED(name); - - if (create != true) { - /* an 'ephemeral' node is never reused. */ - return (ISC_R_NOTFOUND); - } - - mctx = ecdb->common.mctx; - node = isc_mem_get(mctx, sizeof(*node)); - if (node == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&node->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - isc_mem_put(mctx, node, sizeof(*node)); - return (ISC_R_UNEXPECTED); - } - - dns_name_init(&node->name, NULL); - result = dns_name_dup(name, mctx, &node->name); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&node->lock); - isc_mem_put(mctx, node, sizeof(*node)); - return (result); - } - node->ecdb= ecdb; - node->references = 1; - ISC_LIST_INIT(node->rdatasets); - - ISC_LINK_INIT(node, link); - - LOCK(&ecdb->lock); - ISC_LIST_APPEND(ecdb->nodes, node, link); - UNLOCK(&ecdb->lock); - - node->magic = ECDBNODE_MAGIC; - - *nodep = node; - - return (ISC_R_SUCCESS); -} - -static void -bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node, - rdatasetheader_t *header, dns_rdataset_t *rdataset) -{ - unsigned char *raw; - - /* - * Caller must be holding the node lock. - */ - - REQUIRE(!dns_rdataset_isassociated(rdataset)); - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = ecdb->common.rdclass; - rdataset->type = header->type; - rdataset->covers = header->covers; - rdataset->ttl = header->ttl; - rdataset->trust = header->trust; - if (NXDOMAIN(header)) - rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN; - if (NEGATIVE(header)) - rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; - - rdataset->private1 = ecdb; - rdataset->private2 = node; - raw = (unsigned char *)header + sizeof(*header); - rdataset->private3 = raw; - rdataset->count = 0; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - - INSIST(node->references > 0); - node->references++; -} - -static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset) -{ - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - isc_region_t r; - isc_result_t result = ISC_R_SUCCESS; - isc_mem_t *mctx; - dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node; - rdatasetheader_t *header; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(VALID_ECDBNODE(ecdbnode)); - - UNUSED(version); - UNUSED(now); - UNUSED(options); - - mctx = ecdb->common.mctx; - - LOCK(&ecdbnode->lock); - - /* - * Sanity check: this implementation does not allow overriding an - * existing rdataset of the same type. - */ - for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL; - header = ISC_LIST_NEXT(header, link)) { - INSIST(header->type != rdataset->type || - header->covers != rdataset->covers); - } - - result = dns_rdataslab_fromrdataset(rdataset, mctx, - &r, sizeof(rdatasetheader_t)); - if (result != ISC_R_SUCCESS) - goto unlock; - - header = (rdatasetheader_t *)r.base; - header->type = rdataset->type; - header->ttl = rdataset->ttl; - header->trust = rdataset->trust; - header->covers = rdataset->covers; - header->attributes = 0; - if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) - header->attributes |= RDATASET_ATTR_NXDOMAIN; - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) - header->attributes |= RDATASET_ATTR_NEGATIVE; - ISC_LINK_INIT(header, link); - ISC_LIST_APPEND(ecdbnode->rdatasets, header, link); - - if (addedrdataset == NULL) - goto unlock; - - bind_rdataset(ecdb, ecdbnode, header, addedrdataset); - - unlock: - UNLOCK(&ecdbnode->lock); - - return (result); -} - -static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers) -{ - UNUSED(db); - UNUSED(node); - UNUSED(version); - UNUSED(type); - UNUSED(covers); - - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -createiterator(dns_db_t *db, unsigned int options, - dns_dbiterator_t **iteratorp) -{ - UNUSED(db); - UNUSED(options); - UNUSED(iteratorp); - - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) -{ - dns_ecdb_t *ecdb = (dns_ecdb_t *)db; - dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node; - isc_mem_t *mctx; - ecdb_rdatasetiter_t *iterator; - - REQUIRE(VALID_ECDB(ecdb)); - REQUIRE(VALID_ECDBNODE(ecdbnode)); - - mctx = ecdb->common.mctx; - - iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t)); - if (iterator == NULL) - return (ISC_R_NOMEMORY); - - iterator->common.magic = DNS_RDATASETITER_MAGIC; - iterator->common.methods = &rdatasetiter_methods; - iterator->common.db = db; - iterator->common.node = NULL; - attachnode(db, node, &iterator->common.node); - iterator->common.version = version; - iterator->common.now = now; - - *iteratorp = (dns_rdatasetiter_t *)iterator; - - return (ISC_R_SUCCESS); -} - -static dns_dbmethods_t ecdb_methods = { - attach, - detach, - NULL, /* beginload */ - NULL, /* endload */ - NULL, /* serialize */ - NULL, /* dump */ - NULL, /* currentversion */ - NULL, /* newversion */ - NULL, /* attachversion */ - NULL, /* closeversion */ - findnode, - find, - findzonecut, - attachnode, - detachnode, - NULL, /* expirenode */ - NULL, /* printnode */ - createiterator, /* createiterator */ - NULL, /* findrdataset */ - allrdatasets, - addrdataset, - NULL, /* subtractrdataset */ - deleterdataset, - NULL, /* issecure */ - NULL, /* nodecount */ - NULL, /* ispersistent */ - NULL, /* overmem */ - NULL, /* settask */ - NULL, /* getoriginnode */ - NULL, /* transfernode */ - NULL, /* getnsec3parameters */ - NULL, /* findnsec3node */ - NULL, /* setsigningtime */ - NULL, /* getsigningtime */ - NULL, /* resigned */ - NULL, /* isdnssec */ - NULL, /* getrrsetstats */ - NULL, /* rpz_attach */ - NULL, /* rpz_ready */ - NULL, /* findnodeext */ - NULL, /* findext */ - NULL, /* setcachestats */ - NULL, /* hashsize */ - NULL, /* nodefullname */ - NULL, /* getsize */ - NULL, /* setservestalettl */ - NULL /* getservestalettl */ -}; - -static isc_result_t -dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) -{ - dns_ecdb_t *ecdb; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(origin == dns_rootname); - REQUIRE(type == dns_dbtype_cache); - REQUIRE(dbp != NULL && *dbp == NULL); - - UNUSED(argc); - UNUSED(argv); - UNUSED(driverarg); - - ecdb = isc_mem_get(mctx, sizeof(*ecdb)); - if (ecdb == NULL) - return (ISC_R_NOMEMORY); - - ecdb->common.attributes = DNS_DBATTR_CACHE; - ecdb->common.rdclass = rdclass; - ecdb->common.methods = &ecdb_methods; - dns_name_init(&ecdb->common.origin, NULL); - result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, ecdb, sizeof(*ecdb)); - return (result); - } - - result = isc_mutex_init(&ecdb->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - if (dns_name_dynamic(&ecdb->common.origin)) - dns_name_free(&ecdb->common.origin, mctx); - isc_mem_put(mctx, ecdb, sizeof(*ecdb)); - return (ISC_R_UNEXPECTED); - } - - ecdb->references = 1; - ISC_LIST_INIT(ecdb->nodes); - - ecdb->common.mctx = NULL; - isc_mem_attach(mctx, &ecdb->common.mctx); - ecdb->common.impmagic = ECDB_MAGIC; - ecdb->common.magic = DNS_DB_MAGIC; - - *dbp = (dns_db_t *)ecdb; - - return (ISC_R_SUCCESS); -} - -/*% - * Rdataset Methods - */ - -static void -rdataset_disassociate(dns_rdataset_t *rdataset) { - dns_db_t *db = rdataset->private1; - dns_dbnode_t *node = rdataset->private2; - - dns_db_detachnode(db, &node); -} - -static isc_result_t -rdataset_first(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - if (count == 0) { - rdataset->private5 = NULL; - return (ISC_R_NOMORE); - } -#if DNS_RDATASET_FIXED - raw += 2 + (4 * count); -#else - raw += 2; -#endif - /* - * The privateuint4 field is the number of rdata beyond the cursor - * position, so we decrement the total count by one before storing - * it. - */ - count--; - rdataset->privateuint4 = count; - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdataset_next(dns_rdataset_t *rdataset) { - unsigned int count; - unsigned int length; - unsigned char *raw; - - count = rdataset->privateuint4; - if (count == 0) - return (ISC_R_NOMORE); - count--; - rdataset->privateuint4 = count; - raw = rdataset->private5; - length = raw[0] * 256 + raw[1]; -#if DNS_RDATASET_FIXED - raw += length + 4; -#else - raw += length + 2; -#endif - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static void -rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - unsigned char *raw = rdataset->private5; - isc_region_t r; - unsigned int length; - unsigned int flags = 0; - - REQUIRE(raw != NULL); - - length = raw[0] * 256 + raw[1]; -#if DNS_RDATASET_FIXED - raw += 4; -#else - raw += 2; -#endif - if (rdataset->type == dns_rdatatype_rrsig) { - if ((*raw & DNS_RDATASLAB_OFFLINE) != 0) - flags |= DNS_RDATA_OFFLINE; - length--; - raw++; - } - r.length = length; - r.base = raw; - dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); - rdata->flags |= flags; -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - dns_db_t *db = source->private1; - dns_dbnode_t *node = source->private2; - dns_dbnode_t *cloned_node = NULL; - - attachnode(db, node, &cloned_node); - *target = *source; - - /* - * Reset iterator state. - */ - target->privateuint4 = 0; - target->private5 = NULL; -} - -static unsigned int -rdataset_count(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - - return (count); -} - -static void -rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { - rdatasetheader_t *header = rdataset->private3; - - header--; - header->trust = rdataset->trust = trust; -} - -/* - * Rdataset Iterator Methods - */ - -static void -rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { - isc_mem_t *mctx; - union { - dns_rdatasetiter_t *rdatasetiterator; - ecdb_rdatasetiter_t *ecdbiterator; - } u; - - REQUIRE(iteratorp != NULL); - REQUIRE(DNS_RDATASETITER_VALID(*iteratorp)); - - u.rdatasetiterator = *iteratorp; - *iteratorp = NULL; - - mctx = u.ecdbiterator->common.db->mctx; - u.ecdbiterator->common.magic = 0; - - dns_db_detachnode(u.ecdbiterator->common.db, - &u.ecdbiterator->common.node); - isc_mem_put(mctx, u.ecdbiterator, - sizeof(ecdb_rdatasetiter_t)); -} - -static isc_result_t -rdatasetiter_first(dns_rdatasetiter_t *iterator) { - REQUIRE(DNS_RDATASETITER_VALID(iterator)); - - ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; - dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node; - - if (ISC_LIST_EMPTY(ecdbnode->rdatasets)) { - return (ISC_R_NOMORE); - } - ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets); - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdatasetiter_next(dns_rdatasetiter_t *iterator) { - REQUIRE(DNS_RDATASETITER_VALID(iterator)); - - ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; - - ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link); - if (ecdbiterator->current == NULL) { - return (ISC_R_NOMORE); - } else { - return (ISC_R_SUCCESS); - } -} - -static void -rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { - ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; - dns_ecdb_t *ecdb; - - ecdb = (dns_ecdb_t *)iterator->db; - REQUIRE(VALID_ECDB(ecdb)); - - bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset); -} diff --git a/lib/dns-pkcs11/fixedname.c b/lib/dns-pkcs11/fixedname.c deleted file mode 100644 index e5768be..0000000 --- a/lib/dns-pkcs11/fixedname.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -void -dns_fixedname_init(dns_fixedname_t *fixed) { - dns_name_init(&fixed->name, fixed->offsets); - isc_buffer_init(&fixed->buffer, fixed->data, DNS_NAME_MAXWIRE); - dns_name_setbuffer(&fixed->name, &fixed->buffer); -} - -void -dns_fixedname_invalidate(dns_fixedname_t *fixed) { - dns_name_invalidate(&fixed->name); -} - -dns_name_t * -dns_fixedname_name(dns_fixedname_t *fixed) { - return (&fixed->name); -} - -dns_name_t * -dns_fixedname_initname(dns_fixedname_t *fixed) { - dns_fixedname_init(fixed); - return (dns_fixedname_name(fixed)); -} diff --git a/lib/dns-pkcs11/forward.c b/lib/dns-pkcs11/forward.c deleted file mode 100644 index b9f29f6..0000000 --- a/lib/dns-pkcs11/forward.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -struct dns_fwdtable { - /* Unlocked. */ - unsigned int magic; - isc_mem_t *mctx; - isc_rwlock_t rwlock; - /* Locked by lock. */ - dns_rbt_t *table; -}; - -#define FWDTABLEMAGIC ISC_MAGIC('F', 'w', 'd', 'T') -#define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC) - -static void -auto_detach(void *, void *); - -isc_result_t -dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) { - dns_fwdtable_t *fwdtable; - isc_result_t result; - - REQUIRE(fwdtablep != NULL && *fwdtablep == NULL); - - fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t)); - if (fwdtable == NULL) - return (ISC_R_NOMEMORY); - - fwdtable->table = NULL; - result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table); - if (result != ISC_R_SUCCESS) - goto cleanup_fwdtable; - - result = isc_rwlock_init(&fwdtable->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_rbt; - - fwdtable->mctx = NULL; - isc_mem_attach(mctx, &fwdtable->mctx); - fwdtable->magic = FWDTABLEMAGIC; - *fwdtablep = fwdtable; - - return (ISC_R_SUCCESS); - - cleanup_rbt: - dns_rbt_destroy(&fwdtable->table); - - cleanup_fwdtable: - isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); - - return (result); -} - -isc_result_t -dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy) -{ - isc_result_t result; - dns_forwarders_t *forwarders; - dns_forwarder_t *fwd, *nfwd; - - REQUIRE(VALID_FWDTABLE(fwdtable)); - - forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); - if (forwarders == NULL) - return (ISC_R_NOMEMORY); - - ISC_LIST_INIT(forwarders->fwdrs); - for (fwd = ISC_LIST_HEAD(*fwdrs); - fwd != NULL; - fwd = ISC_LIST_NEXT(fwd, link)) - { - nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t)); - if (nfwd == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - *nfwd = *fwd; - ISC_LINK_INIT(nfwd, link); - ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link); - } - forwarders->fwdpolicy = fwdpolicy; - - RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - result = dns_rbt_addname(fwdtable->table, name, forwarders); - RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { - fwd = ISC_LIST_HEAD(forwarders->fwdrs); - ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); - isc_mem_put(fwdtable->mctx, fwd, sizeof(isc_sockaddr_t)); - } - isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); - return (result); -} - -isc_result_t -dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, - isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy) -{ - isc_result_t result; - dns_forwarders_t *forwarders; - dns_forwarder_t *fwd; - isc_sockaddr_t *sa; - - REQUIRE(VALID_FWDTABLE(fwdtable)); - - forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); - if (forwarders == NULL) - return (ISC_R_NOMEMORY); - - ISC_LIST_INIT(forwarders->fwdrs); - for (sa = ISC_LIST_HEAD(*addrs); - sa != NULL; - sa = ISC_LIST_NEXT(sa, link)) - { - fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t)); - if (fwd == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - fwd->addr = *sa; - fwd->dscp = -1; - ISC_LINK_INIT(fwd, link); - ISC_LIST_APPEND(forwarders->fwdrs, fwd, link); - } - forwarders->fwdpolicy = fwdpolicy; - - RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - result = dns_rbt_addname(fwdtable->table, name, forwarders); - RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { - fwd = ISC_LIST_HEAD(forwarders->fwdrs); - ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); - isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t)); - } - isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); - return (result); -} - -isc_result_t -dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name) { - isc_result_t result; - - REQUIRE(VALID_FWDTABLE(fwdtable)); - - RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - result = dns_rbt_deletename(fwdtable->table, name, false); - RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); - - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - - return (result); -} - -isc_result_t -dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_forwarders_t **forwardersp) -{ - return (dns_fwdtable_find2(fwdtable, name, NULL, forwardersp)); -} - -isc_result_t -dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_name_t *foundname, dns_forwarders_t **forwardersp) -{ - isc_result_t result; - - REQUIRE(VALID_FWDTABLE(fwdtable)); - - RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read); - - result = dns_rbt_findname(fwdtable->table, name, 0, foundname, - (void **)forwardersp); - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_SUCCESS; - - RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read); - - return (result); -} - -void -dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) { - dns_fwdtable_t *fwdtable; - isc_mem_t *mctx; - - REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep)); - - fwdtable = *fwdtablep; - - dns_rbt_destroy(&fwdtable->table); - isc_rwlock_destroy(&fwdtable->rwlock); - fwdtable->magic = 0; - mctx = fwdtable->mctx; - isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); - isc_mem_detach(&mctx); - - *fwdtablep = NULL; -} - -/*** - *** Private - ***/ - -static void -auto_detach(void *data, void *arg) { - dns_forwarders_t *forwarders = data; - dns_fwdtable_t *fwdtable = arg; - dns_forwarder_t *fwd; - - UNUSED(arg); - - while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { - fwd = ISC_LIST_HEAD(forwarders->fwdrs); - ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); - isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t)); - } - isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); -} diff --git a/lib/dns-pkcs11/gen-unix.h b/lib/dns-pkcs11/gen-unix.h deleted file mode 100644 index 5329517..0000000 --- a/lib/dns-pkcs11/gen-unix.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file - * \brief - * This file is responsible for defining two operations that are not - * directly portable between Unix-like systems and Windows NT, option - * parsing and directory scanning. It is here because it was decided - * that the "gen" build utility was not to depend on libisc.a, so - * the functions declared in isc/commandline.h and isc/dir.h could not - * be used. - * - * The commandline stuff is really just a wrapper around getopt(). - * The dir stuff was shrunk to fit the needs of gen.c. - */ - -#ifndef DNS_GEN_UNIX_H -#define DNS_GEN_UNIX_H 1 - -#include /* Required on some systems for dirent.h. */ - -#include -#include -#include -#include -#include /* XXXDCL Required for ?. */ - -#include - -#ifdef NEED_OPTARG -extern char *optarg; -#endif - -#define isc_commandline_parse getopt -#define isc_commandline_argument optarg - -typedef struct { - DIR *handle; - char *filename; -} isc_dir_t; - -ISC_LANG_BEGINDECLS - -static bool -start_directory(const char *path, isc_dir_t *dir) { - dir->handle = opendir(path); - - if (dir->handle != NULL) - return (true); - else - return (false); - -} - -static bool -next_file(isc_dir_t *dir) { - struct dirent *dirent; - - dir->filename = NULL; - - if (dir->handle != NULL) { - errno = 0; - dirent = readdir(dir->handle); - if (dirent != NULL) { - dir->filename = dirent->d_name; - } else { - if (errno != 0) { - exit(1); - } - } - } - - if (dir->filename != NULL) - return (true); - else - return (false); -} - -static void -end_directory(isc_dir_t *dir) { - if (dir->handle != NULL) - (void)closedir(dir->handle); - - dir->handle = NULL; -} - -ISC_LANG_ENDDECLS - -#endif /* DNS_GEN_UNIX_H */ diff --git a/lib/dns-pkcs11/gen-win32.h b/lib/dns-pkcs11/gen-win32.h deleted file mode 100644 index a710903..0000000 --- a/lib/dns-pkcs11/gen-win32.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (c) 1987, 1993, 1994 - * 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. 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. - */ - -/* - * \note This file was adapted from the NetBSD project's source tree, RCS ID: - * NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp - * - * The primary change has been to rename items to the ISC namespace - * and format in the ISC coding style. - * - * This file is responsible for defining two operations that are not - * directly portable between Unix-like systems and Windows NT, option - * parsing and directory scanning. It is here because it was decided - * that the "gen" build utility was not to depend on libisc.a, so - * the functions declared in isc/commandline.h and isc/dir.h could not - * be used. - * - * The commandline stuff is pretty much a straight copy from the initial - * isc/commandline.c. The dir stuff was shrunk to fit the needs of gen.c. - */ - -#ifndef DNS_GEN_WIN32_H -#define DNS_GEN_WIN32_H 1 - -#include -#include -#include -#include -#include - -#include - -int isc_commandline_index = 1; /* Index into parent argv vector. */ -int isc_commandline_option; /* Character checked for validity. */ - -char *isc_commandline_argument; /* Argument associated with option. */ -char *isc_commandline_progname; /* For printing error messages. */ - -bool isc_commandline_errprint = true; /* Print error messages. */ -bool isc_commandline_reset = true; /* Reset processing. */ - -#define BADOPT '?' -#define BADARG ':' -#define ENDOPT "" - -ISC_LANG_BEGINDECLS - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -isc_commandline_parse(int argc, char * const *argv, const char *options) { - static char *place = ENDOPT; - char *option; /* Index into *options of option. */ - - /* - * Update scanning pointer, either because a reset was requested or - * the previous argv was finished. - */ - if (isc_commandline_reset || *place == '\0') { - isc_commandline_reset = false; - - if (isc_commandline_progname == NULL) - isc_commandline_progname = argv[0]; - - if (isc_commandline_index >= argc || - *(place = argv[isc_commandline_index]) != '-') { - /* - * Index out of range or points to non-option. - */ - place = ENDOPT; - return (-1); - } - - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - /* - * Found '--' to signal end of options. Advance - * index to next argv, the first non-option. - */ - isc_commandline_index++; - place = ENDOPT; - return (-1); - } - } - - isc_commandline_option = *place++; - option = strchr(options, isc_commandline_option); - - /* - * Ensure valid option has been passed as specified by options string. - * '-:' is never a valid command line option because it could not - * distinguish ':' from the argument specifier in the options string. - */ - if (isc_commandline_option == ':' || option == NULL) { - if (*place == '\0') - isc_commandline_index++; - - if (isc_commandline_errprint && *options != ':') - fprintf(stderr, "%s: illegal option -- %c\n", - isc_commandline_progname, - isc_commandline_option); - - return (BADOPT); - } - - if (*++option != ':') { - /* - * Option does not take an argument. - */ - isc_commandline_argument = NULL; - - /* - * Skip to next argv if at the end of the current argv. - */ - if (*place == '\0') - ++isc_commandline_index; - - } else { - /* - * Option needs an argument. - */ - if (*place != '\0') - /* - * Option is in this argv, -D1 style. - */ - isc_commandline_argument = place; - - else if (argc > ++isc_commandline_index) - /* - * Option is next argv, -D 1 style. - */ - isc_commandline_argument = argv[isc_commandline_index]; - - else { - /* - * Argument needed, but no more argv. - */ - place = ENDOPT; - - /* - * Silent failure with "missing argument" return - * when ':' starts options string, per historical spec. - */ - if (*options == ':') - return (BADARG); - - if (isc_commandline_errprint) - fprintf(stderr, - "%s: option requires an argument -- %c\n", - isc_commandline_progname, - isc_commandline_option); - - return (BADOPT); - } - - place = ENDOPT; - - /* - * Point to argv that follows argument. - */ - isc_commandline_index++; - } - - return (isc_commandline_option); -} - -typedef struct { - HANDLE handle; - WIN32_FIND_DATA find_data; - bool first_file; - char *filename; -} isc_dir_t; - -bool -start_directory(const char *path, isc_dir_t *dir) { - char pattern[_MAX_PATH], *p; - - /* - * Need space for slash-splat and final NUL. - */ - if (strlen(path) + 3 > sizeof(pattern)) - return (false); - - strcpy(pattern, path); - - /* - * Append slash (if needed) and splat. - */ - p = pattern + strlen(pattern); - if (p != pattern && p[-1] != '\\' && p[-1] != ':') - *p++ = '\\'; - *p++ = '*'; - *p++ = '\0'; - - dir->first_file = true; - - dir->handle = FindFirstFile(pattern, &dir->find_data); - - if (dir->handle == INVALID_HANDLE_VALUE) { - dir->filename = NULL; - return (false); - } else { - dir->filename = dir->find_data.cFileName; - return (true); - } -} - -bool -next_file(isc_dir_t *dir) { - if (dir->first_file) - dir->first_file = false; - - else if (dir->handle != INVALID_HANDLE_VALUE) { - if (FindNextFile(dir->handle, &dir->find_data) == TRUE) - dir->filename = dir->find_data.cFileName; - else - dir->filename = NULL; - - } else - dir->filename = NULL; - - if (dir->filename != NULL) - return (true); - else - return (false); -} - -void -end_directory(isc_dir_t *dir) { - if (dir->handle != INVALID_HANDLE_VALUE) - FindClose(dir->handle); -} - -inline struct tm * -gmtime_r(const time_t *clock, struct tm *result) { - errno_t ret = gmtime_s(result, clock); - if (ret != 0) { - errno = ret; - return (NULL); - } - return (result); -} - -ISC_LANG_ENDDECLS - -#endif /* DNS_GEN_WIN32_H */ diff --git a/lib/dns-pkcs11/gen.c b/lib/dns-pkcs11/gen.c deleted file mode 100644 index 89e043a..0000000 --- a/lib/dns-pkcs11/gen.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#ifdef WIN32 -/* - * Silence compiler warnings about using strcpy and friends. - */ -#define _CRT_SECURE_NO_DEPRECATE 1 -/* - * We use snprintf which was defined late in Windows even it is in C99. - */ -#if _MSC_VER < 1900 -#define snprintf _snprintf -#endif -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -#ifdef WIN32 -#include "gen-win32.h" -#else -#include "gen-unix.h" -#endif - -#ifndef ULLONG_MAX -#define ULLONG_MAX (~0ULL) -#endif - -#define INSIST(cond) \ - if (!(cond)) { \ - fprintf(stderr, "%s:%d: INSIST(%s)\n", \ - __FILE__, __LINE__, #cond); \ - abort(); \ - } - -#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" -#define FROMTEXTCLASS "rdclass" -#define FROMTEXTTYPE "type" -#define FROMTEXTDEF "result = DNS_R_UNKNOWN" - -#define TOTEXTARGS "rdata, tctx, target" -#define TOTEXTCLASS "rdata->rdclass" -#define TOTEXTTYPE "rdata->type" -#define TOTEXTDEF "use_default = true" - -#define FROMWIREARGS "rdclass, type, source, dctx, options, target" -#define FROMWIRECLASS "rdclass" -#define FROMWIRETYPE "type" -#define FROMWIREDEF "use_default = true" - -#define TOWIREARGS "rdata, cctx, target" -#define TOWIRECLASS "rdata->rdclass" -#define TOWIRETYPE "rdata->type" -#define TOWIREDEF "use_default = true" - -#define FROMSTRUCTARGS "rdclass, type, source, target" -#define FROMSTRUCTCLASS "rdclass" -#define FROMSTRUCTTYPE "type" -#define FROMSTRUCTDEF "use_default = true" - -#define TOSTRUCTARGS "rdata, target, mctx" -#define TOSTRUCTCLASS "rdata->rdclass" -#define TOSTRUCTTYPE "rdata->type" -#define TOSTRUCTDEF "use_default = true" - -#define FREESTRUCTARGS "source" -#define FREESTRUCTCLASS "common->rdclass" -#define FREESTRUCTTYPE "common->rdtype" -#define FREESTRUCTDEF NULL - -#define COMPAREARGS "rdata1, rdata2" -#define COMPARECLASS "rdata1->rdclass" -#define COMPARETYPE "rdata1->type" -#define COMPAREDEF "use_default = true" - -#define ADDITIONALDATAARGS "rdata, add, arg" -#define ADDITIONALDATACLASS "rdata->rdclass" -#define ADDITIONALDATATYPE "rdata->type" -#define ADDITIONALDATADEF "use_default = true" - -#define DIGESTARGS "rdata, digest, arg" -#define DIGESTCLASS "rdata->rdclass" -#define DIGESTTYPE "rdata->type" -#define DIGESTDEF "use_default = true" - -#define CHECKOWNERARGS "name, rdclass, type, wildcard" -#define CHECKOWNERCLASS "rdclass" -#define CHECKOWNERTYPE "type" -#define CHECKOWNERDEF "result = true" - -#define CHECKNAMESARGS "rdata, owner, bad" -#define CHECKNAMESCLASS "rdata->rdclass" -#define CHECKNAMESTYPE "rdata->type" -#define CHECKNAMESDEF "result = true" - -static const char copyright[] = -"/*\n" -" * Copyright (C) 1998%s Internet Systems Consortium, Inc. (\"ISC\")\n" -" *\n" -" * This Source Code Form is subject to the terms of the Mozilla Public\n" -" * License, v. 2.0. If a copy of the MPL was not distributed with this\n" -" * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n" -" */\n" -"\n" -"/***************\n" -" ***************\n" -" *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n" -" *************** DO NOT EDIT!\n" -" ***************\n" -" ***************/\n" -"\n" -"/*! \\file */\n" -"\n"; - -#define STR_EXPAND(tok) #tok -#define STR(tok) STR_EXPAND(tok) - -#define TYPENAMES 256 -#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ -#define TYPECLASSBUF (TYPECLASSLEN + 1) -#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" -#define ATTRIBUTESIZE 256 - -static struct cc { - struct cc *next; - int rdclass; - char classbuf[TYPECLASSBUF]; -} *classes; - -static struct tt { - struct tt *next; - uint16_t rdclass; - uint16_t type; - char classbuf[TYPECLASSBUF]; - char typebuf[TYPECLASSBUF]; - char dirbuf[PATH_MAX-30]; -} *types; - -static struct ttnam { - char typebuf[TYPECLASSBUF]; - char macroname[TYPECLASSBUF]; - char attr[ATTRIBUTESIZE]; - unsigned int sorted; - uint16_t type; -} typenames[TYPENAMES]; - -static int maxtype = -1; - -static char * -upper(char *); -static char * -funname(const char *, char *); -static void -doswitch(const char *, const char *, const char *, const char *, - const char *, const char *); -static void -add(int, const char *, int, const char *, const char *); -static void -sd(int, const char *, const char *, char); -static void -insert_into_typenames(int, const char *, const char *); - -/*% - * If you use more than 10 of these in, say, a printf(), you'll have problems. - */ -static char * -upper(char *s) { - static int buf_to_use = 0; - static char buf[10][256]; - char *b; - int c; - - buf_to_use++; - if (buf_to_use > 9) - buf_to_use = 0; - - b = buf[buf_to_use]; - memset(b, 0, 256); - - while ((c = (*s++) & 0xff)) - *b++ = islower(c) ? toupper(c) : c; - *b = '\0'; - return (buf[buf_to_use]); -} - -static char * -funname(const char *s, char *buf) { - char *b = buf; - char c; - - INSIST(strlen(s) < TYPECLASSBUF); - while ((c = *s++)) { - *b++ = (c == '-') ? '_' : c; - } - *b = '\0'; - return (buf); -} - -static void -doswitch(const char *name, const char *function, const char *args, - const char *tsw, const char *csw, const char *res) -{ - struct tt *tt; - int first = 1; - int lasttype = 0; - int subswitch = 0; - char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; - const char *result = " result ="; - - if (res == NULL) - result = ""; - - for (tt = types; tt != NULL; tt = tt->next) { - if (first) { - fprintf(stdout, "\n#define %s \\\n", name); - fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw); - first = 0; - } - if (tt->type != lasttype && subswitch) { - if (res == NULL) - fprintf(stdout, "\t\tdefault: break; \\\n"); - else - fprintf(stdout, - "\t\tdefault: %s; break; \\\n", res); - fputs(/*{*/ "\t\t} \\\n", stdout); - fputs("\t\tbreak; \\\n", stdout); - subswitch = 0; - } - if (tt->rdclass && tt->type != lasttype) { - fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/, - tt->type, csw); - subswitch = 1; - } - if (tt->rdclass == 0) - fprintf(stdout, - "\tcase %d:%s %s_%s(%s); break;", - tt->type, result, function, - funname(tt->typebuf, buf1), args); - else - fprintf(stdout, - "\t\tcase %d:%s %s_%s_%s(%s); break;", - tt->rdclass, result, function, - funname(tt->classbuf, buf1), - funname(tt->typebuf, buf2), args); - fputs(" \\\n", stdout); - lasttype = tt->type; - } - if (subswitch) { - if (res == NULL) - fprintf(stdout, "\t\tdefault: break; \\\n"); - else - fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); - fputs(/*{*/ "\t\t} \\\n", stdout); - fputs("\t\tbreak; \\\n", stdout); - } - if (first) { - if (res == NULL) - fprintf(stdout, "\n#define %s\n", name); - else - fprintf(stdout, "\n#define %s %s;\n", name, res); - } else { - if (res == NULL) - fprintf(stdout, "\tdefault: break; \\\n"); - else - fprintf(stdout, "\tdefault: %s; break; \\\n", res); - fputs(/*{*/ "\t}\n", stdout); - } -} - -static struct ttnam * -find_typename(int type) { - int i; - - for (i = 0; i < TYPENAMES; i++) { - if (typenames[i].typebuf[0] != 0 && - typenames[i].type == type) - { - return (&typenames[i]); - } - } - return (NULL); -} - -static void -insert_into_typenames(int type, const char *typebuf, const char *attr) { - struct ttnam *ttn = NULL; - size_t c; - int i, n; - char tmp[256]; - - INSIST(strlen(typebuf) < TYPECLASSBUF); - for (i = 0; i < TYPENAMES; i++) { - if (typenames[i].typebuf[0] != 0 && - typenames[i].type == type && - strcmp(typebuf, typenames[i].typebuf) != 0) - { - fprintf(stderr, - "Error: type %d has two names: %s, %s\n", - type, typenames[i].typebuf, typebuf); - exit(1); - } - if (typenames[i].typebuf[0] == 0 && ttn == NULL) { - ttn = &typenames[i]; - } - } - if (ttn == NULL) { - fprintf(stderr, "Error: typenames array too small\n"); - exit(1); - } - - /* XXXMUKS: This is redundant due to the INSIST above. */ - if (strlen(typebuf) > sizeof(ttn->typebuf) - 1) { - fprintf(stderr, "Error: type name %s is too long\n", - typebuf); - exit(1); - } - - strncpy(ttn->typebuf, typebuf, sizeof(ttn->typebuf)); - ttn->typebuf[sizeof(ttn->typebuf) - 1] = '\0'; - - strncpy(ttn->macroname, ttn->typebuf, sizeof(ttn->macroname)); - ttn->macroname[sizeof(ttn->macroname) - 1] = '\0'; - - ttn->type = type; - c = strlen(ttn->macroname); - while (c > 0) { - if (ttn->macroname[c - 1] == '-') { - ttn->macroname[c - 1] = '_'; - } - c--; - } - - if (attr == NULL) { - n = snprintf(tmp, sizeof(tmp), - "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); - INSIST(n > 0 && (unsigned)n < sizeof(tmp)); - attr = tmp; - } - - if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { - fprintf(stderr, "Error: type %d has different attributes: " - "%s, %s\n", type, ttn->attr, attr); - exit(1); - } - - if (strlen(attr) > sizeof(ttn->attr) - 1) { - fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", - attr, typebuf); - exit(1); - } - - strncpy(ttn->attr, attr, sizeof(ttn->attr)); - ttn->attr[sizeof(ttn->attr) - 1] = '\0'; - - ttn->sorted = 0; - if (maxtype < type) { - maxtype = type; - } -} - -static void -add(int rdclass, const char *classbuf, int type, const char *typebuf, - const char *dirbuf) -{ - struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); - struct tt *tt, *oldtt; - struct cc *newcc; - struct cc *cc, *oldcc; - - INSIST(strlen(typebuf) < TYPECLASSBUF); - INSIST(strlen(classbuf) < TYPECLASSBUF); - INSIST(strlen(dirbuf) < PATH_MAX); - - insert_into_typenames(type, typebuf, NULL); - - if (newtt == NULL) { - fprintf(stderr, "malloc() failed\n"); - exit(1); - } - - newtt->next = NULL; - newtt->rdclass = rdclass; - newtt->type = type; - - strncpy(newtt->classbuf, classbuf, sizeof(newtt->classbuf)); - newtt->classbuf[sizeof(newtt->classbuf) - 1] = '\0'; - - strncpy(newtt->typebuf, typebuf, sizeof(newtt->typebuf)); - newtt->typebuf[sizeof(newtt->typebuf) - 1] = '\0'; - - if (strncmp(dirbuf, "./", 2) == 0) { - dirbuf += 2; - } - strncpy(newtt->dirbuf, dirbuf, sizeof(newtt->dirbuf)); - newtt->dirbuf[sizeof(newtt->dirbuf) - 1] = '\0'; - - tt = types; - oldtt = NULL; - - while ((tt != NULL) && (tt->type < type)) { - oldtt = tt; - tt = tt->next; - } - - while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { - if (strcmp(tt->typebuf, typebuf) != 0) { - exit(1); - } - oldtt = tt; - tt = tt->next; - } - - if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) { - exit(1); - } - - newtt->next = tt; - if (oldtt != NULL) { - oldtt->next = newtt; - } else { - types = newtt; - } - - /* - * Do a class switch for this type. - */ - if (rdclass == 0) { - return; - } - - newcc = (struct cc *)malloc(sizeof(*newcc)); - if (newcc == NULL) { - fprintf(stderr, "malloc() failed\n"); - exit(1); - } - newcc->rdclass = rdclass; - strncpy(newcc->classbuf, classbuf, sizeof(newcc->classbuf)); - newcc->classbuf[sizeof(newcc->classbuf) - 1] = '\0'; - cc = classes; - oldcc = NULL; - - while ((cc != NULL) && (cc->rdclass < rdclass)) { - oldcc = cc; - cc = cc->next; - } - - if ((cc != NULL) && cc->rdclass == rdclass) { - free((char *)newcc); - return; - } - - newcc->next = cc; - if (oldcc != NULL) { - oldcc->next = newcc; - } else { - classes = newcc; - } -} - -static void -sd(int rdclass, const char *classbuf, const char *dirbuf, char filetype) { - char buf[TYPECLASSLEN + sizeof("_65535.h")]; - char typebuf[TYPECLASSBUF]; - int type, n; - isc_dir_t dir; - - if (!start_directory(dirbuf, &dir)) { - return; - } - - while (next_file(&dir)) { - if (sscanf(dir.filename, TYPECLASSFMT, typebuf, &type) != 2) { - continue; - } - if ((type > 65535) || (type < 0)) { - continue; - } - - n = snprintf(buf, sizeof(buf), "%s_%d.%c", typebuf, - type, filetype); - INSIST(n > 0 && (unsigned)n < sizeof(buf)); - if (strcmp(buf, dir.filename) != 0) { - continue; - } - add(rdclass, classbuf, type, typebuf, dirbuf); - } - - end_directory(&dir); -} - -static unsigned int -HASH(char *string) { - size_t n; - unsigned char a, b; - - n = strlen(string); - if (n == 0) { - fprintf(stderr, "n == 0?\n"); - exit(1); - } - a = tolower((unsigned char)string[0]); - b = tolower((unsigned char)string[n - 1]); - - return ((a + n) * b) % 256; -} - -int -main(int argc, char **argv) { - char buf[PATH_MAX]; - char srcdir[PATH_MAX]; - int rdclass; - char classbuf[TYPECLASSBUF]; - struct tt *tt; - struct cc *cc; - struct ttnam *ttn, *ttn2; - unsigned int hash; - time_t now; - char year[11]; - int lasttype; - int code = 1; - int class_enum = 0; - int type_enum = 0; - int structs = 0; - int depend = 0; - int c, i, j, n; - char buf1[TYPECLASSBUF]; - char filetype = 'c'; - FILE *fd; - char *prefix = NULL; - char *suffix = NULL; - char *file = NULL; - char *source_date_epoch; - unsigned long long epoch; - char *endptr; - isc_dir_t dir; - - for (i = 0; i < TYPENAMES; i++) - memset(&typenames[i], 0, sizeof(typenames[i])); - - srcdir[0] = '\0'; - while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) - switch (c) { - case 'c': - code = 0; - depend = 0; - type_enum = 0; - class_enum = 1; - filetype = 'c'; - structs = 0; - break; - case 'd': - code = 0; - depend = 1; - class_enum = 0; - type_enum = 0; - structs = 0; - filetype = 'h'; - break; - case 't': - code = 0; - depend = 0; - class_enum = 0; - type_enum = 1; - filetype = 'c'; - structs = 0; - break; - case 'i': - code = 0; - depend = 0; - class_enum = 0; - type_enum = 0; - structs = 1; - filetype = 'h'; - break; - case 's': - if (strlen(isc_commandline_argument) > - PATH_MAX - 2 * TYPECLASSLEN - - sizeof("/rdata/_65535_65535")) - { - fprintf(stderr, "\"%s\" too long\n", - isc_commandline_argument); - exit(1); - } - n = snprintf(srcdir, sizeof(srcdir), "%s/", - isc_commandline_argument); - INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); - break; - case 'F': - file = isc_commandline_argument; - break; - case 'P': - prefix = isc_commandline_argument; - break; - case 'S': - suffix = isc_commandline_argument; - break; - case '?': - exit(1); - } - - n = snprintf(buf, sizeof(buf), "%srdata", srcdir); - INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); - - if (!start_directory(buf, &dir)) { - exit(1); - } - - while (next_file(&dir)) { - if (sscanf(dir.filename, TYPECLASSFMT, classbuf, - &rdclass) != 2) - { - continue; - } - if ((rdclass > 65535) || (rdclass < 0)) { - continue; - } - - n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", - srcdir, classbuf, rdclass); - INSIST(n > 0 && (unsigned)n < sizeof(buf)); - if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) { - continue; - } - sd(rdclass, classbuf, buf, filetype); - } - end_directory(&dir); - n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); - INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); - sd(0, "", buf, filetype); - - source_date_epoch = getenv("SOURCE_DATE_EPOCH"); - if (source_date_epoch) { - errno = 0; - epoch = strtoull(source_date_epoch, &endptr, 10); - if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) - || (errno != 0 && epoch == 0)) { - fprintf(stderr, "Environment variable " - "$SOURCE_DATE_EPOCH: strtoull: %s\n", - strerror(errno)); - exit (EXIT_FAILURE); - } - if (endptr == source_date_epoch) { - fprintf(stderr, "Environment variable " - "$SOURCE_DATE_EPOCH: " - "No digits were found: %s\n", - endptr); - exit (EXIT_FAILURE); - } - if (*endptr != '\0') { - fprintf(stderr, "Environment variable " - "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n", - endptr); - exit (EXIT_FAILURE); - } - if (epoch > ULONG_MAX) { - fprintf(stderr, "Environment variable " - "$SOURCE_DATE_EPOCH: value must be " - "smaller than or equal to: %lu but " - "was found to be: %llu \n", - ULONG_MAX, epoch); - exit (EXIT_FAILURE); - } - now = epoch; - } else { - time(&now); - } - - if (now != -1) { - struct tm t, *tm = gmtime_r(&now, &t); - - if (tm != NULL && tm->tm_year > 104) { - n = snprintf(year, sizeof(year), "-%d", - tm->tm_year + 1900); - INSIST(n > 0 && (unsigned)n < sizeof(year)); - } else { - snprintf(year, sizeof(year), "-2016"); - } - } else { - snprintf(year, sizeof(year), "-2016"); - } - - if (!depend) { - fprintf(stdout, copyright, year); - } - - if (code) { - fputs("#ifndef DNS_CODE_H\n", stdout); - fputs("#define DNS_CODE_H 1\n\n", stdout); - - fputs("#include \n\n", stdout); - fputs("#include \n\n", stdout); - - for (tt = types; tt != NULL; tt = tt->next) { - fprintf(stdout, "#include \"%s/%s_%d.c\"\n", - tt->dirbuf, tt->typebuf, tt->type); - } - - fputs("\n\n", stdout); - - doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, - FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); - doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, - TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); - doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, - FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); - doswitch("TOWIRESWITCH", "towire", TOWIREARGS, - TOWIRETYPE, TOWIRECLASS, TOWIREDEF); - doswitch("COMPARESWITCH", "compare", COMPAREARGS, - COMPARETYPE, COMPARECLASS, COMPAREDEF); - doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, - COMPARETYPE, COMPARECLASS, COMPAREDEF); - doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, - FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); - doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, - TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); - doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, - FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); - doswitch("ADDITIONALDATASWITCH", "additionaldata", - ADDITIONALDATAARGS, ADDITIONALDATATYPE, - ADDITIONALDATACLASS, ADDITIONALDATADEF); - doswitch("DIGESTSWITCH", "digest", - DIGESTARGS, DIGESTTYPE, - DIGESTCLASS, DIGESTDEF); - doswitch("CHECKOWNERSWITCH", "checkowner", - CHECKOWNERARGS, CHECKOWNERTYPE, - CHECKOWNERCLASS, CHECKOWNERDEF); - doswitch("CHECKNAMESSWITCH", "checknames", - CHECKNAMESARGS, CHECKNAMESTYPE, - CHECKNAMESCLASS, CHECKNAMESDEF); - - /* - * From here down, we are processing the rdata names and - * attributes. - */ - -#define PRINT_COMMA(x) (x == maxtype ? "" : ",") - -#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ - "DNS_RDATATYPEATTR_NOTQUESTION" -#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ - "DNS_RDATATYPEATTR_QUESTIONONLY" -#define RESERVEDNAME "0" -#define RESERVED "DNS_RDATATYPEATTR_RESERVED" - - /* - * Add in reserved/special types. This will let us - * sort them without special cases. - */ - insert_into_typenames(100, "uinfo", RESERVEDNAME); - insert_into_typenames(101, "uid", RESERVEDNAME); - insert_into_typenames(102, "gid", RESERVEDNAME); - insert_into_typenames(103, "unspec", RESERVEDNAME); - insert_into_typenames(251, "ixfr", METAQUESTIONONLY); - insert_into_typenames(252, "axfr", METAQUESTIONONLY); - insert_into_typenames(253, "mailb", METAQUESTIONONLY); - insert_into_typenames(254, "maila", METAQUESTIONONLY); - insert_into_typenames(255, "any", METAQUESTIONONLY); - - /* - * Spit out a quick and dirty hash function. Here, - * we walk through the list of type names, and calculate - * a hash. This isn't perfect, but it will generate "pretty - * good" estimates. Lowercase the characters before - * computing in all cases. - * - * Here, walk the list from top to bottom, calculating - * the hash (mod 256) for each name. - */ - fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); - fprintf(stdout, "\tdo { \\\n"); - fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" - "\t\t strncasecmp(_s,(_tn)," - "(sizeof(_s) - 1)) == 0) { \\\n"); - fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " - "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); - fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); - fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); - fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); - fprintf(stdout, "\t\t} \\\n"); - fprintf(stdout, "\t} while (0)\n\n"); - - fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," - "_typename,_length,_typep) \\\n"); - fprintf(stdout, "\tswitch (_hash) { \\\n"); - for (i = 0; i <= maxtype; i++) { - ttn = find_typename(i); - if (ttn == NULL) { - continue; - } - - /* - * Skip entries we already processed. - */ - if (ttn->sorted != 0) { - continue; - } - - hash = HASH(ttn->typebuf); - fprintf(stdout, "\t\tcase %u: \\\n", hash); - - /* - * Find all other entries that happen to match - * this hash. - */ - for (j = 0; j <= maxtype; j++) { - ttn2 = find_typename(j); - if (ttn2 == NULL) { - continue; - } - if (hash == HASH(ttn2->typebuf)) { - fprintf(stdout, "\t\t\t" - "RDATATYPE_COMPARE" - "(\"%s\", %d, _typename, " - " _length, _typep); \\\n", - ttn2->typebuf, ttn2->type); - ttn2->sorted = 1; - } - } - fprintf(stdout, "\t\t\tbreak; \\\n"); - } - fprintf(stdout, "\t}\n"); - - fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); - fprintf(stdout, "\tswitch (type) { \\\n"); - for (i = 0; i <= maxtype; i++) { - ttn = find_typename(i); - if (ttn == NULL) { - continue; - } - fprintf(stdout, "\tcase %d: return (%s); \\\n", - i, upper(ttn->attr)); - } - fprintf(stdout, "\t}\n"); - - fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); - fprintf(stdout, "\tswitch (type) { \\\n"); - for (i = 0; i <= maxtype; i++) { - ttn = find_typename(i); - if (ttn == NULL) { - continue; - } - /* - * Remove KEYDATA (65533) from the type to memonic - * translation as it is internal use only. This - * stops the tools from displaying KEYDATA instead - * of TYPE65533. - */ - if (i == 65533U) { - continue; - } - fprintf(stdout, "\tcase %d: return " - "(str_totext(\"%s\", target)); \\\n", - i, upper(ttn->typebuf)); - } - fprintf(stdout, "\t}\n"); - - fputs("#endif /* DNS_CODE_H */\n", stdout); - } else if (type_enum) { - char *s; - - fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); - fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); - - fprintf(stdout, "enum {\n"); - fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); - - lasttype = 0; - for (tt = types; tt != NULL; tt = tt->next) { - if (tt->type != lasttype) { - fprintf(stdout, - "\tdns_rdatatype_%s = %d,\n", - funname(tt->typebuf, buf1), - lasttype = tt->type); - } - } - - fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); - fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); - fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); - fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); - fprintf(stdout, "\tdns_rdatatype_any = 255\n"); - - fprintf(stdout, "};\n\n"); - - fprintf(stdout, "#define dns_rdatatype_none\t" - "((dns_rdatatype_t)dns_rdatatype_none)\n"); - - for (tt = types; tt != NULL; tt = tt->next) { - if (tt->type != lasttype) { - s = funname(tt->typebuf, buf1); - fprintf(stdout, - "#define dns_rdatatype_%s\t%s" - "((dns_rdatatype_t)dns_rdatatype_%s)" - "\n", - s, strlen(s) < 2U ? "\t" : "", s); - lasttype = tt->type; - } - } - - fprintf(stdout, "#define dns_rdatatype_ixfr\t" - "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); - fprintf(stdout, "#define dns_rdatatype_axfr\t" - "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); - fprintf(stdout, "#define dns_rdatatype_mailb\t" - "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); - fprintf(stdout, "#define dns_rdatatype_maila\t" - "((dns_rdatatype_t)dns_rdatatype_maila)\n"); - fprintf(stdout, "#define dns_rdatatype_any\t" - "((dns_rdatatype_t)dns_rdatatype_any)\n"); - - fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); - - } else if (class_enum) { - char *s; - int classnum; - - fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); - fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); - - fprintf(stdout, "enum {\n"); - - fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); - fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" - "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); - -#define PRINTCLASS(name, num) \ - do { \ - s = funname(name, buf1); \ - classnum = num; \ - fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ - classnum != 255 ? "," : ""); \ - fprintf(stdout, "#define dns_rdataclass_%s\t" \ - "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ - } while (0) - - for (cc = classes; cc != NULL; cc = cc->next) { - if (cc->rdclass == 3) { - PRINTCLASS("chaos", 3); - } else if (cc->rdclass == 255) { - PRINTCLASS("none", 254); - } - PRINTCLASS(cc->classbuf, cc->rdclass); - } - -#undef PRINTCLASS - - fprintf(stdout, "};\n\n"); - fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); - } else if (structs) { - if (prefix != NULL) { - if ((fd = fopen(prefix,"r")) != NULL) { - while (fgets(buf, sizeof(buf), fd) != NULL) { - fputs(buf, stdout); - } - fclose(fd); - } - } - for (tt = types; tt != NULL; tt = tt->next) { - snprintf(buf, sizeof(buf), "%s/%s_%d.h", - tt->dirbuf, tt->typebuf, tt->type); - if ((fd = fopen(buf,"r")) != NULL) { - while (fgets(buf, sizeof(buf), fd) != NULL) { - fputs(buf, stdout); - } - fclose(fd); - } - } - if (suffix != NULL) { - if ((fd = fopen(suffix,"r")) != NULL) { - while (fgets(buf, sizeof(buf), fd) != NULL) { - fputs(buf, stdout); - } - fclose(fd); - } - } - } else if (depend) { - for (tt = types; tt != NULL; tt = tt->next) { - fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, - tt->dirbuf, tt->typebuf, tt->type); - } - } - - if (ferror(stdout) != 0) { - exit(1); - } - - return (0); -} diff --git a/lib/dns-pkcs11/geoip.c b/lib/dns-pkcs11/geoip.c deleted file mode 100644 index 0408667..0000000 --- a/lib/dns-pkcs11/geoip.c +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include - -#include -#include -#include - -#include -#include - -#include -#include -#ifndef WIN32 -#include -#else -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ -#endif -#include -#endif /* WIN32 */ -#include - -#ifdef HAVE_GEOIP -#include -#include - -/* - * This structure preserves state from the previous GeoIP lookup, - * so that successive lookups for the same data from the same IP - * address will not require repeated calls into the GeoIP library - * to look up data in the database. This should improve performance - * somewhat. - * - * For lookups in the City and Region databases, we preserve pointers - * to the GeoIPRecord and GeoIPregion structures; these will need to be - * freed by GeoIPRecord_delete() and GeoIPRegion_delete(). - * - * for lookups in ISP, AS, Org and Domain we prserve a pointer to - * the returned name; these must be freed by free(). - * - * For lookups in Country we preserve a pointer to the text of - * the country code, name, etc (we use a different pointer for this - * than for the names returned by Org, ISP, etc, because those need - * to be freed but country lookups do not). - * - * For lookups in Netspeed we preserve the returned ID. - * - * XXX: Currently this mechanism is only used for IPv4 lookups; the - * family and addr6 fields are to be used IPv6 is added. - */ -typedef struct geoip_state { - uint16_t subtype; - unsigned int family; - uint32_t ipnum; - geoipv6_t ipnum6; - uint8_t scope; - GeoIPRecord *record; - GeoIPRegion *region; - const char *text; - char *name; - int id; - isc_mem_t *mctx; -} geoip_state_t; - -#ifdef ISC_PLATFORM_USETHREADS -static isc_mutex_t key_mutex; -static bool state_key_initialized = false; -static isc_thread_key_t state_key; -static isc_once_t mutex_once = ISC_ONCE_INIT; -static isc_mem_t *state_mctx = NULL; - -static void -key_mutex_init(void) { - RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS); -} - -static void -free_state(void *arg) { - geoip_state_t *state = arg; - if (state != NULL && state->record != NULL) - GeoIPRecord_delete(state->record); - if (state != NULL) - isc_mem_putanddetach(&state->mctx, - state, sizeof(geoip_state_t)); - isc_thread_key_setspecific(state_key, NULL); -} - -static isc_result_t -state_key_init(void) { - isc_result_t result; - - result = isc_once_do(&mutex_once, key_mutex_init); - if (result != ISC_R_SUCCESS) - return (result); - - if (!state_key_initialized) { - LOCK(&key_mutex); - if (!state_key_initialized) { - int ret; - - if (state_mctx == NULL) - result = isc_mem_create2(0, 0, &state_mctx, 0); - if (result != ISC_R_SUCCESS) - goto unlock; - isc_mem_setname(state_mctx, "geoip_state", NULL); - isc_mem_setdestroycheck(state_mctx, false); - - ret = isc_thread_key_create(&state_key, free_state); - if (ret == 0) - state_key_initialized = true; - else - result = ISC_R_FAILURE; - } - unlock: - UNLOCK(&key_mutex); - } - - return (result); -} -#else -static geoip_state_t saved_state; -#endif - -static void -clean_state(geoip_state_t *state) { - if (state == NULL) - return; - - if (state->record != NULL) { - GeoIPRecord_delete(state->record); - state->record = NULL; - } - if (state->region != NULL) { - GeoIPRegion_delete(state->region); - state->region = NULL; - } - if (state->name != NULL) { - free (state->name); - state->name = NULL; - } - state->ipnum = 0; - state->text = NULL; - state->id = 0; -} - -static isc_result_t -set_state(unsigned int family, uint32_t ipnum, const geoipv6_t *ipnum6, - uint8_t scope, dns_geoip_subtype_t subtype, GeoIPRecord *record, - GeoIPRegion *region, char *name, const char *text, int id) -{ - geoip_state_t *state = NULL; -#ifdef ISC_PLATFORM_USETHREADS - isc_result_t result; - - result = state_key_init(); - if (result != ISC_R_SUCCESS) - return (result); - - state = (geoip_state_t *) isc_thread_key_getspecific(state_key); - if (state == NULL) { - state = (geoip_state_t *) isc_mem_get(state_mctx, - sizeof(geoip_state_t)); - if (state == NULL) - return (ISC_R_NOMEMORY); - memset(state, 0, sizeof(*state)); - - result = isc_thread_key_setspecific(state_key, state); - if (result != ISC_R_SUCCESS) { - isc_mem_put(state_mctx, state, sizeof(geoip_state_t)); - return (result); - } - - isc_mem_attach(state_mctx, &state->mctx); - } else - clean_state(state); -#else - state = &saved_state; - clean_state(state); -#endif - - if (family == AF_INET) { - state->ipnum = ipnum; - } else { - INSIST(ipnum6 != NULL); - state->ipnum6 = *ipnum6; - } - - state->family = family; - state->subtype = subtype; - state->scope = scope; - state->record = record; - state->region = region; - state->name = name; - state->text = text; - state->id = id; - - return (ISC_R_SUCCESS); -} - -static geoip_state_t * -get_state_for(unsigned int family, uint32_t ipnum, - const geoipv6_t *ipnum6) -{ - geoip_state_t *state; - -#ifdef ISC_PLATFORM_USETHREADS - isc_result_t result; - - result = state_key_init(); - if (result != ISC_R_SUCCESS) - return (NULL); - - state = (geoip_state_t *) isc_thread_key_getspecific(state_key); - if (state == NULL) - return (NULL); -#else - state = &saved_state; -#endif - - if (state->family == family && - ((state->family == AF_INET && state->ipnum == ipnum) || - (state->family == AF_INET6 && ipnum6 != NULL && - memcmp(state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0))) - return (state); - - return (NULL); -} - -/* - * Country lookups are performed if the previous lookup was from a - * different IP address than the current, or was for a search of a - * different subtype. - */ -static const char * -country_lookup(GeoIP *db, dns_geoip_subtype_t subtype, - unsigned int family, - uint32_t ipnum, const geoipv6_t *ipnum6, - uint8_t *scope) -{ - geoip_state_t *prev_state = NULL; - const char *text = NULL; - GeoIPLookup gl; - - REQUIRE(db != NULL); - -#ifndef HAVE_GEOIP_V6 - /* no IPv6 support? give up now */ - if (family == AF_INET6) - return (NULL); -#endif - - prev_state = get_state_for(family, ipnum, ipnum6); - if (prev_state != NULL && prev_state->subtype == subtype) { - text = prev_state->text; - if (scope != NULL) - *scope = prev_state->scope; - } - - if (text == NULL) { - switch (subtype) { - case dns_geoip_country_code: - if (family == AF_INET) - text = GeoIP_country_code_by_ipnum_gl(db, - ipnum, &gl); -#ifdef HAVE_GEOIP_V6 - else - text = GeoIP_country_code_by_ipnum_v6_gl(db, - *ipnum6, &gl); -#endif - break; - case dns_geoip_country_code3: - if (family == AF_INET) - text = GeoIP_country_code3_by_ipnum_gl(db, - ipnum, &gl); -#ifdef HAVE_GEOIP_V6 - else - text = GeoIP_country_code3_by_ipnum_v6_gl(db, - *ipnum6, &gl); -#endif - break; - case dns_geoip_country_name: - if (family == AF_INET) - text = GeoIP_country_name_by_ipnum_gl(db, - ipnum, &gl); -#ifdef HAVE_GEOIP_V6 - else - text = GeoIP_country_name_by_ipnum_v6_gl(db, - *ipnum6, &gl); -#endif - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (text == NULL) - return (NULL); - - if (scope != NULL) - *scope = gl.netmask; - - set_state(family, ipnum, ipnum6, gl.netmask, subtype, - NULL, NULL, NULL, text, 0); - } - - return (text); -} - -static char * -city_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) { - const char *s; - char *deconst; - - REQUIRE(record != NULL); - REQUIRE(maxlen != NULL); - - /* Set '*maxlen' to the maximum length of this subtype, if any */ - switch (subtype) { - case dns_geoip_city_countrycode: - case dns_geoip_city_region: - case dns_geoip_city_continentcode: - *maxlen = 2; - break; - - case dns_geoip_city_countrycode3: - *maxlen = 3; - break; - - default: - /* No fixed length; just use strcasecmp() for comparison */ - *maxlen = 255; - } - - switch (subtype) { - case dns_geoip_city_countrycode: - return (record->country_code); - case dns_geoip_city_countrycode3: - return (record->country_code3); - case dns_geoip_city_countryname: - return (record->country_name); - case dns_geoip_city_region: - return (record->region); - case dns_geoip_city_regionname: - s = GeoIP_region_name_by_code(record->country_code, - record->region); - DE_CONST(s, deconst); - return (deconst); - case dns_geoip_city_name: - return (record->city); - case dns_geoip_city_postalcode: - return (record->postal_code); - case dns_geoip_city_continentcode: - return (record->continent_code); - case dns_geoip_city_timezonecode: - s = GeoIP_time_zone_by_country_and_region(record->country_code, - record->region); - DE_CONST(s, deconst); - return (deconst); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static bool -is_city(dns_geoip_subtype_t subtype) { - switch (subtype) { - case dns_geoip_city_countrycode: - case dns_geoip_city_countrycode3: - case dns_geoip_city_countryname: - case dns_geoip_city_region: - case dns_geoip_city_regionname: - case dns_geoip_city_name: - case dns_geoip_city_postalcode: - case dns_geoip_city_continentcode: - case dns_geoip_city_timezonecode: - case dns_geoip_city_metrocode: - case dns_geoip_city_areacode: - return (true); - default: - return (false); - } -} - -/* - * GeoIPRecord lookups are performed if the previous lookup was - * from a different IP address than the current, or was for a search - * outside the City database. - */ -static GeoIPRecord * -city_lookup(GeoIP *db, dns_geoip_subtype_t subtype, - unsigned int family, uint32_t ipnum, - const geoipv6_t *ipnum6, - uint8_t *scope) -{ - GeoIPRecord *record = NULL; - geoip_state_t *prev_state = NULL; - - REQUIRE(db != NULL); - -#ifndef HAVE_GEOIP_V6 - /* no IPv6 support? give up now */ - if (family == AF_INET6) - return (NULL); -#endif - - prev_state = get_state_for(family, ipnum, ipnum6); - if (prev_state != NULL && is_city(prev_state->subtype)) { - record = prev_state->record; - if (scope != NULL) - *scope = record->netmask; - } - - if (record == NULL) { - if (family == AF_INET) - record = GeoIP_record_by_ipnum(db, ipnum); -#ifdef HAVE_GEOIP_V6 - else - record = GeoIP_record_by_ipnum_v6(db, *ipnum6); -#endif - if (record == NULL) - return (NULL); - - if (scope != NULL) - *scope = record->netmask; - - set_state(family, ipnum, ipnum6, record->netmask, subtype, - record, NULL, NULL, NULL, 0); - } - - return (record); -} - -static char * region_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) { - const char *s; - char *deconst; - - REQUIRE(region != NULL); - REQUIRE(maxlen != NULL); - - switch (subtype) { - case dns_geoip_region_countrycode: - *maxlen = 2; - return (region->country_code); - case dns_geoip_region_code: - *maxlen = 2; - return (region->region); - case dns_geoip_region_name: - *maxlen = 255; - s = GeoIP_region_name_by_code(region->country_code, - region->region); - DE_CONST(s, deconst); - return (deconst); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static bool -is_region(dns_geoip_subtype_t subtype) { - switch (subtype) { - case dns_geoip_region_countrycode: - case dns_geoip_region_code: - return (true); - default: - return (false); - } -} - -/* - * GeoIPRegion lookups are performed if the previous lookup was - * from a different IP address than the current, or was for a search - * outside the Region database. - */ -static GeoIPRegion * -region_lookup(GeoIP *db, dns_geoip_subtype_t subtype, - uint32_t ipnum, uint8_t *scope) -{ - GeoIPRegion *region = NULL; - geoip_state_t *prev_state = NULL; - GeoIPLookup gl; - - REQUIRE(db != NULL); - - prev_state = get_state_for(AF_INET, ipnum, NULL); - if (prev_state != NULL && is_region(prev_state->subtype)) { - region = prev_state->region; - if (scope != NULL) - *scope = prev_state->scope; - } - - if (region == NULL) { - region = GeoIP_region_by_ipnum_gl(db, ipnum, &gl); - if (region == NULL) - return (NULL); - - if (scope != NULL) - *scope = gl.netmask; - - set_state(AF_INET, ipnum, NULL, gl.netmask, - subtype, NULL, region, NULL, NULL, 0); - } - - return (region); -} - -/* - * ISP, Organization, AS Number and Domain lookups are performed if - * the previous lookup was from a different IP address than the current, - * or was for a search of a different subtype. - */ -static char * -name_lookup(GeoIP *db, dns_geoip_subtype_t subtype, - uint32_t ipnum, uint8_t *scope) -{ - char *name = NULL; - geoip_state_t *prev_state = NULL; - GeoIPLookup gl; - - REQUIRE(db != NULL); - - prev_state = get_state_for(AF_INET, ipnum, NULL); - if (prev_state != NULL && prev_state->subtype == subtype) { - name = prev_state->name; - if (scope != NULL) - *scope = prev_state->scope; - } - - if (name == NULL) { - name = GeoIP_name_by_ipnum_gl(db, ipnum, &gl); - if (name == NULL) - return (NULL); - - if (scope != NULL) - *scope = gl.netmask; - - set_state(AF_INET, ipnum, NULL, gl.netmask, - subtype, NULL, NULL, name, NULL, 0); - } - - return (name); -} - -/* - * Netspeed lookups are performed if the previous lookup was from a - * different IP address than the current, or was for a search of a - * different subtype. - */ -static int -netspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype, - uint32_t ipnum, uint8_t *scope) -{ - geoip_state_t *prev_state = NULL; - bool found = false; - GeoIPLookup gl; - int id = -1; - - REQUIRE(db != NULL); - - prev_state = get_state_for(AF_INET, ipnum, NULL); - if (prev_state != NULL && prev_state->subtype == subtype) { - id = prev_state->id; - if (scope != NULL) - *scope = prev_state->scope; - found = true; - } - - if (!found) { - id = GeoIP_id_by_ipnum_gl(db, ipnum, &gl); - if (id == 0) - return (0); - - if (scope != NULL) - *scope = gl.netmask; - - set_state(AF_INET, ipnum, NULL, gl.netmask, - subtype, NULL, NULL, NULL, NULL, id); - } - - return (id); -} -#endif /* HAVE_GEOIP */ - -#define DB46(addr, geoip, name) \ - ((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6)) - -#ifdef HAVE_GEOIP -/* - * Find the best database to answer a generic subtype - */ -static dns_geoip_subtype_t -fix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip, - dns_geoip_subtype_t subtype) -{ - dns_geoip_subtype_t ret = subtype; - - switch (subtype) { - case dns_geoip_countrycode: - if (DB46(reqaddr, geoip, city) != NULL) - ret = dns_geoip_city_countrycode; - else if (reqaddr->family == AF_INET && geoip->region != NULL) - ret = dns_geoip_region_countrycode; - else if (DB46(reqaddr, geoip, country) != NULL) - ret = dns_geoip_country_code; - break; - case dns_geoip_countrycode3: - if (DB46(reqaddr, geoip, city) != NULL) - ret = dns_geoip_city_countrycode3; - else if (DB46(reqaddr, geoip, country) != NULL) - ret = dns_geoip_country_code3; - break; - case dns_geoip_countryname: - if (DB46(reqaddr, geoip, city) != NULL) - ret = dns_geoip_city_countryname; - else if (DB46(reqaddr, geoip, country) != NULL) - ret = dns_geoip_country_name; - break; - case dns_geoip_region: - if (DB46(reqaddr, geoip, city) != NULL) - ret = dns_geoip_city_region; - else if (reqaddr->family == AF_INET && geoip->region != NULL) - ret = dns_geoip_region_code; - break; - case dns_geoip_regionname: - if (DB46(reqaddr, geoip, city) != NULL) - ret = dns_geoip_city_regionname; - else if (reqaddr->family == AF_INET && geoip->region != NULL) - ret = dns_geoip_region_name; - break; - default: - break; - } - - return (ret); -} -#endif /* HAVE_GEOIP */ - -bool -dns_geoip_match(const isc_netaddr_t *reqaddr, uint8_t *scope, - const dns_geoip_databases_t *geoip, - const dns_geoip_elem_t *elt) -{ -#ifndef HAVE_GEOIP - UNUSED(reqaddr); - UNUSED(geoip); - UNUSED(elt); - - return (false); -#else - GeoIP *db; - GeoIPRecord *record; - GeoIPRegion *region; - dns_geoip_subtype_t subtype; - uint32_t ipnum = 0; - int maxlen = 0, id, family; - const char *cs; - char *s; -#ifdef HAVE_GEOIP_V6 - const geoipv6_t *ipnum6 = NULL; -#else - const void *ipnum6 = NULL; -#endif - - INSIST(geoip != NULL); - - family = reqaddr->family; - switch (family) { - case AF_INET: - ipnum = ntohl(reqaddr->type.in.s_addr); - break; - case AF_INET6: -#ifdef HAVE_GEOIP_V6 - ipnum6 = &reqaddr->type.in6; - break; -#else - return (false); -#endif - default: - return (false); - } - - subtype = fix_subtype(reqaddr, geoip, elt->subtype); - - switch (subtype) { - case dns_geoip_country_code: - maxlen = 2; - goto getcountry; - - case dns_geoip_country_code3: - maxlen = 3; - goto getcountry; - - case dns_geoip_country_name: - maxlen = 255; - getcountry: - db = DB46(reqaddr, geoip, country); - if (db == NULL) - return (false); - - INSIST(elt->as_string != NULL); - - cs = country_lookup(db, subtype, family, ipnum, ipnum6, scope); - if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0) - return (true); - break; - - case dns_geoip_city_countrycode: - case dns_geoip_city_countrycode3: - case dns_geoip_city_countryname: - case dns_geoip_city_region: - case dns_geoip_city_regionname: - case dns_geoip_city_name: - case dns_geoip_city_postalcode: - case dns_geoip_city_continentcode: - case dns_geoip_city_timezonecode: - INSIST(elt->as_string != NULL); - - db = DB46(reqaddr, geoip, city); - if (db == NULL) - return (false); - - record = city_lookup(db, subtype, family, - ipnum, ipnum6, scope); - if (record == NULL) - break; - - s = city_string(record, subtype, &maxlen); - INSIST(maxlen != 0); - if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) - return (true); - break; - - case dns_geoip_city_metrocode: - db = DB46(reqaddr, geoip, city); - if (db == NULL) - return (false); - - record = city_lookup(db, subtype, family, - ipnum, ipnum6, scope); - if (record == NULL) - break; - - if (elt->as_int == record->metro_code) - return (true); - break; - - case dns_geoip_city_areacode: - db = DB46(reqaddr, geoip, city); - if (db == NULL) - return (false); - - record = city_lookup(db, subtype, family, - ipnum, ipnum6, scope); - if (record == NULL) - break; - - if (elt->as_int == record->area_code) - return (true); - break; - - case dns_geoip_region_countrycode: - case dns_geoip_region_code: - case dns_geoip_region_name: - case dns_geoip_region: - if (geoip->region == NULL) - return (false); - - INSIST(elt->as_string != NULL); - - /* Region DB is not supported for IPv6 */ - if (family == AF_INET6) - return (false); - - region = region_lookup(geoip->region, subtype, ipnum, scope); - if (region == NULL) - break; - - s = region_string(region, subtype, &maxlen); - INSIST(maxlen != 0); - if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) - return (true); - break; - - case dns_geoip_isp_name: - db = geoip->isp; - goto getname; - - case dns_geoip_org_name: - db = geoip->org; - goto getname; - - case dns_geoip_as_asnum: - db = geoip->as; - goto getname; - - case dns_geoip_domain_name: - db = geoip->domain; - - getname: - if (db == NULL) - return (false); - - INSIST(elt->as_string != NULL); - /* ISP, Org, AS, and Domain are not supported for IPv6 */ - if (family == AF_INET6) - return (false); - - s = name_lookup(db, subtype, ipnum, scope); - if (s != NULL) { - size_t l; - if (strcasecmp(elt->as_string, s) == 0) - return (true); - if (subtype != dns_geoip_as_asnum) - break; - /* - * Just check if the ASNNNN value matches. - */ - l = strlen(elt->as_string); - if (l > 0U && strchr(elt->as_string, ' ') == NULL && - strncasecmp(elt->as_string, s, l) == 0 && - s[l] == ' ') - return (true); - } - break; - - case dns_geoip_netspeed_id: - INSIST(geoip->netspeed != NULL); - - /* Netspeed DB is not supported for IPv6 */ - if (family == AF_INET6) - return (false); - - id = netspeed_lookup(geoip->netspeed, subtype, ipnum, scope); - if (id == elt->as_int) - return (true); - break; - - case dns_geoip_countrycode: - case dns_geoip_countrycode3: - case dns_geoip_countryname: - case dns_geoip_regionname: - /* - * If these were not remapped by fix_subtype(), - * the database was unavailable. Always return false. - */ - break; - - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - return (false); -#endif -} - -void -dns_geoip_shutdown(void) { -#ifdef HAVE_GEOIP - GeoIP_cleanup(); -#ifdef ISC_PLATFORM_USETHREADS - if (state_mctx != NULL) - isc_mem_detach(&state_mctx); -#endif -#else - return; -#endif -} diff --git a/lib/dns-pkcs11/geoip2.c b/lib/dns-pkcs11/geoip2.c deleted file mode 100644 index 1e58f05..0000000 --- a/lib/dns-pkcs11/geoip2.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -/* - * This file is only built and linked if GeoIP2 has been configured. - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#ifndef WIN32 -#include -#else -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ -#endif -#include -#endif /* WIN32 */ -#include - -/* - * This structure preserves state from the previous GeoIP lookup, - * so that successive lookups for the same data from the same IP - * address will not require repeated database lookups. - * This should improve performance somewhat. - * - * For all lookups we preserve pointers to the MMDB_lookup_result_s - * and MMDB_entry_s structures, a pointer to the database from which - * the lookup was answered, and a copy of the request address. - * - * If the next geoip ACL lookup is for the same database and from the - * same address, we can reuse the MMDB entry without repeating the lookup. - * This is for the case when a single query has to process multiple - * geoip ACLs: for example, when there are multiple views with - * match-clients statements that search for different countries. - * - * (XXX: Currently the persistent state is stored in thread specific - * memory, but it could more simply be stored in the client object. - * Also multiple entries could be stored in case the ACLs require - * searching in more than one GeoIP database.) - */ - -typedef struct geoip_state { - isc_mem_t *mctx; - uint16_t subtype; - const MMDB_s *db; - isc_netaddr_t addr; - MMDB_lookup_result_s mmresult; - MMDB_entry_s entry; -} geoip_state_t; - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#endif - -#ifdef ISC_PLATFORM_USETHREADS -static isc_mutex_t key_mutex; -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -static _Atomic(int32_t) state_key_initialized = 0; -#define GEOIP2_LOAD(x) atomic_load(&(x)) -#define GEOIP2_STORE(x, v) atomic_store(&(x), v) -#else -static int32_t state_key_initialized = 0; -#if defined(ISC_PLATFORM_HAVEXADD) -#define GEOIP2_LOAD(x) isc_atomic_xadd(&(x), 0) -#define GEOIP2_STORE(x, v) isc_atomic_store(&(x), v) -#else -#define GEOIP2_LOAD(x) (x) -#define GEOIP2_STORE(x, v) (x) = (v) -#endif -#endif -static isc_thread_key_t state_key; -static isc_once_t mutex_once = ISC_ONCE_INIT; -#else -static geoip_state_t *saved_state = NULL; -#endif -static isc_mem_t *state_mctx = NULL; - -#ifdef ISC_PLATFORM_USETHREADS -static void -key_mutex_init(void) { - RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS); -} - -static void -free_state(void *arg) { - geoip_state_t *state = arg; - if (state != NULL) { - isc_mem_putanddetach(&state->mctx, - state, sizeof(geoip_state_t)); - } - isc_thread_key_setspecific(state_key, NULL); -} - -static isc_result_t -state_key_init(void) { - isc_result_t result; - - result = isc_once_do(&mutex_once, key_mutex_init); - if (result != ISC_R_SUCCESS) { - return (result); - } - - if (!GEOIP2_LOAD(state_key_initialized)) { - LOCK(&key_mutex); - if (!GEOIP2_LOAD(state_key_initialized)) { - int ret; - - if (state_mctx == NULL) { - result = isc_mem_create(0, 0, &state_mctx); - } - if (result != ISC_R_SUCCESS) { - goto unlock; - } - isc_mem_setname(state_mctx, "geoip_state", NULL); - isc_mem_setdestroycheck(state_mctx, false); - - ret = isc_thread_key_create(&state_key, free_state); - if (ret == 0) { - GEOIP2_STORE(state_key_initialized, 1); - } else { - result = ISC_R_FAILURE; - } - } - unlock: - UNLOCK(&key_mutex); - } - - return (result); -} -#else -static isc_result_t -state_key_init(void) { - isc_result_t result = ISC_R_SUCCESS; - - if (state_mctx == NULL) { - result = isc_mem_create(0, 0, &state_mctx); - isc_mem_setname(state_mctx, "geoip_state", NULL); - isc_mem_setdestroycheck(state_mctx, false); - } - - return (result); -} -#endif - -static isc_result_t -set_state(const MMDB_s *db, const isc_netaddr_t *addr, - MMDB_lookup_result_s mmresult, MMDB_entry_s entry, - geoip_state_t **statep) -{ - geoip_state_t *state = NULL; - isc_result_t result; - - result = state_key_init(); - if (result != ISC_R_SUCCESS) { - return (result); - } - -#ifdef ISC_PLATFORM_USETHREADS - state = (geoip_state_t *) isc_thread_key_getspecific(state_key); -#else - state = saved_state; -#endif - if (state == NULL) { - LOCK(&key_mutex); - state = (geoip_state_t *) isc_mem_get(state_mctx, - sizeof(geoip_state_t)); - UNLOCK(&key_mutex); - if (state == NULL) { - return (ISC_R_NOMEMORY); - } - memset(state, 0, sizeof(*state)); - -#ifdef ISC_PLATFORM_USETHREADS - result = isc_thread_key_setspecific(state_key, state); - if (result != ISC_R_SUCCESS) { - LOCK(&key_mutex); - isc_mem_put(state_mctx, state, sizeof(geoip_state_t)); - UNLOCK(&key_mutex); - return (result); - } -#else - saved_state = state; -#endif - - LOCK(&key_mutex); - isc_mem_attach(state_mctx, &state->mctx); - UNLOCK(&key_mutex); - } - - state->db = db; - state->addr = *addr; - state->mmresult = mmresult; - state->entry = entry; - - if (statep != NULL) { - *statep = state; - } - - return (ISC_R_SUCCESS); -} - -static geoip_state_t * -get_entry_for(MMDB_s * const db, const isc_netaddr_t *addr) { - isc_result_t result; - isc_sockaddr_t sa; - geoip_state_t *state; - MMDB_lookup_result_s match; - int err; - - result = state_key_init(); - if (result != ISC_R_SUCCESS) { - return (NULL); - } - -#ifdef ISC_PLATFORM_USETHREADS - state = (geoip_state_t *) isc_thread_key_getspecific(state_key); -#else - state = saved_state; -#endif - if (state != NULL) { - if (db == state->db && isc_netaddr_equal(addr, &state->addr)) { - return (state); - } - } - - isc_sockaddr_fromnetaddr(&sa, addr, 0); - match = MMDB_lookup_sockaddr(db, &sa.type.sa, &err); - if (err != MMDB_SUCCESS || !match.found_entry) { - return (NULL); - } - - result = set_state(db, addr, match, match.entry, &state); - if (result != ISC_R_SUCCESS) { - return (NULL); - } - - return (state); -} - -static dns_geoip_subtype_t -fix_subtype(const dns_geoip_databases_t *geoip, dns_geoip_subtype_t subtype) { - dns_geoip_subtype_t ret = subtype; - - switch (subtype) { - case dns_geoip_countrycode: - if (geoip->city != NULL) { - ret = dns_geoip_city_countrycode; - } else if (geoip->country != NULL) { - ret = dns_geoip_country_code; - } - break; - case dns_geoip_countryname: - if (geoip->city != NULL) { - ret = dns_geoip_city_countryname; - } else if (geoip->country != NULL) { - ret = dns_geoip_country_name; - } - break; - case dns_geoip_continentcode: - if (geoip->city != NULL) { - ret = dns_geoip_city_continentcode; - } else if (geoip->country != NULL) { - ret = dns_geoip_country_continentcode; - } - break; - case dns_geoip_continent: - if (geoip->city != NULL) { - ret = dns_geoip_city_continent; - } else if (geoip->country != NULL) { - ret = dns_geoip_country_continent; - } - break; - case dns_geoip_region: - if (geoip->city != NULL) { - ret = dns_geoip_city_region; - } - break; - case dns_geoip_regionname: - if (geoip->city != NULL) { - ret = dns_geoip_city_regionname; - } - default: - break; - } - - return (ret); -} - -static MMDB_s * -geoip2_database(const dns_geoip_databases_t *geoip, - dns_geoip_subtype_t subtype) -{ - switch (subtype) { - case dns_geoip_country_code: - case dns_geoip_country_name: - case dns_geoip_country_continentcode: - case dns_geoip_country_continent: - return (geoip->country); - - case dns_geoip_city_countrycode: - case dns_geoip_city_countryname: - case dns_geoip_city_continentcode: - case dns_geoip_city_continent: - case dns_geoip_city_region: - case dns_geoip_city_regionname: - case dns_geoip_city_name: - case dns_geoip_city_postalcode: - case dns_geoip_city_timezonecode: - case dns_geoip_city_metrocode: - case dns_geoip_city_areacode: - return (geoip->city); - - case dns_geoip_isp_name: - return (geoip->isp); - - case dns_geoip_as_asnum: - case dns_geoip_org_name: - return (geoip->as); - - case dns_geoip_domain_name: - return (geoip->domain); - - default: - /* - * All other subtypes are unavailable in GeoIP2. - */ - return (NULL); - } -} - -static bool -match_string(MMDB_entry_data_s *value, const char *str) { - REQUIRE(str != NULL); - - if (value == NULL || !value->has_data || - value->type != MMDB_DATA_TYPE_UTF8_STRING || - value->utf8_string == NULL) - { - return (false); - } - - return (strncasecmp(value->utf8_string, str, value->data_size) == 0); -} - -static bool -match_int(MMDB_entry_data_s *value, const uint32_t ui32) { - if (value == NULL || !value->has_data || - (value->type != MMDB_DATA_TYPE_UINT32 && - value->type != MMDB_DATA_TYPE_UINT16)) - { - return (false); - } - - return (value->uint32 == ui32); -} - -bool -dns_geoip_match(const isc_netaddr_t *reqaddr, uint8_t *scope, - const dns_geoip_databases_t *geoip, - const dns_geoip_elem_t *elt) -{ - MMDB_s *db = NULL; - MMDB_entry_data_s value; - geoip_state_t *state = NULL; - dns_geoip_subtype_t subtype; - const char *s = NULL; - int ret; - - REQUIRE(reqaddr != NULL); - REQUIRE(elt != NULL); - REQUIRE(geoip != NULL); - - subtype = fix_subtype(geoip, elt->subtype); - db = geoip2_database(geoip, subtype); - if (db == NULL) { - return (false); - } - - state = get_entry_for(db, reqaddr); - if (state == NULL) { - return (false); - } - - switch (subtype) { - case dns_geoip_country_code: - case dns_geoip_city_countrycode: - ret = MMDB_get_value(&state->entry, &value, - "country", "iso_code", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; -#define isc_netaddr_pf(x) (x)->family - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_country_name: - case dns_geoip_city_countryname: - ret = MMDB_get_value(&state->entry, &value, - "country", "names", "en", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_country_continentcode: - case dns_geoip_city_continentcode: - ret = MMDB_get_value(&state->entry, &value, - "continent", "code", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_country_continent: - case dns_geoip_city_continent: - ret = MMDB_get_value(&state->entry, &value, - "continent", "names", "en", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_region: - case dns_geoip_city_region: - ret = MMDB_get_value(&state->entry, &value, - "subdivisions", "0", "iso_code", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_regionname: - case dns_geoip_city_regionname: - ret = MMDB_get_value(&state->entry, &value, - "subdivisions", "0", "names", "en", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_city_name: - ret = MMDB_get_value(&state->entry, &value, - "city", "names", "en", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_city_postalcode: - ret = MMDB_get_value(&state->entry, &value, - "postal", "code", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_city_timezonecode: - ret = MMDB_get_value(&state->entry, &value, - "location", "time_zone", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - - case dns_geoip_city_metrocode: - ret = MMDB_get_value(&state->entry, &value, - "location", "metro_code", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_isp_name: - ret = MMDB_get_value(&state->entry, &value, "isp", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_as_asnum: - INSIST(elt->as_string != NULL); - - ret = MMDB_get_value(&state->entry, &value, - "autonomous_system_number", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - - s = elt->as_string; - if (strncasecmp(s, "AS", 2) == 0) { - s += 2; - } - - return (match_int(&value, strtol(s, NULL, 10))); - } - break; - - case dns_geoip_org_name: - ret = MMDB_get_value(&state->entry, &value, - "autonomous_system_organization", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - case dns_geoip_domain_name: - ret = MMDB_get_value(&state->entry, &value, "domain", (char *)0); - if (ret == MMDB_SUCCESS) { - if (scope != NULL) { - *scope = state->mmresult.netmask; - if (isc_netaddr_pf(reqaddr) == AF_INET) { - *scope -= 96; - } - } - return (match_string(&value, elt->as_string)); - } - break; - - default: - /* - * For any other subtype, we assume the database was - * unavailable and return false. - */ - return (false); - } - - /* - * No database matched: return false. - */ - return (false); -} - -void -dns_geoip_shutdown(void) { -#ifndef ISC_PLATFORM_USETHREADS - if (saved_state != NULL) { - isc_mem_putanddetach(&saved_state->mctx, - saved_state, sizeof(geoip_state_t)); - } -#endif - if (state_mctx != NULL) { - isc_mem_detach(&state_mctx); - } -} diff --git a/lib/dns-pkcs11/gssapi_link.c b/lib/dns-pkcs11/gssapi_link.c deleted file mode 100644 index e2ebc51..0000000 --- a/lib/dns-pkcs11/gssapi_link.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#ifdef GSSAPI - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_parse.h" - -#include - -#define INITIAL_BUFFER_SIZE 1024 -#define BUFFER_EXTRA 1024 - -#define REGION_TO_GBUFFER(r, gb) \ - do { \ - (gb).length = (r).length; \ - (gb).value = (r).base; \ - } while (0) - -#define GBUFFER_TO_REGION(gb, r) \ - do { \ - (r).length = (unsigned int)(gb).length; \ - (r).base = (gb).value; \ - } while (0) - - -struct dst_gssapi_signverifyctx { - isc_buffer_t *buffer; -}; - -/*% - * Allocate a temporary "context" for use in gathering data for signing - * or verifying. - */ -static isc_result_t -gssapi_create_signverify_ctx(dst_key_t *key, dst_context_t *dctx) { - dst_gssapi_signverifyctx_t *ctx; - isc_result_t result; - - UNUSED(key); - - ctx = isc_mem_get(dctx->mctx, sizeof(dst_gssapi_signverifyctx_t)); - if (ctx == NULL) - return (ISC_R_NOMEMORY); - ctx->buffer = NULL; - result = isc_buffer_allocate(dctx->mctx, &ctx->buffer, - INITIAL_BUFFER_SIZE); - if (result != ISC_R_SUCCESS) { - isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); - return (result); - } - - dctx->ctxdata.gssctx = ctx; - - return (ISC_R_SUCCESS); -} - -/*% - * Destroy the temporary sign/verify context. - */ -static void -gssapi_destroy_signverify_ctx(dst_context_t *dctx) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - - if (ctx != NULL) { - if (ctx->buffer != NULL) - isc_buffer_free(&ctx->buffer); - isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); - dctx->ctxdata.gssctx = NULL; - } -} - -/*% - * Add data to our running buffer of data we will be signing or verifying. - * This code will see if the new data will fit in our existing buffer, and - * copy it in if it will. If not, it will attempt to allocate a larger - * buffer and copy old+new into it, and free the old buffer. - */ -static isc_result_t -gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_buffer_t *newbuffer = NULL; - isc_region_t r; - unsigned int length; - isc_result_t result; - - result = isc_buffer_copyregion(ctx->buffer, data); - if (result == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA; - - result = isc_buffer_allocate(dctx->mctx, &newbuffer, length); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_usedregion(ctx->buffer, &r); - (void)isc_buffer_copyregion(newbuffer, &r); - (void)isc_buffer_copyregion(newbuffer, data); - - isc_buffer_free(&ctx->buffer); - ctx->buffer = newbuffer; - - return (ISC_R_SUCCESS); -} - -/*% - * Sign. - */ -static isc_result_t -gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_region_t message; - gss_buffer_desc gmessage, gsig; - OM_uint32 minor, gret; - gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; - char buf[1024]; - - /* - * Convert the data we wish to sign into a structure gssapi can - * understand. - */ - isc_buffer_usedregion(ctx->buffer, &message); - REGION_TO_GBUFFER(message, gmessage); - - /* - * Generate the signature. - */ - gret = gss_get_mic(&minor, gssctx, GSS_C_QOP_DEFAULT, &gmessage, - &gsig); - - /* - * If it did not complete, we log the result and return a generic - * failure code. - */ - if (gret != GSS_S_COMPLETE) { - gss_log(3, "GSS sign error: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - return (ISC_R_FAILURE); - } - - /* - * If it will not fit in our allocated buffer, return that we need - * more space. - */ - if (gsig.length > isc_buffer_availablelength(sig)) { - gss_release_buffer(&minor, &gsig); - return (ISC_R_NOSPACE); - } - - /* - * Copy the output into our buffer space, and release the gssapi - * allocated space. - */ - isc_buffer_putmem(sig, gsig.value, (unsigned int)gsig.length); - if (gsig.length != 0U) - gss_release_buffer(&minor, &gsig); - - return (ISC_R_SUCCESS); -} - -/*% - * Verify. - */ -static isc_result_t -gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_region_t message, r; - gss_buffer_desc gmessage, gsig; - OM_uint32 minor, gret; - gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; - unsigned char *buf; - char err[1024]; - - /* - * Convert the data we wish to sign into a structure gssapi can - * understand. - */ - isc_buffer_usedregion(ctx->buffer, &message); - REGION_TO_GBUFFER(message, gmessage); - - /* - * XXXMLG - * It seem that gss_verify_mic() modifies the signature buffer, - * at least on Heimdal's implementation. Copy it here to an allocated - * buffer. - */ - buf = isc_mem_allocate(dst__memory_pool, sig->length); - if (buf == NULL) - return (ISC_R_FAILURE); - memmove(buf, sig->base, sig->length); - r.base = buf; - r.length = sig->length; - REGION_TO_GBUFFER(r, gsig); - - /* - * Verify the data. - */ - gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL); - - isc_mem_free(dst__memory_pool, buf); - - /* - * Convert return codes into something useful to us. - */ - if (gret != GSS_S_COMPLETE) { - gss_log(3, "GSS verify error: %s", - gss_error_tostring(gret, minor, err, sizeof(err))); - if (gret == GSS_S_DEFECTIVE_TOKEN || - gret == GSS_S_BAD_SIG || - gret == GSS_S_DUPLICATE_TOKEN || - gret == GSS_S_OLD_TOKEN || - gret == GSS_S_UNSEQ_TOKEN || - gret == GSS_S_GAP_TOKEN || - gret == GSS_S_CONTEXT_EXPIRED || - gret == GSS_S_NO_CONTEXT || - gret == GSS_S_FAILURE) - return(DST_R_VERIFYFAILURE); - else - return (ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); -} - -static bool -gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) { - gss_ctx_id_t gsskey1 = key1->keydata.gssctx; - gss_ctx_id_t gsskey2 = key2->keydata.gssctx; - - /* No idea */ - return (gsskey1 == gsskey2); -} - -static isc_result_t -gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) { - UNUSED(key); - UNUSED(unused); - UNUSED(callback); - - /* No idea */ - return (ISC_R_FAILURE); -} - -static bool -gssapi_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -gssapi_destroy(dst_key_t *key) { - REQUIRE(key != NULL); - dst_gssapi_deletectx(key->mctx, &key->keydata.gssctx); - key->keydata.gssctx = NULL; -} - -static isc_result_t -gssapi_restore(dst_key_t *key, const char *keystr) { - OM_uint32 major, minor; - unsigned int len; - isc_buffer_t *b = NULL; - isc_region_t r; - gss_buffer_desc gssbuffer; - isc_result_t result; - - len = strlen(keystr); - if ((len % 4) != 0U) - return (ISC_R_BADBASE64); - - len = (len / 4) * 3; - - result = isc_buffer_allocate(key->mctx, &b, len); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_base64_decodestring(keystr, b); - if (result != ISC_R_SUCCESS) { - isc_buffer_free(&b); - return (result); - } - - isc_buffer_remainingregion(b, &r); - REGION_TO_GBUFFER(r, gssbuffer); - major = gss_import_sec_context(&minor, &gssbuffer, - &key->keydata.gssctx); - if (major != GSS_S_COMPLETE) { - isc_buffer_free(&b); - return (ISC_R_FAILURE); - } - - isc_buffer_free(&b); - return (ISC_R_SUCCESS); -} - -static isc_result_t -gssapi_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { - OM_uint32 major, minor; - gss_buffer_desc gssbuffer; - size_t len; - char *buf; - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - major = gss_export_sec_context(&minor, &key->keydata.gssctx, - &gssbuffer); - if (major != GSS_S_COMPLETE) { - fprintf(stderr, "gss_export_sec_context -> %u, %u\n", - major, minor); - return (ISC_R_FAILURE); - } - if (gssbuffer.length == 0U) - return (ISC_R_FAILURE); - len = ((gssbuffer.length + 2)/3) * 4; - buf = isc_mem_get(mctx, len); - if (buf == NULL) { - gss_release_buffer(&minor, &gssbuffer); - return (ISC_R_NOMEMORY); - } - isc_buffer_init(&b, buf, (unsigned int)len); - GBUFFER_TO_REGION(gssbuffer, r); - result = isc_base64_totext(&r, 0, "", &b); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - gss_release_buffer(&minor, &gssbuffer); - *buffer = buf; - *length = (int)len; - return (ISC_R_SUCCESS); -} - -static dst_func_t gssapi_functions = { - gssapi_create_signverify_ctx, - NULL, /*%< createctx2 */ - gssapi_destroy_signverify_ctx, - gssapi_adddata, - gssapi_sign, - gssapi_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - gssapi_compare, - NULL, /*%< paramcompare */ - gssapi_generate, - gssapi_isprivate, - gssapi_destroy, - NULL, /*%< todns */ - NULL, /*%< fromdns */ - NULL, /*%< tofile */ - NULL, /*%< parse */ - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - gssapi_dump, - gssapi_restore, -}; - -isc_result_t -dst__gssapi_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &gssapi_functions; - return (ISC_R_SUCCESS); -} - -#else -int gssapi_link_unneeded = 1; -#endif - -/*! \file */ diff --git a/lib/dns-pkcs11/gssapictx.c b/lib/dns-pkcs11/gssapictx.c deleted file mode 100644 index 02539cd..0000000 --- a/lib/dns-pkcs11/gssapictx.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" - -/* - * If we're using our own SPNEGO implementation (see configure.in), - * pull it in now. Otherwise, we just use whatever GSSAPI supplies. - */ -#if defined(GSSAPI) && defined(USE_ISC_SPNEGO) -#include "spnego.h" -#define gss_accept_sec_context gss_accept_sec_context_spnego -#define gss_init_sec_context gss_init_sec_context_spnego -#endif - -/* - * Solaris8 apparently needs an explicit OID set, and Solaris10 needs - * one for anything but Kerberos. Supplying an explicit OID set - * doesn't appear to hurt anything in other implementations, so we - * always use one. If we're not using our own SPNEGO implementation, - * we include SPNEGO's OID. - */ -#ifdef GSSAPI -#ifdef WIN32 -#include -#else -#include ISC_PLATFORM_KRB5HEADER -#endif - -static unsigned char krb5_mech_oid_bytes[] = { - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 -}; - -#ifndef USE_ISC_SPNEGO -static unsigned char spnego_mech_oid_bytes[] = { - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 -}; -#endif - -static gss_OID_desc mech_oid_set_array[] = { - { sizeof(krb5_mech_oid_bytes), krb5_mech_oid_bytes }, -#ifndef USE_ISC_SPNEGO - { sizeof(spnego_mech_oid_bytes), spnego_mech_oid_bytes }, -#endif -}; - -static gss_OID_set_desc mech_oid_set = { - sizeof(mech_oid_set_array) / sizeof(*mech_oid_set_array), - mech_oid_set_array -}; - -#endif - -#define REGION_TO_GBUFFER(r, gb) \ - do { \ - (gb).length = (r).length; \ - (gb).value = (r).base; \ - } while (0) - -#define GBUFFER_TO_REGION(gb, r) \ - do { \ - (r).length = (unsigned int)(gb).length; \ - (r).base = (gb).value; \ - } while (0) - - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto out; \ - } while (0) - -#ifdef GSSAPI -static inline void -name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer, - gss_buffer_desc *gbuffer) -{ - dns_name_t tname, *namep; - isc_region_t r; - isc_result_t result; - - if (!dns_name_isabsolute(name)) - namep = name; - else - { - unsigned int labels; - dns_name_init(&tname, NULL); - labels = dns_name_countlabels(name); - dns_name_getlabelsequence(name, 0, labels - 1, &tname); - namep = &tname; - } - - result = dns_name_toprincipal(namep, buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_putuint8(buffer, 0); - isc_buffer_usedregion(buffer, &r); - REGION_TO_GBUFFER(r, *gbuffer); -} - -static void -log_cred(const gss_cred_id_t cred) { - OM_uint32 gret, minor, lifetime; - gss_name_t gname; - gss_buffer_desc gbuffer; - gss_cred_usage_t usage; - const char *usage_text; - char buf[1024]; - - gret = gss_inquire_cred(&minor, cred, &gname, &lifetime, &usage, NULL); - if (gret != GSS_S_COMPLETE) { - gss_log(3, "failed gss_inquire_cred: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - return; - } - - gret = gss_display_name(&minor, gname, &gbuffer, NULL); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_display_name: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - else { - switch (usage) { - case GSS_C_BOTH: - usage_text = "GSS_C_BOTH"; - break; - case GSS_C_INITIATE: - usage_text = "GSS_C_INITIATE"; - break; - case GSS_C_ACCEPT: - usage_text = "GSS_C_ACCEPT"; - break; - default: - usage_text = "???"; - } - gss_log(3, "gss cred: \"%s\", %s, %lu", (char *)gbuffer.value, - usage_text, (unsigned long)lifetime); - } - - if (gret == GSS_S_COMPLETE) { - if (gbuffer.length != 0U) { - gret = gss_release_buffer(&minor, &gbuffer); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_release_buffer: %s", - gss_error_tostring(gret, minor, buf, - sizeof(buf))); - } - } - - gret = gss_release_name(&minor, &gname); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_release_name: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); -} -#endif - -#ifdef GSSAPI -/* - * check for the most common configuration errors. - * - * The errors checked for are: - * - tkey-gssapi-credential doesn't start with DNS/ - * - the default realm in /etc/krb5.conf and the - * tkey-gssapi-credential bind config option don't match - * - * Note that if tkey-gssapi-keytab is set then these configure checks - * are not performed, and runtime errors from gssapi are used instead - */ -static void -check_config(const char *gss_name) { - const char *p; - krb5_context krb5_ctx; - char *krb5_realm_name = NULL; - - if (strncasecmp(gss_name, "DNS/", 4) != 0) { - gss_log(ISC_LOG_ERROR, "tkey-gssapi-credential (%s) " - "should start with 'DNS/'", gss_name); - return; - } - - if (krb5_init_context(&krb5_ctx) != 0) { - gss_log(ISC_LOG_ERROR, "Unable to initialise krb5 context"); - return; - } - if (krb5_get_default_realm(krb5_ctx, &krb5_realm_name) != 0) { - gss_log(ISC_LOG_ERROR, "Unable to get krb5 default realm"); - krb5_free_context(krb5_ctx); - return; - } - p = strchr(gss_name, '@'); - if (p == NULL) { - gss_log(ISC_LOG_ERROR, "badly formatted " - "tkey-gssapi-credentials (%s)", gss_name); - krb5_free_context(krb5_ctx); - return; - } - if (strcasecmp(p + 1, krb5_realm_name) != 0) { - gss_log(ISC_LOG_ERROR, "default realm from krb5.conf (%s) " - "does not match tkey-gssapi-credential (%s)", - krb5_realm_name, gss_name); - krb5_free_context(krb5_ctx); - return; - } - krb5_free_context(krb5_ctx); -} -#endif - -isc_result_t -dst_gssapi_acquirecred(dns_name_t *name, bool initiate, - gss_cred_id_t *cred) -{ -#ifdef GSSAPI - isc_result_t result; - isc_buffer_t namebuf; - gss_name_t gname; - gss_buffer_desc gnamebuf; - unsigned char array[DNS_NAME_MAXTEXT + 1]; - OM_uint32 gret, minor; - OM_uint32 lifetime; - gss_cred_usage_t usage; - char buf[1024]; - - REQUIRE(cred != NULL && *cred == NULL); - - /* - * XXXSRA In theory we could use GSS_C_NT_HOSTBASED_SERVICE - * here when we're in the acceptor role, which would let us - * default the hostname and use a compiled in default service - * name of "DNS", giving one less thing to configure in - * named.conf. Unfortunately, this creates a circular - * dependency due to DNS-based realm lookup in at least one - * GSSAPI implementation (Heimdal). Oh well. - */ - if (name != NULL) { - isc_buffer_init(&namebuf, array, sizeof(array)); - name_to_gbuffer(name, &namebuf, &gnamebuf); - gret = gss_import_name(&minor, &gnamebuf, - GSS_C_NO_OID, &gname); - if (gret != GSS_S_COMPLETE) { - check_config((char *)array); - - gss_log(3, "failed gss_import_name: %s", - gss_error_tostring(gret, minor, buf, - sizeof(buf))); - return (ISC_R_FAILURE); - } - } else - gname = NULL; - - /* Get the credentials. */ - if (gname != NULL) - gss_log(3, "acquiring credentials for %s", - (char *)gnamebuf.value); - else { - /* XXXDCL does this even make any sense? */ - gss_log(3, "acquiring credentials for ?"); - } - - if (initiate) - usage = GSS_C_INITIATE; - else - usage = GSS_C_ACCEPT; - - gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE, - &mech_oid_set, usage, cred, NULL, &lifetime); - - if (gret != GSS_S_COMPLETE) { - gss_log(3, "failed to acquire %s credentials for %s: %s", - initiate ? "initiate" : "accept", - (gname != NULL) ? (char *)gnamebuf.value : "?", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - if (gname != NULL) - check_config((char *)array); - result = ISC_R_FAILURE; - goto cleanup; - } - - gss_log(4, "acquired %s credentials for %s", - initiate ? "initiate" : "accept", - (gname != NULL) ? (char *)gnamebuf.value : "?"); - - log_cred(*cred); - result = ISC_R_SUCCESS; - -cleanup: - if (gname != NULL) { - gret = gss_release_name(&minor, &gname); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_release_name: %s", - gss_error_tostring(gret, minor, buf, - sizeof(buf))); - } - - return (result); -#else - REQUIRE(cred != NULL && *cred == NULL); - - UNUSED(name); - UNUSED(initiate); - UNUSED(cred); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -bool -dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, - const dns_name_t *name, - const dns_name_t *realm, - bool subdomain) -{ -#ifdef GSSAPI - char sbuf[DNS_NAME_FORMATSIZE]; - char rbuf[DNS_NAME_FORMATSIZE]; - char *sname; - char *rname; - isc_buffer_t buffer; - isc_result_t result; - - /* - * It is far, far easier to write the names we are looking at into - * a string, and do string operations on them. - */ - isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); - result = dns_name_toprincipal(signer, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_putuint8(&buffer, 0); - dns_name_format(realm, rbuf, sizeof(rbuf)); - - /* - * Find the realm portion. This is the part after the @. If it - * does not exist, we don't have something we like, so we fail our - * compare. - */ - rname = strchr(sbuf, '@'); - if (rname == NULL) - return (false); - *rname = '\0'; - rname++; - - if (strcmp(rname, rbuf) != 0) { - return (false); - } - - /* - * Find the host portion of the signer's name. We do this by - * searching for the first / character. We then check to make - * certain the instance name is "host" - * - * This will work for - * host/example.com@EXAMPLE.COM - */ - sname = strchr(sbuf, '/'); - if (sname == NULL) - return (false); - *sname = '\0'; - sname++; - if (strcmp(sbuf, "host") != 0) - return (false); - - /* - * If name is non NULL check that it matches against the - * machine name as expected. - */ - if (name != NULL) { - dns_fixedname_t fixed; - dns_name_t *machine; - - machine = dns_fixedname_initname(&fixed); - result = dns_name_fromstring(machine, sname, 0, NULL); - if (result != ISC_R_SUCCESS) { - return (false); - } - if (subdomain) { - return (dns_name_issubdomain(name, machine)); - } - return (dns_name_equal(name, machine)); - } - - return (true); -#else - UNUSED(signer); - UNUSED(name); - UNUSED(realm); - UNUSED(subdomain); - return (false); -#endif -} - -bool -dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, - const dns_name_t *name, - const dns_name_t *realm, - bool subdomain) -{ -#ifdef GSSAPI - char sbuf[DNS_NAME_FORMATSIZE]; - char rbuf[DNS_NAME_FORMATSIZE]; - char *sname; - char *rname; - isc_buffer_t buffer; - isc_result_t result; - - /* - * It is far, far easier to write the names we are looking at into - * a string, and do string operations on them. - */ - isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); - result = dns_name_toprincipal(signer, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_putuint8(&buffer, 0); - dns_name_format(realm, rbuf, sizeof(rbuf)); - - /* - * Find the realm portion. This is the part after the @. If it - * does not exist, we don't have something we like, so we fail our - * compare. - */ - rname = strchr(sbuf, '@'); - if (rname == NULL) - return (false); - sname = strchr(sbuf, '$'); - if (sname == NULL) - return (false); - - /* - * Verify that the $ and @ follow one another. - */ - if (rname - sname != 1) - return (false); - - /* - * Find the host portion of the signer's name. Zero out the $ so - * it terminates the signer's name, and skip past the @ for - * the realm. - * - * All service principals in Microsoft format seem to be in - * machinename$@EXAMPLE.COM - * format. - */ - rname++; - *sname = '\0'; - - if (strcmp(rname, rbuf) != 0) { - return (false); - } - - /* - * Now, we check that the realm matches (case sensitive) and that - * 'name' matches against 'machinename' qualified with 'realm'. - */ - if (name != NULL) { - dns_fixedname_t fixed; - dns_name_t *machine; - - machine = dns_fixedname_initname(&fixed); - result = dns_name_fromstring2(machine, sbuf, realm, 0, NULL); - if (result != ISC_R_SUCCESS) { - return (false); - } - if (subdomain) { - return (dns_name_issubdomain(name, machine)); - } - return (dns_name_equal(name, machine)); - } - - return (true); -#else - UNUSED(signer); - UNUSED(name); - UNUSED(realm); - UNUSED(subdomain); - return (false); -#endif -} - -isc_result_t -dst_gssapi_releasecred(gss_cred_id_t *cred) { -#ifdef GSSAPI - OM_uint32 gret, minor; - char buf[1024]; - - REQUIRE(cred != NULL && *cred != NULL); - - gret = gss_release_cred(&minor, cred); - if (gret != GSS_S_COMPLETE) { - /* Log the error, but still free the credential's memory */ - gss_log(3, "failed releasing credential: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - } - *cred = NULL; - - return(ISC_R_SUCCESS); -#else - UNUSED(cred); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -#ifdef GSSAPI -/* - * Format a gssapi error message info into a char ** on the given memory - * context. This is used to return gssapi error messages back up the - * call chain for reporting to the user. - */ -static void -gss_err_message(isc_mem_t *mctx, uint32_t major, uint32_t minor, - char **err_message) -{ - char buf[1024]; - char *estr; - - if (err_message == NULL || mctx == NULL) { - /* the caller doesn't want any error messages */ - return; - } - - estr = gss_error_tostring(major, minor, buf, sizeof(buf)); - if (estr != NULL) - (*err_message) = isc_mem_strdup(mctx, estr); -} -#endif - -isc_result_t -dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, - isc_buffer_t *outtoken, gss_ctx_id_t *gssctx, - isc_mem_t *mctx, char **err_message) -{ -#ifdef GSSAPI - isc_region_t r; - isc_buffer_t namebuf; - gss_name_t gname; - OM_uint32 gret, minor, ret_flags, flags; - gss_buffer_desc gintoken, *gintokenp, gouttoken = GSS_C_EMPTY_BUFFER; - isc_result_t result; - gss_buffer_desc gnamebuf; - unsigned char array[DNS_NAME_MAXTEXT + 1]; - - /* Client must pass us a valid gss_ctx_id_t here */ - REQUIRE(gssctx != NULL); - REQUIRE(mctx != NULL); - - isc_buffer_init(&namebuf, array, sizeof(array)); - name_to_gbuffer(name, &namebuf, &gnamebuf); - - /* Get the name as a GSS name */ - gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); - if (gret != GSS_S_COMPLETE) { - gss_err_message(mctx, gret, minor, err_message); - result = ISC_R_FAILURE; - goto out; - } - - if (intoken != NULL) { - /* Don't call gss_release_buffer for gintoken! */ - REGION_TO_GBUFFER(*intoken, gintoken); - gintokenp = &gintoken; - } else { - gintokenp = NULL; - } - - /* - * Note that we don't set GSS_C_SEQUENCE_FLAG as Windows DNS - * servers don't like it. - */ - flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG; - - gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx, - gname, GSS_SPNEGO_MECHANISM, flags, - 0, NULL, gintokenp, - NULL, &gouttoken, &ret_flags, NULL); - - if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) { - gss_err_message(mctx, gret, minor, err_message); - if (err_message != NULL && *err_message != NULL) - gss_log(3, "Failure initiating security context: %s", - *err_message); - else - gss_log(3, "Failure initiating security context"); - - result = ISC_R_FAILURE; - goto out; - } - - /* - * XXXSRA Not handled yet: RFC 3645 3.1.1: check ret_flags - * MUTUAL and INTEG flags, fail if either not set. - */ - - /* - * RFC 2744 states the a valid output token has a non-zero length. - */ - if (gouttoken.length != 0U) { - GBUFFER_TO_REGION(gouttoken, r); - RETERR(isc_buffer_copyregion(outtoken, &r)); - } - - if (gret == GSS_S_COMPLETE) - result = ISC_R_SUCCESS; - else - result = DNS_R_CONTINUE; - - out: - if (gouttoken.length != 0U) - (void)gss_release_buffer(&minor, &gouttoken); - (void)gss_release_name(&minor, &gname); - return (result); -#else - UNUSED(name); - UNUSED(intoken); - UNUSED(outtoken); - UNUSED(gssctx); - UNUSED(mctx); - UNUSED(err_message); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -dst_gssapi_acceptctx(gss_cred_id_t cred, - const char *gssapi_keytab, - isc_region_t *intoken, isc_buffer_t **outtoken, - gss_ctx_id_t *ctxout, dns_name_t *principal, - isc_mem_t *mctx) -{ -#ifdef GSSAPI - isc_region_t r; - isc_buffer_t namebuf; - gss_buffer_desc gnamebuf = GSS_C_EMPTY_BUFFER, gintoken, - gouttoken = GSS_C_EMPTY_BUFFER; - OM_uint32 gret, minor; - gss_ctx_id_t context = GSS_C_NO_CONTEXT; - gss_name_t gname = NULL; - isc_result_t result; - char buf[1024]; - - REQUIRE(outtoken != NULL && *outtoken == NULL); - - REGION_TO_GBUFFER(*intoken, gintoken); - - if (*ctxout == NULL) - context = GSS_C_NO_CONTEXT; - else - context = *ctxout; - - if (gssapi_keytab != NULL) { -#if defined(ISC_PLATFORM_GSSAPI_KRB5_HEADER) || defined(WIN32) - gret = gsskrb5_register_acceptor_identity(gssapi_keytab); - if (gret != GSS_S_COMPLETE) { - gss_log(3, "failed " - "gsskrb5_register_acceptor_identity(%s): %s", - gssapi_keytab, - gss_error_tostring(gret, 0, buf, sizeof(buf))); - return (DNS_R_INVALIDTKEY); - } -#else - /* - * Minimize memory leakage by only setting KRB5_KTNAME - * if it needs to change. - */ - const char *old = getenv("KRB5_KTNAME"); - if (old == NULL || strcmp(old, gssapi_keytab) != 0) { - size_t size; - char *kt; - - size = strlen(gssapi_keytab) + 13; - kt = malloc(size); - if (kt == NULL) - return (ISC_R_NOMEMORY); - snprintf(kt, size, "KRB5_KTNAME=%s", gssapi_keytab); - if (putenv(kt) != 0) - return (ISC_R_NOMEMORY); - } -#endif - } - - log_cred(cred); - - gret = gss_accept_sec_context(&minor, &context, cred, &gintoken, - GSS_C_NO_CHANNEL_BINDINGS, &gname, - NULL, &gouttoken, NULL, NULL, NULL); - - result = ISC_R_FAILURE; - - switch (gret) { - case GSS_S_COMPLETE: - case GSS_S_CONTINUE_NEEDED: - break; - case GSS_S_DEFECTIVE_TOKEN: - case GSS_S_DEFECTIVE_CREDENTIAL: - case GSS_S_BAD_SIG: - case GSS_S_DUPLICATE_TOKEN: - case GSS_S_OLD_TOKEN: - case GSS_S_NO_CRED: - case GSS_S_CREDENTIALS_EXPIRED: - case GSS_S_BAD_BINDINGS: - case GSS_S_NO_CONTEXT: - case GSS_S_BAD_MECH: - case GSS_S_FAILURE: - result = DNS_R_INVALIDTKEY; - /* fall through */ - default: - gss_log(3, "failed gss_accept_sec_context: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - return (result); - } - - if (gouttoken.length > 0U) { - RETERR(isc_buffer_allocate(mctx, outtoken, - (unsigned int)gouttoken.length)); - GBUFFER_TO_REGION(gouttoken, r); - RETERR(isc_buffer_copyregion(*outtoken, &r)); - (void)gss_release_buffer(&minor, &gouttoken); - } - - if (gret == GSS_S_COMPLETE) { - gret = gss_display_name(&minor, gname, &gnamebuf, NULL); - if (gret != GSS_S_COMPLETE) { - gss_log(3, "failed gss_display_name: %s", - gss_error_tostring(gret, minor, - buf, sizeof(buf))); - RETERR(ISC_R_FAILURE); - } - - /* - * Compensate for a bug in Solaris8's implementation - * of gss_display_name(). Should be harmless in any - * case, since principal names really should not - * contain null characters. - */ - if (gnamebuf.length > 0U && - ((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0') - gnamebuf.length--; - - gss_log(3, "gss-api source name (accept) is %.*s", - (int)gnamebuf.length, (char *)gnamebuf.value); - - GBUFFER_TO_REGION(gnamebuf, r); - isc_buffer_init(&namebuf, r.base, r.length); - isc_buffer_add(&namebuf, r.length); - - RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname, - 0, NULL)); - - if (gnamebuf.length != 0U) { - gret = gss_release_buffer(&minor, &gnamebuf); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_release_buffer: %s", - gss_error_tostring(gret, minor, buf, - sizeof(buf))); - } - } else - result = DNS_R_CONTINUE; - - *ctxout = context; - - out: - if (gname != NULL) { - gret = gss_release_name(&minor, &gname); - if (gret != GSS_S_COMPLETE) - gss_log(3, "failed gss_release_name: %s", - gss_error_tostring(gret, minor, buf, - sizeof(buf))); - } - - return (result); -#else - UNUSED(cred); - UNUSED(gssapi_keytab); - UNUSED(intoken); - UNUSED(outtoken); - UNUSED(ctxout); - UNUSED(principal); - UNUSED(mctx); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx) -{ -#ifdef GSSAPI - OM_uint32 gret, minor; - char buf[1024]; - - UNUSED(mctx); - - REQUIRE(gssctx != NULL && *gssctx != NULL); - - /* Delete the context from the GSS provider */ - gret = gss_delete_sec_context(&minor, gssctx, GSS_C_NO_BUFFER); - if (gret != GSS_S_COMPLETE) { - /* Log the error, but still free the context's memory */ - gss_log(3, "Failure deleting security context %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - } - return(ISC_R_SUCCESS); -#else - UNUSED(mctx); - UNUSED(gssctx); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -char * -gss_error_tostring(uint32_t major, uint32_t minor, - char *buf, size_t buflen) { -#ifdef GSSAPI - gss_buffer_desc msg_minor = GSS_C_EMPTY_BUFFER, - msg_major = GSS_C_EMPTY_BUFFER; - OM_uint32 msg_ctx, minor_stat; - - /* Handle major status */ - msg_ctx = 0; - (void)gss_display_status(&minor_stat, major, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg_major); - - /* Handle minor status */ - msg_ctx = 0; - (void)gss_display_status(&minor_stat, minor, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg_minor); - - snprintf(buf, buflen, "GSSAPI error: Major = %s, Minor = %s.", - (char *)msg_major.value, (char *)msg_minor.value); - - if (msg_major.length != 0U) - (void)gss_release_buffer(&minor_stat, &msg_major); - if (msg_minor.length != 0U) - (void)gss_release_buffer(&minor_stat, &msg_minor); - return(buf); -#else - snprintf(buf, buflen, "GSSAPI error: Major = %u, Minor = %u.", - major, minor); - - return (buf); -#endif -} - -void -gss_log(int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_TKEY, ISC_LOG_DEBUG(level), fmt, ap); - va_end(ap); -} - -/*! \file */ diff --git a/lib/dns-pkcs11/hmac_link.c b/lib/dns-pkcs11/hmac_link.c deleted file mode 100644 index 1347593..0000000 --- a/lib/dns-pkcs11/hmac_link.c +++ /dev/null @@ -1,1804 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "dst_internal.h" -#ifdef HAVE_FIPS_MODE -#include "dst_openssl.h" /* FIPS_mode() prototype */ -#endif -#include "dst_parse.h" - -#ifndef PK11_MD5_DISABLE -static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacmd5_key { - unsigned char key[ISC_MD5_BLOCK_LENGTH]; -}; -#endif - -static isc_result_t -getkeybits(dst_key_t *key, struct dst_private_element *element) { - - if (element->length != 2) - return (DST_R_INVALIDPRIVATEKEY); - - key->key_bits = (element->data[0] << 8) + element->data[1]; - - return (ISC_R_SUCCESS); -} - -#ifndef PK11_MD5_DISABLE -static isc_result_t -hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacmd5_t *hmacmd5ctx; - dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5; - - hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t)); - if (hmacmd5ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_MD5_BLOCK_LENGTH); - dctx->ctxdata.hmacmd5ctx = hmacmd5ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacmd5_destroyctx(dst_context_t *dctx) { - isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; - - if (hmacmd5ctx != NULL) { - isc_hmacmd5_invalidate(hmacmd5ctx); - isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t)); - dctx->ctxdata.hmacmd5ctx = NULL; - } -} - -static isc_result_t -hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; - - isc_hmacmd5_update(hmacmd5ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacmd5_sign(hmacmd5ctx, digest); - isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; - - if (sig->length > ISC_MD5_DIGESTLENGTH) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacmd5_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacmd5; - hkey2 = key2->keydata.hmacmd5; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_MD5_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_MD5_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_MD5_BLOCK_LENGTH) { - bytes = ISC_MD5_BLOCK_LENGTH; - key->key_size = ISC_MD5_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_MD5_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacmd5_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacmd5_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacmd5_destroy(dst_key_t *key) { - dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacmd5 = NULL; -} - -static isc_result_t -hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacmd5_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacmd5 != NULL); - - hkey = key->keydata.hmacmd5; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacmd5_key_t *hkey; - int keylen; - isc_region_t r; - isc_md5_t md5ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_MD5_BLOCK_LENGTH) { - isc_md5_init(&md5ctx); - isc_md5_update(&md5ctx, r.base, r.length); - isc_md5_final(&md5ctx, hkey->key); - keylen = ISC_MD5_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacmd5 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacmd5_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacmd5_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacmd5 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacmd5; - - priv.elements[cnt].tag = TAG_HMACMD5_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACMD5_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACMD5_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacmd5_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACMD5_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacmd5_functions = { - hmacmd5_createctx, - NULL, /*%< createctx2 */ - hmacmd5_destroyctx, - hmacmd5_adddata, - hmacmd5_sign, - hmacmd5_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - hmacmd5_compare, - NULL, /*%< paramcompare */ - hmacmd5_generate, - hmacmd5_isprivate, - hmacmd5_destroy, - hmacmd5_todns, - hmacmd5_fromdns, - hmacmd5_tofile, - hmacmd5_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__hmacmd5_init(dst_func_t **funcp) { - - /* Intentionally skip initialization */ - if (!isc_md5_available()) - return (ISC_R_SUCCESS); - -#if PK11_FLAVOR != PK11_UTIMACO_FLAVOR - /* - * Prevent use of incorrect crypto - */ - RUNTIME_CHECK(isc_md5_check(false)); - RUNTIME_CHECK(isc_hmacmd5_check(0)); -#endif - - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacmd5_functions; - return (ISC_R_SUCCESS); -} -#endif - -static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacsha1_key { - unsigned char key[ISC_SHA1_BLOCK_LENGTH]; -}; - -static isc_result_t -hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacsha1_t *hmacsha1ctx; - dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; - - hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t)); - if (hmacsha1ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH); - dctx->ctxdata.hmacsha1ctx = hmacsha1ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacsha1_destroyctx(dst_context_t *dctx) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - - if (hmacsha1ctx != NULL) { - isc_hmacsha1_invalidate(hmacsha1ctx); - isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t)); - dctx->ctxdata.hmacsha1ctx = NULL; - } -} - -static isc_result_t -hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - - isc_hmacsha1_update(hmacsha1ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH); - isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; - - if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha1_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha1; - hkey2 = key2->keydata.hmacsha1; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_SHA1_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_SHA1_BLOCK_LENGTH) { - bytes = ISC_SHA1_BLOCK_LENGTH; - key->key_size = ISC_SHA1_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_SHA1_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacsha1_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha1_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacsha1_destroy(dst_key_t *key) { - dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha1 = NULL; -} - -static isc_result_t -hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha1_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha1 != NULL); - - hkey = key->keydata.hmacsha1; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha1_key_t *hkey; - int keylen; - isc_region_t r; - isc_sha1_t sha1ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_SHA1_BLOCK_LENGTH) { - isc_sha1_init(&sha1ctx); - isc_sha1_update(&sha1ctx, r.base, r.length); - isc_sha1_final(&sha1ctx, hkey->key); - keylen = ISC_SHA1_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha1 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha1_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacsha1_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha1 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha1; - - priv.elements[cnt].tag = TAG_HMACSHA1_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACSHA1_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACSHA1_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacsha1_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACSHA1_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacsha1_functions = { - hmacsha1_createctx, - NULL, /*%< createctx2 */ - hmacsha1_destroyctx, - hmacsha1_adddata, - hmacsha1_sign, - hmacsha1_verify, - NULL, /* verify2 */ - NULL, /* computesecret */ - hmacsha1_compare, - NULL, /* paramcompare */ - hmacsha1_generate, - hmacsha1_isprivate, - hmacsha1_destroy, - hmacsha1_todns, - hmacsha1_fromdns, - hmacsha1_tofile, - hmacsha1_parse, - NULL, /* cleanup */ - NULL, /* fromlabel */ - NULL, /* dump */ - NULL, /* restore */ -}; - -isc_result_t -dst__hmacsha1_init(dst_func_t **funcp) { -#if PK11_FLAVOR != PK11_UTIMACO_FLAVOR - /* - * Prevent use of incorrect crypto - */ - RUNTIME_CHECK(isc_sha1_check(false)); - RUNTIME_CHECK(isc_hmacsha1_check(0)); -#endif - - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacsha1_functions; - return (ISC_R_SUCCESS); -} - -static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacsha224_key { - unsigned char key[ISC_SHA224_BLOCK_LENGTH]; -}; - -static isc_result_t -hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacsha224_t *hmacsha224ctx; - dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; - - hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t)); - if (hmacsha224ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH); - dctx->ctxdata.hmacsha224ctx = hmacsha224ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacsha224_destroyctx(dst_context_t *dctx) { - isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; - - if (hmacsha224ctx != NULL) { - isc_hmacsha224_invalidate(hmacsha224ctx); - isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t)); - dctx->ctxdata.hmacsha224ctx = NULL; - } -} - -static isc_result_t -hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; - - isc_hmacsha224_update(hmacsha224ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH); - isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; - - if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha224_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha224; - hkey2 = key2->keydata.hmacsha224; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, - void (*callback)(int)) -{ - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_SHA224_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_SHA224_BLOCK_LENGTH) { - bytes = ISC_SHA224_BLOCK_LENGTH; - key->key_size = ISC_SHA224_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_SHA224_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacsha224_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha224_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacsha224_destroy(dst_key_t *key) { - dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha224 = NULL; -} - -static isc_result_t -hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha224_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha224 != NULL); - - hkey = key->keydata.hmacsha224; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha224_key_t *hkey; - int keylen; - isc_region_t r; - isc_sha224_t sha224ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_SHA224_BLOCK_LENGTH) { - isc_sha224_init(&sha224ctx); - isc_sha224_update(&sha224ctx, r.base, r.length); - isc_sha224_final(hkey->key, &sha224ctx); - keylen = ISC_SHA224_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha224 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha224_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacsha224_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha224 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha224; - - priv.elements[cnt].tag = TAG_HMACSHA224_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACSHA224_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACSHA224_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacsha224_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACSHA224_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacsha224_functions = { - hmacsha224_createctx, - NULL, /*%< createctx2 */ - hmacsha224_destroyctx, - hmacsha224_adddata, - hmacsha224_sign, - hmacsha224_verify, - NULL, /* verify2 */ - NULL, /* computesecret */ - hmacsha224_compare, - NULL, /* paramcompare */ - hmacsha224_generate, - hmacsha224_isprivate, - hmacsha224_destroy, - hmacsha224_todns, - hmacsha224_fromdns, - hmacsha224_tofile, - hmacsha224_parse, - NULL, /* cleanup */ - NULL, /* fromlabel */ - NULL, /* dump */ - NULL, /* restore */ -}; - -isc_result_t -dst__hmacsha224_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacsha224_functions; - return (ISC_R_SUCCESS); -} - -static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacsha256_key { - unsigned char key[ISC_SHA256_BLOCK_LENGTH]; -}; - -static isc_result_t -hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacsha256_t *hmacsha256ctx; - dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; - - hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t)); - if (hmacsha256ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH); - dctx->ctxdata.hmacsha256ctx = hmacsha256ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacsha256_destroyctx(dst_context_t *dctx) { - isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; - - if (hmacsha256ctx != NULL) { - isc_hmacsha256_invalidate(hmacsha256ctx); - isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t)); - dctx->ctxdata.hmacsha256ctx = NULL; - } -} - -static isc_result_t -hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; - - isc_hmacsha256_update(hmacsha256ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH); - isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; - - if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha256_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha256; - hkey2 = key2->keydata.hmacsha256; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, - void (*callback)(int)) -{ - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_SHA256_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_SHA256_BLOCK_LENGTH) { - bytes = ISC_SHA256_BLOCK_LENGTH; - key->key_size = ISC_SHA256_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_SHA256_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacsha256_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha256_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacsha256_destroy(dst_key_t *key) { - dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha256 = NULL; -} - -static isc_result_t -hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha256_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha256 != NULL); - - hkey = key->keydata.hmacsha256; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha256_key_t *hkey; - int keylen; - isc_region_t r; - isc_sha256_t sha256ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_SHA256_BLOCK_LENGTH) { - isc_sha256_init(&sha256ctx); - isc_sha256_update(&sha256ctx, r.base, r.length); - isc_sha256_final(hkey->key, &sha256ctx); - keylen = ISC_SHA256_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha256 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha256_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacsha256_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha256 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha256; - - priv.elements[cnt].tag = TAG_HMACSHA256_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACSHA256_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACSHA256_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacsha256_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACSHA256_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacsha256_functions = { - hmacsha256_createctx, - NULL, /*%< createctx2 */ - hmacsha256_destroyctx, - hmacsha256_adddata, - hmacsha256_sign, - hmacsha256_verify, - NULL, /* verify2 */ - NULL, /* computesecret */ - hmacsha256_compare, - NULL, /* paramcompare */ - hmacsha256_generate, - hmacsha256_isprivate, - hmacsha256_destroy, - hmacsha256_todns, - hmacsha256_fromdns, - hmacsha256_tofile, - hmacsha256_parse, - NULL, /* cleanup */ - NULL, /* fromlabel */ - NULL, /* dump */ - NULL, /* restore */ -}; - -isc_result_t -dst__hmacsha256_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacsha256_functions; - return (ISC_R_SUCCESS); -} - -static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacsha384_key { - unsigned char key[ISC_SHA384_BLOCK_LENGTH]; -}; - -static isc_result_t -hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacsha384_t *hmacsha384ctx; - dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; - - hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t)); - if (hmacsha384ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH); - dctx->ctxdata.hmacsha384ctx = hmacsha384ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacsha384_destroyctx(dst_context_t *dctx) { - isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; - - if (hmacsha384ctx != NULL) { - isc_hmacsha384_invalidate(hmacsha384ctx); - isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t)); - dctx->ctxdata.hmacsha384ctx = NULL; - } -} - -static isc_result_t -hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; - - isc_hmacsha384_update(hmacsha384ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH); - isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; - - if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha384_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha384; - hkey2 = key2->keydata.hmacsha384; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, - void (*callback)(int)) -{ - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_SHA384_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_SHA384_BLOCK_LENGTH) { - bytes = ISC_SHA384_BLOCK_LENGTH; - key->key_size = ISC_SHA384_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_SHA384_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacsha384_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha384_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacsha384_destroy(dst_key_t *key) { - dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha384 = NULL; -} - -static isc_result_t -hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha384_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha384 != NULL); - - hkey = key->keydata.hmacsha384; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha384_key_t *hkey; - int keylen; - isc_region_t r; - isc_sha384_t sha384ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_SHA384_BLOCK_LENGTH) { - isc_sha384_init(&sha384ctx); - isc_sha384_update(&sha384ctx, r.base, r.length); - isc_sha384_final(hkey->key, &sha384ctx); - keylen = ISC_SHA384_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha384 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha384_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacsha384_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha384 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha384; - - priv.elements[cnt].tag = TAG_HMACSHA384_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACSHA384_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACSHA384_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacsha384_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACSHA384_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacsha384_functions = { - hmacsha384_createctx, - NULL, /*%< createctx2 */ - hmacsha384_destroyctx, - hmacsha384_adddata, - hmacsha384_sign, - hmacsha384_verify, - NULL, /* verify2 */ - NULL, /* computesecret */ - hmacsha384_compare, - NULL, /* paramcompare */ - hmacsha384_generate, - hmacsha384_isprivate, - hmacsha384_destroy, - hmacsha384_todns, - hmacsha384_fromdns, - hmacsha384_tofile, - hmacsha384_parse, - NULL, /* cleanup */ - NULL, /* fromlabel */ - NULL, /* dump */ - NULL, /* restore */ -}; - -isc_result_t -dst__hmacsha384_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacsha384_functions; - return (ISC_R_SUCCESS); -} - -static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data); - -struct dst_hmacsha512_key { - unsigned char key[ISC_SHA512_BLOCK_LENGTH]; -}; - -static isc_result_t -hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_hmacsha512_t *hmacsha512ctx; - dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; - - hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t)); - if (hmacsha512ctx == NULL) - return (ISC_R_NOMEMORY); - isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH); - dctx->ctxdata.hmacsha512ctx = hmacsha512ctx; - return (ISC_R_SUCCESS); -} - -static void -hmacsha512_destroyctx(dst_context_t *dctx) { - isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; - - if (hmacsha512ctx != NULL) { - isc_hmacsha512_invalidate(hmacsha512ctx); - isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t)); - dctx->ctxdata.hmacsha512ctx = NULL; - } -} - -static isc_result_t -hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; - - isc_hmacsha512_update(hmacsha512ctx, data->base, data->length); - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; - unsigned char *digest; - - if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH) - return (ISC_R_NOSPACE); - digest = isc_buffer_used(sig); - isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH); - isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; - - if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0) - return (DST_R_VERIFYFAILURE); - - if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length)) - return (ISC_R_SUCCESS); - else - return (DST_R_VERIFYFAILURE); -} - -static bool -hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) { - dst_hmacsha512_key_t *hkey1, *hkey2; - - hkey1 = key1->keydata.hmacsha512; - hkey2 = key2->keydata.hmacsha512; - - if (hkey1 == NULL && hkey2 == NULL) - return (true); - else if (hkey1 == NULL || hkey2 == NULL) - return (false); - - if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH)) - return (true); - else - return (false); -} - -static isc_result_t -hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, - void (*callback)(int)) -{ - isc_buffer_t b; - isc_result_t ret; - unsigned int bytes; - unsigned char data[ISC_SHA512_BLOCK_LENGTH]; - - UNUSED(callback); - - bytes = (key->key_size + 7) / 8; - if (bytes > ISC_SHA512_BLOCK_LENGTH) { - bytes = ISC_SHA512_BLOCK_LENGTH; - key->key_size = ISC_SHA512_BLOCK_LENGTH * 8; - } - - memset(data, 0, ISC_SHA512_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, pseudorandom_ok); - - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_init(&b, data, bytes); - isc_buffer_add(&b, bytes); - ret = hmacsha512_fromdns(key, &b); - isc_safe_memwipe(data, sizeof(data)); - - return (ret); -} - -static bool -hmacsha512_isprivate(const dst_key_t *key) { - UNUSED(key); - return (true); -} - -static void -hmacsha512_destroy(dst_key_t *key) { - dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; - - isc_safe_memwipe(hkey, sizeof(*hkey)); - isc_mem_put(key->mctx, hkey, sizeof(*hkey)); - key->keydata.hmacsha512 = NULL; -} - -static isc_result_t -hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha512_key_t *hkey; - unsigned int bytes; - - REQUIRE(key->keydata.hmacsha512 != NULL); - - hkey = key->keydata.hmacsha512; - - bytes = (key->key_size + 7) / 8; - if (isc_buffer_availablelength(data) < bytes) - return (ISC_R_NOSPACE); - isc_buffer_putmem(data, hkey->key, bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) { - dst_hmacsha512_key_t *hkey; - int keylen; - isc_region_t r; - isc_sha512_t sha512ctx; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t)); - if (hkey == NULL) - return (ISC_R_NOMEMORY); - - memset(hkey->key, 0, sizeof(hkey->key)); - - if (r.length > ISC_SHA512_BLOCK_LENGTH) { - isc_sha512_init(&sha512ctx); - isc_sha512_update(&sha512ctx, r.base, r.length); - isc_sha512_final(hkey->key, &sha512ctx); - keylen = ISC_SHA512_DIGESTLENGTH; - } else { - memmove(hkey->key, r.base, r.length); - keylen = r.length; - } - - key->key_size = keylen * 8; - key->keydata.hmacsha512 = hkey; - - isc_buffer_forward(data, r.length); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -hmacsha512_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - dst_hmacsha512_key_t *hkey; - dst_private_t priv; - int bytes = (key->key_size + 7) / 8; - unsigned char buf[2]; - - if (key->keydata.hmacsha512 == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - hkey = key->keydata.hmacsha512; - - priv.elements[cnt].tag = TAG_HMACSHA512_KEY; - priv.elements[cnt].length = bytes; - priv.elements[cnt++].data = hkey->key; - - buf[0] = (key->key_bits >> 8) & 0xffU; - buf[1] = key->key_bits & 0xffU; - priv.elements[cnt].tag = TAG_HMACSHA512_BITS; - priv.elements[cnt].data = buf; - priv.elements[cnt++].length = 2; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t result, tresult; - isc_buffer_t b; - isc_mem_t *mctx = key->mctx; - unsigned int i; - - UNUSED(pub); - /* read private key file */ - result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx, - &priv); - if (result != ISC_R_SUCCESS) - return (result); - - if (key->external) - result = DST_R_EXTERNALKEY; - - key->key_bits = 0; - for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { - switch (priv.elements[i].tag) { - case TAG_HMACSHA512_KEY: - isc_buffer_init(&b, priv.elements[i].data, - priv.elements[i].length); - isc_buffer_add(&b, priv.elements[i].length); - tresult = hmacsha512_fromdns(key, &b); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - case TAG_HMACSHA512_BITS: - tresult = getkeybits(key, &priv.elements[i]); - if (tresult != ISC_R_SUCCESS) - result = tresult; - break; - default: - result = DST_R_INVALIDPRIVATEKEY; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (result); -} - -static dst_func_t hmacsha512_functions = { - hmacsha512_createctx, - NULL, /*%< createctx2 */ - hmacsha512_destroyctx, - hmacsha512_adddata, - hmacsha512_sign, - hmacsha512_verify, - NULL, /* verify2 */ - NULL, /* computesecret */ - hmacsha512_compare, - NULL, /* paramcompare */ - hmacsha512_generate, - hmacsha512_isprivate, - hmacsha512_destroy, - hmacsha512_todns, - hmacsha512_fromdns, - hmacsha512_tofile, - hmacsha512_parse, - NULL, /* cleanup */ - NULL, /* fromlabel */ - NULL, /* dump */ - NULL, /* restore */ -}; - -isc_result_t -dst__hmacsha512_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &hmacsha512_functions; - return (ISC_R_SUCCESS); -} - -/*! \file */ diff --git a/lib/dns-pkcs11/include/Makefile.in b/lib/dns-pkcs11/include/Makefile.in deleted file mode 100644 index 3aad93b..0000000 --- a/lib/dns-pkcs11/include/Makefile.in +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -SUBDIRS = dns dst -TARGETS = - -@BIND9_MAKE_RULES@ diff --git a/lib/dns-pkcs11/include/dns/Makefile.in b/lib/dns-pkcs11/include/dns/Makefile.in deleted file mode 100644 index dd20002..0000000 --- a/lib/dns-pkcs11/include/dns/Makefile.in +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -VERSION=@BIND9_VERSION@ - -HEADERS = acache.h acl.h adb.h badcache.h bit.h byaddr.h \ - cache.h callbacks.h catz.h cert.h \ - client.h clientinfo.h compress.h \ - db.h dbiterator.h dbtable.h diff.h dispatch.h \ - dlz.h dlz_dlopen.h dns64.h dnssec.h ds.h dsdigest.h \ - dnstap.h dyndb.h \ - edns.h ecdb.h events.h fixedname.h forward.h geoip.h \ - ipkeylist.h iptable.h \ - journal.h keydata.h keyflags.h keytable.h keyvalues.h \ - lib.h lookup.h log.h master.h masterdump.h message.h \ - name.h ncache.h nsec.h nsec3.h nta.h opcode.h order.h \ - peer.h portlist.h private.h \ - rbt.h rcode.h rdata.h rdataclass.h rdatalist.h \ - rdataset.h rdatasetiter.h rdataslab.h rdatatype.h request.h \ - resolver.h result.h rootns.h rpz.h rriterator.h rrl.h \ - sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h stats.h \ - tcpmsg.h time.h timer.h tkey.h tsec.h tsig.h ttl.h types.h \ - update.h validator.h version.h view.h xfrin.h \ - zone.h zonekey.h zt.h - -GENHEADERS = enumclass.h enumtype.h rdatastruct.h - -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/dns - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dns || exit 1; \ - done - for i in ${GENHEADERS}; do \ - ${INSTALL_DATA} $$i ${DESTDIR}${includedir}/dns || exit 1; \ - done - -uninstall:: - for i in ${GENHEADERS}; do \ - rm -f ${DESTDIR}${includedir}/dns/$$i || exit 1; \ - done - for i in ${HEADERS}; do \ - rm -f ${DESTDIR}${includedir}/dns/$$i || exit 1; \ - done diff --git a/lib/dns-pkcs11/include/dns/acache.h b/lib/dns-pkcs11/include/dns/acache.h deleted file mode 100644 index d63c1fc..0000000 --- a/lib/dns-pkcs11/include/dns/acache.h +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_ACACHE_H -#define DNS_ACACHE_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Acache - * - * The Additional Cache Object - * - * This module manages internal caching entries that correspond to - * the additional section data of a DNS DB node (an RRset header, more - * accurately). An additional cache entry is expected to be (somehow) - * attached to a particular RR in a particular DB node, and contains a set - * of information of an additional data for the DB node. - * - * An additional cache object is intended to be created as a per-view - * object, and manages all cache entries within the view. - * - * The intended usage of the additional caching is to provide a short cut - * to additional glue RRs of an NS RR. For each NS RR, it is often - * necessary to look for glue RRs to make a proper response. Once the - * glue RRs are known, the additional caching allows the client to - * associate the information to the original NS RR so that further - * expensive lookups can be avoided for the NS RR. - * - * Each additional cache entry contains information to identify a - * particular DB node and (optionally) an associated RRset. The - * information consists of its zone, database, the version of the - * database, database node, and RRset. - * - * A "negative" information can also be cached. For example, if a glue - * RR does not exist as an authoritative data in the same zone as that - * of the NS RR, this fact can be cached by specifying a NULL pointer - * for the database, version, and node. (See the description for - * dns_acache_getentry() below for more details.) - * - * Since each member stored in an additional cache entry holds a reference - * to a corresponding object, a stale cache entry may cause unnecessary - * memory consumption. For instance, when a zone is reloaded, additional - * cache entries that have a reference to the zone (and its DB and/or - * DB nodes) can delay the cleanup of the referred objects. In order to - * minimize such a bad effect, this module provides several cleanup - * mechanisms. - * - * The first one is a shutdown procedure called when the associated view - * is shut down. In this case, dns_acache_shutdown() will be called and - * all cache entries will be purged. This mechanism will help the - * situation when the configuration is reloaded or the main server is - * stopped. - * - * Per-DB cleanup mechanism is also provided. Each additional cache entry - * is associated with related DB, which is expected to have been - * registered when the DB was created by dns_acache_setdb(). If a - * particular DB is going to be destroyed, the primary holder of the DB, - * a typical example of which is a zone, will call dns_acache_putdb(). - * Then this module will clean-up all cache entries associated with the - * DB. This mechanism is effective when a secondary zone DB is going to - * be stale after a zone transfer. - * - * Finally, this module supports for periodic clean-up of stale entries. - * Each cache entry has a timestamp field, which is updated every time - * the entry is referred. A periodically invoked cleaner checks the - * timestamp of each entry, and purge entries that have not been referred - * for a certain period. The cleaner interval can be specified by - * dns_acache_setcleaninginterval(). If the periodic clean-up is not - * enough, it is also possible to specify the upper limit of entries - * in terms of the memory consumption. If the maximum value is - * specified, the cleaner is invoked when the memory consumption reaches - * the high watermark inferred from the maximum value. In this case, - * the cleaner will use more aggressive algorithm to decide the "victim" - * entries. The maximum value can be specified by - * dns_acache_setcachesize(). - * - * When a cache entry is going to be purged within this module, the - * callback function specified at the creation time will be called. - * The callback function is expected to release all internal resources - * related to the entry, which will typically be specific to DB - * implementation, and to call dns_acache_detachentry(). The callback - * mechanism is very important, since the holder of an additional cache - * entry may not be able to initiate the clean-up of the entry, due to - * the reference ordering. For example, as long as an additional cache - * entry has a reference to a DB object, the DB cannot be freed, in which - * a DB node may have a reference to the cache entry. - * - * Credits: - * The basic idea of this kind of short-cut for frequently used - * information is similar to the "pre-compiled answer" approach adopted - * in nsd by NLnet LABS with RIPE NCC. Our work here is an independent - * effort, but the success of nsd encouraged us to pursue this path. - * - * The design and implementation of the periodic memory management and - * the upper limitation of memory consumption was derived from the cache - * DB implementation of BIND9. - * - * MP: - * There are two main locks in this module. One is for each entry, and - * the other is for the additional cache object. - * - * Reliability: - * The callback function for a cache entry is called with holding the - * entry lock. Thus, it implicitly assumes the callback function does not - * call a function that can require the lock. Typically, the only - * function that can be called from the callback function safely is - * dns_acache_detachentry(). The breakage of this implicit assumption - * may cause a deadlock. - * - * Resources: - * In a 32-bit architecture (such as i386), the following additional - * memory is required comparing to the case that disables this module. - * - 76 bytes for each additional cache entry - * - if the entry has a DNS name and associated RRset, - * * 44 bytes + size of the name (1-255 bytes) - * * 52 bytes x number_of_RRs - * - 28 bytes for each DB related to this module - * - * Using the additional cache also requires extra memory consumption in - * the DB implementation. In the current implementation for rbtdb, we - * need: - * - two additional pointers for each DB node (8 bytes for a 32-bit - * architecture - * - for each RR associated to an RR in a DB node, we also need - * a pointer and management objects to support the additional cache - * function. These are allocated on-demand. The total size is - * 32 bytes for a 32-bit architecture. - * - * Security: - * Since this module does not handle any low-level data directly, - * no security issue specific to this module is anticipated. - * - * Standards: - * None. - */ - -/*** - *** Imports - ***/ - -#include -#include -#include - -#include - -/*** - *** Functions - ***/ -ISC_LANG_BEGINDECLS - -isc_result_t -dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, - isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr); -/* - * Create a new DNS additional cache object. - * - * Requires: - * - * 'mctx' is a valid memory context - * - * 'taskmgr' is a valid task manager - * - * 'timermgr' is a valid timer or NULL. If NULL, no periodic cleaning of - * the cache will take place. - * - * 'acachep' is a valid pointer, and *acachep == NULL - * - * Ensures: - * - * '*acachep' is attached to the newly created cache - * - * Returns: - * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_UNEXPECTED - */ - -void -dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp); -/* - * Attach *targetp to cache. - * - * Requires: - * - * 'acache' is a valid additional cache. - * - * 'targetp' points to a NULL dns_acache_t *. - * - * Ensures: - * - * *targetp is attached to the 'source' additional cache. - */ - -void -dns_acache_detach(dns_acache_t **acachep); -/* - * Detach *acachep from its cache. - * - * Requires: - * - * '*acachep' points to a valid additional cache. - * - * Ensures: - * - * *acachep is NULL. - * - * If '*acachep' is the last reference to the cache and the additional - * cache does not have an outstanding task, all resources used by the - * cache will be freed. - */ - -void -dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t); -/* - * Set the periodic cleaning interval of an additional cache to 'interval' - * seconds. - */ - -void -dns_acache_setcachesize(dns_acache_t *acache, size_t size); -/* - * Set the maximum additional cache size. 0 means unlimited. - */ - -isc_result_t -dns_acache_setdb(dns_acache_t *acache, dns_db_t *db); -/* - * Set 'db' in 'acache' when the db can be referred from acache, in order - * to provide a hint for resolving the back reference. - * - * Requires: - * 'acache' is a valid acache pointer. - * 'db' is a valid DNS DB pointer. - * - * Ensures: - * 'acache' will have a reference to 'db'. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_EXISTS (which means the specified 'db' is already set) - * ISC_R_NOMEMORY - */ - -isc_result_t -dns_acache_putdb(dns_acache_t *acache, dns_db_t *db); -/* - * Release 'db' from 'acache' if it has been set by dns_acache_setdb(). - * - * Requires: - * 'acache' is a valid acache pointer. - * 'db' is a valid DNS DB pointer. - * - * Ensures: - * 'acache' will release the reference to 'db'. Additionally, the content - * of each cache entry that is related to the 'db' will be released via - * the callback function. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND (which means the specified 'db' is not set in 'acache') - * ISC_R_NOMEMORY - */ - -void -dns_acache_shutdown(dns_acache_t *acache); -/* - * Shutdown 'acache'. - * - * Requires: - * - * '*acache' is a valid additional cache. - */ - -isc_result_t -dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, - void (*callback)(dns_acacheentry_t *, void **), - void *cbarg, dns_acacheentry_t **entryp); -/* - * Create an additional cache entry. A new entry is created and attached to - * the given additional cache object. A callback function is also associated - * with the created entry, which will be called when the cache entry is purged - * for some reason. - * - * Requires: - * - * 'acache' is a valid additional cache. - * 'entryp' is a valid pointer, and *entryp == NULL - * 'origdb' is a valid DNS DB pointer. - * 'callback' and 'cbarg' can be NULL. In this case, however, the entry - * is meaningless (and will be cleaned-up in the next periodical - * cleaning). - * - * Ensures: - * '*entryp' will point to a new additional cache entry. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -isc_result_t -dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, - dns_db_t **dbp, dns_dbversion_t **versionp, - dns_dbnode_t **nodep, dns_name_t *fname, - dns_message_t *msg, isc_stdtime_t now); -/* - * Get content from a particular additional cache entry. - * - * Requires: - * - * 'entry' is a valid additional cache entry. - * 'zonep' is a NULL pointer or '*zonep' == NULL (this is the only - * optional parameter.) - * 'dbp' is a valid pointer, and '*dbp' == NULL - * 'versionp' is a valid pointer, and '*versionp' == NULL - * 'nodep' is a valid pointer, and '*nodep' == NULL - * 'fname' is a valid DNS name. - * 'msg' is a valid DNS message. - * - * Ensures: - * Several possible cases can happen according to the content. - * 1. For a positive cache entry, - * '*zonep' will point to the corresponding zone (if zonep is a valid - * pointer), - * '*dbp' will point to a DB for the zone, - * '*versionp' will point to its version, and - * '*nodep' will point to the corresponding DB node. - * 'fname' will have the DNS name of the DB node and contain a list of - * rdataset for the node (which can be an empty list). - * - * 2. For a negative cache entry that means no corresponding zone exists, - * '*zonep' == NULL (if zonep is a valid pointer) - * '*dbp', '*versionp', and '*nodep' will be NULL. - * - * 3. For a negative cache entry that means no corresponding DB node - * exists, '*zonep' will point to the corresponding zone (if zonep is a - * valid pointer), - * '*dbp' will point to a corresponding DB for zone, - * '*versionp' will point to its version. - * '*nodep' will be kept as NULL. - * 'fname' will not change. - * - * On failure, no new references will be created. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -isc_result_t -dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, - dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *fname); -/* - * Set content to a particular additional cache entry. - * - * Requires: - * 'acache' is a valid additional cache. - * 'entry' is a valid additional cache entry. - * All the others pointers are NULL or a valid pointer of the - * corresponding type. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOTFOUND - */ - -bool -dns_acache_cancelentry(dns_acacheentry_t *entry); -/* - * Cancel the use of the cache entry 'entry'. This function is supposed to - * be called when the node that holds the entry finds the content is not - * correct any more. This function will try to release as much dependency as - * possible, and will be ready to be cleaned-up. The registered callback - * function will be canceled and will never called. - * - * Requires: - * 'entry' is a valid additional cache entry. - * - * Returns: - * true if the entry was active when canceled - */ - -void -dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp); -/* - * Attach *targetp to the cache entry 'source'. - * - * Requires: - * - * 'source' is a valid additional cache entry. - * - * 'targetp' points to a NULL dns_acacheentry_t *. - * - * Ensures: - * - * *targetp is attached to 'source'. - */ - -void -dns_acache_detachentry(dns_acacheentry_t **entryp); -/* - * Detach *entryp from its cache. - * - * Requires: - * - * '*entryp' points to a valid additional cache entry. - * - * Ensures: - * - * *entryp is NULL. - * - * If '*entryp' is the last reference to the entry, - * cache does not have an outstanding task, all resources used by the - * entry (including the entry object itself) will be freed. - */ - -void -dns_acache_countquerymiss(dns_acache_t *acache); -/* - * Count up a missed acache query. XXXMLG need more docs. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ACACHE_H */ diff --git a/lib/dns-pkcs11/include/dns/acl.h b/lib/dns-pkcs11/include/dns/acl.h deleted file mode 100644 index 0913ccd..0000000 --- a/lib/dns-pkcs11/include/dns/acl.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_ACL_H -#define DNS_ACL_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/acl.h - * \brief - * Address match list handling. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include -#include - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -#include -#endif -#include -#include -#include - -/*** - *** Types - ***/ - -typedef enum { - dns_aclelementtype_ipprefix, - dns_aclelementtype_keyname, - dns_aclelementtype_nestedacl, - dns_aclelementtype_localhost, - dns_aclelementtype_localnets, -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - dns_aclelementtype_geoip, -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - dns_aclelementtype_any -} dns_aclelementtype_t; - -typedef struct dns_aclipprefix dns_aclipprefix_t; - -struct dns_aclipprefix { - isc_netaddr_t address; /* IP4/IP6 */ - unsigned int prefixlen; -}; - -struct dns_aclelement { - dns_aclelementtype_t type; - bool negative; - dns_name_t keyname; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - dns_geoip_elem_t geoip_elem; -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - dns_acl_t *nestedacl; - int node_num; -}; - -#define dns_acl_node_count(acl) acl->iptable->radix->num_added_node - -struct dns_acl { - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t refcount; - dns_iptable_t *iptable; - dns_aclelement_t *elements; - bool has_negatives; - unsigned int alloc; /*%< Elements allocated */ - unsigned int length; /*%< Elements initialized */ - char *name; /*%< Temporary use only */ - ISC_LINK(dns_acl_t) nextincache; /*%< Ditto */ -}; - -struct dns_aclenv { - dns_acl_t *localhost; - dns_acl_t *localnets; - bool match_mapped; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - dns_geoip_databases_t *geoip; - bool geoip_use_ecs; -#endif -}; - -#define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l') -#define DNS_ACL_VALID(a) ISC_MAGIC_VALID(a, DNS_ACL_MAGIC) - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target); -/*%< - * Create a new ACL, including an IP table and an array with room - * for 'n' ACL elements. The elements are uninitialized and the - * length is 0. - */ - -isc_result_t -dns_acl_any(isc_mem_t *mctx, dns_acl_t **target); -/*%< - * Create a new ACL that matches everything. - */ - -isc_result_t -dns_acl_none(isc_mem_t *mctx, dns_acl_t **target); -/*%< - * Create a new ACL that matches nothing. - */ - -bool -dns_acl_isany(dns_acl_t *acl); -/*%< - * Test whether ACL is set to "{ any; }" - */ - -bool -dns_acl_isnone(dns_acl_t *acl); -/*%< - * Test whether ACL is set to "{ none; }" - */ - -isc_result_t -dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, bool pos); -/*%< - * Merge the contents of one ACL into another. Call dns_iptable_merge() - * for the IP tables, then concatenate the element arrays. - * - * If pos is set to false, then the nested ACL is to be negated. This - * means reverse the sense of each *positive* element or IP table node, - * but leave negatives alone, so as to prevent a double-negative causing - * an unexpected positive match in the parent ACL. - */ - -void -dns_acl_attach(dns_acl_t *source, dns_acl_t **target); -/*%< - * Attach to acl 'source'. - * - * Requires: - *\li 'source' to be a valid acl. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_acl_detach(dns_acl_t **aclp); -/*%< - * Detach the acl. On final detach the acl must not be linked on any - * list. - * - * Requires: - *\li '*aclp' to be a valid acl. - * - * Insists: - *\li '*aclp' is not linked on final detach. - */ - -bool -dns_acl_isinsecure(const dns_acl_t *a); -/*%< - * Return #true iff the acl 'a' is considered insecure, that is, - * if it contains IP addresses other than those of the local host. - * This is intended for applications such as printing warning - * messages for suspect ACLs; it is not intended for making access - * control decisions. We make no guarantee that an ACL for which - * this function returns #false is safe. - */ - -isc_result_t -dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env); -/*%< - * Initialize ACL environment, setting up localhost and localnets ACLs - */ - -void -dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s); - -void -dns_aclenv_destroy(dns_aclenv_t *env); - -isc_result_t -dns_acl_match(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const dns_acl_t *acl, - const dns_aclenv_t *env, - int *match, - const dns_aclelement_t **matchelt); - -isc_result_t -dns_acl_match2(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const isc_netaddr_t *ecs, - uint8_t ecslen, - uint8_t *scope, - const dns_acl_t *acl, - const dns_aclenv_t *env, - int *match, - const dns_aclelement_t **matchelt); -/*%< - * General, low-level ACL matching. This is expected to - * be useful even for weird stuff like the topology and sortlist statements. - * - * Match the address 'reqaddr', and optionally the key name 'reqsigner', - * and optionally the client prefix 'ecs' of length 'ecslen' - * (reported via EDNS client subnet option) against 'acl'. - * - * 'reqsigner' and 'ecs' may be NULL. If an ACL matches against 'ecs' - * and 'ecslen', then 'scope' will be set to indicate the netmask that - * matched. - * - * If there is a match, '*match' will be set to an integer whose absolute - * value corresponds to the order in which the matching value was inserted - * into the ACL. For a positive match, this value will be positive; for a - * negative match, it will be negative. - * - * If there is no match, *match will be set to zero. - * - * If there is a match in the element list (either positive or negative) - * and 'matchelt' is non-NULL, *matchelt will be pointed to the matching - * element. - * - * 'env' points to the current ACL environment, including the - * current values of localhost and localnets and (if applicable) - * the GeoIP context. - * - * Returns: - *\li #ISC_R_SUCCESS Always succeeds. - */ - -bool -dns_aclelement_match(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const dns_aclelement_t *e, - const dns_aclenv_t *env, - const dns_aclelement_t **matchelt); - -bool -dns_aclelement_match2(const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, - const isc_netaddr_t *ecs, - uint8_t ecslen, - uint8_t *scope, - const dns_aclelement_t *e, - const dns_aclenv_t *env, - const dns_aclelement_t **matchelt); -/*%< - * Like dns_acl_match, but matches against the single ACL element 'e' - * rather than a complete ACL, and returns true iff it matched. - * - * To determine whether the match was positive or negative, the - * caller should examine e->negative. Since the element 'e' may be - * a reference to a named ACL or a nested ACL, a matching element - * returned through 'matchelt' is not necessarily 'e' itself. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ACL_H */ diff --git a/lib/dns-pkcs11/include/dns/adb.h b/lib/dns-pkcs11/include/dns/adb.h deleted file mode 100644 index 2eb77b3..0000000 --- a/lib/dns-pkcs11/include/dns/adb.h +++ /dev/null @@ -1,845 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ADB_H -#define DNS_ADB_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/adb.h - *\brief - * DNS Address Database - * - * This module implements an address database (ADB) for mapping a name - * to an isc_sockaddr_t. It also provides statistical information on - * how good that address might be. - * - * A client will pass in a dns_name_t, and the ADB will walk through - * the rdataset looking up addresses associated with the name. If it - * is found on the internal lists, a structure is filled in with the - * address information and stats for found addresses. - * - * If the name cannot be found on the internal lists, a new entry will - * be created for a name if all the information needed can be found - * in the zone table or cache. This new address will then be returned. - * - * If a request must be made to remote servers to satisfy a name lookup, - * this module will start fetches to try to complete these addresses. When - * at least one more completes, an event is sent to the caller. If none of - * them resolve before the fetch times out, an event indicating this is - * sent instead. - * - * Records are stored internally until a timer expires. The timer is the - * smaller of the TTL or signature validity period. - * - * Lameness is stored per tuple, and this data hangs off each - * address field. When an address is marked lame for a given tuple the address - * will not be returned to a caller. - * - * - * MP: - * - *\li The ADB takes care of all necessary locking. - * - *\li Only the task which initiated the name lookup can cancel the lookup. - * - * - * Security: - * - *\li None, since all data stored is required to be pre-filtered. - * (Cache needs to be sane, fetches return bounds-checked and sanity- - * checked data, caller passes a good dns_name_t for the zone, etc) - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Magic number checks - ***/ - -#define DNS_ADBFIND_MAGIC ISC_MAGIC('a','d','b','H') -#define DNS_ADBFIND_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFIND_MAGIC) -#define DNS_ADBADDRINFO_MAGIC ISC_MAGIC('a','d','A','I') -#define DNS_ADBADDRINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBADDRINFO_MAGIC) - - -/*** - *** TYPES - ***/ - -typedef struct dns_adbname dns_adbname_t; - -/*! - *\brief - * Represents a lookup for a single name. - * - * On return, the client can safely use "list", and can reorder the list. - * Items may not be _deleted_ from this list, however, or added to it - * other than by using the dns_adb_*() API. - */ -struct dns_adbfind { - /* Public */ - unsigned int magic; /*%< RO: magic */ - dns_adbaddrinfolist_t list; /*%< RO: list of addrs */ - unsigned int query_pending; /*%< RO: partial list */ - unsigned int partial_result; /*%< RO: addrs missing */ - unsigned int options; /*%< RO: options */ - isc_result_t result_v4; /*%< RO: v4 result */ - isc_result_t result_v6; /*%< RO: v6 result */ - ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */ - - /* Private */ - isc_mutex_t lock; /* locks all below */ - in_port_t port; - int name_bucket; - unsigned int flags; - dns_adbname_t *adbname; - dns_adb_t *adb; - isc_event_t event; - ISC_LINK(dns_adbfind_t) plink; -}; - -/* - * _INET: - * _INET6: - * return addresses of that type. - * - * _EMPTYEVENT: - * Only schedule an event if no addresses are known. - * Must set _WANTEVENT for this to be meaningful. - * - * _WANTEVENT: - * An event is desired. Check this bit in the returned find to see - * if one will actually be generated. - * - * _AVOIDFETCHES: - * If set, fetches will not be generated unless no addresses are - * available in any of the address families requested. - * - * _STARTATZONE: - * Fetches will start using the closest zone data or use the root servers. - * This is useful for reestablishing glue that has expired. - * - * _GLUEOK: - * _HINTOK: - * Glue or hints are ok. These are used when matching names already - * in the adb, and when dns databases are searched. - * - * _RETURNLAME: - * Return lame servers in a find, so that all addresses are returned. - * - * _LAMEPRUNED: - * At least one address was omitted from the list because it was lame. - * This bit will NEVER be set if _RETURNLAME is set in the createfind(). - */ -/*% Return addresses of type INET. */ -#define DNS_ADBFIND_INET 0x00000001 -/*% Return addresses of type INET6. */ -#define DNS_ADBFIND_INET6 0x00000002 -#define DNS_ADBFIND_ADDRESSMASK 0x00000003 -/*% - * Only schedule an event if no addresses are known. - * Must set _WANTEVENT for this to be meaningful. - */ -#define DNS_ADBFIND_EMPTYEVENT 0x00000004 -/*% - * An event is desired. Check this bit in the returned find to see - * if one will actually be generated. - */ -#define DNS_ADBFIND_WANTEVENT 0x00000008 -/*% - * If set, fetches will not be generated unless no addresses are - * available in any of the address families requested. - */ -#define DNS_ADBFIND_AVOIDFETCHES 0x00000010 -/*% - * Fetches will start using the closest zone data or use the root servers. - * This is useful for reestablishing glue that has expired. - */ -#define DNS_ADBFIND_STARTATZONE 0x00000020 -/*% - * Glue or hints are ok. These are used when matching names already - * in the adb, and when dns databases are searched. - */ -#define DNS_ADBFIND_GLUEOK 0x00000040 -/*% - * Glue or hints are ok. These are used when matching names already - * in the adb, and when dns databases are searched. - */ -#define DNS_ADBFIND_HINTOK 0x00000080 -/*% - * Return lame servers in a find, so that all addresses are returned. - */ -#define DNS_ADBFIND_RETURNLAME 0x00000100 -/*% - * Only schedule an event if no addresses are known. - * Must set _WANTEVENT for this to be meaningful. - */ -#define DNS_ADBFIND_LAMEPRUNED 0x00000200 -/*% - * The server's fetch quota is exceeded; it will be treated as - * lame for this query. - */ -#define DNS_ADBFIND_OVERQUOTA 0x00000400 -/*% - * Don't perform a fetch even if there are no address records available. - */ -#define DNS_ADBFIND_NOFETCH 0x00000800 - -/*% - * The answers to queries come back as a list of these. - */ -struct dns_adbaddrinfo { - unsigned int magic; /*%< private */ - - isc_sockaddr_t sockaddr; /*%< [rw] */ - unsigned int srtt; /*%< [rw] microsecs */ - isc_dscp_t dscp; - - unsigned int flags; /*%< [rw] */ - dns_adbentry_t *entry; /*%< private */ - ISC_LINK(dns_adbaddrinfo_t) publink; -}; - -/*!< - * The event sent to the caller task is just a plain old isc_event_t. It - * contains no data other than a simple status, passed in the "type" field - * to indicate that another address resolved, or all partially resolved - * addresses have failed to resolve. - * - * "sender" is the dns_adbfind_t used to issue this query. - * - * This is simply a standard event, with the "type" set to: - * - *\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved. - *\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed, - * were canceled, or otherwise will - * not be usable. - *\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a - * 3rd party. - *\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request - * was canceled. - * - * In each of these cases, the addresses returned by the initial call - * to dns_adb_createfind() can still be used until they are no longer needed. - */ - -/**** - **** FUNCTIONS - ****/ - - -isc_result_t -dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *tmgr, - isc_taskmgr_t *taskmgr, dns_adb_t **newadb); -/*%< - * Create a new ADB. - * - * Notes: - * - *\li Generally, applications should not create an ADB directly, but - * should instead call dns_view_createresolver(). - * - * Requires: - * - *\li 'mem' must be a valid memory context. - * - *\li 'view' be a pointer to a valid view. - * - *\li 'tmgr' be a pointer to a valid timer manager. - * - *\li 'taskmgr' be a pointer to a valid task manager. - * - *\li 'newadb' != NULL && '*newadb' == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS after happiness. - *\li #ISC_R_NOMEMORY after resource allocation failure. - */ - -void -dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbp); -/*% - * Attach to an 'adb' to 'adbp'. - * - * Requires: - *\li 'adb' to be a valid dns_adb_t, created via dns_adb_create(). - *\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized - * to NULL. - */ - -void -dns_adb_detach(dns_adb_t **adb); -/*% - * Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests. - * - * Requires: - * - *\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via - * dns_adb_create(). - */ - -void -dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp); -/*% - * Send '*eventp' to 'task' when 'adb' has shutdown. - * - * Requires: - * - *\li '*adb' is a valid dns_adb_t. - * - *\li eventp != NULL && *eventp is a valid event. - * - * Ensures: - * - *\li *eventp == NULL - * - *\li The event's sender field is set to the value of adb when the event - * is sent. - */ - -void -dns_adb_shutdown(dns_adb_t *adb); -/*%< - * Shutdown 'adb'. - * - * Requires: - * - * \li '*adb' is a valid dns_adb_t. - */ - -isc_result_t -dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *qname, - dns_rdatatype_t qtype, unsigned int options, - isc_stdtime_t now, dns_name_t *target, - in_port_t port, dns_adbfind_t **find); -isc_result_t -dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *qname, - dns_rdatatype_t qtype, unsigned int options, - isc_stdtime_t now, dns_name_t *target, in_port_t port, - unsigned int depth, isc_counter_t *qc, - dns_adbfind_t **find); -/*%< - * Main interface for clients. The adb will look up the name given in - * "name" and will build up a list of found addresses, and perhaps start - * internal fetches to resolve names that are unknown currently. - * - * If other addresses resolve after this call completes, an event will - * be sent to the with the sender of that event - * set to a pointer to the dns_adbfind_t returned by this function. - * - * If no events will be generated, the *find->result_v4 and/or result_v6 - * members may be examined for address lookup status. The usual #ISC_R_SUCCESS, - * #ISC_R_FAILURE, #DNS_R_NXDOMAIN, and #DNS_R_NXRRSET are returned, along with - * #ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this - * latter case, retrying may produce more addresses. - * - * If events will be returned, the result_v[46] members are only valid - * when that event is actually returned. - * - * The list of addresses returned is unordered. The caller must impose - * any ordering required. The list will not contain "known bad" addresses, - * however. For instance, it will not return hosts that are known to be - * lame for the zone in question. - * - * The caller cannot (directly) modify the contents of the address list's - * fields other than the "link" field. All values can be read at any - * time, however. - * - * The "now" parameter is used only for determining which entries that - * have a specific time to live or expire time should be removed from - * the running database. If specified as zero, the current time will - * be retrieved and used. - * - * If 'target' is not NULL and 'name' is an alias (i.e. the name is - * CNAME'd or DNAME'd to another name), then 'target' will be updated with - * the domain name that 'name' is aliased to. - * - * All addresses returned will have the sockaddr's port set to 'port.' - * The caller may change them directly in the dns_adbaddrinfo_t since - * they are copies of the internal address only. - * - * XXXMLG Document options, especially the flags which control how - * events are sent. - * - * Requires: - * - *\li *adb be a valid isc_adb_t object. - * - *\li If events are to be sent, *task be a valid task, - * and isc_taskaction_t != NULL. - * - *\li *name is a valid dns_name_t. - * - *\li qname != NULL and *qname be a valid dns_name_t. - * - *\li target == NULL or target is a valid name with a buffer. - * - *\li find != NULL && *find == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS Addresses might have been returned, and events will be - * delivered for unresolved addresses. - *\li #ISC_R_NOMORE Addresses might have been returned, but no events - * will ever be posted for this context. This is only - * returned if task != NULL. - *\li #ISC_R_NOMEMORY insufficient resources - *\li #DNS_R_ALIAS 'name' is an alias for another name. - * - * Calls, and returns error codes from: - * - *\li isc_stdtime_get() - * - * Notes: - * - *\li No internal reference to "name" exists after this function - * returns. - */ - -void -dns_adb_cancelfind(dns_adbfind_t *find); -/*%< - * Cancels the find, and sends the event off to the caller. - * - * It is an error to call dns_adb_cancelfind() on a find where - * no event is wanted, or will ever be sent. - * - * Note: - * - *\li It is possible that the real completion event was posted just - * before the dns_adb_cancelfind() call was made. In this case, - * dns_adb_cancelfind() will do nothing. The event callback needs - * to be prepared to find this situation (i.e. result is valid but - * the caller expects it to be canceled). - * - * Requires: - * - *\li 'find' be a valid dns_adbfind_t pointer. - * - *\li events would have been posted to the task. This can be checked - * with (find->options & DNS_ADBFIND_WANTEVENT). - * - * Ensures: - * - *\li The event was posted to the task. - */ - -void -dns_adb_destroyfind(dns_adbfind_t **find); -/*%< - * Destroys the find reference. - * - * Note: - * - *\li This can only be called after the event was delivered for a - * find. Additionally, the event MUST have been freed via - * isc_event_free() BEFORE this function is called. - * - * Requires: - * - *\li 'find' != NULL and *find be valid dns_adbfind_t pointer. - * - * Ensures: - * - *\li No "address found" events will be posted to the originating task - * after this function returns. - */ - -void -dns_adb_dump(dns_adb_t *adb, FILE *f); -/*%< - * This function is only used for debugging. It will dump as much of the - * state of the running system as possible. - * - * Requires: - * - *\li adb be valid. - * - *\li f != NULL, and is a file open for writing. - */ - -void -dns_adb_dumpfind(dns_adbfind_t *find, FILE *f); -/*%< - * This function is only used for debugging. Dump the data associated - * with a find. - * - * Requires: - * - *\li find is valid. - * - * \li f != NULL, and is a file open for writing. - */ - -isc_result_t -dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, - dns_rdatatype_t type, isc_stdtime_t expire_time); -/*%< - * Mark the given address as lame for the . expire_time should - * be set to the time when the entry should expire. That is, if it is to - * expire 10 minutes in the future, it should set it to (now + 10 * 60). - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - * - *\li qname be the qname used in the dns_adb_createfind() call. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - *\li #ISC_R_NOMEMORY -- could not mark address as lame. - */ - -/* - * Reasonable defaults for RTT adjustments - * - * (Note: these values function both as scaling factors and as - * indicators of the type of RTT adjustment operation taking place. - * Adjusting the scaling factors is fine, as long as they all remain - * unique values.) - */ -#define DNS_ADB_RTTADJDEFAULT 7 /*%< default scale */ -#define DNS_ADB_RTTADJREPLACE 0 /*%< replace with our rtt */ -#define DNS_ADB_RTTADJAGE 10 /*%< age this rtt */ - -void -dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned int rtt, unsigned int factor); -/*%< - * Mix the round trip time into the existing smoothed rtt. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - * - *\li 0 <= factor <= 10 - * - * Note: - * - *\li The srtt in addr will be updated to reflect the new global - * srtt value. This may include changes made by others. - */ - -void -dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now); -/* - * dns_adb_agesrtt is equivalent to dns_adb_adjustsrtt with factor - * equal to DNS_ADB_RTTADJAGE and the current time passed in. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - * - * Note: - * - *\li The srtt in addr will be updated to reflect the new global - * srtt value. This may include changes made by others. - */ - -void -dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned int bits, unsigned int mask); -/*% - * Change Flags. - * - * Set the flags as given by: - * - *\li newflags = (oldflags & ~mask) | (bits & mask); - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -void -dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); -/*% - * Update seen UDP response size. The largest seen will be returned by - * dns_adb_getudpsize(). - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -unsigned int -dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -/*% - * Return the largest seen UDP response size. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -unsigned int -dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -unsigned int -dns_adb_probesize2(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups); -/*% - * Return suggested EDNS UDP size based on observed responses / failures. - * 'lookups' is the number of times the current lookup has been attempted. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -void -dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -/*% - * Record a successful plain DNS response. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -void -dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -/*% - * Record a plain DNS UDP query failed. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -void -dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); -/*% - * Record a failed EDNS UDP response and the advertised EDNS UDP buffer size - * used. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -bool -dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -/*% - * Return whether EDNS should be disabled for this server. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - - -isc_result_t -dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, - dns_adbaddrinfo_t **addrp, isc_stdtime_t now); -/*%< - * Return a dns_adbaddrinfo_t that is associated with address 'sa'. - * - * Requires: - * - *\li adb is valid. - * - *\li sa is valid. - * - *\li addrp != NULL && *addrp == NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_SHUTTINGDOWN - */ - -void -dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp); -/*%< - * Free a dns_adbaddrinfo_t allocated by dns_adb_findaddrinfo(). - * - * Requires: - * - *\li adb is valid. - * - *\li *addrp is a valid dns_adbaddrinfo_t *. - */ - -void -dns_adb_flush(dns_adb_t *adb); -/*%< - * Flushes all cached data from the adb. - * - * Requires: - *\li adb is valid. - */ - -void -dns_adb_setadbsize(dns_adb_t *adb, size_t size); -/*%< - * Set a target memory size. If memory usage exceeds the target - * size entries will be removed before they would have expired on - * a random basis. - * - * If 'size' is 0 then memory usage is unlimited. - * - * Requires: - *\li 'adb' is valid. - */ - -void -dns_adb_flushname(dns_adb_t *adb, dns_name_t *name); -/*%< - * Flush 'name' from the adb cache. - * - * Requires: - *\li 'adb' is valid. - *\li 'name' is valid. - */ - -void -dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name); -/*%< - * Flush 'name' and all subdomains from the adb cache. - * - * Requires: - *\li 'adb' is valid. - *\li 'name' is valid. - */ - -void -dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - const unsigned char *cookie, size_t len); -/*%< - * Record the COOKIE associated with this address. If - * cookie is NULL or len is zero the recorded COOKIE is cleared. - * - * Requires: - *\li 'adb' is valid. - *\li 'addr' is valid. - */ - -size_t -dns_adb_getcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr, - unsigned char *cookie, size_t len); -/* - * Retrieve the saved COOKIE value and store it in 'cookie' which has - * size 'len'. - * - * Requires: - *\li 'adb' is valid. - *\li 'addr' is valid. - * - * Returns: - * The size of the cookie or zero if it doesn't fit in the buffer - * or it doesn't exist. - */ - -void -dns_adb_setquota(dns_adb_t *adb, uint32_t quota, uint32_t freq, - double low, double high, double discount); -/*%< - * Set the baseline ADB quota, and configure parameters for the - * quota adjustment algorithm. - * - * If the number of fetches currently waiting for responses from this - * address exceeds the current quota, then additional fetches are spilled. - * - * 'quota' is the highest permissible quota; it will adjust itself - * downward in response to detected congestion. - * - * After every 'freq' fetches have either completed or timed out, an - * exponentially weighted moving average of the ratio of timeouts - * to responses is calculated. If the EWMA goes above a 'high' - * threshold, then the quota is adjusted down one step; if it drops - * below a 'low' threshold, then the quota is adjusted back up one - * step. - * - * The quota adjustment is based on the function (1 / 1 + (n/10)^(3/2)), - * for values of n from 0 to 99. It starts at 100% of the baseline - * quota, and descends after 100 steps to 2%. - * - * 'discount' represents the discount rate of the moving average. Higher - * values cause older values to be discounted sooner, providing a faster - * response to changes in the timeout ratio. - * - * Requires: - *\li 'adb' is valid. - */ - -bool -dns_adbentry_overquota(dns_adb_t *adb, dns_adbentry_t *entry); -/*%< - * Returns true if the specified ADB has too many active fetches. - * - * Requires: - *\li 'entry' is valid. - */ - -void -dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -void -dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); -/*% - * Begin/end a UDP fetch on a particular address. - * - * These functions increment or decrement the fetch counter for - * the ADB entry so that the fetch quota can be enforced. - * - * Requires: - * - *\li adb be valid. - * - *\li addr be valid. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ADB_H */ diff --git a/lib/dns-pkcs11/include/dns/badcache.h b/lib/dns-pkcs11/include/dns/badcache.h deleted file mode 100644 index 2237a0e..0000000 --- a/lib/dns-pkcs11/include/dns/badcache.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_BADCACHE_H -#define DNS_BADCACHE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/badcache.h - * \brief - * Defines dns_badcache_t, the "bad cache" object. - * - * Notes: - *\li A bad cache object is a hash table of name/type tuples, - * indicating whether a given tuple known to be "bad" in some - * sense (e.g., queries for that name and type have been - * returning SERVFAIL). This is used for both the "bad server - * cache" in the resolver and for the "servfail cache" in - * the view. - * - * Reliability: - * - * Resources: - * - * Security: - * - * Standards: - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_badcache_init(isc_mem_t *mctx, unsigned int size, dns_badcache_t **bcp); -/*% - * Allocate and initialize a badcache and store it in '*bcp'. - * - * Requires: - * \li mctx != NULL - * \li bcp != NULL - * \li *bcp == NULL - */ - -void -dns_badcache_destroy(dns_badcache_t **bcp); -/*% - * Flush and then free badcache in 'bcp'. '*bcp' is set to NULL on return. - * - * Requires: - * \li '*bcp' to be a valid badcache - */ - -void -dns_badcache_add(dns_badcache_t *bc, dns_name_t *name, - dns_rdatatype_t type, bool update, - uint32_t flags, isc_time_t *expire); -/*% - * Adds a badcache entry to the badcache 'bc' for name 'name' and - * type 'type'. If an entry already exists, then it will be updated if - * 'update' is true. The entry will be stored with flags 'flags' - * and expiration date 'expire'. - * - * Requires: - * \li bc to be a valid badcache. - * \li name != NULL - * \li expire != NULL - */ - -bool -dns_badcache_find(dns_badcache_t *bc, dns_name_t *name, - dns_rdatatype_t type, uint32_t *flagp, - isc_time_t *now); -/*% - * Returns true if a record is found in the badcache 'bc' matching - * 'name' and 'type', with an expiration date later than 'now'. - * If 'flagp' is not NULL, then '*flagp' is updated to the flags - * that were stored in the badcache entry. Returns false if - * no matching record is found. - * - * Requires: - * \li bc to be a valid badcache. - * \li name != NULL - * \li now != NULL - */ - -void -dns_badcache_flush(dns_badcache_t *bc); -/*% - * Flush the entire bad cache. - * - * Requires: - * \li bc to be a valid badcache - */ - -void -dns_badcache_flushname(dns_badcache_t *bc, dns_name_t *name); -/*% - * Flush the bad cache of all entries at 'name'. - * - * Requires: - * \li bc to be a valid badcache - * \li name != NULL - */ - -void -dns_badcache_flushtree(dns_badcache_t *bc, dns_name_t *name); -/*% - * Flush the bad cache of all entries at or below 'name'. - * - * Requires: - * \li bc to be a valid badcache - * \li name != NULL - */ - -void -dns_badcache_print(dns_badcache_t *bc, const char *cachename, FILE *fp); -/*% - * Print the contents of badcache 'bc' (headed by the title 'cachename') - * to file pointer 'fp'. - * - * Requires: - * \li bc to be a valid badcache - * \li cachename != NULL - * \li fp != NULL - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_BADCACHE_H */ diff --git a/lib/dns-pkcs11/include/dns/bit.h b/lib/dns-pkcs11/include/dns/bit.h deleted file mode 100644 index f65c774..0000000 --- a/lib/dns-pkcs11/include/dns/bit.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_BIT_H -#define DNS_BIT_H 1 - -/*! \file dns/bit.h */ - -#include - -typedef uint64_t dns_bitset_t; - -#define DNS_BIT_SET(bit, bitset) \ - (*(bitset) |= ((dns_bitset_t)1 << (bit))) -#define DNS_BIT_CLEAR(bit, bitset) \ - (*(bitset) &= ~((dns_bitset_t)1 << (bit))) -#define DNS_BIT_CHECK(bit, bitset) \ - ((*(bitset) & ((dns_bitset_t)1 << (bit))) \ - == ((dns_bitset_t)1 << (bit))) - -#endif /* DNS_BIT_H */ diff --git a/lib/dns-pkcs11/include/dns/byaddr.h b/lib/dns-pkcs11/include/dns/byaddr.h deleted file mode 100644 index 719d246..0000000 --- a/lib/dns-pkcs11/include/dns/byaddr.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_BYADDR_H -#define DNS_BYADDR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/byaddr.h - * \brief - * The byaddr module provides reverse lookup services for IPv4 and IPv6 - * addresses. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li RFCs: 1034, 1035, 2181, TBS - *\li Drafts: TBS - */ - -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*% - * A 'dns_byaddrevent_t' is returned when a byaddr completes. - * The sender field will be set to the byaddr that completed. If 'result' - * is ISC_R_SUCCESS, then 'names' will contain a list of names associated - * with the address. The recipient of the event must not change the list - * and must not refer to any of the name data after the event is freed. - */ -typedef struct dns_byaddrevent { - ISC_EVENT_COMMON(struct dns_byaddrevent); - isc_result_t result; - dns_namelist_t names; -} dns_byaddrevent_t; - -/* - * This option is deprecated since we now only consider nibbles. -#define DNS_BYADDROPT_IPV6NIBBLE 0x0001 - */ -/*% Note DNS_BYADDROPT_IPV6NIBBLE is now deprecated. */ -#define DNS_BYADDROPT_IPV6INT 0x0002 - -isc_result_t -dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp); -/*%< - * Find the domain name of 'address'. - * - * Notes: - * - *\li There is a reverse lookup format for IPv6 addresses, 'nibble' - * - *\li The 'nibble' format for that address is - * - * \code - * 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa. - * \endcode - * - *\li #DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int. - * - * Requires: - * - *\li 'mctx' is a valid mctx. - * - *\li 'address' is a valid IPv4 or IPv6 address. - * - *\li 'view' is a valid view which has a resolver. - * - *\li 'task' is a valid task. - * - *\li byaddrp != NULL && *byaddrp == NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - * - *\li Any resolver-related error (e.g. #ISC_R_SHUTTINGDOWN) may also be - * returned. - */ - -void -dns_byaddr_cancel(dns_byaddr_t *byaddr); -/*%< - * Cancel 'byaddr'. - * - * Notes: - * - *\li If 'byaddr' has not completed, post its #DNS_EVENT_BYADDRDONE - * event with a result code of #ISC_R_CANCELED. - * - * Requires: - * - *\li 'byaddr' is a valid byaddr. - */ - -void -dns_byaddr_destroy(dns_byaddr_t **byaddrp); -/*%< - * Destroy 'byaddr'. - * - * Requires: - * - *\li '*byaddrp' is a valid byaddr. - * - *\li The caller has received the #DNS_EVENT_BYADDRDONE event (either because - * the byaddr completed or because dns_byaddr_cancel() was called). - * - * Ensures: - * - *\li *byaddrp == NULL. - */ - -isc_result_t -dns_byaddr_createptrname(isc_netaddr_t *address, bool nibble, - dns_name_t *name); - -isc_result_t -dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, - dns_name_t *name); -/*%< - * Creates a name that would be used in a PTR query for this address. The - * nibble flag indicates that the 'nibble' format is to be used if an IPv6 - * address is provided, instead of the 'bitstring' format. Since we dropped - * the support of the bitstring labels, it is expected that the flag is always - * set. 'options' are the same as for dns_byaddr_create(). - * - * Requires: - * - * \li 'address' is a valid address. - * \li 'name' is a valid name with a dedicated buffer. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_BYADDR_H */ diff --git a/lib/dns-pkcs11/include/dns/cache.h b/lib/dns-pkcs11/include/dns/cache.h deleted file mode 100644 index e158014..0000000 --- a/lib/dns-pkcs11/include/dns/cache.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CACHE_H -#define DNS_CACHE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/cache.h - * \brief - * Defines dns_cache_t, the cache object. - * - * Notes: - *\li A cache object contains DNS data of a single class. - * Multiple classes will be handled by creating multiple - * views, each with a different class and its own cache. - * - * MP: - *\li See notes at the individual functions. - * - * Reliability: - * - * Resources: - * - * Security: - * - * Standards: - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_cache_create(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *db_type, unsigned int db_argc, char **db_argv, - dns_cache_t **cachep); -isc_result_t -dns_cache_create2(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *cachename, const char *db_type, - unsigned int db_argc, char **db_argv, dns_cache_t **cachep); -isc_result_t -dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, - const char *cachename, const char *db_type, - unsigned int db_argc, char **db_argv, dns_cache_t **cachep); -/*%< - * Create a new DNS cache. - * - * dns_cache_create2() will create a named cache. - * - * dns_cache_create3() will create a named cache using two separate memory - * contexts, one for cache data which can be cleaned and a separate one for - * memory allocated for the heap (which can grow without an upper limit and - * has no mechanism for shrinking). - * - * dns_cache_create() is a backward compatible version that internally - * specifies an empty cache name and a single memory context. - * - * Requires: - * - *\li 'cmctx' (and 'hmctx' if applicable) is a valid memory context. - * - *\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer - * manager, or both are NULL. If NULL, no periodic cleaning of the - * cache will take place. - * - *\li 'cachename' is a valid string. This must not be NULL. - * - *\li 'cachep' is a valid pointer, and *cachep == NULL - * - * Ensures: - * - *\li '*cachep' is attached to the newly created cache - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -void -dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp); -/*%< - * Attach *targetp to cache. - * - * Requires: - * - *\li 'cache' is a valid cache. - * - *\li 'targetp' points to a NULL dns_cache_t *. - * - * Ensures: - * - *\li *targetp is attached to cache. - */ - -void -dns_cache_detach(dns_cache_t **cachep); -/*%< - * Detach *cachep from its cache. - * - * Requires: - * - *\li 'cachep' points to a valid cache. - * - * Ensures: - * - *\li *cachep is NULL. - * - *\li If '*cachep' is the last reference to the cache, - * all resources used by the cache will be freed - */ - -void -dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp); -/*%< - * Attach *dbp to the cache's database. - * - * Notes: - * - *\li This may be used to get a reference to the database for - * the purpose of cache lookups (XXX currently it is also - * the way to add data to the cache, but having a - * separate dns_cache_add() interface instead would allow - * more control over memory usage). - * The caller should call dns_db_detach() on the reference - * when it is no longer needed. - * - * Requires: - * - *\li 'cache' is a valid cache. - * - *\li 'dbp' points to a NULL dns_db *. - * - * Ensures: - * - *\li *dbp is attached to the database. - */ - - -isc_result_t -dns_cache_setfilename(dns_cache_t *cache, const char *filename); -/*%< - * If 'filename' is non-NULL, make the cache persistent. - * The cache's data will be stored in the given file. - * If 'filename' is NULL, make the cache non-persistent. - * Files that are no longer used are not unlinked automatically. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li Various file-related failures - */ - -isc_result_t -dns_cache_load(dns_cache_t *cache); -/*%< - * If the cache has a file name, load the cache contents from the file. - * Previous cache contents are not discarded. - * If no file name has been set, do nothing and return success. - * - * MT: - *\li Multiple simultaneous attempts to load or dump the cache - * will be serialized with respect to one another, but - * the cache may be read and updated while the dump is - * in progress. Updates performed during loading - * may or may not be preserved, and reads may return - * either the old or the newly loaded data. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * \li Various failures depending on the database implementation type - */ - -isc_result_t -dns_cache_dump(dns_cache_t *cache); -/*%< - * If the cache has a file name, write the cache contents to disk, - * overwriting any preexisting file. If no file name has been set, - * do nothing and return success. - * - * MT: - *\li Multiple simultaneous attempts to load or dump the cache - * will be serialized with respect to one another, but - * the cache may be read and updated while the dump is - * in progress. Updates performed during the dump may - * or may not be reflected in the dumped file. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * \li Various failures depending on the database implementation type - */ - -isc_result_t -dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now); -/*%< - * Force immediate cleaning of the cache, freeing all rdatasets - * whose TTL has expired as of 'now' and that have no pending - * references. - */ - -void -dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int interval); -/*%< - * Set the periodic cache cleaning interval to 'interval' seconds. - */ - -unsigned int -dns_cache_getcleaninginterval(dns_cache_t *cache); -/*%< - * Get the periodic cache cleaning interval to 'interval' seconds. - */ - -const char * -dns_cache_getname(dns_cache_t *cache); -/*%< - * Get the cache name. - */ - -void -dns_cache_setcachesize(dns_cache_t *cache, size_t size); -/*%< - * Set the maximum cache size. 0 means unlimited. - */ - -size_t -dns_cache_getcachesize(dns_cache_t *cache); -/*%< - * Get the maximum cache size. - */ - -void -dns_cache_setservestalettl(dns_cache_t *cache, dns_ttl_t ttl); -/*%< - * Sets the maximum length of time that cached answers may be retained - * past their normal TTL. Default value for the library is 0, disabling - * the use of stale data. - * - * Requires: - *\li 'cache' to be valid. - */ - -dns_ttl_t -dns_cache_getservestalettl(dns_cache_t *cache); -/*%< - * Gets the maximum length of time that cached answers may be kept past - * normal expiry. - * - * Requires: - *\li 'cache' to be valid. - */ - -isc_result_t -dns_cache_flush(dns_cache_t *cache); -/*%< - * Flushes all data from the cache. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, - bool tree); -/* - * Flush a given name from the cache. If 'tree' is true, then - * also flush all names under 'name'. - * - * Requires: - *\li 'cache' to be valid. - *\li 'name' to be valid. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li other error returns. - */ - -isc_result_t -dns_cache_flushname(dns_cache_t *cache, dns_name_t *name); -/* - * Flush a given name from the cache. Equivalent to - * dns_cache_flushpartial(cache, name, false). - * - * Requires: - *\li 'cache' to be valid. - *\li 'name' to be valid. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li other error returns. - */ - -isc_stats_t * -dns_cache_getstats(dns_cache_t *cache); -/* - * Return a pointer to the stats collection object for 'cache' - */ - -void -dns_cache_dumpstats(dns_cache_t *cache, FILE *fp); -/* - * Dump cache statistics and status in text to 'fp' - */ - -void -dns_cache_updatestats(dns_cache_t *cache, isc_result_t result); -/* - * Update cache statistics based on result code in 'result' - */ - -#ifdef HAVE_LIBXML2 -int -dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer); -/* - * Render cache statistics and status in XML for 'writer'. - */ -#endif /* HAVE_LIBXML2 */ - -#ifdef HAVE_JSON -isc_result_t -dns_cache_renderjson(dns_cache_t *cache, json_object *cstats); -/* - * Render cache statistics and status in JSON - */ -#endif /* HAVE_JSON */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_CACHE_H */ diff --git a/lib/dns-pkcs11/include/dns/callbacks.h b/lib/dns-pkcs11/include/dns/callbacks.h deleted file mode 100644 index 4c7d73d..0000000 --- a/lib/dns-pkcs11/include/dns/callbacks.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CALLBACKS_H -#define DNS_CALLBACKS_H 1 - -/*! \file dns/callbacks.h */ - -/*** - *** Imports - ***/ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -#define DNS_CALLBACK_MAGIC ISC_MAGIC('C','L','L','B') -#define DNS_CALLBACK_VALID(cb) ISC_MAGIC_VALID(cb, DNS_CALLBACK_MAGIC) - -struct dns_rdatacallbacks { - unsigned int magic; - - /*% - * dns_load_master calls this when it has rdatasets to commit. - */ - dns_addrdatasetfunc_t add; - - /*% - * This is called when reading in a database image from a 'map' - * format zone file. - */ - dns_deserializefunc_t deserialize; - - /*% - * dns_master_load*() call this when loading a raw zonefile, - * to pass back information obtained from the file header - */ - dns_rawdatafunc_t rawdata; - dns_zone_t *zone; - - /*% - * dns_load_master / dns_rdata_fromtext call this to issue a error. - */ - void (*error)(struct dns_rdatacallbacks *, const char *, ...); - /*% - * dns_load_master / dns_rdata_fromtext call this to issue a warning. - */ - void (*warn)(struct dns_rdatacallbacks *, const char *, ...); - /*% - * Private data handles for use by the above callback functions. - */ - void *add_private; - void *deserialize_private; - void *error_private; - void *warn_private; -}; - -/*** - *** Initialization - ***/ - -void -dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks); -/*%< - * Initialize 'callbacks'. - * - * \li 'magic' is set to DNS_CALLBACK_MAGIC - * - * \li 'error' and 'warn' are set to default callbacks that print the - * error message through the DNS library log context. - * - *\li All other elements are initialized to NULL. - * - * Requires: - * \li 'callbacks' is a valid dns_rdatacallbacks_t, - */ - -void -dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks); -/*%< - * Like dns_rdatacallbacks_init, but logs to stdio. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_CALLBACKS_H */ diff --git a/lib/dns-pkcs11/include/dns/catz.h b/lib/dns-pkcs11/include/dns/catz.h deleted file mode 100644 index 297f3ce..0000000 --- a/lib/dns-pkcs11/include/dns/catz.h +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CATZ_H -#define DNS_CATZ_H 1 - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -#define DNS_CATZ_ERROR_LEVEL ISC_LOG_WARNING -#define DNS_CATZ_INFO_LEVEL ISC_LOG_INFO -#define DNS_CATZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1) -#define DNS_CATZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2) -#define DNS_CATZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3) -#define DNS_CATZ_DEBUG_QUIET (DNS_CATZ_DEBUG_LEVEL3+1) - -/* - * Catalog Zones functions and structures. - */ - -/* - * Options for a member zone in a catalog - */ -struct dns_catz_entry_options { - /* - * Options that can be overridden in catalog zone - */ - /* default-masters definition */ - dns_ipkeylist_t masters; - - /* both as text in config format, NULL if none */ - isc_buffer_t *allow_query; - isc_buffer_t *allow_transfer; - - /* - * Options that are only set in named.conf - */ - /* zone-directory definition */ - char *zonedir; - - /* zone should not be stored on disk (no 'file' statement in def */ - bool in_memory; - /* - * Minimal interval between catalog zone updates, if a new version - * of catalog zone is received before this time the update will be - * postponed. This is a global option for the whole catalog zone. - */ - uint32_t min_update_interval; -}; - -void -dns_catz_options_init(dns_catz_options_t *options); -/*%< - * Initialize 'options' to NULL values. - * - * Requires: - * \li 'options' to be non NULL. - */ - -void -dns_catz_options_free(dns_catz_options_t *options, isc_mem_t *mctx); -/*%< - * Free 'options' contents into 'mctx'. ('options' itself is not freed.) - * - * Requires: - * \li 'options' to be non NULL. - * \li 'mctx' to be a valid memory context. - */ - -isc_result_t -dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *opts, - dns_catz_options_t *nopts); -/*%< - * Duplicate 'opts' into 'nopts', allocating space from 'mctx'. - * - * Requires: - * \li 'mctx' to be a valid memory context. - * \li 'options' to be non NULL and valid options. - * \li 'nopts' to be non NULL. - */ - -isc_result_t -dns_catz_options_setdefault(isc_mem_t *mctx, const dns_catz_options_t *defaults, - dns_catz_options_t *opts); -/*%< - * Replace empty values in 'opts' with values from 'defaults' - * - * Requires: - * \li 'mctx' to be a valid memory context. - * \li 'defaults' to be non NULL and valid options. - * \li 'opts' to be non NULL. - */ - -dns_name_t * -dns_catz_entry_getname(dns_catz_entry_t *entry); -/*%< - * Get domain name for 'entry' - * - * Requires: - * \li 'entry' to be non NULL. - * - * Returns: - * \li domain name for entry. - */ - -isc_result_t -dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain, - dns_catz_entry_t **nentryp); -/*%< - * Allocate a new catz_entry on 'mctx', with the name 'domain' - * - * Requires: - * \li 'mctx' to be a valid memory context. - * \li 'domain' to be valid dns_name or NULL. - * \li 'nentryp' to be non NULL, *nentryp to be NULL. - * - * Returns: - * \li ISC_R_SUCCESS on success - * \li ISC_R_NOMEMORY on allocation failure - */ - -isc_result_t -dns_catz_entry_copy(dns_catz_zone_t *zone, const dns_catz_entry_t *entry, - dns_catz_entry_t **nentryp); -/*%< - * Allocate a new catz_entry and deep copy 'entry' into 'nentryp'. - * - * Requires: - * \li 'mctx' to be a valid memory context. - * \li 'entry' to be non NULL. - * \li 'nentryp' to be non NULL, *nentryp to be NULL. - * - * Returns: - * \li ISC_R_SUCCESS on success - * \li ISC_R_NOMEMORY on allocation failure - */ - -void -dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp); -/*%< - * Attach an entry - * - * Requires: - * \li 'entry' is a valid dns_catz_entry_t. - * \li 'entryp' is not NULL and '*entryp' is NULL. - */ - -void -dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp); -/*%< - * Detach an entry, free if no further references - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - * \li 'entryp' is not NULL and '*entryp' is not NULL. - */ - -bool -dns_catz_entry_validate(const dns_catz_entry_t *entry); -/*%< - * Validate whether entry is correct. - * (NOT YET IMPLEMENTED: always returns true) - * - * Requires: - *\li 'entry' is a valid dns_catz_entry_t. - */ - -bool -dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb); -/*%< - * Deep compare two entries - * - * Requires: - * \li 'ea' is a valid dns_catz_entry_t. - * \li 'eb' is a valid dns_catz_entry_t. - * - * Returns: - * \li 'true' if entries are the same. - * \li 'false' if the entries differ. - */ - -void -dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep); -/*%< - * Attach a catzone - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - * \li 'zonep' is not NULL and '*zonep' is NULL. - */ - -void -dns_catz_zone_detach(dns_catz_zone_t** zonep); -/*%< - * Detach a zone, free if no further references - * - * Requires: - * \li 'zonep' is not NULL and '*zonep' is not NULL. - */ - -isc_result_t -dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep, - const dns_name_t *name); -/*%< - * Allocate a new catz zone on catzs mctx - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'zonep' is not NULL and '*zonep' is NULL. - * \li 'name' is a valid dns_name_t. - * - */ - -dns_name_t * -dns_catz_zone_getname(dns_catz_zone_t *zone); -/*%< - * Get catalog zone name - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - */ - -dns_catz_options_t * -dns_catz_zone_getdefoptions(dns_catz_zone_t *zone); -/*%< - * Get default member zone options for catalog zone 'zone' - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - */ - -void -dns_catz_zone_resetdefoptions(dns_catz_zone_t *zone); -/*%< - * Reset the default member zone options for catalog zone 'zone' to - * the default values. - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - */ - -isc_result_t -dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone); -/*%< - * Merge 'newzone' into 'target', calling addzone/delzone/modzone - * (from zone->catzs->zmm) for appropriate member zones. - * - * Requires: - * \li 'orig' is a valid dns_catz_zone_t. - * \li 'newzone' is not NULL and '*newzone' is not NULL. - * - */ - -isc_result_t -dns_catz_update_process(dns_catz_zones_t *catzs, dns_catz_zone_t *zone, - dns_name_t *src_name, dns_rdataset_t *rdataset); -/*%< - * Process a single rdataset from a catalog zone 'zone' update, src_name is the - * record name. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'zone' is a valid dns_catz_zone_t. - * \li 'src_name' is a valid dns_name_t. - * \li 'rdataset' is valid rdataset. - */ - -isc_result_t -dns_catz_generate_masterfilename(dns_catz_zone_t *zone, dns_catz_entry_t *entry, - isc_buffer_t **buffer); -/*%< - * Generate master file name and put it into *buffer (might be reallocated). - * The general format of the file name is: - * __catz__catalog.zone.name__member_zone_name.db - * But if it's too long it's shortened to: - * __catz__unique_hash_generated_from_the_above.db - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - * \li 'entry' is a valid dns_catz_entry_t. - * \li 'buffer' is not NULL and '*buffer' is not NULL. - */ - -isc_result_t -dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry, - isc_buffer_t **buf); -/*%< - * Generate a zone config entry (in text form) from dns_catz_entry and puts - * it into *buf. buf might be reallocated. - * - * Requires: - * \li 'zone' is a valid dns_catz_zone_t. - * \li 'entry' is a valid dns_catz_entry_t. - * \li 'buf' is not NULL and '*buf' is NULL. - * - */ - - -/* Methods provided by named to dynamically modify the member zones */ -/* xxxwpk TODO config! */ -typedef isc_result_t (*dns_catz_zoneop_fn_t)(dns_catz_entry_t *entry, - dns_catz_zone_t *origin, - dns_view_t *view, - isc_taskmgr_t *taskmgr, - void *udata); -struct dns_catz_zonemodmethods { - dns_catz_zoneop_fn_t addzone; - dns_catz_zoneop_fn_t modzone; - dns_catz_zoneop_fn_t delzone; - void *udata; -}; - - -isc_result_t -dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm, - isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr); -/*%< - * Allocate a new catz_zones object, a collection storing all catalog zones - * for a view. - * - * Requires: - * \li 'catzsp' is not NULL and '*catzsp' is NULL. - * \li 'zmm' is not NULL. - * - */ - -isc_result_t -dns_catz_add_zone(dns_catz_zones_t *catzs, const dns_name_t *name, - dns_catz_zone_t **catzp); -/*%< - * Allocate a new catz named 'name' and put it in 'catzs' collection. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'name' is a valid dns_name_t. - * \li 'zonep' is not NULL and *zonep is NULL. - * - */ - -dns_catz_zone_t * -dns_catz_get_zone(dns_catz_zones_t *catzs, const dns_name_t *name); -/*%< - * Returns a zone named 'name' from collection 'catzs' - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'name' is a valid dns_name_t. - */ - -void -dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp); -/*%< - * Attach 'catzs' to 'catzsp'. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'catzsp' is not NULL and *catzsp is NULL. - */ - -void -dns_catz_catzs_detach(dns_catz_zones_t **catzsp); -/*%< - * Detach 'catzsp', free if no further references. - * - * Requires: - * \li 'catzsp' is not NULL and *catzsp is not NULL. - */ - -void -dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view); -/*%< - * Set a view for 'catzs'. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'catzs->view' is NULL or 'catzs->view' == 'view'. - */ - - -isc_result_t -dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg); -/*%< - * Callback for update of catalog zone database. - * If there was no catalog zone update recently it launches an - * update_taskaction immediately. - * If there was an update recently it schedules update_taskaction for some time - * in the future. - * If there is an update scheduled it replaces old db version with a new one. - * - * Requires: - * \li 'db' is a valid database. - * \li 'fn_arg' is not NULL (casted to dns_catz_zones_t*). - */ - -void -dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event); -/*%< - * Task that launches dns_catz_update_from_db. - * - * Requires: - * \li 'event' is not NULL. - */ - -void -dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs); -/*%< - * Process an updated database for a catalog zone. - * It creates a new catz, iterates over database to fill it with content, and - * then merges new catz into old catz. - * - * Requires: - * \li 'db' is a valid DB. - * \li 'catzs' is a valid dns_catz_zones_t. - * - */ - -void -dns_catz_prereconfig(dns_catz_zones_t *catzs); -/*%< - * Called before reconfig, clears 'active' flag on all the zones in set - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * - */ - -void -dns_catz_postreconfig(dns_catz_zones_t *catzs); -/*%< - * Called after reconfig, walks through all zones in set, removes those - * inactive and force reload of those with changed configuration. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - */ - -isc_result_t -dns_catz_get_iterator(dns_catz_zone_t *catz, isc_ht_iter_t **itp); -/*%< - * Get the hashtable iterator on catalog zone members, point '*itp' to it. - * - * Requires: - * \li 'catzs' is a valid dns_catz_zones_t. - * \li 'itp' is not NULL and '*itp' is NULL. - * - * Returns: - * \li #ISC_R_SUCCESS -- success - * \li Any other value -- failure - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_CATZ_H_ */ diff --git a/lib/dns-pkcs11/include/dns/cert.h b/lib/dns-pkcs11/include/dns/cert.h deleted file mode 100644 index ce33540..0000000 --- a/lib/dns-pkcs11/include/dns/cert.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CERT_H -#define DNS_CERT_H 1 - -/*! \file dns/cert.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a certificate type. - * The text may contain either a mnemonic type name or a decimal type number. - * - * Requires: - *\li 'certp' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_RANGE numeric type is out of range - *\li #DNS_R_UNKNOWN mnemonic type is unknown - */ - -isc_result_t -dns_cert_totext(dns_cert_t cert, isc_buffer_t *target); -/*%< - * Put a textual representation of certificate type 'cert' into 'target'. - * - * Requires: - *\li 'cert' is a valid cert. - * - *\li 'target' is a valid text buffer. - * - * Ensures: - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_CERT_H */ diff --git a/lib/dns-pkcs11/include/dns/client.h b/lib/dns-pkcs11/include/dns/client.h deleted file mode 100644 index f71d16f..0000000 --- a/lib/dns-pkcs11/include/dns/client.h +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CLIENT_H -#define DNS_CLIENT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * - * \brief - * The DNS client module provides convenient programming interfaces to various - * DNS services, such as name resolution with or without DNSSEC validation or - * dynamic DNS update. This module is primarily expected to be used by other - * applications than BIND9-related ones that need such advanced DNS features. - * - * MP: - *\li In the typical usage of this module, application threads will not share - * the same data structures created and manipulated in this module. - * However, the module still ensures appropriate synchronization of such - * data structures. - * - * Resources: - *\li TBS - * - * Security: - *\li This module does not handle any low-level data directly, and so no - * security issue specific to this module is anticipated. - */ - -#include -#include - -#include -#include - -#include - -typedef enum { - updateop_none = 0, - updateop_add = 1, - updateop_delete = 2, - updateop_exist = 3, - updateop_notexist = 4, - updateop_max = 5 -} dns_client_updateop_t; - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -/*% - * Optional flags for dns_client_create(x). - */ -/*%< Enable caching resolution results (experimental). */ -#define DNS_CLIENTCREATEOPT_USECACHE 0x8000 - -/*% - * Optional flags for dns_client_(start)resolve. - */ -/*%< Do not return DNSSEC data (e.g. RRSIGS) with response. */ -#define DNS_CLIENTRESOPT_NODNSSEC 0x01 -/*%< Allow running external context. */ -#define DNS_CLIENTRESOPT_ALLOWRUN 0x02 -/*%< Don't validate responses. */ -#define DNS_CLIENTRESOPT_NOVALIDATE 0x04 -/*%< Don't set the CD flag on upstream queries. */ -#define DNS_CLIENTRESOPT_NOCDFLAG 0x08 -/*%< Use TCP transport. */ -#define DNS_CLIENTRESOPT_TCP 0x10 - -/*% - * Optional flags for dns_client_(start)request. - */ -/*%< Allow running external context. */ -#define DNS_CLIENTREQOPT_ALLOWRUN 0x01 -/*%< Use TCP transport. */ -#define DNS_CLIENTREQOPT_TCP 0x02 - -/*% - * Optional flags for dns_client_(start)update. - */ -/*%< Allow running external context. */ -#define DNS_CLIENTUPDOPT_ALLOWRUN 0x01 -/*%< Use TCP transport. */ -#define DNS_CLIENTUPDOPT_TCP 0x02 - -/*% - * A dns_clientresevent_t is sent when name resolution performed by a client - * completes. 'result' stores the result code of the entire resolution - * procedure. 'vresult' specifically stores the result code of DNSSEC - * validation if it is performed. When name resolution successfully completes, - * 'answerlist' is typically non empty, containing answer names along with - * RRsets. It is the receiver's responsibility to free this list by calling - * dns_client_freeresanswer() before freeing the event structure. - */ -typedef struct dns_clientresevent { - ISC_EVENT_COMMON(struct dns_clientresevent); - isc_result_t result; - isc_result_t vresult; - dns_namelist_t answerlist; -} dns_clientresevent_t; /* too long? */ - -/*% - * Status of a dynamic update procedure. - */ -typedef enum { - dns_clientupdatestate_prepare, /*%< no updates have been sent */ - dns_clientupdatestate_sent, /*%< updates were sent, no response */ - dns_clientupdatestate_done /*%< update was sent and succeeded */ -} dns_clientupdatestate_t; - -/*% - * A dns_clientreqevent_t is sent when a DNS request is completed by a client. - * 'result' stores the result code of the entire transaction. - * If the transaction is successfully completed but the response packet cannot - * be parsed, 'result' will store the result code of dns_message_parse(). - * If the response packet is received, 'rmessage' will contain the response - * message, whether it is successfully parsed or not. - */ -typedef struct dns_clientreqevent { - ISC_EVENT_COMMON(struct dns_clientreqevent); - isc_result_t result; - dns_message_t *rmessage; -} dns_clientreqevent_t; /* too long? */ - -/*% - * A dns_clientupdateevent_t is sent when dynamic update performed by a client - * completes. 'result' stores the result code of the entire update procedure. - * 'state' specifies the status of the update procedure when this event is - * sent. This can be used as a hint by the receiver to determine whether - * the update attempt was ever made. In particular, if the state is - * dns_clientupdatestate_prepare, the receiver can be sure that the requested - * update was not applied. - */ -typedef struct dns_clientupdateevent { - ISC_EVENT_COMMON(struct dns_clientupdateevent); - isc_result_t result; - dns_clientupdatestate_t state; -} dns_clientupdateevent_t; /* too long? */ - -isc_result_t -dns_client_create(dns_client_t **clientp, unsigned int options); - -isc_result_t -dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, - unsigned int options, dns_client_t **clientp); - -isc_result_t -dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, - isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, unsigned int options, - dns_client_t **clientp, - isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6); -/*%< - * Create a DNS client. These functions create a new client object with - * minimal internal resources such as the default 'view' for the IN class and - * IPv4/IPv6 dispatches for the view. - * - * dns_client_createx() takes 'manager' arguments so that the caller can - * control the behavior of the client through the underlying event framework. - * On the other hand, dns_client_create() simplifies the interface and creates - * the managers internally. A DNS client object created via - * dns_client_create() is expected to be used by an application that only needs - * simple synchronous services or by a thread-based application. - * - * dns_client_createx2 takes two additional parameters, 'localaddr4' and - * 'localaddr6', to specify the local address to use for each family. If - * both are set to NULL, then wildcard addresses will be used for both - * families. If only one is NULL, then the other address will be used - * as the local address, and the other protocol family will not be used. - * - * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options', - * dns_client_create(x) will create a cache database with the view. - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li 'actx' is a valid application context. - * - *\li 'taskmgr' is a valid task manager. - * - *\li 'socketmgr' is a valid socket manager. - * - *\li 'timermgr' is a valid timer manager. - * - *\li clientp != NULL && *clientp == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -void -dns_client_destroy(dns_client_t **clientp); -/*%< - * Destroy 'client'. - * - * Requires: - * - *\li '*clientp' is a valid client. - * - * Ensures: - * - *\li *clientp == NULL. - */ - -isc_result_t -dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *name_space, isc_sockaddrlist_t *addrs); -/*%< - * Specify a list of addresses of recursive name servers that the client will - * use for name resolution. A view for the 'rdclass' class must be created - * beforehand. If 'name_space' is non NULL, the specified server will be used - * if and only if the query name is a subdomain of 'name_space'. When servers - * for multiple 'name_space's are provided, and a query name is covered by - * more than one 'name_space', the servers for the best (longest) matching - * name_space will be used. If 'name_space' is NULL, it works as if - * dns_rootname (.) were specified. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'name_space' is NULL or a valid name. - * - *\li 'addrs' != NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -isc_result_t -dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *name_space); -/*%< - * Remove configured recursive name servers for the 'rdclass' and 'name_space' - * from the client. See the description of dns_client_setservers() for - * the requirements about 'rdclass' and 'name_space'. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'name_space' is NULL or a valid name. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -isc_result_t -dns_client_setdlv(dns_client_t *client, dns_rdataclass_t rdclass, - const char *dlvname); -/*%< - * Specify a name to use for DNSSEC lookaside validation. - * If a trusted key has been added for that name, then DLV will be - * used during validation. If 'dlvname' is NULL, then DLV will no - * longer be used for this client. - * - * Requires: - * - *\li 'client' is a valid client. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -isc_result_t -dns_client_resolve(dns_client_t *client, dns_name_t *name, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int options, dns_namelist_t *namelist); - -isc_result_t -dns_client_startresolve(dns_client_t *client, dns_name_t *name, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_clientrestrans_t **transp); -/*%< - * Perform name resolution for 'name', 'rdclass', and 'type'. - * - * If any trusted keys are configured and the query name is considered to - * belong to a secure zone, these functions also validate the responses - * using DNSSEC by default. If the DNS_CLIENTRESOPT_NOVALIDATE flag is set - * in 'options', DNSSEC validation is disabled regardless of the configured - * trusted keys or the query name. With DNS_CLIENTRESOPT_NODNSSEC - * DNSSEC data is not returned with response. DNS_CLIENTRESOPT_NOCDFLAG - * disables the CD flag on queries, DNS_CLIENTRESOPT_TCP switches to - * the TCP (vs. UDP) transport. - * - * dns_client_resolve() provides a synchronous service. This function starts - * name resolution internally and blocks until it completes. On success, - * 'namelist' will contain a list of answer names, each of which has - * corresponding RRsets. The caller must provide a valid empty list, and - * is responsible for freeing the list content via dns_client_freeresanswer(). - * If the name resolution fails due to an error in DNSSEC validation, - * dns_client_resolve() returns the result code indicating the validation - * error. Otherwise, it returns the result code of the entire resolution - * process, either success or failure. - * - * It is typically expected that the client object passed to - * dns_client_resolve() was created via dns_client_create() and has its own - * managers and contexts. However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is - * set in 'options', this function performs the synchronous service even if - * it does not have its own manager and context structures. - * - * dns_client_startresolve() is an asynchronous version of dns_client_resolve() - * and does not block. When name resolution is completed, 'action' will be - * called with the argument of a 'dns_clientresevent_t' object, which contains - * the resulting list of answer names (on success). On return, '*transp' is - * set to an opaque transaction ID so that the caller can cancel this - * resolution process. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'addrs' != NULL. - * - *\li 'name' is a valid name. - * - *\li 'namelist' != NULL and is not empty. - * - *\li 'task' is a valid task. - * - *\li 'transp' != NULL && *transp == NULL; - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -void -dns_client_cancelresolve(dns_clientrestrans_t *trans); -/*%< - * Cancel an ongoing resolution procedure started via - * dns_client_startresolve(). - * - * Notes: - * - *\li If the resolution procedure has not completed, post its CLIENTRESDONE - * event with a result code of #ISC_R_CANCELED. - * - * Requires: - * - *\li 'trans' is a valid transaction ID. - */ - -void -dns_client_destroyrestrans(dns_clientrestrans_t **transp); -/*%< - * Destroy name resolution transaction state identified by '*transp'. - * - * Requires: - * - *\li '*transp' is a valid transaction ID. - * - *\li The caller has received the CLIENTRESDONE event (either because the - * resolution completed or because dns_client_cancelresolve() was called). - * - * Ensures: - * - *\li *transp == NULL. - */ - -void -dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist); -/*%< - * Free resources allocated for the content of 'namelist'. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'namelist' != NULL. - */ - -isc_result_t -dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *keyname, isc_buffer_t *keydatabuf); -/*%< - * Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass' - * class must be created beforehand. 'keyname' is the DNS name of the key, - * and 'keydatabuf' stores the resource data of the key. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'keyname' is a valid name. - * - *\li 'keydatabuf' is a valid buffer. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -isc_result_t -dns_client_request(dns_client_t *client, dns_message_t *qmessage, - dns_message_t *rmessage, isc_sockaddr_t *server, - unsigned int options, unsigned int parseoptions, - dns_tsec_t *tsec, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries); - -isc_result_t -dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, - dns_message_t *rmessage, isc_sockaddr_t *server, - unsigned int options, unsigned int parseoptions, - dns_tsec_t *tsec, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_clientreqtrans_t **transp); - -/*%< - * Send a DNS request containing a query message 'query' to 'server'. - * - * 'parseoptions' will be used when the response packet is parsed, and will be - * passed to dns_message_parse() via dns_request_getresponse(). See - * dns_message_parse() for more details. - * - * 'tsec' is a transaction security object containing, e.g. a TSIG key for - * authenticating the request/response transaction. This is optional and can - * be NULL, in which case this library performs the transaction without any - * transaction authentication. - * - * 'timeout', 'udptimeout', and 'udpretries' are passed to - * dns_request_createvia3(). See dns_request_createvia3() for more details. - * - * dns_client_request() provides a synchronous service. This function sends - * the request and blocks until a response is received. On success, - * 'rmessage' will contain the response message. The caller must provide a - * valid initialized message. - * - * It is usually expected that the client object passed to - * dns_client_request() was created via dns_client_create() and has its own - * managers and contexts. However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is - * set in 'options', this function performs the synchronous service even if - * it does not have its own manager and context structures. - * - * dns_client_startrequest() is an asynchronous version of dns_client_request() - * and does not block. When the transaction is completed, 'action' will be - * called with the argument of a 'dns_clientreqevent_t' object, which contains - * the response message (on success). On return, '*transp' is set to an opaque - * transaction ID so that the caller can cancel this request. - * - * DNS_CLIENTREQOPT_TCP switches to the TCP (vs. UDP) transport. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'qmessage' and 'rmessage' are valid initialized message. - * - *\li 'server' is a valid socket address structure. - * - *\li 'task' is a valid task. - * - *\li 'transp' != NULL && *transp == NULL; - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - * - *\li Any result that dns_message_parse() can return. - */ - -void -dns_client_cancelrequest(dns_clientreqtrans_t *transp); -/*%< - * Cancel an ongoing DNS request procedure started via - * dns_client_startrequest(). - * - * Notes: - * - *\li If the request procedure has not completed, post its CLIENTREQDONE - * event with a result code of #ISC_R_CANCELED. - * - * Requires: - * - *\li 'trans' is a valid transaction ID. - */ - -void -dns_client_destroyreqtrans(dns_clientreqtrans_t **transp); -/*% - * Destroy DNS request transaction state identified by '*transp'. - * - * Requires: - * - *\li '*transp' is a valid transaction ID. - * - *\li The caller has received the CLIENTREQDONE event (either because the - * request completed or because dns_client_cancelrequest() was called). - * - * Ensures: - * - *\li *transp == NULL. - */ - -isc_result_t -dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *zonename, dns_namelist_t *prerequisites, - dns_namelist_t *updates, isc_sockaddrlist_t *servers, - dns_tsec_t *tsec, unsigned int options); - -isc_result_t -dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, - dns_name_t *zonename, dns_namelist_t *prerequisites, - dns_namelist_t *updates, isc_sockaddrlist_t *servers, - dns_tsec_t *tsec, unsigned int options, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_clientupdatetrans_t **transp); -/*%< - * Perform DNS dynamic update for 'updates' of the 'rdclass' class with - * optional 'prerequisites'. - * - * 'updates' are a list of names with associated RRsets to be updated. - * - * 'prerequisites' are a list of names with associated RRsets corresponding to - * the prerequisites of the updates. This is optional and can be NULL, in - * which case the prerequisite section of the update message will be empty. - * - * Both 'updates' and 'prerequisites' must be constructed as specified in - * RFC2136. - * - * 'zonename' is the name of the zone in which the updated names exist. - * This is optional and can be NULL. In this case, these functions internally - * identify the appropriate zone through some queries for the SOA RR starting - * with the first name in prerequisites or updates. - * - * 'servers' is a list of authoritative servers to which the update message - * should be sent. This is optional and can be NULL. In this case, these - * functions internally identify the appropriate primary server name and its - * addresses through some queries for the SOA RR (like the case of zonename) - * and supplemental A/AAAA queries for the server name. - * Note: The client module generally assumes the given addresses are of the - * primary server of the corresponding zone. It will work even if a secondary - * server address is specified as long as the server allows update forwarding, - * it is generally discouraged to include secondary server addresses unless - * there's strong reason to do so. - * - * 'tsec' is a transaction security object containing, e.g. a TSIG key for - * authenticating the update transaction (and the supplemental query/response - * transactions if the server is specified). This is optional and can be - * NULL, in which case the library tries the update without any transaction - * authentication. - * - * It is typically expected that the client object passed to - * dns_client_update() was created via dns_client_create() and has its own - * managers and contexts. However, if the DNS_CLIENTUPDOPT_ALLOWRUN flag is - * set in 'options', this function performs the synchronous service even if - * it does not have its own manager and context structures. - * - * dns_client_update() provides a synchronous service. This function blocks - * until the entire update procedure completes, including the additional - * queries when necessary. - * - * dns_client_startupdate() is an asynchronous version of dns_client_update(). - * It immediately returns (typically with *transp being set to a non-NULL - * pointer), and performs the update procedure through a set of internal - * events. All transactions including the additional query exchanges are - * performed as a separate event, so none of these events cause blocking - * operation. When the update procedure completes, the specified function - * 'action' will be called with the argument of a 'dns_clientupdateevent_t' - * structure. On return, '*transp' is set to an opaque transaction ID so that - * the caller can cancel this update process. - * - * DNS_CLIENTUPDOPT_TCP switches to the TCP (vs. UDP) transport. - * - * Requires: - * - *\li 'client' is a valid client. - * - *\li 'updates' != NULL. - * - *\li 'task' is a valid task. - * - *\li 'transp' != NULL && *transp == NULL; - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -void -dns_client_cancelupdate(dns_clientupdatetrans_t *trans); -/*%< - * Cancel an ongoing dynamic update procedure started via - * dns_client_startupdate(). - * - * Notes: - * - *\li If the update procedure has not completed, post its UPDATEDONE - * event with a result code of #ISC_R_CANCELED. - * - * Requires: - * - *\li 'trans' is a valid transaction ID. - */ - -void -dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp); -/*%< - * Destroy dynamic update transaction identified by '*transp'. - * - * Requires: - * - *\li '*transp' is a valid transaction ID. - * - *\li The caller has received the UPDATEDONE event (either because the - * update completed or because dns_client_cancelupdate() was called). - * - * Ensures: - * - *\li *transp == NULL. - */ - -isc_result_t -dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner, - dns_rdatatype_t type, dns_rdata_t *source, - dns_ttl_t ttl, dns_name_t *target, - dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist, - dns_rdata_t *rdata, isc_mem_t *mctx); -/*%< - * TBD - */ - -void -dns_client_freeupdate(dns_name_t **namep); -/*%< - * TBD - */ - -isc_mem_t * -dns_client_mctx(dns_client_t *client); - -ISC_LANG_ENDDECLS - -#endif /* DNS_CLIENT_H */ diff --git a/lib/dns-pkcs11/include/dns/clientinfo.h b/lib/dns-pkcs11/include/dns/clientinfo.h deleted file mode 100644 index 11e0f2a..0000000 --- a/lib/dns-pkcs11/include/dns/clientinfo.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_CLIENTINFO_H -#define DNS_CLIENTINFO_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/clientinfo.h - * \brief - * The DNS clientinfo interface allows libdns to retrieve information - * about the client from the caller. - * - * The clientinfo interface is used by the DNS DB and DLZ interfaces; - * it allows databases to modify their answers on the basis of information - * about the client, such as source IP address. - * - * dns_clientinfo_t contains a pointer to an opaque structure containing - * client information in some form. dns_clientinfomethods_t contains a - * list of methods which operate on that opaque structure to return - * potentially useful data. Both structures also contain versioning - * information. - */ - -/***** - ***** Imports - *****/ - -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Types - *****/ - -#define DNS_CLIENTINFO_VERSION 2 -typedef struct dns_clientinfo { - uint16_t version; - void *data; - void *dbversion; -} dns_clientinfo_t; - -typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client, - isc_sockaddr_t **addrp); - -#define DNS_CLIENTINFOMETHODS_VERSION 2 -#define DNS_CLIENTINFOMETHODS_AGE 1 - -typedef struct dns_clientinfomethods { - uint16_t version; - uint16_t age; - dns_clientinfo_sourceip_t sourceip; -} dns_clientinfomethods_t; - -/***** - ***** Methods - *****/ -void -dns_clientinfomethods_init(dns_clientinfomethods_t *methods, - dns_clientinfo_sourceip_t sourceip); - -void -dns_clientinfo_init(dns_clientinfo_t *ci, void *data, void *versionp); - -ISC_LANG_ENDDECLS - -#endif /* DNS_CLIENTINFO_H */ diff --git a/lib/dns-pkcs11/include/dns/compress.h b/lib/dns-pkcs11/include/dns/compress.h deleted file mode 100644 index 3d11e4a..0000000 --- a/lib/dns-pkcs11/include/dns/compress.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_COMPRESS_H -#define DNS_COMPRESS_H 1 - -#include -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*! \file dns/compress.h - * Direct manipulation of the structures is strongly discouraged. - * - * A name compression context handles compression of multiple DNS names - * in relation to a single DNS message. The context can be used to - * selectively turn on/off compression for specific names (depending on - * the RR type) by using \c dns_compress_setmethods(). Alternately, - * compression can be disabled completely using \c - * dns_compress_disable(). - * - * \c dns_compress_setmethods() is intended for use by RDATA towire() - * implementations, whereas \c dns_compress_disable() is intended to be - * used by a nameserver's configuration manager. - */ - -#define DNS_COMPRESS_NONE 0x00 /*%< no compression */ -#define DNS_COMPRESS_GLOBAL14 0x01 /*%< "normal" compression. */ -#define DNS_COMPRESS_ALL 0x01 /*%< all compression. */ -#define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */ -#define DNS_COMPRESS_ENABLED 0x04 - -#define DNS_COMPRESS_READY 0x80000000 - -#define DNS_COMPRESS_TABLESIZE 64 -#define DNS_COMPRESS_INITIALNODES 16 - -typedef struct dns_compressnode dns_compressnode_t; - -struct dns_compressnode { - isc_region_t r; - uint16_t offset; - uint16_t count; - uint8_t labels; - dns_compressnode_t *next; -}; - -struct dns_compress { - unsigned int magic; /*%< Magic number. */ - unsigned int allowed; /*%< Allowed methods. */ - int edns; /*%< Edns version or -1. */ - /*% Global compression table. */ - dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE]; - /*% Preallocated nodes for the table. */ - dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES]; - uint16_t count; /*%< Number of nodes. */ - isc_mem_t *mctx; /*%< Memory context. */ -}; - -typedef enum { - DNS_DECOMPRESS_ANY, /*%< Any compression */ - DNS_DECOMPRESS_STRICT, /*%< Allowed compression */ - DNS_DECOMPRESS_NONE /*%< No compression */ -} dns_decompresstype_t; - -struct dns_decompress { - unsigned int magic; /*%< Magic number. */ - unsigned int allowed; /*%< Allowed methods. */ - int edns; /*%< Edns version or -1. */ - dns_decompresstype_t type; /*%< Strict checking */ -}; - -isc_result_t -dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx); -/*%< - * Initialise the compression context structure pointed to by - * 'cctx'. A freshly initialized context has name compression - * enabled, but no methods are set. Please use \c - * dns_compress_setmethods() to set a compression method. - * - * Requires: - * \li 'cctx' is a valid dns_compress_t structure. - * \li 'mctx' is an initialized memory context. - * Ensures: - * \li cctx->global is initialized. - * - * Returns: - * \li #ISC_R_SUCCESS - */ - -void -dns_compress_invalidate(dns_compress_t *cctx); - -/*%< - * Invalidate the compression structure pointed to by cctx. - * - * Requires: - *\li 'cctx' to be initialized. - */ - -void -dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed); - -/*%< - * Sets allowed compression methods. - * - * Requires: - *\li 'cctx' to be initialized. - */ - -unsigned int -dns_compress_getmethods(dns_compress_t *cctx); - -/*%< - * Gets allowed compression methods. - * - * Requires: - *\li 'cctx' to be initialized. - * - * Returns: - *\li allowed compression bitmap. - */ - -void -dns_compress_disable(dns_compress_t *cctx); -/*%< - * Disables all name compression in the context. Once disabled, - * name compression cannot currently be re-enabled. - * - * Requires: - *\li 'cctx' to be initialized. - * - */ - -void -dns_compress_setsensitive(dns_compress_t *cctx, bool sensitive); - -/* - * Preserve the case of compressed domain names. - * - * Requires: - * 'cctx' to be initialized. - */ - -bool -dns_compress_getsensitive(dns_compress_t *cctx); -/* - * Return whether case is to be preserved when compressing - * domain names. - * - * Requires: - * 'cctx' to be initialized. - */ - -int -dns_compress_getedns(dns_compress_t *cctx); - -/*%< - * Gets edns value. - * - * Requires: - *\li 'cctx' to be initialized. - * - * Returns: - *\li -1 .. 255 - */ - -bool -dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, - dns_name_t *prefix, uint16_t *offset); -/*%< - * Finds longest possible match of 'name' in the global compression table. - * - * Requires: - *\li 'cctx' to be initialized. - *\li 'name' to be a absolute name. - *\li 'prefix' to be initialized. - *\li 'offset' to point to an uint16_t. - * - * Ensures: - *\li 'prefix' and 'offset' are valid if true is returned. - * - * Returns: - *\li #true / #false - */ - -void -dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, - const dns_name_t *prefix, uint16_t offset); -/*%< - * Add compression pointers for 'name' to the compression table, - * not replacing existing pointers. - * - * Requires: - *\li 'cctx' initialized - * - *\li 'name' must be initialized and absolute, and must remain - * valid until the message compression is complete. - * - *\li 'prefix' must be a prefix returned by - * dns_compress_findglobal(), or the same as 'name'. - */ - -void -dns_compress_rollback(dns_compress_t *cctx, uint16_t offset); - -/*%< - * Remove any compression pointers from global table >= offset. - * - * Requires: - *\li 'cctx' is initialized. - */ - -void -dns_decompress_init(dns_decompress_t *dctx, int edns, - dns_decompresstype_t type); - -/*%< - * Initializes 'dctx'. - * Records 'edns' and 'type' into the structure. - * - * Requires: - *\li 'dctx' to be a valid pointer. - */ - -void -dns_decompress_invalidate(dns_decompress_t *dctx); - -/*%< - * Invalidates 'dctx'. - * - * Requires: - *\li 'dctx' to be initialized - */ - -void -dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); - -/*%< - * Sets 'dctx->allowed' to 'allowed'. - * - * Requires: - *\li 'dctx' to be initialized - */ - -unsigned int -dns_decompress_getmethods(dns_decompress_t *dctx); - -/*%< - * Returns 'dctx->allowed' - * - * Requires: - *\li 'dctx' to be initialized - */ - -int -dns_decompress_edns(dns_decompress_t *dctx); - -/*%< - * Returns 'dctx->edns' - * - * Requires: - *\li 'dctx' to be initialized - */ - -dns_decompresstype_t -dns_decompress_type(dns_decompress_t *dctx); - -/*%< - * Returns 'dctx->type' - * - * Requires: - *\li 'dctx' to be initialized - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_COMPRESS_H */ diff --git a/lib/dns-pkcs11/include/dns/db.h b/lib/dns-pkcs11/include/dns/db.h deleted file mode 100644 index 452770f..0000000 --- a/lib/dns-pkcs11/include/dns/db.h +++ /dev/null @@ -1,1723 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_DB_H -#define DNS_DB_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/db.h - * \brief - * The DNS DB interface allows named rdatasets to be stored and retrieved. - * - * The dns_db_t type is like a "virtual class". To actually use - * DBs, an implementation of the class is required. - * - * XXX more XXX - * - * MP: - * \li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - * \li No anticipated impact. - * - * Resources: - * \li TBS - * - * Security: - * \li No anticipated impact. - * - * Standards: - * \li None. - */ - -/***** - ***** Imports - *****/ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Types - *****/ - -typedef struct dns_dbmethods { - void (*attach)(dns_db_t *source, dns_db_t **targetp); - void (*detach)(dns_db_t **dbp); - isc_result_t (*beginload)(dns_db_t *db, - dns_rdatacallbacks_t *callbacks); - isc_result_t (*endload)(dns_db_t *db, - dns_rdatacallbacks_t *callbacks); - isc_result_t (*serialize)(dns_db_t *db, - dns_dbversion_t *version, FILE *file); - isc_result_t (*dump)(dns_db_t *db, dns_dbversion_t *version, - const char *filename, - dns_masterformat_t masterformat); - void (*currentversion)(dns_db_t *db, - dns_dbversion_t **versionp); - isc_result_t (*newversion)(dns_db_t *db, - dns_dbversion_t **versionp); - void (*attachversion)(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp); - void (*closeversion)(dns_db_t *db, - dns_dbversion_t **versionp, - bool commit); - isc_result_t (*findnode)(dns_db_t *db, dns_name_t *name, - bool create, - dns_dbnode_t **nodep); - isc_result_t (*find)(dns_db_t *db, dns_name_t *name, - dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, - isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - isc_result_t (*findzonecut)(dns_db_t *db, dns_name_t *name, - unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, - dns_name_t *foundname, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - void (*attachnode)(dns_db_t *db, - dns_dbnode_t *source, - dns_dbnode_t **targetp); - void (*detachnode)(dns_db_t *db, - dns_dbnode_t **targetp); - isc_result_t (*expirenode)(dns_db_t *db, dns_dbnode_t *node, - isc_stdtime_t now); - void (*printnode)(dns_db_t *db, dns_dbnode_t *node, - FILE *out); - isc_result_t (*createiterator)(dns_db_t *db, unsigned int options, - dns_dbiterator_t **iteratorp); - isc_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - dns_rdatatype_t type, - dns_rdatatype_t covers, - isc_stdtime_t now, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - isc_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - isc_stdtime_t now, - dns_rdatasetiter_t **iteratorp); - isc_result_t (*addrdataset)(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - isc_stdtime_t now, - dns_rdataset_t *rdataset, - unsigned int options, - dns_rdataset_t *addedrdataset); - isc_result_t (*subtractrdataset)(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - dns_rdataset_t *rdataset, - unsigned int options, - dns_rdataset_t *newrdataset); - isc_result_t (*deleterdataset)(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - dns_rdatatype_t type, - dns_rdatatype_t covers); - bool (*issecure)(dns_db_t *db); - unsigned int (*nodecount)(dns_db_t *db); - bool (*ispersistent)(dns_db_t *db); - void (*overmem)(dns_db_t *db, bool overmem); - void (*settask)(dns_db_t *db, isc_task_t *); - isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep); - void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep, - dns_dbnode_t **targetp); - isc_result_t (*getnsec3parameters)(dns_db_t *db, - dns_dbversion_t *version, - dns_hash_t *hash, - uint8_t *flags, - uint16_t *iterations, - unsigned char *salt, - size_t *salt_len); - isc_result_t (*findnsec3node)(dns_db_t *db, dns_name_t *name, - bool create, - dns_dbnode_t **nodep); - isc_result_t (*setsigningtime)(dns_db_t *db, - dns_rdataset_t *rdataset, - isc_stdtime_t resign); - isc_result_t (*getsigningtime)(dns_db_t *db, - dns_rdataset_t *rdataset, - dns_name_t *name); - void (*resigned)(dns_db_t *db, dns_rdataset_t *rdataset, - dns_dbversion_t *version); - bool (*isdnssec)(dns_db_t *db); - dns_stats_t *(*getrrsetstats)(dns_db_t *db); - void (*rpz_attach)(dns_db_t *db, dns_rpz_zones_t *rpzs, - dns_rpz_num_t rpz_num); - isc_result_t (*rpz_ready)(dns_db_t *db); - isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name, - bool create, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_dbnode_t **nodep); - isc_result_t (*findext)(dns_db_t *db, dns_name_t *name, - dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, - isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - isc_result_t (*setcachestats)(dns_db_t *db, isc_stats_t *stats); - size_t (*hashsize)(dns_db_t *db); - isc_result_t (*nodefullname)(dns_db_t *db, dns_dbnode_t *node, - dns_name_t *name); - isc_result_t (*getsize)(dns_db_t *db, dns_dbversion_t *version, - uint64_t *records, uint64_t *bytes); - isc_result_t (*setservestalettl)(dns_db_t *db, dns_ttl_t ttl); - isc_result_t (*getservestalettl)(dns_db_t *db, dns_ttl_t *ttl); -} dns_dbmethods_t; - -typedef isc_result_t -(*dns_dbcreatefunc_t)(isc_mem_t *mctx, dns_name_t *name, - dns_dbtype_t type, dns_rdataclass_t rdclass, - unsigned int argc, char *argv[], void *driverarg, - dns_db_t **dbp); - -typedef isc_result_t -(*dns_dbupdate_callback_t)(dns_db_t *db, void *fn_arg); - -#define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D') -#define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC) - -/*% - * This structure is actually just the common prefix of a DNS db - * implementation's version of a dns_db_t. - * \brief - * Direct use of this structure by clients is forbidden. DB implementations - * may change the structure. 'magic' must be DNS_DB_MAGIC for any of the - * dns_db_ routines to work. DB implementations must maintain all DB - * invariants. - */ -struct dns_db { - unsigned int magic; - unsigned int impmagic; - dns_dbmethods_t * methods; - uint16_t attributes; - dns_rdataclass_t rdclass; - dns_name_t origin; - isc_ondestroy_t ondest; - isc_mem_t * mctx; - ISC_LIST(dns_dbonupdatelistener_t) update_listeners; -}; - -#define DNS_DBATTR_CACHE 0x01 -#define DNS_DBATTR_STUB 0x02 - -struct dns_dbonupdatelistener { - dns_dbupdate_callback_t onupdate; - void * onupdate_arg; - ISC_LINK(dns_dbonupdatelistener_t) link; -}; - -/*@{*/ -/*% - * Options that can be specified for dns_db_find(). - */ -#define DNS_DBFIND_GLUEOK 0x0001 -#define DNS_DBFIND_VALIDATEGLUE 0x0002 -#define DNS_DBFIND_NOWILD 0x0004 -#define DNS_DBFIND_PENDINGOK 0x0008 -#define DNS_DBFIND_NOEXACT 0x0010 -#define DNS_DBFIND_FORCENSEC 0x0020 -#define DNS_DBFIND_COVERINGNSEC 0x0040 -#define DNS_DBFIND_FORCENSEC3 0x0080 -#define DNS_DBFIND_ADDITIONALOK 0x0100 -#define DNS_DBFIND_NOZONECUT 0x0200 -#define DNS_DBFIND_STALEOK 0x0400 -/*@}*/ - -/*@{*/ -/*% - * Options that can be specified for dns_db_addrdataset(). - */ -#define DNS_DBADD_MERGE 0x01 -#define DNS_DBADD_FORCE 0x02 -#define DNS_DBADD_EXACT 0x04 -#define DNS_DBADD_EXACTTTL 0x08 -#define DNS_DBADD_PREFETCH 0x10 -/*@}*/ - -/*% - * Options that can be specified for dns_db_subtractrdataset(). - */ -#define DNS_DBSUB_EXACT 0x01 -#define DNS_DBSUB_WANTOLD 0x02 - -/*@{*/ -/*% - * Iterator options - */ -#define DNS_DB_RELATIVENAMES 0x1 -#define DNS_DB_NSEC3ONLY 0x2 -#define DNS_DB_NONSEC3 0x4 -/*@}*/ - -/***** - ***** Methods - *****/ - -/*** - *** Basic DB Methods - ***/ - -isc_result_t -dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, - dns_dbtype_t type, dns_rdataclass_t rdclass, - unsigned int argc, char *argv[], dns_db_t **dbp); -/*%< - * Create a new database using implementation 'db_type'. - * - * Notes: - * \li All names in the database must be subdomains of 'origin' and in class - * 'rdclass'. The database makes its own copy of the origin, so the - * caller may do whatever they like with 'origin' and its storage once the - * call returns. - * - * \li DB implementation-specific parameters are passed using argc and argv. - * - * Requires: - * - * \li dbp != NULL and *dbp == NULL - * - * \li 'origin' is a valid absolute domain name. - * - * \li mctx is a valid memory context - * - * Ensures: - * - * \li A copy of 'origin' has been made for the databases use, and the - * caller is free to do whatever they want with the name and storage - * associated with 'origin'. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * \li #ISC_R_NOTFOUND db_type not found - * - * \li Many other errors are possible, depending on what db_type was - * specified. - */ - -void -dns_db_attach(dns_db_t *source, dns_db_t **targetp); -/*%< - * Attach *targetp to source. - * - * Requires: - * - * \li 'source' is a valid database. - * - * \li 'targetp' points to a NULL dns_db_t *. - * - * Ensures: - * - * \li *targetp is attached to source. - */ - -void -dns_db_detach(dns_db_t **dbp); -/*%< - * Detach *dbp from its database. - * - * Requires: - * - * \li 'dbp' points to a valid database. - * - * Ensures: - * - * \li *dbp is NULL. - * - * \li If '*dbp' is the last reference to the database, - * all resources used by the database will be freed - */ - -isc_result_t -dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp); -/*%< - * Causes 'eventp' to be sent to be sent to 'task' when the database is - * destroyed. - * - * Note; ownership of the eventp is taken from the caller (and *eventp is - * set to NULL). The sender field of the event is set to 'db' before it is - * sent to the task. - */ - -bool -dns_db_iscache(dns_db_t *db); -/*%< - * Does 'db' have cache semantics? - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li #true 'db' has cache semantics - * \li #false otherwise - */ - -bool -dns_db_iszone(dns_db_t *db); -/*%< - * Does 'db' have zone semantics? - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li #true 'db' has zone semantics - * \li #false otherwise - */ - -bool -dns_db_isstub(dns_db_t *db); -/*%< - * Does 'db' have stub semantics? - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li #true 'db' has zone semantics - * \li #false otherwise - */ - -bool -dns_db_issecure(dns_db_t *db); -/*%< - * Is 'db' secure? - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * Returns: - * \li #true 'db' is secure. - * \li #false 'db' is not secure. - */ - -bool -dns_db_isdnssec(dns_db_t *db); -/*%< - * Is 'db' secure or partially secure? - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * Returns: - * \li #true 'db' is secure or is partially. - * \li #false 'db' is not secure. - */ - -dns_name_t * -dns_db_origin(dns_db_t *db); -/*%< - * The origin of the database. - * - * Note: caller must not try to change this name. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * - * \li The origin of the database. - */ - -dns_rdataclass_t -dns_db_class(dns_db_t *db); -/*%< - * The class of the database. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * - * \li The class of the database. - */ - -isc_result_t -dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks); -/*%< - * Begin loading 'db'. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li This is the first attempt to load 'db'. - * - * \li 'callbacks' is a pointer to an initialized dns_rdatacallbacks_t - * structure. - * - * Ensures: - * - * \li On success, callbacks->add will be a valid dns_addrdatasetfunc_t - * suitable for loading records into 'db' from a raw or text zone - * file. callbacks->add_private will be a valid DB load context - * which should be used as 'arg' when callbacks->add is called. - * callbacks->deserialize will be a valid dns_deserialize_func_t - * suitable for loading 'db' from a map format zone file. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used, syntax errors in the master file, etc. - */ - -isc_result_t -dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks); -/*%< - * Finish loading 'db'. - * - * Requires: - * - * \li 'db' is a valid database that is being loaded. - * - * \li 'callbacks' is a valid dns_rdatacallbacks_t structure. - * - * \li callbacks->add_private is not NULL and is a valid database load context. - * - * Ensures: - * - * \li 'callbacks' is returned to its state prior to calling dns_db_beginload() - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used, syntax errors in the master file, etc. - */ - -isc_result_t -dns_db_load(dns_db_t *db, const char *filename); - -isc_result_t -dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format); - -isc_result_t -dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format, - unsigned int options); -/*%< - * Load master file 'filename' into 'db'. - * - * Notes: - * \li This routine is equivalent to calling - * - *\code - * dns_db_beginload(); - * dns_master_loadfile(); - * dns_db_endload(); - *\endcode - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li This is the first attempt to load 'db'. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used, syntax errors in the master file, etc. - */ - -isc_result_t -dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *rbtfile); -/*%< - * Dump version 'version' of 'db' to map-format file 'filename'. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'version' is a valid version. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used, OS file errors, etc. - */ - -isc_result_t -dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename); - -isc_result_t -dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat); -/*%< - * Dump version 'version' of 'db' to master file 'filename'. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'version' is a valid version. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used, OS file errors, etc. - */ - -/*** - *** Version Methods - ***/ - -void -dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp); -/*%< - * Open the current version for reading. - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * \li versionp != NULL && *verisonp == NULL - * - * Ensures: - * - * \li On success, '*versionp' is attached to the current version. - * - */ - -isc_result_t -dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp); -/*%< - * Open a new version for reading and writing. - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * \li versionp != NULL && *verisonp == NULL - * - * Ensures: - * - * \li On success, '*versionp' is attached to the current version. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -void -dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp); -/*%< - * Attach '*targetp' to 'source'. - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * \li source is a valid open version - * - * \li targetp != NULL && *targetp == NULL - * - * Ensures: - * - * \li '*targetp' is attached to source. - */ - -void -dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, - bool commit); -/*%< - * Close version '*versionp'. - * - * Note: if '*versionp' is a read-write version and 'commit' is true, - * then all changes made in the version will take effect, otherwise they - * will be rolled back. The value of 'commit' is ignored for read-only - * versions. - * - * Requires: - * - * \li 'db' is a valid database with zone semantics. - * - * \li '*versionp' refers to a valid version. - * - * \li If committing a writable version, then there must be no other - * outstanding references to the version (e.g. an active rdataset - * iterator). - * - * Ensures: - * - * \li *versionp == NULL - * - * \li If *versionp is a read-write version, and commit is true, then - * the version will become the current version. If !commit, then all - * changes made in the version will be undone, and the version will - * not become the current version. - */ - -/*** - *** Node Methods - ***/ - -isc_result_t -dns_db_findnode(dns_db_t *db, dns_name_t *name, bool create, - dns_dbnode_t **nodep); - -isc_result_t -dns_db_findnodeext(dns_db_t *db, dns_name_t *name, bool create, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep); -/*%< - * Find the node with name 'name'. - * - * dns_db_findnodeext() (findnode extended) also accepts parameters - * 'methods' and 'clientinfo', which, when provided, enable the database to - * retrieve information about the client from the caller, and modify its - * response on the basis of that information. - * - * Notes: - * \li If 'create' is true and no node with name 'name' exists, then - * such a node will be created. - * - * \li This routine is for finding or creating a node with the specified - * name. There are no partial matches. It is not suitable for use - * in building responses to ordinary DNS queries; clients which wish - * to do that should use dns_db_find() instead. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'name' is a valid, non-empty, absolute name. - * - * \li nodep != NULL && *nodep == NULL - * - * Ensures: - * - * \li On success, *nodep is attached to the node with name 'name'. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND If !create and name not found. - * \li #ISC_R_NOMEMORY Can only happen if create is true. - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -isc_result_t -dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/*%< - * Find the best match for 'name' and 'type' in version 'version' of 'db'. - * - * dns_db_findext() (find extended) also accepts parameters 'methods' - * and 'clientinfo', which when provided enable the database to retrieve - * information about the client from the caller, and modify its response - * on the basis of this information. - * - * Notes: - * - * \li If type == dns_rdataset_any, then rdataset will not be bound. - * - * \li If 'options' does not have #DNS_DBFIND_GLUEOK set, then no glue will - * be returned. For zone databases, glue is as defined in RFC2181. - * For cache databases, glue is any rdataset with a trust of - * dns_trust_glue. - * - * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no - * additional records will be returned. Only caches can have - * rdataset with trust dns_trust_additional. - * - * \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no - * pending data will be returned. This option is only meaningful for - * cache databases. - * - * \li If the #DNS_DBFIND_NOWILD option is set, then wildcard matching will - * be disabled. This option is only meaningful for zone databases. - * - * \li If the #DNS_DBFIND_NOZONECUT option is set, the database is - * assumed to contain no zone cuts above 'name'. An implementation - * may therefore choose to search for a match beginning at 'name' - * rather than walking down the tree to check check for delegations. - * If #DNS_DBFIND_NOWILD is not set, wildcard matching will be - * attempted at each node starting at the direct ancestor of 'name' - * and working up to the zone origin. This option is only meaningful - * when querying redirect zones. - * - * \li If the #DNS_DBFIND_FORCENSEC option is set, the database is assumed to - * have NSEC records, and these will be returned when appropriate. This - * is only necessary when querying a database that was not secure - * when created. - * - * \li If the DNS_DBFIND_COVERINGNSEC option is set, then look for a - * NSEC record that potentially covers 'name' if a answer cannot - * be found. Note the returned NSEC needs to be checked to ensure - * that it is correct. This only affects answers returned from the - * cache. - * - * \li If the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking - * in the NSEC3 tree and not the main tree. Without this option being - * set NSEC3 records will not be found. - * - * \li To respond to a query for SIG records, the caller should create a - * rdataset iterator and extract the signatures from each rdataset. - * - * \li Making queries of type ANY with #DNS_DBFIND_GLUEOK is not recommended, - * because the burden of determining whether a given rdataset is valid - * glue or not falls upon the caller. - * - * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a - * cache database, an rdataset will not be found unless it expires after - * 'now'. Any ANY query will not match unless at least one rdataset at - * the node expires after 'now'. If 'now' is zero, then the current time - * will be used. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'type' is not SIG, or a meta-RR type other than 'ANY' (e.g. 'OPT'). - * - * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. - * - * \li 'foundname' is a valid name with a dedicated buffer. - * - * \li 'rdataset' is NULL, or is a valid unassociated rdataset. - * - * Ensures, - * on a non-error completion: - * - * \li If nodep != NULL, then it is bound to the found node. - * - * \li If foundname != NULL, then it contains the full name of the - * found node. - * - * \li If rdataset != NULL and type != dns_rdatatype_any, then - * rdataset is bound to the found rdataset. - * - * Non-error results are: - * - * \li #ISC_R_SUCCESS The desired node and type were - * found. - * - * \li #DNS_R_GLUE The desired node and type were - * found, but are glue. This - * result can only occur if - * the DNS_DBFIND_GLUEOK option - * is set. This result can only - * occur if 'db' is a zone - * database. If type == - * dns_rdatatype_any, then the - * node returned may contain, or - * consist entirely of invalid - * glue (i.e. data occluded by a - * zone cut). The caller must - * take care not to return invalid - * glue to a client. - * - * \li #DNS_R_DELEGATION The data requested is beneath - * a zone cut. node, foundname, - * and rdataset reference the - * NS RRset of the zone cut. - * If 'db' is a cache database, - * then this is the deepest known - * delegation. - * - * \li #DNS_R_ZONECUT type == dns_rdatatype_any, and - * the desired node is a zonecut. - * The caller must take care not - * to return inappropriate glue - * to a client. This result can - * only occur if 'db' is a zone - * database and DNS_DBFIND_GLUEOK - * is set. - * - * \li #DNS_R_DNAME The data requested is beneath - * a DNAME. node, foundname, - * and rdataset reference the - * DNAME RRset. - * - * \li #DNS_R_CNAME The rdataset requested was not - * found, but there is a CNAME - * at the desired name. node, - * foundname, and rdataset - * reference the CNAME RRset. - * - * \li #DNS_R_NXDOMAIN The desired name does not - * exist. - * - * \li #DNS_R_NXRRSET The desired name exists, but - * the desired type does not. - * - * \li #ISC_R_NOTFOUND The desired name does not - * exist, and no delegation could - * be found. This result can only - * occur if 'db' is a cache - * database. The caller should - * use its nameserver(s) of last - * resort (e.g. root hints). - * - * \li #DNS_R_NCACHENXDOMAIN The desired name does not - * exist. 'node' is bound to the - * cache node with the desired - * name, and 'rdataset' contains - * the negative caching proof. - * - * \li #DNS_R_NCACHENXRRSET The desired type does not - * exist. 'node' is bound to the - * cache node with the desired - * name, and 'rdataset' contains - * the negative caching proof. - * - * \li #DNS_R_EMPTYNAME The name exists but there is - * no data at the name. - * - * \li #DNS_R_COVERINGNSEC The returned data is a NSEC - * that potentially covers 'name'. - * - * \li #DNS_R_EMPTYWILD The name is a wildcard without - * resource records. - * - * Error results: - * - * \li #ISC_R_NOMEMORY - * - * \li #DNS_R_BADDB Data that is required to be - * present in the DB, e.g. an NSEC - * record in a secure zone, is not - * present. - * - * \li Other results are possible, and should all be treated as - * errors. - */ - -isc_result_t -dns_db_findzonecut(dns_db_t *db, dns_name_t *name, - unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/*%< - * Find the deepest known zonecut which encloses 'name' in 'db'. - * - * Notes: - * - * \li If the #DNS_DBFIND_NOEXACT option is set, then the zonecut returned - * (if any) will be the deepest known ancestor of 'name'. - * - * \li If 'now' is zero, then the current time will be used. - * - * Requires: - * - * \li 'db' is a valid database with cache semantics. - * - * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. - * - * \li 'foundname' is a valid name with a dedicated buffer. - * - * \li 'rdataset' is NULL, or is a valid unassociated rdataset. - * - * Ensures, on a non-error completion: - * - * \li If nodep != NULL, then it is bound to the found node. - * - * \li If foundname != NULL, then it contains the full name of the - * found node. - * - * \li If rdataset != NULL and type != dns_rdatatype_any, then - * rdataset is bound to the found rdataset. - * - * Non-error results are: - * - * \li #ISC_R_SUCCESS - * - * \li #ISC_R_NOTFOUND - * - * \li Other results are possible, and should all be treated as - * errors. - */ - -void -dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp); -/*%< - * Attach *targetp to source. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'source' is a valid node. - * - * \li 'targetp' points to a NULL dns_dbnode_t *. - * - * Ensures: - * - * \li *targetp is attached to source. - */ - -void -dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep); -/*%< - * Detach *nodep from its node. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'nodep' points to a valid node. - * - * Ensures: - * - * \li *nodep is NULL. - */ - -void -dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, - dns_dbnode_t **targetp); -/*%< - * Transfer a node between pointer. - * - * This is equivalent to calling dns_db_attachnode() then dns_db_detachnode(). - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li '*sourcep' is a valid node. - * - * \li 'targetp' points to a NULL dns_dbnode_t *. - * - * Ensures: - * - * \li '*sourcep' is NULL. - */ - -isc_result_t -dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now); -/*%< - * Mark as stale all records at 'node' which expire at or before 'now'. - * - * Note: if 'now' is zero, then the current time will be used. - * - * Requires: - * - * \li 'db' is a valid cache database. - * - * \li 'node' is a valid node. - */ - -void -dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out); -/*%< - * Print a textual representation of the contents of the node to - * 'out'. - * - * Note: this function is intended for debugging, not general use. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - */ - -/*** - *** DB Iterator Creation - ***/ - -isc_result_t -dns_db_createiterator(dns_db_t *db, unsigned int options, - dns_dbiterator_t **iteratorp); -/*%< - * Create an iterator for version 'version' of 'db'. - * - * Notes: - * - * \li One or more of the following options can be set. - * #DNS_DB_RELATIVENAMES - * #DNS_DB_NSEC3ONLY - * #DNS_DB_NONSEC3 - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li iteratorp != NULL && *iteratorp == NULL - * - * Ensures: - * - * \li On success, *iteratorp will be a valid database iterator. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - */ - -/*** - *** Rdataset Methods - ***/ - -/* - * XXXRTH Should we check for glue and pending data in dns_db_findrdataset()? - */ - -isc_result_t -dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - -/*%< - * Search for an rdataset of type 'type' at 'node' that are in version - * 'version' of 'db'. If found, make 'rdataset' refer to it. - * - * Notes: - * - * \li If 'version' is NULL, then the current version will be used. - * - * \li Care must be used when using this routine to build a DNS response: - * 'node' should have been found with dns_db_find(), not - * dns_db_findnode(). No glue checking is done. No checking for - * pending data is done. - * - * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a - * cache database, an rdataset will not be found unless it expires after - * 'now'. If 'now' is zero, then the current time will be used. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - * - * \li 'rdataset' is a valid, disassociated rdataset. - * - * \li 'sigrdataset' is a valid, disassociated rdataset, or it is NULL. - * - * \li If 'covers' != 0, 'type' must be SIG. - * - * \li 'type' is not a meta-RR type such as 'ANY' or 'OPT'. - * - * Ensures: - * - * \li On success, 'rdataset' is associated with the found rdataset. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp); -/*%< - * Make '*iteratorp' an rdataset iterator for all rdatasets at 'node' in - * version 'version' of 'db'. - * - * Notes: - * - * \li If 'version' is NULL, then the current version will be used. - * - * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a - * cache database, an rdataset will not be found unless it expires after - * 'now'. Any ANY query will not match unless at least one rdataset at - * the node expires after 'now'. If 'now' is zero, then the current time - * will be used. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - * - * \li iteratorp != NULL && *iteratorp == NULL - * - * Ensures: - * - * \li On success, '*iteratorp' is a valid rdataset iterator. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, - unsigned int options, dns_rdataset_t *addedrdataset); -/*%< - * Add 'rdataset' to 'node' in version 'version' of 'db'. - * - * Notes: - * - * \li If the database has zone semantics, the #DNS_DBADD_MERGE option is set, - * and an rdataset of the same type as 'rdataset' already exists at - * 'node' then the contents of 'rdataset' will be merged with the existing - * rdataset. If the option is not set, then rdataset will replace any - * existing rdataset of the same type. If not merging and the - * #DNS_DBADD_FORCE option is set, then the data will update the database - * without regard to trust levels. If not forcing the data, then the - * rdataset will only be added if its trust level is >= the trust level of - * any existing rdataset. Forcing is only meaningful for cache databases. - * If #DNS_DBADD_EXACT is set then there must be no rdata in common between - * the old and new rdata sets. If #DNS_DBADD_EXACTTTL is set then both - * the old and new rdata sets must have the same ttl. - * - * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is - * a cache database, then the added rdataset will expire no later than - * now + rdataset->ttl. - * - * \li If 'addedrdataset' is not NULL, then it will be attached to the - * resulting new rdataset in the database, or to the existing data if - * the existing data was better. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - * - * \li 'rdataset' is a valid, associated rdataset with the same class - * as 'db'. - * - * \li 'addedrdataset' is NULL, or a valid, unassociated rdataset. - * - * \li The database has zone semantics and 'version' is a valid - * read-write version, or the database has cache semantics - * and version is NULL. - * - * \li If the database has cache semantics, the #DNS_DBADD_MERGE option must - * not be set. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #DNS_R_UNCHANGED The operation did not change anything. - * \li #ISC_R_NOMEMORY - * \li #DNS_R_NOTEXACT - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_rdataset_t *rdataset, - unsigned int options, dns_rdataset_t *newrdataset); -/*%< - * Remove any rdata in 'rdataset' from 'node' in version 'version' of - * 'db'. - * - * Notes: - * - * \li If 'newrdataset' is not NULL, then it will be attached to the - * resulting new rdataset in the database, unless the rdataset has - * become nonexistent. If DNS_DBSUB_EXACT is set then all elements - * of 'rdataset' must exist at 'node'. - * - *\li If DNS_DBSUB_WANTOLD is set and the entire rdataset was deleted - * then return the original rdatatset in newrdataset if that existed. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - * - * \li 'rdataset' is a valid, associated rdataset with the same class - * as 'db'. - * - * \li 'newrdataset' is NULL, or a valid, unassociated rdataset. - * - * \li The database has zone semantics and 'version' is a valid - * read-write version. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #DNS_R_UNCHANGED The operation did not change anything. - * \li #DNS_R_NXRRSET All rdata of the same type as those - * in 'rdataset' have been deleted. - * \li #DNS_R_NOTEXACT Some part of 'rdataset' did not - * exist and DNS_DBSUB_EXACT was set. - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, dns_rdatatype_t type, - dns_rdatatype_t covers); -/*%< - * Make it so that no rdataset of type 'type' exists at 'node' in version - * version 'version' of 'db'. - * - * Notes: - * - * \li If 'type' is dns_rdatatype_any, then no rdatasets will exist in - * 'version' (provided that the dns_db_deleterdataset() isn't followed - * by one or more dns_db_addrdataset() calls). - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'node' is a valid node. - * - * \li The database has zone semantics and 'version' is a valid - * read-write version, or the database has cache semantics - * and version is NULL. - * - * \li 'type' is not a meta-RR type, except for dns_rdatatype_any, which is - * allowed. - * - * \li If 'covers' != 0, 'type' must be SIG. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #DNS_R_UNCHANGED No rdatasets of 'type' existed before - * the operation was attempted. - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, uint32_t *serialp); -/*%< - * Get the current SOA serial number from a zone database. - * - * Requires: - * \li 'db' is a valid database with zone semantics. - * \li 'ver' is a valid version. - */ - -void -dns_db_overmem(dns_db_t *db, bool overmem); -/*%< - * Enable / disable aggressive cache cleaning. - */ - -unsigned int -dns_db_nodecount(dns_db_t *db); -/*%< - * Count the number of nodes in 'db'. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li The number of nodes in the database - */ - -size_t -dns_db_hashsize(dns_db_t *db); -/*%< - * For database implementations using a hash table, report the - * current number of buckets. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li The number of buckets in the database's hash table, or - * 0 if not implemented. - */ - -void -dns_db_settask(dns_db_t *db, isc_task_t *task); -/*%< - * If task is set then the final detach maybe performed asynchronously. - * - * Requires: - * \li 'db' is a valid database. - * \li 'task' to be valid or NULL. - */ - -bool -dns_db_ispersistent(dns_db_t *db); -/*%< - * Is 'db' persistent? A persistent database does not need to be loaded - * from disk or written to disk. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * \li #true 'db' is persistent. - * \li #false 'db' is not persistent. - */ - -isc_result_t -dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, - isc_mem_t *mctx, dns_dbimplementation_t **dbimp); - -/*%< - * Register a new database implementation and add it to the list of - * supported implementations. - * - * Requires: - * - * \li 'name' is not NULL - * \li 'order' is a valid function pointer - * \li 'mctx' is a valid memory context - * \li dbimp != NULL && *dbimp == NULL - * - * Returns: - * \li #ISC_R_SUCCESS The registration succeeded - * \li #ISC_R_NOMEMORY Out of memory - * \li #ISC_R_EXISTS A database implementation with the same name exists - * - * Ensures: - * - * \li *dbimp points to an opaque structure which must be passed to - * dns_db_unregister(). - */ - -void -dns_db_unregister(dns_dbimplementation_t **dbimp); -/*%< - * Remove a database implementation from the list of supported - * implementations. No databases of this type can be active when this - * is called. - * - * Requires: - * \li dbimp != NULL && *dbimp == NULL - * - * Ensures: - * - * \li Any memory allocated in *dbimp will be freed. - */ - -isc_result_t -dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep); -/*%< - * Get the origin DB node corresponding to the DB's zone. This function - * should typically succeed unless the underlying DB implementation doesn't - * support the feature. - * - * Requires: - * - * \li 'db' is a valid zone database. - * \li 'nodep' != NULL && '*nodep' == NULL - * - * Ensures: - * \li On success, '*nodep' will point to the DB node of the zone's origin. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature. - */ - -isc_result_t -dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, - dns_hash_t *hash, uint8_t *flags, - uint16_t *iterations, - unsigned char *salt, size_t *salt_length); -/*%< - * Get the NSEC3 parameters that are associated with this zone. - * - * Requires: - * \li 'db' is a valid zone database. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature - * or this zone does not have NSEC3 records. - */ - -isc_result_t -dns_db_getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records, - uint64_t *bytes); -/*%< - * Get the number of records in the given version of the database as well - * as the number bytes used to store those records. - * - * Requires: - * \li 'db' is a valid zone database. - * \li 'version' is NULL or a valid version. - * \li 'records' is NULL or a pointer to return the record count in. - * \li 'bytes' is NULL or a pointer to return the byte count in. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTIMPLEMENTED - */ - -isc_result_t -dns_db_findnsec3node(dns_db_t *db, dns_name_t *name, - bool create, dns_dbnode_t **nodep); -/*%< - * Find the NSEC3 node with name 'name'. - * - * Notes: - * \li If 'create' is true and no node with name 'name' exists, then - * such a node will be created. - * - * Requires: - * - * \li 'db' is a valid database. - * - * \li 'name' is a valid, non-empty, absolute name. - * - * \li nodep != NULL && *nodep == NULL - * - * Ensures: - * - * \li On success, *nodep is attached to the node with name 'name'. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND If !create and name not found. - * \li #ISC_R_NOMEMORY Can only happen if create is true. - * - * \li Other results are possible, depending upon the database - * implementation used. - */ - -isc_result_t -dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, - isc_stdtime_t resign); -/*%< - * Sets the re-signing time associated with 'rdataset' to 'resign'. - * - * Requires: - * \li 'db' is a valid zone database. - * \li 'rdataset' is or is to be associated with 'db'. - * \li 'rdataset' is not pending removed from the heap via an - * uncommitted call to dns_db_resigned(). - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation. - */ - -isc_result_t -dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name); -/*%< - * Return the rdataset with the earliest signing time in the zone. - * Note: the rdataset is version agnostic. - * - * Requires: - * \li 'db' is a valid zone database. - * \li 'rdataset' to be initialized but not associated. - * \li 'name' to be NULL or have a buffer associated with it. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - No dataset exists. - */ - -void -dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, - dns_dbversion_t *version); -/*%< - * Mark 'rdataset' as not being available to be returned by - * dns_db_getsigningtime(). If the changes associated with 'version' - * are committed this will be permanent. If the version is not committed - * this change will be rolled back when the version is closed. Until - * 'version' is either committed or rolled back, 'rdataset' can no longer - * be acted upon by dns_db_setsigningtime(). - * - * Requires: - * \li 'db' is a valid zone database. - * \li 'rdataset' to be associated with 'db'. - * \li 'version' to be open for writing. - */ - -dns_stats_t * -dns_db_getrrsetstats(dns_db_t *db); -/*%< - * Get statistics information counting RRsets stored in the DB, when available. - * The statistics may not be available depending on the DB implementation. - * - * Requires: - * - * \li 'db' is a valid database (cache only). - * - * Returns: - * \li when available, a pointer to a statistics object created by - * dns_rdatasetstats_create(); otherwise NULL. - */ - -isc_result_t -dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats); -/*%< - * Set the location in which to collect cache statistics. - * This option may not exist depending on the DB implementation. - * - * Requires: - * - * \li 'db' is a valid database (cache only). - * - * Returns: - * \li when available, a pointer to a statistics object created by - * dns_rdatasetstats_create(); otherwise NULL. - */ - -void -dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); -/*%< - * Attach the response policy information for a view to a database for a - * zone for the view. - */ - -isc_result_t -dns_db_rpz_ready(dns_db_t *db); -/*%< - * Finish loading a response policy zone. - */ - -isc_result_t -dns_db_updatenotify_register(dns_db_t *db, - dns_dbupdate_callback_t fn, - void *fn_arg); -/*%< - * Register a notify-on-update callback function to a database. - * - * Requires: - * - * \li 'db' is a valid database - * \li 'db' does not have an update callback registered - * \li 'fn' is not NULL - * - */ - -isc_result_t -dns_db_updatenotify_unregister(dns_db_t *db, - dns_dbupdate_callback_t fn, - void *fn_arg); -/*%< - * Unregister a notify-on-update callback. - * - * Requires: - * - * \li 'db' is a valid database - * \li 'db' has update callback registered - * - */ - -isc_result_t -dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name); -/*%< - * Get the name associated with a database node. - * - * Requires: - * - * \li 'db' is a valid database - * \li 'node' and 'name' are not NULL - */ - -isc_result_t -dns_db_setservestalettl(dns_db_t *db, dns_ttl_t ttl); -/*%< - * Sets the maximum length of time that cached answers may be retained - * past their normal TTL. Default value for the library is 0, disabling - * the use of stale data. - * - * Requires: - * \li 'db' is a valid cache database. - * \li 'ttl' is the number of seconds to retain data past its normal expiry. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation. - */ - -isc_result_t -dns_db_getservestalettl(dns_db_t *db, dns_ttl_t *ttl); -/*%< - * Gets maximum length of time that cached answers may be kept past - * normal TTL expiration. - * - * Requires: - * \li 'db' is a valid cache database. - * \li 'ttl' is the number of seconds to retain data past its normal expiry. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DB_H */ diff --git a/lib/dns-pkcs11/include/dns/dbiterator.h b/lib/dns-pkcs11/include/dns/dbiterator.h deleted file mode 100644 index 9ed43c2..0000000 --- a/lib/dns-pkcs11/include/dns/dbiterator.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DBITERATOR_H -#define DNS_DBITERATOR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/dbiterator.h - * \brief - * The DNS DB Iterator interface allows iteration of all of the nodes in a - * database. - * - * The dns_dbiterator_t type is like a "virtual class". To actually use - * it, an implementation of the class is required. This implementation is - * supplied by the database. - * - * It is the client's responsibility to call dns_db_detachnode() on all - * nodes returned. - * - * XXX <more> XXX - * - * MP: - *\li The iterator itself is not locked. The caller must ensure - * synchronization. - * - *\li The iterator methods ensure appropriate database locking. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -/***** - ***** Imports - *****/ - -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Types - *****/ - -typedef struct dns_dbiteratormethods { - void (*destroy)(dns_dbiterator_t **iteratorp); - isc_result_t (*first)(dns_dbiterator_t *iterator); - isc_result_t (*last)(dns_dbiterator_t *iterator); - isc_result_t (*seek)(dns_dbiterator_t *iterator, dns_name_t *name); - isc_result_t (*prev)(dns_dbiterator_t *iterator); - isc_result_t (*next)(dns_dbiterator_t *iterator); - isc_result_t (*current)(dns_dbiterator_t *iterator, - dns_dbnode_t **nodep, dns_name_t *name); - isc_result_t (*pause)(dns_dbiterator_t *iterator); - isc_result_t (*origin)(dns_dbiterator_t *iterator, - dns_name_t *name); -} dns_dbiteratormethods_t; - -#define DNS_DBITERATOR_MAGIC ISC_MAGIC('D','N','S','I') -#define DNS_DBITERATOR_VALID(dbi) ISC_MAGIC_VALID(dbi, DNS_DBITERATOR_MAGIC) -/*% - * This structure is actually just the common prefix of a DNS db - * implementation's version of a dns_dbiterator_t. - * - * Clients may use the 'db' field of this structure. Except for that field, - * direct use of this structure by clients is forbidden. DB implementations - * may change the structure. 'magic' must be DNS_DBITERATOR_MAGIC for any of - * the dns_dbiterator routines to work. DB iterator implementations must - * maintain all DB iterator invariants. - */ -struct dns_dbiterator { - /* Unlocked. */ - unsigned int magic; - dns_dbiteratormethods_t * methods; - dns_db_t * db; - bool relative_names; - bool cleaning; -}; - -void -dns_dbiterator_destroy(dns_dbiterator_t **iteratorp); -/*%< - * Destroy '*iteratorp'. - * - * Requires: - * - *\li '*iteratorp' is a valid iterator. - * - * Ensures: - * - *\li All resources used by the iterator are freed. - * - *\li *iteratorp == NULL. - */ - -isc_result_t -dns_dbiterator_first(dns_dbiterator_t *iterator); -/*%< - * Move the node cursor to the first node in the database (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no nodes in the database. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_last(dns_dbiterator_t *iterator); -/*%< - * Move the node cursor to the last node in the database (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no nodes in the database. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); -/*%< - * Move the node cursor to the node with name 'name'. - * - * Requires: - *\li 'iterator' is a valid iterator. - * - *\li 'name' is a valid name. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOTFOUND - *\li #DNS_R_PARTIALMATCH - * (node is at name above requested named when name has children) - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_prev(dns_dbiterator_t *iterator); -/*%< - * Move the node cursor to the previous node in the database (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no more nodes in the - * database. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_next(dns_dbiterator_t *iterator); -/*%< - * Move the node cursor to the next node in the database (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no more nodes in the - * database. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, - dns_name_t *name); -/*%< - * Return the current node. - * - * Notes: - *\li If 'name' is not NULL, it will be set to the name of the node. - * - * Requires: - *\li 'iterator' is a valid iterator. - * - *\li nodep != NULL && *nodep == NULL - * - *\li The node cursor of 'iterator' is at a valid location (i.e. the - * result of last call to a cursor movement command was ISC_R_SUCCESS). - * - *\li 'name' is NULL, or is a valid name with a dedicated buffer. - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #DNS_R_NEWORIGIN If this iterator was created with - * 'relative_names' set to true, - * then #DNS_R_NEWORIGIN will be returned - * when the origin the names are - * relative to changes. This result - * can occur only when 'name' is not - * NULL. This is also a successful - * result. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_pause(dns_dbiterator_t *iterator); -/*%< - * Pause iteration. - * - * Calling a cursor movement method or dns_dbiterator_current() may cause - * database locks to be acquired. Rather than reacquire these locks every - * time one of these routines is called, the locks may simply be held. - * Calling dns_dbiterator_pause() releases any such locks. Iterator clients - * should call this routine any time they are not going to execute another - * iterator method in the immediate future. - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Ensures: - *\li Any database locks being held for efficiency of iterator access are - * released. - * - * Returns: - *\li #ISC_R_SUCCESS - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); -/*%< - * Return the origin to which returned node names are relative. - * - * Requires: - * - *\li 'iterator' is a valid relative_names iterator. - * - *\li 'name' is a valid name with a dedicated buffer. - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - * - *\li Other results are possible, depending on the DB implementation. - */ - -void -dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, bool mode); -/*%< - * Indicate that the given iterator is/is not cleaning the DB. - * - * Notes: - *\li When 'mode' is true, - * - * Requires: - *\li 'iterator' is a valid iterator. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DBITERATOR_H */ diff --git a/lib/dns-pkcs11/include/dns/dbtable.h b/lib/dns-pkcs11/include/dns/dbtable.h deleted file mode 100644 index b9756cd..0000000 --- a/lib/dns-pkcs11/include/dns/dbtable.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DBTABLE_H -#define DNS_DBTABLE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/dbtable.h - * \brief - * DNS DB Tables - * - * XXX TBS XXX - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li None. - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -#include - -#include - -#define DNS_DBTABLEFIND_NOEXACT 0x01 - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, - dns_dbtable_t **dbtablep); -/*%< - * Make a new dbtable of class 'rdclass' - * - * Requires: - *\li mctx != NULL - * \li dbtablep != NULL && *dptablep == NULL - *\li 'rdclass' is a valid class - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_UNEXPECTED - */ - -void -dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp); -/*%< - * Attach '*targetp' to 'source'. - * - * Requires: - * - *\li 'source' is a valid dbtable. - * - *\li 'targetp' points to a NULL dns_dbtable_t *. - * - * Ensures: - * - *\li *targetp is attached to source. - */ - -void -dns_dbtable_detach(dns_dbtable_t **dbtablep); -/*%< - * Detach *dbtablep from its dbtable. - * - * Requires: - * - *\li '*dbtablep' points to a valid dbtable. - * - * Ensures: - * - *\li *dbtablep is NULL. - * - *\li If '*dbtablep' is the last reference to the dbtable, - * all resources used by the dbtable will be freed - */ - -isc_result_t -dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db); -/*%< - * Add 'db' to 'dbtable'. - * - * Requires: - *\li 'dbtable' is a valid dbtable. - * - *\li 'db' is a valid database with the same class as 'dbtable' - */ - -void -dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db); -/*%< - * Remove 'db' from 'dbtable'. - * - * Requires: - *\li 'db' was previously added to 'dbtable'. - */ - -void -dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db); -/*%< - * Use 'db' as the result of a dns_dbtable_find() if no better match is - * available. - */ - -void -dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **db); -/*%< - * Get the 'db' used as the result of a dns_dbtable_find() - * if no better match is available. - */ - -void -dns_dbtable_removedefault(dns_dbtable_t *dbtable); -/*%< - * Remove the default db from 'dbtable'. - */ - -isc_result_t -dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, - unsigned int options, dns_db_t **dbp); -/*%< - * Find the deepest match to 'name' in the dbtable, and return it - * - * Notes: - *\li If the DNS_DBTABLEFIND_NOEXACT option is set, the best partial - * match (if any) to 'name' will be returned. - * - * Returns: - * \li #ISC_R_SUCCESS on success - *\li something else: no default and match - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DBTABLE_H */ diff --git a/lib/dns-pkcs11/include/dns/diff.h b/lib/dns-pkcs11/include/dns/diff.h deleted file mode 100644 index b75c9c0..0000000 --- a/lib/dns-pkcs11/include/dns/diff.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DIFF_H -#define DNS_DIFF_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/diff.h - * \brief - * A diff is a convenience type representing a list of changes to be - * made to a database. - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include - -/*** - *** Types - ***/ - -/*% - * A dns_difftuple_t represents a single RR being added or deleted. - * The RR type and class are in the 'rdata' member; the class is always - * the real one, not a DynDNS meta-class, so that the rdatas can be - * compared using dns_rdata_compare(). The TTL is significant - * even for deletions, because a deletion/addition pair cannot - * be canceled out if the TTL differs (it might be an explicit - * TTL update). - * - * Tuples are also used to represent complete RRs with owner - * names for a couple of other purposes, such as the - * individual RRs of a "RRset exists (value dependent)" - * prerequisite set. In this case, op==DNS_DIFFOP_EXISTS, - * and the TTL is ignored. - * - * DNS_DIFFOP_*RESIGN will cause the 'resign' attribute of the resulting - * RRset to be recomputed to be 'resign' seconds before the earliest RRSIG - * timeexpire. - */ - -typedef enum { - DNS_DIFFOP_ADD = 0, /*%< Add an RR. */ - DNS_DIFFOP_DEL = 1, /*%< Delete an RR. */ - DNS_DIFFOP_EXISTS = 2, /*%< Assert RR existence. */ - DNS_DIFFOP_ADDRESIGN = 4, /*%< ADD + RESIGN. */ - DNS_DIFFOP_DELRESIGN = 5 /*%< DEL + RESIGN. */ -} dns_diffop_t; - -typedef struct dns_difftuple dns_difftuple_t; - -#define DNS_DIFFTUPLE_MAGIC ISC_MAGIC('D','I','F','T') -#define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC) - -struct dns_difftuple { - unsigned int magic; - isc_mem_t *mctx; - dns_diffop_t op; - dns_name_t name; - dns_ttl_t ttl; - dns_rdata_t rdata; - ISC_LINK(dns_difftuple_t) link; - /* Variable-size name data and rdata follows. */ -}; - -/*% - * A dns_diff_t represents a set of changes being applied to - * a zone. Diffs are also used to represent "RRset exists - * (value dependent)" prerequisites. - */ -typedef struct dns_diff dns_diff_t; - -#define DNS_DIFF_MAGIC ISC_MAGIC('D','I','F','F') -#define DNS_DIFF_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFF_MAGIC) - -struct dns_diff { - unsigned int magic; - isc_mem_t * mctx; - ISC_LIST(dns_difftuple_t) tuples; -}; - -/* Type of comparison function for sorting diffs. */ -typedef int dns_diff_compare_func(const void *, const void *); - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -/**************************************************************************/ -/* - * Manipulation of diffs and tuples. - */ - -isc_result_t -dns_difftuple_create(isc_mem_t *mctx, - dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, - dns_rdata_t *rdata, dns_difftuple_t **tp); -/*%< - * Create a tuple. Deep copies are made of the name and rdata, so - * they need not remain valid after the call. - * - * Requires: - *\li *tp != NULL && *tp == NULL. - * - * Returns: - *\li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - */ - -void -dns_difftuple_free(dns_difftuple_t **tp); -/*%< - * Free a tuple. - * - * Requires: - * \li **tp is a valid tuple. - * - * Ensures: - * \li *tp == NULL - * \li All memory used by the tuple is freed. - */ - -isc_result_t -dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp); -/*%< - * Copy a tuple. - * - * Requires: - * \li 'orig' points to a valid tuple - *\li copyp != NULL && *copyp == NULL - */ - -void -dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff); -/*%< - * Initialize a diff. - * - * Requires: - * \li 'diff' points to an uninitialized dns_diff_t - * \li allocated by the caller. - * - * Ensures: - * \li '*diff' is a valid, empty diff. - */ - -void -dns_diff_clear(dns_diff_t *diff); -/*%< - * Clear a diff, destroying all its tuples. - * - * Requires: - * \li 'diff' points to a valid dns_diff_t. - * - * Ensures: - * \li Any tuples in the diff are destroyed. - * The diff now empty, but it is still valid - * and may be reused without calling dns_diff_init - * again. The only memory used is that of the - * dns_diff_t structure itself. - * - * Notes: - * \li Managing the memory of the dns_diff_t structure itself - * is the caller's responsibility. - */ - -void -dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple); -/*%< - * Append a single tuple to a diff. - * - *\li 'diff' is a valid diff. - * \li '*tuple' is a valid tuple. - * - * Ensures: - *\li *tuple is NULL. - *\li The tuple has been freed, or will be freed when the diff is cleared. - */ - -void -dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple); -/*%< - * Append 'tuple' to 'diff', removing any duplicate - * or conflicting updates as needed to create a minimal diff. - * - * Requires: - *\li 'diff' is a minimal diff. - * - * Ensures: - *\li 'diff' is still a minimal diff. - * \li *tuple is NULL. - * \li The tuple has been freed, or will be freed when the diff is cleared. - * - */ - -isc_result_t -dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare); -/*%< - * Sort 'diff' in-place according to the comparison function 'compare'. - */ - -isc_result_t -dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); -isc_result_t -dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); -/*%< - * Apply 'diff' to the database 'db'. - * - * dns_diff_apply() logs warnings about updates with no effect or - * with inconsistent TTLs; dns_diff_applysilently() does not. - * - * For efficiency, the diff should be sorted by owner name. - * If it is not sorted, operation will still be correct, - * but less efficient. - * - * Requires: - *\li *diff is a valid diff (possibly empty), containing - * tuples of type #DNS_DIFFOP_ADD and/or - * For #DNS_DIFFOP_DEL tuples, the TTL is ignored. - * - */ - -isc_result_t -dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc, - void *add_private); -/*%< - * Like dns_diff_apply, but for use when loading a new database - * instead of modifying an existing one. This bypasses the - * database transaction mechanisms. - * - * Requires: - *\li 'addfunc' is a valid dns_addradatasetfunc_t obtained from - * dns_db_beginload() - * - *\li 'add_private' points to a corresponding dns_dbload_t * - * (XXX why is it a void pointer, then?) - */ - -isc_result_t -dns_diff_print(dns_diff_t *diff, FILE *file); - -/*%< - * Print the differences to 'file' or if 'file' is NULL via the - * logging system. - * - * Require: - *\li 'diff' to be valid. - *\li 'file' to refer to a open file or NULL. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_UNEXPECTED - *\li any error from dns_rdataset_totext() - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DIFF_H */ diff --git a/lib/dns-pkcs11/include/dns/dispatch.h b/lib/dns-pkcs11/include/dns/dispatch.h deleted file mode 100644 index 9e6f886..0000000 --- a/lib/dns-pkcs11/include/dns/dispatch.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_DISPATCH_H -#define DNS_DISPATCH_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/dispatch.h - * \brief - * DNS Dispatch Management - * Shared UDP and single-use TCP dispatches for queries and responses. - * - * MP: - * - *\li All locking is performed internally to each dispatch. - * Restrictions apply to dns_dispatch_removeresponse(). - * - * Reliability: - * - * Resources: - * - * Security: - * - *\li Depends on the isc_socket_t and dns_message_t for prevention of - * buffer overruns. - * - * Standards: - * - *\li None. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*% - * This event is sent to a task when a response comes in. - * No part of this structure should ever be modified by the caller, - * other than parts of the buffer. The holy parts of the buffer are - * the base and size of the buffer. All other parts of the buffer may - * be used. On event delivery the used region contains the packet. - * - * "id" is the received message id, - * - * "addr" is the host that sent it to us, - * - * "buffer" holds state on the received data. - * - * The "free" routine for this event will clean up itself as well as - * any buffer space allocated from common pools. - */ - -struct dns_dispatchevent { - ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ - isc_result_t result; /*%< result code */ - int32_t id; /*%< message id */ - isc_sockaddr_t addr; /*%< address recv'd from */ - struct in6_pktinfo pktinfo; /*%< reply info for v6 */ - isc_buffer_t buffer; /*%< data buffer */ - uint32_t attributes; /*%< mirrored from socket.h */ -}; - -/*% - * This is a set of one or more dispatches which can be retrieved - * round-robin fashion. - */ -struct dns_dispatchset { - isc_mem_t *mctx; - dns_dispatch_t **dispatches; - int ndisp; - int cur; - isc_mutex_t lock; -}; - -/*@{*/ -/*% - * Attributes for added dispatchers. - * - * Values with the mask 0xffff0000 are application defined. - * Values with the mask 0x0000ffff are library defined. - * - * Insane values (like setting both TCP and UDP) are not caught. Don't - * do that. - * - * _PRIVATE - * The dispatcher cannot be shared. - * - * _TCP, _UDP - * The dispatcher is a TCP or UDP socket. - * - * _IPV4, _IPV6 - * The dispatcher uses an IPv4 or IPv6 socket. - * - * _NOLISTEN - * The dispatcher should not listen on the socket. - * - * _MAKEQUERY - * The dispatcher can be used to issue queries to other servers, and - * accept replies from them. - * - * _RANDOMPORT - * Previously used to indicate that the port of a dispatch UDP must be - * chosen randomly. This behavior now always applies and the attribute - * is obsoleted. - * - * _EXCLUSIVE - * A separate socket will be used on-demand for each transaction. - */ -#define DNS_DISPATCHATTR_PRIVATE 0x00000001U -#define DNS_DISPATCHATTR_TCP 0x00000002U -#define DNS_DISPATCHATTR_UDP 0x00000004U -#define DNS_DISPATCHATTR_IPV4 0x00000008U -#define DNS_DISPATCHATTR_IPV6 0x00000010U -#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U -#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U -#define DNS_DISPATCHATTR_CONNECTED 0x00000080U -#define DNS_DISPATCHATTR_FIXEDID 0x00000100U -#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U -/*@}*/ - -/* - */ -#define DNS_DISPATCHOPT_FIXEDID 0x00000001U - -isc_result_t -dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, - dns_dispatchmgr_t **mgrp); -/*%< - * Creates a new dispatchmgr object. - * - * Requires: - *\li "mctx" be a valid memory context. - * - *\li mgrp != NULL && *mgrp == NULL - * - *\li "entropy" may be NULL, in which case an insecure random generator - * will be used. If it is non-NULL, it must be a valid entropy - * source. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - - -void -dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp); -/*%< - * Destroys the dispatchmgr when it becomes empty. This could be - * immediately. - * - * Requires: - *\li mgrp != NULL && *mgrp is a valid dispatchmgr. - */ - - -void -dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole); -/*%< - * Sets the dispatcher's "blackhole list," a list of addresses that will - * be ignored by all dispatchers created by the dispatchmgr. - * - * Requires: - * \li mgrp is a valid dispatchmgr - * \li blackhole is a valid acl - */ - - -dns_acl_t * -dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr); -/*%< - * Gets a pointer to the dispatcher's current blackhole list, - * without incrementing its reference count. - * - * Requires: - *\li mgr is a valid dispatchmgr - * Returns: - *\li A pointer to the current blackhole list, or NULL. - */ - -void -dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, - dns_portlist_t *portlist); -/*%< - * This function is deprecated. Use dns_dispatchmgr_setavailports() instead. - * - * Requires: - *\li mgr is a valid dispatchmgr - */ - -dns_portlist_t * -dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr); -/*%< - * This function is deprecated and always returns NULL. - * - * Requires: - *\li mgr is a valid dispatchmgr - */ - -isc_result_t -dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, - isc_portset_t *v6portset); -/*%< - * Sets a list of UDP ports that can be used for outgoing UDP messages. - * - * Requires: - *\li mgr is a valid dispatchmgr - *\li v4portset is NULL or a valid port set - *\li v6portset is NULL or a valid port set - */ - -void -dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); -/*%< - * Sets statistics counter for the dispatchmgr. This function is expected to - * be called only on zone creation (when necessary). - * Once installed, it cannot be removed or replaced. Also, there is no - * interface to get the installed stats from the zone; the caller must keep the - * stats to reference (e.g. dump) it later. - * - * Requires: - *\li mgr is a valid dispatchmgr with no managed dispatch. - *\li stats is a valid statistics supporting resolver statistics counters - * (see dns/stats.h). - */ - -isc_result_t -dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp); - -isc_result_t -dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp, dns_dispatch_t *dup); -/*%< - * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, - * otherwise create a new UDP dispatch. - * - * Requires: - *\li All pointer parameters be valid for their respective types. - * - *\li dispp != NULL && *disp == NULL - * - *\li 512 <= buffersize <= 64k - * - *\li maxbuffers > 0 - * - *\li buckets < 2097169 - * - *\li increment > buckets - * - *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 - * - * Returns: - *\li ISC_R_SUCCESS -- success. - * - *\li Anything else -- failure. - */ - -isc_result_t -dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_taskmgr_t *taskmgr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp); -isc_result_t -dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, isc_socket_t *sock, - isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, - isc_sockaddr_t *destaddr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp); -/*%< - * Create a new dns_dispatch and attach it to the provided isc_socket_t. - * - * For all dispatches, "buffersize" is the maximum packet size we will - * accept. - * - * "maxbuffers" and "maxrequests" control the number of buffers in the - * overall system and the number of buffers which can be allocated to - * requests. - * - * "buckets" is the number of buckets to use, and should be prime. - * - * "increment" is used in a collision avoidance function, and needs to be - * a prime > buckets, and not 2. - * - * Requires: - * - *\li mgr is a valid dispatch manager. - * - *\li sock is a valid. - * - *\li task is a valid task that can be used internally to this dispatcher. - * - * \li 512 <= buffersize <= 64k - * - *\li maxbuffers > 0. - * - *\li maxrequests <= maxbuffers. - * - *\li buckets < 2097169 (the next prime after 65536 * 32) - * - *\li increment > buckets (and prime). - * - *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include - * #DNS_DISPATCHATTR_UDP. - * - * Returns: - *\li ISC_R_SUCCESS -- success. - * - *\li Anything else -- failure. - */ - -void -dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp); -/*%< - * Attach to a dispatch handle. - * - * Requires: - *\li disp is valid. - * - *\li dispp != NULL && *dispp == NULL - */ - -void -dns_dispatch_detach(dns_dispatch_t **dispp); -/*%< - * Detaches from the dispatch. - * - * Requires: - *\li dispp != NULL and *dispp be a valid dispatch. - */ - -void -dns_dispatch_starttcp(dns_dispatch_t *disp); -/*%< - * Start processing of a TCP dispatch once the socket connects. - * - * Requires: - *\li 'disp' is valid. - */ - -isc_result_t -dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, - isc_sockaddr_t *localaddr, dns_dispatch_t **dispp); -isc_result_t -dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, - isc_sockaddr_t *localaddr, bool *connected, - dns_dispatch_t **dispp); -/* - * Attempt to connect to a existing TCP connection (connection completed - * for dns_dispatch_gettcp()). - */ - - -isc_result_t -dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, - isc_sockaddr_t *dest, isc_task_t *task, - isc_taskaction_t action, void *arg, - uint16_t *idp, dns_dispentry_t **resp, - isc_socketmgr_t *sockmgr); - -isc_result_t -dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_task_t *task, isc_taskaction_t action, void *arg, - uint16_t *idp, dns_dispentry_t **resp, - isc_socketmgr_t *sockmgr); - -isc_result_t -dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_task_t *task, isc_taskaction_t action, void *arg, - uint16_t *idp, dns_dispentry_t **resp); -/*%< - * Add a response entry for this dispatch. - * - * "*idp" is filled in with the assigned message ID, and *resp is filled in - * to contain the magic token used to request event flow stop. - * - * Arranges for the given task to get a callback for response packets. When - * the event is delivered, it must be returned using dns_dispatch_freeevent() - * or through dns_dispatch_removeresponse() for another to be delivered. - * - * Requires: - *\li "idp" be non-NULL. - * - *\li "task" "action" and "arg" be set as appropriate. - * - *\li "dest" be non-NULL and valid. - * - *\li "resp" be non-NULL and *resp be NULL - * - *\li "sockmgr" be NULL or a valid socket manager. If 'disp' has - * the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL, - * which also means dns_dispatch_addresponse() cannot be used. - * - * Ensures: - * - *\li <id, dest> is a unique tuple. That means incoming messages - * are identifiable. - * - * Returns: - * - *\li ISC_R_SUCCESS -- all is well. - *\li ISC_R_NOMEMORY -- memory could not be allocated. - *\li ISC_R_NOMORE -- no more message ids can be allocated - * for this destination. - */ - - -void -dns_dispatch_removeresponse(dns_dispentry_t **resp, - dns_dispatchevent_t **sockevent); -/*%< - * Stops the flow of responses for the provided id and destination. - * If "sockevent" is non-NULL, the dispatch event and associated buffer is - * also returned to the system. - * - * Requires: - *\li "resp" != NULL and "*resp" contain a value previously allocated - * by dns_dispatch_addresponse(); - * - *\li May only be called from within the task given as the 'task' - * argument to dns_dispatch_addresponse() when allocating '*resp'. - */ - -isc_socket_t * -dns_dispatch_getentrysocket(dns_dispentry_t *resp); - -isc_socket_t * -dns_dispatch_getsocket(dns_dispatch_t *disp); -/*%< - * Return the socket associated with this dispatcher. - * - * Requires: - *\li disp is valid. - * - * Returns: - *\li The socket the dispatcher is using. - */ - -isc_result_t -dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp); -/*%< - * Return the local address for this dispatch. - * This currently only works for dispatches using UDP sockets. - * - * Requires: - *\li disp is valid. - *\li addrp to be non null. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOTIMPLEMENTED - */ - -void -dns_dispatch_cancel(dns_dispatch_t *disp); -/*%< - * cancel outstanding clients - * - * Requires: - *\li disp is valid. - */ - -unsigned int -dns_dispatch_getattributes(dns_dispatch_t *disp); -/*%< - * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the - * non-changeable attributes are expected to be referenced by the caller. - * - * Requires: - *\li disp is valid. - */ - -void -dns_dispatch_changeattributes(dns_dispatch_t *disp, - unsigned int attributes, unsigned int mask); -/*%< - * Set the bits described by "mask" to the corresponding values in - * "attributes". - * - * That is: - * - * \code - * new = (old & ~mask) | (attributes & mask) - * \endcode - * - * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. - * When the flag becomes off, the dispatch will start receiving on the - * corresponding socket. When the flag becomes on, receive events on the - * corresponding socket will be canceled. - * - * Requires: - *\li disp is valid. - * - *\li attributes are reasonable for the dispatch. That is, setting the UDP - * attribute on a TCP socket isn't reasonable. - */ - -void -dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event); -/*%< - * Inform the dispatcher of a socket receive. This is used for sockets - * shared between dispatchers and clients. If the dispatcher fails to copy - * or send the event, nothing happens. - * - * If the attribute DNS_DISPATCHATTR_NOLISTEN is not set, then - * the dispatch is already handling a recv; return immediately. - * - * Requires: - *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. - * event != NULL - */ - -dns_dispatch_t * -dns_dispatchset_get(dns_dispatchset_t *dset); -/*%< - * Retrieve the next dispatch from dispatch set 'dset', and increment - * the round-robin counter. - * - * Requires: - *\li dset != NULL - */ - -isc_result_t -dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, - isc_taskmgr_t *taskmgr, dns_dispatch_t *source, - dns_dispatchset_t **dsetp, int n); -/*%< - * Given a valid dispatch 'source', create a dispatch set containing - * 'n' UDP dispatches, with the remainder filled out by clones of the - * source. - * - * Requires: - *\li source is a valid UDP dispatcher - *\li dsetp != NULL, *dsetp == NULL - */ - -void -dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); -/*%< - * Cancel socket operations for the dispatches in 'dset'. - */ - -void -dns_dispatchset_destroy(dns_dispatchset_t **dsetp); -/*%< - * Dereference all the dispatches in '*dsetp', free the dispatchset - * memory, and set *dsetp to NULL. - * - * Requires: - *\li dset is valid - */ - -void -dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp); -isc_dscp_t -dns_dispatch_getdscp(dns_dispatch_t *disp); -/*%< - * Set/get the DSCP value to be used when sending responses to clients, - * as defined in the "listen-on" or "listen-on-v6" statements. - * - * Requires: - *\li disp is valid. - */ - -isc_result_t -dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent); -/*%< - * Free the sockevent and trigger the sending of the next item off the - * dispatch queue if present. - * - * Requires: - *\li resp is valid - *\li *sockevent to be valid - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DISPATCH_H */ diff --git a/lib/dns-pkcs11/include/dns/dlz.h b/lib/dns-pkcs11/include/dns/dlz.h deleted file mode 100644 index 2ee613b..0000000 --- a/lib/dns-pkcs11/include/dns/dlz.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. - * - * 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 STICHTING NLNET - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * STICHTING NLNET 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. - * - * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was - * conceived and contributed by Rob Butler. - * - * 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 ROB BUTLER - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * ROB BUTLER 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. - */ - - -/*! \file dns/dlz.h */ - -#ifndef DLZ_H -#define DLZ_H 1 - -/***** - ***** Module Info - *****/ - -/* - * DLZ Interface - * - * The DLZ interface allows zones to be looked up using a driver instead of - * Bind's default in memory zone table. - * - * - * Reliability: - * No anticipated impact. - * - * Resources: - * - * Security: - * No anticipated impact. - * - * Standards: - * None. - */ - -/***** - ***** Imports - *****/ - -#include - -#include -#include -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -#define DNS_DLZ_MAGIC ISC_MAGIC('D','L','Z','D') -#define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC) - -typedef isc_result_t -(*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_name_t *name, - isc_sockaddr_t *clientaddr, - dns_db_t **dbp); - -/*%< - * Method prototype. Drivers implementing the DLZ interface MUST - * supply an allow zone transfer method. This method is called when - * the DNS server is performing a zone transfer query. The driver's - * method should return ISC_R_SUCCESS and a database pointer to the - * name server if the zone is supported by the database, and zone - * transfer is allowed. Otherwise it will return ISC_R_NOTFOUND if - * the zone is not supported by the database, or ISC_R_NOPERM if zone - * transfers are not allowed. If an error occurs it should return a - * result code indicating the type of error. - */ - -typedef isc_result_t -(*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname, unsigned int argc, - char *argv[], void *driverarg, void **dbdata); - -/*%< - * Method prototype. Drivers implementing the DLZ interface MUST - * supply a create method. This method is called when the DNS server - * is starting up and creating drivers for use later. - */ - -typedef void -(*dns_dlzdestroy_t)(void *driverarg, void **dbdata); - -/*%< - * Method prototype. Drivers implementing the DLZ interface MUST - * supply a destroy method. This method is called when the DNS server - * is shutting down and no longer needs the driver. - */ - -typedef isc_result_t -(*dns_dlzfindzone_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_name_t *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_db_t **dbp); - -/*%< - * Method prototype. Drivers implementing the DLZ interface MUST - * supply a find zone method. This method is called when the DNS - * server is performing a query. The find zone method will be called - * with the longest possible name first, and continue to be called - * with successively shorter domain names, until any of the following - * occur: - * - * \li 1) a match is found, and the function returns (ISC_R_SUCCESS) - * - * \li 2) a problem occurs, and the functions returns anything other - * than (ISC_R_NOTFOUND) - * \li 3) we run out of domain name labels. I.E. we have tried the - * shortest domain name - * \li 4) the number of labels in the domain name is less than - * min_labels for dns_dlzfindzone - * - * The driver's find zone method should return ISC_R_SUCCESS and a - * database pointer to the name server if the zone is supported by the - * database. Otherwise it will return ISC_R_NOTFOUND, and a null - * pointer if the zone is not supported. If an error occurs it should - * return a result code indicating the type of error. - */ - - -typedef isc_result_t -(*dns_dlzconfigure_t)(void *driverarg, void *dbdata, - dns_view_t *view, dns_dlzdb_t *dlzdb); -/*%< - * Method prototype. Drivers implementing the DLZ interface may - * optionally supply a configure method. If supplied, this will be - * called immediately after the create method is called. The driver - * may call configuration functions during the configure call - */ - - -typedef bool (*dns_dlzssumatch_t)(dns_name_t *signer, - dns_name_t *name, - isc_netaddr_t *tcpaddr, - dns_rdatatype_t type, - const dst_key_t *key, - void *driverarg, void *dbdata); -/*%< - * Method prototype. Drivers implementing the DLZ interface may - * optionally supply a ssumatch method. If supplied, this will be - * called to authorize update requests - */ - -/*% the methods supplied by a DLZ driver */ -typedef struct dns_dlzmethods { - dns_dlzcreate_t create; - dns_dlzdestroy_t destroy; - dns_dlzfindzone_t findzone; - dns_dlzallowzonexfr_t allowzonexfr; - dns_dlzconfigure_t configure; - dns_dlzssumatch_t ssumatch; -} dns_dlzmethods_t; - -/*% information about a DLZ driver */ -struct dns_dlzimplementation { - const char *name; - const dns_dlzmethods_t *methods; - isc_mem_t *mctx; - void *driverarg; - ISC_LINK(dns_dlzimplementation_t) link; -}; - -typedef isc_result_t (*dlzconfigure_callback_t)(dns_view_t *, dns_dlzdb_t *, - dns_zone_t *); - -/*% An instance of a DLZ driver */ -struct dns_dlzdb { - unsigned int magic; - isc_mem_t *mctx; - dns_dlzimplementation_t *implementation; - void *dbdata; - dlzconfigure_callback_t configure_callback; - bool search; - char *dlzname; - ISC_LINK(dns_dlzdb_t) link; - dns_ssutable_t *ssutable; -}; - - -/*** - *** Method declarations - ***/ - -isc_result_t -dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, - isc_sockaddr_t *clientaddr, dns_db_t **dbp); - -/*%< - * This method is called when the DNS server is performing a zone - * transfer query. It will call the DLZ driver's allow zone transfer - * method. - */ - -isc_result_t -dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, - const char *drivername, unsigned int argc, - char *argv[], dns_dlzdb_t **dbp); - -/*%< - * This method is called when the DNS server is starting up and - * creating drivers for use later. It will search the DLZ driver list - * for 'drivername' and return a DLZ driver via dbp if a match is - * found. If the DLZ driver supplies a create method, this function - * will call it. - */ - -void -dns_dlzdestroy(dns_dlzdb_t **dbp); - -/*%< - * This method is called when the DNS server is shutting down and no - * longer needs the driver. If the DLZ driver supplies a destroy - * methods, this function will call it. - */ - -isc_result_t -dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, - void *driverarg, isc_mem_t *mctx, - dns_dlzimplementation_t **dlzimp); - -/*%< - * Register a dynamically loadable zones (DLZ) driver for the database - * type 'drivername', implemented by the functions in '*methods'. - * - * dlzimp must point to a NULL dlz_implementation_t pointer. That is, - * dlzimp != NULL && *dlzimp == NULL. It will be assigned a value that - * will later be used to identify the driver when deregistering it. - */ - -isc_result_t -dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp); - -/*%< - * This method is called when the name server is starting up to parse - * the DLZ driver command line from named.conf. Basically it splits - * up a string into and argc / argv. The primary difference of this - * method is items between braces { } are considered only 1 word. for - * example the command line "this is { one grouped phrase } and this - * isn't" would be parsed into: - * - * \li argv[0]: "this" - * \li argv[1]: "is" - * \li argv{2]: " one grouped phrase " - * \li argv[3]: "and" - * \li argv[4]: "this" - * \li argv{5}: "isn't" - * - * braces should NOT be nested, more than one grouping in the command - * line is allowed. Notice, argv[2] has an extra space at the - * beginning and end. Extra spaces are not stripped between a - * grouping. You can do so in your driver if needed, or be sure not - * to put extra spaces before / after the braces. - */ - -void -dns_dlzunregister(dns_dlzimplementation_t **dlzimp); - -/*%< - * Removes the dlz driver from the list of registered dlz drivers. - * There must be no active dlz drivers of this type when this function - * is called. - */ - - -typedef isc_result_t dns_dlz_writeablezone_t(dns_view_t *view, - dns_dlzdb_t *dlzdb, - const char *zone_name); -dns_dlz_writeablezone_t dns_dlz_writeablezone; -/*%< - * creates a writeable DLZ zone. Must be called from within the - * configure() method of a DLZ driver. - */ - - -isc_result_t -dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb, - dlzconfigure_callback_t callback); -/*%< - * call a DLZ drivers configure method, if supplied - */ - -bool -dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, - dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, - dns_rdatatype_t type, const dst_key_t *key); -/*%< - * call a DLZ drivers ssumatch method, if supplied. Otherwise return false - */ - -ISC_LANG_ENDDECLS - -#endif /* DLZ_H */ diff --git a/lib/dns-pkcs11/include/dns/dlz_dlopen.h b/lib/dns-pkcs11/include/dns/dlz_dlopen.h deleted file mode 100644 index 2efd39b..0000000 --- a/lib/dns-pkcs11/include/dns/dlz_dlopen.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file dns/dlz_dlopen.h */ - -#ifndef DLZ_DLOPEN_H -#define DLZ_DLOPEN_H - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/* - * This header provides a minimal set of defines and typedefs needed - * for the entry points of an external DLZ module for bind9. - */ - -#define DLZ_DLOPEN_VERSION 3 -#define DLZ_DLOPEN_AGE 0 - -/* - * dlz_dlopen_version() is required for all DLZ external drivers. It - * should return DLZ_DLOPEN_VERSION - */ -typedef int dlz_dlopen_version_t(unsigned int *flags); - -/* - * dlz_dlopen_create() is required for all DLZ external drivers. - */ -typedef isc_result_t dlz_dlopen_create_t(const char *dlzname, - unsigned int argc, - char *argv[], - void **dbdata, - ...); - -/* - * dlz_dlopen_destroy() is optional, and will be called when the - * driver is unloaded if supplied - */ -typedef void dlz_dlopen_destroy_t(void *dbdata); - -/* - * dlz_dlopen_findzonedb() is required for all DLZ external drivers - */ -typedef isc_result_t dlz_dlopen_findzonedb_t(void *dbdata, - const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); - -/* - * dlz_dlopen_lookup() is required for all DLZ external drivers - */ -typedef isc_result_t dlz_dlopen_lookup_t(const char *zone, - const char *name, - void *dbdata, - dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); - -/* - * dlz_dlopen_authority is optional() if dlz_dlopen_lookup() - * supplies authority information for the dns record - */ -typedef isc_result_t dlz_dlopen_authority_t(const char *zone, - void *dbdata, - dns_sdlzlookup_t *lookup); - -/* - * dlz_dlopen_allowzonexfr() is optional, and should be supplied if - * you want to support zone transfers - */ -typedef isc_result_t dlz_dlopen_allowzonexfr_t(void *dbdata, - const char *name, - const char *client); - -/* - * dlz_dlopen_allnodes() is optional, but must be supplied if supply a - * dlz_dlopen_allowzonexfr() function - */ -typedef isc_result_t dlz_dlopen_allnodes_t(const char *zone, - void *dbdata, - dns_sdlzallnodes_t *allnodes); - -/* - * dlz_dlopen_newversion() is optional. It should be supplied if you - * want to support dynamic updates. - */ -typedef isc_result_t dlz_dlopen_newversion_t(const char *zone, - void *dbdata, - void **versionp); - -/* - * dlz_closeversion() is optional, but must be supplied if you supply - * a dlz_newversion() function - */ -typedef void dlz_dlopen_closeversion_t(const char *zone, - bool commit, - void *dbdata, - void **versionp); - -/* - * dlz_dlopen_configure() is optional, but must be supplied if you - * want to support dynamic updates - */ -typedef isc_result_t dlz_dlopen_configure_t(dns_view_t *view, - dns_dlzdb_t *dlzdb, - void *dbdata); - -/* - * dlz_dlopen_setclientcallback() is optional, but must be supplied if you - * want to retrieve information about the client (e.g., source address) - * before sending a replay. - */ -typedef isc_result_t dlz_dlopen_setclientcallback_t(dns_view_t *view, - void *dbdata); - - -/* - * dlz_dlopen_ssumatch() is optional, but must be supplied if you want - * to support dynamic updates - */ -typedef bool dlz_dlopen_ssumatch_t(const char *signer, - const char *name, - const char *tcpaddr, - const char *type, - const char *key, - uint32_t keydatalen, - unsigned char *keydata, - void *dbdata); - -/* - * dlz_dlopen_addrdataset() is optional, but must be supplied if you - * want to support dynamic updates - */ -typedef isc_result_t dlz_dlopen_addrdataset_t(const char *name, - const char *rdatastr, - void *dbdata, - void *version); - -/* - * dlz_dlopen_subrdataset() is optional, but must be supplied if you - * want to support dynamic updates - */ -typedef isc_result_t dlz_dlopen_subrdataset_t(const char *name, - const char *rdatastr, - void *dbdata, - void *version); - -/* - * dlz_dlopen_delrdataset() is optional, but must be supplied if you - * want to support dynamic updates - */ -typedef isc_result_t dlz_dlopen_delrdataset_t(const char *name, - const char *type, - void *dbdata, - void *version); - -ISC_LANG_ENDDECLS - -#endif diff --git a/lib/dns-pkcs11/include/dns/dns64.h b/lib/dns-pkcs11/include/dns/dns64.h deleted file mode 100644 index 7fa0be5..0000000 --- a/lib/dns-pkcs11/include/dns/dns64.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DNS64_H -#define DNS_DNS64_H 1 - -#include - -#include - -#include - -ISC_LANG_BEGINDECLS - -/* - * dns_dns64_create() flags. - */ -#define DNS_DNS64_RECURSIVE_ONLY 0x01 /* If set then this record - * only applies to recursive - * queries. - */ -#define DNS_DNS64_BREAK_DNSSEC 0x02 /* If set then still perform - * DNSSEC synthesis even - * though the result would - * fail validation. - */ - -/* - * dns_dns64_aaaaok() and dns_dns64_aaaafroma() flags. - */ -#define DNS_DNS64_RECURSIVE 0x01 /* Recursive query. */ -#define DNS_DNS64_DNSSEC 0x02 /* DNSSEC sensitive query. */ - -isc_result_t -dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix, - unsigned int prefixlen, isc_netaddr_t *suffix, - dns_acl_t *client, dns_acl_t *mapped, dns_acl_t *excluded, - unsigned int flags, dns_dns64_t **dns64); -/* - * Create a dns64 record which is used to identify the set of clients - * it applies to and how to perform the DNS64 synthesis. - * - * 'prefix' and 'prefixlen' defined the leading bits of the AAAA records - * to be synthesised. 'suffix' defines the bits after the A records bits. - * If suffix is NULL zeros will be used for these bits. 'client' defines - * for which clients this record applies. If 'client' is NULL then all - * clients apply. 'mapped' defines which A records are candidated for - * mapping. If 'mapped' is NULL then all A records will be mapped. - * 'excluded' defines which AAAA are to be treated as non-existent for the - * purposed of determining whether to perform synthesis. If 'excluded' is - * NULL then no AAAA records prevent synthesis. - * - * If DNS_DNS64_RECURSIVE_ONLY is set then the record will only match if - * DNS_DNS64_RECURSIVE is set when calling dns_dns64_aaaaok() and - * dns_dns64_aaaafroma(). - * - * If DNS_DNS64_BREAK_DNSSEC is set then the record will still apply if - * DNS_DNS64_DNSSEC is set when calling dns_dns64_aaaaok() and - * dns_dns64_aaaafroma() otherwise the record will be ignored. - * - * Requires: - * 'mctx' to be valid. - * 'prefix' to be valid and the address family to AF_INET6. - * 'prefixlen' to be one of 32, 40, 48, 56, 72 and 96. - * the bits not covered by prefixlen in prefix to - * be zero. - * 'suffix' to be NULL or the address family be set to AF_INET6 - * and the leading 'prefixlen' + 32 bits of the 'suffix' - * to be zero. If 'prefixlen' is 40, 48 or 56 then the - * the leading 'prefixlen' + 40 bits of 'suffix' must be - * zero. - * 'client' to be NULL or a valid acl. - * 'mapped' to be NULL or a valid acl. - * 'excluded' to be NULL or a valid acl. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -void -dns_dns64_destroy(dns_dns64_t **dns64p); -/* - * Destroys a dns64 record. - * - * Requires the record to not be linked. - */ - -isc_result_t -dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, const dns_aclenv_t *env, - unsigned int flags, unsigned char *a, unsigned char *aaaa); -/* - * dns_dns64_aaaafroma() determines whether to perform a DNS64 address - * synthesis from 'a' based on 'dns64', 'reqaddr', 'reqsigner', 'env', - * 'flags' and 'aaaa'. If synthesis is performed then the result is - * written to '*aaaa'. - * - * The synthesised address will be of the form: - * - * - * - * If straddle bits 64-71 of the AAAA record, then 8 zero bits will - * be inserted at bits 64-71. - * - * Requires: - * 'dns64' to be valid. - * 'reqaddr' to be valid. - * 'reqsigner' to be NULL or valid. - * 'env' to be valid. - * 'a' to point to a IPv4 address in network order. - * 'aaaa' to point to a IPv6 address buffer in network order. - * - * Returns: - * ISC_R_SUCCESS if synthesis was performed. - * DNS_R_DISALLOWED if there is no match. - */ - -dns_dns64_t * -dns_dns64_next(dns_dns64_t *dns64); -/* - * Return the next dns64 record in the list. - */ - -void -dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64); -/* - * Append the dns64 record to the list. - */ - -void -dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64); -/* - * Unlink the dns64 record from the list. - */ - -bool -dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, - const dns_name_t *reqsigner, const dns_aclenv_t *env, - unsigned int flags, dns_rdataset_t *rdataset, - bool *aaaaok, size_t aaaaoklen); -/* - * Determine if there are any non-excluded AAAA records in from the - * matching dns64 records in the list starting at 'dns64'. If there - * is a non-excluded address return true. If all addresses are - * excluded in the matched records return false. If no records - * match then return true. - * - * If aaaaok is defined then dns_dns64_aaaaok() return a array of which - * addresses in 'rdataset' were deemed to not be exclude by any matching - * record. If there are no matching records then all entries are set - * to true. - * - * Requires - * 'rdataset' to be valid and to be for type AAAA and class IN. - * 'aaaaoklen' must match the number of records in 'rdataset' - * if 'aaaaok' in non NULL. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DNS64_H */ diff --git a/lib/dns-pkcs11/include/dns/dnssec.h b/lib/dns-pkcs11/include/dns/dnssec.h deleted file mode 100644 index 31e2586..0000000 --- a/lib/dns-pkcs11/include/dns/dnssec.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DNSSEC_H -#define DNS_DNSSEC_H 1 - -/*! \file dns/dnssec.h */ - -#include - -#include -#include -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats; - -/*%< Maximum number of keys supported in a zone. */ -#define DNS_MAXZONEKEYS 32 - -/* - * Indicates how the signer found this key: in the key repository, at the - * zone apex, or specified by the user. - */ -typedef enum { - dns_keysource_unknown, - dns_keysource_repository, - dns_keysource_zoneapex, - dns_keysource_user -} dns_keysource_t; - -/* - * A DNSSEC key and hints about its intended use gleaned from metadata - */ -struct dns_dnsseckey { - dst_key_t *key; - bool hint_publish; /*% metadata says to publish */ - bool force_publish; /*% publish regardless of metadata */ - bool hint_sign; /*% metadata says to sign with this key */ - bool force_sign; /*% sign with key regardless of metadata */ - bool hint_remove; /*% metadata says *don't* publish */ - bool is_active; /*% key is already active */ - bool first_sign; /*% key is newly becoming active */ - unsigned int prepublish; /*% how long until active? */ - dns_keysource_t source; /*% how the key was found */ - bool ksk; /*% this is a key-signing key */ - bool legacy; /*% this is old-style key with no - metadata (possibly generated by - an older version of BIND9) and - should be ignored when searching - for keys to import into the zone */ - unsigned int index; /*% position in list */ - ISC_LINK(dns_dnsseckey_t) link; -}; - -isc_result_t -dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, - dst_key_t **key); -/*%< - * Creates a DST key from a DNS record. Basically a wrapper around - * dst_key_fromdns(). - * - * Requires: - *\li 'name' is not NULL - *\li 'rdata' is not NULL - *\li 'mctx' is not NULL - *\li 'key' is not NULL - *\li '*key' is NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li DST_R_INVALIDPUBLICKEY - *\li various errors from dns_name_totext - */ - -isc_result_t -dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - isc_stdtime_t *inception, isc_stdtime_t *expire, - isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); -/*%< - * Generates a RRSIG record covering this rdataset. This has no effect - * on existing RRSIG records. - * - * Requires: - *\li 'name' (the owner name of the record) is a valid name - *\li 'set' is a valid rdataset - *\li 'key' is a valid key - *\li 'inception' is not NULL - *\li 'expire' is not NULL - *\li 'mctx' is not NULL - *\li 'buffer' is not NULL - *\li 'sigrdata' is not NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_NOSPACE - *\li #DNS_R_INVALIDTIME - the expiration is before the inception - *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either - * it is not a zone key or its flags prevent - * authentication) - *\li DST_R_* - */ - -isc_result_t -dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, isc_mem_t *mctx, - dns_rdata_t *sigrdata); - -isc_result_t -dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, isc_mem_t *mctx, - dns_rdata_t *sigrdata, dns_name_t *wild); - -isc_result_t -dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, - bool ignoretime, unsigned int maxbits, - isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); -/*%< - * Verifies the RRSIG record covering this rdataset signed by a specific - * key. This does not determine if the key's owner is authorized to sign - * this record, as this requires a resolver or database. - * If 'ignoretime' is true, temporal validity will not be checked. - * - * 'maxbits' specifies the maximum number of rsa exponent bits accepted. - * - * Requires: - *\li 'name' (the owner name of the record) is a valid name - *\li 'set' is a valid rdataset - *\li 'key' is a valid key - *\li 'mctx' is not NULL - *\li 'sigrdata' is a valid rdata containing a SIG record - *\li 'wild' if non-NULL then is a valid and has a buffer. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #DNS_R_FROMWILDCARD - the signature is valid and is from - * a wildcard expansion. dns_dnssec_verify2() only. - * 'wild' contains the name of the wildcard if non-NULL. - *\li #DNS_R_SIGINVALID - the signature fails to verify - *\li #DNS_R_SIGEXPIRED - the signature has expired - *\li #DNS_R_SIGFUTURE - the signature's validity period has not begun - *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either - * it is not a zone key or its flags prevent - * authentication) - *\li DST_R_* - */ - -/*@{*/ -isc_result_t -dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, - dns_name_t *name, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys); - -isc_result_t -dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys); - -isc_result_t -dns_dnssec_findzonekeys3(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_stdtime_t now, - isc_mem_t *mctx, unsigned int maxkeys, - dst_key_t **keys, unsigned int *nkeys); - -/*%< - * Finds a set of zone keys. - * XXX temporary - this should be handled in dns_zone_t. - */ -/*@}*/ - -bool -dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now); -/*%< - * - * Returns true if 'key' is active as of the time specified - * in 'now' (i.e., if the activation date has passed, inactivation or - * deletion date has not yet been reached, and the key is not revoked - * -- or if it is a legacy key without metadata). Otherwise returns - * false. - * - * Requires: - *\li 'key' is a valid key - */ - -isc_result_t -dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key); -/*%< - * Signs a message with a SIG(0) record. This is implicitly called by - * dns_message_renderend() if msg->sig0key is not NULL. - * - * Requires: - *\li 'msg' is a valid message - *\li 'key' is a valid key that can be used for signing - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li DST_R_* - */ - -isc_result_t -dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, - dst_key_t *key); -/*%< - * Verifies a message signed by a SIG(0) record. This is not - * called implicitly by dns_message_parse(). If dns_message_signer() - * is called before dns_dnssec_verifymessage(), it will return - * #DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set - * the verified_sig0 flag in msg if the verify succeeds, and - * the sig0status field otherwise. - * - * Requires: - *\li 'source' is a valid buffer containing the unparsed message - *\li 'msg' is a valid message - *\li 'key' is a valid key - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_NOTFOUND - no SIG(0) was found - *\li #DNS_R_SIGINVALID - the SIG record is not well-formed or - * was not generated by the key. - *\li DST_R_* - */ - -bool -dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - bool ignoretime, isc_mem_t *mctx); - - -bool -dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - bool ignoretime, isc_mem_t *mctx); -/*%< - * Verify that 'rdataset' is validly signed in 'sigrdataset' by - * the key in 'rdata'. - * - * dns_dnssec_selfsigns() requires that rdataset be a DNSKEY or KEY - * rrset. dns_dnssec_signs() works on any rrset. - */ - - -isc_result_t -dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey, - dns_dnsseckey_t **dkp); -/*%< - * Create and initialize a dns_dnsseckey_t structure. - * - * Requires: - *\li 'dkp' is not NULL and '*dkp' is NULL. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -void -dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp); -/*%< - * Reclaim a dns_dnsseckey_t structure. - * - * Requires: - *\li 'dkp' is not NULL and '*dkp' is not NULL. - * - * Ensures: - *\li '*dkp' is NULL. - */ - -isc_result_t -dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, - isc_mem_t *mctx, dns_dnsseckeylist_t *keylist); - -isc_result_t -dns_dnssec_findmatchingkeys2(dns_name_t *origin, const char *directory, - isc_stdtime_t now, isc_mem_t *mctx, - dns_dnsseckeylist_t *keylist); -/*%< - * Search 'directory' for K* key files matching the name in 'origin'. - * Append all such keys, along with use hints gleaned from their - * metadata, onto 'keylist'. Skip any unsupported algorithms. - * - * Requires: - *\li 'keylist' is not NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOTFOUND - *\li #ISC_R_NOMEMORY - *\li any error returned by dns_name_totext(), isc_dir_open(), or - * dst_key_fromnamedfile() - * - * Ensures: - *\li On error, keylist is unchanged - */ - -isc_result_t -dns_dnssec_keylistfromrdataset(dns_name_t *origin, - const char *directory, isc_mem_t *mctx, - dns_rdataset_t *keyset, dns_rdataset_t *keysigs, - dns_rdataset_t *soasigs, bool savekeys, - bool publickey, - dns_dnsseckeylist_t *keylist); -/*%< - * Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'. - * Omit duplicates. If 'publickey' is false, search 'directory' for - * matching key files, and load the private keys that go with - * the public ones. If 'savekeys' is true, mark the keys so - * they will not be deleted or inactivated regardless of metadata. - * - * 'keysigs' and 'soasigs', if not NULL and associated, contain the - * RRSIGS for the DNSKEY and SOA records respectively and are used to mark - * whether a key is already active in the zone. - */ - -isc_result_t -dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, - dns_dnsseckeylist_t *removed, dns_name_t *origin, - dns_ttl_t hint_ttl, dns_diff_t *diff, bool allzsk, - isc_mem_t *mctx, void (*report)(const char *, ...)); -/*%< - * Update the list of keys in 'keys' with new key information in 'newkeys'. - * - * For each key in 'newkeys', see if it has a match in 'keys'. - * - If not, and if the metadata says the key should be published: - * add it to 'keys', and place a dns_difftuple into 'diff' so - * the key can be added to the DNSKEY set. If the metadata says it - * should be active, set the first_sign flag. - * - If so, and if the metadata says it should be removed: - * remove it from 'keys', and place a dns_difftuple into 'diff' so - * the key can be removed from the DNSKEY set. if 'removed' is non-NULL, - * copy the key into that list; otherwise destroy it. - * - Otherwise, make sure keys has current metadata. - * - * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as - * ZSKs. - * - * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no - * existing RRset, and if none of the keys to be added has a default TTL - * (in which case we would use the shortest one). If the TTL is longer - * than the time until a new key will be activated, then we have to delay - * the key's activation. - * - * 'report' points to a function for reporting status. - * - * On completion, any remaining keys in 'newkeys' are freed. - */ - -isc_result_t -dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, - dns_rdataset_t *cds, dns_rdataset_t *cdnskey, - isc_stdtime_t now, dns_ttl_t hint_ttl, dns_diff_t *diff, - isc_mem_t *mctx); -/*%< - * Update the CDS and CDNSKEY RRsets, adding and removing keys as needed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DNSSEC_H */ diff --git a/lib/dns-pkcs11/include/dns/dnstap.h b/lib/dns-pkcs11/include/dns/dnstap.h deleted file mode 100644 index 1ba6001..0000000 --- a/lib/dns-pkcs11/include/dns/dnstap.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef _DNSTAP_H -#define _DNSTAP_H - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The dt (dnstap) module provides fast passive logging of DNS messages. - * Protocol Buffers. The protobuf schema for Dnstap messages is in the - * file dnstap.proto, which is compiled to dnstap.pb-c.c and dnstap.pb-c.h. - */ - -#include -#include - -#ifdef HAVE_DNSTAP -#include -#include -#else -struct fstrm_iothr_options; -#endif /* HAVE_DNSTAP */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -/*% - * Dnstap message types: - * - * STUB QUERY: SQ - * STUB RESPONSE: SR - * CLIENT QUERY: CQ - * CLIENT RESPONSE: CR - * AUTH QUERY: AQ - * AUTH RESPONSE: AR - * RESOLVER QUERY: RQ - * RESOLVER RESPONSE: RR - * FORWARDER QUERY: FQ - * FORWARDER RESPONSE: FR - */ - -#define DNS_DTTYPE_SQ 0x0001 -#define DNS_DTTYPE_SR 0x0002 -#define DNS_DTTYPE_CQ 0x0004 -#define DNS_DTTYPE_CR 0x0008 -#define DNS_DTTYPE_AQ 0x0010 -#define DNS_DTTYPE_AR 0x0020 -#define DNS_DTTYPE_RQ 0x0040 -#define DNS_DTTYPE_RR 0x0080 -#define DNS_DTTYPE_FQ 0x0100 -#define DNS_DTTYPE_FR 0x0200 -#define DNS_DTTYPE_TQ 0x0400 -#define DNS_DTTYPE_TR 0x0800 - -#define DNS_DTTYPE_QUERY \ - (DNS_DTTYPE_SQ|DNS_DTTYPE_CQ|DNS_DTTYPE_AQ|\ - DNS_DTTYPE_RQ|DNS_DTTYPE_FQ|DNS_DTTYPE_TQ) -#define DNS_DTTYPE_RESPONSE \ - (DNS_DTTYPE_SR|DNS_DTTYPE_CR|DNS_DTTYPE_AR|\ - DNS_DTTYPE_RR|DNS_DTTYPE_FR|DNS_DTTYPE_TR) -#define DNS_DTTYPE_ALL \ - (DNS_DTTYPE_QUERY|DNS_DTTYPE_RESPONSE) - -typedef enum { - dns_dtmode_none = 0, - dns_dtmode_file, - dns_dtmode_unix -} dns_dtmode_t; - -typedef struct dns_dthandle dns_dthandle_t; - -#ifdef HAVE_DNSTAP -struct dns_dtdata { - isc_mem_t *mctx; - - void *frame; - - bool query; - bool tcp; - dns_dtmsgtype_t type; - - isc_time_t qtime; - isc_time_t rtime; - - isc_region_t qaddr; - isc_region_t raddr; - - uint32_t qport; - uint32_t rport; - - isc_region_t msgdata; - dns_message_t *msg; - - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; -}; -#endif /* HAVE_DNSTAP */ - -isc_result_t -dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path, - struct fstrm_iothr_options **foptp, dns_dtenv_t **envp); -/*%< - * Create and initialize the dnstap environment. - * - * There should be a single global dnstap environment for the server; - * copies of it will be attached to each view. - * - * Notes: - * - *\li 'path' refers to a UNIX domain socket by default. It may - * optionally be prepended with "socket:" or "file:". If prepended - * with "file:", then dnstap logs are sent to a file instead of a - * socket. - * - *\li '*foptp' set the options for fstrm_iothr_init(). '*foptp' must have - * have had the number of input queues set and this should be set - * to the number of worker threads. Additionally the queue model - * should also be set. Other options may be set if desired. - * If dns_dt_create succeeds the *foptp is set to NULL. - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li 'path' is a valid C string. - * - *\li 'fopt' is non NULL. - * - *\li envp != NULL && *envp == NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - * - *\li Other errors are possible. - */ - -isc_result_t -dns_dt_reopen(dns_dtenv_t *env, int roll); -/*%< - * Reopens files established by dns_dt_create(). - * - * If 'roll' is non-negative and 'env->mode' is dns_dtmode_file, - * then the file is automatically rolled over before reopening. - * The value of 'roll' indicates the number of backup log files to - * keep. If 'roll' is negative, or if 'env->mode' is dns_dtmode_unix, - * then the channel is simply reopened. - * - * Note: dns_dt_reopen() must be called in task exclusive mode. - * - * Requires: - *\li 'env' is a valid dnstap environment. - */ - -isc_result_t -dns_dt_setidentity(dns_dtenv_t *env, const char *identity); -isc_result_t -dns_dt_setversion(dns_dtenv_t *env, const char *version); -/*%< - * Set the "identity" and "version" strings to be sent in dnstap messages. - * - * Requires: - * - *\li 'env' is a valid dnstap environment. - */ - -void -dns_dt_attach(dns_dtenv_t *source, dns_dtenv_t **destp); -/*%< - * Attach '*destp' to 'source', incrementing the reference counter. - * - * Requires: - * - *\li 'source' is a valid dnstap environment. - * - *\li 'destp' is not NULL and '*destp' is NULL. - * - *\li *destp is attached to source. - */ - -void -dns_dt_detach(dns_dtenv_t **envp); -/*%< - * Detach '*envp', decrementing the reference counter. - * - * Requires: - * - *\li '*envp' is a valid dnstap environment. - * - * Ensures: - * - *\li '*envp' will be destroyed when the number of references reaches zero. - * - *\li '*envp' is NULL. - */ - -isc_result_t -dns_dt_getstats(dns_dtenv_t *env, isc_stats_t **statsp); -/*%< - * Attach to the stats struct if it exists. - * - * Requires: - * - *\li 'env' is a valid dnstap environment. - * - *\li 'statsp' is non NULL and '*statsp' is NULL. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li ISC_R_NOTFOUND - */ - -void -dns_dt_shutdown(void); -/*%< - * Shuts down dnstap and frees global resources. This function must only - * be called immediately before server shutdown. - */ - -void -dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, - isc_sockaddr_t *qaddr, isc_sockaddr_t *dstaddr, - bool tcp, isc_region_t *zone, isc_time_t *qtime, - isc_time_t *rtime, isc_buffer_t *buf); -/*%< - * Sends a dnstap message to the log, if 'msgtype' is one of the message - * types represented in 'view->dttypes'. - * - * Parameters are: 'qaddr' (query address, i.e, the address of the - * query initiator); 'raddr' (response address, i.e., the address of - * the query responder); 'tcp' (boolean indicating whether the transaction - * was over TCP); 'zone' (the authoritative zone or bailiwick, in - * uncompressed wire format), 'qtime' and 'rtime' (query and response - * times; if NULL, they are set to the current time); and 'buf' (the - * DNS message being logged, in wire format). - * - * Requires: - * - *\li 'view' is a valid view, and 'view->dtenv' is NULL or is a - * valid dnstap environment. - */ - -isc_result_t -dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp); -/*%< - * Converts a raw dnstap frame in 'src' to a parsed dnstap data structure - * in '*destp'. - * - * Requires: - *\li 'src' is not NULL - * - *\li 'destp' is not NULL and '*destp' points to a valid buffer. - * - * Returns: - *\li #ISC_R_SUCCESS on success - * - *\li Other errors are possible. - */ - -isc_result_t -dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest); -/*%< - * Converts a parsed dnstap data structure 'd' to text, storing - * the result in the buffer 'dest'. If 'dest' points to a dynamically - * allocated buffer, then it may be reallocated as needed. - * - * (XXX: add a 'long_form' option to generate a detailed listing of - * dnstap data instead * of a one-line summary.) - * - * Requires: - *\li 'd' is not NULL - * - *\li 'dest' is not NULL and '*dest' points to a valid buffer. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE if buffer is not dynamic and runs out of space - *\li #ISC_R_NOMEMORY if buffer is dynamic but memory could not be allocated - * - *\li Other errors are possible. - */ - -void -dns_dtdata_free(dns_dtdata_t **dp); -/*%< - * Frees the specified dns_dtdata structure and all its members, - * and sets *dp to NULL. - */ - -isc_result_t -dns_dt_open(const char *filename, dns_dtmode_t mode, - isc_mem_t *mctx, dns_dthandle_t **handlep); -/*%< - * Opens a dnstap framestream at 'filename' and stores a pointer to the - * reader object in a dns_dthandle_t structure. - * - * The caller is responsible for allocating the handle structure. - * - * (XXX: Currently only file readers are supported, not unix-domain socket - * readers.) - * - * Requires: - * - *\li 'filename' is not NULL. - * - *\li 'handlep' is not NULL and '*handlep' is NULL. - * - *\li '*mctx' is not a valid memory context. - * - * Returns: - * - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOTIMPLEMENTED if 'mode' is not dns_dtmode_file. (XXX) - *\li #ISC_R_NOMEMORY if the fstrm library was unable to allocate a - * reader or options structure - *\li #ISC_R_FAILURE if 'filename' could not be opened. - *\li #DNS_R_BADDNSTAP if 'filename' does not contain a dnstap - * framestream. - */ - -isc_result_t -dns_dt_getframe(dns_dthandle_t *handle, uint8_t **bufp, size_t *sizep); -/*%< - * Read a dnstap frame from the framstream reader in 'handle', storing - * a pointer to it in '*bufp' and its size in '*sizep'. - * - * Requires: - * - *\li 'handle' is not NULL - *\li 'bufp' is not NULL - *\li 'sizep' is not NULL - * - * Ensures: - * \li if returning ISC_R_SUCCESS then '*bufp' is not NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOMORE at the end of the frame stream - *\li #ISC_R_FAILURE for any other failure - */ - -void -dns_dt_close(dns_dthandle_t **handlep); -/*%< - * Closes the dnstap file referenced by 'handle'. - * - * Requires: - * - *\li '*handlep' is not NULL - */ - -#endif /* _DNSTAP_H */ diff --git a/lib/dns-pkcs11/include/dns/ds.h b/lib/dns-pkcs11/include/dns/ds.h deleted file mode 100644 index 20b4666..0000000 --- a/lib/dns-pkcs11/include/dns/ds.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DS_H -#define DNS_DS_H 1 - -#include - -#include - -#define DNS_DSDIGEST_SHA1 (1) -#define DNS_DSDIGEST_SHA256 (2) -#define DNS_DSDIGEST_GOST (3) -#define DNS_DSDIGEST_SHA384 (4) - -/* - * Assuming SHA-384 digest type. - */ -#define DNS_DS_BUFFERSIZE (52) - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, - dns_dsdigest_t digest_type, unsigned char *buffer, - dns_rdata_t *rdata); -/*%< - * Build the rdata of a DS record. - * - * Requires: - *\li key Points to a valid DNS KEY record. - *\li buffer Points to a temporary buffer of at least - * #DNS_DS_BUFFERSIZE bytes. - *\li rdata Points to an initialized dns_rdata_t. - * - * Ensures: - * \li *rdata Contains a valid DS rdata. The 'data' member refers - * to 'buffer'. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DS_H */ diff --git a/lib/dns-pkcs11/include/dns/dsdigest.h b/lib/dns-pkcs11/include/dns/dsdigest.h deleted file mode 100644 index 7097ffc..0000000 --- a/lib/dns-pkcs11/include/dns/dsdigest.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_DSDIGEST_H -#define DNS_DSDIGEST_H 1 - -/*! \file dns/dsdigest.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_dsdigest_fromtext(dns_dsdigest_t *dsdigestp, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DS/DLV digest type value. - * The text may contain either a mnemonic digest name or a decimal - * digest number. - * - * Requires: - *\li 'dsdigestp' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_RANGE numeric type is out of range - *\li DNS_R_UNKNOWN mnemonic type is unknown - */ - -isc_result_t -dns_dsdigest_totext(dns_dsdigest_t dsdigest, isc_buffer_t *target); -/*%< - * Put a textual representation of the DS/DLV digest type 'dsdigest' - * into 'target'. - * - * Requires: - *\li 'dsdigest' is a valid dsdigest. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_NOSPACE target buffer is too small - */ - -#define DNS_DSDIGEST_FORMATSIZE 20 -void -dns_dsdigest_format(dns_dsdigest_t typ, char *cp, unsigned int size); -/*%< - * Wrapper for dns_dsdigest_totext(), writing text into 'cp' - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DSDIGEST_H */ diff --git a/lib/dns-pkcs11/include/dns/dyndb.h b/lib/dns-pkcs11/include/dns/dyndb.h deleted file mode 100644 index d95b229..0000000 --- a/lib/dns-pkcs11/include/dns/dyndb.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_DYNDB_H -#define DNS_DYNDB_H - -#include - -#include - -#include - -ISC_LANG_BEGINDECLS - -/*! - * \brief - * Context for initializing a dyndb module. - * - * This structure passes global server data to which a dyndb - * module will need access -- the server memory context, hash - * initializer, log context, etc. The structure doesn't persist - * beyond configuring the dyndb module. The module's register function - * should attach to all reference-counted variables and its destroy - * function should detach from them. - */ -struct dns_dyndbctx { - unsigned int magic; - const void *hashinit; - isc_mem_t *mctx; - isc_log_t *lctx; - dns_view_t *view; - dns_zonemgr_t *zmgr; - isc_task_t *task; - isc_timermgr_t *timermgr; - bool *refvar; -}; - -#define DNS_DYNDBCTX_MAGIC ISC_MAGIC('D', 'd', 'b', 'c') -#define DNS_DYNDBCTX_VALID(d) ISC_MAGIC_VALID(d, DNS_DYNDBCTX_MAGIC) - -/* - * API version - * - * When the API changes, increment DNS_DYNDB_VERSION. If the - * change is backward-compatible (e.g., adding a new function call - * but not changing or removing an old one), increment DNS_DYNDB_AGE; - * if not, set DNS_DYNDB_AGE to 0. - */ -#ifndef DNS_DYNDB_VERSION -#define DNS_DYNDB_VERSION 1 -#define DNS_DYNDB_AGE 0 -#endif - -typedef isc_result_t dns_dyndb_register_t(isc_mem_t *mctx, - const char *name, - const char *parameters, - const char *file, - unsigned long line, - const dns_dyndbctx_t *dctx, - void **instp); -/*% - * Called when registering a new driver instance. 'name' must be unique. - * 'parameters' contains the driver configuration text. 'dctx' is the - * initialization context set up in dns_dyndb_createctx(). - * - * '*instp' must be set to the driver instance handle if the function - * is successful. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li Other errors are possible - */ - -typedef void dns_dyndb_destroy_t(void **instp); -/*% - * Destroy a driver instance. Dereference any reference-counted - * variables passed in 'dctx' and 'inst' in the register function. - * - * \c *instp must be set to \c NULL by the function before it returns. - */ - -typedef int dns_dyndb_version_t(unsigned int *flags); -/*% - * Return the API version number a dyndb module was compiled with. - * - * If the returned version number is no greater than than - * DNS_DYNDB_VERSION, and no less than DNS_DYNDB_VERSION - DNS_DYNDB_AGE, - * then the module is API-compatible with named. - * - * 'flags' is currently unused and may be NULL, but could be used in - * the future to pass back driver capabilities or other information. - */ - -isc_result_t -dns_dyndb_load(const char *libname, const char *name, const char *parameters, - const char *file, unsigned long line, isc_mem_t *mctx, - const dns_dyndbctx_t *dctx); -/*% - * Load a dyndb module. - * - * This loads a dyndb module using dlopen() or equivalent, calls its register - * function (see dns_dyndb_register_t above), and if successful, adds - * the instance handle to a list of dyndb instances so it can be cleaned - * up later. - * - * 'file' and 'line' can be used to indicate the name of the file and - * the line number from which the parameters were taken, so that logged - * error messages, if any, will display the correct locations. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li Other errors are possible - */ - -void -dns_dyndb_cleanup(bool exiting); -/*% - * Shut down and destroy all running dyndb modules. - * - * 'exiting' indicates whether the server is shutting down, - * as opposed to merely being reconfigured. - */ - -isc_result_t -dns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx, - dns_view_t *view, dns_zonemgr_t *zmgr, isc_task_t *task, - isc_timermgr_t *tmgr, dns_dyndbctx_t **dctxp); -/*% - * Create a dyndb initialization context structure, with - * pointers to structures in the server that the dyndb module will - * need to access (view, zone manager, memory context, hash initializer, - * etc). This structure is expected to last only until all dyndb - * modules have been loaded and initialized; after that it will be - * destroyed with dns_dyndb_destroyctx(). - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li Other errors are possible - */ - -void -dns_dyndb_destroyctx(dns_dyndbctx_t **dctxp); -/*% - * Destroys a dyndb initialization context structure; all - * reference-counted members are detached and the structure is freed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_DYNDB_H */ diff --git a/lib/dns-pkcs11/include/dns/ecdb.h b/lib/dns-pkcs11/include/dns/ecdb.h deleted file mode 100644 index b277a89..0000000 --- a/lib/dns-pkcs11/include/dns/ecdb.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ECDB_H -#define DNS_ECDB_H 1 - -/***** - ***** Module Info - *****/ - -/* TBD */ - -/*** - *** Imports - ***/ - -#include - -/*** - *** Types - ***/ - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -/* TBD: describe those */ - -isc_result_t -dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp); - -void -dns_ecdb_unregister(dns_dbimplementation_t **dbimp); - -ISC_LANG_ENDDECLS - -#endif /* DNS_ECDB_H */ diff --git a/lib/dns-pkcs11/include/dns/edns.h b/lib/dns-pkcs11/include/dns/edns.h deleted file mode 100644 index 44aa097..0000000 --- a/lib/dns-pkcs11/include/dns/edns.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_EDNS_H -#define DNS_EDNS_H 1 - -/*% - * The maximum version on EDNS supported by this build. - */ -#define DNS_EDNS_VERSION 0 -#ifdef DRAFT_ANDREWS_EDNS1 -#undef DNS_EDNS_VERSION -/* - * Warning: this currently disables sending COOKIE requests in resolver.c - */ -#define DNS_EDNS_VERSION 1 /* draft-andrews-edns1 */ -#endif - -#endif diff --git a/lib/dns-pkcs11/include/dns/events.h b/lib/dns-pkcs11/include/dns/events.h deleted file mode 100644 index 6cc5635..0000000 --- a/lib/dns-pkcs11/include/dns/events.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_EVENTS_H -#define DNS_EVENTS_H 1 - -#include - -/*! \file dns/events.h - * \brief - * Registry of DNS event numbers. - */ - -#define DNS_EVENT_FETCHCONTROL (ISC_EVENTCLASS_DNS + 0) -#define DNS_EVENT_FETCHDONE (ISC_EVENTCLASS_DNS + 1) -#define DNS_EVENT_VIEWRESSHUTDOWN (ISC_EVENTCLASS_DNS + 2) -#define DNS_EVENT_VIEWADBSHUTDOWN (ISC_EVENTCLASS_DNS + 3) -#define DNS_EVENT_UPDATE (ISC_EVENTCLASS_DNS + 4) -#define DNS_EVENT_UPDATEDONE (ISC_EVENTCLASS_DNS + 5) -#define DNS_EVENT_DISPATCH (ISC_EVENTCLASS_DNS + 6) -#define DNS_EVENT_TCPMSG (ISC_EVENTCLASS_DNS + 7) -#define DNS_EVENT_ADBMOREADDRESSES (ISC_EVENTCLASS_DNS + 8) -#define DNS_EVENT_ADBNOMOREADDRESSES (ISC_EVENTCLASS_DNS + 9) -#define DNS_EVENT_ADBCANCELED (ISC_EVENTCLASS_DNS + 10) -#define DNS_EVENT_ADBNAMEDELETED (ISC_EVENTCLASS_DNS + 11) -#define DNS_EVENT_ADBSHUTDOWN (ISC_EVENTCLASS_DNS + 12) -#define DNS_EVENT_ADBEXPIRED (ISC_EVENTCLASS_DNS + 13) -#define DNS_EVENT_ADBCONTROL (ISC_EVENTCLASS_DNS + 14) -#define DNS_EVENT_CACHECLEAN (ISC_EVENTCLASS_DNS + 15) -#define DNS_EVENT_BYADDRDONE (ISC_EVENTCLASS_DNS + 16) -#define DNS_EVENT_ZONECONTROL (ISC_EVENTCLASS_DNS + 17) -#define DNS_EVENT_DBDESTROYED (ISC_EVENTCLASS_DNS + 18) -#define DNS_EVENT_VALIDATORDONE (ISC_EVENTCLASS_DNS + 19) -#define DNS_EVENT_REQUESTDONE (ISC_EVENTCLASS_DNS + 20) -#define DNS_EVENT_VALIDATORSTART (ISC_EVENTCLASS_DNS + 21) -#define DNS_EVENT_VIEWREQSHUTDOWN (ISC_EVENTCLASS_DNS + 22) -#define DNS_EVENT_NOTIFYSENDTOADDR (ISC_EVENTCLASS_DNS + 23) -#define DNS_EVENT_ZONE (ISC_EVENTCLASS_DNS + 24) -#define DNS_EVENT_ZONESTARTXFRIN (ISC_EVENTCLASS_DNS + 25) -#define DNS_EVENT_MASTERQUANTUM (ISC_EVENTCLASS_DNS + 26) -#define DNS_EVENT_CACHEOVERMEM (ISC_EVENTCLASS_DNS + 27) -#define DNS_EVENT_MASTERNEXTZONE (ISC_EVENTCLASS_DNS + 28) -#define DNS_EVENT_IOREADY (ISC_EVENTCLASS_DNS + 29) -#define DNS_EVENT_LOOKUPDONE (ISC_EVENTCLASS_DNS + 30) -#define DNS_EVENT_RBTDEADNODES (ISC_EVENTCLASS_DNS + 31) -#define DNS_EVENT_DISPATCHCONTROL (ISC_EVENTCLASS_DNS + 32) -#define DNS_EVENT_REQUESTCONTROL (ISC_EVENTCLASS_DNS + 33) -#define DNS_EVENT_DUMPQUANTUM (ISC_EVENTCLASS_DNS + 34) -#define DNS_EVENT_IMPORTRECVDONE (ISC_EVENTCLASS_DNS + 35) -#define DNS_EVENT_FREESTORAGE (ISC_EVENTCLASS_DNS + 36) -#define DNS_EVENT_VIEWACACHESHUTDOWN (ISC_EVENTCLASS_DNS + 37) -#define DNS_EVENT_ACACHECONTROL (ISC_EVENTCLASS_DNS + 38) -#define DNS_EVENT_ACACHECLEAN (ISC_EVENTCLASS_DNS + 39) -#define DNS_EVENT_ACACHEOVERMEM (ISC_EVENTCLASS_DNS + 40) -#define DNS_EVENT_RBTPRUNE (ISC_EVENTCLASS_DNS + 41) -#define DNS_EVENT_MANAGEKEYS (ISC_EVENTCLASS_DNS + 42) -#define DNS_EVENT_CLIENTRESDONE (ISC_EVENTCLASS_DNS + 43) -#define DNS_EVENT_CLIENTREQDONE (ISC_EVENTCLASS_DNS + 44) -#define DNS_EVENT_ADBGROWENTRIES (ISC_EVENTCLASS_DNS + 45) -#define DNS_EVENT_ADBGROWNAMES (ISC_EVENTCLASS_DNS + 46) -#define DNS_EVENT_ZONESECURESERIAL (ISC_EVENTCLASS_DNS + 47) -#define DNS_EVENT_ZONESECUREDB (ISC_EVENTCLASS_DNS + 48) -#define DNS_EVENT_ZONELOAD (ISC_EVENTCLASS_DNS + 49) -#define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50) -#define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51) -#define DNS_EVENT_SETSERIAL (ISC_EVENTCLASS_DNS + 52) -#define DNS_EVENT_CATZUPDATED (ISC_EVENTCLASS_DNS + 53) -#define DNS_EVENT_CATZADDZONE (ISC_EVENTCLASS_DNS + 54) -#define DNS_EVENT_CATZMODZONE (ISC_EVENTCLASS_DNS + 55) -#define DNS_EVENT_CATZDELZONE (ISC_EVENTCLASS_DNS + 56) -#define DNS_EVENT_STARTUPDATE (ISC_EVENTCLASS_DNS + 58) - -#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) -#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535) - -#endif /* DNS_EVENTS_H */ diff --git a/lib/dns-pkcs11/include/dns/fixedname.h b/lib/dns-pkcs11/include/dns/fixedname.h deleted file mode 100644 index 4b04905..0000000 --- a/lib/dns-pkcs11/include/dns/fixedname.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_FIXEDNAME_H -#define DNS_FIXEDNAME_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/fixedname.h - * \brief - * Fixed-size Names - * - * dns_fixedname_t is a convenience type containing a name, an offsets - * table, and a dedicated buffer big enough for the longest possible - * name. This is typically used for stack-allocated names. - * - * MP: - *\li The caller must ensure any required synchronization. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li Per dns_fixedname_t: - *\code - * sizeof(dns_name_t) + sizeof(dns_offsets_t) + - * sizeof(isc_buffer_t) + 255 bytes + structure padding - *\endcode - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -/***** - ***** Imports - *****/ - -#include -#include - -#include - -/***** - ***** Types - *****/ - -struct dns_fixedname { - dns_name_t name; - dns_offsets_t offsets; - isc_buffer_t buffer; - unsigned char data[DNS_NAME_MAXWIRE]; -}; - -ISC_LANG_BEGINDECLS - -void -dns_fixedname_init(dns_fixedname_t *fixed); - -void -dns_fixedname_invalidate(dns_fixedname_t *fixed); - -dns_name_t * -dns_fixedname_name(dns_fixedname_t *fixed); - -dns_name_t * -dns_fixedname_initname(dns_fixedname_t *fixed); - -ISC_LANG_ENDDECLS - -#endif /* DNS_FIXEDNAME_H */ diff --git a/lib/dns-pkcs11/include/dns/forward.h b/lib/dns-pkcs11/include/dns/forward.h deleted file mode 100644 index 674a08a..0000000 --- a/lib/dns-pkcs11/include/dns/forward.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_FORWARD_H -#define DNS_FORWARD_H 1 - -/*! \file dns/forward.h */ - -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -struct dns_forwarder { - isc_sockaddr_t addr; - isc_dscp_t dscp; - ISC_LINK(dns_forwarder_t) link; -}; - -typedef ISC_LIST(struct dns_forwarder) dns_forwarderlist_t; - -struct dns_forwarders { - dns_forwarderlist_t fwdrs; - dns_fwdpolicy_t fwdpolicy; -}; - -isc_result_t -dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep); -/*%< - * Creates a new forwarding table. - * - * Requires: - * \li mctx is a valid memory context. - * \li fwdtablep != NULL && *fwdtablep == NULL - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t policy); -isc_result_t -dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, - isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy); -/*%< - * Adds an entry to the forwarding table. The entry associates - * a domain with a list of forwarders and a forwarding policy. The - * addrs/fwdrs list is copied if not empty, so the caller should free - * its copy. - * - * Requires: - * \li fwdtable is a valid forwarding table. - * \li name is a valid name - * \li addrs/fwdrs is a valid list of isc_sockaddr/dns_forwarder - * structures, which may be empty. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name); -/*%< - * Removes an entry for 'name' from the forwarding table. If an entry - * that exactly matches 'name' does not exist, ISC_R_NOTFOUND will be returned. - * - * Requires: - * \li fwdtable is a valid forwarding table. - * \li name is a valid name - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - */ - -isc_result_t -dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_forwarders_t **forwardersp); -/*%< - * Finds a domain in the forwarding table. The closest matching parent - * domain is returned. - * - * Requires: - * \li fwdtable is a valid forwarding table. - * \li name is a valid name - * \li forwardersp != NULL && *forwardersp == NULL - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - */ - -isc_result_t -dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name, - dns_name_t *foundname, dns_forwarders_t **forwardersp); -/*%< - * Finds a domain in the forwarding table. The closest matching parent - * domain is returned. - * - * Requires: - * \li fwdtable is a valid forwarding table. - * \li name is a valid name - * \li forwardersp != NULL && *forwardersp == NULL - * \li foundname to be NULL or a valid name with buffer. - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - */ - -void -dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep); -/*%< - * Destroys a forwarding table. - * - * Requires: - * \li fwtablep != NULL && *fwtablep != NULL - * - * Ensures: - * \li all memory associated with the forwarding table is freed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_FORWARD_H */ diff --git a/lib/dns-pkcs11/include/dns/geoip.h b/lib/dns-pkcs11/include/dns/geoip.h deleted file mode 100644 index a0cc5ec..0000000 --- a/lib/dns-pkcs11/include/dns/geoip.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_GEOIP_H -#define DNS_GEOIP_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/geoip.h - * \brief - * GeoIP/GeoIP2 data types and function prototypes. - */ - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - -/*** - *** Imports - ***/ - -#include - -#include -#include -#include - -#include -#include -#include - -/*** - *** Types - ***/ - -typedef enum { - dns_geoip_countrycode, - dns_geoip_countrycode3, - dns_geoip_countryname, - dns_geoip_continentcode, - dns_geoip_continent, - dns_geoip_region, - dns_geoip_regionname, - dns_geoip_country_code, - dns_geoip_country_code3, - dns_geoip_country_name, - dns_geoip_country_continentcode, - dns_geoip_country_continent, - dns_geoip_region_countrycode, - dns_geoip_region_code, - dns_geoip_region_name, - dns_geoip_city_countrycode, - dns_geoip_city_countrycode3, - dns_geoip_city_countryname, - dns_geoip_city_region, - dns_geoip_city_regionname, - dns_geoip_city_name, - dns_geoip_city_postalcode, - dns_geoip_city_metrocode, - dns_geoip_city_areacode, - dns_geoip_city_continentcode, - dns_geoip_city_continent, - dns_geoip_city_timezonecode, - dns_geoip_isp_name, - dns_geoip_org_name, - dns_geoip_as_asnum, - dns_geoip_domain_name, - dns_geoip_netspeed_id -} dns_geoip_subtype_t; - -typedef struct dns_geoip_elem { - dns_geoip_subtype_t subtype; - void *db; - union { - char as_string[256]; - int as_int; - }; -} dns_geoip_elem_t; - -struct dns_geoip_databases { -#ifdef HAVE_GEOIP2 - void *country; /* GeoIP2-Country or GeoLite2-Country */ - void *city; /* GeoIP2-CIty or GeoLite2-City */ - void *domain; /* GeoIP2-Domain */ - void *isp; /* GeoIP2-ISP */ - void *as; /* GeoIP2-ASN or GeoLite2-ASN */ -#else /* HAVE_GEOIP */ - void *country_v4; /* GeoIP DB 1 */ - void *city_v4; /* GeoIP DB 2 or 6 */ - void *region; /* GeoIP DB 3 or 7 */ - void *isp; /* GeoIP DB 4 */ - void *org; /* GeoIP DB 5 */ - void *as; /* GeoIP DB 9 */ - void *netspeed; /* GeoIP DB 10 */ - void *domain; /* GeoIP DB 11 */ - void *country_v6; /* GeoIP DB 12 */ - void *city_v6; /* GeoIP DB 30 or 31 */ -#endif /* HAVE_GEOIP */ -}; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -bool -dns_geoip_match(const isc_netaddr_t *reqaddr, uint8_t *scope, - const dns_geoip_databases_t *geoip, - const dns_geoip_elem_t *elt); - -void -dns_geoip_shutdown(void); - -ISC_LANG_ENDDECLS - -#endif /* HAVE_GEOIP | HAVE_GEOIP2 */ - -#endif /* DNS_GEOIP_H */ diff --git a/lib/dns-pkcs11/include/dns/ipkeylist.h b/lib/dns-pkcs11/include/dns/ipkeylist.h deleted file mode 100644 index 9652256..0000000 --- a/lib/dns-pkcs11/include/dns/ipkeylist.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_IPKEYLIST_H -#define DNS_IPKEYLIST_H 1 - -#include - -#include -#include - -/*% - * A structure holding a list of addresses, dscps and keys. Used to - * store masters for a slave zone, created by parsing config options. - */ -struct dns_ipkeylist { - isc_sockaddr_t *addrs; - isc_dscp_t *dscps; - dns_name_t **keys; - dns_name_t **labels; - uint32_t count; - uint32_t allocated; -}; - -void -dns_ipkeylist_init(dns_ipkeylist_t *ipkl); -/*%< - * Reset ipkl to empty state - * - * Requires: - *\li 'ipkl' to be non NULL. - */ - -void -dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl); -/*%< - * Free `ipkl` contents using `mctx`. - * - * After this call, `ipkl` is a freshly cleared structure with all - * pointers set to `NULL` and count set to 0. - * - * Requires: - *\li 'mctx' to be a valid memory context. - *\li 'ipkl' to be non NULL. - */ - -isc_result_t -dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, - dns_ipkeylist_t *dst); -/*%< - * Deep copy `src` into empty `dst`, allocating `dst`'s contents. - * - * Requires: - *\li 'mctx' to be a valid memory context. - *\li 'src' to be non NULL - *\li 'dst' to be non NULL and point to an empty \ref dns_ipkeylist_t - * with all pointers set to `NULL` and count set to 0. - * - * Returns: - *\li #ISC_R_SUCCESS -- success - *\li any other value -- failure - */ -isc_result_t -dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n); -/*%< - * Resize ipkl to contain n elements. Size (count) is not changed, and the - * added space is zeroed. - * - * Requires: - * \li 'mctx' to be a valid memory context. - * \li 'ipk' to be non NULL - * \li 'n' >= ipkl->count - * - * Returns: - * \li #ISC_R_SUCCESS if success - * \li #ISC_R_NOMEMORY if there's no memory, ipkeylist is left untouched - */ - -#endif diff --git a/lib/dns-pkcs11/include/dns/iptable.h b/lib/dns-pkcs11/include/dns/iptable.h deleted file mode 100644 index 4a4cc4b..0000000 --- a/lib/dns-pkcs11/include/dns/iptable.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_IPTABLE_H -#define DNS_IPTABLE_H 1 - -#include - -#include -#include -#include - -#include - -struct dns_iptable { - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t refcount; - isc_radix_tree_t *radix; - ISC_LINK(dns_iptable_t) nextincache; -}; - -#define DNS_IPTABLE_MAGIC ISC_MAGIC('T','a','b','l') -#define DNS_IPTABLE_VALID(a) ISC_MAGIC_VALID(a, DNS_IPTABLE_MAGIC) - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target); -/* - * Create a new IP table and the underlying radix structure - */ - -isc_result_t -dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr, - uint16_t bitlen, bool pos); -isc_result_t -dns_iptable_addprefix2(dns_iptable_t *tab, isc_netaddr_t *addr, - uint16_t bitlen, bool pos, - bool is_ecs); -/* - * Add an IP prefix to an existing IP table - */ - -isc_result_t -dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, bool pos); -/* - * Merge one IP table into another one. - */ - -void -dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target); - -void -dns_iptable_detach(dns_iptable_t **tabp); - -ISC_LANG_ENDDECLS - -#endif /* DNS_IPTABLE_H */ diff --git a/lib/dns-pkcs11/include/dns/journal.h b/lib/dns-pkcs11/include/dns/journal.h deleted file mode 100644 index 1eaea53..0000000 --- a/lib/dns-pkcs11/include/dns/journal.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_JOURNAL_H -#define DNS_JOURNAL_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/journal.h - * \brief - * Database journaling. - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include - -#include -#include -#include -#include - -/*** - *** Defines. - ***/ -#define DNS_JOURNALOPT_RESIGN 0x00000001 - -#define DNS_JOURNAL_READ 0x00000000 /* false */ -#define DNS_JOURNAL_CREATE 0x00000001 /* true */ -#define DNS_JOURNAL_WRITE 0x00000002 - -/*** - *** Types - ***/ - -/*% - * A dns_journal_t represents an open journal file. This is an opaque type. - * - * A particular dns_journal_t object may be opened for writing, in which case - * it can be used for writing transactions to a journal file, or it can be - * opened for reading, in which case it can be used for reading transactions - * from (iterating over) a journal file. A single dns_journal_t object may - * not be used for both purposes. - */ -typedef struct dns_journal dns_journal_t; - - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -/**************************************************************************/ - -isc_result_t -dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, - dns_diffop_t op, dns_difftuple_t **tp); -/*!< brief - * Create a diff tuple for the current database SOA. - * XXX this probably belongs somewhere else. - */ - - -/*@{*/ -#define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) -#define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) -/*!< brief - * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff - * a is "greater than" b where "greater than" is as defined in RFC1982. - * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. - */ -/*@}*/ - -/**************************************************************************/ -/* - * Journal object creation and destruction. - */ - -isc_result_t -dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, - dns_journal_t **journalp); -/*%< - * Open the journal file 'filename' and create a dns_journal_t object for it. - * - * DNS_JOURNAL_CREATE open the journal for reading and writing and create - * the journal if it does not exist. - * DNS_JOURNAL_WRITE open the journal for reading and writing. - * DNS_JOURNAL_READ open the journal for reading only. - */ - -void -dns_journal_destroy(dns_journal_t **journalp); -/*%< - * Destroy a dns_journal_t, closing any open files and freeing its memory. - */ - -/**************************************************************************/ -/* - * Writing transactions to journals. - */ - -isc_result_t -dns_journal_begin_transaction(dns_journal_t *j); -/*%< - * Prepare to write a new transaction to the open journal file 'j'. - * - * Requires: - * \li 'j' is open for writing. - */ - -isc_result_t -dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); -/*%< - * Write 'diff' to the current transaction of journal file 'j'. - * - * Requires: - * \li 'j' is open for writing and dns_journal_begin_transaction() - * has been called. - * - *\li 'diff' is a full or partial, correctly ordered IXFR - * difference sequence. - */ - -isc_result_t -dns_journal_commit(dns_journal_t *j); -/*%< - * Commit the current transaction of journal file 'j'. - * - * Requires: - * \li 'j' is open for writing and dns_journal_begin_transaction() - * has been called. - * - * \li dns_journal_writediff() has been called one or more times - * to form a complete, correctly ordered IXFR difference - * sequence. - */ - -isc_result_t -dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); -/*% - * Write a complete transaction at once to a journal file, - * sorting it if necessary, and commit it. Equivalent to calling - * dns_diff_sort(), dns_journal_begin_transaction(), - * dns_journal_writediff(), and dns_journal_commit(). - * - * Requires: - *\li 'j' is open for writing. - * - * \li 'diff' contains exactly one SOA deletion, one SOA addition - * with a greater serial number, and possibly other changes, - * in arbitrary order. - */ - -/**************************************************************************/ -/* - * Reading transactions from journals. - */ - -uint32_t -dns_journal_first_serial(dns_journal_t *j); -uint32_t -dns_journal_last_serial(dns_journal_t *j); -/*%< - * Get the first and last addressable serial number in the journal. - */ - -isc_result_t -dns_journal_iter_init(dns_journal_t *j, - uint32_t begin_serial, uint32_t end_serial); -/*%< - * Prepare to iterate over the transactions that will bring the database - * from SOA serial number 'begin_serial' to 'end_serial'. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_RANGE begin_serial is outside the addressable range. - *\li ISC_R_NOTFOUND begin_serial is within the range of addressable - * serial numbers covered by the journal, but - * this particular serial number does not exist. - */ - -/*@{*/ -isc_result_t -dns_journal_first_rr(dns_journal_t *j); -isc_result_t -dns_journal_next_rr(dns_journal_t *j); -/*%< - * Position the iterator at the first/next RR in a journal - * transaction sequence established using dns_journal_iter_init(). - * - * Requires: - * \li dns_journal_iter_init() has been called. - * - */ -/*@}*/ - -void -dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata); -/*%< - * Get the name, ttl, and rdata of the current journal RR. - * - * Requires: - * \li The last call to dns_journal_first_rr() or dns_journal_next_rr() - * returned ISC_R_SUCCESS. - */ - -/**************************************************************************/ -/* - * Database roll-forward. - */ - -isc_result_t -dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, - const char *filename); -/*%< - * Roll forward (play back) the journal file "filename" into the - * database "db". This should be called when the server starts - * after a shutdown or crash. - * - * Requires: - *\li 'mctx' is a valid memory context. - *\li 'db' is a valid database which does not have a version - * open for writing. - *\li 'filename' is the name of the journal file belonging to 'db'. - * - * Returns: - *\li DNS_R_NOJOURNAL when journal does not exist. - *\li ISC_R_NOTFOUND when current serial in not in journal. - *\li ISC_R_RANGE when current serial in not in journals range. - *\li ISC_R_SUCCESS journal has been applied successfully to database. - * others - */ - -isc_result_t -dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file); -/* For debugging not general use */ - -isc_result_t -dns_db_diff(isc_mem_t *mctx, - dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - const char *journal_filename); - -isc_result_t -dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - const char *journal_filename); -/*%< - * Compare the databases 'dba' and 'dbb' and generate a diff/journal - * entry containing the changes to make 'dba' from 'dbb' (note - * the order). This journal entry will consist of a single, - * possibly very large transaction. Append the journal - * entry to the journal file specified by 'journal_filename' if - * non-NULL. - */ - -isc_result_t -dns_journal_compact(isc_mem_t *mctx, char *filename, uint32_t serial, - uint32_t target_size); -/*%< - * Attempt to compact the journal if it is greater that 'target_size'. - * Changes from 'serial' onwards will be preserved. If the journal - * exists and is non-empty 'serial' must exist in the journal. - */ - -bool -dns_journal_get_sourceserial(dns_journal_t *j, uint32_t *sourceserial); -void -dns_journal_set_sourceserial(dns_journal_t *j, uint32_t sourceserial); -/*%< - * Get and set source serial. - * - * Returns: - * true if sourceserial has previously been set. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_JOURNAL_H */ diff --git a/lib/dns-pkcs11/include/dns/keydata.h b/lib/dns-pkcs11/include/dns/keydata.h deleted file mode 100644 index c0f56ee..0000000 --- a/lib/dns-pkcs11/include/dns/keydata.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_KEYDATA_H -#define DNS_KEYDATA_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/keydata.h - * \brief - * KEYDATA utilities. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_keydata_todnskey(dns_rdata_keydata_t *keydata, - dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx); - -isc_result_t -dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata, - dns_rdata_dnskey_t *dnskey, - uint32_t refresh, uint32_t addhd, - uint32_t removehd, isc_mem_t *mctx); - -ISC_LANG_ENDDECLS - -#endif /* DNS_KEYDATA_H */ diff --git a/lib/dns-pkcs11/include/dns/keyflags.h b/lib/dns-pkcs11/include/dns/keyflags.h deleted file mode 100644 index 5e995da..0000000 --- a/lib/dns-pkcs11/include/dns/keyflags.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_KEYFLAGS_H -#define DNS_KEYFLAGS_H 1 - -/*! \file dns/keyflags.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNSSEC KEY flags value. - * The text may contain either a set of flag mnemonics separated by - * vertical bars or a decimal flags value. For compatibility with - * older versions of BIND and the DNSSEC signer, octal values - * prefixed with a zero and hexadecimal values prefixed with "0x" - * are also accepted. - * - * Requires: - *\li 'flagsp' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_RANGE numeric flag value is out of range - *\li DNS_R_UNKNOWN mnemonic flag is unknown - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_KEYFLAGS_H */ diff --git a/lib/dns-pkcs11/include/dns/keytable.h b/lib/dns-pkcs11/include/dns/keytable.h deleted file mode 100644 index 6e10227..0000000 --- a/lib/dns-pkcs11/include/dns/keytable.h +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_KEYTABLE_H -#define DNS_KEYTABLE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The keytable module provides services for storing and retrieving DNSSEC - * trusted keys, as well as the ability to find the deepest matching key - * for a given domain name. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - */ - -#include - -#include -#include -#include -#include - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep); -/*%< - * Create a keytable. - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li keytablep != NULL && *keytablep == NULL - * - * Ensures: - * - *\li On success, *keytablep is a valid, empty key table. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - - -void -dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp); -/*%< - * Attach *targetp to source. - * - * Requires: - * - *\li 'source' is a valid keytable. - * - *\li 'targetp' points to a NULL dns_keytable_t *. - * - * Ensures: - * - *\li *targetp is attached to source. - */ - -void -dns_keytable_detach(dns_keytable_t **keytablep); -/*%< - * Detach *keytablep from its keytable. - * - * Requires: - * - *\li 'keytablep' points to a valid keytable. - * - * Ensures: - * - *\li *keytablep is NULL. - * - *\li If '*keytablep' is the last reference to the keytable, - * all resources used by the keytable will be freed - */ - -isc_result_t -dns_keytable_add(dns_keytable_t *keytable, bool managed, - dst_key_t **keyp); -/*%< - * Add '*keyp' to 'keytable' (using the name in '*keyp'). - * The value of keynode->managed is set to 'managed' - * - * Notes: - * - *\li Ownership of *keyp is transferred to the keytable. - *\li If the key already exists in the table, ISC_R_EXISTS is - * returned and the new key is freed. - * - * Requires: - * - *\li 'keytable' points to a valid keytable. - * - *\li keyp != NULL && *keyp is a valid dst_key_t *. - * - * Ensures: - * - *\li On success, *keyp == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_EXISTS - * - *\li Any other result indicates failure. - */ - -isc_result_t -dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name); -/*%< - * Add a null key to 'keytable' for name 'name'. This marks the - * name as a secure domain, but doesn't supply any key data to allow the - * domain to be validated. (Used when automated trust anchor management - * has gotten broken by a zone misconfiguration; for example, when the - * active key has been revoked but the stand-by key was still in its 30-day - * waiting period for validity.) - * - * Notes: - * - *\li If a key already exists in the table, ISC_R_EXISTS is - * returned and nothing is done. - * - * Requires: - * - *\li 'keytable' points to a valid keytable. - * - *\li keyp != NULL && *keyp is a valid dst_key_t *. - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_EXISTS - * - *\li Any other result indicates failure. - */ - -isc_result_t -dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname); -/*%< - * Delete node(s) from 'keytable' matching name 'keyname' - * - * Requires: - * - *\li 'keytable' points to a valid keytable. - * - *\li 'name' is not NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - -isc_result_t -dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey); -/*%< - * Delete node(s) from 'keytable' containing copies of the key pointed - * to by 'dstkey' - * - * Requires: - * - *\li 'keytable' points to a valid keytable. - *\li 'dstkey' is not NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - -isc_result_t -dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, - dns_keynode_t **keynodep); -/*%< - * Search for the first instance of a key named 'name' in 'keytable', - * without regard to keyid and algorithm. Use dns_keytable_nextkeynode() - * to find subsequent instances. - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'name' is a valid absolute name. - * - *\li keynodep != NULL && *keynodep == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - * - *\li Any other result indicates an error. - */ - -isc_result_t -dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, - dns_keynode_t **nextnodep); -/*%< - * Return for the next key after 'keynode' in 'keytable', without regard to - * keyid and algorithm. - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'keynode' is a valid keynode. - * - *\li nextnodep != NULL && *nextnodep == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - * - *\li Any other result indicates an error. - */ - -isc_result_t -dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, - dns_secalg_t algorithm, dns_keytag_t tag, - dns_keynode_t **keynodep); -/*%< - * Search for a key named 'name', matching 'algorithm' and 'tag' in - * 'keytable'. This finds the first instance which matches. Use - * dns_keytable_findnextkeynode() to find other instances. - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'name' is a valid absolute name. - * - *\li keynodep != NULL && *keynodep == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li DNS_R_PARTIALMATCH the name existed in the keytable. - *\li ISC_R_NOTFOUND - * - *\li Any other result indicates an error. - */ - -isc_result_t -dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, - dns_keynode_t **nextnodep); -/*%< - * Search for the next key with the same properties as 'keynode' in - * 'keytable' as found by dns_keytable_findkeynode(). - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'keynode' is a valid keynode. - * - *\li nextnodep != NULL && *nextnodep == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - * - *\li Any other result indicates an error. - */ - -isc_result_t -dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, - dns_name_t *foundname); -/*%< - * Search for the deepest match of 'name' in 'keytable'. - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'name' is a valid absolute name. - * - *\li 'foundname' is a name with a dedicated buffer. - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - * - *\li Any other result indicates an error. - */ - -void -dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, - dns_keynode_t **target); -/*%< - * Attach a keynode and and increment the active_nodes counter in a - * corresponding keytable. - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'source' is a valid keynode. - * - *\li 'target' is not null and '*target' is null. - */ - -void -dns_keytable_detachkeynode(dns_keytable_t *keytable, - dns_keynode_t **keynodep); -/*%< - * Give back a keynode found via dns_keytable_findkeynode(). - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li *keynodep is a valid keynode returned by a call to - * dns_keytable_findkeynode(). - * - * Ensures: - * - *\li *keynodep == NULL - */ - -isc_result_t -dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, - dns_name_t *foundname, bool *wantdnssecp); -/*%< - * Is 'name' at or beneath a trusted key? - * - * Requires: - * - *\li 'keytable' is a valid keytable. - * - *\li 'name' is a valid absolute name. - * - *\li 'foundanme' is NULL or is a pointer to an initialized dns_name_t - * - *\li '*wantsdnssecp' is a valid bool. - - * Ensures: - * - *\li On success, *wantsdnssecp will be true if and only if 'name' - * is at or beneath a trusted key. If 'foundname' is not NULL, then - * it will be updated to contain the name of the closest enclosing - * trust anchor. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result is an error. - */ - -isc_result_t -dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); -/*%< - * Dump the keytable on fp. - */ - -isc_result_t -dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **buf); -/*%< - * Dump the keytable to buffer at 'buf' - */ - -dst_key_t * -dns_keynode_key(dns_keynode_t *keynode); -/*%< - * Get the DST key associated with keynode. - */ - -bool -dns_keynode_managed(dns_keynode_t *keynode); -/*%< - * Is this flagged as a managed key? - */ - -isc_result_t -dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target); -/*%< - * Allocate space for a keynode - */ - -void -dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target); -/*%< - * Attach keynode 'source' to '*target' - */ - -void -dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target); -/*%< - * Detach a single keynode, without touching any keynodes that - * may be pointed to by its 'next' pointer - */ - -void -dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target); -/*%< - * Detach a keynode and all its successors. - */ - -isc_result_t -dns_keytable_forall(dns_keytable_t *keytable, - void (*func)(dns_keytable_t *, dns_keynode_t *, void *), - void *arg); -ISC_LANG_ENDDECLS - -#endif /* DNS_KEYTABLE_H */ diff --git a/lib/dns-pkcs11/include/dns/keyvalues.h b/lib/dns-pkcs11/include/dns/keyvalues.h deleted file mode 100644 index 667f0ab..0000000 --- a/lib/dns-pkcs11/include/dns/keyvalues.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_KEYVALUES_H -#define DNS_KEYVALUES_H 1 - -/*! \file dns/keyvalues.h */ - -/* - * Flags field of the KEY RR rdata - */ -#define DNS_KEYFLAG_TYPEMASK 0xC000 /*%< Mask for "type" bits */ -#define DNS_KEYTYPE_AUTHCONF 0x0000 /*%< Key usable for both */ -#define DNS_KEYTYPE_CONFONLY 0x8000 /*%< Key usable for confidentiality */ -#define DNS_KEYTYPE_AUTHONLY 0x4000 /*%< Key usable for authentication */ -#define DNS_KEYTYPE_NOKEY 0xC000 /*%< No key usable for either; no key */ -#define DNS_KEYTYPE_NOAUTH DNS_KEYTYPE_CONFONLY -#define DNS_KEYTYPE_NOCONF DNS_KEYTYPE_AUTHONLY - -#define DNS_KEYFLAG_RESERVED2 0x2000 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_EXTENDED 0x1000 /*%< key has extended flags */ -#define DNS_KEYFLAG_RESERVED4 0x0800 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED5 0x0400 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_OWNERMASK 0x0300 /*%< these bits determine the type */ -#define DNS_KEYOWNER_USER 0x0000 /*%< key is assoc. with user */ -#define DNS_KEYOWNER_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ -#define DNS_KEYOWNER_ZONE 0x0100 /*%< key is zone key */ -#define DNS_KEYOWNER_RESERVED 0x0300 /*%< reserved meaning */ -#define DNS_KEYFLAG_REVOKE 0x0080 /*%< key revoked (per rfc5011) */ -#define DNS_KEYFLAG_RESERVED9 0x0040 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED10 0x0020 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED11 0x0010 /*%< reserved - must be zero */ -#define DNS_KEYFLAG_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ - -#define DNS_KEYFLAG_RESERVEDMASK (DNS_KEYFLAG_RESERVED2 | \ - DNS_KEYFLAG_RESERVED4 | \ - DNS_KEYFLAG_RESERVED5 | \ - DNS_KEYFLAG_RESERVED9 | \ - DNS_KEYFLAG_RESERVED10 | \ - DNS_KEYFLAG_RESERVED11 ) -#define DNS_KEYFLAG_KSK 0x0001 /*%< key signing key */ - -#define DNS_KEYFLAG_RESERVEDMASK2 0xFFFF /*%< no bits defined here */ - -/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ -#define DNS_KEYALG_RSAMD5 1 /*%< RSA with MD5 */ -#define DNS_KEYALG_RSA DNS_KEYALG_RSAMD5 -#define DNS_KEYALG_DH 2 /*%< Diffie Hellman KEY */ -#define DNS_KEYALG_DSA 3 /*%< DSA KEY */ -#define DNS_KEYALG_NSEC3DSA 6 -#define DNS_KEYALG_DSS DNS_ALG_DSA -#define DNS_KEYALG_ECC 4 -#define DNS_KEYALG_RSASHA1 5 -#define DNS_KEYALG_NSEC3RSASHA1 7 -#define DNS_KEYALG_RSASHA256 8 -#define DNS_KEYALG_RSASHA512 10 -#define DNS_KEYALG_ECCGOST 12 -#define DNS_KEYALG_ECDSA256 13 -#define DNS_KEYALG_ECDSA384 14 -#define DNS_KEYALG_ED25519 15 -#define DNS_KEYALG_ED448 16 -#define DNS_KEYALG_INDIRECT 252 -#define DNS_KEYALG_PRIVATEDNS 253 -#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ - -/* Protocol values */ -#define DNS_KEYPROTO_RESERVED 0 -#define DNS_KEYPROTO_TLS 1 -#define DNS_KEYPROTO_EMAIL 2 -#define DNS_KEYPROTO_DNSSEC 3 -#define DNS_KEYPROTO_IPSEC 4 -#define DNS_KEYPROTO_ANY 255 - -/* Signatures */ -#define DNS_SIG_RSAMINBITS 512 /*%< Size of a mod or exp in bits */ -#define DNS_SIG_RSAMAXBITS 2552 - /* Total of binary mod and exp */ -#define DNS_SIG_RSAMAXBYTES ((DNS_SIG_RSAMAXBITS+7/8)*2+3) - /*%< Max length of text sig block */ -#define DNS_SIG_RSAMAXBASE64 (((DNS_SIG_RSAMAXBYTES+2)/3)*4) -#define DNS_SIG_RSAMINSIZE ((DNS_SIG_RSAMINBITS+7)/8) -#define DNS_SIG_RSAMAXSIZE ((DNS_SIG_RSAMAXBITS+7)/8) - -#define DNS_SIG_DSASIGSIZE 41 -#define DNS_SIG_DSAMINBITS 512 -#define DNS_SIG_DSAMAXBITS 1024 -#define DNS_SIG_DSAMINBYTES 213 -#define DNS_SIG_DSAMAXBYTES 405 - -#define DNS_SIG_GOSTSIGSIZE 64 - -#define DNS_SIG_ECDSA256SIZE 64 -#define DNS_SIG_ECDSA384SIZE 96 - -#define DNS_KEY_ECDSA256SIZE 64 -#define DNS_KEY_ECDSA384SIZE 96 - -#define DNS_SIG_ED25519SIZE 64 -#define DNS_SIG_ED448SIZE 114 - -#define DNS_KEY_ED25519SIZE 32 -#define DNS_KEY_ED448SIZE 57 - -#endif /* DNS_KEYVALUES_H */ diff --git a/lib/dns-pkcs11/include/dns/lib.h b/lib/dns-pkcs11/include/dns/lib.h deleted file mode 100644 index 89a6838..0000000 --- a/lib/dns-pkcs11/include/dns/lib.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_LIB_H -#define DNS_LIB_H 1 - -/*! \file dns/lib.h */ - -#include -#include - -ISC_LANG_BEGINDECLS - -/*% - * Tuning: external query load in packets per seconds. - */ -LIBDNS_EXTERNAL_DATA extern unsigned int dns_pps; -LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dns_msgcat; - -void -dns_lib_initmsgcat(void); -/*%< - * Initialize the DNS library's message catalog, dns_msgcat, if it - * has not already been initialized. - */ - -isc_result_t -dns_lib_init(void); -/*%< - * A set of initialization procedure used in the DNS library. This function - * is provided for an application that is not aware of the underlying ISC or - * DNS libraries much. - */ - -void -dns_lib_shutdown(void); -/*%< - * Free temporary resources allocated in dns_lib_init(). - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_LIB_H */ diff --git a/lib/dns-pkcs11/include/dns/log.h b/lib/dns-pkcs11/include/dns/log.h deleted file mode 100644 index fec54bc..0000000 --- a/lib/dns-pkcs11/include/dns/log.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file dns/log.h - */ - -#ifndef DNS_LOG_H -#define DNS_LOG_H 1 - -#include -#include - -LIBDNS_EXTERNAL_DATA extern isc_log_t *dns_lctx; -LIBDNS_EXTERNAL_DATA extern isc_logcategory_t dns_categories[]; -LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; - -#define DNS_LOGCATEGORY_NOTIFY (&dns_categories[0]) -#define DNS_LOGCATEGORY_DATABASE (&dns_categories[1]) -#define DNS_LOGCATEGORY_SECURITY (&dns_categories[2]) -/* DNS_LOGCATEGORY_CONFIG superseded by CFG_LOGCATEGORY_CONFIG */ -#define DNS_LOGCATEGORY_DNSSEC (&dns_categories[4]) -#define DNS_LOGCATEGORY_RESOLVER (&dns_categories[5]) -#define DNS_LOGCATEGORY_XFER_IN (&dns_categories[6]) -#define DNS_LOGCATEGORY_XFER_OUT (&dns_categories[7]) -#define DNS_LOGCATEGORY_DISPATCH (&dns_categories[8]) -#define DNS_LOGCATEGORY_LAME_SERVERS (&dns_categories[9]) -#define DNS_LOGCATEGORY_DELEGATION_ONLY (&dns_categories[10]) -#define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11]) -#define DNS_LOGCATEGORY_RPZ (&dns_categories[12]) -#define DNS_LOGCATEGORY_RRL (&dns_categories[13]) -#define DNS_LOGCATEGORY_CNAME (&dns_categories[14]) -#define DNS_LOGCATEGORY_SPILL (&dns_categories[15]) -#define DNS_LOGCATEGORY_DNSTAP (&dns_categories[16]) - -/* Backwards compatibility. */ -#define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL - -#define DNS_LOGMODULE_DB (&dns_modules[0]) -#define DNS_LOGMODULE_RBTDB (&dns_modules[1]) -#define DNS_LOGMODULE_RBTDB64 (&dns_modules[2]) -#define DNS_LOGMODULE_RBT (&dns_modules[3]) -#define DNS_LOGMODULE_RDATA (&dns_modules[4]) -#define DNS_LOGMODULE_MASTER (&dns_modules[5]) -#define DNS_LOGMODULE_MESSAGE (&dns_modules[6]) -#define DNS_LOGMODULE_CACHE (&dns_modules[7]) -#define DNS_LOGMODULE_CONFIG (&dns_modules[8]) -#define DNS_LOGMODULE_RESOLVER (&dns_modules[9]) -#define DNS_LOGMODULE_ZONE (&dns_modules[10]) -#define DNS_LOGMODULE_JOURNAL (&dns_modules[11]) -#define DNS_LOGMODULE_ADB (&dns_modules[12]) -#define DNS_LOGMODULE_XFER_IN (&dns_modules[13]) -#define DNS_LOGMODULE_XFER_OUT (&dns_modules[14]) -#define DNS_LOGMODULE_ACL (&dns_modules[15]) -#define DNS_LOGMODULE_VALIDATOR (&dns_modules[16]) -#define DNS_LOGMODULE_DISPATCH (&dns_modules[17]) -#define DNS_LOGMODULE_REQUEST (&dns_modules[18]) -#define DNS_LOGMODULE_MASTERDUMP (&dns_modules[19]) -#define DNS_LOGMODULE_TSIG (&dns_modules[20]) -#define DNS_LOGMODULE_TKEY (&dns_modules[21]) -#define DNS_LOGMODULE_SDB (&dns_modules[22]) -#define DNS_LOGMODULE_DIFF (&dns_modules[23]) -#define DNS_LOGMODULE_HINTS (&dns_modules[24]) -#define DNS_LOGMODULE_ACACHE (&dns_modules[25]) -#define DNS_LOGMODULE_DLZ (&dns_modules[26]) -#define DNS_LOGMODULE_DNSSEC (&dns_modules[27]) -#define DNS_LOGMODULE_CRYPTO (&dns_modules[28]) -#define DNS_LOGMODULE_PACKETS (&dns_modules[29]) -#define DNS_LOGMODULE_NTA (&dns_modules[30]) -#define DNS_LOGMODULE_DYNDB (&dns_modules[31]) -#define DNS_LOGMODULE_DNSTAP (&dns_modules[32]) -#define DNS_LOGMODULE_SSU (&dns_modules[33]) - -ISC_LANG_BEGINDECLS - -void -dns_log_init(isc_log_t *lctx); -/*% - * Make the libdns categories and modules available for use with the - * ISC logging library. - * - * Requires: - *\li lctx is a valid logging context. - * - *\li dns_log_init() is called only once. - * - * Ensures: - * \li The categories and modules defined above are available for - * use by isc_log_usechannnel() and isc_log_write(). - */ - -void -dns_log_setcontext(isc_log_t *lctx); -/*% - * Make the libdns library use the provided context for logging internal - * messages. - * - * Requires: - *\li lctx is a valid logging context. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_LOG_H */ diff --git a/lib/dns-pkcs11/include/dns/lookup.h b/lib/dns-pkcs11/include/dns/lookup.h deleted file mode 100644 index 5bc36b1..0000000 --- a/lib/dns-pkcs11/include/dns/lookup.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_LOOKUP_H -#define DNS_LOOKUP_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/lookup.h - * \brief - * The lookup module performs simple DNS lookups. It implements - * the full resolver algorithm, both looking for local data and - * resolving external names as necessary. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li RFCs: 1034, 1035, 2181, TBS - *\li Drafts: TBS - */ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*% - * A 'dns_lookupevent_t' is returned when a lookup completes. - * The sender field will be set to the lookup that completed. If 'result' - * is ISC_R_SUCCESS, then 'names' will contain a list of names associated - * with the address. The recipient of the event must not change the list - * and must not refer to any of the name data after the event is freed. - */ -typedef struct dns_lookupevent { - ISC_EVENT_COMMON(struct dns_lookupevent); - isc_result_t result; - dns_name_t *name; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - dns_db_t *db; - dns_dbnode_t *node; -} dns_lookupevent_t; - -isc_result_t -dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type, - dns_view_t *view, unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, dns_lookup_t **lookupp); -/*%< - * Finds the rrsets matching 'name' and 'type'. - * - * Requires: - * - *\li 'mctx' is a valid mctx. - * - *\li 'name' is a valid name. - * - *\li 'view' is a valid view which has a resolver. - * - *\li 'task' is a valid task. - * - *\li lookupp != NULL && *lookupp == NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - * - *\li Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be - * returned. - */ - -void -dns_lookup_cancel(dns_lookup_t *lookup); -/*%< - * Cancel 'lookup'. - * - * Notes: - * - *\li If 'lookup' has not completed, post its LOOKUPDONE event with a - * result code of ISC_R_CANCELED. - * - * Requires: - * - *\li 'lookup' is a valid lookup. - */ - -void -dns_lookup_destroy(dns_lookup_t **lookupp); -/*%< - * Destroy 'lookup'. - * - * Requires: - * - *\li '*lookupp' is a valid lookup. - * - *\li The caller has received the LOOKUPDONE event (either because the - * lookup completed or because dns_lookup_cancel() was called). - * - * Ensures: - * - *\li *lookupp == NULL. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_LOOKUP_H */ diff --git a/lib/dns-pkcs11/include/dns/master.h b/lib/dns-pkcs11/include/dns/master.h deleted file mode 100644 index d626636..0000000 --- a/lib/dns-pkcs11/include/dns/master.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_MASTER_H -#define DNS_MASTER_H 1 - -/*! \file dns/master.h */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include - -/* - * Flags to be passed in the 'options' argument in the functions below. - */ -#define DNS_MASTER_AGETTL 0x00000001 /*%< Age the ttl based on $DATE. */ -#define DNS_MASTER_MANYERRORS 0x00000002 /*%< Continue processing on errors. */ -#define DNS_MASTER_NOINCLUDE 0x00000004 /*%< Disallow $INCLUDE directives. */ -#define DNS_MASTER_ZONE 0x00000008 /*%< Loading a zone master file. */ -#define DNS_MASTER_HINT 0x00000010 /*%< Loading a hint master file. */ -#define DNS_MASTER_SLAVE 0x00000020 /*%< Loading a slave master file. */ -#define DNS_MASTER_CHECKNS 0x00000040 /*%< - * Check NS records to see - * if they are an address - */ -#define DNS_MASTER_FATALNS 0x00000080 /*%< - * Treat DNS_MASTER_CHECKNS - * matches as fatal - */ -#define DNS_MASTER_CHECKNAMES 0x00000100 -#define DNS_MASTER_CHECKNAMESFAIL 0x00000200 -#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */ -#define DNS_MASTER_CHECKMX 0x00000800 -#define DNS_MASTER_CHECKMXFAIL 0x00001000 - -#define DNS_MASTER_RESIGN 0x00002000 -#define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */ -#define DNS_MASTER_NOTTL 0x00008000 /*%< Don't require ttl. */ -#define DNS_MASTER_CHECKTTL 0x00010000 /*%< Check max-zone-ttl */ - -ISC_LANG_BEGINDECLS - -/* - * Structures that implement the "raw" format for master dump. - * These are provided for a reference purpose only; in the actual - * encoding, we directly read/write each field so that the encoded data - * is always "packed", regardless of the hardware architecture. - */ -#define DNS_RAWFORMAT_VERSION 1 - -/* - * Flags to indicate the status of the data in the raw file header - */ -#define DNS_MASTERRAW_COMPAT 0x01 -#define DNS_MASTERRAW_SOURCESERIALSET 0x02 -#define DNS_MASTERRAW_LASTXFRINSET 0x04 - -/* Common header */ -struct dns_masterrawheader { - uint32_t format; /* must be - * dns_masterformat_raw - * or - * dns_masterformat_map */ - uint32_t version; /* compatibility for future - * extensions */ - uint32_t dumptime; /* timestamp on creation - * (currently unused) */ - uint32_t flags; /* Flags */ - uint32_t sourceserial; /* Source serial number (used - * by inline-signing zones) */ - uint32_t lastxfrin; /* timestamp of last transfer - * (used by slave zones) */ -}; - -/* The structure for each RRset */ -typedef struct { - uint32_t totallen; /* length of the data for this - * RRset, including the - * "header" part */ - dns_rdataclass_t rdclass; /* 16-bit class */ - dns_rdatatype_t type; /* 16-bit type */ - dns_rdatatype_t covers; /* same as type */ - dns_ttl_t ttl; /* 32-bit TTL */ - uint32_t nrdata; /* number of RRs in this set */ - /* followed by encoded owner name, and then rdata */ -} dns_masterrawrdataset_t; - -/* - * Method prototype: a callback to register each include file as - * it is encountered. - */ -typedef void -(*dns_masterincludecb_t)(const char *file, void *arg); - -/*** - *** Function - ***/ - -isc_result_t -dns_master_loadfile(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx); - -isc_result_t -dns_master_loadfile2(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile3(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile4(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, - void *include_arg, isc_mem_t *mctx, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile5(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, - void *include_arg, isc_mem_t *mctx, - dns_masterformat_t format, - dns_ttl_t maxttl); - -isc_result_t -dns_master_loadstream(FILE *stream, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx); - -isc_result_t -dns_master_loadbuffer(isc_buffer_t *buffer, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx); - -isc_result_t -dns_master_loadlexer(isc_lex_t *lex, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_mem_t *mctx); - -isc_result_t -dns_master_loadfileinc(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx); - -isc_result_t -dns_master_loadfileinc2(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc3(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc4(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc5(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format, - uint32_t maxttl); - -isc_result_t -dns_master_loadstreaminc(FILE *stream, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx); - -isc_result_t -dns_master_loadbufferinc(isc_buffer_t *buffer, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx); - -isc_result_t -dns_master_loadlexerinc(isc_lex_t *lex, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, isc_mem_t *mctx); - -/*%< - * Loads a RFC1305 master file from a file, stream, buffer, or existing - * lexer into rdatasets and then calls 'callbacks->commit' to commit the - * rdatasets. Rdata memory belongs to dns_master_load and will be - * reused / released when the callback completes. dns_load_master will - * abort if callbacks->commit returns any value other than ISC_R_SUCCESS. - * - * If 'DNS_MASTER_AGETTL' is set and the master file contains one or more - * $DATE directives, the TTLs of the data will be aged accordingly. - * - * 'callbacks->commit' is assumed to call 'callbacks->error' or - * 'callbacks->warn' to generate any error messages required. - * - * 'done' is called with 'done_arg' and a result code when the loading - * is completed or has failed. If the initial setup fails 'done' is - * not called. - * - * 'resign' the number of seconds before a RRSIG expires that it should - * be re-signed. 0 is used if not provided. - * - * Requires: - *\li 'master_file' points to a valid string. - *\li 'lexer' points to a valid lexer. - *\li 'top' points to a valid name. - *\li 'origin' points to a valid name. - *\li 'callbacks->commit' points to a valid function. - *\li 'callbacks->error' points to a valid function. - *\li 'callbacks->warn' points to a valid function. - *\li 'mctx' points to a valid memory context. - *\li 'task' and 'done' to be valid. - *\li 'lmgr' to be valid. - *\li 'ctxp != NULL && ctxp == NULL'. - * - * Returns: - *\li ISC_R_SUCCESS upon successfully loading the master file. - *\li ISC_R_SEENINCLUDE upon successfully loading the master file with - * a $INCLUDE statement. - *\li ISC_R_NOMEMORY out of memory. - *\li ISC_R_UNEXPECTEDEND expected to be able to read a input token and - * there was not one. - *\li ISC_R_UNEXPECTED - *\li DNS_R_NOOWNER failed to specify a ownername. - *\li DNS_R_NOTTL failed to specify a ttl. - *\li DNS_R_BADCLASS record class did not match zone class. - *\li DNS_R_CONTINUE load still in progress (dns_master_load*inc() only). - *\li Any dns_rdata_fromtext() error code. - *\li Any error code from callbacks->commit(). - */ - -void -dns_loadctx_detach(dns_loadctx_t **ctxp); -/*%< - * Detach from the load context. - * - * Requires: - *\li '*ctxp' to be valid. - * - * Ensures: - *\li '*ctxp == NULL' - */ - -void -dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target); -/*%< - * Attach to the load context. - * - * Requires: - *\li 'source' to be valid. - *\li 'target != NULL && *target == NULL'. - */ - -void -dns_loadctx_cancel(dns_loadctx_t *ctx); -/*%< - * Cancel loading the zone file associated with this load context. - * - * Requires: - *\li 'ctx' to be valid - */ - -void -dns_master_initrawheader(dns_masterrawheader_t *header); -/*%< - * Initializes the header for a raw master file, setting all - * values to zero. - */ -ISC_LANG_ENDDECLS - -#endif /* DNS_MASTER_H */ diff --git a/lib/dns-pkcs11/include/dns/masterdump.h b/lib/dns-pkcs11/include/dns/masterdump.h deleted file mode 100644 index 948fa65..0000000 --- a/lib/dns-pkcs11/include/dns/masterdump.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_MASTERDUMP_H -#define DNS_MASTERDUMP_H 1 - -/*! \file dns/masterdump.h */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include - -/*** - *** Types - ***/ - -typedef struct dns_master_style dns_master_style_t; - -/*** - *** Definitions - ***/ - -/* - * Flags affecting master file formatting. Flags 0x0000FFFF - * define the formatting of the rdata part and are defined in - * rdata.h. - */ - -/*% Omit the owner name when possible. */ -#define DNS_STYLEFLAG_OMIT_OWNER 0x000010000ULL - -/*% - * Omit the TTL when possible. If DNS_STYLEFLAG_TTL is - * also set, this means no TTLs are ever printed - * because $TTL directives are generated before every - * change in the TTL. In this case, no columns need to - * be reserved for the TTL. Master files generated with - * these options will be rejected by BIND 4.x because it - * does not recognize the $TTL directive. - * - * If DNS_STYLEFLAG_TTL is not also set, the TTL will be - * omitted when it is equal to the previous TTL. - * This is correct according to RFC1035, but the - * TTLs may be silently misinterpreted by older - * versions of BIND which use the SOA MINTTL as a - * default TTL value. - */ -#define DNS_STYLEFLAG_OMIT_TTL 0x000020000ULL - -/*% Omit the class when possible. */ -#define DNS_STYLEFLAG_OMIT_CLASS 0x000040000ULL - -/*% Output $TTL directives. */ -#define DNS_STYLEFLAG_TTL 0x000080000ULL - -/*% - * Output $ORIGIN directives and print owner names relative to - * the origin when possible. - */ -#define DNS_STYLEFLAG_REL_OWNER 0x000100000ULL - -/*% Print domain names in RR data in relative form when possible. - For this to take effect, DNS_STYLEFLAG_REL_OWNER must also be set. */ -#define DNS_STYLEFLAG_REL_DATA 0x000200000ULL - -/*% Print the trust level of each rdataset. */ -#define DNS_STYLEFLAG_TRUST 0x000400000ULL - -/*% Print negative caching entries. */ -#define DNS_STYLEFLAG_NCACHE 0x000800000ULL - -/*% Never print the TTL. */ -#define DNS_STYLEFLAG_NO_TTL 0x001000000ULL - -/*% Never print the CLASS. */ -#define DNS_STYLEFLAG_NO_CLASS 0x002000000ULL - -/*% Report re-signing time. */ -#define DNS_STYLEFLAG_RESIGN 0x004000000ULL - -/*% Don't printout the cryptographic parts of DNSSEC records. */ -#define DNS_STYLEFLAG_NOCRYPTO 0x008000000ULL - -/*% Comment out data by prepending with ";" */ -#define DNS_STYLEFLAG_COMMENTDATA 0x010000000ULL - -/*% Print TTL with human-readable units. */ -#define DNS_STYLEFLAG_TTL_UNITS 0x020000000ULL - -/*% Indent output. */ -#define DNS_STYLEFLAG_INDENT 0x040000000ULL - -/*% Output in YAML style. */ -#define DNS_STYLEFLAG_YAML 0x080000000ULL - -/*% Print ECS cache entries as comments (reserved for future use). */ -#define DNS_STYLEFLAG_ECSCACHE 0x100000000ULL - -ISC_LANG_BEGINDECLS - -/*** - *** Constants - ***/ - -/*% - * The default master file style. - * - * This uses $TTL directives to avoid the need to dedicate a - * tab stop for the TTL. The class is only printed for the first - * rrset in the file and shares a tab stop with the RR type. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_default; - -/*% - * A master file style that dumps zones to a very generic format easily - * imported/checked with external tools. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_full; - -/*% - * A master file style that prints explicit TTL values on each - * record line, never using $TTL statements. The TTL has a tab - * stop of its own, but the class and type share one. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t - dns_master_style_explicitttl; - -/*% - * A master style format designed for cache files. It prints explicit TTL - * values on each record line and never uses $ORIGIN or relative names. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_cache; - -/*% - * A master style that prints name, ttl, class, type, and value on - * every line. Similar to explicitttl above, but more verbose. - * Intended for generating master files which can be easily parsed - * by perl scripts and similar applications. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_simple; - -/*% - * The style used for debugging, "dig" output, etc. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug; - -/*% - * Similar to dns_master_style_debug but data is prepended with ";" - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_comment; - -/*% - * Similar to dns_master_style_debug but data is indented with - * dns_master_indentstr (defaults to tab). - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_indent; - -/*% - * The style used for dumping "key" zones. - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_keyzone; - -/*% - * YAML-compatible output - */ -LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_yaml; - -/*% - * The default indent string to prepend lines with when using - * styleflag DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML. - * This is set to "\t" by default. The indent is repeated - * 'dns_master_indent' times. This precedes everything else - * on the line, including comment characters (;). - * - * XXX: Changing this value at runtime is not thread-safe. - */ -LIBDNS_EXTERNAL_DATA extern const char *dns_master_indentstr; - -/*% - * The number of copies of the indent string to put at the beginning - * of the line when using DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML. - * This is set to 1 by default. It is increased and decreased - * to adjust indentation levels when producing YAML output. - * - * XXX: This is not thread-safe. - */ -LIBDNS_EXTERNAL_DATA extern unsigned int dns_master_indent; - -/*** - *** Functions - ***/ - -void -dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target); -/*%< - * Attach to a dump context. - * - * Require: - *\li 'source' to be valid. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_dumpctx_detach(dns_dumpctx_t **dctxp); -/*%< - * Detach from a dump context. - * - * Require: - *\li 'dctxp' to point to a valid dump context. - * - * Ensures: - *\li '*dctxp' is NULL. - */ - -void -dns_dumpctx_cancel(dns_dumpctx_t *dctx); -/*%< - * Cancel a in progress dump. - * - * Require: - *\li 'dctx' to be valid. - */ - -dns_dbversion_t * -dns_dumpctx_version(dns_dumpctx_t *dctx); -/*%< - * Return the version handle (if any) of the database being dumped. - * - * Require: - *\li 'dctx' to be valid. - */ - -dns_db_t * -dns_dumpctx_db(dns_dumpctx_t *dctx); -/*%< - * Return the database being dumped. - * - * Require: - *\li 'dctx' to be valid. - */ - - -/*@{*/ -isc_result_t -dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, FILE *f, - isc_task_t *task, dns_dumpdonefunc_t done, - void *done_arg, dns_dumpctx_t **dctxp); - -isc_result_t -dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, FILE *f); - -isc_result_t -dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - dns_masterformat_t format, FILE *f); - -isc_result_t -dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - dns_masterformat_t format, - dns_masterrawheader_t *header, FILE *f); -/*%< - * Dump the database 'db' to the steam 'f' in the specified format by - * 'format'. If the format is dns_masterformat_text (the RFC1035 format), - * 'style' specifies the file style (e.g., &dns_master_style_default). - * - * dns_master_dumptostream() is an old form of dns_master_dumptostream3(), - * which always specifies the dns_masterformat_text format. - * dns_master_dumptostream2() is an old form which always specifies - * a NULL header. - * - * If 'format' is dns_masterformat_raw, then 'header' can contain - * information to be written to the file header. - * - * Temporary dynamic memory may be allocated from 'mctx'. - * - * Require: - *\li 'task' to be valid. - *\li 'done' to be non NULL. - *\li 'dctxp' to be non NULL && '*dctxp' to be NULL. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_CONTINUE dns_master_dumptostreaminc() only. - *\li ISC_R_NOMEMORY - *\li Any database or rrset iterator error. - *\li Any dns_rdata_totext() error code. - */ -/*@}*/ - -/*@{*/ -isc_result_t -dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, - dns_dumpctx_t **dctxp); - -isc_result_t -dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format); - -isc_result_t -dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void - *done_arg, dns_dumpctx_t **dctxp, - dns_masterformat_t format, dns_masterrawheader_t *header); - -isc_result_t -dns_master_dump(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename); - -isc_result_t -dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - dns_masterformat_t format); - -isc_result_t -dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - dns_masterformat_t format, dns_masterrawheader_t *header); - -/*%< - * Dump the database 'db' to the file 'filename' in the specified format by - * 'format'. If the format is dns_masterformat_text (the RFC1035 format), - * 'style' specifies the file style (e.g., &dns_master_style_default). - * - * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3() - * and _dump3(), respectively, which always specify the dns_masterformat_text - * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which - * always specify a NULL header. - * - * If 'format' is dns_masterformat_raw, then 'header' can contain - * information to be written to the file header. - * - * Temporary dynamic memory may be allocated from 'mctx'. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_CONTINUE dns_master_dumpinc() only. - *\li ISC_R_NOMEMORY - *\li Any database or rrset iterator error. - *\li Any dns_rdata_totext() error code. - */ -/*@}*/ - -isc_result_t -dns_master_rdatasettotext(dns_name_t *owner_name, - dns_rdataset_t *rdataset, - const dns_master_style_t *style, - isc_buffer_t *target); -/*%< - * Convert 'rdataset' to text format, storing the result in 'target'. - * - * Notes: - *\li The rdata cursor position will be changed. - * - * Requires: - *\li 'rdataset' is a valid non-question rdataset. - * - *\li 'rdataset' is not empty. - */ - -isc_result_t -dns_master_questiontotext(dns_name_t *owner_name, - dns_rdataset_t *rdataset, - const dns_master_style_t *style, - isc_buffer_t *target); - -isc_result_t -dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *name, - const dns_master_style_t *style, - FILE *f); - -isc_result_t -dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *name, - const dns_master_style_t *style, const char *filename); - -dns_masterstyle_flags_t -dns_master_styleflags(const dns_master_style_t *style); - -isc_result_t -dns_master_stylecreate(dns_master_style_t **style, unsigned int flags, - unsigned int ttl_column, unsigned int class_column, - unsigned int type_column, unsigned int rdata_column, - unsigned int line_length, unsigned int tab_width, - isc_mem_t *mctx); - -isc_result_t -dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags, - unsigned int ttl_column, unsigned int class_column, - unsigned int type_column, unsigned int rdata_column, - unsigned int line_length, unsigned int tab_width, - unsigned int split_width, isc_mem_t *mctx); - -void -dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx); - -ISC_LANG_ENDDECLS - -#endif /* DNS_MASTERDUMP_H */ diff --git a/lib/dns-pkcs11/include/dns/message.h b/lib/dns-pkcs11/include/dns/message.h deleted file mode 100644 index f64522b..0000000 --- a/lib/dns-pkcs11/include/dns/message.h +++ /dev/null @@ -1,1452 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_MESSAGE_H -#define DNS_MESSAGE_H 1 - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -/*! \file dns/message.h - * \brief Message Handling Module - * - * How this beast works: - * - * When a dns message is received in a buffer, dns_message_parse() is called - * on the memory region. Various items are checked including the format - * of the message (if counts are right, if counts consume the entire sections, - * and if sections consume the entire message) and known pseudo-RRs in the - * additional data section are analyzed and removed. - * - * TSIG checking is also done at this layer, and any DNSSEC transaction - * signatures should also be checked here. - * - * Notes on using the gettemp*() and puttemp*() functions: - * - * These functions return items (names, rdatasets, etc) allocated from some - * internal state of the dns_message_t. - * - * Names and rdatasets must be put back into the dns_message_t in - * one of two ways. Assume a name was allocated via - * dns_message_gettempname(): - * - *\li (1) insert it into a section, using dns_message_addname(). - * - *\li (2) return it to the message using dns_message_puttempname(). - * - * The same applies to rdatasets. - * - * On the other hand, offsets, rdatalists and rdatas allocated using - * dns_message_gettemp*() will always be freed automatically - * when the message is reset or destroyed; calling dns_message_puttemp*() - * on rdatalists and rdatas is optional and serves only to enable the item - * to be reused multiple times during the lifetime of the message; offsets - * cannot be reused. - * - * Buffers allocated using isc_buffer_allocate() can be automatically freed - * as well by giving the buffer to the message using dns_message_takebuffer(). - * Doing this will cause the buffer to be freed using isc_buffer_free() - * when the section lists are cleared, such as in a reset or in a destroy. - * Since the buffer itself exists until the message is destroyed, this sort - * of code can be written: - * - * \code - * buffer = isc_buffer_allocate(mctx, 512); - * name = NULL; - * name = dns_message_gettempname(message, &name); - * dns_name_init(name, NULL); - * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); - * dns_message_takebuffer(message, &buffer); - * \endcode - * - * - * TODO: - * - * XXX Needed: ways to set and retrieve EDNS information, add rdata to a - * section, move rdata from one section to another, remove rdata, etc. - */ - -#define DNS_MESSAGEFLAG_QR 0x8000U -#define DNS_MESSAGEFLAG_AA 0x0400U -#define DNS_MESSAGEFLAG_TC 0x0200U -#define DNS_MESSAGEFLAG_RD 0x0100U -#define DNS_MESSAGEFLAG_RA 0x0080U -#define DNS_MESSAGEFLAG_AD 0x0020U -#define DNS_MESSAGEFLAG_CD 0x0010U - -/*%< EDNS0 extended message flags */ -#define DNS_MESSAGEEXTFLAG_DO 0x8000U - -/*%< EDNS0 extended OPT codes */ -#define DNS_OPT_LLQ 1 /*%< LLQ opt code */ -#define DNS_OPT_NSID 3 /*%< NSID opt code */ -#define DNS_OPT_CLIENT_SUBNET 8 /*%< client subnet opt code */ -#define DNS_OPT_EXPIRE 9 /*%< EXPIRE opt code */ -#define DNS_OPT_COOKIE 10 /*%< COOKIE opt code */ -#define DNS_OPT_TCP_KEEPALIVE 11 /*%< TCP keepalive opt code */ -#define DNS_OPT_PAD 12 /*%< PAD opt code */ -#define DNS_OPT_KEY_TAG 14 /*%< Key tag opt code */ -#define DNS_OPT_EDE 15 /*%< Extended DNS Error opt code */ -#define DNS_OPT_CLIENT_TAG 16 /*%< Client tag opt code */ -#define DNS_OPT_SERVER_TAG 17 /*%< Server tag opt code */ - -/*%< Experimental options [65001...65534] as per RFC6891 */ - -/*%< The number of EDNS options we know about. */ -#define DNS_EDNSOPTIONS 5 - -#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) -#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) - -#define DNS_MESSAGE_HEADERLEN 12 /*%< 6 uint16_t's */ - -#define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') -#define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) - -/* - * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, - * and DNS_SECTION_MAX must be one greater than the last used section. - */ -typedef int dns_section_t; -#define DNS_SECTION_ANY (-1) -#define DNS_SECTION_QUESTION 0 -#define DNS_SECTION_ANSWER 1 -#define DNS_SECTION_AUTHORITY 2 -#define DNS_SECTION_ADDITIONAL 3 -#define DNS_SECTION_MAX 4 - -typedef int dns_pseudosection_t; -#define DNS_PSEUDOSECTION_ANY (-1) -#define DNS_PSEUDOSECTION_OPT 0 -#define DNS_PSEUDOSECTION_TSIG 1 -#define DNS_PSEUDOSECTION_SIG0 2 -#define DNS_PSEUDOSECTION_MAX 3 - -typedef int dns_messagetextflag_t; -#define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 -#define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 -#define DNS_MESSAGETEXTFLAG_ONESOA 0x0004 -#define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008 - -/* - * Dynamic update names for these sections. - */ -#define DNS_SECTION_ZONE DNS_SECTION_QUESTION -#define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER -#define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY - -/* - * These tell the message library how the created dns_message_t will be used. - */ -#define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ -#define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ -#define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ - -/* - * Control behavior of parsing - */ -#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */ -#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a - recoverable parse error - occurs */ -#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the - source buffer */ -#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are - * not fatal. */ - -/* - * Control behavior of rendering - */ -#define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */ -#define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */ -#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */ -#define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in - additional section. */ -#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in - additional section. */ -#ifdef ALLOW_FILTER_AAAA -#define DNS_MESSAGERENDER_FILTER_AAAA 0x0020 /*%< filter AAAA records */ -#endif - -typedef struct dns_msgblock dns_msgblock_t; - -struct dns_message { - /* public from here down */ - unsigned int magic; - isc_refcount_t refcount; - - dns_messageid_t id; - unsigned int flags; - dns_rcode_t rcode; - dns_opcode_t opcode; - dns_rdataclass_t rdclass; - - /* 4 real, 1 pseudo */ - unsigned int counts[DNS_SECTION_MAX]; - - /* private from here down */ - dns_namelist_t sections[DNS_SECTION_MAX]; - dns_name_t *cursors[DNS_SECTION_MAX]; - dns_rdataset_t *opt; - dns_rdataset_t *sig0; - dns_rdataset_t *tsig; - - int state; - unsigned int from_to_wire : 2; - unsigned int header_ok : 1; - unsigned int question_ok : 1; - unsigned int tcp_continuation : 1; - unsigned int verified_sig : 1; - unsigned int verify_attempted : 1; - unsigned int free_query : 1; - unsigned int free_saved : 1; - unsigned int cc_ok : 1; - unsigned int cc_bad : 1; - unsigned int tkey : 1; - unsigned int rdclass_set : 1; - - unsigned int opt_reserved; - unsigned int sig_reserved; - unsigned int reserved; /* reserved space (render) */ - - isc_buffer_t *buffer; - dns_compress_t *cctx; - - isc_mem_t *mctx; - isc_mempool_t *namepool; - isc_mempool_t *rdspool; - - isc_bufferlist_t scratchpad; - isc_bufferlist_t cleanup; - - ISC_LIST(dns_msgblock_t) rdatas; - ISC_LIST(dns_msgblock_t) rdatalists; - ISC_LIST(dns_msgblock_t) offsets; - - ISC_LIST(dns_rdata_t) freerdata; - ISC_LIST(dns_rdatalist_t) freerdatalist; - - dns_rcode_t tsigstatus; - dns_rcode_t querytsigstatus; - dns_name_t *tsigname; /* Owner name of TSIG, if any */ - dns_rdataset_t *querytsig; - dns_tsigkey_t *tsigkey; - dst_context_t *tsigctx; - int sigstart; - int timeadjust; - - dns_name_t *sig0name; /* Owner name of SIG0, if any */ - dst_key_t *sig0key; - dns_rcode_t sig0status; - isc_region_t query; - isc_region_t saved; - - dns_rdatasetorderfunc_t order; - const void * order_arg; - - dns_indent_t indent; -}; - -struct dns_ednsopt { - uint16_t code; - uint16_t length; - unsigned char *value; -}; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); - -/*%< - * Create msg structure. - * - * This function will allocate some internal blocks of memory that are - * expected to be needed for parsing or rendering nearly any type of message. - * - * Requires: - *\li 'mctx' be a valid memory context. - * - *\li 'msgp' be non-null and '*msg' be NULL. - * - *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or - * #DNS_MESSAGE_INTENTRENDER. - * - * Ensures: - *\li The data in "*msg" is set to indicate an unused and empty msg - * structure. - * - * Returns: - *\li #ISC_R_NOMEMORY -- out of memory - *\li #ISC_R_SUCCESS -- success - */ - -void -dns_message_reset(dns_message_t *msg, unsigned int intent); -/*%< - * Reset a message structure to default state. All internal lists are freed - * or reset to a default state as well. This is simply a more efficient - * way to call dns_message_detach() (assuming last reference is hold), - * followed by dns_message_create(), since it avoid many memory allocations. - * - * If any data loanouts (buffers, names, rdatas, etc) were requested, - * the caller must no longer use them after this call. - * - * The intended next use of the message will be 'intent'. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER - */ - -void -dns_message_attach(dns_message_t *source, dns_message_t **target); -/*%< - * Attach to message 'source'. - * - * Requires: - *\li 'source' to be a valid message. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_message_detach(dns_message_t **messagep); -/*%< - * Detach *messagep from its message. - * list. - * - * Requires: - *\li '*messagep' to be a valid message. - */ - -isc_result_t -dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, - const dns_master_style_t *style, - dns_messagetextflag_t flags, - isc_buffer_t *target); - -isc_result_t -dns_message_pseudosectiontotext(dns_message_t *msg, - dns_pseudosection_t section, - const dns_master_style_t *style, - dns_messagetextflag_t flags, - isc_buffer_t *target); -/*%< - * Convert section 'section' or 'pseudosection' of message 'msg' to - * a cleartext representation - * - * Notes: - * \li See dns_message_totext for meanings of flags. - * - * Requires: - * - *\li 'msg' is a valid message. - * - *\li 'style' is a valid master dump style. - * - *\li 'target' is a valid buffer. - * - *\li 'section' is a valid section label. - * - * Ensures: - * - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - *\li #ISC_R_NOMORE - * - *\li Note: On error return, *target may be partially filled with data. -*/ - -isc_result_t -dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, - dns_messagetextflag_t flags, isc_buffer_t *target); -/*%< - * Convert all sections of message 'msg' to a cleartext representation - * - * Notes on flags: - *\li If #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning with - * ";;" will be emitted indicating section name. - *\li If #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will be - * emitted. - *\li If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the first - * SOA record in the answer section. - *\li If *#DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records - * in the answer section. - * - * The SOA flags are useful for suppressing the display of the second - * SOA record in an AXFR by setting #DNS_MESSAGETEXTFLAG_ONESOA on the - * first message in an AXFR stream and #DNS_MESSAGETEXTFLAG_OMITSOA on - * subsequent messages. - * - * Requires: - * - *\li 'msg' is a valid message. - * - *\li 'style' is a valid master dump style. - * - *\li 'target' is a valid buffer. - * - * Ensures: - * - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - *\li #ISC_R_NOMORE - * - *\li Note: On error return, *target may be partially filled with data. - */ - -isc_result_t -dns_message_parse(dns_message_t *msg, isc_buffer_t *source, - unsigned int options); -/*%< - * Parse raw wire data in 'source' as a DNS message. - * - * OPT records are detected and stored in the pseudo-section "opt". - * TSIGs are detected and stored in the pseudo-section "tsig". - * - * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message - * is UPDATE, a separate dns_name_t object will be created for each RR in the - * message. Each such dns_name_t will have a single rdataset containing the - * single RR, and the order of the RRs in the message is preserved. - * Otherwise, only one dns_name_t object will be created for each unique - * owner name in the section, and each such dns_name_t will have a list - * of rdatasets. To access the names and their data, use - * dns_message_firstname() and dns_message_nextname(). - * - * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will - * not be considered FORMERRs. If the entire message can be parsed, it - * will be returned and DNS_R_RECOVERABLE will be returned. - * - * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete - * RR's as possible, DNS_R_RECOVERABLE will be returned. - * - * OPT and TSIG records are always handled specially, regardless of the - * 'preserve_order' setting. - * - * Requires: - *\li "msg" be valid. - * - *\li "buffer" be a wire format buffer. - * - * Ensures: - *\li The buffer's data format is correct. - * - *\li The buffer's contents verify as correct regarding header bits, buffer - * and rdata sizes, etc. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well - *\li #ISC_R_NOMEMORY -- no memory - *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained - * errors. - *\li Many other errors possible XXXMLG - */ - -isc_result_t -dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, - isc_buffer_t *buffer); -/*%< - * Begin rendering on a message. Only one call can be made to this function - * per message. - * - * The compression context is "owned" by the message library until - * dns_message_renderend() is called. It must be invalidated by the caller. - * - * The buffer is "owned" by the message library until dns_message_renderend() - * is called. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'cctx' be valid. - * - *\li 'buffer' is a valid buffer. - * - * Side Effects: - * - *\li The buffer is cleared before it is used. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well - *\li #ISC_R_NOSPACE -- output buffer is too small - */ - -isc_result_t -dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); -/*%< - * Reset the buffer. This can be used after growing the old buffer - * on a ISC_R_NOSPACE return from most of the render functions. - * - * On successful completion, the old buffer is no longer used by the - * library. The new buffer is owned by the library until - * dns_message_renderend() is called. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li dns_message_renderbegin() was called. - * - *\li buffer != NULL. - * - * Returns: - *\li #ISC_R_NOSPACE -- new buffer is too small - *\li #ISC_R_SUCCESS -- all is well. - */ - -isc_result_t -dns_message_renderreserve(dns_message_t *msg, unsigned int space); -/*%< - * XXXMLG should use size_t rather than unsigned int once the buffer - * API is cleaned up - * - * Reserve "space" bytes in the given buffer. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li dns_message_renderbegin() was called. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well. - *\li #ISC_R_NOSPACE -- not enough free space in the buffer. - */ - -void -dns_message_renderrelease(dns_message_t *msg, unsigned int space); -/*%< - * XXXMLG should use size_t rather than unsigned int once the buffer - * API is cleaned up - * - * Release "space" bytes in the given buffer that was previously reserved. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'space' is less than or equal to the total amount of space reserved - * via prior calls to dns_message_renderreserve(). - * - *\li dns_message_renderbegin() was called. - */ - -isc_result_t -dns_message_rendersection(dns_message_t *msg, dns_section_t section, - unsigned int options); -/*%< - * Render all names, rdatalists, etc from the given section at the - * specified priority or higher. - * - * Requires: - *\li 'msg' be valid. - * - *\li 'section' be a valid section. - * - *\li dns_message_renderbegin() was called. - * - * Returns: - *\li #ISC_R_SUCCESS -- all records were written, and there are - * no more records for this section. - *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write - * all records requested. - *\li #DNS_R_MOREDATA -- All requested records written, and there - * are records remaining for this section. - */ - -void -dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); -/*%< - * Render the message header. This is implicitly called by - * dns_message_renderend(). - * - * Requires: - * - *\li 'msg' be a valid message. - * - *\li dns_message_renderbegin() was called. - * - *\li 'target' is a valid buffer with enough space to hold a message header - */ - -isc_result_t -dns_message_renderend(dns_message_t *msg); -/*%< - * Finish rendering to the buffer. Note that more data can be in the - * 'msg' structure. Destroying the structure will free this, or in a multi- - * part EDNS1 message this data can be rendered to another buffer later. - * - * Requires: - * - *\li 'msg' be a valid message. - * - *\li dns_message_renderbegin() was called. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well. - */ - -void -dns_message_renderreset(dns_message_t *msg); -/*%< - * Reset the message so that it may be rendered again. - * - * Notes: - * - *\li If dns_message_renderbegin() has been called, dns_message_renderend() - * must be called before calling this function. - * - * Requires: - * - *\li 'msg' be a valid message with rendering intent. - */ - -isc_result_t -dns_message_firstname(dns_message_t *msg, dns_section_t section); -/*%< - * Set internal per-section name pointer to the beginning of the section. - * - * The functions dns_message_firstname() and dns_message_nextname() may - * be used for iterating over the owner names in a section. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'section' be a valid section. - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMORE -- No names on given section. - */ - -isc_result_t -dns_message_nextname(dns_message_t *msg, dns_section_t section); -/*%< - * Sets the internal per-section name pointer to point to the next name - * in that section. - * - * Requires: - * - * \li 'msg' be valid. - * - *\li 'section' be a valid section. - * - *\li dns_message_firstname() must have been called on this section, - * and the result was ISC_R_SUCCESS. - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMORE -- No more names in given section. - */ - -void -dns_message_currentname(dns_message_t *msg, dns_section_t section, - dns_name_t **name); -/*%< - * Sets 'name' to point to the name where the per-section internal name - * pointer is currently set. - * - * This function returns the name in the database, so any data associated - * with it (via the name's "list" member) contains the actual rdatasets. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'name' be non-NULL, and *name be NULL. - * - *\li 'section' be a valid section. - * - *\li dns_message_firstname() must have been called on this section, - * and the result of it and any dns_message_nextname() calls was - * #ISC_R_SUCCESS. - */ - -isc_result_t -dns_message_findname(dns_message_t *msg, dns_section_t section, - dns_name_t *target, dns_rdatatype_t type, - dns_rdatatype_t covers, dns_name_t **foundname, - dns_rdataset_t **rdataset); -/*%< - * Search for a name in the specified section. If it is found, *name is - * set to point to the name, and *rdataset is set to point to the found - * rdataset (if type is specified as other than dns_rdatatype_any). - * - * Requires: - *\li 'msg' be valid. - * - *\li 'section' be a valid section. - * - *\li If a pointer to the name is desired, 'foundname' should be non-NULL. - * If it is non-NULL, '*foundname' MUST be NULL. - * - *\li If a type other than dns_datatype_any is searched for, 'rdataset' - * may be non-NULL, '*rdataset' be NULL, and will point at the found - * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. - * - *\li 'target' be a valid name. - * - *\li 'type' be a valid type. - * - *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. - * Otherwise it should be 0. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well. - *\li #DNS_R_NXDOMAIN -- name does not exist in that section. - *\li #DNS_R_NXRRSET -- The name does exist, but the desired - * type does not. - */ - -isc_result_t -dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, - dns_rdatatype_t covers, dns_rdataset_t **rdataset); -/*%< - * Search the name for the specified type. If it is found, *rdataset is - * filled in with a pointer to that rdataset. - * - * Requires: - *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. - * - *\li 'type' be a valid type, and NOT dns_rdatatype_any. - * - *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. - * Otherwise it should be 0. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well. - *\li #ISC_R_NOTFOUND -- the desired type does not exist. - */ - -isc_result_t -dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, - dns_rdatatype_t type, dns_rdatatype_t covers, - dns_rdataset_t **rdataset); -/*%< - * Search the name for the specified rdclass and type. If it is found, - * *rdataset is filled in with a pointer to that rdataset. - * - * Requires: - *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. - * - *\li 'type' be a valid type, and NOT dns_rdatatype_any. - * - *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. - * Otherwise it should be 0. - * - * Returns: - *\li #ISC_R_SUCCESS -- all is well. - *\li #ISC_R_NOTFOUND -- the desired type does not exist. - */ - -void -dns_message_movename(dns_message_t *msg, dns_name_t *name, - dns_section_t fromsection, - dns_section_t tosection); -/*%< - * Move a name from one section to another. - * - * Requires: - * - *\li 'msg' be valid. - * - *\li 'name' must be a name already in 'fromsection'. - * - *\li 'fromsection' must be a valid section. - * - *\li 'tosection' must be a valid section. - */ - -void -dns_message_addname(dns_message_t *msg, dns_name_t *name, - dns_section_t section); -/*%< - * Adds the name to the given section. - * - * It is the caller's responsibility to enforce any unique name requirements - * in a section. - * - * Requires: - * - *\li 'msg' be valid, and be a renderable message. - * - *\li 'name' be a valid absolute name. - * - *\li 'section' be a named section. - */ - -void -dns_message_removename(dns_message_t *msg, dns_name_t *name, - dns_section_t section); -/*%< - * Remove a existing name from a given section. - * - * It is the caller's responsibility to ensure the name is part of the - * given section. - * - * Requires: - * - *\li 'msg' be valid, and be a renderable message. - * - *\li 'name' be a valid absolute name. - * - *\li 'section' be a named section. - */ - - -/* - * LOANOUT FUNCTIONS - * - * Each of these functions loan a particular type of data to the caller. - * The storage for these will vanish when the message is destroyed or - * reset, and must NOT be used after these operations. - */ - -isc_result_t -dns_message_gettempname(dns_message_t *msg, dns_name_t **item); -/*%< - * Return a name that can be used for any temporary purpose, including - * inserting into the message's linked lists. The name must be returned - * to the message code using dns_message_puttempname() or inserted into - * one of the message's sections before the message is destroyed. - * - * It is the caller's responsibility to initialize this name. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -isc_result_t -dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); -/*%< - * Return an offsets array that can be used for any temporary purpose, - * such as attaching to a temporary name. The offsets will be freed - * when the message is destroyed or reset. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -isc_result_t -dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); -/*%< - * Return a rdata that can be used for any temporary purpose, including - * inserting into the message's linked lists. The rdata will be freed - * when the message is destroyed or reset. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -isc_result_t -dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); -/*%< - * Return a rdataset that can be used for any temporary purpose, including - * inserting into the message's linked lists. The name must be returned - * to the message code using dns_message_puttempname() or inserted into - * one of the message's sections before the message is destroyed. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -isc_result_t -dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); -/*%< - * Return a rdatalist that can be used for any temporary purpose, including - * inserting into the message's linked lists. The rdatalist will be - * destroyed when the message is destroyed or reset. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -void -dns_message_puttempname(dns_message_t *msg, dns_name_t **item); -/*%< - * Return a borrowed name to the message's name free list. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item point to a name returned by - * dns_message_gettempname() - * - * Ensures: - *\li *item == NULL - */ - -void -dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); -/*%< - * Return a borrowed rdata to the message's rdata free list. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item point to a rdata returned by - * dns_message_gettemprdata() - * - * Ensures: - *\li *item == NULL - */ - -void -dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); -/*%< - * Return a borrowed rdataset to the message's rdataset free list. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item point to a rdataset returned by - * dns_message_gettemprdataset() - * - * Ensures: - *\li *item == NULL - */ - -void -dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); -/*%< - * Return a borrowed rdatalist to the message's rdatalist free list. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item point to a rdatalist returned by - * dns_message_gettemprdatalist() - * - * Ensures: - *\li *item == NULL - */ - -isc_result_t -dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, - unsigned int *flagsp); -/*%< - * Assume the remaining region of "source" is a DNS message. Peek into - * it and fill in "*idp" with the message id, and "*flagsp" with the flags. - * - * Requires: - * - *\li source != NULL - * - * Ensures: - * - *\li if (idp != NULL) *idp == message id. - * - *\li if (flagsp != NULL) *flagsp == message flags. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - * - *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. - */ - -isc_result_t -dns_message_reply(dns_message_t *msg, bool want_question_section); -/*%< - * Start formatting a reply to the query in 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message with parsing intent, and contains a query. - * - * Ensures: - * - *\li The message will have a rendering intent. If 'want_question_section' - * is true, the message opcode is query or notify, and the question - * section is present and properly formatted, then the question section - * will be included in the reply. All other sections will be cleared. - * The QR flag will be set, the RD flag will be preserved, and all other - * flags will be cleared. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - * - *\li #DNS_R_FORMERR -- the header or question section of the - * message is invalid, replying is impossible. - * If DNS_R_FORMERR is returned when - * want_question_section is false, then - * it's the header section that's bad; - * otherwise either of the header or question - * sections may be bad. - */ - -dns_rdataset_t * -dns_message_getopt(dns_message_t *msg); -/*%< - * Get the OPT record for 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message. - * - * Returns: - * - *\li The OPT rdataset of 'msg', or NULL if there isn't one. - */ - -isc_result_t -dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); -/*%< - * Set the OPT record for 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message with rendering intent - * and no sections have been rendered. - * - *\li 'opt' is a valid OPT record. - * - * Ensures: - * - *\li The OPT record has either been freed or ownership of it has - * been transferred to the message. - * - *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered - * when dns_message_renderend() is called. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - * - *\li #ISC_R_NOSPACE -- there is no space for the OPT record. - */ - -dns_rdataset_t * -dns_message_gettsig(dns_message_t *msg, dns_name_t **owner); -/*%< - * Get the TSIG record and owner for 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message. - *\li 'owner' is NULL or *owner is NULL. - * - * Returns: - * - *\li The TSIG rdataset of 'msg', or NULL if there isn't one. - * - * Ensures: - * - * \li If 'owner' is not NULL, it will point to the owner name. - */ - -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 - * query or parsing a response. The key (if non-NULL) is attached to, and - * will be detached when the message is destroyed. - * - * Requires: - * - *\li 'msg' is a valid message with rendering intent, - * dns_message_renderbegin() has been called, and no sections have been - * rendered. - *\li 'key' is a valid tsig key or NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - * - *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. - */ - -dns_tsigkey_t * -dns_message_gettsigkey(dns_message_t *msg); -/*%< - * Gets the tsig key for 'msg'. - * - * Requires: - * - *\li '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: - * - *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() - * or NULL - * - *\li 'msg' is a valid message - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #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: - * - *\li 'msg' is a valid signed message - *\li 'mctx' is a valid memory context - *\li querytsig != NULL && *querytsig == NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - * - * Ensures: - *\li '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); -/*%< - * Get the SIG(0) record and owner for 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message. - *\li 'owner' is NULL or *owner is NULL. - * - * Returns: - * - *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. - * - * Ensures: - * - * \li If 'owner' is not NULL, it will point to the owner name. - */ - -isc_result_t -dns_message_setsig0key(dns_message_t *msg, dst_key_t *key); -/*%< - * Set the SIG(0) key for 'msg'. - * - * Requires: - * - *\li 'msg' is a valid message with rendering intent, - * dns_message_renderbegin() has been called, and no sections have been - * rendered. - *\li 'key' is a valid sig key or NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS -- all is well. - * - *\li #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: - * - *\li 'msg' is a valid message - */ - -void -dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); -/*%< - * Give the *buffer to the message code to clean up when it is no - * longer needed. This is usually when the message is reset or - * destroyed. - * - * Requires: - * - *\li msg be a valid message. - * - *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was - * dynamically allocated via isc_buffer_allocate(). - */ - -isc_result_t -dns_message_signer(dns_message_t *msg, dns_name_t *signer); -/*%< - * If this message was signed, return the identity of the signer. - * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the - * key that signed the message. - * - * Requires: - * - *\li msg is a valid parsed message. - *\li signer is a valid name - * - * Returns: - * - *\li #ISC_R_SUCCESS - the message was signed, and *signer - * contains the signing identity - * - *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the - * message - * - *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the - * signature failed to verify - * - *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and - * verified, but the query was rejected by - * the server - * - *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and - * verified, but the key has no identity since - * it was generated by an unsigned TKEY process - * - *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but - * the signature failed to verify - * - *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), - * but the signature has not been verified yet - */ - -isc_result_t -dns_message_checksig(dns_message_t *msg, dns_view_t *view); -/*%< - * If this message was signed, verify the signature. - * - * Requires: - * - *\li msg is a valid parsed message. - *\li view is a valid view or NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - the message was unsigned, or the message - * was signed correctly. - * - *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen - *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify - */ - -isc_result_t -dns_message_rechecksig(dns_message_t *msg, dns_view_t *view); -/*%< - * Reset the signature state and then if the message was signed, - * verify the message. - * - * Requires: - * - *\li msg is a valid parsed message. - *\li view is a valid view or NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - the message was unsigned, or the message - * was signed correctly. - * - *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen - *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify - */ - -void -dns_message_resetsig(dns_message_t *msg); -/*%< - * Reset the signature state. - * - * Requires: - *\li 'msg' is a valid parsed message. - */ - -isc_region_t * -dns_message_getrawmessage(dns_message_t *msg); -/*%< - * Retrieve the raw message in compressed wire format. The message must - * have been successfully parsed for it to have been saved. - * - * Requires: - *\li msg is a valid parsed message. - * - * Returns: - *\li NULL if there is no saved message. - * a pointer to a region which refers the dns message. - */ - -void -dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, - const void *order_arg); -/*%< - * Define the order in which RR sets get rendered by - * dns_message_rendersection() to be the ascending order - * defined by the integer value returned by 'order' when - * given each RR and 'arg' as arguments. If 'order' and - * 'order_arg' are NULL, a default order is used. - * - * Requires: - *\li msg be a valid message. - *\li order_arg is NULL if and only if order is NULL. - */ - -void -dns_message_settimeadjust(dns_message_t *msg, int timeadjust); -/*%< - * Adjust the time used to sign/verify a message by timeadjust. - * Currently only TSIG. - * - * Requires: - *\li msg be a valid message. - */ - -int -dns_message_gettimeadjust(dns_message_t *msg); -/*%< - * Return the current time adjustment. - * - * Requires: - *\li msg be a valid message. - */ - -void -dns_message_logpacket(dns_message_t *message, const char *description, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, isc_mem_t *mctx); -void -dns_message_logpacket2(dns_message_t *message, - const char *description, isc_sockaddr_t *address, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, isc_mem_t *mctx); -void -dns_message_logfmtpacket(dns_message_t *message, const char *description, - isc_logcategory_t *category, isc_logmodule_t *module, - const dns_master_style_t *style, int level, - isc_mem_t *mctx); -void -dns_message_logfmtpacket2(dns_message_t *message, - const char *description, isc_sockaddr_t *address, - isc_logcategory_t *category, isc_logmodule_t *module, - const dns_master_style_t *style, int level, - isc_mem_t *mctx); -/*%< - * Log 'message' at the specified logging parameters. - * - * For dns_message_logpacket and dns_message_logfmtpacket expect the - * 'description' to end in a newline. - * - * For dns_message_logpacket2 and dns_message_logfmtpacket2 - * 'description' will be emitted at the start of the message followed - * by the formatted address and a newline. - * - * Requires: - * \li message be a valid. - * \li description to be non NULL. - * \li address to be non NULL. - * \li category to be valid. - * \li module to be valid. - * \li style to be valid. - * \li mctx to be a valid. - */ - -isc_result_t -dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, - unsigned int version, uint16_t udpsize, - unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); -/*%< - * Built a opt record. - * - * Requires: - * \li msg be a valid message. - * \li opt to be a non NULL and *opt to be NULL. - * - * Returns: - * \li ISC_R_SUCCESS on success. - * \li ISC_R_NOMEMORY - * \li ISC_R_NOSPACE - * \li other. - */ - -void -dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass); -/*%< - * Set the expected class of records in the response. - * - * Requires: - * \li msg be a valid message with parsing intent. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_MESSAGE_H */ diff --git a/lib/dns-pkcs11/include/dns/name.h b/lib/dns-pkcs11/include/dns/name.h deleted file mode 100644 index 0ca5d47..0000000 --- a/lib/dns-pkcs11/include/dns/name.h +++ /dev/null @@ -1,1428 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_NAME_H -#define DNS_NAME_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/name.h - * \brief - * Provides facilities for manipulating DNS names and labels, including - * conversions to and from wire format and text format. - * - * Given the large number of names possible in a nameserver, and because - * names occur in rdata, it was important to come up with a very efficient - * way of storing name data, but at the same time allow names to be - * manipulated. The decision was to store names in uncompressed wire format, - * and not to make them fully abstracted objects; i.e. certain parts of the - * server know names are stored that way. This saves a lot of memory, and - * makes adding names to messages easy. Having much of the server know - * the representation would be perilous, and we certainly don't want each - * user of names to be manipulating such a low-level structure. This is - * where the Names and Labels module comes in. The module allows name or - * label handles to be created and attached to uncompressed wire format - * regions. All name operations and conversions are done through these - * handles. - * - * MP: - *\li Clients of this module must impose any required synchronization. - * - * Reliability: - *\li This module deals with low-level byte streams. Errors in any of - * the functions are likely to crash the server or corrupt memory. - * - * Resources: - *\li None. - * - * Security: - * - *\li *** WARNING *** - * - *\li dns_name_fromwire() deals with raw network data. An error in - * this routine could result in the failure or hijacking of the server. - * - * Standards: - *\li RFC1035 - *\li Draft EDNS0 (0) - *\li Draft Binary Labels (2) - * - */ - -/*** - *** Imports - ***/ - -#include -#include -#include - -#include -#include -#include /* Required for storage size of dns_label_t. */ - -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Labels - ***** - ***** A 'label' is basically a region. It contains one DNS wire format - ***** label of type 00 (ordinary). - *****/ - -/***** - ***** Names - ***** - ***** A 'name' is a handle to a binary region. It contains a sequence of one - ***** or more DNS wire format labels of type 00 (ordinary). - ***** Note that all names are not required to end with the root label, - ***** as they are in the actual DNS wire protocol. - *****/ - -/*** - *** Types - ***/ - -/*% - * Clients are strongly discouraged from using this type directly, with - * the exception of the 'link' and 'list' fields which may be used directly - * for whatever purpose the client desires. - */ -struct dns_name { - unsigned int magic; - unsigned char * ndata; - unsigned int length; - unsigned int labels; - unsigned int attributes; - unsigned char * offsets; - isc_buffer_t * buffer; - ISC_LINK(dns_name_t) link; - ISC_LIST(dns_rdataset_t) list; -}; - -#define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n') - -#define DNS_NAMEATTR_ABSOLUTE 0x00000001 -#define DNS_NAMEATTR_READONLY 0x00000002 -#define DNS_NAMEATTR_DYNAMIC 0x00000004 -#define DNS_NAMEATTR_DYNOFFSETS 0x00000008 -#define DNS_NAMEATTR_NOCOMPRESS 0x00000010 -/* - * Attributes below 0x0100 reserved for name.c usage. - */ -#define DNS_NAMEATTR_CACHE 0x00000100 /*%< Used by resolver. */ -#define DNS_NAMEATTR_ANSWER 0x00000200 /*%< Used by resolver. */ -#define DNS_NAMEATTR_NCACHE 0x00000400 /*%< Used by resolver. */ -#define DNS_NAMEATTR_CHAINING 0x00000800 /*%< Used by resolver. */ -#define DNS_NAMEATTR_CHASE 0x00001000 /*%< Used by resolver. */ -#define DNS_NAMEATTR_WILDCARD 0x00002000 /*%< Used by server. */ -#define DNS_NAMEATTR_PREREQUISITE 0x00004000 /*%< Used by client. */ -#define DNS_NAMEATTR_UPDATE 0x00008000 /*%< Used by client. */ -#define DNS_NAMEATTR_HASUPDATEREC 0x00010000 /*%< Used by client. */ - -/* - * Various flags. - */ -#define DNS_NAME_DOWNCASE 0x0001 -#define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */ -#define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */ -#define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */ -#define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */ -#define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */ - -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname; -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname; - -/*%< - * DNS_NAME_INITNONABSOLUTE and DNS_NAME_INITABSOLUTE are macros for - * initializing dns_name_t structures. - * - * Note[1]: 'length' is set to (sizeof(A) - 1) in DNS_NAME_INITNONABSOLUTE - * and sizeof(A) in DNS_NAME_INITABSOLUTE to allow C strings to be used - * to initialize 'ndata'. - * - * Note[2]: The final value of offsets for DNS_NAME_INITABSOLUTE should - * match (sizeof(A) - 1) which is the offset of the root label. - * - * Typical usage: - * unsigned char data[] = "\005value"; - * unsigned char offsets[] = { 0 }; - * dns_name_t value = DNS_NAME_INITNONABSOLUTE(data, offsets); - * - * unsigned char data[] = "\005value"; - * unsigned char offsets[] = { 0, 6 }; - * dns_name_t value = DNS_NAME_INITABSOLUTE(data, offsets); - */ -#define DNS_NAME_INITNONABSOLUTE(A,B) { \ - DNS_NAME_MAGIC, \ - A, (sizeof(A) - 1), sizeof(B), \ - DNS_NAMEATTR_READONLY, \ - B, NULL, { (void *)-1, (void *)-1}, \ - {NULL, NULL} \ -} - -#define DNS_NAME_INITABSOLUTE(A,B) { \ - DNS_NAME_MAGIC, \ - A, sizeof(A), sizeof(B), \ - DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \ - B, NULL, { (void *)-1, (void *)-1}, \ - {NULL, NULL} \ -} - -#define DNS_NAME_INITEMPTY { \ - DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \ - { (void *)-1, (void *)-1 }, { NULL, NULL } \ -} - -/*% - * Standard size of a wire format name - */ -#define DNS_NAME_MAXWIRE 255 - -/* - * Text output filter procedure. - * 'target' is the buffer to be converted. The region to be converted - * is from 'buffer'->base + 'used_org' to the end of the used region. - */ -typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target, - unsigned int used_org, - bool absolute); - -/*** - *** Initialization - ***/ - -void -dns_name_init(dns_name_t *name, unsigned char *offsets); -/*%< - * Initialize 'name'. - * - * Notes: - * \li 'offsets' is never required to be non-NULL, but specifying a - * dns_offsets_t for 'offsets' will improve the performance of most - * name operations if the name is used more than once. - * - * Requires: - * \li 'name' is not NULL and points to a struct dns_name. - * - * \li offsets == NULL or offsets is a dns_offsets_t. - * - * Ensures: - * \li 'name' is a valid name. - * \li dns_name_countlabels(name) == 0 - * \li dns_name_isabsolute(name) == false - */ - -void -dns_name_reset(dns_name_t *name); -/*%< - * Reinitialize 'name'. - * - * Notes: - * \li This function distinguishes itself from dns_name_init() in two - * key ways: - * - * \li + If any buffer is associated with 'name' (via dns_name_setbuffer() - * or by being part of a dns_fixedname_t) the link to the buffer - * is retained but the buffer itself is cleared. - * - * \li + Of the attributes associated with 'name', all are retained except - * DNS_NAMEATTR_ABSOLUTE. - * - * Requires: - * \li 'name' is a valid name. - * - * Ensures: - * \li 'name' is a valid name. - * \li dns_name_countlabels(name) == 0 - * \li dns_name_isabsolute(name) == false - */ - -void -dns_name_invalidate(dns_name_t *name); -/*%< - * Make 'name' invalid. - * - * Requires: - * \li 'name' is a valid name. - * - * Ensures: - * \li If assertion checking is enabled, future attempts to use 'name' - * without initializing it will cause an assertion failure. - * - * \li If the name had a dedicated buffer, that association is ended. - */ - -bool -dns_name_isvalid(const dns_name_t *name); -/*%< - * Check whether 'name' points to a valid dns_name - */ - -/*** - *** Dedicated Buffers - ***/ - -void -dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer); -/*%< - * Dedicate a buffer for use with 'name'. - * - * Notes: - * \li Specification of a target buffer in dns_name_fromwire(), - * dns_name_fromtext(), and dns_name_concatenate() is optional if - * 'name' has a dedicated buffer. - * - * \li The caller must not write to buffer until the name has been - * invalidated or is otherwise known not to be in use. - * - * \li If buffer is NULL and the name previously had a dedicated buffer, - * than that buffer is no longer dedicated to use with this name. - * The caller is responsible for ensuring that the storage used by - * the name remains valid. - * - * Requires: - * \li 'name' is a valid name. - * - * \li 'buffer' is a valid binary buffer and 'name' doesn't have a - * dedicated buffer already, or 'buffer' is NULL. - */ - -bool -dns_name_hasbuffer(const dns_name_t *name); -/*%< - * Does 'name' have a dedicated buffer? - * - * Requires: - * \li 'name' is a valid name. - * - * Returns: - * \li true 'name' has a dedicated buffer. - * \li false 'name' does not have a dedicated buffer. - */ - -/*** - *** Properties - ***/ - -bool -dns_name_isabsolute(const dns_name_t *name); -/*%< - * Does 'name' end in the root label? - * - * Requires: - * \li 'name' is a valid name - * - * Returns: - * \li TRUE The last label in 'name' is the root label. - * \li FALSE The last label in 'name' is not the root label. - */ - -bool -dns_name_iswildcard(const dns_name_t *name); -/*%< - * Is 'name' a wildcard name? - * - * Requires: - * \li 'name' is a valid name - * - * \li dns_name_countlabels(name) > 0 - * - * Returns: - * \li TRUE The least significant label of 'name' is '*'. - * \li FALSE The least significant label of 'name' is not '*'. - */ - -unsigned int -dns_name_hash(dns_name_t *name, bool case_sensitive); -/*%< - * Provide a hash value for 'name'. - * - * Note: if 'case_sensitive' is false, then names which differ only in - * case will have the same hash value. - * - * Requires: - * \li 'name' is a valid name - * - * Returns: - * \li A hash value - */ - -unsigned int -dns_name_fullhash(dns_name_t *name, bool case_sensitive); -/*%< - * Provide a hash value for 'name'. Unlike dns_name_hash(), this function - * always takes into account of the entire name to calculate the hash value. - * - * Note: if 'case_sensitive' is false, then names which differ only in - * case will have the same hash value. - * - * Requires: - *\li 'name' is a valid name - * - * Returns: - *\li A hash value - */ - -unsigned int -dns_name_hashbylabel(dns_name_t *name, bool case_sensitive); -/*%< - * Provide a hash value for 'name', where the hash value is the sum - * of the hash values of each label. This function should only be used - * when incremental hashing is necessary, for example, during RBT - * traversal. It is not currently used in BIND. Generally, - * dns_name_fullhash() is the correct function to use for name - * hashing. - * - * Note: if 'case_sensitive' is false, then names which differ only in - * case will have the same hash value. - * - * Requires: - *\li 'name' is a valid name - * - * Returns: - *\li A hash value - */ - -/* - *** Comparisons - ***/ - -dns_namereln_t -dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, - int *orderp, unsigned int *nlabelsp); -/*%< - * Determine the relative ordering under the DNSSEC order relation of - * 'name1' and 'name2', and also determine the hierarchical - * relationship of the names. - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - * - * Requires: - *\li 'name1' is a valid name - * - *\li dns_name_countlabels(name1) > 0 - * - *\li 'name2' is a valid name - * - *\li dns_name_countlabels(name2) > 0 - * - *\li orderp and nlabelsp are valid pointers. - * - *\li Either name1 is absolute and name2 is absolute, or neither is. - * - * Ensures: - * - *\li *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if - * name1 > name2. - * - *\li *nlabelsp is the number of common significant labels. - * - * Returns: - *\li dns_namereln_none There's no hierarchical relationship - * between name1 and name2. - *\li dns_namereln_contains name1 properly contains name2; i.e. - * name2 is a proper subdomain of name1. - *\li dns_namereln_subdomain name1 is a proper subdomain of name2. - *\li dns_namereln_equal name1 and name2 are equal. - *\li dns_namereln_commonancestor name1 and name2 share a common - * ancestor. - */ - -int -dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); -/*%< - * Determine the relative ordering under the DNSSEC order relation of - * 'name1' and 'name2'. - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - * - * Requires: - * \li 'name1' is a valid name - * - * \li 'name2' is a valid name - * - * \li Either name1 is absolute and name2 is absolute, or neither is. - * - * Returns: - * \li < 0 'name1' is less than 'name2' - * \li 0 'name1' is equal to 'name2' - * \li > 0 'name1' is greater than 'name2' - */ - -bool -dns_name_equal(const dns_name_t *name1, const dns_name_t *name2); -/*%< - * Are 'name1' and 'name2' equal? - * - * Notes: - * \li Because it only needs to test for equality, dns_name_equal() can be - * significantly faster than dns_name_fullcompare() or dns_name_compare(). - * - * \li Offsets tables are not used in the comparison. - * - * \li It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - * - * Requires: - * \li 'name1' is a valid name - * - * \li 'name2' is a valid name - * - * \li Either name1 is absolute and name2 is absolute, or neither is. - * - * Returns: - * \li true 'name1' and 'name2' are equal - * \li false 'name1' and 'name2' are not equal - */ - -bool -dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2); -/*%< - * Case sensitive version of dns_name_equal(). - */ - -int -dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2); -/*%< - * Compare two names as if they are part of rdata in DNSSEC canonical - * form. - * - * Requires: - * \li 'name1' is a valid absolute name - * - * \li dns_name_countlabels(name1) > 0 - * - * \li 'name2' is a valid absolute name - * - * \li dns_name_countlabels(name2) > 0 - * - * Returns: - * \li < 0 'name1' is less than 'name2' - * \li 0 'name1' is equal to 'name2' - * \li > 0 'name1' is greater than 'name2' - */ - -bool -dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2); -/*%< - * Is 'name1' a subdomain of 'name2'? - * - * Notes: - * \li name1 is a subdomain of name2 if name1 is contained in name2, or - * name1 equals name2. - * - * \li It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - * - * Requires: - * \li 'name1' is a valid name - * - * \li 'name2' is a valid name - * - * \li Either name1 is absolute and name2 is absolute, or neither is. - * - * Returns: - * \li TRUE 'name1' is a subdomain of 'name2' - * \li FALSE 'name1' is not a subdomain of 'name2' - */ - -bool -dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname); -/*%< - * Does 'name' match the wildcard specified in 'wname'? - * - * Notes: - * \li name matches the wildcard specified in wname if all labels - * following the wildcard in wname are identical to the same number - * of labels at the end of name. - * - * \li It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - * - * Requires: - * \li 'name' is a valid name - * - * \li dns_name_countlabels(name) > 0 - * - * \li 'wname' is a valid name - * - * \li dns_name_countlabels(wname) > 0 - * - * \li dns_name_iswildcard(wname) is true - * - * \li Either name is absolute and wname is absolute, or neither is. - * - * Returns: - * \li TRUE 'name' matches the wildcard specified in 'wname' - * \li FALSE 'name' does not match the wildcard specified in 'wname' - */ - -/*** - *** Labels - ***/ - -unsigned int -dns_name_countlabels(const dns_name_t *name); -/*%< - * How many labels does 'name' have? - * - * Notes: - * \li In this case, as in other places, a 'label' is an ordinary label. - * - * Requires: - * \li 'name' is a valid name - * - * Ensures: - * \li The result is <= 128. - * - * Returns: - * \li The number of labels in 'name'. - */ - -void -dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label); -/*%< - * Make 'label' refer to the 'n'th least significant label of 'name'. - * - * Notes: - * \li Numbering starts at 0. - * - * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the - * root label. - * - * \li 'label' refers to the same memory as 'name', so 'name' must not - * be changed while 'label' is still in use. - * - * Requires: - * \li n < dns_name_countlabels(name) - */ - -void -dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, - unsigned int n, dns_name_t *target); -/*%< - * Make 'target' refer to the 'n' labels including and following 'first' - * in 'source'. - * - * Notes: - * \li Numbering starts at 0. - * - * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the - * root label. - * - * \li 'target' refers to the same memory as 'source', so 'source' - * must not be changed while 'target' is still in use. - * - * Requires: - * \li 'source' and 'target' are valid names. - * - * \li first < dns_name_countlabels(name) - * - * \li first + n <= dns_name_countlabels(name) - */ - - -void -dns_name_clone(const dns_name_t *source, dns_name_t *target); -/*%< - * Make 'target' refer to the same name as 'source'. - * - * Notes: - * - * \li 'target' refers to the same memory as 'source', so 'source' - * must not be changed while 'target' is still in use. - * - * \li This call is functionally equivalent to: - * - * \code - * dns_name_getlabelsequence(source, 0, - * dns_name_countlabels(source), - * target); - * \endcode - * - * but is more efficient. Also, dns_name_clone() works even if 'source' - * is empty. - * - * Requires: - * - * \li 'source' is a valid name. - * - * \li 'target' is a valid name that is not read-only. - */ - -/*** - *** Conversions - ***/ - -void -dns_name_fromregion(dns_name_t *name, const isc_region_t *r); -/*%< - * Make 'name' refer to region 'r'. - * - * Note: - * \li If the conversion encounters a root label before the end of the - * region the conversion stops and the length is set to the length - * so far converted. A maximum of 255 bytes is converted. - * - * Requires: - * \li The data in 'r' is a sequence of one or more type 00 or type 01000001 - * labels. - */ - -void -dns_name_toregion(dns_name_t *name, isc_region_t *r); -/*%< - * Make 'r' refer to 'name'. - * - * Requires: - * - * \li 'name' is a valid name. - * - * \li 'r' is a valid region. - */ - -isc_result_t -dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, - dns_decompress_t *dctx, unsigned int options, - isc_buffer_t *target); -/*%< - * Copy the possibly-compressed name at source (active region) into target, - * decompressing it. - * - * Notes: - * \li Decompression policy is controlled by 'dctx'. - * - * \li If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be - * downcased when they are copied into 'target'. - * - * Security: - * - * \li *** WARNING *** - * - * \li This routine will often be used when 'source' contains raw network - * data. A programming error in this routine could result in a denial - * of service, or in the hijacking of the server. - * - * Requires: - * - * \li 'name' is a valid name. - * - * \li 'source' is a valid buffer and the first byte of the active - * region should be the first byte of a DNS wire format domain name. - * - * \li 'target' is a valid buffer or 'target' is NULL and 'name' has - * a dedicated buffer. - * - * \li 'dctx' is a valid decompression context. - * - * Ensures: - * - * If result is success: - * \li If 'target' is not NULL, 'name' is attached to it. - * - * \li Uppercase letters are downcased in the copy iff - * DNS_NAME_DOWNCASE is set in options. - * - * \li The current location in source is advanced, and the used space - * in target is updated. - * - * Result: - * \li Success - * \li Bad Form: Label Length - * \li Bad Form: Unknown Label Type - * \li Bad Form: Name Length - * \li Bad Form: Compression type not allowed - * \li Bad Form: Bad compression pointer - * \li Bad Form: Input too short - * \li Resource Limit: Too many compression pointers - * \li Resource Limit: Not enough space in buffer - */ - -isc_result_t -dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, - isc_buffer_t *target); -/*%< - * Convert 'name' into wire format, compressing it as specified by the - * compression context 'cctx', and storing the result in 'target'. - * - * Notes: - * \li If the compression context allows global compression, then the - * global compression table may be updated. - * - * Requires: - * \li 'name' is a valid name - * - * \li dns_name_countlabels(name) > 0 - * - * \li dns_name_isabsolute(name) == TRUE - * - * \li target is a valid buffer. - * - * \li Any offsets specified in a global compression table are valid - * for buffer. - * - * Ensures: - * - * If the result is success: - * - * \li The used space in target is updated. - * - * Returns: - * \li Success - * \li Resource Limit: Not enough space in buffer - */ - -isc_result_t -dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, - const dns_name_t *origin, unsigned int options, - isc_buffer_t *target); -/*%< - * Convert the textual representation of a DNS name at source - * into uncompressed wire form stored in target. - * - * Notes: - * \li Relative domain names will have 'origin' appended to them - * unless 'origin' is NULL, in which case relative domain names - * will remain relative. - * - * \li If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters - * in 'source' will be downcased when they are copied into 'target'. - * - * Requires: - * - * \li 'name' is a valid name. - * - * \li 'source' is a valid buffer. - * - * \li 'target' is a valid buffer or 'target' is NULL and 'name' has - * a dedicated buffer. - * - * Ensures: - * - * If result is success: - * \li If 'target' is not NULL, 'name' is attached to it. - * - * \li Uppercase letters are downcased in the copy iff - * DNS_NAME_DOWNCASE is set in 'options'. - * - * \li The current location in source is advanced, and the used space - * in target is updated. - * - * Result: - *\li #ISC_R_SUCCESS - *\li #DNS_R_EMPTYLABEL - *\li #DNS_R_LABELTOOLONG - *\li #DNS_R_BADESCAPE - *\li #DNS_R_BADDOTTEDQUAD - *\li #ISC_R_NOSPACE - *\li #ISC_R_UNEXPECTEDEND - */ - -#define DNS_NAME_OMITFINALDOT 0x01U -#define DNS_NAME_MASTERFILE 0x02U /* escape $ and @ */ - -isc_result_t -dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target); - -isc_result_t -dns_name_totext(const dns_name_t *name, bool omit_final_dot, - isc_buffer_t *target); - -isc_result_t -dns_name_totext2(const dns_name_t *name, unsigned int options, - isc_buffer_t *target); -/*%< - * Convert 'name' into text format, storing the result in 'target'. - * - * Notes: - *\li If 'omit_final_dot' is true, then the final '.' in absolute - * names other than the root name will be omitted. - * - *\li If DNS_NAME_OMITFINALDOT is set in options, then the final '.' - * in absolute names other than the root name will be omitted. - * - *\li If DNS_NAME_MASTERFILE is set in options, '$' and '@' will also - * be escaped. - * - *\li If dns_name_countlabels == 0, the name will be "@", representing the - * current origin as described by RFC1035. - * - *\li The name is not NUL terminated. - * - * Requires: - * - *\li 'name' is a valid name - * - *\li 'target' is a valid buffer. - * - *\li if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE - * - * Ensures: - * - *\li If the result is success: - * the used space in target is updated. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - */ - -#define DNS_NAME_MAXTEXT 1023 -/*%< - * The maximum length of the text representation of a domain - * name as generated by dns_name_totext(). This does not - * include space for a terminating NULL. - * - * This definition is conservative - the actual maximum - * is 1004, derived as follows: - * - * A backslash-decimal escaped character takes 4 bytes. - * A wire-encoded name can be up to 255 bytes and each - * label is one length byte + at most 63 bytes of data. - * Maximizing the label lengths gives us a name of - * three 63-octet labels, one 61-octet label, and the - * root label: - * - * 1 + 63 + 1 + 63 + 1 + 63 + 1 + 61 + 1 = 255 - * - * When printed, this is (3 * 63 + 61) * 4 - * bytes for the escaped label data + 4 bytes for the - * dot terminating each label = 1004 bytes total. - */ - -isc_result_t -dns_name_tofilenametext(dns_name_t *name, bool omit_final_dot, - isc_buffer_t *target); -/*%< - * Convert 'name' into an alternate text format appropriate for filenames, - * storing the result in 'target'. The name data is downcased, guaranteeing - * that the filename does not depend on the case of the converted name. - * - * Notes: - *\li If 'omit_final_dot' is true, then the final '.' in absolute - * names other than the root name will be omitted. - * - *\li The name is not NUL terminated. - * - * Requires: - * - *\li 'name' is a valid absolute name - * - *\li 'target' is a valid buffer. - * - * Ensures: - * - *\li If the result is success: - * the used space in target is updated. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - */ - -isc_result_t -dns_name_downcase(dns_name_t *source, dns_name_t *name, - isc_buffer_t *target); -/*%< - * Downcase 'source'. - * - * Requires: - * - *\li 'source' and 'name' are valid names. - * - *\li If source == name, then - * 'source' must not be read-only - * - *\li Otherwise, - * 'target' is a valid buffer or 'target' is NULL and - * 'name' has a dedicated buffer. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - * - * Note: if source == name, then the result will always be ISC_R_SUCCESS. - */ - -isc_result_t -dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, - dns_name_t *name, isc_buffer_t *target); -/*%< - * Concatenate 'prefix' and 'suffix'. - * - * Requires: - * - *\li 'prefix' is a valid name or NULL. - * - *\li 'suffix' is a valid name or NULL. - * - *\li 'name' is a valid name or NULL. - * - *\li 'target' is a valid buffer or 'target' is NULL and 'name' has - * a dedicated buffer. - * - *\li If 'prefix' is absolute, 'suffix' must be NULL or the empty name. - * - * Ensures: - * - *\li On success, - * If 'target' is not NULL and 'name' is not NULL, then 'name' - * is attached to it. - * The used space in target is updated. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - *\li #DNS_R_NAMETOOLONG - */ - -void -dns_name_split(dns_name_t *name, unsigned int suffixlabels, - dns_name_t *prefix, dns_name_t *suffix); -/*%< - * - * Split 'name' into two pieces on a label boundary. - * - * Notes: - * \li 'name' is split such that 'suffix' holds the most significant - * 'suffixlabels' labels. All other labels are stored in 'prefix'. - * - *\li Copying name data is avoided as much as possible, so 'prefix' - * and 'suffix' will end up pointing at the data for 'name'. - * - *\li It is legitimate to pass a 'prefix' or 'suffix' that has - * its name data stored someplace other than the dedicated buffer. - * This is useful to avoid name copying in the calling function. - * - *\li It is also legitimate to pass a 'prefix' or 'suffix' that is - * the same dns_name_t as 'name'. - * - * Requires: - *\li 'name' is a valid name. - * - *\li 'suffixlabels' cannot exceed the number of labels in 'name'. - * - * \li 'prefix' is a valid name or NULL, and cannot be read-only. - * - *\li 'suffix' is a valid name or NULL, and cannot be read-only. - * - * Ensures: - * - *\li On success: - * If 'prefix' is not NULL it will contain the least significant - * labels. - * If 'suffix' is not NULL it will contain the most significant - * labels. dns_name_countlabels(suffix) will be equal to - * suffixlabels. - * - *\li On failure: - * Either 'prefix' or 'suffix' is invalidated (depending - * on which one the problem was encountered with). - * - * Returns: - *\li #ISC_R_SUCCESS No worries. (This function should always success). - */ - -isc_result_t -dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, - dns_name_t *target); -/*%< - * Make 'target' a dynamically allocated copy of 'source'. - * - * Requires: - * - *\li 'source' is a valid non-empty name. - * - *\li 'target' is a valid name that is not read-only. - * - *\li 'mctx' is a valid memory context. - */ - -isc_result_t -dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, - dns_name_t *target); -/*%< - * Make 'target' a read-only dynamically allocated copy of 'source'. - * 'target' will also have a dynamically allocated offsets table. - * - * Requires: - * - *\li 'source' is a valid non-empty name. - * - *\li 'target' is a valid name that is not read-only. - * - *\li 'target' has no offsets table. - * - *\li 'mctx' is a valid memory context. - */ - -void -dns_name_free(dns_name_t *name, isc_mem_t *mctx); -/*%< - * Free 'name'. - * - * Requires: - * - *\li 'name' is a valid name created previously in 'mctx' by dns_name_dup(). - * - *\li 'mctx' is a valid memory context. - * - * Ensures: - * - *\li All dynamic resources used by 'name' are freed and the name is - * invalidated. - */ - -isc_result_t -dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg); -/*%< - * Send 'name' in DNSSEC canonical form to 'digest'. - * - * Requires: - * - *\li 'name' is a valid name. - * - *\li 'digest' is a valid dns_digestfunc_t. - * - * Ensures: - * - *\li If successful, the DNSSEC canonical form of 'name' will have been - * sent to 'digest'. - * - *\li If digest() returns something other than ISC_R_SUCCESS, that result - * will be returned as the result of dns_name_digest(). - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Many other results are possible if not successful. - * - */ - -bool -dns_name_dynamic(dns_name_t *name); -/*%< - * Returns whether there is dynamic memory associated with this name. - * - * Requires: - * - *\li 'name' is a valid name. - * - * Returns: - * - *\li 'true' if the name is dynamic otherwise 'false'. - */ - -isc_result_t -dns_name_print(dns_name_t *name, FILE *stream); -/*%< - * Print 'name' on 'stream'. - * - * Requires: - * - *\li 'name' is a valid name. - * - *\li 'stream' is a valid stream. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Any error that dns_name_totext() can return. - */ - -void -dns_name_format(const dns_name_t *name, char *cp, unsigned int size); -/*%< - * Format 'name' as text appropriate for use in log messages. - * - * Store the formatted name at 'cp', writing no more than - * 'size' bytes. The resulting string is guaranteed to be - * null terminated. - * - * The formatted name will have a terminating dot only if it is - * the root. - * - * This function cannot fail, instead any errors are indicated - * in the returned text. - * - * Requires: - * - *\li 'name' is a valid name. - * - *\li 'cp' points a valid character array of size 'size'. - * - *\li 'size' > 0. - * - */ - -isc_result_t -dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx); -/*%< - * Convert 'name' to string format, allocating sufficient memory to - * hold it (free with isc_mem_free()). - * - * Differs from dns_name_format in that it allocates its own memory. - * - * Requires: - * - *\li 'name' is a valid name. - *\li 'target' is not NULL. - *\li '*target' is NULL. - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - * - *\li Any error that dns_name_totext() can return. - */ - -isc_result_t -dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options, - isc_mem_t *mctx); -isc_result_t -dns_name_fromstring2(dns_name_t *target, const char *src, - const dns_name_t *origin, unsigned int options, - isc_mem_t *mctx); -/*%< - * Convert a string to a name and place it in target, allocating memory - * as necessary. 'options' has the same semantics as that of - * dns_name_fromtext(). - * - * If 'target' has a buffer then the name will be copied into it rather than - * memory being allocated. - * - * Requires: - * - * \li 'target' is a valid name that is not read-only. - * \li 'src' is not NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Any error that dns_name_fromtext() can return. - * - *\li Any error that dns_name_dup() can return. - */ - -isc_result_t -dns_name_settotextfilter(dns_name_totextfilter_t proc); -/*%< - * Set / clear a thread specific function 'proc' to be called at the - * end of dns_name_totext(). - * - * Note: Under Windows you need to call "dns_name_settotextfilter(NULL);" - * prior to exiting the thread otherwise memory will be leaked. - * For other platforms, which are pthreads based, this is still a good - * idea but not required. - * - * Returns - *\li #ISC_R_SUCCESS - *\li #ISC_R_UNEXPECTED - */ - -#define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1) -/*%< - * Suggested size of buffer passed to dns_name_format(). - * Includes space for the terminating NULL. - */ - -isc_result_t -dns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target); -/*%< - * Makes 'dest' refer to a copy of the name in 'source'. The data are - * either copied to 'target' or the dedicated buffer in 'dest'. - * - * Requires: - * \li 'source' is a valid name. - * - * \li 'dest' is an initialized name with a dedicated buffer. - * - * \li 'target' is NULL or an initialized buffer. - * - * \li Either dest has a dedicated buffer or target != NULL. - * - * Ensures: - * - *\li On success, the used space in target is updated. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - */ - -bool -dns_name_ishostname(const dns_name_t *name, bool wildcard); -/*%< - * Return if 'name' is a valid hostname. RFC 952 / RFC 1123. - * If 'wildcard' is true then allow the first label of name to - * be a wildcard. - * The root is also accepted. - * - * Requires: - * 'name' to be valid. - */ - - -bool -dns_name_ismailbox(const dns_name_t *name); -/*%< - * Return if 'name' is a valid mailbox. RFC 821. - * - * Requires: - * \li 'name' to be valid. - */ - -bool -dns_name_internalwildcard(const dns_name_t *name); -/*%< - * Return if 'name' contains a internal wildcard name. - * - * Requires: - * \li 'name' to be valid. - */ - -void -dns_name_destroy(void); -/*%< - * Cleanup dns_name_settotextfilter() / dns_name_totext() state. - * - * This should be called as part of the final cleanup process. - * - * Note: dns_name_settotextfilter(NULL); should be called for all - * threads which have called dns_name_settotextfilter() with a - * non-NULL argument prior to calling dns_name_destroy(); - */ - -bool -dns_name_isdnssd(const dns_name_t *owner); -/*%< - * Determine if the 'owner' is a DNS-SD prefix. - */ - -bool -dns_name_isrfc1918(const dns_name_t *owner); -/*%< - * Determine if the 'name' is in the RFC 1918 reverse namespace. - */ - -bool -dns_name_isula(const dns_name_t *owner); -/*%< - * Determine if the 'name' is in the ULA reverse namespace. - */ - -bool -dns_name_istat(const dns_name_t *name); -/* - * Determine if 'name' is a potential 'trust-anchor-telemetry' name. - */ - -ISC_LANG_ENDDECLS - -/* - *** High Performance Macros - ***/ - -/* - * WARNING: Use of these macros by applications may require recompilation - * of the application in some situations where calling the function - * would not. - * - * WARNING: No assertion checking is done for these macros. - */ - -#define DNS_NAME_INIT(n, o) \ -do { \ - dns_name_t *_n = (n); \ - /* memset(_n, 0, sizeof(*_n)); */ \ - _n->magic = DNS_NAME_MAGIC; \ - _n->ndata = NULL; \ - _n->length = 0; \ - _n->labels = 0; \ - _n->attributes = 0; \ - _n->offsets = (o); \ - _n->buffer = NULL; \ - ISC_LINK_INIT(_n, link); \ - ISC_LIST_INIT(_n->list); \ -} while (0) - -#define DNS_NAME_RESET(n) \ -do { \ - (n)->ndata = NULL; \ - (n)->length = 0; \ - (n)->labels = 0; \ - (n)->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ - if ((n)->buffer != NULL) \ - isc_buffer_clear((n)->buffer); \ -} while (0) - -#define DNS_NAME_SETBUFFER(n, b) \ - (n)->buffer = (b) - -#define DNS_NAME_ISABSOLUTE(n) \ - (((n)->attributes & DNS_NAMEATTR_ABSOLUTE) != 0 ? true : false) - -#define DNS_NAME_COUNTLABELS(n) \ - ((n)->labels) - -#define DNS_NAME_TOREGION(n, r) \ -do { \ - (r)->base = (n)->ndata; \ - (r)->length = (n)->length; \ -} while (0) - -#define DNS_NAME_SPLIT(n, l, p, s) \ -do { \ - dns_name_t *_n = (n); \ - dns_name_t *_p = (p); \ - dns_name_t *_s = (s); \ - unsigned int _l = (l); \ - if (_p != NULL) \ - dns_name_getlabelsequence(_n, 0, _n->labels - _l, _p); \ - if (_s != NULL) \ - dns_name_getlabelsequence(_n, _n->labels - _l, _l, _s); \ -} while (0) - -#ifdef DNS_NAME_USEINLINE - -#define dns_name_init(n, o) DNS_NAME_INIT(n, o) -#define dns_name_reset(n) DNS_NAME_RESET(n) -#define dns_name_setbuffer(n, b) DNS_NAME_SETBUFFER(n, b) -#define dns_name_countlabels(n) DNS_NAME_COUNTLABELS(n) -#define dns_name_isabsolute(n) DNS_NAME_ISABSOLUTE(n) -#define dns_name_toregion(n, r) DNS_NAME_TOREGION(n, r) -#define dns_name_split(n, l, p, s) DNS_NAME_SPLIT(n, l, p, s) - -#endif /* DNS_NAME_USEINLINE */ - -#endif /* DNS_NAME_H */ diff --git a/lib/dns-pkcs11/include/dns/ncache.h b/lib/dns-pkcs11/include/dns/ncache.h deleted file mode 100644 index c984a18..0000000 --- a/lib/dns-pkcs11/include/dns/ncache.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_NCACHE_H -#define DNS_NCACHE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/ncache.h - *\brief - * DNS Ncache - * - * XXX TBS XXX - * - * MP: - *\li The caller must ensure any required synchronization. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li RFC2308 - */ - -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*% - * _OMITDNSSEC: - * Omit DNSSEC records when rendering. - */ -#define DNS_NCACHETOWIRE_OMITDNSSEC 0x0001 - -isc_result_t -dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - dns_rdataset_t *addedrdataset); -isc_result_t -dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, - dns_dbnode_t *node, dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, dns_rdataset_t *addedrdataset); -/*%< - * Convert the authority data from 'message' into a negative cache - * rdataset, and store it in 'cache' at 'node' with a TTL limited to - * 'maxttl'. - * - * \li dns_ncache_add produces a negative cache entry with a trust of no - * more than answer - * \li dns_ncache_addoptout produces a negative cache entry which will have - * a trust of secure if all the records that make up the entry are secure. - * - * The 'covers' argument is the RR type whose nonexistence we are caching, - * or dns_rdatatype_any when caching a NXDOMAIN response. - * - * 'optout' indicates a DNS_RDATASETATTR_OPTOUT should be set. - * - * Note: - *\li If 'addedrdataset' is not NULL, then it will be attached to the added - * rdataset. See dns_db_addrdataset() for more details. - * - * Requires: - *\li 'message' is a valid message with a properly formatting negative cache - * authority section. - * - *\li The requirements of dns_db_addrdataset() apply to 'cache', 'node', - * 'now', and 'addedrdataset'. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOSPACE - * - *\li Any result code of dns_db_addrdataset() is a possible result code - * of dns_ncache_add(). - */ - -isc_result_t -dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, - isc_buffer_t *target, unsigned int options, - unsigned int *countp); -/*%< - * Convert the negative caching rdataset 'rdataset' to wire format, - * compressing names as specified in 'cctx', and storing the result in - * 'target'. If 'omit_dnssec' is set, DNSSEC records will not - * be added to 'target'. - * - * Notes: - *\li The number of RRs added to target will be added to *countp. - * - * Requires: - *\li 'rdataset' is a valid negative caching rdataset. - * - *\li 'rdataset' is not empty. - * - *\li 'countp' is a valid pointer. - * - * Ensures: - *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format - * for the data contained in 'rdataset'. Any error return leaves - * the buffer unchanged. - * - *\li *countp has been incremented by the number of RRs added to - * target. - * - * Returns: - *\li #ISC_R_SUCCESS - all ok - *\li #ISC_R_NOSPACE - 'target' doesn't have enough room - * - *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), - * dns_name_towire(). - */ - -isc_result_t -dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, - dns_rdatatype_t type, dns_rdataset_t *rdataset); -/*%< - * Search the negative caching rdataset for an rdataset with the - * specified name and type. - * - * Requires: - *\li 'ncacherdataset' is a valid negative caching rdataset. - * - *\li 'ncacherdataset' is not empty. - * - *\li 'name' is a valid name. - * - *\li 'type' is not SIG, or a meta-RR type. - * - *\li 'rdataset' is a valid disassociated rdataset. - * - * Ensures: - *\li On a return of ISC_R_SUCCESS, 'rdataset' is bound to the found - * rdataset. - * - * Returns: - *\li #ISC_R_SUCCESS - the rdataset was found. - *\li #ISC_R_NOTFOUND - the rdataset was not found. - * - */ - -isc_result_t -dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, - dns_rdatatype_t covers, dns_rdataset_t *rdataset); -/*%< - * Similar to dns_ncache_getrdataset() but get the rrsig that matches. - */ - -void -dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, - dns_rdataset_t *rdataset); - -/*%< - * Extract the current rdataset and name from a ncache entry. - * - * Requires: - * \li 'ncacherdataset' to be valid and to be a negative cache entry - * \li 'found' to be valid. - * \li 'rdataset' to be unassociated. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_NCACHE_H */ diff --git a/lib/dns-pkcs11/include/dns/nsec.h b/lib/dns-pkcs11/include/dns/nsec.h deleted file mode 100644 index 4e12cbe..0000000 --- a/lib/dns-pkcs11/include/dns/nsec.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_NSEC_H -#define DNS_NSEC_H 1 - -/*! \file dns/nsec.h */ - -#include - -#include - -#include -#include - -#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512) - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *target, - unsigned char *buffer, dns_rdata_t *rdata); -/*%< - * Build the rdata of a NSEC record. - * - * Requires: - *\li buffer Points to a temporary buffer of at least - * DNS_NSEC_BUFFERSIZE bytes. - *\li rdata Points to an initialized dns_rdata_t. - * - * Ensures: - * \li *rdata Contains a valid NSEC rdata. The 'data' member refers - * to 'buffer'. - */ - -isc_result_t -dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, - dns_name_t *target, dns_ttl_t ttl); -/*%< - * Build a NSEC record and add it to a database. - */ - -bool -dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); -/*%< - * Determine if a type is marked as present in an NSEC record. - * - * Requires: - *\li 'nsec' points to a valid rdataset of type NSEC - */ - -isc_result_t -dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, - bool *answer); -/* - * Report whether the DNSKEY RRset has a NSEC only algorithm. Unknown - * algorithms are assumed to support NSEC3. If DNSKEY is not found, - * *answer is set to false, and ISC_R_NOTFOUND is returned. - * - * Requires: - * 'answer' to be non NULL. - */ - -unsigned int -dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, - unsigned int max_type); -/*%< - * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw' - * may overlap. - * - * Returns the length of the compressed windowed bit map. - */ - -void -dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit); -/*%< - * Set type bit in raw 'array' to 'bit'. - */ - -bool -dns_nsec_isset(const unsigned char *array, unsigned int type); -/*%< - * Test if the corresponding 'type' bit is set in 'array'. - */ - -isc_result_t -dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, - dns_name_t *nsecname, dns_rdataset_t *nsecset, - bool *exists, bool *data, - dns_name_t *wild, dns_nseclog_t log, void *arg); -/*% - * Return ISC_R_SUCCESS if we can determine that the name doesn't exist - * or we can determine whether there is data or not at the name. - * If the name does not exist return the wildcard name. - * - * Return ISC_R_IGNORE when the NSEC is not the appropriate one. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_NSEC_H */ diff --git a/lib/dns-pkcs11/include/dns/nsec3.h b/lib/dns-pkcs11/include/dns/nsec3.h deleted file mode 100644 index 4712d44..0000000 --- a/lib/dns-pkcs11/include/dns/nsec3.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_NSEC3_H -#define DNS_NSEC3_H 1 - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define DNS_NSEC3_SALTSIZE 255 - -/* - * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max) - * hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max) - */ -#define DNS_NSEC3_BUFFERSIZE (6 + 255 + 255 + 8192 + 512) -/* - * hash = 1, flags = 1, iterations = 2, salt length = 1, salt = 255 (max) - */ -#define DNS_NSEC3PARAM_BUFFERSIZE (5 + 255) - -/* - * Test "unknown" algorithm. Is mapped to dns_hash_sha1. - */ -#define DNS_NSEC3_UNKNOWNALG ((dns_hash_t)245U) - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, unsigned int hashalg, - unsigned int optin, unsigned int iterations, - const unsigned char *salt, size_t salt_length, - const unsigned char *nexthash, size_t hash_length, - unsigned char *buffer, dns_rdata_t *rdata); -/*%< - * Build the rdata of a NSEC3 record for the data at 'node'. - * Note: 'node' is not the node where the NSEC3 record will be stored. - * - * Requires: - * buffer Points to a temporary buffer of at least - * DNS_NSEC_BUFFERSIZE bytes. - * rdata Points to an initialized dns_rdata_t. - * - * Ensures: - * *rdata Contains a valid NSEC3 rdata. The 'data' member refers - * to 'buffer'. - */ - -bool -dns_nsec3_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); -/*%< - * Determine if a type is marked as present in an NSEC3 record. - * - * Requires: - * 'nsec' points to a valid rdataset of type NSEC3 - */ - -isc_result_t -dns_nsec3_hashname(dns_fixedname_t *result, - unsigned char rethash[NSEC3_MAX_HASH_LENGTH], - size_t *hash_length, dns_name_t *name, dns_name_t *origin, - dns_hash_t hashalg, unsigned int iterations, - const unsigned char *salt, size_t saltlength); -/*%< - * Make a hashed domain name from an unhashed one. If rethash is not NULL - * the raw hash is stored there. - */ - -unsigned int -dns_nsec3_hashlength(dns_hash_t hash); -/*%< - * Return the length of the hash produced by the specified algorithm - * or zero when unknown. - */ - -bool -dns_nsec3_supportedhash(dns_hash_t hash); -/*%< - * Return whether we support this hash algorithm or not. - */ - -isc_result_t -dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, - dns_ttl_t nsecttl, bool unsecure, dns_diff_t *diff); - -isc_result_t -dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, dns_ttl_t nsecttl, - bool unsecure, dns_diff_t *diff); - -isc_result_t -dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, dns_ttl_t nsecttl, - bool unsecure, dns_rdatatype_t private, - dns_diff_t *diff); -/*%< - * Add NSEC3 records for 'name', recording the change in 'diff'. - * Adjust previous NSEC3 records, if any, to reflect the addition. - * The existing NSEC3 records are removed. - * - * dns_nsec3_addnsec3() will only add records to the chain identified by - * 'nsec3param'. - * - * 'unsecure' should be set to reflect if this is a potentially - * unsecure delegation (no DS record). - * - * dns_nsec3_addnsec3s() will examine the NSEC3PARAM RRset to determine which - * chains to be updated. NSEC3PARAM records with the DNS_NSEC3FLAG_CREATE - * will be preferentially chosen over NSEC3PARAM records without - * DNS_NSEC3FLAG_CREATE set. NSEC3PARAM records with DNS_NSEC3FLAG_REMOVE - * set will be ignored by dns_nsec3_addnsec3s(). If DNS_NSEC3FLAG_CREATE - * is set then the new NSEC3 will have OPTOUT set to match the that in the - * NSEC3PARAM record otherwise OPTOUT will be inherited from the previous - * record in the chain. - * - * dns_nsec3_addnsec3sx() is similar to dns_nsec3_addnsec3s() but 'private' - * specifies the type of the private rdataset to be checked in addition to - * the nsec3param rdataset at the zone apex. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'name' to be valid. - * 'nsec3param' to be valid. - * 'diff' to be valid. - */ - -isc_result_t -dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff); - -isc_result_t -dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_diff_t *diff); - -isc_result_t -dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_rdatatype_t private, dns_diff_t *diff); -/*%< - * Remove NSEC3 records for 'name', recording the change in 'diff'. - * Adjust previous NSEC3 records, if any, to reflect the removal. - * - * dns_nsec3_delnsec3() performs the above for the chain identified by - * 'nsec3param'. - * - * dns_nsec3_delnsec3s() examines the NSEC3PARAM RRset in a similar manner - * to dns_nsec3_addnsec3s(). Unlike dns_nsec3_addnsec3s() updated NSEC3 - * records have the OPTOUT flag preserved. - * - * dns_nsec3_delnsec3sx() is similar to dns_nsec3_delnsec3s() but 'private' - * specifies the type of the private rdataset to be checked in addition to - * the nsec3param rdataset at the zone apex. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'name' to be valid. - * 'nsec3param' to be valid. - * 'diff' to be valid. - */ - -isc_result_t -dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, - bool complete, bool *answer); - -isc_result_t -dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, - bool complete, dns_rdatatype_t private, - bool *answer); -/*%< - * Check if there are any complete/to be built NSEC3 chains. - * If 'complete' is true only complete chains will be recognized. - * - * dns_nsec3_activex() is similar to dns_nsec3_active() but 'private' - * specifies the type of the private rdataset to be checked in addition to - * the nsec3param rdataset at the zone apex. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'answer' to be non NULL. - */ - -isc_result_t -dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, - isc_mem_t *mctx, unsigned int *iterationsp); -/*%< - * Find the maximum permissible number of iterations allowed based on - * the key strength. - * - * Requires: - * 'db' to be valid. - * 'version' to be valid or NULL. - * 'mctx' to be valid. - * 'iterationsp' to be non NULL. - */ - -bool -dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, - unsigned char *buf, size_t buflen); -/*%< - * Convert a private rdata to a nsec3param rdata. - * - * Return true if 'src' could be successfully converted. - * - * 'buf' should be at least DNS_NSEC3PARAM_BUFFERSIZE in size. - */ - -void -dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, - dns_rdatatype_t privatetype, - unsigned char *buf, size_t buflen); -/*%< - * Convert a nsec3param rdata to a private rdata. - * - * 'buf' should be at least src->length + 1 in size. - */ - -isc_result_t -dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst, - size_t dstlen); -/*%< - * Convert the salt of given NSEC3PARAM RDATA into hex-encoded, NULL-terminated - * text stored at "dst". - * - * Requires: - * - *\li "dst" to have enough space (as indicated by "dstlen") to hold the - * resulting text and its NULL-terminating byte. - */ - -isc_result_t -dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, - dns_zone_t *zone, bool nonsec, - dns_diff_t *diff); - -/*%< - * Mark NSEC3PARAM for deletion. - */ - -isc_result_t -dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, - dns_name_t *nsec3name, dns_rdataset_t *nsec3set, - dns_name_t *zonename, bool *exists, - bool *data, bool *optout, - bool *unknown, bool *setclosest, - bool *setnearest, dns_name_t *closest, - dns_name_t *nearest, dns_nseclog_t logit, void *arg); - -ISC_LANG_ENDDECLS - -#endif /* DNS_NSEC3_H */ diff --git a/lib/dns-pkcs11/include/dns/nta.h b/lib/dns-pkcs11/include/dns/nta.h deleted file mode 100644 index 6a7739e..0000000 --- a/lib/dns-pkcs11/include/dns/nta.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_NTA_H -#define DNS_NTA_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The NTA module provides services for storing and retrieving negative - * trust anchors, and determine whether a given domain is subject to - * DNSSEC validation. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -struct dns_ntatable { - /* Unlocked. */ - unsigned int magic; - dns_view_t *view; - isc_rwlock_t rwlock; - isc_taskmgr_t *taskmgr; - isc_timermgr_t *timermgr; - isc_task_t *task; - /* Locked by rwlock. */ - uint32_t references; - dns_rbt_t *table; - bool shuttingdown; -}; - -#define NTATABLE_MAGIC ISC_MAGIC('N', 'T', 'A', 't') -#define VALID_NTATABLE(nt) ISC_MAGIC_VALID(nt, NTATABLE_MAGIC) - -isc_result_t -dns_ntatable_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, - dns_ntatable_t **ntatablep); -/*%< - * Create an NTA table in view 'view'. - * - * Requires: - * - *\li 'view' is a valid view. - * - *\li 'tmgr' is a valid timer manager. - * - *\li ntatablep != NULL && *ntatablep == NULL - * - * Ensures: - * - *\li On success, *ntatablep is a valid, empty NTA table. - * - * Returns: - * - *\li ISC_R_SUCCESS - *\li Any other result indicates failure. - */ - -void -dns_ntatable_attach(dns_ntatable_t *source, dns_ntatable_t **targetp); -/*%< - * Attach *targetp to source. - * - * Requires: - * - *\li 'source' is a valid ntatable. - * - *\li 'targetp' points to a NULL dns_ntatable_t *. - * - * Ensures: - * - *\li *targetp is attached to source. - */ - -void -dns_ntatable_detach(dns_ntatable_t **ntatablep); -/*%< - * Detach *ntatablep from its ntatable. - * - * Requires: - * - *\li 'ntatablep' points to a valid ntatable. - * - * Ensures: - * - *\li *ntatablep is NULL. - * - *\li If '*ntatablep' is the last reference to the ntatable, - * all resources used by the ntatable will be freed - */ - -isc_result_t -dns_ntatable_add(dns_ntatable_t *ntatable, dns_name_t *name, - bool force, isc_stdtime_t now, - uint32_t lifetime); -/*%< - * Add a negative trust anchor to 'ntatable' for name 'name', - * which will expire at time 'now' + 'lifetime'. If 'force' is false, - * then the name will be checked periodically to see if it's bogus; - * if not, then the NTA will be allowed to expire early. - * - * Notes: - * - *\li If an NTA already exists in the table, its expiry time - * is updated. - * - * Requires: - * - *\li 'ntatable' points to a valid ntatable. - * - *\li 'name' points to a valid name. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - -isc_result_t -dns_ntatable_delete(dns_ntatable_t *ntatable, dns_name_t *keyname); -/*%< - * Delete node(s) from 'ntatable' matching name 'keyname' - * - * Requires: - * - *\li 'ntatable' points to a valid ntatable. - * - *\li 'name' is not NULL - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - -bool -dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now, - dns_name_t *name, dns_name_t *anchor); -/*%< - * Return true if 'name' is below a non-expired negative trust - * anchor which in turn is at or below 'anchor'. - * - * If 'ntatable' has not been initialized, return false. - * - * Requires: - * - *\li 'ntatable' is NULL or is a valid ntatable. - * - *\li 'name' is a valid absolute name. - */ - -isc_result_t -dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf); -/*%< - * Dump the NTA table to buffer at 'buf' - * - * Requires: - * \li "ntatable" is a valid table. - * - * \li "*buf" is a valid buffer. - */ - -isc_result_t -dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp); -/*%< - * Dump the NTA table to the file opened as 'fp'. - */ - -isc_result_t -dns_ntatable_save(dns_ntatable_t *ntatable, FILE *fp); -/*%< - * Save the NTA table to the file opened as 'fp', for later loading. - */ - -void -dns_ntatable_shutdown(dns_ntatable_t *ntatable); -/*%< - * Cancel future checks to see if NTAs can be removed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_NTA_H */ diff --git a/lib/dns-pkcs11/include/dns/opcode.h b/lib/dns-pkcs11/include/dns/opcode.h deleted file mode 100644 index dcf9bed..0000000 --- a/lib/dns-pkcs11/include/dns/opcode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_OPCODE_H -#define DNS_OPCODE_H 1 - -/*! \file dns/opcode.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target); -/*%< - * Put a textual representation of error 'opcode' into 'target'. - * - * Requires: - *\li 'opcode' is a valid opcode. - * - *\li 'target' is a valid text buffer. - * - * Ensures: - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_OPCODE_H */ diff --git a/lib/dns-pkcs11/include/dns/order.h b/lib/dns-pkcs11/include/dns/order.h deleted file mode 100644 index f27512e..0000000 --- a/lib/dns-pkcs11/include/dns/order.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ORDER_H -#define DNS_ORDER_H 1 - -/*! \file dns/order.h */ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_order_create(isc_mem_t *mctx, dns_order_t **orderp); -/*%< - * Create a order object. - * - * Requires: - * \li 'orderp' to be non NULL and '*orderp == NULL'. - *\li 'mctx' to be valid. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -isc_result_t -dns_order_add(dns_order_t *order, dns_name_t *name, - dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, - unsigned int mode); -/*%< - * Add a entry to the end of the order list. - * - * Requires: - * \li 'order' to be valid. - *\li 'name' to be valid. - *\li 'mode' to be one of #DNS_RDATASETATTR_RANDOMIZE, - * #DNS_RDATASETATTR_FIXEDORDER or zero (#DNS_RDATASETATTR_CYCLIC). - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -unsigned int -dns_order_find(dns_order_t *order, dns_name_t *name, - dns_rdatatype_t rdtype, dns_rdataclass_t rdclass); -/*%< - * Find the first matching entry on the list. - * - * Requires: - *\li 'order' to be valid. - *\li 'name' to be valid. - * - * Returns the mode set by dns_order_add() or zero. - */ - -void -dns_order_attach(dns_order_t *source, dns_order_t **target); -/*%< - * Attach to the 'source' object. - * - * Requires: - * \li 'source' to be valid. - *\li 'target' to be non NULL and '*target == NULL'. - */ - -void -dns_order_detach(dns_order_t **orderp); -/*%< - * Detach from the object. Clean up if last this was the last - * reference. - * - * Requires: - *\li '*orderp' to be valid. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ORDER_H */ diff --git a/lib/dns-pkcs11/include/dns/peer.h b/lib/dns-pkcs11/include/dns/peer.h deleted file mode 100644 index 2c737fc..0000000 --- a/lib/dns-pkcs11/include/dns/peer.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_PEER_H -#define DNS_PEER_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/peer.h - * \brief - * Data structures for peers (e.g. a 'server' config file statement) - */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include - -#include - -#define DNS_PEERLIST_MAGIC ISC_MAGIC('s','e','R','L') -#define DNS_PEER_MAGIC ISC_MAGIC('S','E','r','v') - -#define DNS_PEERLIST_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEERLIST_MAGIC) -#define DNS_PEER_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEER_MAGIC) - -/*** - *** Types - ***/ - -struct dns_peerlist { - unsigned int magic; - uint32_t refs; - - isc_mem_t *mem; - - ISC_LIST(dns_peer_t) elements; -}; - -struct dns_peer { - unsigned int magic; - uint32_t refs; - - isc_mem_t *mem; - - isc_netaddr_t address; - unsigned int prefixlen; - bool bogus; - dns_transfer_format_t transfer_format; - uint32_t transfers; - bool support_ixfr; - bool provide_ixfr; - bool request_ixfr; - bool support_edns; - bool request_nsid; - bool send_cookie; - bool request_expire; - bool force_tcp; - dns_name_t *key; - isc_sockaddr_t *transfer_source; - isc_dscp_t transfer_dscp; - isc_sockaddr_t *notify_source; - isc_dscp_t notify_dscp; - isc_sockaddr_t *query_source; - isc_dscp_t query_dscp; - uint16_t udpsize; /* receive size */ - uint16_t maxudp; /* transmit size */ - uint8_t ednsversion; /* edns version */ - - uint32_t bitflags; - - ISC_LINK(dns_peer_t) next; -}; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list); - -void -dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target); - -void -dns_peerlist_detach(dns_peerlist_t **list); - -/* - * After return caller still holds a reference to peer. - */ -void -dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer); - -/* - * Ditto. */ -isc_result_t -dns_peerlist_peerbyaddr(dns_peerlist_t *peers, isc_netaddr_t *addr, - dns_peer_t **retval); - -/* - * What he said. - */ -isc_result_t -dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval); - -isc_result_t -dns_peer_new(isc_mem_t *mem, isc_netaddr_t *ipaddr, dns_peer_t **peer); - -isc_result_t -dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *ipaddr, - unsigned int prefixlen, dns_peer_t **peer); - -void -dns_peer_attach(dns_peer_t *source, dns_peer_t **target); - -void -dns_peer_detach(dns_peer_t **list); - -isc_result_t -dns_peer_setbogus(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getbogus(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setrequestixfr(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getrequestixfr(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setprovideixfr(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getprovideixfr(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setrequestnsid(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setsendcookie(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getsendcookie(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setrequestexpire(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getrequestexpire(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setsupportedns(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getforcetcp(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_setforcetcp(dns_peer_t *peer, bool newval); - -isc_result_t -dns_peer_getsupportedns(dns_peer_t *peer, bool *retval); - -isc_result_t -dns_peer_settransfers(dns_peer_t *peer, uint32_t newval); - -isc_result_t -dns_peer_gettransfers(dns_peer_t *peer, uint32_t *retval); - -isc_result_t -dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval); - -isc_result_t -dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval); - -isc_result_t -dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval); - -isc_result_t -dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval); - -isc_result_t -dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval); - -isc_result_t -dns_peer_settransfersource(dns_peer_t *peer, - const isc_sockaddr_t *transfer_source); - -isc_result_t -dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); - -isc_result_t -dns_peer_setudpsize(dns_peer_t *peer, uint16_t udpsize); - -isc_result_t -dns_peer_getudpsize(dns_peer_t *peer, uint16_t *udpsize); - -isc_result_t -dns_peer_setmaxudp(dns_peer_t *peer, uint16_t maxudp); - -isc_result_t -dns_peer_getmaxudp(dns_peer_t *peer, uint16_t *maxudp); - -isc_result_t -dns_peer_setnotifysource(dns_peer_t *peer, const isc_sockaddr_t *notify_source); - -isc_result_t -dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source); - -isc_result_t -dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source); - -isc_result_t -dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source); - -isc_result_t -dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp); - -isc_result_t -dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp); - -isc_result_t -dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp); - -isc_result_t -dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp); - -isc_result_t -dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp); - -isc_result_t -dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp); - -isc_result_t -dns_peer_setednsversion(dns_peer_t *peer, uint8_t ednsversion); - -isc_result_t -dns_peer_getednsversion(dns_peer_t *peer, uint8_t *ednsversion); -ISC_LANG_ENDDECLS - -#endif /* DNS_PEER_H */ diff --git a/lib/dns-pkcs11/include/dns/portlist.h b/lib/dns-pkcs11/include/dns/portlist.h deleted file mode 100644 index 30705ac..0000000 --- a/lib/dns-pkcs11/include/dns/portlist.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file dns/portlist.h */ - -#include - -#include -#include -#include - -#include - -#ifndef DNS_PORTLIST_H -#define DNS_PORTLIST_H 1 - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp); -/*%< - * Create a port list. - * - * Requires: - *\li 'mctx' to be valid. - *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_UNEXPECTED - */ - -isc_result_t -dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port); -/*%< - * Add the given tuple to the portlist. - * - * Requires: - *\li 'portlist' to be valid. - *\li 'af' to be AF_INET or AF_INET6 - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -void -dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port); -/*%< - * Remove the given tuple to the portlist. - * - * Requires: - *\li 'portlist' to be valid. - *\li 'af' to be AF_INET or AF_INET6 - */ - -bool -dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port); -/*%< - * Find the given tuple to the portlist. - * - * Requires: - *\li 'portlist' to be valid. - *\li 'af' to be AF_INET or AF_INET6 - * - * Returns - * \li #true if the tuple is found, false otherwise. - */ - -void -dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp); -/*%< - * Attach to a port list. - * - * Requires: - *\li 'portlist' to be valid. - *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; - */ - -void -dns_portlist_detach(dns_portlist_t **portlistp); -/*%< - * Detach from a port list. - * - * Requires: - *\li '*portlistp' to be valid. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_PORTLIST_H */ diff --git a/lib/dns-pkcs11/include/dns/private.h b/lib/dns-pkcs11/include/dns/private.h deleted file mode 100644 index 0d3fb3b..0000000 --- a/lib/dns-pkcs11/include/dns/private.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include - -#ifndef DNS_PRIVATE_H -#define DNS_PRIVATE_H - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_private_chains(dns_db_t *db, dns_dbversion_t *ver, - dns_rdatatype_t privatetype, - bool *build_nsec, bool *build_nsec3); -/*%< - * Examine the NSEC, NSEC3PARAM and privatetype RRsets at the apex of the - * database to determine which of NSEC or NSEC3 chains we are currently - * maintaining. In normal operations only one of NSEC or NSEC3 is being - * maintained but when we are transitiong between NSEC and NSEC3 we need - * to update both sets of chains. If 'privatetype' is zero then the - * privatetype RRset will not be examined. - * - * Requires: - * \li 'db' is valid. - * \li 'version' is valid or NULL. - * \li 'build_nsec' is a pointer to a bool or NULL. - * \li 'build_nsec3' is a pointer to a bool or NULL. - * - * Returns: - * \li ISC_R_SUCCESS, 'build_nsec' and 'build_nsec3' will be valid. - * \li other on error - */ - -isc_result_t -dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer); -/*%< - * Convert a private-type RR 'privaterdata' to human-readable form, - * and place the result in 'buffer'. The text should indicate - * which action the private-type record specifies and whether the - * action has been completed. - * - * Requires: - * \li 'privaterdata' is a valid rdata containing at least five bytes - * \li 'buffer' is a valid buffer - * - * Returns: - * \li ISC_R_SUCCESS - * \li other on error - */ - -ISC_LANG_ENDDECLS - -#endif diff --git a/lib/dns-pkcs11/include/dns/rbt.h b/lib/dns-pkcs11/include/dns/rbt.h deleted file mode 100644 index 076bf36..0000000 --- a/lib/dns-pkcs11/include/dns/rbt.h +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RBT_H -#define DNS_RBT_H 1 - -/*! \file dns/rbt.h */ - -#include -#include - -#include -#include -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -#define DNS_RBT_USEHASH 1 - -/*@{*/ -/*% - * Option values for dns_rbt_findnode() and dns_rbt_findname(). - * These are used to form a bitmask. - */ -#define DNS_RBTFIND_NOOPTIONS 0x00 -#define DNS_RBTFIND_EMPTYDATA 0x01 -#define DNS_RBTFIND_NOEXACT 0x02 -#define DNS_RBTFIND_NOPREDECESSOR 0x04 -/*@}*/ - -#ifndef DNS_RBT_USEISCREFCOUNT -#ifdef ISC_REFCOUNT_HAVEATOMIC -#define DNS_RBT_USEISCREFCOUNT 1 -#endif -#endif - -#define DNS_RBT_USEMAGIC 1 - -/* - * These should add up to 30. - */ -#define DNS_RBT_LOCKLENGTH 10 -#define DNS_RBT_REFLENGTH 20 - -#define DNS_RBTNODE_MAGIC ISC_MAGIC('R','B','N','O') -#if DNS_RBT_USEMAGIC -#define DNS_RBTNODE_VALID(n) ISC_MAGIC_VALID(n, DNS_RBTNODE_MAGIC) -#else -#define DNS_RBTNODE_VALID(n) true -#endif - -/*% - * This is the structure that is used for each node in the red/black - * tree of trees. NOTE WELL: the implementation manages this as a variable - * length structure, with the actual wire-format name and other data - * appended to this structure. Allocating a contiguous block of memory for - * multiple dns_rbtnode structures will not work. - */ -typedef struct dns_rbtnode dns_rbtnode_t; -enum { - DNS_RBT_NSEC_NORMAL=0, /* in main tree */ - DNS_RBT_NSEC_HAS_NSEC=1, /* also has node in nsec tree */ - DNS_RBT_NSEC_NSEC=2, /* in nsec tree */ - DNS_RBT_NSEC_NSEC3=3 /* in nsec3 tree */ -}; -struct dns_rbtnode { -#if DNS_RBT_USEMAGIC - unsigned int magic; -#endif - /*@{*/ - /*! - * The following bitfields add up to a total bitwidth of 32. - * The range of values necessary for each item is indicated, - * but in the case of "attributes" the field is wider to accommodate - * possible future expansion. - * - * In each case below the "range" indicated is what's _necessary_ for - * the bitfield to hold, not what it actually _can_ hold. - * - * Note: Tree lock must be held before modifying these - * bit-fields. - * - * Note: The two "unsigned int :0;" unnamed bitfields on either - * side of the bitfields below are scaffolding that border the - * set of bitfields which are accessed after acquiring the tree - * lock. Please don't insert any other bitfield members between - * the unnamed bitfields unless they should also be accessed - * after acquiring the tree lock. - */ - unsigned int :0; /* start of bitfields c/o tree lock */ - unsigned int is_root : 1; /*%< range is 0..1 */ - unsigned int color : 1; /*%< range is 0..1 */ - unsigned int find_callback : 1; /*%< range is 0..1 */ - unsigned int attributes : 3; /*%< range is 0..2 */ - unsigned int nsec : 2; /*%< range is 0..3 */ - unsigned int namelen : 8; /*%< range is 1..255 */ - unsigned int offsetlen : 8; /*%< range is 1..128 */ - unsigned int oldnamelen : 8; /*%< range is 1..255 */ - /*@}*/ - - /* flags needed for serialization to file*/ - unsigned int is_mmapped : 1; - unsigned int parent_is_relative : 1; - unsigned int left_is_relative : 1; - unsigned int right_is_relative : 1; - unsigned int down_is_relative : 1; - unsigned int data_is_relative : 1; - - /* node needs to be cleaned from rpz */ - unsigned int rpz : 1; - unsigned int :0; /* end of bitfields c/o tree lock */ - -#ifdef DNS_RBT_USEHASH - unsigned int hashval; - dns_rbtnode_t *uppernode; - dns_rbtnode_t *hashnext; -#endif - dns_rbtnode_t *parent; - dns_rbtnode_t *left; - dns_rbtnode_t *right; - dns_rbtnode_t *down; - - /*% - * Used for LRU cache. This linked list is used to mark nodes which - * have no data any longer, but we cannot unlink at that exact moment - * because we did not or could not obtain a write lock on the tree. - */ - ISC_LINK(dns_rbtnode_t) deadlink; - - /*@{*/ - /*! - * These values are used in the RBT DB implementation. The appropriate - * node lock must be held before accessing them. - * - * Note: The two "unsigned int :0;" unnamed bitfields on either - * side of the bitfields below are scaffolding that border the - * set of bitfields which are accessed after acquiring the node - * lock. Please don't insert any other bitfield members between - * the unnamed bitfields unless they should also be accessed - * after acquiring the node lock. - * - * NOTE: Do not merge these fields into bitfields above, as - * they'll all be put in the same qword that could be accessed - * without the node lock as it shares the qword with other - * members. Leave these members here so that they occupy a - * separate region of memory. - */ - void *data; - unsigned int locknum; - unsigned int :0; /* start of bitfields c/o node lock */ - unsigned int dirty:1; - unsigned int wild:1; -#ifndef DNS_RBT_USEISCREFCOUNT - unsigned int references:DNS_RBT_REFLENGTH; -#endif - unsigned int :0; /* end of bitfields c/o node lock */ -#ifdef DNS_RBT_USEISCREFCOUNT - isc_refcount_t references; /* note that this is not in the bitfield */ -#endif - /*@}*/ -}; - -typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, - dns_name_t *name, - void *callback_arg); - -typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file, - unsigned char *data, - void *arg, - uint64_t *crc); - -typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode, - void *base, size_t offset, - void *arg, uint64_t *crc); - -typedef void (*dns_rbtdeleter_t)(void *, void *); - -/***** - ***** Chain Info - *****/ - -/*! - * A chain is used to keep track of the sequence of nodes to reach any given - * node from the root of the tree. Originally nodes did not have parent - * pointers in them (for memory usage reasons) so there was no way to find - * the path back to the root from any given node. Now that nodes have parent - * pointers, chains might be going away in a future release, though the - * movement functionality would remain. - * - * Chains may be used to iterate over a tree of trees. After setting up the - * chain's structure using dns_rbtnodechain_init(), it needs to be initialized - * to point to the lexically first or lexically last node in the tree of trees - * using dns_rbtnodechain_first() or dns_rbtnodechain_last(), respectively. - * Calling dns_rbtnodechain_next() or dns_rbtnodechain_prev() then moves the - * chain over to the next or previous node, respectively. - * - * In any event, parent information, whether via parent pointers or chains, is - * necessary information for iterating through the tree or for basic internal - * tree maintenance issues (ie, the rotations that are done to rebalance the - * tree when a node is added). The obvious implication of this is that for a - * chain to remain valid, the tree has to be locked down against writes for the - * duration of the useful life of the chain, because additions or removals can - * change the path from the root to the node the chain has targeted. - * - * The dns_rbtnodechain_ functions _first, _last, _prev and _next all take - * dns_name_t parameters for the name and the origin, which can be NULL. If - * non-NULL, 'name' will end up pointing to the name data and offsets that are - * stored at the node (and thus it will be read-only), so it should be a - * regular dns_name_t that has been initialized with dns_name_init. When - * 'origin' is non-NULL, it will get the name of the origin stored in it, so it - * needs to have its own buffer space and offsets, which is most easily - * accomplished with a dns_fixedname_t. It is _not_ necessary to reinitialize - * either 'name' or 'origin' between calls to the chain functions. - * - * NOTE WELL: even though the name data at the root of the tree of trees will - * be absolute (typically just "."), it will will be made into a relative name - * with an origin of "." -- an empty name when the node is ".". This is - * because a common on operation on 'name' and 'origin' is to use - * dns_name_concatenate() on them to generate the complete name. An empty name - * can be detected when dns_name_countlabels == 0, and is printed by - * dns_name_totext()/dns_name_format() as "@", consistent with RFC1035's - * definition of "@" as the current origin. - * - * dns_rbtnodechain_current is similar to the _first, _last, _prev and _next - * functions but additionally can provide the node to which the chain points. - */ - -/*% - * The number of level blocks to allocate at a time. Currently the maximum - * number of levels is allocated directly in the structure, but future - * revisions of this code might have a static initial block with dynamic - * growth. Allocating space for 256 levels when the tree is almost never that - * deep is wasteful, but it's not clear that it matters, since the waste is - * only 2MB for 1000 concurrently active chains on a system with 64-bit - * pointers. - */ -#define DNS_RBT_LEVELBLOCK 254 - -typedef struct dns_rbtnodechain { - unsigned int magic; - isc_mem_t * mctx; - /*% - * The terminal node of the chain. It is not in levels[]. - * This is ostensibly private ... but in a pinch it could be - * used tell that the chain points nowhere without needing to - * call dns_rbtnodechain_current(). - */ - dns_rbtnode_t * end; - /*% - * The maximum number of labels in a name is 128; bitstrings mean - * a conceptually very large number (which I have not bothered to - * compute) of logical levels because splitting can potentially occur - * at each bit. However, DNSSEC restricts the number of "logical" - * labels in a name to 255, meaning only 254 pointers are needed - * in the worst case. - */ - dns_rbtnode_t * levels[DNS_RBT_LEVELBLOCK]; - /*% - * level_count indicates how deep the chain points into the - * tree of trees, and is the index into the levels[] array. - * Thus, levels[level_count - 1] is the last level node stored. - * A chain that points to the top level of the tree of trees has - * a level_count of 0, the first level has a level_count of 1, and - * so on. - */ - unsigned int level_count; - /*% - * level_matches tells how many levels matched above the node - * returned by dns_rbt_findnode(). A match (partial or exact) found - * in the first level thus results in level_matches being set to 1. - * This is used by the rbtdb to set the start point for a recursive - * search of superdomains until the RR it is looking for is found. - */ - unsigned int level_matches; -} dns_rbtnodechain_t; - -/***** - ***** Public interfaces. - *****/ -isc_result_t -dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, - void *deleter_arg, dns_rbt_t **rbtp); -/*%< - * Initialize a red-black tree of trees. - * - * Notes: - *\li The deleter argument, if non-null, points to a function that is - * responsible for cleaning up any memory associated with the data - * pointer of a node when the node is deleted. It is passed the - * deleted node's data pointer as its first argument and deleter_arg - * as its second argument. - * - * Requires: - * \li mctx is a pointer to a valid memory context. - *\li rbtp != NULL && *rbtp == NULL - *\li arg == NULL iff deleter == NULL - * - * Ensures: - *\li If result is ISC_R_SUCCESS: - * *rbtp points to a valid red-black tree manager - * - *\li If result is failure: - * *rbtp does not point to a valid red-black tree manager. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource limit: Out of Memory - */ - -isc_result_t -dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data); -/*%< - * Add 'name' to the tree of trees, associated with 'data'. - * - * Notes: - *\li 'data' is never required to be non-NULL, but specifying it - * when the name is added is faster than searching for 'name' - * again and then setting the data pointer. The lack of a data pointer - * for a node also has other ramifications regarding whether - * dns_rbt_findname considers a node to exist, or dns_rbt_deletename - * joins nodes. - * - * Requires: - *\li rbt is a valid rbt manager. - *\li dns_name_isabsolute(name) == TRUE - * - * Ensures: - *\li 'name' is not altered in any way. - * - *\li Any external references to nodes in the tree are unaffected by - * node splits that are necessary to insert the new name. - * - *\li If result is #ISC_R_SUCCESS: - * 'name' is findable in the red/black tree of trees in O(log N). - * The data pointer of the node for 'name' is set to 'data'. - * - *\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE: - * The tree of trees is unaltered. - * - *\li If result is #ISC_R_NOMEMORY: - * No guarantees. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_EXISTS The name already exists with associated data. - *\li #ISC_R_NOSPACE The name had more logical labels than are allowed. - *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory - */ - -isc_result_t -dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep); - -/*%< - * Just like dns_rbt_addname, but returns the address of the node. - * - * Requires: - *\li rbt is a valid rbt structure. - *\li dns_name_isabsolute(name) == TRUE - *\li nodep != NULL && *nodep == NULL - * - * Ensures: - *\li 'name' is not altered in any way. - * - *\li Any external references to nodes in the tree are unaffected by - * node splits that are necessary to insert the new name. - * - *\li If result is ISC_R_SUCCESS: - * 'name' is findable in the red/black tree of trees in O(log N). - * *nodep is the node that was added for 'name'. - * - *\li If result is ISC_R_EXISTS: - * The tree of trees is unaltered. - * *nodep is the existing node for 'name'. - * - *\li If result is ISC_R_NOMEMORY: - * No guarantees. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_EXISTS The name already exists, possibly without data. - *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory - */ - -isc_result_t -dns_rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options, - dns_name_t *foundname, void **data); -/*%< - * Get the data pointer associated with 'name'. - * - * Notes: - *\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is - * returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is - * an exact match in the tree. - * - *\li A node that has no data is considered not to exist for this function, - * unless the #DNS_RBTFIND_EMPTYDATA option is set. - * - * Requires: - *\li rbt is a valid rbt manager. - *\li dns_name_isabsolute(name) == TRUE - *\li data != NULL && *data == NULL - * - * Ensures: - *\li 'name' and the tree are not altered in any way. - * - *\li If result is ISC_R_SUCCESS: - * *data is the data associated with 'name'. - * - *\li If result is DNS_R_PARTIALMATCH: - * *data is the data associated with the deepest superdomain - * of 'name' which has data. - * - *\li If result is ISC_R_NOTFOUND: - * Neither the name nor a superdomain was found with data. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #DNS_R_PARTIALMATCH Superdomain found with data - *\li #ISC_R_NOTFOUND No match - *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed - */ - -isc_result_t -dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname, - dns_rbtnode_t **node, dns_rbtnodechain_t *chain, - unsigned int options, dns_rbtfindcallback_t callback, - void *callback_arg); -/*%< - * Find the node for 'name'. - * - * Notes: - *\li A node that has no data is considered not to exist for this function, - * unless the DNS_RBTFIND_EMPTYDATA option is set. This applies to both - * exact matches and partial matches. - * - *\li If the chain parameter is non-NULL, then the path through the tree - * to the DNSSEC predecessor of the searched for name is maintained, - * unless the DNS_RBTFIND_NOPREDECESSOR or DNS_RBTFIND_NOEXACT option - * is used. (For more details on those options, see below.) - * - *\li If there is no predecessor, then the chain will point to nowhere, as - * indicated by chain->end being NULL or dns_rbtnodechain_current - * returning ISC_R_NOTFOUND. Note that in a normal Internet DNS RBT - * there will always be a predecessor for all names except the root - * name, because '.' will exist and '.' is the predecessor of - * everything. But you can certainly construct a trivial tree and a - * search for it that has no predecessor. - * - *\li Within the chain structure, the 'levels' member of the structure holds - * the root node of each level except the first. - * - *\li The 'level_count' of the chain indicates how deep the chain to the - * predecessor name is, as an index into the 'levels[]' array. It does - * not count name elements, per se, but only levels of the tree of trees, - * the distinction arising because multiple labels from a name can be - * stored on only one level. It is also does not include the level - * that has the node, since that level is not stored in levels[]. - * - *\li The chain's 'level_matches' is not directly related to the predecessor. - * It is the number of levels above the level of the found 'node', - * regardless of whether it was a partial match or exact match. When - * the node is found in the top level tree, or no node is found at all, - * level_matches is 0. - * - *\li When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is - * returned (also subject to DNS_RBTFIND_EMPTYDATA), even when - * there is an exact match in the tree. In this case, the chain - * will not point to the DNSSEC predecessor, but will instead point - * to the exact match, if there was any. Thus the preceding paragraphs - * should have "exact match" substituted for "predecessor" to describe - * how the various elements of the chain are set. This was done to - * ensure that the chain's state was sane, and to prevent problems that - * occurred when running the predecessor location code under conditions - * it was not designed for. It is not clear *where* the chain should - * point when DNS_RBTFIND_NOEXACT is set, so if you end up using a chain - * with this option because you want a particular node, let us know - * where you want the chain pointed, so this can be made more firm. - * - * Requires: - *\li rbt is a valid rbt manager. - *\li dns_name_isabsolute(name) == TRUE. - *\li node != NULL && *node == NULL. - *\li #DNS_RBTFIND_NOEXACT and DNS_RBTFIND_NOPREDECESSOR are mutually - * exclusive. - * - * Ensures: - *\li 'name' and the tree are not altered in any way. - * - *\li If result is ISC_R_SUCCESS: - *\verbatim - * *node is the terminal node for 'name'. - - * 'foundname' and 'name' represent the same name (though not - * the same memory). - - * 'chain' points to the DNSSEC predecessor, if any, of 'name'. - * - * chain->level_matches and chain->level_count are equal. - *\endverbatim - * - * If result is DNS_R_PARTIALMATCH: - *\verbatim - * *node is the data associated with the deepest superdomain - * of 'name' which has data. - * - * 'foundname' is the name of deepest superdomain (which has - * data, unless the DNS_RBTFIND_EMPTYDATA option is set). - * - * 'chain' points to the DNSSEC predecessor, if any, of 'name'. - *\endverbatim - * - *\li If result is ISC_R_NOTFOUND: - *\verbatim - * Neither the name nor a superdomain was found. *node is NULL. - * - * 'chain' points to the DNSSEC predecessor, if any, of 'name'. - * - * chain->level_matches is 0. - *\endverbatim - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #DNS_R_PARTIALMATCH Superdomain found with data - *\li #ISC_R_NOTFOUND No match, or superdomain with no data - *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed - */ - -isc_result_t -dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, bool recurse); -/*%< - * Delete 'name' from the tree of trees. - * - * Notes: - *\li When 'name' is removed, if recurse is true then all of its - * subnames are removed too. - * - * Requires: - *\li rbt is a valid rbt manager. - *\li dns_name_isabsolute(name) == TRUE - * - * Ensures: - *\li 'name' is not altered in any way. - * - *\li Does NOT ensure that any external references to nodes in the tree - * are unaffected by node joins. - * - *\li If result is ISC_R_SUCCESS: - * 'name' does not appear in the tree with data; however, - * the node for the name might still exist which can be - * found with dns_rbt_findnode (but not dns_rbt_findname). - * - *\li If result is ISC_R_NOTFOUND: - * 'name' does not appear in the tree with data, because - * it did not appear in the tree before the function was called. - * - *\li If result is something else: - * See result codes for dns_rbt_findnode (if it fails, the - * node is not deleted) or dns_rbt_deletenode (if it fails, - * the node is deleted, but the tree is not optimized when - * it could have been). - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOTFOUND No match - *\li something_else Any return code from dns_rbt_findnode except - * DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND - * to be returned instead), and any code from - * dns_rbt_deletenode. - */ - -isc_result_t -dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse); -/*%< - * Delete 'node' from the tree of trees. - * - * Notes: - *\li When 'node' is removed, if recurse is true then all nodes - * in levels down from it are removed too. - * - * Requires: - *\li rbt is a valid rbt manager. - *\li node != NULL. - * - * Ensures: - *\li Does NOT ensure that any external references to nodes in the tree - * are unaffected by node joins. - * - *\li If result is ISC_R_SUCCESS: - * 'node' does not appear in the tree with data; however, - * the node might still exist if it serves as a pointer to - * a lower tree level as long as 'recurse' was false, hence - * the node could can be found with dns_rbt_findnode when - * that function's empty_data_ok parameter is true. - * - *\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE: - * The node was deleted, but the tree structure was not - * optimized. - * - * Returns: - *\li #ISC_R_SUCCESS Success - *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes. - *\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes. - */ - -void -dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name); -/*%< - * Convert the sequence of labels stored at 'node' into a 'name'. - * - * Notes: - *\li This function does not return the full name, from the root, but - * just the labels at the indicated node. - * - *\li The name data pointed to by 'name' is the information stored - * in the node, not a copy. Altering the data at this pointer - * will likely cause grief. - * - * Requires: - * \li name->offsets == NULL - * - * Ensures: - * \li 'name' is DNS_NAMEATTR_READONLY. - * - * \li 'name' will point directly to the labels stored after the - * dns_rbtnode_t struct. - * - * \li 'name' will have offsets that also point to the information stored - * as part of the node. - */ - -isc_result_t -dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name); -/*%< - * Like dns_rbt_namefromnode, but returns the full name from the root. - * - * Notes: - * \li Unlike dns_rbt_namefromnode, the name will not point directly - * to node data. Rather, dns_name_concatenate will be used to copy - * the name data from each node into the 'name' argument. - * - * Requires: - * \li name != NULL - * \li name has a dedicated buffer. - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOSPACE (possible via dns_name_concatenate) - * \li DNS_R_NAMETOOLONG (possible via dns_name_concatenate) - */ - -char * -dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, - unsigned int size); -/*%< - * Format the full name of a node for printing, using dns_name_format(). - * - * Notes: - * \li 'size' is the length of the printname buffer. This should be - * DNS_NAME_FORMATSIZE or larger. - * - * Requires: - * \li node and printname are not NULL. - * - * Returns: - * \li The 'printname' pointer. - */ - -unsigned int -dns_rbt_nodecount(dns_rbt_t *rbt); -/*%< - * Obtain the number of nodes in the tree of trees. - * - * Requires: - * \li rbt is a valid rbt manager. - */ - -size_t -dns_rbt_hashsize(dns_rbt_t *rbt); -/*%< - * Obtain the current number of buckets in the 'rbt' hash table. - * - * Requires: - * \li rbt is a valid rbt manager. - */ - -void -dns_rbt_destroy(dns_rbt_t **rbtp); -isc_result_t -dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum); -/*%< - * Stop working with a red-black tree of trees. - * If 'quantum' is zero then the entire tree will be destroyed. - * If 'quantum' is non zero then up to 'quantum' nodes will be destroyed - * allowing the rbt to be incrementally destroyed by repeated calls to - * dns_rbt_destroy2(). Once dns_rbt_destroy2() has been called no other - * operations than dns_rbt_destroy()/dns_rbt_destroy2() should be - * performed on the tree of trees. - * - * Requires: - * \li *rbt is a valid rbt manager. - * - * Ensures on ISC_R_SUCCESS: - * \li All space allocated by the RBT library has been returned. - * - * \li *rbt is invalidated as an rbt manager. - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_QUOTA if 'quantum' nodes have been destroyed. - */ - -off_t -dns_rbt_serialize_align(off_t target); -/*%< - * Align the provided integer to a pointer-size boundary. - * This should be used if, during serialization of data to a will-be - * mmap()ed file, a pointer alignment is needed for some data. - */ - -isc_result_t -dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt, - dns_rbtdatawriter_t datawriter, - void *writer_arg, off_t *offset); -/*%< - * Write out the RBT structure and its data to a file. - * - * Notes: - * \li The file must be an actual file which allows seek() calls, so it cannot - * be a stream. Returns ISC_R_INVALIDFILE if not. - */ - -isc_result_t -dns_rbt_deserialize_tree(void *base_address, size_t filesize, - off_t header_offset, isc_mem_t *mctx, - dns_rbtdeleter_t deleter, void *deleter_arg, - dns_rbtdatafixer_t datafixer, void *fixer_arg, - dns_rbtnode_t **originp, dns_rbt_t **rbtp); -/*%< - * Read a RBT structure and its data from a file. - * - * If 'originp' is not NULL, then it is pointed to the root node of the RBT. - * - * Notes: - * \li The file must be an actual file which allows seek() calls, so it cannot - * be a stream. This condition is not checked in the code. - */ - -void -dns_rbt_printtext(dns_rbt_t *rbt, - void (*data_printer)(FILE *, void *), FILE *f); -/*%< - * Print an ASCII representation of the internal structure of the red-black - * tree of trees to the passed stream. - * - * data_printer is a callback function that is called to print the data - * in a node. It should print it to the passed FILE stream. - * - * Notes: - * \li The name stored at each node, along with the node's color, is printed. - * Then the down pointer, left and right pointers are displayed - * recursively in turn. NULL down pointers are silently omitted; - * NULL left and right pointers are printed. - */ - -void -dns_rbt_printdot(dns_rbt_t *rbt, bool show_pointers, FILE *f); -/*%< - * Print a GraphViz dot representation of the internal structure of the - * red-black tree of trees to the passed stream. - * - * If show_pointers is TRUE, pointers are also included in the generated - * graph. - * - * Notes: - * \li The name stored at each node, along with the node's color is displayed. - * Then the down pointer, left and right pointers are displayed - * recursively in turn. NULL left, right and down pointers are - * silently omitted. - */ - -void -dns_rbt_printnodeinfo(dns_rbtnode_t *n, FILE *f); -/*%< - * Print out various information about a node - * - * Requires: - *\li 'n' is a valid pointer. - * - *\li 'f' points to a valid open FILE structure that allows writing. - */ - - -size_t -dns__rbt_getheight(dns_rbt_t *rbt); -/*%< - * Return the maximum height of sub-root nodes found in the red-black - * forest. - * - * The height of a node is defined as the number of nodes in the longest - * path from the node to a leaf. For each subtree in the forest, this - * function determines the height of its root node. Then it returns the - * maximum such height in the forest. - * - * Note: This function exists for testing purposes. Non-test code must - * not use it. - * - * Requires: - * \li rbt is a valid rbt manager. - */ - -bool -dns__rbt_checkproperties(dns_rbt_t *rbt); -/*%< - * Check red-black properties of the forest. - * - * Note: This function exists for testing purposes. Non-test code must - * not use it. - * - * Requires: - * \li rbt is a valid rbt manager. - */ - -size_t -dns__rbtnode_getdistance(dns_rbtnode_t *node); -/*%< - * Return the distance (in nodes) from the node to its upper node of its - * subtree. The root node has a distance of 1. A child of the root node - * has a distance of 2. - */ - -/***** - ***** Chain Functions - *****/ - -void -dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx); -/*%< - * Initialize 'chain'. - * - * Requires: - *\li 'chain' is a valid pointer. - * - *\li 'mctx' is a valid memory context. - * - * Ensures: - *\li 'chain' is suitable for use. - */ - -void -dns_rbtnodechain_reset(dns_rbtnodechain_t *chain); -/*%< - * Free any dynamic storage associated with 'chain', and then reinitialize - * 'chain'. - * - * Requires: - *\li 'chain' is a valid pointer. - * - * Ensures: - *\li 'chain' is suitable for use, and uses no dynamic storage. - */ - -void -dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain); -/*%< - * Free any dynamic storage associated with 'chain', and then invalidates it. - * - * Notes: - *\li Future calls to any dns_rbtnodechain_ function will need to call - * dns_rbtnodechain_init on the chain first (except, of course, - * dns_rbtnodechain_init itself). - * - * Requires: - *\li 'chain' is a valid chain. - * - * Ensures: - *\li 'chain' is no longer suitable for use, and uses no dynamic storage. - */ - -isc_result_t -dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin, dns_rbtnode_t **node); -/*%< - * Provide the name, origin and node to which the chain is currently pointed. - * - * Notes: - *\li The tree need not have be locked against additions for the chain - * to remain valid, however there are no guarantees if any deletion - * has been made since the chain was established. - * - * Requires: - *\li 'chain' is a valid chain. - * - * Ensures: - *\li 'node', if non-NULL, is the node to which the chain was pointed - * by dns_rbt_findnode, dns_rbtnodechain_first or dns_rbtnodechain_last. - * If none were called for the chain since it was initialized or reset, - * or if the was no predecessor to the name searched for with - * dns_rbt_findnode, then '*node' is NULL and ISC_R_NOTFOUND is returned. - * - *\li 'name', if non-NULL, is the name stored at the terminal level of - * the chain. This is typically a single label, like the "www" of - * "www.isc.org", but need not be so. At the root of the tree of trees, - * if the node is "." then 'name' is ".", otherwise it is relative to ".". - * (Minimalist and atypical case: if the tree has just the name - * "isc.org." then the root node's stored name is "isc.org." but 'name' - * will be "isc.org".) - * - *\li 'origin', if non-NULL, is the sequence of labels in the levels - * above the terminal level, such as "isc.org." in the above example. - * 'origin' is always "." for the root node. - * - * - * Returns: - *\li #ISC_R_SUCCESS name, origin & node were successfully set. - *\li #ISC_R_NOTFOUND The chain does not point to any node. - *\li <something_else> Any error return from dns_name_concatenate. - */ - -isc_result_t -dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, - dns_name_t *name, dns_name_t *origin); -/*%< - * Set the chain to the lexically first node in the tree of trees. - * - * Notes: - *\li By the definition of ordering for DNS names, the root of the tree of - * trees is the very first node, since everything else in the megatree - * uses it as a common suffix. - * - * Requires: - *\li 'chain' is a valid chain. - *\li 'rbt' is a valid rbt manager. - * - * Ensures: - *\li The chain points to the very first node of the tree. - * - *\li 'name' and 'origin', if non-NULL, are set as described for - * dns_rbtnodechain_current. Thus 'origin' will always be ".". - * - * Returns: - *\li #DNS_R_NEWORIGIN The name & origin were successfully set. - *\li <something_else> Any error result from dns_rbtnodechain_current. - */ - -isc_result_t -dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, - dns_name_t *name, dns_name_t *origin); -/*%< - * Set the chain to the lexically last node in the tree of trees. - * - * Requires: - *\li 'chain' is a valid chain. - *\li 'rbt' is a valid rbt manager. - * - * Ensures: - *\li The chain points to the very last node of the tree. - * - *\li 'name' and 'origin', if non-NULL, are set as described for - * dns_rbtnodechain_current. - * - * Returns: - *\li #DNS_R_NEWORIGIN The name & origin were successfully set. - *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain. - *\li <something_else> Any error result from dns_name_concatenate. - */ - -isc_result_t -dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin); -/*%< - * Adjusts chain to point the DNSSEC predecessor of the name to which it - * is currently pointed. - * - * Requires: - *\li 'chain' is a valid chain. - *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, - * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that - * dns_rbt_findnode is not guaranteed to point the chain somewhere, - * since there may have been no predecessor to the searched for name. - * - * Ensures: - *\li The chain is pointed to the predecessor of its current target. - * - *\li 'name' and 'origin', if non-NULL, are set as described for - * dns_rbtnodechain_current. - * - *\li 'origin' is only if a new origin was found. - * - * Returns: - *\li #ISC_R_SUCCESS The predecessor was found and 'name' was set. - *\li #DNS_R_NEWORIGIN The predecessor was found with a different - * origin and 'name' and 'origin' were set. - *\li #ISC_R_NOMORE There was no predecessor. - *\li <something_else> Any error result from dns_rbtnodechain_current. - */ - -isc_result_t -dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin); -/*%< - * Adjusts chain to point the DNSSEC successor of the name to which it - * is currently pointed. - * - * Requires: - *\li 'chain' is a valid chain. - *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, - * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that - * dns_rbt_findnode is not guaranteed to point the chain somewhere, - * since there may have been no predecessor to the searched for name. - * - * Ensures: - *\li The chain is pointed to the successor of its current target. - * - *\li 'name' and 'origin', if non-NULL, are set as described for - * dns_rbtnodechain_current. - * - *\li 'origin' is only if a new origin was found. - * - * Returns: - *\li #ISC_R_SUCCESS The successor was found and 'name' was set. - *\li #DNS_R_NEWORIGIN The successor was found with a different - * origin and 'name' and 'origin' were set. - *\li #ISC_R_NOMORE There was no successor. - *\li <something_else> Any error result from dns_name_concatenate. - */ - -isc_result_t -dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin); -/*%< - * Descend down if possible. - */ - -isc_result_t -dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name); -/*%< - * Find the next node at the current depth in DNSSEC order. - */ - -/* - * Wrapper macros for manipulating the rbtnode reference counter: - * Since we selectively use isc_refcount_t for the reference counter of - * a rbtnode, operations on the counter depend on the actual type of it. - * The following macros provide a common interface to these operations, - * hiding the back-end. The usage is the same as that of isc_refcount_xxx(). - */ -#ifdef DNS_RBT_USEISCREFCOUNT -#define dns_rbtnode_refinit(node, n) \ - do { \ - isc_refcount_init(&(node)->references, (n)); \ - } while (0) -#define dns_rbtnode_refdestroy(node) \ - do { \ - isc_refcount_destroy(&(node)->references); \ - } while (0) -#define dns_rbtnode_refcurrent(node) \ - isc_refcount_current(&(node)->references) -#define dns_rbtnode_refincrement0(node, refs) \ - do { \ - isc_refcount_increment0(&(node)->references, (refs)); \ - } while (0) -#define dns_rbtnode_refincrement(node, refs) \ - do { \ - isc_refcount_increment(&(node)->references, (refs)); \ - } while (0) -#define dns_rbtnode_refdecrement(node, refs) \ - do { \ - isc_refcount_decrement(&(node)->references, (refs)); \ - } while (0) -#else /* DNS_RBT_USEISCREFCOUNT */ -#define dns_rbtnode_refinit(node, n) ((node)->references = (n)) -#define dns_rbtnode_refdestroy(node) ISC_REQUIRE((node)->references == 0) -#define dns_rbtnode_refcurrent(node) ((node)->references) - -#if (__STDC_VERSION__ + 0) >= 199901L || defined __GNUC__ -static inline void -dns_rbtnode_refincrement0(dns_rbtnode_t *node, unsigned int *refs) { - node->references++; - if (refs != NULL) - *refs = node->references; -} - -static inline void -dns_rbtnode_refincrement(dns_rbtnode_t *node, unsigned int *refs) { - ISC_REQUIRE(node->references > 0); - node->references++; - if (refs != NULL) - *refs = node->references; -} - -static inline void -dns_rbtnode_refdecrement(dns_rbtnode_t *node, unsigned int *refs) { - ISC_REQUIRE(node->references > 0); - node->references--; - if (refs != NULL) - *refs = node->references; -} -#else -#define dns_rbtnode_refincrement0(node, refs) \ - do { \ - unsigned int *_tmp = (unsigned int *)(refs); \ - (node)->references++; \ - if ((_tmp) != NULL) \ - (*_tmp) = (node)->references; \ - } while (0) -#define dns_rbtnode_refincrement(node, refs) \ - do { \ - ISC_REQUIRE((node)->references > 0); \ - (node)->references++; \ - if ((refs) != NULL) \ - (*refs) = (node)->references; \ - } while (0) -#define dns_rbtnode_refdecrement(node, refs) \ - do { \ - ISC_REQUIRE((node)->references > 0); \ - (node)->references--; \ - if ((refs) != NULL) \ - (*refs) = (node)->references; \ - } while (0) -#endif -#endif /* DNS_RBT_USEISCREFCOUNT */ - -void -dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name); - -dns_rbtnode_t * -dns_rbt_root(dns_rbt_t *rbt); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RBT_H */ diff --git a/lib/dns-pkcs11/include/dns/rcode.h b/lib/dns-pkcs11/include/dns/rcode.h deleted file mode 100644 index 30664b6..0000000 --- a/lib/dns-pkcs11/include/dns/rcode.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RCODE_H -#define DNS_RCODE_H 1 - -/*! \file dns/rcode.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNS error value. - * - * Requires: - *\li 'rcodep' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #DNS_R_UNKNOWN type is unknown - */ - -isc_result_t dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target); -/*%< - * Put a textual representation of error 'rcode' into 'target'. - * - * Requires: - *\li 'rcode' is a valid rcode. - * - *\li 'target' is a valid text buffer. - * - * Ensures: - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -isc_result_t dns_tsigrcode_fromtext(dns_rcode_t *rcodep, - isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a TSIG/TKEY error value. - * - * Requires: - *\li 'rcodep' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #DNS_R_UNKNOWN type is unknown - */ - -isc_result_t dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target); -/*%< - * Put a textual representation of TSIG/TKEY error 'rcode' into 'target'. - * - * Requires: - *\li 'rcode' is a valid TSIG/TKEY error code. - * - *\li 'target' is a valid text buffer. - * - * Ensures: - *\li If the result is success: - * The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -isc_result_t -dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a has algorithm value. - * - * Requires: - *\li 'hashalg' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #DNS_R_UNKNOWN type is unknown - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RCODE_H */ diff --git a/lib/dns-pkcs11/include/dns/rdata.h b/lib/dns-pkcs11/include/dns/rdata.h deleted file mode 100644 index 7794fb0..0000000 --- a/lib/dns-pkcs11/include/dns/rdata.h +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RDATA_H -#define DNS_RDATA_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/rdata.h - * \brief - * Provides facilities for manipulating DNS rdata, including conversions to - * and from wire format and text format. - * - * Given the large amount of rdata possible in a nameserver, it was important - * to come up with a very efficient way of storing rdata, but at the same - * time allow it to be manipulated. - * - * The decision was to store rdata in uncompressed wire format, - * and not to make it a fully abstracted object; i.e. certain parts of the - * server know rdata is stored that way. This saves a lot of memory, and - * makes adding rdata to messages easy. Having much of the server know - * the representation would be perilous, and we certainly don't want each - * user of rdata to be manipulating such a low-level structure. This is - * where the rdata module comes in. The module allows rdata handles to be - * created and attached to uncompressed wire format regions. All rdata - * operations and conversions are done through these handles. - * - * Implementation Notes: - * - *\li The routines in this module are expected to be synthesized by the - * build process from a set of source files, one per rdata type. For - * portability, it's probably best that the building be done by a C - * program. Adding a new rdata type will be a simple matter of adding - * a file to a directory and rebuilding the server. *All* knowledge of - * the format of a particular rdata type is in this file. - * - * MP: - *\li Clients of this module must impose any required synchronization. - * - * Reliability: - *\li This module deals with low-level byte streams. Errors in any of - * the functions are likely to crash the server or corrupt memory. - * - *\li Rdata is typed, and the caller must know what type of rdata it has. - * A caller that gets this wrong could crash the server. - * - *\li The fromstruct() and tostruct() routines use a void * pointer to - * represent the structure. The caller must ensure that it passes a - * pointer to the appropriate type, or the server could crash or memory - * could be corrupted. - * - * Resources: - *\li None. - * - * Security: - * - *\li *** WARNING *** - * dns_rdata_fromwire() deals with raw network data. An error in - * this routine could result in the failure or hijacking of the server. - * - * Standards: - *\li RFC1035 - *\li Draft EDNS0 (0) - *\li Draft EDNS1 (0) - *\li Draft Binary Labels (2) - *\li Draft Local Compression (1) - *\li Various RFCs for particular types; these will be documented in the - * sources files of the types. - * - */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include -#include -#include - -ISC_LANG_BEGINDECLS - - -/*** - *** Types - ***/ - -/*% - ***** An 'rdata' is a handle to a binary region. The handle has an RR - ***** class and type, and the data in the binary region is in the format - ***** of the given class and type. - *****/ -/*% - * Clients are strongly discouraged from using this type directly, with - * the exception of the 'link' field which may be used directly for whatever - * purpose the client desires. - */ -struct dns_rdata { - unsigned char * data; - unsigned int length; - dns_rdataclass_t rdclass; - dns_rdatatype_t type; - unsigned int flags; - ISC_LINK(dns_rdata_t) link; -}; - -#define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}} - -#define DNS_RDATA_CHECKINITIALIZED -#ifdef DNS_RDATA_CHECKINITIALIZED -#define DNS_RDATA_INITIALIZED(rdata) \ - ((rdata)->data == NULL && (rdata)->length == 0 && \ - (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \ - !ISC_LINK_LINKED((rdata), link)) -#else -#ifdef ISC_LIST_CHECKINIT -#define DNS_RDATA_INITIALIZED(rdata) \ - (!ISC_LINK_LINKED((rdata), link)) -#else -#define DNS_RDATA_INITIALIZED(rdata) true -#endif -#endif - -#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record. */ -#define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */ - -#define DNS_RDATA_VALIDFLAGS(rdata) \ - (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0) - -/* - * The maximum length of a RDATA that can be sent on the wire. - * Max packet size (65535) less header (12), less name (1), type (2), - * class (2), ttl(4), length (2). - * - * None of the defined types that support name compression can exceed - * this and all new types are to be sent uncompressed. - */ - -#define DNS_RDATA_MAXLENGTH 65512U - -/* - * Flags affecting rdata formatting style. Flags 0xFFFF0000 - * are used by masterfile-level formatting and defined elsewhere. - * See additional comments at dns_rdata_tofmttext(). - */ - -/*% Split the rdata into multiple lines to try to keep it - within the "width". */ -#define DNS_STYLEFLAG_MULTILINE 0x00000001ULL - -/*% Output explanatory comments. */ -#define DNS_STYLEFLAG_COMMENT 0x00000002ULL -#define DNS_STYLEFLAG_RRCOMMENT 0x00000004ULL - -/*% Output KEYDATA in human readable format. */ -#define DNS_STYLEFLAG_KEYDATA 0x00000008ULL - -/*% Output textual RR type and RDATA in RFC 3597 unknown format */ -#define DNS_STYLEFLAG_UNKNOWNFORMAT 0x00000010ULL - -#define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE -#define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES -#define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL -#define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE -#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX -#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL -#define DNS_RDATA_UNKNOWNESCAPE 0x80000000 - -/*** - *** Initialization - ***/ - -void -dns_rdata_init(dns_rdata_t *rdata); -/*%< - * Make 'rdata' empty. - * - * Requires: - * 'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata) - */ - -void -dns_rdata_reset(dns_rdata_t *rdata); -/*%< - * Make 'rdata' empty. - * - * Requires: - *\li 'rdata' is a previously initialized rdata and is not linked. - */ - -void -dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); -/*%< - * Clone 'target' from 'src'. - * - * Requires: - *\li 'src' to be initialized. - *\li 'target' to be initialized. - */ - -/*** - *** Comparisons - ***/ - -int -dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); -/*%< - * Determine the relative ordering under the DNSSEC order relation of - * 'rdata1' and 'rdata2'. - * - * Requires: - * - *\li 'rdata1' is a valid, non-empty rdata - * - *\li 'rdata2' is a valid, non-empty rdata - * - * Returns: - *\li < 0 'rdata1' is less than 'rdata2' - *\li 0 'rdata1' is equal to 'rdata2' - *\li > 0 'rdata1' is greater than 'rdata2' - */ - -int -dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); -/*%< - * dns_rdata_casecompare() is similar to dns_rdata_compare() but also - * compares domain names case insensitively in known rdata types that - * are treated as opaque data by dns_rdata_compare(). - * - * Requires: - * - *\li 'rdata1' is a valid, non-empty rdata - * - *\li 'rdata2' is a valid, non-empty rdata - * - * Returns: - *\li < 0 'rdata1' is less than 'rdata2' - *\li 0 'rdata1' is equal to 'rdata2' - *\li > 0 'rdata1' is greater than 'rdata2' - */ - -/*** - *** Conversions - ***/ - -void -dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_region_t *r); -/*%< - * Make 'rdata' refer to region 'r'. - * - * Requires: - * - *\li The data in 'r' is properly formatted for whatever type it is. - */ - -void -dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r); -/*%< - * Make 'r' refer to 'rdata'. - */ - -isc_result_t -dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_buffer_t *source, - dns_decompress_t *dctx, unsigned int options, - isc_buffer_t *target); -/*%< - * Copy the possibly-compressed rdata at source into the target region. - * - * Notes: - *\li Name decompression policy is controlled by 'dctx'. - * - * 'options' - *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied - * into target. - * - * Requires: - * - *\li 'rdclass' and 'type' are valid. - * - *\li 'source' is a valid buffer, and the active region of 'source' - * references the rdata to be processed. - * - *\li 'target' is a valid buffer. - * - *\li 'dctx' is a valid decompression context. - * - * Ensures, - * if result is success: - * \li If 'rdata' is not NULL, it is attached to the target. - * \li The conditions dns_name_fromwire() ensures for names hold - * for all names in the rdata. - * \li The current location in source is advanced, and the used space - * in target is updated. - * - * Result: - *\li Success - *\li Any non-success status from dns_name_fromwire() - *\li Various 'Bad Form' class failures depending on class and type - *\li Bad Form: Input too short - *\li Resource Limit: Not enough space - */ - -isc_result_t -dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, - isc_buffer_t *target); -/*%< - * Convert 'rdata' into wire format, compressing it as specified by the - * compression context 'cctx', and storing the result in 'target'. - * - * Notes: - *\li If the compression context allows global compression, then the - * global compression table may be updated. - * - * Requires: - *\li 'rdata' is a valid, non-empty rdata - * - *\li target is a valid buffer - * - *\li Any offsets specified in a global compression table are valid - * for target. - * - * Ensures, - * if the result is success: - * \li The used space in target is updated. - * - * Returns: - *\li Success - *\li Any non-success status from dns_name_towire() - *\li Resource Limit: Not enough space - */ - -isc_result_t -dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, - unsigned int options, isc_mem_t *mctx, - isc_buffer_t *target, dns_rdatacallbacks_t *callbacks); -/*%< - * Convert the textual representation of a DNS rdata into uncompressed wire - * form stored in the target region. Tokens constituting the text of the rdata - * are taken from 'lexer'. - * - * Notes: - *\li Relative domain names in the rdata will have 'origin' appended to them. - * A NULL origin implies "origin == dns_rootname". - * - * - * 'options' - *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied - * into target. - *\li DNS_RDATA_CHECKNAMES perform checknames checks. - *\li DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If - * not set a warning will be issued. - *\li DNS_RDATA_CHECKREVERSE this should set if the owner name ends - * in IP6.ARPA, IP6.INT or IN-ADDR.ARPA. - * - * Requires: - * - *\li 'rdclass' and 'type' are valid. - * - *\li 'lexer' is a valid isc_lex_t. - * - *\li 'mctx' is a valid isc_mem_t. - * - *\li 'target' is a valid region. - * - *\li 'origin' if non NULL it must be absolute. - * - *\li 'callbacks' to be NULL or callbacks->warn and callbacks->error be - * initialized. - * - * Ensures, - * if result is success: - *\li If 'rdata' is not NULL, it is attached to the target. - - *\li The conditions dns_name_fromtext() ensures for names hold - * for all names in the rdata. - - *\li The used space in target is updated. - * - * Result: - *\li Success - *\li Translated result codes from isc_lex_gettoken - *\li Various 'Bad Form' class failures depending on class and type - *\li Bad Form: Input too short - *\li Resource Limit: Not enough space - *\li Resource Limit: Not enough memory - */ - -isc_result_t -dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target); -/*%< - * Convert 'rdata' into text format, storing the result in 'target'. - * The text will consist of a single line, with fields separated by - * single spaces. - * - * Notes: - *\li If 'origin' is not NULL, then any names in the rdata that are - * subdomains of 'origin' will be made relative it. - * - *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no" - * at the moment. - * - * Requires: - * - *\li 'rdata' is a valid, non-empty rdata - * - *\li 'origin' is NULL, or is a valid name - * - *\li 'target' is a valid text buffer - * - * Ensures, - * if the result is success: - * - * \li The used space in target is updated. - * - * Returns: - *\li Success - *\li Any non-success status from dns_name_totext() - *\li Resource Limit: Not enough space - */ - -isc_result_t -dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, - unsigned int width, unsigned int split_width, - const char *linebreak, isc_buffer_t *target); -/*%< - * Like dns_rdata_totext, but do formatted output suitable for - * database dumps. This is intended for use by dns_db_dump(); - * library users are discouraged from calling it directly. - * - * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay - * within 'width' by breaking the text into multiple lines. - * The string 'linebreak' is inserted between lines, and parentheses - * are added when necessary. Because RRs contain unbreakable elements - * such as domain names whose length is variable, unpredictable, and - * potentially large, there is no guarantee that the lines will - * not exceed 'width' anyway. - * - * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always - * printed as a single line, and no parentheses are used. - * The 'width' and 'linebreak' arguments are ignored. - * - * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory - * comments next to things like the SOA timer fields. Some - * comments (e.g., the SOA ones) are only printed when multiline - * output is selected. - * - * base64 rdata text (e.g., DNSKEY records) will be split into chunks - * of 'split_width' characters. If split_width == 0, the text will - * not be split at all. If split_width == UINT_MAX (0xffffffff), then - * it is undefined and falls back to the default value of 'width' - */ - -isc_result_t -dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, void *source, isc_buffer_t *target); -/*%< - * Convert the C structure representation of an rdata into uncompressed wire - * format in 'target'. - * - * XXX Should we have a 'size' parameter as a sanity check on target? - * - * Requires: - * - *\li 'rdclass' and 'type' are valid. - * - *\li 'source' points to a valid C struct for the class and type. - * - *\li 'target' is a valid buffer. - * - *\li All structure pointers to memory blocks should be NULL if their - * corresponding length values are zero. - * - * Ensures, - * if result is success: - * \li If 'rdata' is not NULL, it is attached to the target. - * - * \li The used space in 'target' is updated. - * - * Result: - *\li Success - *\li Various 'Bad Form' class failures depending on class and type - *\li Resource Limit: Not enough space - */ - -isc_result_t -dns_rdata_tostruct(const dns_rdata_t *rdata, void *target, isc_mem_t *mctx); -/*%< - * Convert an rdata into its C structure representation. - * - * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used. - * - * If 'mctx' is non NULL then memory will be allocated if required. - * - * Requires: - * - *\li 'rdata' is a valid, non-empty rdata. - * - *\li 'target' to point to a valid pointer for the type and class. - * - * Result: - *\li Success - *\li Resource Limit: Not enough memory - */ - -void -dns_rdata_freestruct(void *source); -/*%< - * Free dynamic memory attached to 'source' (if any). - * - * Requires: - * - *\li 'source' to point to the structure previously filled in by - * dns_rdata_tostruct(). - */ - -bool -dns_rdatatype_ismeta(dns_rdatatype_t type); -/*%< - * Return true iff the rdata type 'type' is a meta-type - * like ANY or AXFR. - */ - -bool -dns_rdatatype_issingleton(dns_rdatatype_t type); -/*%< - * Return true iff the rdata type 'type' is a singleton type, - * like CNAME or SOA. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -bool -dns_rdataclass_ismeta(dns_rdataclass_t rdclass); -/*%< - * Return true iff the rdata class 'rdclass' is a meta-class - * like ANY or NONE. - */ - -bool -dns_rdatatype_isdnssec(dns_rdatatype_t type); -/*%< - * Return true iff 'type' is one of the DNSSEC - * rdata types that may exist alongside a CNAME record. - * - * Requires: - * \li 'type' is a valid rdata type. - */ - -bool -dns_rdatatype_iszonecutauth(dns_rdatatype_t type); -/*%< - * Return true iff rdata of type 'type' is considered authoritative - * data (not glue) in the NSEC chain when it occurs in the parent zone - * at a zone cut. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -bool -dns_rdatatype_isknown(dns_rdatatype_t type); -/*%< - * Return true iff the rdata type 'type' is known. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -isc_result_t -dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, - void *arg); -/*%< - * Call 'add' for each name and type from 'rdata' which is subject to - * additional section processing. - * - * Requires: - * - *\li 'rdata' is a valid, non-empty rdata. - * - *\li 'add' is a valid dns_additionalfunc_t. - * - * Ensures: - * - *\li If successful, then add() will have been called for each name - * and type subject to additional section processing. - * - *\li If add() returns something other than #ISC_R_SUCCESS, that result - * will be returned as the result of dns_rdata_additionaldata(). - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Many other results are possible if not successful. - */ - -isc_result_t -dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg); -/*%< - * Send 'rdata' in DNSSEC canonical form to 'digest'. - * - * Note: - *\li 'digest' may be called more than once by dns_rdata_digest(). The - * concatenation of all the regions, in the order they were given - * to 'digest', will be the DNSSEC canonical form of 'rdata'. - * - * Requires: - * - *\li 'rdata' is a valid, non-empty rdata. - * - *\li 'digest' is a valid dns_digestfunc_t. - * - * Ensures: - * - *\li If successful, then all of the rdata's data has been sent, in - * DNSSEC canonical form, to 'digest'. - * - *\li If digest() returns something other than ISC_R_SUCCESS, that result - * will be returned as the result of dns_rdata_digest(). - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Many other results are possible if not successful. - */ - -bool -dns_rdatatype_questiononly(dns_rdatatype_t type); -/*%< - * Return true iff rdata of type 'type' can only appear in the question - * section of a properly formatted message. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -bool -dns_rdatatype_notquestion(dns_rdatatype_t type); -/*%< - * Return true iff rdata of type 'type' can not appear in the question - * section of a properly formatted message. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -bool -dns_rdatatype_atparent(dns_rdatatype_t type); -/*%< - * Return true iff rdata of type 'type' should appear at the parent of - * a zone cut. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -bool -dns_rdatatype_atcname(dns_rdatatype_t type); -/*%< - * Return true iff rdata of type 'type' can appear beside a cname. - * - * Requires: - * \li 'type' is a valid rdata type. - * - */ - -unsigned int -dns_rdatatype_attributes(dns_rdatatype_t rdtype); -/*%< - * Return attributes for the given type. - * - * Requires: - *\li 'rdtype' are known. - * - * Returns: - *\li a bitmask consisting of the following flags. - */ - -/*% only one may exist for a name */ -#define DNS_RDATATYPEATTR_SINGLETON 0x00000001U -/*% requires no other data be present */ -#define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U -/*% Is a meta type */ -#define DNS_RDATATYPEATTR_META 0x00000004U -/*% Is a DNSSEC type, like RRSIG or NSEC */ -#define DNS_RDATATYPEATTR_DNSSEC 0x00000008U -/*% Is a zone cut authority type */ -#define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U -/*% Is reserved (unusable) */ -#define DNS_RDATATYPEATTR_RESERVED 0x00000020U -/*% Is an unknown type */ -#define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U -/*% Is META, and can only be in a question section */ -#define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U -/*% Is META, and can NOT be in a question section */ -#define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U -/*% Is present at zone cuts in the parent, not the child */ -#define DNS_RDATATYPEATTR_ATPARENT 0x00000200U -/*% Can exist along side a CNAME */ -#define DNS_RDATATYPEATTR_ATCNAME 0x00000400U - -dns_rdatatype_t -dns_rdata_covers(dns_rdata_t *rdata); -/*%< - * Return the rdatatype that this type covers. - * - * Requires: - *\li 'rdata' is a valid, non-empty rdata. - * - *\li 'rdata' is a type that covers other rdata types. - * - * Returns: - *\li The type covered. - */ - -bool -dns_rdata_checkowner(dns_name_t* name, dns_rdataclass_t rdclass, - dns_rdatatype_t type, bool wildcard); -/* - * Returns whether this is a valid ownername for this . - * If wildcard is true allow the first label to be a wildcard if - * appropriate. - * - * Requires: - * 'name' is a valid name. - */ - -bool -dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad); -/* - * Returns whether 'rdata' contains valid domain names. The checks are - * sensitive to the owner name. - * - * If 'bad' is non-NULL and a domain name fails the check the - * the offending name will be return in 'bad' by cloning from - * the 'rdata' contents. - * - * Requires: - * 'rdata' to be valid. - * 'owner' to be valid. - * 'bad' to be NULL or valid. - */ - -void -dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type); - -void -dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type); - -void -dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type); - -void -dns_rdata_makedelete(dns_rdata_t *rdata); - -const char * -dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATA_H */ diff --git a/lib/dns-pkcs11/include/dns/rdataclass.h b/lib/dns-pkcs11/include/dns/rdataclass.h deleted file mode 100644 index cc481cd..0000000 --- a/lib/dns-pkcs11/include/dns/rdataclass.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATACLASS_H -#define DNS_RDATACLASS_H 1 - -/*! \file dns/rdataclass.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNS class. - * - * Requires: - *\li 'classp' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #DNS_R_UNKNOWN class is unknown - */ - -isc_result_t -dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target); -/*%< - * Put a textual representation of class 'rdclass' into 'target'. - * - * Requires: - *\li 'rdclass' is a valid class. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -isc_result_t -dns_rdataclass_tounknowntext(dns_rdataclass_t rdclass, isc_buffer_t *target); -/*%< - * Put textual RFC3597 CLASSXXXX representation of class 'rdclass' into - * 'target'. - * - * Requires: - *\li 'rdclass' is a valid class. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -void -dns_rdataclass_format(dns_rdataclass_t rdclass, - char *array, unsigned int size); -/*%< - * Format a human-readable representation of the class 'rdclass' - * into the character array 'array', which is of size 'size'. - * The resulting string is guaranteed to be null-terminated. - */ - -#define DNS_RDATACLASS_FORMATSIZE sizeof("CLASS65535") -/*%< - * Minimum size of array to pass to dns_rdataclass_format(). - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATACLASS_H */ diff --git a/lib/dns-pkcs11/include/dns/rdatalist.h b/lib/dns-pkcs11/include/dns/rdatalist.h deleted file mode 100644 index de34a1c..0000000 --- a/lib/dns-pkcs11/include/dns/rdatalist.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATALIST_H -#define DNS_RDATALIST_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/rdatalist.h - * \brief - * A DNS rdatalist is a list of rdata of a common type and class. - * - * MP: - *\li Clients of this module must impose any required synchronization. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -#include - -#include - -/*% - * Clients may use this type directly. - */ -struct dns_rdatalist { - dns_rdataclass_t rdclass; - dns_rdatatype_t type; - dns_rdatatype_t covers; - dns_ttl_t ttl; - ISC_LIST(dns_rdata_t) rdata; - ISC_LINK(dns_rdatalist_t) link; - /*%< - * Case vector. If the bit is set then the corresponding - * character in the owner name needs to be AND'd with 0x20, - * rendering that character upper case. - */ - unsigned char upper[32]; -}; - -ISC_LANG_BEGINDECLS - -void -dns_rdatalist_init(dns_rdatalist_t *rdatalist); -/*%< - * Initialize rdatalist. - * - * Ensures: - *\li All fields of rdatalist have been initialized to their default - * values. - */ - -isc_result_t -dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, - dns_rdataset_t *rdataset); -/*%< - * Make 'rdataset' refer to the rdata in 'rdatalist'. - * - * Note: - *\li The caller must ensure that 'rdatalist' remains valid and unchanged - * while 'rdataset' is associated with it. - * - * Requires: - * - *\li 'rdatalist' is a valid rdatalist. - * - *\li 'rdataset' is a valid rdataset that is not currently associated with - * any rdata. - * - * Ensures, - * on success, - * - *\li 'rdataset' is associated with the rdata in rdatalist. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_result_t -dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset, - dns_rdatalist_t **rdatalist); -/*%< - * Point 'rdatalist' to the rdatalist in 'rdataset'. - * - * Requires: - * - *\li 'rdatalist' is a pointer to a NULL dns_rdatalist_t pointer. - * - *\li 'rdataset' is a valid rdataset associated with an rdatalist. - * - * Ensures, - * on success, - * - *\li 'rdatalist' is pointed to the rdatalist in rdataset. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATALIST_H */ diff --git a/lib/dns-pkcs11/include/dns/rdataset.h b/lib/dns-pkcs11/include/dns/rdataset.h deleted file mode 100644 index 710e97c..0000000 --- a/lib/dns-pkcs11/include/dns/rdataset.h +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RDATASET_H -#define DNS_RDATASET_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/rdataset.h - * \brief - * A DNS rdataset is a handle that can be associated with a collection of - * rdata all having a common owner name, class, and type. - * - * The dns_rdataset_t type is like a "virtual class". To actually use - * rdatasets, an implementation of the method suite (e.g. "slabbed rdata") is - * required. - * - * XXX <more> XXX - * - * MP: - *\li Clients of this module must impose any required synchronization. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -#include -#include - -#include -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -typedef enum { - dns_rdatasetadditional_fromauth, - dns_rdatasetadditional_fromcache, - dns_rdatasetadditional_fromglue -} dns_rdatasetadditional_t; - -typedef struct dns_rdatasetmethods { - void (*disassociate)(dns_rdataset_t *rdataset); - isc_result_t (*first)(dns_rdataset_t *rdataset); - isc_result_t (*next)(dns_rdataset_t *rdataset); - void (*current)(dns_rdataset_t *rdataset, - dns_rdata_t *rdata); - void (*clone)(dns_rdataset_t *source, - dns_rdataset_t *target); - unsigned int (*count)(dns_rdataset_t *rdataset); - isc_result_t (*addnoqname)(dns_rdataset_t *rdataset, - dns_name_t *name); - isc_result_t (*getnoqname)(dns_rdataset_t *rdataset, - dns_name_t *name, - dns_rdataset_t *neg, - dns_rdataset_t *negsig); - isc_result_t (*addclosest)(dns_rdataset_t *rdataset, - dns_name_t *name); - isc_result_t (*getclosest)(dns_rdataset_t *rdataset, - dns_name_t *name, - dns_rdataset_t *neg, - dns_rdataset_t *negsig); - isc_result_t (*getadditional)(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t **zonep, - dns_db_t **dbp, - dns_dbversion_t **versionp, - dns_dbnode_t **nodep, - dns_name_t *fname, - dns_message_t *msg, - isc_stdtime_t now); - isc_result_t (*setadditional)(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t *zone, - dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, - dns_name_t *fname); - isc_result_t (*putadditional)(dns_acache_t *acache, - dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype); - void (*settrust)(dns_rdataset_t *rdataset, - dns_trust_t trust); - void (*expire)(dns_rdataset_t *rdataset); - void (*clearprefetch)(dns_rdataset_t *rdataset); - void (*setownercase)(dns_rdataset_t *rdataset, - const dns_name_t *name); - void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name); -} dns_rdatasetmethods_t; - -#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') -#define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC) - -/*% - * Direct use of this structure by clients is strongly discouraged, except - * for the 'link' field which may be used however the client wishes. The - * 'private', 'current', and 'index' fields MUST NOT be changed by clients. - * rdataset implementations may change any of the fields. - */ -struct dns_rdataset { - unsigned int magic; /* XXX ? */ - dns_rdatasetmethods_t * methods; - ISC_LINK(dns_rdataset_t) link; - - /* - * XXX do we need these, or should they be retrieved by methods? - * Leaning towards the latter, since they are not frequently required - * once you have the rdataset. - */ - dns_rdataclass_t rdclass; - dns_rdatatype_t type; - dns_ttl_t ttl; - /* - * Stale ttl is used to see how long this RRset can still be used - * to serve to clients, after the TTL has expired. - */ - dns_ttl_t stale_ttl; - dns_trust_t trust; - dns_rdatatype_t covers; - - /* - * attributes - */ - unsigned int attributes; - - /*% - * the counter provides the starting point in the "cyclic" order. - * The value UINT32_MAX has a special meaning of "picking up a - * random value." in order to take care of databases that do not - * increment the counter. - */ - uint32_t count; - - /* - * This RRSIG RRset should be re-generated around this time. - * Only valid if DNS_RDATASETATTR_RESIGN is set in attributes. - */ - isc_stdtime_t resign; - - /*@{*/ - /*% - * These are for use by the rdataset implementation, and MUST NOT - * be changed by clients. - */ - void * private1; - void * private2; - void * private3; - unsigned int privateuint4; - void * private5; - void * private6; - void * private7; - /*@}*/ - -}; - -/*! - * \def DNS_RDATASETATTR_RENDERED - * Used by message.c to indicate that the rdataset was rendered. - * - * \def DNS_RDATASETATTR_TTLADJUSTED - * Used by message.c to indicate that the rdataset's rdata had differing - * TTL values, and the rdataset->ttl holds the smallest. - * - * \def DNS_RDATASETATTR_LOADORDER - * Output the RRset in load order. - */ - -#define DNS_RDATASETATTR_QUESTION 0x00000001 -#define DNS_RDATASETATTR_RENDERED 0x00000002 /*%< Used by message.c */ -#define DNS_RDATASETATTR_ANSWERED 0x00000004 /*%< Used by server. */ -#define DNS_RDATASETATTR_CACHE 0x00000008 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_ANSWER 0x00000010 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_EXTERNAL 0x00000040 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_NCACHE 0x00000080 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_CHAINING 0x00000100 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /*%< Used by message.c */ -#define DNS_RDATASETATTR_FIXEDORDER 0x00000400 -#define DNS_RDATASETATTR_RANDOMIZE 0x00000800 -#define DNS_RDATASETATTR_CHASE 0x00001000 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_NXDOMAIN 0x00002000 -#define DNS_RDATASETATTR_NOQNAME 0x00004000 -#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_REQUIRED 0x00010000 -#define DNS_RDATASETATTR_REQUIREDGLUE DNS_RDATASETATTR_REQUIRED -#define DNS_RDATASETATTR_LOADORDER 0x00020000 -#define DNS_RDATASETATTR_RESIGN 0x00040000 -#define DNS_RDATASETATTR_CLOSEST 0x00080000 -#define DNS_RDATASETATTR_OPTOUT 0x00100000 /*%< OPTOUT proof */ -#define DNS_RDATASETATTR_NEGATIVE 0x00200000 -#define DNS_RDATASETATTR_PREFETCH 0x00400000 -#define DNS_RDATASETATTR_STALE 0x01000000 - -/*% - * _OMITDNSSEC: - * Omit DNSSEC records when rendering ncache records. - */ -#define DNS_RDATASETTOWIRE_OMITDNSSEC 0x0001 - -void -dns_rdataset_init(dns_rdataset_t *rdataset); -/*%< - * Make 'rdataset' a valid, disassociated rdataset. - * - * Requires: - *\li 'rdataset' is not NULL. - * - * Ensures: - *\li 'rdataset' is a valid, disassociated rdataset. - */ - -void -dns_rdataset_invalidate(dns_rdataset_t *rdataset); -/*%< - * Invalidate 'rdataset'. - * - * Requires: - *\li 'rdataset' is a valid, disassociated rdataset. - * - * Ensures: - *\li If assertion checking is enabled, future attempts to use 'rdataset' - * without initializing it will cause an assertion failure. - */ - -void -dns_rdataset_disassociate(dns_rdataset_t *rdataset); -/*%< - * Disassociate 'rdataset' from its rdata, allowing it to be reused. - * - * Notes: - *\li The client must ensure it has no references to rdata in the rdataset - * before disassociating. - * - * Requires: - *\li 'rdataset' is a valid, associated rdataset. - * - * Ensures: - *\li 'rdataset' is a valid, disassociated rdataset. - */ - -bool -dns_rdataset_isassociated(dns_rdataset_t *rdataset); -/*%< - * Is 'rdataset' associated? - * - * Requires: - *\li 'rdataset' is a valid rdataset. - * - * Returns: - *\li #true 'rdataset' is associated. - *\li #false 'rdataset' is not associated. - */ - -void -dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass, - dns_rdatatype_t type); -/*%< - * Make 'rdataset' a valid, associated, question rdataset, with a - * question class of 'rdclass' and type 'type'. - * - * Notes: - *\li Question rdatasets have a class and type, but no rdata. - * - * Requires: - *\li 'rdataset' is a valid, disassociated rdataset. - * - * Ensures: - *\li 'rdataset' is a valid, associated, question rdataset. - */ - -void -dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); -/*%< - * Make 'target' refer to the same rdataset as 'source'. - * - * Requires: - *\li 'source' is a valid, associated rdataset. - * - *\li 'target' is a valid, dissociated rdataset. - * - * Ensures: - *\li 'target' references the same rdataset as 'source'. - */ - -unsigned int -dns_rdataset_count(dns_rdataset_t *rdataset); -/*%< - * Return the number of records in 'rdataset'. - * - * Requires: - *\li 'rdataset' is a valid, associated rdataset. - * - * Returns: - *\li The number of records in 'rdataset'. - */ - -isc_result_t -dns_rdataset_first(dns_rdataset_t *rdataset); -/*%< - * Move the rdata cursor to the first rdata in the rdataset (if any). - * - * Requires: - *\li 'rdataset' is a valid, associated rdataset. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no rdata in the set. - */ - -isc_result_t -dns_rdataset_next(dns_rdataset_t *rdataset); -/*%< - * Move the rdata cursor to the next rdata in the rdataset (if any). - * - * Requires: - *\li 'rdataset' is a valid, associated rdataset. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no more rdata in the set. - */ - -void -dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); -/*%< - * Make 'rdata' refer to the current rdata. - * - * Notes: - * - *\li The data returned in 'rdata' is valid for the life of the - * rdataset; in particular, subsequent changes in the cursor position - * do not invalidate 'rdata'. - * - * Requires: - *\li 'rdataset' is a valid, associated rdataset. - * - *\li The rdata cursor of 'rdataset' is at a valid location (i.e. the - * result of last call to a cursor movement command was ISC_R_SUCCESS). - * - * Ensures: - *\li 'rdata' refers to the rdata at the rdata cursor location of - *\li 'rdataset'. - */ - -isc_result_t -dns_rdataset_totext(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - bool omit_final_dot, - bool question, - isc_buffer_t *target); -/*%< - * Convert 'rdataset' to text format, storing the result in 'target'. - * - * Notes: - *\li The rdata cursor position will be changed. - * - *\li The 'question' flag should normally be #false. If it is - * #true, the TTL and rdata fields are not printed. This is - * for use when printing an rdata representing a question section. - * - *\li This interface is deprecated; use dns_master_rdatasettottext() - * and/or dns_master_questiontotext() instead. - * - * Requires: - *\li 'rdataset' is a valid rdataset. - * - *\li 'rdataset' is not empty. - */ - -isc_result_t -dns_rdataset_towire(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - unsigned int options, - unsigned int *countp); -/*%< - * Convert 'rdataset' to wire format, compressing names as specified - * in 'cctx', and storing the result in 'target'. - * - * Notes: - *\li The rdata cursor position will be changed. - * - *\li The number of RRs added to target will be added to *countp. - * - * Requires: - *\li 'rdataset' is a valid rdataset. - * - *\li 'rdataset' is not empty. - * - *\li 'countp' is a valid pointer. - * - * Ensures: - *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format - * for the data contained in 'rdataset'. Any error return leaves - * the buffer unchanged. - * - *\li *countp has been incremented by the number of RRs added to - * target. - * - * Returns: - *\li #ISC_R_SUCCESS - all ok - *\li #ISC_R_NOSPACE - 'target' doesn't have enough room - * - *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), - * dns_name_towire(). - */ - -isc_result_t -dns_rdataset_towiresorted(dns_rdataset_t *rdataset, - const dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - dns_rdatasetorderfunc_t order, - const void *order_arg, - unsigned int options, - unsigned int *countp); -/*%< - * Like dns_rdataset_towire(), but sorting the rdatasets according to - * the integer value returned by 'order' when called with the rdataset - * and 'order_arg' as arguments. - * - * Requires: - *\li All the requirements of dns_rdataset_towire(), and - * that order_arg is NULL if and only if order is NULL. - */ - -isc_result_t -dns_rdataset_towirepartial(dns_rdataset_t *rdataset, - const dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - dns_rdatasetorderfunc_t order, - const void *order_arg, - unsigned int options, - unsigned int *countp, - void **state); -/*%< - * Like dns_rdataset_towiresorted() except that a partial rdataset - * may be written. - * - * Requires: - *\li All the requirements of dns_rdataset_towiresorted(). - * If 'state' is non NULL then the current position in the - * rdataset will be remembered if the rdataset in not - * completely written and should be passed on on subsequent - * calls (NOT CURRENTLY IMPLEMENTED). - * - * Returns: - *\li #ISC_R_SUCCESS if all of the records were written. - *\li #ISC_R_NOSPACE if unable to fit in all of the records. *countp - * will be updated to reflect the number of records - * written. - */ - -isc_result_t -dns_rdataset_additionaldata(dns_rdataset_t *rdataset, - dns_additionaldatafunc_t add, void *arg); -/*%< - * For each rdata in rdataset, call 'add' for each name and type in the - * rdata which is subject to additional section processing. - * - * Requires: - * - *\li 'rdataset' is a valid, non-question rdataset. - * - *\li 'add' is a valid dns_additionaldatafunc_t - * - * Ensures: - * - *\li If successful, dns_rdata_additionaldata() will have been called for - * each rdata in 'rdataset'. - * - *\li If a call to dns_rdata_additionaldata() is not successful, the - * result returned will be the result of dns_rdataset_additionaldata(). - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Any error that dns_rdata_additionaldata() can return. - */ - -isc_result_t -dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig); -/*%< - * Return the noqname proof for this record. - * - * Requires: - *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. - *\li 'name' to be valid. - *\li 'neg' and 'negsig' to be valid and not associated. - */ - -isc_result_t -dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name); -/*%< - * Associate a noqname proof with this record. - * Sets #DNS_RDATASETATTR_NOQNAME if successful. - * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and - * the 'nsec'/'nsec3' and 'rrsig(nsec)'/'rrsig(nsec3)' ttl. - * - * Requires: - *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. - *\li 'name' to be valid and have NSEC or NSEC3 and associated RRSIG - * rdatasets. - */ - -isc_result_t -dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *nsec, dns_rdataset_t *nsecsig); -/*%< - * Return the closest encloser for this record. - * - * Requires: - *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set. - *\li 'name' to be valid. - *\li 'nsec' and 'nsecsig' to be valid and not associated. - */ - -isc_result_t -dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name); -/*%< - * Associate a closest encloset proof with this record. - * Sets #DNS_RDATASETATTR_CLOSEST if successful. - * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and - * the 'nsec' and 'rrsig(nsec)' ttl. - * - * Requires: - *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set. - *\li 'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets. - */ - -isc_result_t -dns_rdataset_getadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t **zonep, - dns_db_t **dbp, - dns_dbversion_t **versionp, - dns_dbnode_t **nodep, - dns_name_t *fname, - dns_message_t *msg, - isc_stdtime_t now); -/*%< - * Get cached additional information from the DB node for a particular - * 'rdataset.' 'type' is one of dns_rdatasetadditional_fromauth, - * dns_rdatasetadditional_fromcache, and dns_rdatasetadditional_fromglue, - * which specifies the origin of the information. 'qtype' is intended to - * be used for specifying a particular rdata type in the cached information. - * - * Requires: - * \li 'rdataset' is a valid rdataset. - * \li 'acache' can be NULL, in which case this function will simply return - * ISC_R_FAILURE. - * \li For the other pointers, see dns_acache_getentry(). - * - * Ensures: - * \li See dns_acache_getentry(). - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_FAILURE - additional information caching is not supported. - * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional - * information for 'rdataset.' - * \li Any error that dns_acache_getentry() can return. - */ - -isc_result_t -dns_rdataset_setadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t *zone, - dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, - dns_name_t *fname); -/*%< - * Set cached additional information to the DB node for a particular - * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' - * and 'qtype'. - * - * Requires: - * \li 'rdataset' is a valid rdataset. - * \li 'acache' can be NULL, in which case this function will simply return - * ISC_R_FAILURE. - * \li For the other pointers, see dns_acache_setentry(). - * - * Ensures: - * \li See dns_acache_setentry(). - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_FAILURE - additional information caching is not supported. - * \li #ISC_R_NOMEMORY - * \li Any error that dns_acache_setentry() can return. - */ - -isc_result_t -dns_rdataset_putadditional(dns_acache_t *acache, - dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype); -/*%< - * Discard cached additional information stored in the DB node for a particular - * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' - * and 'qtype'. - * - * Requires: - * \li 'rdataset' is a valid rdataset. - * \li 'acache' can be NULL, in which case this function will simply return - * ISC_R_FAILURE. - * - * Ensures: - * \li See dns_acache_cancelentry(). - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_FAILURE - additional information caching is not supported. - * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional - * information for 'rdataset.' - */ - -void -dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); -/*%< - * Set the trust of the 'rdataset' to trust in any in the backing database. - * The local trust level of 'rdataset' is also set. - */ - -void -dns_rdataset_expire(dns_rdataset_t *rdataset); -/*%< - * Mark the rdataset to be expired in the backing database. - */ - -void -dns_rdataset_clearprefetch(dns_rdataset_t *rdataset); -/*%< - * Clear the PREFETCH attribute for the given rdataset in the - * underlying database. - * - * In the cache database, this signals that the rdataset is not - * eligible to be prefetched when the TTL is close to expiring. - * It has no function in other databases. - */ - -void -dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name); -/*%< - * Store the casing of 'name', the owner name of 'rdataset', into - * a bitfield so that the name can be capitalized the same when when - * the rdataset is used later. This sets the CASESET attribute. - */ - -void -dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name); -/*%< - * If the CASESET attribute is set, retrieve the case bitfield that was - * previously stored by dns_rdataset_getownername(), and capitalize 'name' - * according to it. If CASESET is not set, do nothing. - */ - -void -dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, - bool acceptexpired); -/*%< - * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire - * at or before 'rrsig->expiretime'. If 'acceptexpired' is true and the - * signature has expired or will expire in the next 120 seconds, limit - * the ttl to be no more than 120 seconds. - * - * The ttl is further limited by the original ttl as stored in 'rrsig' - * and the original ttl values of 'rdataset' and 'sigrdataset'. - * - * Requires: - * \li 'rdataset' is a valid rdataset. - * \li 'sigrdataset' is a valid rdataset. - * \li 'rrsig' is non NULL. - */ - -const char * -dns_trust_totext(dns_trust_t trust); -/*%< - * Display trust in textual form. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATASET_H */ diff --git a/lib/dns-pkcs11/include/dns/rdatasetiter.h b/lib/dns-pkcs11/include/dns/rdatasetiter.h deleted file mode 100644 index 15857f6..0000000 --- a/lib/dns-pkcs11/include/dns/rdatasetiter.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATASETITER_H -#define DNS_RDATASETITER_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/rdatasetiter.h - * \brief - * The DNS Rdataset Iterator interface allows iteration of all of the - * rdatasets at a node. - * - * The dns_rdatasetiter_t type is like a "virtual class". To actually use - * it, an implementation of the class is required. This implementation is - * supplied by the database. - * - * It is the client's responsibility to call dns_rdataset_disassociate() - * on all rdatasets returned. - * - * XXX more XXX - * - * MP: - *\li The iterator itself is not locked. The caller must ensure - * synchronization. - * - *\li The iterator methods ensure appropriate database locking. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -/***** - ***** Imports - *****/ - -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Types - *****/ - -typedef struct dns_rdatasetitermethods { - void (*destroy)(dns_rdatasetiter_t **iteratorp); - isc_result_t (*first)(dns_rdatasetiter_t *iterator); - isc_result_t (*next)(dns_rdatasetiter_t *iterator); - void (*current)(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset); -} dns_rdatasetitermethods_t; - -#define DNS_RDATASETITER_MAGIC ISC_MAGIC('D','N','S','i') -#define DNS_RDATASETITER_VALID(i) ISC_MAGIC_VALID(i, DNS_RDATASETITER_MAGIC) - -/*% - * This structure is actually just the common prefix of a DNS db - * implementation's version of a dns_rdatasetiter_t. - * \brief - * Direct use of this structure by clients is forbidden. DB implementations - * may change the structure. 'magic' must be #DNS_RDATASETITER_MAGIC for - * any of the dns_rdatasetiter routines to work. DB implementations must - * maintain all DB rdataset iterator invariants. - */ -struct dns_rdatasetiter { - /* Unlocked. */ - unsigned int magic; - dns_rdatasetitermethods_t * methods; - dns_db_t * db; - dns_dbnode_t * node; - dns_dbversion_t * version; - isc_stdtime_t now; -}; - -void -dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); -/*%< - * Destroy '*iteratorp'. - * - * Requires: - * - *\li '*iteratorp' is a valid iterator. - * - * Ensures: - * - *\li All resources used by the iterator are freed. - * - *\li *iteratorp == NULL. - */ - -isc_result_t -dns_rdatasetiter_first(dns_rdatasetiter_t *iterator); -/*%< - * Move the rdataset cursor to the first rdataset at the node (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMORE There are no rdatasets at the node. - * - *\li Other results are possible, depending on the DB implementation. - */ - -isc_result_t -dns_rdatasetiter_next(dns_rdatasetiter_t *iterator); -/*%< - * Move the rdataset cursor to the next rdataset at the node (if any). - * - * Requires: - *\li 'iterator' is a valid iterator. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMORE There are no more rdatasets at the - * node. - * - *\li Other results are possible, depending on the DB implementation. - */ - -void -dns_rdatasetiter_current(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset); -/*%< - * Return the current rdataset. - * - * Requires: - *\li 'iterator' is a valid iterator. - * - *\li 'rdataset' is a valid, disassociated rdataset. - * - *\li The rdataset cursor of 'iterator' is at a valid location (i.e. the - * result of last call to a cursor movement command was #ISC_R_SUCCESS). - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATASETITER_H */ diff --git a/lib/dns-pkcs11/include/dns/rdataslab.h b/lib/dns-pkcs11/include/dns/rdataslab.h deleted file mode 100644 index f38d539..0000000 --- a/lib/dns-pkcs11/include/dns/rdataslab.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATASLAB_H -#define DNS_RDATASLAB_H 1 - -/*! \file dns/rdataslab.h - * \brief - * Implements storage of rdatasets into slabs of memory. - * - * MP: - *\li Clients of this module must impose any required synchronization. - * - * Reliability: - *\li This module deals with low-level byte streams. Errors in any of - * the functions are likely to crash the server or corrupt memory. - * - *\li If the caller passes invalid memory references, these functions are - * likely to crash the server or corrupt memory. - * - * Resources: - *\li None. - * - * Security: - *\li None. - * - * Standards: - *\li None. - */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include - -ISC_LANG_BEGINDECLS - -#define DNS_RDATASLAB_FORCE 0x1 -#define DNS_RDATASLAB_EXACT 0x2 - -#define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */ -#define DNS_RDATASLAB_WARNMASK 0x0E /*%< RRSIG(DNSKEY) expired - * warnings number mask. */ -#define DNS_RDATASLAB_WARNSHIFT 1 /*%< How many bits to shift to find - * remaining expired warning number. */ - - -/*** - *** Functions - ***/ - -isc_result_t -dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, - isc_region_t *region, unsigned int reservelen); -/*%< - * Slabify a rdataset. The slab area will be allocated and returned - * in 'region'. - * - * Requires: - *\li 'rdataset' is valid. - * - * Ensures: - *\li 'region' will have base pointing to the start of allocated memory, - * with the slabified region beginning at region->base + reservelen. - * region->length contains the total length allocated. - * - * Returns: - *\li ISC_R_SUCCESS - successful completion - *\li ISC_R_NOMEMORY - no memory. - *\li XXX others - */ - -void -dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, - dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, - dns_rdatatype_t covers, dns_ttl_t ttl, - dns_rdataset_t *rdataset); -/*%< - * Construct an rdataset from a slab. - * - * Requires: - *\li 'slab' points to a slab. - *\li 'rdataset' is disassociated. - * - * Ensures: - *\li 'rdataset' is associated and points to a valid rdataest. - */ - -unsigned int -dns_rdataslab_size(unsigned char *slab, unsigned int reservelen); -/*%< - * Return the total size of an rdataslab. - * - * Requires: - *\li 'slab' points to a slab. - * - * Returns: - *\li The number of bytes in the slab, including the reservelen. - */ - -unsigned int -dns_rdataslab_count(unsigned char *slab, unsigned int reservelen); -/*%< - * Return the number of records in the rdataslab - * - * Requires: - *\li 'slab' points to a slab. - * - * Returns: - *\li The number of records in the slab. - */ - -isc_result_t -dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, - unsigned int reservelen, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int flags, unsigned char **tslabp); -/*%< - * Merge 'oslab' and 'nslab'. - */ - -isc_result_t -dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, - unsigned int reservelen, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int flags, unsigned char **tslabp); -/*%< - * Subtract 'sslab' from 'mslab'. If 'exact' is true then all elements - * of 'sslab' must exist in 'mslab'. - * - * XXX - * valid flags are DNS_RDATASLAB_EXACT - */ - -bool -dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen); -/*%< - * Compare two rdataslabs for equality. This does _not_ do a full - * DNSSEC comparison. - * - * Requires: - *\li 'slab1' and 'slab2' point to slabs. - * - * Returns: - *\li true if the slabs are equal, false otherwise. - */ -bool -dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen, dns_rdataclass_t rdclass, - dns_rdatatype_t type); -/*%< - * Compare two rdataslabs for DNSSEC equality. - * - * Requires: - *\li 'slab1' and 'slab2' point to slabs. - * - * Returns: - *\li true if the slabs are equal, #false otherwise. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATASLAB_H */ diff --git a/lib/dns-pkcs11/include/dns/rdatatype.h b/lib/dns-pkcs11/include/dns/rdatatype.h deleted file mode 100644 index 398ed97..0000000 --- a/lib/dns-pkcs11/include/dns/rdatatype.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATATYPE_H -#define DNS_RDATATYPE_H 1 - -/*! \file dns/rdatatype.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNS rdata type. - * - * Requires: - *\li 'typep' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li DNS_R_UNKNOWN type is unknown - */ - -isc_result_t -dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target); -/*%< - * Put a textual representation of type 'type' into 'target'. - * - * Requires: - *\li 'type' is a valid type. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -isc_result_t -dns_rdatatype_tounknowntext(dns_rdatatype_t type, isc_buffer_t *target); -/*%< - * Put textual RFC3597 TYPEXXXX representation of type 'type' into - * 'target'. - * - * Requires: - *\li 'type' is a valid type. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li #ISC_R_SUCCESS on success - *\li #ISC_R_NOSPACE target buffer is too small - */ - -void -dns_rdatatype_format(dns_rdatatype_t rdtype, - char *array, unsigned int size); -/*%< - * Format a human-readable representation of the type 'rdtype' - * into the character array 'array', which is of size 'size'. - * The resulting string is guaranteed to be null-terminated. - */ - -#define DNS_RDATATYPE_FORMATSIZE sizeof("NSEC3PARAM") - -/*%< - * Minimum size of array to pass to dns_rdatatype_format(). - * May need to be adjusted if a new RR type with a very long - * name is defined. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATATYPE_H */ diff --git a/lib/dns-pkcs11/include/dns/request.h b/lib/dns-pkcs11/include/dns/request.h deleted file mode 100644 index cb4b95b..0000000 --- a/lib/dns-pkcs11/include/dns/request.h +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_REQUEST_H -#define DNS_REQUEST_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/request.h - * - * \brief - * The request module provides simple request/response services useful for - * sending SOA queries, DNS Notify messages, and dynamic update requests. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - */ - -#include -#include -#include - -#include - -#define DNS_REQUESTOPT_TCP 0x00000001U -#define DNS_REQUESTOPT_CASE 0x00000002U -#define DNS_REQUESTOPT_FIXEDID 0x00000004U -#define DNS_REQUESTOPT_SHARE 0x00000008U - -typedef struct dns_requestevent { - ISC_EVENT_COMMON(struct dns_requestevent); - isc_result_t result; - dns_request_t *request; -} dns_requestevent_t; - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, - isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, - dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, - dns_requestmgr_t **requestmgrp); -/*%< - * Create a request manager. - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li 'timermgr' is a valid timer manager. - * - *\li 'socketmgr' is a valid socket manager. - * - *\li 'taskmgr' is a valid task manager. - * - *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. - * - *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. - * - *\li requestmgrp != NULL && *requestmgrp == NULL - * - * Ensures: - * - *\li On success, *requestmgrp is a valid request manager. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any other result indicates failure. - */ - -void -dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, - isc_event_t **eventp); -/*%< - * Send '*eventp' to 'task' when 'requestmgr' has completed shutdown. - * - * Notes: - * - *\li It is not safe to detach the last reference to 'requestmgr' until - * shutdown is complete. - * - * Requires: - * - *\li 'requestmgr' is a valid request manager. - * - *\li 'task' is a valid task. - * - *\li *eventp is a valid event. - * - * Ensures: - * - *\li *eventp == NULL. - */ - -void -dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr); -/*%< - * Start the shutdown process for 'requestmgr'. - * - * Notes: - * - *\li This call has no effect if the request manager is already shutting - * down. - * - * Requires: - * - *\li 'requestmgr' is a valid requestmgr. - */ - -void -dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp); -/*%< - * Attach to the request manager. dns_requestmgr_shutdown() must not - * have been called on 'source' prior to calling dns_requestmgr_attach(). - * - * Requires: - * - *\li 'source' is a valid requestmgr. - * - *\li 'targetp' to be non NULL and '*targetp' to be NULL. - */ - -void -dns_requestmgr_detach(dns_requestmgr_t **requestmgrp); -/*%< - * Detach from the given requestmgr. If this is the final detach - * requestmgr will be destroyed. dns_requestmgr_shutdown() must - * be called before the final detach. - * - * Requires: - * - *\li '*requestmgrp' is a valid requestmgr. - * - * Ensures: - *\li '*requestmgrp' is NULL. - */ - -isc_result_t -dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *address, unsigned int options, - dns_tsigkey_t *key, - unsigned int timeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp); -/*%< - * Create and send a request. - * - * Notes: - * - *\li 'message' will be rendered and sent to 'address'. If the - * #DNS_REQUESTOPT_TCP option is set, TCP will be used, - * #DNS_REQUESTOPT_SHARE option is set too, connecting TCP - * (vs. connected) will be shared too. The request - * will timeout after 'timeout' seconds. - * - *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive - * compression. - * - *\li When the request completes, successfully, due to a timeout, or - * because it was canceled, a completion event will be sent to 'task'. - * - * Requires: - * - *\li 'message' is a valid DNS message. - * - *\li 'address' is a valid sockaddr. - * - *\li 'timeout' > 0 - * - *\li 'task' is a valid task. - * - *\li requestp != NULL && *requestp == NULL - */ - -/*% See dns_request_createvia4() */ -isc_result_t -dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -/*% See dns_request_createvia4() */ -isc_result_t -dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, unsigned int udptimeout, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -/*% See dns_request_createvia4() */ -isc_result_t -dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, unsigned int udptimeout, - unsigned int udpretries, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -isc_result_t -dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - isc_dscp_t dscp, unsigned int options, - dns_tsigkey_t *key, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp); -/*%< - * Create and send a request. - * - * Notes: - * - *\li 'message' will be rendered and sent to 'address'. If the - * #DNS_REQUESTOPT_TCP option is set, TCP will be used, - * #DNS_REQUESTOPT_SHARE option is set too, connecting TCP - * (vs. connected) will be shared too. The request - * will timeout after 'timeout' seconds. UDP requests will be resent - * at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero. - * - *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive - * compression. - * - *\li When the request completes, successfully, due to a timeout, or - * because it was canceled, a completion event will be sent to 'task'. - * - * Requires: - * - *\li 'message' is a valid DNS message. - * - *\li 'dstaddr' is a valid sockaddr. - * - *\li 'srcaddr' is a valid sockaddr or NULL. - * - *\li 'srcaddr' and 'dstaddr' are the same protocol family. - * - *\li 'timeout' > 0 - * - *\li 'task' is a valid task. - * - *\li requestp != NULL && *requestp == NULL - */ - -/*% See dns_request_createraw4() */ -isc_result_t -dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -/*% See dns_request_createraw4() */ -isc_result_t -dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - unsigned int udptimeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -/*% See dns_request_createraw4() */ -isc_result_t -dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp); - -isc_result_t -dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - isc_dscp_t dscp, unsigned int options, - unsigned int timeout, unsigned int udptimeout, - unsigned int udpretries, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp); -/*!< - * \brief Create and send a request. - * - * Notes: - * - *\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the - * #DNS_REQUESTOPT_TCP option is set, TCP will be used, - * #DNS_REQUESTOPT_SHARE option is set too, connecting TCP - * (vs. connected) will be shared too. The request - * will timeout after 'timeout' seconds. UDP requests will be resent - * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero. - * - *\li When the request completes, successfully, due to a timeout, or - * because it was canceled, a completion event will be sent to 'task'. - * - * Requires: - * - *\li 'msgbuf' is a valid DNS message in compressed wire format. - * - *\li 'destaddr' is a valid sockaddr. - * - *\li 'srcaddr' is a valid sockaddr or NULL. - * - *\li 'srcaddr' and 'dstaddr' are the same protocol family. - * - *\li 'timeout' > 0 - * - *\li 'task' is a valid task. - * - *\li requestp != NULL && *requestp == NULL - */ - -void -dns_request_cancel(dns_request_t *request); -/*%< - * Cancel 'request'. - * - * Requires: - * - *\li 'request' is a valid request. - * - * Ensures: - * - *\li If the completion event for 'request' has not yet been sent, it - * will be sent, and the result code will be ISC_R_CANCELED. - */ - -isc_result_t -dns_request_getresponse(dns_request_t *request, dns_message_t *message, - unsigned int options); -/*%< - * Get the response to 'request' by filling in 'message'. - * - * 'options' is passed to dns_message_parse(). See dns_message_parse() - * for more details. - * - * Requires: - * - *\li 'request' is a valid request for which the caller has received the - * completion event. - * - *\li The result code of the completion event was #ISC_R_SUCCESS. - * - * Returns: - * - *\li ISC_R_SUCCESS - * - *\li Any result that dns_message_parse() can return. - */ - -bool -dns_request_usedtcp(dns_request_t *request); -/*%< - * Return whether this query used TCP or not. Setting #DNS_REQUESTOPT_TCP - * in the call to dns_request_create() will cause the function to return - * #true, otherwise the result is based on the query message size. - * - * Requires: - *\li 'request' is a valid request. - * - * Returns: - *\li true if TCP was used. - *\li false if UDP was used. - */ - -void -dns_request_destroy(dns_request_t **requestp); -/*%< - * Destroy 'request'. - * - * Requires: - * - *\li 'request' is a valid request for which the caller has received the - * completion event. - * - * Ensures: - * - *\li *requestp == NULL - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_REQUEST_H */ diff --git a/lib/dns-pkcs11/include/dns/resolver.h b/lib/dns-pkcs11/include/dns/resolver.h deleted file mode 100644 index bd7d225..0000000 --- a/lib/dns-pkcs11/include/dns/resolver.h +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RESOLVER_H -#define DNS_RESOLVER_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/resolver.h - * - * \brief - * This is the BIND 9 resolver, the module responsible for resolving DNS - * requests by iteratively querying authoritative servers and following - * referrals. This is a "full resolver", not to be confused with - * the stub resolvers most people associate with the word "resolver". - * The full resolver is part of the caching name server or resolver - * daemon the stub resolver talks to. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li RFCs: 1034, 1035, 2181, TBS - *\li Drafts: TBS - */ - -#include -#include - -#include -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/*% - * A dns_fetchevent_t is sent when a 'fetch' completes. Any of 'db', - * 'node', 'rdataset', and 'sigrdataset' may be bound. It is the - * receiver's responsibility to detach before freeing the event. - * \brief - * 'rdataset', 'sigrdataset', 'client' and 'id' are the values that were - * supplied when dns_resolver_createfetch() was called. They are returned - * to the caller so that they may be freed. - */ -typedef struct dns_fetchevent { - ISC_EVENT_COMMON(struct dns_fetchevent); - dns_fetch_t * fetch; - isc_result_t result; - dns_rdatatype_t qtype; - dns_db_t * db; - dns_dbnode_t * node; - dns_rdataset_t * rdataset; - dns_rdataset_t * sigrdataset; - dns_fixedname_t foundname; - isc_sockaddr_t * client; - dns_messageid_t id; - isc_result_t vresult; -} dns_fetchevent_t; - -/*% - * The two quota types (fetches-per-zone and fetches-per-server) - */ -typedef enum { - dns_quotatype_zone = 0, - dns_quotatype_server -} dns_quotatype_t; - -/* - * Options that modify how a 'fetch' is done. - */ -#define DNS_FETCHOPT_TCP 0x00001 /*%< Use TCP. */ -#define DNS_FETCHOPT_UNSHARED 0x00002 /*%< See below. */ -#define DNS_FETCHOPT_RECURSIVE 0x00004 /*%< Set RD? */ -#define DNS_FETCHOPT_NOEDNS0 0x00008 /*%< Do not use EDNS. */ -#define DNS_FETCHOPT_FORWARDONLY 0x00010 /*%< Only use forwarders. */ -#define DNS_FETCHOPT_NOVALIDATE 0x00020 /*%< Disable validation. */ -#define DNS_FETCHOPT_EDNS512 0x00040 /*%< Advertise a 512 byte - 0 UDP buffer. */ -#define DNS_FETCHOPT_WANTNSID 0x00080 /*%< Request NSID */ -#define DNS_FETCHOPT_PREFETCH 0x00100 /*%< Do prefetch */ -#define DNS_FETCHOPT_NOCDFLAG 0x00200 /*%< Don't set CD flag. */ -#define DNS_FETCHOPT_NONTA 0x00400 /*%< Ignore NTA table. */ -/* RESERVED ECS 0x00000 */ -/* RESERVED ECS 0x01000 */ -/* RESERVED ECS 0x02000 */ -/* RESERVED TCPCLIENT 0x04000 */ -#define DNS_FETCHOPT_NOCACHED 0x08000 /*%< Force cache update. */ -#define DNS_FETCHOPT_NOFORWARD 0x80000 /*%< Do not use forwarders - if possible. */ - -/* Reserved in use by adb.c 0x00400000 */ -#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 -#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000 -#define DNS_FETCHOPT_EDNSVERSIONSHIFT 24 - -/* - * Upper bounds of class of query RTT (ms). Corresponds to - * dns_resstatscounter_queryrttX statistics counters. - */ -#define DNS_RESOLVER_QRYRTTCLASS0 10 -#define DNS_RESOLVER_QRYRTTCLASS0STR "10" -#define DNS_RESOLVER_QRYRTTCLASS1 100 -#define DNS_RESOLVER_QRYRTTCLASS1STR "100" -#define DNS_RESOLVER_QRYRTTCLASS2 500 -#define DNS_RESOLVER_QRYRTTCLASS2STR "500" -#define DNS_RESOLVER_QRYRTTCLASS3 800 -#define DNS_RESOLVER_QRYRTTCLASS3STR "800" -#define DNS_RESOLVER_QRYRTTCLASS4 1600 -#define DNS_RESOLVER_QRYRTTCLASS4STR "1600" - -/* - * XXXRTH Should this API be made semi-private? (I.e. - * _dns_resolver_create()). - */ - -#define DNS_RESOLVER_CHECKNAMES 0x01 -#define DNS_RESOLVER_CHECKNAMESFAIL 0x02 - -isc_result_t -dns_resolver_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, - unsigned int ntasks, unsigned int ndisp, - isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, - unsigned int options, - dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, - dns_dispatch_t *dispatchv6, - dns_resolver_t **resp); - -/*%< - * Create a resolver. - * - * Notes: - * - *\li Generally, applications should not create a resolver directly, but - * should instead call dns_view_createresolver(). - * - * Requires: - * - *\li 'view' is a valid view. - * - *\li 'taskmgr' is a valid task manager. - * - *\li 'ntasks' > 0. - * - *\li 'socketmgr' is a valid socket manager. - * - *\li 'timermgr' is a valid timer manager. - * - *\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL. - * If not NULL, 'ndisp' clones of it will be created by the resolver. - * - *\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL. - * If not NULL, 'ndisp' clones of it will be created by the resolver. - * - *\li resp != NULL && *resp == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -void -dns_resolver_freeze(dns_resolver_t *res); -/*%< - * Freeze resolver. - * - * Notes: - * - *\li Certain configuration changes cannot be made after the resolver - * is frozen. Fetches cannot be created until the resolver is frozen. - * - * Requires: - * - *\li 'res' is a valid resolver. - * - * Ensures: - * - *\li 'res' is frozen. - */ - -void -dns_resolver_prime(dns_resolver_t *res); -/*%< - * Prime resolver. - * - * Notes: - * - *\li Resolvers which have a forwarding policy other than dns_fwdpolicy_only - * need to be primed with the root nameservers, otherwise the root - * nameserver hints data may be used indefinitely. This function requests - * that the resolver start a priming fetch, if it isn't already priming. - * - * Requires: - * - *\li 'res' is a valid, frozen resolver. - */ - - -void -dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, - isc_event_t **eventp); -/*%< - * Send '*eventp' to 'task' when 'res' has completed shutdown. - * - * Notes: - * - *\li It is not safe to detach the last reference to 'res' until - * shutdown is complete. - * - * Requires: - * - *\li 'res' is a valid resolver. - * - *\li 'task' is a valid task. - * - *\li *eventp is a valid event. - * - * Ensures: - * - *\li *eventp == NULL. - */ - -void -dns_resolver_shutdown(dns_resolver_t *res); -/*%< - * Start the shutdown process for 'res'. - * - * Notes: - * - *\li This call has no effect if the resolver is already shutting down. - * - * Requires: - * - *\li 'res' is a valid resolver. - */ - -void -dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp); - -void -dns_resolver_detach(dns_resolver_t **resp); - -isc_result_t -dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp); - -isc_result_t -dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - isc_sockaddr_t *client, uint16_t id, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp); -isc_result_t -dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - isc_sockaddr_t *client, uint16_t id, - unsigned int options, unsigned int depth, - isc_counter_t *qc, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp); -/*%< - * Recurse to answer a question. - * - * Notes: - * - *\li This call starts a query for 'name', type 'type'. - * - *\li The 'domain' is a parent domain of 'name' for which - * a set of name servers 'nameservers' is known. If no - * such name server information is available, set - * 'domain' and 'nameservers' to NULL. - * - *\li 'forwarders' is unimplemented, and subject to change when - * we figure out how selective forwarding will work. - * - *\li When the fetch completes (successfully or otherwise), a - * #DNS_EVENT_FETCHDONE event with action 'action' and arg 'arg' will be - * posted to 'task'. - * - *\li The values of 'rdataset' and 'sigrdataset' will be returned in - * the FETCHDONE event. - * - *\li 'client' and 'id' are used for duplicate query detection. '*client' - * must remain stable until after 'action' has been called or - * dns_resolver_cancelfetch() is called. - * - * Requires: - * - *\li 'res' is a valid resolver that has been frozen. - * - *\li 'name' is a valid name. - * - *\li 'type' is not a meta type other than ANY. - * - *\li 'domain' is a valid name or NULL. - * - *\li 'nameservers' is a valid NS rdataset (whose owner name is 'domain') - * iff. 'domain' is not NULL. - * - *\li 'forwarders' is NULL. - * - *\li 'client' is a valid sockaddr or NULL. - * - *\li 'options' contains valid options. - * - *\li 'rdataset' is a valid, disassociated rdataset. - * - *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. - * - *\li fetchp != NULL && *fetchp == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS Success - *\li #DNS_R_DUPLICATE - *\li #DNS_R_DROP - * - *\li Many other values are possible, all of which indicate failure. - */ - -void -dns_resolver_cancelfetch(dns_fetch_t *fetch); -/*%< - * Cancel 'fetch'. - * - * Notes: - * - *\li If 'fetch' has not completed, post its FETCHDONE event with a - * result code of #ISC_R_CANCELED. - * - * Requires: - * - *\li 'fetch' is a valid fetch. - */ - -void -dns_resolver_destroyfetch(dns_fetch_t **fetchp); -/*%< - * Destroy 'fetch'. - * - * Requires: - * - *\li '*fetchp' is a valid fetch. - * - *\li The caller has received the FETCHDONE event (either because the - * fetch completed or because dns_resolver_cancelfetch() was called). - * - * Ensures: - * - *\li *fetchp == NULL. - */ - -void -dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, bool duplicateok); -/*%< - * Dump a log message on internal state at the completion of given 'fetch'. - * 'lctx', 'category', 'module', and 'level' are used to write the log message. - * By default, only one log message is written even if the corresponding fetch - * context serves multiple clients; if 'duplicateok' is true the suppression - * is disabled and the message can be written every time this function is - * called. - * - * Requires: - * - *\li 'fetch' is a valid fetch, and has completed. - */ - -dns_dispatchmgr_t * -dns_resolver_dispatchmgr(dns_resolver_t *resolver); - -dns_dispatch_t * -dns_resolver_dispatchv4(dns_resolver_t *resolver); - -dns_dispatch_t * -dns_resolver_dispatchv6(dns_resolver_t *resolver); - -isc_socketmgr_t * -dns_resolver_socketmgr(dns_resolver_t *resolver); - -isc_taskmgr_t * -dns_resolver_taskmgr(dns_resolver_t *resolver); - -uint32_t -dns_resolver_getlamettl(dns_resolver_t *resolver); -/*%< - * Get the resolver's lame-ttl. zero => no lame processing. - * - * Requires: - *\li 'resolver' to be valid. - */ - -void -dns_resolver_setlamettl(dns_resolver_t *resolver, uint32_t lame_ttl); -/*%< - * Set the resolver's lame-ttl. zero => no lame processing. - * - * Requires: - *\li 'resolver' to be valid. - */ - -unsigned int -dns_resolver_nrunning(dns_resolver_t *resolver); -/*%< - * Return the number of currently running resolutions in this - * resolver. This is may be less than the number of outstanding - * fetches due to multiple identical fetches, or more than the - * number of of outstanding fetches due to the fact that resolution - * can continue even though a fetch has been canceled. - */ - -isc_result_t -dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, - dns_name_t *name, in_port_t port); -/*%< - * Add alternate addresses to be tried in the event that the nameservers - * for a zone are not available in the address families supported by the - * operating system. - * - * Require: - * \li only one of 'name' or 'alt' to be valid. - */ - -void -dns_resolver_setudpsize(dns_resolver_t *resolver, uint16_t udpsize); -/*%< - * Set the EDNS UDP buffer size advertised by the server. - */ - -uint16_t -dns_resolver_getudpsize(dns_resolver_t *resolver); -/*%< - * Get the current EDNS UDP buffer size. - */ - -void -dns_resolver_reset_algorithms(dns_resolver_t *resolver); -/*%< - * Clear the disabled DNSSEC algorithms. - */ - -void -dns_resolver_reset_ds_digests(dns_resolver_t *resolver); -/*%< - * Clear the disabled DS/DLV digest types. - */ - -isc_result_t -dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, - unsigned int alg); -/*%< - * Mark the given DNSSEC algorithm as disabled and below 'name'. - * Valid algorithms are less than 256. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_RANGE - *\li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name, - unsigned int digest_type); -/*%< - * Mark the given DS/DLV digest type as disabled and below 'name'. - * Valid types are less than 256. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_RANGE - *\li #ISC_R_NOMEMORY - */ - -bool -dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, - unsigned int alg); -/*%< - * Check if the given algorithm is supported by this resolver. - * This checks whether the algorithm has been disabled via - * dns_resolver_disable_algorithm(), then checks the underlying - * crypto libraries if it was not specifically disabled. - */ - -bool -dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name, - unsigned int digest_type); -/*%< - * Check if the given digest type is supported by this resolver. - * This checks whether the digest type has been disabled via - * dns_resolver_disable_ds_digest(), then checks the underlying - * crypto libraries if it was not specifically disabled. - */ - -void -dns_resolver_resetmustbesecure(dns_resolver_t *resolver); - -isc_result_t -dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, - bool value); - -bool -dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name); - - -void -dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int timeout); -/*%< - * Set the length of time the resolver will work on a query, in milliseconds. - * - * 'timeout' was originally defined in seconds, and later redefined to be in - * milliseconds. Values less than or equal to 300 are treated as seconds. - * - * If timeout is 0, the default timeout will be applied. - * - * Requires: - * \li resolver to be valid. - */ - -unsigned int -dns_resolver_gettimeout(dns_resolver_t *resolver); -/*%< - * Get the current length of time the resolver will work on a query, - * in milliseconds. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_setclientsperquery(dns_resolver_t *resolver, - uint32_t min, uint32_t max); -void -dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients); - -void -dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur, - uint32_t *min, uint32_t *max); - -bool -dns_resolver_getzeronosoattl(dns_resolver_t *resolver); - -void -dns_resolver_setzeronosoattl(dns_resolver_t *resolver, bool state); - -unsigned int -dns_resolver_getretryinterval(dns_resolver_t *resolver); - -void -dns_resolver_setretryinterval(dns_resolver_t *resolver, unsigned int interval); -/*%< - * Sets the amount of time, in millseconds, that is waited for a reply - * to a server before another server is tried. Interacts with the - * value of dns_resolver_getnonbackofftries() by trying that number of times - * at this interval, before doing exponential backoff and doubling the interval - * on each subsequent try, to a maximum of 10 seconds. Defaults to 800 ms; - * silently capped at 2000 ms. - * - * Requires: - * \li resolver to be valid. - * \li interval > 0. - */ - -unsigned int -dns_resolver_getnonbackofftries(dns_resolver_t *resolver); - -void -dns_resolver_setnonbackofftries(dns_resolver_t *resolver, unsigned int tries); -/*%< - * Sets the number of failures of getting a reply from remote servers for - * a query before backing off by doubling the retry interval for each - * subsequent request sent. Defaults to 3. - * - * Requires: - * \li resolver to be valid. - * \li tries > 0. - */ - -unsigned int -dns_resolver_getoptions(dns_resolver_t *resolver); - -void -dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, - dns_rdatatype_t type, isc_time_t *expire); -/*%< - * Add a entry to the bad cache for that will expire at 'expire'. - * - * Requires: - * \li resolver to be valid. - * \li name to be valid. - */ - -bool -dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, - dns_rdatatype_t type, isc_time_t *now); -/*%< - * Check to see if there is a unexpired entry in the bad cache for - * . - * - * Requires: - * \li resolver to be valid. - * \li name to be valid. - */ - -void -dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name); -/*%< - * Flush the bad cache of all entries at 'name' if 'name' is non NULL. - * Flush the entire bad cache if 'name' is NULL. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name); -/*%< - * Flush the bad cache of all entries at or below 'name'. - * - * Requires: - * \li resolver to be valid. - * \li name != NULL - */ - -void -dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); -/*% - * Print out the contents of the bad cache to 'fp'. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp); -isc_dscp_t -dns_resolver_getquerydscp4(dns_resolver_t *resolver); - -void -dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp); -isc_dscp_t -dns_resolver_getquerydscp6(dns_resolver_t *resolver); -/*% - * Get and set the DSCP values for the resolver's IPv4 and IPV6 query - * sources. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth); -unsigned int -dns_resolver_getmaxdepth(dns_resolver_t *resolver); -/*% - * Get and set how many NS indirections will be followed when looking for - * nameserver addresses. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries); -unsigned int -dns_resolver_getmaxqueries(dns_resolver_t *resolver); -/*% - * Get and set how many iterative queries will be allowed before - * terminating a recursive query. - * - * Requires: - * \li resolver to be valid. - */ - -void -dns_resolver_setquotaresponse(dns_resolver_t *resolver, - dns_quotatype_t which, isc_result_t resp); -isc_result_t -dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which); -/*% - * Get and set the result code that will be used when quotas - * are exceeded. If 'which' is set to quotatype "zone", then the - * result specified in 'resp' will be used when the fetches-per-zone - * quota is exceeded by a fetch. If 'which' is set to quotatype "server", - * then the result specified in 'resp' will be used when the - * fetches-per-server quota has been exceeded for all the - * authoritative servers for a zone. Valid choices are - * DNS_R_DROP or DNS_R_SERVFAIL. - * - * Requires: - * \li 'resolver' to be valid. - * \li 'which' to be dns_quotatype_zone or dns_quotatype_server - * \li 'resp' to be DNS_R_DROP or DNS_R_SERVFAIL. - */ - -void -dns_resolver_dumpfetches(dns_resolver_t *resolver, - isc_statsformat_t format, FILE *fp); - - -#ifdef ENABLE_AFL -/*% - * Enable fuzzing of resolver, changes behaviour and eliminates retries - */ -void dns_resolver_setfuzzing(void); -#endif - -ISC_LANG_ENDDECLS - -#endif /* DNS_RESOLVER_H */ diff --git a/lib/dns-pkcs11/include/dns/result.h b/lib/dns-pkcs11/include/dns/result.h deleted file mode 100644 index d0c83de..0000000 --- a/lib/dns-pkcs11/include/dns/result.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RESULT_H -#define DNS_RESULT_H 1 - -/*! \file dns/result.h */ - -#include -#include - -#include - -/* - * Nothing in this file truly depends on , but the - * DNS result codes are considered to be publicly derived from - * the ISC result codes, so including this file buys you the ISC_R_ - * namespace too. - */ -#include /* Contractual promise. */ - -/* - * DNS library result codes - */ -#define DNS_R_LABELTOOLONG (ISC_RESULTCLASS_DNS + 0) -#define DNS_R_BADESCAPE (ISC_RESULTCLASS_DNS + 1) -/* - * Since we dropped the support of bitstring labels, deprecate the related - * result codes too. - -#define DNS_R_BADBITSTRING (ISC_RESULTCLASS_DNS + 2) -#define DNS_R_BITSTRINGTOOLONG (ISC_RESULTCLASS_DNS + 3) -*/ -#define DNS_R_EMPTYLABEL (ISC_RESULTCLASS_DNS + 4) -#define DNS_R_BADDOTTEDQUAD (ISC_RESULTCLASS_DNS + 5) -#define DNS_R_INVALIDNS (ISC_RESULTCLASS_DNS + 6) -#define DNS_R_UNKNOWN (ISC_RESULTCLASS_DNS + 7) -#define DNS_R_BADLABELTYPE (ISC_RESULTCLASS_DNS + 8) -#define DNS_R_BADPOINTER (ISC_RESULTCLASS_DNS + 9) -#define DNS_R_TOOMANYHOPS (ISC_RESULTCLASS_DNS + 10) -#define DNS_R_DISALLOWED (ISC_RESULTCLASS_DNS + 11) -#define DNS_R_EXTRATOKEN (ISC_RESULTCLASS_DNS + 12) -#define DNS_R_EXTRADATA (ISC_RESULTCLASS_DNS + 13) -#define DNS_R_TEXTTOOLONG (ISC_RESULTCLASS_DNS + 14) -#define DNS_R_NOTZONETOP (ISC_RESULTCLASS_DNS + 15) -#define DNS_R_SYNTAX (ISC_RESULTCLASS_DNS + 16) -#define DNS_R_BADCKSUM (ISC_RESULTCLASS_DNS + 17) -#define DNS_R_BADAAAA (ISC_RESULTCLASS_DNS + 18) -#define DNS_R_NOOWNER (ISC_RESULTCLASS_DNS + 19) -#define DNS_R_NOTTL (ISC_RESULTCLASS_DNS + 20) -#define DNS_R_BADCLASS (ISC_RESULTCLASS_DNS + 21) -#define DNS_R_NAMETOOLONG (ISC_RESULTCLASS_DNS + 22) -#define DNS_R_PARTIALMATCH (ISC_RESULTCLASS_DNS + 23) -#define DNS_R_NEWORIGIN (ISC_RESULTCLASS_DNS + 24) -#define DNS_R_UNCHANGED (ISC_RESULTCLASS_DNS + 25) -#define DNS_R_BADTTL (ISC_RESULTCLASS_DNS + 26) -#define DNS_R_NOREDATA (ISC_RESULTCLASS_DNS + 27) -#define DNS_R_CONTINUE (ISC_RESULTCLASS_DNS + 28) -#define DNS_R_DELEGATION (ISC_RESULTCLASS_DNS + 29) -#define DNS_R_GLUE (ISC_RESULTCLASS_DNS + 30) -#define DNS_R_DNAME (ISC_RESULTCLASS_DNS + 31) -#define DNS_R_CNAME (ISC_RESULTCLASS_DNS + 32) -#define DNS_R_BADDB (ISC_RESULTCLASS_DNS + 33) -#define DNS_R_ZONECUT (ISC_RESULTCLASS_DNS + 34) -#define DNS_R_BADZONE (ISC_RESULTCLASS_DNS + 35) -#define DNS_R_MOREDATA (ISC_RESULTCLASS_DNS + 36) -#define DNS_R_UPTODATE (ISC_RESULTCLASS_DNS + 37) -#define DNS_R_TSIGVERIFYFAILURE (ISC_RESULTCLASS_DNS + 38) -#define DNS_R_TSIGERRORSET (ISC_RESULTCLASS_DNS + 39) -#define DNS_R_SIGINVALID (ISC_RESULTCLASS_DNS + 40) -#define DNS_R_SIGEXPIRED (ISC_RESULTCLASS_DNS + 41) -#define DNS_R_SIGFUTURE (ISC_RESULTCLASS_DNS + 42) -#define DNS_R_KEYUNAUTHORIZED (ISC_RESULTCLASS_DNS + 43) -#define DNS_R_INVALIDTIME (ISC_RESULTCLASS_DNS + 44) -#define DNS_R_EXPECTEDTSIG (ISC_RESULTCLASS_DNS + 45) -#define DNS_R_UNEXPECTEDTSIG (ISC_RESULTCLASS_DNS + 46) -#define DNS_R_INVALIDTKEY (ISC_RESULTCLASS_DNS + 47) -#define DNS_R_HINT (ISC_RESULTCLASS_DNS + 48) -#define DNS_R_DROP (ISC_RESULTCLASS_DNS + 49) -#define DNS_R_NOTLOADED (ISC_RESULTCLASS_DNS + 50) -#define DNS_R_NCACHENXDOMAIN (ISC_RESULTCLASS_DNS + 51) -#define DNS_R_NCACHENXRRSET (ISC_RESULTCLASS_DNS + 52) -#define DNS_R_WAIT (ISC_RESULTCLASS_DNS + 53) -#define DNS_R_NOTVERIFIEDYET (ISC_RESULTCLASS_DNS + 54) -#define DNS_R_NOIDENTITY (ISC_RESULTCLASS_DNS + 55) -#define DNS_R_NOJOURNAL (ISC_RESULTCLASS_DNS + 56) -#define DNS_R_ALIAS (ISC_RESULTCLASS_DNS + 57) -#define DNS_R_USETCP (ISC_RESULTCLASS_DNS + 58) -#define DNS_R_NOVALIDSIG (ISC_RESULTCLASS_DNS + 59) -#define DNS_R_NOVALIDNSEC (ISC_RESULTCLASS_DNS + 60) -#define DNS_R_NOTINSECURE (ISC_RESULTCLASS_DNS + 61) -#define DNS_R_UNKNOWNSERVICE (ISC_RESULTCLASS_DNS + 62) -#define DNS_R_RECOVERABLE (ISC_RESULTCLASS_DNS + 63) -#define DNS_R_UNKNOWNOPT (ISC_RESULTCLASS_DNS + 64) -#define DNS_R_UNEXPECTEDID (ISC_RESULTCLASS_DNS + 65) -#define DNS_R_SEENINCLUDE (ISC_RESULTCLASS_DNS + 66) -#define DNS_R_NOTEXACT (ISC_RESULTCLASS_DNS + 67) -#define DNS_R_BLACKHOLED (ISC_RESULTCLASS_DNS + 68) -#define DNS_R_BADALG (ISC_RESULTCLASS_DNS + 69) -#define DNS_R_METATYPE (ISC_RESULTCLASS_DNS + 70) -#define DNS_R_CNAMEANDOTHER (ISC_RESULTCLASS_DNS + 71) -#define DNS_R_SINGLETON (ISC_RESULTCLASS_DNS + 72) -#define DNS_R_HINTNXRRSET (ISC_RESULTCLASS_DNS + 73) -#define DNS_R_NOMASTERFILE (ISC_RESULTCLASS_DNS + 74) -#define DNS_R_UNKNOWNPROTO (ISC_RESULTCLASS_DNS + 75) -#define DNS_R_CLOCKSKEW (ISC_RESULTCLASS_DNS + 76) -#define DNS_R_BADIXFR (ISC_RESULTCLASS_DNS + 77) -#define DNS_R_NOTAUTHORITATIVE (ISC_RESULTCLASS_DNS + 78) -#define DNS_R_NOVALIDKEY (ISC_RESULTCLASS_DNS + 79) -#define DNS_R_OBSOLETE (ISC_RESULTCLASS_DNS + 80) -#define DNS_R_FROZEN (ISC_RESULTCLASS_DNS + 81) -#define DNS_R_UNKNOWNFLAG (ISC_RESULTCLASS_DNS + 82) -#define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83) -#define DNS_R_NOVALIDDS (ISC_RESULTCLASS_DNS + 84) -#define DNS_R_NSISADDRESS (ISC_RESULTCLASS_DNS + 85) -#define DNS_R_REMOTEFORMERR (ISC_RESULTCLASS_DNS + 86) -#define DNS_R_TRUNCATEDTCP (ISC_RESULTCLASS_DNS + 87) -#define DNS_R_LAME (ISC_RESULTCLASS_DNS + 88) -#define DNS_R_UNEXPECTEDRCODE (ISC_RESULTCLASS_DNS + 89) -#define DNS_R_UNEXPECTEDOPCODE (ISC_RESULTCLASS_DNS + 90) -#define DNS_R_CHASEDSSERVERS (ISC_RESULTCLASS_DNS + 91) -#define DNS_R_EMPTYNAME (ISC_RESULTCLASS_DNS + 92) -#define DNS_R_EMPTYWILD (ISC_RESULTCLASS_DNS + 93) -#define DNS_R_BADBITMAP (ISC_RESULTCLASS_DNS + 94) -#define DNS_R_FROMWILDCARD (ISC_RESULTCLASS_DNS + 95) -#define DNS_R_BADOWNERNAME (ISC_RESULTCLASS_DNS + 96) -#define DNS_R_BADNAME (ISC_RESULTCLASS_DNS + 97) -#define DNS_R_DYNAMIC (ISC_RESULTCLASS_DNS + 98) -#define DNS_R_UNKNOWNCOMMAND (ISC_RESULTCLASS_DNS + 99) -#define DNS_R_MUSTBESECURE (ISC_RESULTCLASS_DNS + 100) -#define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101) -#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102) -#define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103) -#define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104) -#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105) -#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106) -#define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107) -#define DNS_R_NOTDYNAMIC (ISC_RESULTCLASS_DNS + 108) -#define DNS_R_BADEUI (ISC_RESULTCLASS_DNS + 109) -#define DNS_R_NTACOVERED (ISC_RESULTCLASS_DNS + 110) -#define DNS_R_BADCDS (ISC_RESULTCLASS_DNS + 111) -#define DNS_R_BADCDNSKEY (ISC_RESULTCLASS_DNS + 112) -#define DNS_R_OPTERR (ISC_RESULTCLASS_DNS + 113) -#define DNS_R_BADDNSTAP (ISC_RESULTCLASS_DNS + 114) -#define DNS_R_BADTSIG (ISC_RESULTCLASS_DNS + 115) -#define DNS_R_BADSIG0 (ISC_RESULTCLASS_DNS + 116) -#define DNS_R_TOOMANYRECORDS (ISC_RESULTCLASS_DNS + 117) - -#define DNS_R_NRESULTS 118 /*%< Number of results */ - -/* - * DNS wire format rcodes. - * - * By making these their own class we can easily convert them into the - * wire-format rcode value simply by masking off the resultclass. - */ -#define DNS_R_NOERROR (ISC_RESULTCLASS_DNSRCODE + 0) -#define DNS_R_FORMERR (ISC_RESULTCLASS_DNSRCODE + 1) -#define DNS_R_SERVFAIL (ISC_RESULTCLASS_DNSRCODE + 2) -#define DNS_R_NXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 3) -#define DNS_R_NOTIMP (ISC_RESULTCLASS_DNSRCODE + 4) -#define DNS_R_REFUSED (ISC_RESULTCLASS_DNSRCODE + 5) -#define DNS_R_YXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 6) -#define DNS_R_YXRRSET (ISC_RESULTCLASS_DNSRCODE + 7) -#define DNS_R_NXRRSET (ISC_RESULTCLASS_DNSRCODE + 8) -#define DNS_R_NOTAUTH (ISC_RESULTCLASS_DNSRCODE + 9) -#define DNS_R_NOTZONE (ISC_RESULTCLASS_DNSRCODE + 10) -#define DNS_R_RCODE11 (ISC_RESULTCLASS_DNSRCODE + 11) -#define DNS_R_RCODE12 (ISC_RESULTCLASS_DNSRCODE + 12) -#define DNS_R_RCODE13 (ISC_RESULTCLASS_DNSRCODE + 13) -#define DNS_R_RCODE14 (ISC_RESULTCLASS_DNSRCODE + 14) -#define DNS_R_RCODE15 (ISC_RESULTCLASS_DNSRCODE + 15) -#define DNS_R_BADVERS (ISC_RESULTCLASS_DNSRCODE + 16) - -#define DNS_R_NRCODERESULTS 17 /*%< Number of rcode results */ - -#define DNS_RESULT_ISRCODE(result) \ - (ISC_RESULTCLASS_INCLASS(ISC_RESULTCLASS_DNSRCODE, (result))) - -ISC_LANG_BEGINDECLS - -const char * -dns_result_totext(isc_result_t); - -void -dns_result_register(void); - -dns_rcode_t -dns_result_torcode(isc_result_t result); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RESULT_H */ diff --git a/lib/dns-pkcs11/include/dns/rootns.h b/lib/dns-pkcs11/include/dns/rootns.h deleted file mode 100644 index a097f65..0000000 --- a/lib/dns-pkcs11/include/dns/rootns.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ROOTNS_H -#define DNS_ROOTNS_H 1 - -/*! \file dns/rootns.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, - const char *filename, dns_db_t **target); - -void -dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db); -/* - * Reports differences between hints and the real roots. - * - * Requires view, hints and (cache) db to be valid. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ROOTNS_H */ diff --git a/lib/dns-pkcs11/include/dns/rpz.h b/lib/dns-pkcs11/include/dns/rpz.h deleted file mode 100644 index 32ce335..0000000 --- a/lib/dns-pkcs11/include/dns/rpz.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RPZ_H -#define DNS_RPZ_H 1 - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -ISC_LANG_BEGINDECLS - -#define DNS_RPZ_PREFIX "rpz-" -/* - * Sub-zones of various trigger types. - */ -#define DNS_RPZ_CLIENT_IP_ZONE DNS_RPZ_PREFIX"client-ip" -#define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip" -#define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip" -#define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname" -/* - * Special policies. - */ -#define DNS_RPZ_PASSTHRU_NAME DNS_RPZ_PREFIX"passthru" -#define DNS_RPZ_DROP_NAME DNS_RPZ_PREFIX"drop" -#define DNS_RPZ_TCP_ONLY_NAME DNS_RPZ_PREFIX"tcp-only" - - -typedef uint8_t dns_rpz_prefix_t; - -typedef enum { - DNS_RPZ_TYPE_BAD, - DNS_RPZ_TYPE_CLIENT_IP, - DNS_RPZ_TYPE_QNAME, - DNS_RPZ_TYPE_IP, - DNS_RPZ_TYPE_NSDNAME, - DNS_RPZ_TYPE_NSIP -} dns_rpz_type_t; - -/* - * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_DROP - * < DNS_RPZ_POLICY_TCP_ONLY DNS_RPZ_POLICY_NXDOMAIN < DNS_RPZ_POLICY_NODATA - * < DNS_RPZ_POLICY_CNAME to choose among competing policies. - */ -typedef enum { - DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what policy record says */ - DNS_RPZ_POLICY_DISABLED = 1, /* log what would have happened */ - DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */ - DNS_RPZ_POLICY_DROP = 3, /* 'drop': do not respond */ - DNS_RPZ_POLICY_TCP_ONLY = 4, /* 'tcp-only': answer UDP with TC=1 */ - DNS_RPZ_POLICY_NXDOMAIN = 5, /* 'nxdomain': answer with NXDOMAIN */ - DNS_RPZ_POLICY_NODATA = 6, /* 'nodata': answer with ANCOUNT=0 */ - DNS_RPZ_POLICY_CNAME = 7, /* 'cname x': answer with x's rrsets */ - DNS_RPZ_POLICY_DNS64, /* Apply DN64 to the A rewrite */ - DNS_RPZ_POLICY_RECORD, - DNS_RPZ_POLICY_WILDCNAME, - DNS_RPZ_POLICY_MISS, - DNS_RPZ_POLICY_ERROR -} dns_rpz_policy_t; - -typedef uint8_t dns_rpz_num_t; - -#define DNS_RPZ_MAX_ZONES 32 -#if DNS_RPZ_MAX_ZONES > 32 -# if DNS_RPZ_MAX_ZONES > 64 -# error "rpz zone bit masks must fit in a word" -# endif -typedef uint64_t dns_rpz_zbits_t; -#else -typedef uint32_t dns_rpz_zbits_t; -#endif - -#define DNS_RPZ_ALL_ZBITS ((dns_rpz_zbits_t)-1) - -#define DNS_RPZ_INVALID_NUM DNS_RPZ_MAX_ZONES - -#define DNS_RPZ_ZBIT(n) (((dns_rpz_zbits_t)1) << (dns_rpz_num_t)(n)) - -/* - * Mask of the specified and higher numbered policy zones - * Avoid hassles with (1<<33) or (1<<65) - */ -#define DNS_RPZ_ZMASK(n) ((dns_rpz_zbits_t)((((n) >= DNS_RPZ_MAX_ZONES-1) ? \ - 0 : (1<<((n)+1))) -1)) - -/* - * The trigger counter type. - */ -typedef size_t dns_rpz_trigger_counter_t; - -/* - * The number of triggers of each type in a response policy zone. - */ -typedef struct dns_rpz_triggers dns_rpz_triggers_t; -struct dns_rpz_triggers { - dns_rpz_trigger_counter_t client_ipv4; - dns_rpz_trigger_counter_t client_ipv6; - dns_rpz_trigger_counter_t qname; - dns_rpz_trigger_counter_t ipv4; - dns_rpz_trigger_counter_t ipv6; - dns_rpz_trigger_counter_t nsdname; - dns_rpz_trigger_counter_t nsipv4; - dns_rpz_trigger_counter_t nsipv6; -}; - -/* - * A single response policy zone. - */ -typedef struct dns_rpz_zone dns_rpz_zone_t; -struct dns_rpz_zone { - isc_refcount_t refs; - dns_rpz_num_t num; /* ordinal in list of policy zones */ - dns_name_t origin; /* Policy zone name */ - dns_name_t client_ip; /* DNS_RPZ_CLIENT_IP_ZONE.origin. */ - dns_name_t ip; /* DNS_RPZ_IP_ZONE.origin. */ - dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */ - dns_name_t nsip; /* DNS_RPZ_NSIP_ZONE.origin. */ - dns_name_t passthru; /* DNS_RPZ_PASSTHRU_NAME. */ - dns_name_t drop; /* DNS_RPZ_DROP_NAME. */ - dns_name_t tcp_only; /* DNS_RPZ_TCP_ONLY_NAME. */ - dns_name_t cname; /* override value for ..._CNAME */ - dns_ttl_t max_policy_ttl; - dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ -}; - -/* - * Radix tree node for response policy IP addresses - */ -typedef struct dns_rpz_cidr_node dns_rpz_cidr_node_t; - -/* - * Bitfields indicating which policy zones have policies of - * which type. - */ -typedef struct dns_rpz_have dns_rpz_have_t; -struct dns_rpz_have { - dns_rpz_zbits_t client_ipv4; - dns_rpz_zbits_t client_ipv6; - dns_rpz_zbits_t client_ip; - dns_rpz_zbits_t qname; - dns_rpz_zbits_t ipv4; - dns_rpz_zbits_t ipv6; - dns_rpz_zbits_t ip; - dns_rpz_zbits_t nsdname; - dns_rpz_zbits_t nsipv4; - dns_rpz_zbits_t nsipv6; - dns_rpz_zbits_t nsip; - dns_rpz_zbits_t qname_skip_recurse; -}; - -/* - * Policy options - */ -typedef struct dns_rpz_popt dns_rpz_popt_t; -struct dns_rpz_popt { - dns_rpz_zbits_t no_rd_ok; - dns_rpz_zbits_t no_log; - bool break_dnssec; - bool qname_wait_recurse; - bool nsip_wait_recurse; - unsigned int min_ns_labels; - dns_rpz_num_t num_zones; -}; - -/* - * Response policy zones known to a view. - */ -typedef struct dns_rpz_zones dns_rpz_zones_t; -struct dns_rpz_zones { - dns_rpz_popt_t p; - dns_rpz_zone_t *zones[DNS_RPZ_MAX_ZONES]; - dns_rpz_triggers_t triggers[DNS_RPZ_MAX_ZONES]; - - /* - * RPZ policy version number (initially 0, increases whenever - * the server is reconfigured with new zones or policy) - */ - int rpz_ver; - - dns_rpz_zbits_t defined; - - /* - * The set of records for a policy zone are in one of these states: - * never loaded load_begun=0 have=0 - * during initial loading load_begun=1 have=0 - * and rbtdb->rpzsp == rbtdb->load_rpzsp - * after good load load_begun=1 have!=0 - * after failed initial load load_begun=1 have=0 - * and rbtdb->load_rpzsp == NULL - * reloading after failure load_begun=1 have=0 - * reloading after success - * main rpzs load_begun=1 have!=0 - * load rpzs load_begun=1 have=0 - */ - dns_rpz_zbits_t load_begun; - dns_rpz_have_t have; - - /* - * total_triggers maintains the total number of triggers in all - * policy zones in the view. It is only used to print summary - * statistics after a zone load of how the trigger counts - * changed. - */ - dns_rpz_triggers_t total_triggers; - - isc_mem_t *mctx; - isc_refcount_t refs; - /* - * One lock for short term read-only search that guarantees the - * consistency of the pointers. - * A second lock for maintenance that guarantees no other thread - * is adding or deleting nodes. - */ - isc_rwlock_t search_lock; - isc_mutex_t maint_lock; - - dns_rpz_cidr_node_t *cidr; - dns_rbt_t *rbt; -}; - - -/* - * context for finding the best policy - */ -typedef struct { - unsigned int state; -# define DNS_RPZ_REWRITTEN 0x0001 -# define DNS_RPZ_DONE_CLIENT_IP 0x0002 /* client IP address checked */ -# define DNS_RPZ_DONE_QNAME 0x0004 /* qname checked */ -# define DNS_RPZ_DONE_QNAME_IP 0x0008 /* IP addresses of qname checked */ -# define DNS_RPZ_DONE_NSDNAME 0x0010 /* NS name missed; checking addresses */ -# define DNS_RPZ_DONE_IPv4 0x0020 -# define DNS_RPZ_RECURSING 0x0040 -# define DNS_RPZ_ACTIVE 0x0080 - /* - * Best match so far. - */ - struct { - dns_rpz_type_t type; - dns_rpz_zone_t *rpz; - dns_rpz_prefix_t prefix; - dns_rpz_policy_t policy; - dns_ttl_t ttl; - isc_result_t result; - dns_zone_t *zone; - dns_db_t *db; - dns_dbversion_t *version; - dns_dbnode_t *node; - dns_rdataset_t *rdataset; - } m; - /* - * State for chasing IP addresses and NS names including recursion. - */ - struct { - unsigned int label; - dns_db_t *db; - dns_rdataset_t *ns_rdataset; - dns_rdatatype_t r_type; - isc_result_t r_result; - dns_rdataset_t *r_rdataset; - } r; - - /* - * State of real query while recursing for NSIP or NSDNAME. - */ - struct { - isc_result_t result; - bool is_zone; - bool authoritative; - dns_zone_t *zone; - dns_db_t *db; - dns_dbnode_t *node; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - dns_rdatatype_t qtype; - } q; - - /* - * A copy of the 'have' and 'p' structures and the RPZ - * policy version as of the beginning of RPZ processing, - * used to avoid problems when policy is updated while - * RPZ recursion is ongoing. - */ - dns_rpz_have_t have; - dns_rpz_popt_t popt; - int rpz_ver; - - /* - * p_name: current policy owner name - * r_name: recursing for this name to possible policy triggers - * f_name: saved found name from before recursion - */ - dns_name_t *p_name; - dns_name_t *r_name; - dns_name_t *fname; - dns_fixedname_t _p_namef; - dns_fixedname_t _r_namef; - dns_fixedname_t _fnamef; -} dns_rpz_st_t; - -#define DNS_RPZ_TTL_DEFAULT 5 -#define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT - -/* - * So various response policy zone messages can be turned up or down. - */ -#define DNS_RPZ_ERROR_LEVEL ISC_LOG_WARNING -#define DNS_RPZ_INFO_LEVEL ISC_LOG_INFO -#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1) -#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2) -#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3) -#define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1) - -const char * -dns_rpz_type2str(dns_rpz_type_t type); - -dns_rpz_policy_t -dns_rpz_str2policy(const char *str); - -const char * -dns_rpz_policy2str(dns_rpz_policy_t policy); - -dns_rpz_policy_t -dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, - dns_name_t *selfname); - -isc_result_t -dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, isc_mem_t *mctx); - -void -dns_rpz_attach_rpzs(dns_rpz_zones_t *source, dns_rpz_zones_t **target); - -void -dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp); - -isc_result_t -dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, - dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); - -isc_result_t -dns_rpz_ready(dns_rpz_zones_t *rpzs, - dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num); - -isc_result_t -dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *name); - -void -dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *name); - -dns_rpz_num_t -dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, - dns_name_t *ip_name, dns_rpz_prefix_t *prefixp); - -dns_rpz_zbits_t -dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, dns_name_t *trig_name); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RPZ_H */ diff --git a/lib/dns-pkcs11/include/dns/rriterator.h b/lib/dns-pkcs11/include/dns/rriterator.h deleted file mode 100644 index b88aa53..0000000 --- a/lib/dns-pkcs11/include/dns/rriterator.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RRITERATOR_H -#define DNS_RRITERATOR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/rriterator.h - * \brief - * Functions for "walking" a zone database, visiting each RR or RRset in turn. - */ - -/***** - ***** Imports - *****/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -/***** - ***** Types - *****/ - -/*% - * A dns_rriterator_t is an iterator that iterates over an entire database, - * returning one RR at a time, in some arbitrary order. - */ - -typedef struct dns_rriterator { - unsigned int magic; - isc_result_t result; - dns_db_t *db; - dns_dbiterator_t *dbit; - dns_dbversion_t *ver; - isc_stdtime_t now; - dns_dbnode_t *node; - dns_fixedname_t fixedname; - dns_rdatasetiter_t *rdatasetit; - dns_rdataset_t rdataset; - dns_rdata_t rdata; -} dns_rriterator_t; - -#define RRITERATOR_MAGIC ISC_MAGIC('R', 'R', 'I', 't') -#define VALID_RRITERATOR(m) ISC_MAGIC_VALID(m, RRITERATOR_MAGIC) - -isc_result_t -dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, - dns_dbversion_t *ver, isc_stdtime_t now); -/*% - * Initialize an rriterator; sets the cursor to the origin node - * of the database. - * - * Requires: - * - * \li 'db' is a valid database. - * - * Returns: - * - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_rriterator_first(dns_rriterator_t *it); -/*%< - * Move the rriterator cursor to the first rdata in the database. - * - * Requires: - *\li 'it' is a valid, initialized rriterator - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE There are no rdata in the set. - */ - -isc_result_t -dns_rriterator_nextrrset(dns_rriterator_t *it); -/*%< - * Move the rriterator cursor to the next rrset in the database, - * skipping over any remaining records that have the same rdatatype - * as the current one. - * - * Requires: - *\li 'it' is a valid, initialized rriterator - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE No more rrsets in the database - */ - -isc_result_t -dns_rriterator_next(dns_rriterator_t *it); -/*%< - * Move the rriterator cursor to the next rrset in the database, - * skipping over any remaining records that have the same rdatatype - * as the current one. - * - * Requires: - *\li 'it' is a valid, initialized rriterator - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE No more records in the database - */ - -void -dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, - uint32_t *ttl, dns_rdataset_t **rdataset, - dns_rdata_t **rdata); -/*%< - * Make '*name' refer to the current name. If 'rdataset' is not NULL, - * make '*rdataset' refer to the current * rdataset. If '*rdata' is not - * NULL, make '*rdata' refer to the current record. - * - * Requires: - *\li '*name' is a valid name object - *\li 'rdataset' is NULL or '*rdataset' is NULL - *\li 'rdata' is NULL or '*rdata' is NULL - * - * Ensures: - *\li 'rdata' refers to the rdata at the rdata cursor location of - *\li 'rdataset'. - */ - -void -dns_rriterator_pause(dns_rriterator_t *it); -/*%< - * Pause rriterator. Frees any locks held by the database iterator. - * Callers should use this routine any time they are not going to - * execute another rriterator method in the immediate future. - * - * Requires: - *\li 'it' is a valid iterator. - * - * Ensures: - *\li Any database locks being held for efficiency of iterator access are - * released. - */ - -void -dns_rriterator_destroy(dns_rriterator_t *it); -/*%< - * Shut down and free resources in rriterator 'it'. - * - * Requires: - * - *\li 'it' is a valid iterator. - * - * Ensures: - * - *\li All resources used by the rriterator are freed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RRITERATOR_H */ diff --git a/lib/dns-pkcs11/include/dns/rrl.h b/lib/dns-pkcs11/include/dns/rrl.h deleted file mode 100644 index 5a65886..0000000 --- a/lib/dns-pkcs11/include/dns/rrl.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RRL_H -#define DNS_RRL_H 1 - -/* - * Rate limit DNS responses. - */ - -#include -#include - -#include - -#include -#include -#include - -ISC_LANG_BEGINDECLS - - -/* - * Memory allocation or other failures. - */ -#define DNS_RRL_LOG_FAIL ISC_LOG_WARNING -/* - * dropped or slipped responses. - */ -#define DNS_RRL_LOG_DROP ISC_LOG_INFO -/* - * Major events in dropping or slipping. - */ -#define DNS_RRL_LOG_DEBUG1 ISC_LOG_DEBUG(3) -/* - * Limit computations. - */ -#define DNS_RRL_LOG_DEBUG2 ISC_LOG_DEBUG(4) -/* - * Even less interesting. - */ -#define DNS_RRL_LOG_DEBUG3 ISC_LOG_DEBUG(9) - - -#define DNS_RRL_LOG_ERR_LEN 64 -#define DNS_RRL_LOG_BUF_LEN (sizeof("would continue limiting") + \ - DNS_RRL_LOG_ERR_LEN + \ - sizeof(" responses to ") + \ - ISC_NETADDR_FORMATSIZE + \ - sizeof("/128 for IN ") + \ - DNS_RDATATYPE_FORMATSIZE + \ - DNS_NAME_FORMATSIZE) - - -typedef struct dns_rrl_hash dns_rrl_hash_t; - -/* - * Response types. - */ -typedef enum { - DNS_RRL_RTYPE_FREE = 0, - DNS_RRL_RTYPE_QUERY, - DNS_RRL_RTYPE_REFERRAL, - DNS_RRL_RTYPE_NODATA, - DNS_RRL_RTYPE_NXDOMAIN, - DNS_RRL_RTYPE_ERROR, - DNS_RRL_RTYPE_ALL, - DNS_RRL_RTYPE_TCP, -} dns_rrl_rtype_t; - -/* - * A rate limit bucket key. - * This should be small to limit the total size of the database. - * The hash of the qname should be wide enough to make the probability - * of collisions among requests from a single IP address block less than 50%. - * We need a 32-bit hash value for 10000 qps (e.g. random qnames forged - * by attacker) to collide with legitimate qnames from the target with - * probability at most 1%. - */ -#define DNS_RRL_MAX_PREFIX 64 -typedef union dns_rrl_key dns_rrl_key_t; -struct dns__rrl_key { - uint32_t ip[DNS_RRL_MAX_PREFIX/32]; - uint32_t qname_hash; - dns_rdatatype_t qtype; - uint8_t qclass; - unsigned int rtype :4; /* dns_rrl_rtype_t */ - unsigned int ipv6 :1; -}; -union dns_rrl_key { - struct dns__rrl_key s; - uint16_t w[sizeof(struct dns__rrl_key)/sizeof(uint16_t)]; -}; - -/* - * A rate-limit entry. - * This should be small to limit the total size of the table of entries. - */ -typedef struct dns_rrl_entry dns_rrl_entry_t; -typedef ISC_LIST(dns_rrl_entry_t) dns_rrl_bin_t; -struct dns_rrl_entry { - ISC_LINK(dns_rrl_entry_t) lru; - ISC_LINK(dns_rrl_entry_t) hlink; - dns_rrl_key_t key; -# define DNS_RRL_RESPONSE_BITS 24 - signed int responses :DNS_RRL_RESPONSE_BITS; -# define DNS_RRL_QNAMES_BITS 8 - unsigned int log_qname :DNS_RRL_QNAMES_BITS; - -# define DNS_RRL_TS_GEN_BITS 2 - unsigned int ts_gen :DNS_RRL_TS_GEN_BITS; - unsigned int ts_valid :1; -# define DNS_RRL_HASH_GEN_BITS 1 - unsigned int hash_gen :DNS_RRL_HASH_GEN_BITS; - unsigned int logged :1; -# define DNS_RRL_LOG_BITS 11 - unsigned int log_secs :DNS_RRL_LOG_BITS; - -# define DNS_RRL_TS_BITS 12 - unsigned int ts :DNS_RRL_TS_BITS; - -# define DNS_RRL_MAX_SLIP 10 - unsigned int slip_cnt :4; -}; - -#define DNS_RRL_MAX_TIME_TRAVEL 5 -#define DNS_RRL_FOREVER (1<= DNS_RRL_MAX_TS -#error "DNS_RRL_MAX_WINDOW is too large" -#endif -#define DNS_RRL_MAX_RATE 1000 -#if DNS_RRL_MAX_RATE >= (DNS_RRL_MAX_RESPONSES / DNS_RRL_MAX_WINDOW) -#error "DNS_RRL_MAX_rate is too large" -#endif - -#if (1<= DNS_RRL_FOREVER -#error DNS_RRL_LOG_BITS is too big -#endif -#define DNS_RRL_MAX_LOG_SECS 1800 -#if DNS_RRL_MAX_LOG_SECS >= (1<= (1< - -#include - -#include -#include - -/*** - *** Types - ***/ - -/*% - * A simple database. This is an opaque type. - */ -typedef struct dns_sdb dns_sdb_t; - -/*% - * A simple database lookup in progress. This is an opaque type. - */ -typedef struct dns_sdblookup dns_sdblookup_t; - -/*% - * A simple database traversal in progress. This is an opaque type. - */ -typedef struct dns_sdballnodes dns_sdballnodes_t; - -typedef isc_result_t -(*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); -typedef isc_result_t -(*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name, - void *dbdata, dns_sdblookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); - -typedef isc_result_t -(*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *); - -typedef isc_result_t -(*dns_sdballnodesfunc_t)(const char *zone, void *dbdata, - dns_sdballnodes_t *allnodes); - -typedef isc_result_t -(*dns_sdbcreatefunc_t)(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata); - -typedef void -(*dns_sdbdestroyfunc_t)(const char *zone, void *driverdata, void **dbdata); - - -typedef struct dns_sdbmethods { - dns_sdblookupfunc_t lookup; - dns_sdbauthorityfunc_t authority; - dns_sdballnodesfunc_t allnodes; - dns_sdbcreatefunc_t create; - dns_sdbdestroyfunc_t destroy; - dns_sdblookup2func_t lookup2; -} dns_sdbmethods_t; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -#define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U -#define DNS_SDBFLAG_RELATIVERDATA 0x00000002U -#define DNS_SDBFLAG_THREADSAFE 0x00000004U -#define DNS_SDBFLAG_DNS64 0x00000008U - -isc_result_t -dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, - void *driverdata, unsigned int flags, isc_mem_t *mctx, - dns_sdbimplementation_t **sdbimp); -/*%< - * Register a simple database driver for the database type 'drivername', - * implemented by the functions in '*methods'. - * - * sdbimp must point to a NULL dns_sdbimplementation_t pointer. That is, - * sdbimp != NULL && *sdbimp == NULL. It will be assigned a value that - * will later be used to identify the driver when deregistering it. - * - * The name server will perform lookups in the database by calling the - * function 'lookup', passing it a printable zone name 'zone', a printable - * domain name 'name', and a copy of the argument 'dbdata' that - * was potentially returned by the create function. The 'dns_sdblookup_t' - * argument to 'lookup' and 'authority' is an opaque pointer to be passed to - * ns_sdb_putrr(). - * - * The lookup function returns the lookup results to the name server - * by calling ns_sdb_putrr() once for each record found. On success, - * the return value of the lookup function should be ISC_R_SUCCESS. - * If the domain name 'name' does not exist, the lookup function should - * ISC_R_NOTFOUND. Any other return value is treated as an error. - * - * Lookups at the zone apex will cause the server to also call the - * function 'authority' (if non-NULL), which must provide an SOA record - * and NS records for the zone by calling ns_sdb_putrr() once for each of - * these records. The 'authority' function may be NULL if invoking - * the 'lookup' function on the zone apex will return SOA and NS records. - * - * The allnodes function, if non-NULL, fills in an opaque structure to be - * used by a database iterator. This allows the zone to be transferred. - * This may use a considerable amount of memory for large zones, and the - * zone transfer may not be fully RFC1035 compliant if the zone is - * frequently changed. - * - * The create function will be called for each zone configured - * into the name server using this database type. It can be used - * to create a "database object" containing zone specific data, - * which can make use of the database arguments specified in the - * name server configuration. - * - * The destroy function will be called to free the database object - * when its zone is destroyed. - * - * The create and destroy functions may be NULL. - * - * If flags includes DNS_SDBFLAG_RELATIVEOWNER, the lookup and authority - * functions will be called with relative names rather than absolute names. - * The string "@" represents the zone apex in this case. - * - * If flags includes DNS_SDBFLAG_RELATIVERDATA, the rdata strings may - * include relative names. Otherwise, all names in the rdata string must - * be absolute. Be aware that if relative names are allowed, any - * absolute names must contain a trailing dot. - * - * If flags includes DNS_SDBFLAG_THREADSAFE, the driver must be able to - * handle multiple lookups in parallel. Otherwise, calls into the driver - * are serialized. - */ - -void -dns_sdb_unregister(dns_sdbimplementation_t **sdbimp); -/*%< - * Removes the simple database driver from the list of registered database - * types. There must be no active databases of this type when this function - * is called. - */ - -/*% See dns_sdb_putradata() */ -isc_result_t -dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, - const char *data); -isc_result_t -dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl, - const unsigned char *rdata, unsigned int rdlen); -/*%< - * Add a single resource record to the lookup structure to be - * returned in the query response. dns_sdb_putrr() takes the - * resource record in master file text format as a null-terminated - * string, and dns_sdb_putrdata() takes the raw RDATA in - * uncompressed wire format. - */ - -/*% See dns_sdb_putnamerdata() */ -isc_result_t -dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, - const char *type, dns_ttl_t ttl, const char *data); -isc_result_t -dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, - dns_rdatatype_t type, dns_ttl_t ttl, - const void *rdata, unsigned int rdlen); -/*%< - * Add a single resource record to the allnodes structure to be - * included in a zone transfer response, in text or wire - * format as above. - */ - -isc_result_t -dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, - uint32_t serial); -/*%< - * This function may optionally be called from the 'authority' callback - * to simplify construction of the SOA record for 'zone'. It will - * provide a SOA listing 'mname' as as the master server and 'rname' as - * the responsible person mailbox. It is the responsibility of the - * driver to increment the serial number between responses if necessary. - * All other SOA fields will have reasonable default values. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_SDB_H */ diff --git a/lib/dns-pkcs11/include/dns/sdlz.h b/lib/dns-pkcs11/include/dns/sdlz.h deleted file mode 100644 index 0318d1b..0000000 --- a/lib/dns-pkcs11/include/dns/sdlz.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. - * - * 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 STICHTING NLNET - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * STICHTING NLNET 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. - * - * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was - * conceived and contributed by Rob Butler. - * - * 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 ROB BUTLER - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * ROB BUTLER 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. - */ - - -/*! \file dns/sdlz.h */ - -#ifndef SDLZ_H -#define SDLZ_H 1 - -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -#define DNS_SDLZFLAG_THREADSAFE 0x00000001U -#define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U -#define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U - - /* A simple DLZ database. */ -typedef struct dns_sdlz_db dns_sdlz_db_t; - - /* A simple DLZ database lookup in progress. */ -typedef struct dns_sdlzlookup dns_sdlzlookup_t; - - /* A simple DLZ database traversal in progress. */ -typedef struct dns_sdlzallnodes dns_sdlzallnodes_t; - -typedef isc_result_t (*dns_sdlzallnodesfunc_t)(const char *zone, - void *driverarg, - void *dbdata, - dns_sdlzallnodes_t *allnodes); -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply an all nodes method. This method is called when the DNS - * server is performing a zone transfer query, after the allow zone - * transfer method has been called. This method is only called if the - * allow zone transfer method returned ISC_R_SUCCESS. This method and - * the allow zone transfer method are both required for zone transfers - * to be supported. If the driver generates data dynamically (instead - * of searching in a database for it) it should not implement this - * function as a zone transfer would be meaningless. A SDLZ driver - * does not have to implement an all nodes method. - */ - -typedef isc_result_t (*dns_sdlzallowzonexfr_t)(void *driverarg, - void *dbdata, const char *name, - const char *client); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply an allow zone transfer method. This method is called when - * the DNS server is performing a zone transfer query, before the all - * nodes method can be called. This method and the all node method - * are both required for zone transfers to be supported. If the - * driver generates data dynamically (instead of searching in a - * database for it) it should not implement this function as a zone - * transfer would be meaningless. A SDLZ driver does not have to - * implement an allow zone transfer method. - * - * This method should return ISC_R_SUCCESS if the zone is supported by - * the database and a zone transfer is allowed for the specified - * client. If the zone is supported by the database, but zone - * transfers are not allowed for the specified client this method - * should return ISC_R_NOPERM.. Lastly the method should return - * ISC_R_NOTFOUND if the zone is not supported by the database. If an - * error occurs it should return a result code indicating the type of - * error. - */ - -typedef isc_result_t (*dns_sdlzauthorityfunc_t)(const char *zone, - void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply an authority method. This method is called when the DNS - * server is performing a query, after both the find zone and lookup - * methods have been called. This method is required if the lookup - * function does not supply authority information for the dns - * record. A SDLZ driver does not have to implement an authority - * method. - */ - -typedef isc_result_t (*dns_sdlzcreate_t)(const char *dlzname, - unsigned int argc, char *argv[], - void *driverarg, void **dbdata); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a create method. This method is called when the DNS server - * is starting up and creating drivers for use later. A SDLZ driver - * does not have to implement a create method. - */ - -typedef void (*dns_sdlzdestroy_t)(void *driverarg, void *dbdata); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a destroy method. This method is called when the DNS server - * is shutting down and no longer needs the driver. A SDLZ driver does - * not have to implement a destroy method. - */ - -typedef isc_result_t -(*dns_sdlzfindzone_t)(void *driverarg, void *dbdata, const char *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); -/*%< - * Method prototype. Drivers implementing the SDLZ interface MUST - * supply a find zone method. This method is called when the DNS - * server is performing a query to to determine if 'name' is a - * supported dns zone. The find zone method will be called with the - * longest possible name first, and continue to be called with - * successively shorter domain names, until any of the following - * occur: - * - * \li 1) the function returns (ISC_R_SUCCESS) indicating a zone name - * match. - * - * \li 2) a problem occurs, and the functions returns anything other than - * (ISC_R_NOTFOUND) - * - * \li 3) we run out of domain name labels. I.E. we have tried the - * shortest domain name - * - * \li 4) the number of labels in the domain name is less than min_labels - * for dns_dlzfindzone - * - * The driver's find zone method should return ISC_R_SUCCESS if the - * zone is supported by the database. Otherwise it should return - * ISC_R_NOTFOUND, if the zone is not supported. If an error occurs - * it should return a result code indicating the type of error. - */ - -typedef isc_result_t -(*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface MUST - * supply a lookup method. This method is called when the - * DNS server is performing a query, after the find zone and before any - * other methods have been called. This function returns DNS record - * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions. - * If this function supplies authority information for the DNS record - * the authority method is not required. If it does not, the - * authority function is required. - * - * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve - * information about the querying client (such as source IP address) - * from the caller. - */ - -typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone, - void *driverarg, void *dbdata, - void **versionp); -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a newversion method. This method is called to start a - * write transaction on a zone and should only be implemented by - * writeable backends. - * When implemented, the driver should create a new transaction, and - * fill *versionp with a pointer to the transaction state. The - * closeversion function will be called to close the transaction. - */ - -typedef void (*dns_sdlzcloseversion_t)(const char *zone, bool commit, - void *driverarg, void *dbdata, - void **versionp); -/*%< - * Method prototype. Drivers implementing the SDLZ interface must - * supply a closeversion method if they supply a newversion method. - * When implemented, the driver should close the given transaction, - * committing changes if 'commit' is true. If 'commit' is not true - * then all changes should be discarded and the database rolled back. - * If the call is successful then *versionp should be set to NULL - */ - -typedef isc_result_t (*dns_sdlzconfigure_t)(dns_view_t *view, - dns_dlzdb_t *dlzdb, - void *driverarg, void *dbdata); -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a configure method. When supplied, it will be called - * immediately after the create method to give the driver a chance - * to configure writeable zones - */ - - -typedef bool (*dns_sdlzssumatch_t)(const char *signer, - const char *name, - const char *tcpaddr, - const char *type, - const char *key, - uint32_t keydatalen, - unsigned char *keydata, - void *driverarg, - void *dbdata); - -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a ssumatch method. If supplied, then ssumatch will be - * called to authorize any zone updates. The driver should return - * true to allow the update, and false to deny it. For a DLZ - * controlled zone, this is the only access control on updates. - */ - - -typedef isc_result_t (*dns_sdlzmodrdataset_t)(const char *name, - const char *rdatastr, - void *driverarg, void *dbdata, - void *version); -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply addrdataset and subtractrdataset methods. If supplied, then these - * will be called when rdatasets are added/subtracted during - * updates. The version parameter comes from a call to the sdlz - * newversion() method from the driver. The rdataset parameter is a - * linearise string representation of the rdataset change. The format - * is the same as used by dig when displaying records. The fields are - * tab delimited. - */ - -typedef isc_result_t (*dns_sdlzdelrdataset_t)(const char *name, - const char *type, - void *driverarg, void *dbdata, - void *version); -/*%< - * Method prototype. Drivers implementing the SDLZ interface may - * supply a delrdataset method. If supplied, then this - * function will be called when rdatasets are deleted during - * updates. The call should remove all rdatasets of the given type for - * the specified name. - */ - -typedef struct dns_sdlzmethods { - dns_sdlzcreate_t create; - dns_sdlzdestroy_t destroy; - dns_sdlzfindzone_t findzone; - dns_sdlzlookupfunc_t lookup; - dns_sdlzauthorityfunc_t authority; - dns_sdlzallnodesfunc_t allnodes; - dns_sdlzallowzonexfr_t allowzonexfr; - dns_sdlznewversion_t newversion; - dns_sdlzcloseversion_t closeversion; - dns_sdlzconfigure_t configure; - dns_sdlzssumatch_t ssumatch; - dns_sdlzmodrdataset_t addrdataset; - dns_sdlzmodrdataset_t subtractrdataset; - dns_sdlzdelrdataset_t delrdataset; -} dns_sdlzmethods_t; - -isc_result_t -dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, - void *driverarg, unsigned int flags, isc_mem_t *mctx, - dns_sdlzimplementation_t **sdlzimp); -/*%< - * Register a dynamically loadable zones (dlz) driver for the database - * type 'drivername', implemented by the functions in '*methods'. - * - * sdlzimp must point to a NULL dns_sdlzimplementation_t pointer. - * That is, sdlzimp != NULL && *sdlzimp == NULL. It will be assigned - * a value that will later be used to identify the driver when - * deregistering it. - */ - -void -dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp); - -/*%< - * Removes the sdlz driver from the list of registered sdlz drivers. - * There must be no active sdlz drivers of this type when this - * function is called. - */ - -typedef isc_result_t dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes, - const char *name, - const char *type, - dns_ttl_t ttl, - const char *data); -dns_sdlz_putnamedrr_t dns_sdlz_putnamedrr; - -/*%< - * Add a single resource record to the allnodes structure to be later - * parsed into a zone transfer response. - */ - -typedef isc_result_t dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup, - const char *type, - dns_ttl_t ttl, - const char *data); -dns_sdlz_putrr_t dns_sdlz_putrr; -/*%< - * Add a single resource record to the lookup structure to be later - * parsed into a query response. - */ - -typedef isc_result_t dns_sdlz_putsoa_t(dns_sdlzlookup_t *lookup, - const char *mname, - const char *rname, - uint32_t serial); -dns_sdlz_putsoa_t dns_sdlz_putsoa; -/*%< - * This function may optionally be called from the 'authority' - * callback to simplify construction of the SOA record for 'zone'. It - * will provide a SOA listing 'mname' as as the master server and - * 'rname' as the responsible person mailbox. It is the - * responsibility of the driver to increment the serial number between - * responses if necessary. All other SOA fields will have reasonable - * default values. - */ - - -typedef isc_result_t dns_sdlz_setdb_t(dns_dlzdb_t *dlzdatabase, - dns_rdataclass_t rdclass, - dns_name_t *name, - dns_db_t **dbp); -dns_sdlz_setdb_t dns_sdlz_setdb; -/*%< - * Create the database pointers for a writeable SDLZ zone - */ - - -ISC_LANG_ENDDECLS - -#endif /* SDLZ_H */ diff --git a/lib/dns-pkcs11/include/dns/secalg.h b/lib/dns-pkcs11/include/dns/secalg.h deleted file mode 100644 index f193855..0000000 --- a/lib/dns-pkcs11/include/dns/secalg.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_SECALG_H -#define DNS_SECALG_H 1 - -/*! \file dns/secalg.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNSSEC security algorithm value. - * The text may contain either a mnemonic algorithm name or a decimal algorithm - * number. - * - * Requires: - *\li 'secalgp' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_RANGE numeric type is out of range - *\li DNS_R_UNKNOWN mnemonic type is unknown - */ - -isc_result_t -dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target); -/*%< - * Put a textual representation of the DNSSEC security algorithm 'secalg' - * into 'target'. - * - * Requires: - *\li 'secalg' is a valid secalg. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - *\li The used space in 'target' is updated. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_NOSPACE target buffer is too small - */ - -#define DNS_SECALG_FORMATSIZE 20 -void -dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size); -/*%< - * Wrapper for dns_secalg_totext(), writing text into 'cp' - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_SECALG_H */ diff --git a/lib/dns-pkcs11/include/dns/secproto.h b/lib/dns-pkcs11/include/dns/secproto.h deleted file mode 100644 index 09f45cf..0000000 --- a/lib/dns-pkcs11/include/dns/secproto.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_SECPROTO_H -#define DNS_SECPROTO_H 1 - -/*! \file dns/secproto.h */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source); -/*%< - * Convert the text 'source' refers to into a DNSSEC security protocol value. - * The text may contain either a mnemonic protocol name or a decimal protocol - * number. - * - * Requires: - *\li 'secprotop' is a valid pointer. - * - *\li 'source' is a valid text region. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_RANGE numeric type is out of range - *\li DNS_R_UNKNOWN mnemonic type is unknown - */ - -isc_result_t -dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target); -/*%< - * Put a textual representation of the DNSSEC security protocol 'secproto' - * into 'target'. - * - * Requires: - *\li 'secproto' is a valid secproto. - * - *\li 'target' is a valid text buffer. - * - * Ensures, - * if the result is success: - * \li The used space in 'target' is updated. - * - * Returns: - *\li ISC_R_SUCCESS on success - *\li ISC_R_NOSPACE target buffer is too small - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_SECPROTO_H */ diff --git a/lib/dns-pkcs11/include/dns/soa.h b/lib/dns-pkcs11/include/dns/soa.h deleted file mode 100644 index cb0f982..0000000 --- a/lib/dns-pkcs11/include/dns/soa.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_SOA_H -#define DNS_SOA_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/soa.h - * \brief - * SOA utilities. - */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -#define DNS_SOA_BUFFERSIZE ((2 * DNS_NAME_MAXWIRE) + (4 * 5)) - -isc_result_t -dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact, - dns_rdataclass_t rdclass, - uint32_t serial, uint32_t refresh, - uint32_t retry, uint32_t expire, - uint32_t minimum, unsigned char *buffer, - dns_rdata_t *rdata); -/*%< - * Build the rdata of an SOA record. - * - * Requires: - *\li buffer Points to a temporary buffer of at least - * DNS_SOA_BUFFERSIZE bytes. - *\li rdata Points to an initialized dns_rdata_t. - * - * Ensures: - * \li *rdata Contains a valid SOA rdata. The 'data' member - * refers to 'buffer'. - */ - -uint32_t -dns_soa_getserial(dns_rdata_t *rdata); -uint32_t -dns_soa_getrefresh(dns_rdata_t *rdata); -uint32_t -dns_soa_getretry(dns_rdata_t *rdata); -uint32_t -dns_soa_getexpire(dns_rdata_t *rdata); -uint32_t -dns_soa_getminimum(dns_rdata_t *rdata); -/* - * Extract an integer field from the rdata of a SOA record. - * - * Requires: - * rdata refers to the rdata of a well-formed SOA record. - */ - -void -dns_soa_setserial(uint32_t val, dns_rdata_t *rdata); -void -dns_soa_setrefresh(uint32_t val, dns_rdata_t *rdata); -void -dns_soa_setretry(uint32_t val, dns_rdata_t *rdata); -void -dns_soa_setexpire(uint32_t val, dns_rdata_t *rdata); -void -dns_soa_setminimum(uint32_t val, dns_rdata_t *rdata); -/* - * Change an integer field of a SOA record by modifying the - * rdata in-place. - * - * Requires: - * rdata refers to the rdata of a well-formed SOA record. - */ - - -ISC_LANG_ENDDECLS - -#endif /* DNS_SOA_H */ diff --git a/lib/dns-pkcs11/include/dns/ssu.h b/lib/dns-pkcs11/include/dns/ssu.h deleted file mode 100644 index 74faf47..0000000 --- a/lib/dns-pkcs11/include/dns/ssu.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_SSU_H -#define DNS_SSU_H 1 - -/*! \file dns/ssu.h */ - -#include - -#include - -#include -#include -#include - -ISC_LANG_BEGINDECLS - -typedef enum { - dns_ssumatchtype_name = 0, - dns_ssumatchtype_subdomain = 1, - dns_ssumatchtype_wildcard = 2, - dns_ssumatchtype_self = 3, - dns_ssumatchtype_selfsub = 4, - dns_ssumatchtype_selfwild = 5, - dns_ssumatchtype_selfkrb5 = 6, - dns_ssumatchtype_selfms = 7, - dns_ssumatchtype_subdomainms = 8, - dns_ssumatchtype_subdomainkrb5 = 9, - dns_ssumatchtype_tcpself = 10, - dns_ssumatchtype_6to4self = 11, - dns_ssumatchtype_external = 12, - dns_ssumatchtype_local = 13, - dns_ssumatchtype_selfsubms = 14, - dns_ssumatchtype_selfsubkrb5 = 15, - dns_ssumatchtype_max = 15, /* max value */ - - dns_ssumatchtype_dlz = 16 /* intentionally higher than _max */ -} dns_ssumatchtype_t; - -#define DNS_SSUMATCHTYPE_NAME dns_ssumatchtype_name -#define DNS_SSUMATCHTYPE_SUBDOMAIN dns_ssumatchtype_subdomain -#define DNS_SSUMATCHTYPE_WILDCARD dns_ssumatchtype_wildcard -#define DNS_SSUMATCHTYPE_SELF dns_ssumatchtype_self -#define DNS_SSUMATCHTYPE_SELFSUB dns_ssumatchtype_selfsub -#define DNS_SSUMATCHTYPE_SELFWILD dns_ssumatchtype_selfwild -#define DNS_SSUMATCHTYPE_SELFKRB5 dns_ssumatchtype_selfkrb5 -#define DNS_SSUMATCHTYPE_SELFMS dns_ssumatchtype_selfms -#define DNS_SSUMATCHTYPE_SUBDOMAINMS dns_ssumatchtype_subdomainms -#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 dns_ssumatchtype_subdomainkrb5 -#define DNS_SSUMATCHTYPE_TCPSELF dns_ssumatchtype_tcpself -#define DNS_SSUMATCHTYPE_6TO4SELF dns_ssumatchtype_6to4self -#define DNS_SSUMATCHTYPE_EXTERNAL dns_ssumatchtype_external -#define DNS_SSUMATCHTYPE_LOCAL dns_ssumatchtype_local -#define DNS_SSUMATCHTYPE_MAX dns_ssumatchtype_max /* max value */ - -#define DNS_SSUMATCHTYPE_DLZ dns_ssumatchtype_dlz /* intentionally higher than _MAX */ - -isc_result_t -dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table); -/*%< - * Creates a table that will be used to store simple-secure-update rules. - * Note: all locking must be provided by the client. - * - * Requires: - *\li 'mctx' is a valid memory context - *\li 'table' is not NULL, and '*table' is NULL - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -isc_result_t -dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, - dns_dlzdb_t *dlzdatabase); -/*%< - * Create an SSU table that contains a dlzdatabase pointer, and a - * single rule with matchtype DNS_SSUMATCHTYPE_DLZ. This type of SSU - * table is used by writeable DLZ drivers to offload authorization for - * updates to the driver. - */ - -void -dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp); -/*%< - * Attach '*targetp' to 'source'. - * - * Requires: - *\li 'source' is a valid SSU table - *\li 'targetp' points to a NULL dns_ssutable_t *. - * - * Ensures: - *\li *targetp is attached to source. - */ - -void -dns_ssutable_detach(dns_ssutable_t **tablep); -/*%< - * Detach '*tablep' from its simple-secure-update rule table. - * - * Requires: - *\li 'tablep' points to a valid dns_ssutable_t - * - * Ensures: - *\li *tablep is NULL - *\li If '*tablep' is the last reference to the SSU table, all - * resources used by the table will be freed. - */ - -isc_result_t -dns_ssutable_addrule(dns_ssutable_t *table, bool grant, - dns_name_t *identity, unsigned int matchtype, - dns_name_t *name, unsigned int ntypes, - dns_rdatatype_t *types); -/*%< - * Adds a new rule to a simple-secure-update rule table. The rule - * either grants or denies update privileges of an identity (or set of - * identities) to modify a name (or set of names) or certain types present - * at that name. - * - * Notes: - *\li If 'matchtype' is of SELF type, this rule only matches if the - * name to be updated matches the signing identity. - * - *\li If 'ntypes' is 0, this rule applies to all types except - * NS, SOA, RRSIG, and NSEC. - * - *\li If 'types' includes ANY, this rule applies to all types - * except NSEC. - * - * Requires: - *\li 'table' is a valid SSU table - *\li 'identity' is a valid absolute name - *\li 'matchtype' must be one of the defined constants. - *\li 'name' is a valid absolute name - *\li If 'ntypes' > 0, 'types' must not be NULL - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -bool -dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *addr, - dns_rdatatype_t type, const dst_key_t *key); -bool -dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *addr, - bool tcp, const dns_aclenv_t *env, - dns_rdatatype_t type, const dst_key_t *key); -/*%< - * Checks that the attempted update of (name, type) is allowed according - * to the rules specified in the simple-secure-update rule table. If - * no rules are matched, access is denied. - * - * Notes: - * In dns_ssutable_checkrules(), 'addr' should only be - * set if the request received via TCP. This provides a - * weak assurance that the request was not spoofed. - * 'addr' is to to validate DNS_SSUMATCHTYPE_TCPSELF - * and DNS_SSUMATCHTYPE_6TO4SELF rules. - * - * In dns_ssutable_checkrules2(), 'addr' can also be passed for - * UDP requests and TCP is specified via the 'tcp' parameter. - * In addition to DNS_SSUMATCHTYPE_TCPSELF and - * tcp_ssumatchtype_6to4self rules, the address - * also be used to check DNS_SSUMATCHTYPE_LOCAL rules. - * If 'addr' is set then 'env' must also be set so that - * requests from non-localhost addresses can be rejected. - * - * For DNS_SSUMATCHTYPE_TCPSELF the addresses are mapped to - * the standard reverse names under IN-ADDR.ARPA and IP6.ARPA. - * RFC 1035, Section 3.5, "IN-ADDR.ARPA domain" and RFC 3596, - * Section 2.5, "IP6.ARPA Domain". - * - * For DNS_SSUMATCHTYPE_6TO4SELF, IPv4 address are converted - * to a 6to4 prefix (48 bits) per the rules in RFC 3056. Only - * the top 48 bits of the IPv6 address are mapped to the reverse - * name. This is independent of whether the most significant 16 - * bits match 2002::/16, assigned for 6to4 prefixes, or not. - * - * Requires: - *\li 'table' is a valid SSU table - *\li 'signer' is NULL or a valid absolute name - *\li 'addr' is NULL or a valid network address. - *\li 'aclenv' is NULL or a valid ACL environment. - *\li 'name' is a valid absolute name - *\li if 'addr' is not NULL, 'env' is not NULL. - */ - - -/*% Accessor functions to extract rule components */ -bool dns_ssurule_isgrant(const dns_ssurule_t *rule); -/*% Accessor functions to extract rule components */ -dns_name_t * dns_ssurule_identity(const dns_ssurule_t *rule); -/*% Accessor functions to extract rule components */ -unsigned int dns_ssurule_matchtype(const dns_ssurule_t *rule); -/*% Accessor functions to extract rule components */ -dns_name_t * dns_ssurule_name(const dns_ssurule_t *rule); -/*% Accessor functions to extract rule components */ -unsigned int dns_ssurule_types(const dns_ssurule_t *rule, - dns_rdatatype_t **types); - -isc_result_t dns_ssutable_firstrule(const dns_ssutable_t *table, - dns_ssurule_t **rule); -/*%< - * Initiates a rule iterator. There is no need to maintain any state. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE - */ - -isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule, - dns_ssurule_t **nextrule); -/*%< - * Returns the next rule in the table. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMORE - */ - -bool -dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *tcpaddr, - dns_rdatatype_t type, const dst_key_t *key, - isc_mem_t *mctx); -/*%< - * Check a policy rule via an external application - */ - -isc_result_t -dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype); -/*%< - * Set 'mtype' from 'str' - * - * Requires: - *\li 'str' is not NULL. - *\li 'mtype' is not NULL, - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOTFOUND - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_SSU_H */ diff --git a/lib/dns-pkcs11/include/dns/stats.h b/lib/dns-pkcs11/include/dns/stats.h deleted file mode 100644 index bcfb878..0000000 --- a/lib/dns-pkcs11/include/dns/stats.h +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_STATS_H -#define DNS_STATS_H 1 - -/*! \file dns/stats.h */ - -#include - -#include - -/*% - * Statistics counters. Used as isc_statscounter_t values. - */ -enum { - /*% - * Resolver statistics counters. - */ - dns_resstatscounter_queryv4 = 0, - dns_resstatscounter_queryv6 = 1, - dns_resstatscounter_responsev4 = 2, - dns_resstatscounter_responsev6 = 3, - dns_resstatscounter_nxdomain = 4, - dns_resstatscounter_servfail = 5, - dns_resstatscounter_formerr = 6, - dns_resstatscounter_othererror = 7, - dns_resstatscounter_edns0fail = 8, - dns_resstatscounter_mismatch = 9, - dns_resstatscounter_truncated = 10, - dns_resstatscounter_lame = 11, - dns_resstatscounter_retry = 12, - dns_resstatscounter_gluefetchv4 = 13, - dns_resstatscounter_gluefetchv6 = 14, - dns_resstatscounter_gluefetchv4fail = 15, - dns_resstatscounter_gluefetchv6fail = 16, - dns_resstatscounter_val = 17, - dns_resstatscounter_valsuccess = 18, - dns_resstatscounter_valnegsuccess = 19, - dns_resstatscounter_valfail = 20, - dns_resstatscounter_dispabort = 21, - dns_resstatscounter_dispsockfail = 22, - dns_resstatscounter_querytimeout = 23, - dns_resstatscounter_queryrtt0 = 24, - dns_resstatscounter_queryrtt1 = 25, - dns_resstatscounter_queryrtt2 = 26, - dns_resstatscounter_queryrtt3 = 27, - dns_resstatscounter_queryrtt4 = 28, - dns_resstatscounter_queryrtt5 = 29, - dns_resstatscounter_nfetch = 30, - dns_resstatscounter_disprequdp = 31, - dns_resstatscounter_dispreqtcp = 32, - dns_resstatscounter_buckets = 33, - dns_resstatscounter_refused = 34, - dns_resstatscounter_cookienew = 35, - dns_resstatscounter_cookieout = 36, - dns_resstatscounter_cookiein = 37, - dns_resstatscounter_cookieok = 38, - dns_resstatscounter_badvers = 39, - dns_resstatscounter_badcookie = 40, - dns_resstatscounter_zonequota = 41, - dns_resstatscounter_serverquota = 42, - dns_resstatscounter_nextitem = 43, - dns_resstatscounter_max = 44, - - /* - * DNSSEC stats. - */ - dns_dnssecstats_asis = 0, - dns_dnssecstats_downcase = 1, - dns_dnssecstats_wildcard = 2, - dns_dnssecstats_fail = 3, - - dns_dnssecstats_max = 4, - - /*% - * Zone statistics counters. - */ - dns_zonestatscounter_notifyoutv4 = 0, - dns_zonestatscounter_notifyoutv6 = 1, - dns_zonestatscounter_notifyinv4 = 2, - dns_zonestatscounter_notifyinv6 = 3, - dns_zonestatscounter_notifyrej = 4, - dns_zonestatscounter_soaoutv4 = 5, - dns_zonestatscounter_soaoutv6 = 6, - dns_zonestatscounter_axfrreqv4 = 7, - dns_zonestatscounter_axfrreqv6 = 8, - dns_zonestatscounter_ixfrreqv4 = 9, - dns_zonestatscounter_ixfrreqv6 = 10, - dns_zonestatscounter_xfrsuccess = 11, - dns_zonestatscounter_xfrfail = 12, - - dns_zonestatscounter_max = 13, - - /* - * Adb statistics values. - */ - dns_adbstats_nentries = 0, - dns_adbstats_entriescnt = 1, - dns_adbstats_nnames = 2, - dns_adbstats_namescnt = 3, - - dns_adbstats_max = 4, - - /* - * Cache statistics values. - */ - dns_cachestatscounter_hits = 1, - dns_cachestatscounter_misses = 2, - dns_cachestatscounter_queryhits = 3, - dns_cachestatscounter_querymisses = 4, - dns_cachestatscounter_deletelru = 5, - dns_cachestatscounter_deletettl = 6, - - dns_cachestatscounter_max = 7, - - /*% - * Query statistics counters (obsolete). - */ - dns_statscounter_success = 0, /*%< Successful lookup */ - dns_statscounter_referral = 1, /*%< Referral result */ - dns_statscounter_nxrrset = 2, /*%< NXRRSET result */ - dns_statscounter_nxdomain = 3, /*%< NXDOMAIN result */ - dns_statscounter_recursion = 4, /*%< Recursion was used */ - dns_statscounter_failure = 5, /*%< Some other failure */ - dns_statscounter_duplicate = 6, /*%< Duplicate query */ - dns_statscounter_dropped = 7, /*%< Duplicate query (dropped) */ - - /*% - * DNSTAP statistics counters. - */ - dns_dnstapcounter_success = 0, - dns_dnstapcounter_drop = 1, - dns_dnstapcounter_max = 2 -}; - -#define DNS_STATS_NCOUNTERS 8 - -#if 0 -/*%< - * Flag(s) for dns_xxxstats_dump(). DNS_STATSDUMP_VERBOSE is obsolete. - * ISC_STATSDUMP_VERBOSE should be used instead. These two values are - * intentionally defined to be the same value to ensure binary compatibility. - */ -#define DNS_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */ -#endif - -/*%< - * (Obsoleted) - */ -LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[]; - -/*% - * Attributes for statistics counters of RRset and Rdatatype types. - * - * _OTHERTYPE - * The rdata type is not explicitly supported and the corresponding counter - * is counted for other such types, too. When this attribute is set, - * the base type is of no use. - * - * _NXRRSET - * RRset type counters only. Indicates the RRset is non existent. - * - * _NXDOMAIN - * RRset type counters only. Indicates a non existent name. When this - * attribute is set, the base type is of no use. - * - * _STALE - * RRset type counters only. This indicates a record that marked for - * removal. - * - * Note: incrementing _STALE will decrement the corresponding non-stale - * counter. - */ -#define DNS_RDATASTATSTYPE_ATTR_OTHERTYPE 0x0001 -#define DNS_RDATASTATSTYPE_ATTR_NXRRSET 0x0002 -#define DNS_RDATASTATSTYPE_ATTR_NXDOMAIN 0x0004 -#define DNS_RDATASTATSTYPE_ATTR_STALE 0x0008 - -/*%< - * Conversion macros among dns_rdatatype_t, attributes and isc_statscounter_t. - */ -#define DNS_RDATASTATSTYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF)) -#define DNS_RDATASTATSTYPE_ATTR(type) ((type) >> 16) -#define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b)) - -/*%< - * Types of dump callbacks. - */ -typedef void (*dns_generalstats_dumper_t)(isc_statscounter_t, uint64_t, - void *); -typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, uint64_t, - void *); -typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, uint64_t, void *); - -typedef void (*dns_rcodestats_dumper_t)(dns_rcode_t, uint64_t, void *); - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters); -/*%< - * Create a statistics counter structure of general type. It counts a general - * set of counters indexed by an ID between 0 and ncounters -1. - * This function is obsolete. A more general function, isc_stats_create(), - * should be used. - * - * Requires: - *\li 'mctx' must be a valid memory context. - * - *\li 'statsp' != NULL && '*statsp' == NULL. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - -isc_result_t -dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp); -/*%< - * Create a statistics counter structure per rdatatype. - * - * Requires: - *\li 'mctx' must be a valid memory context. - * - *\li 'statsp' != NULL && '*statsp' == NULL. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - -isc_result_t -dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp); -/*%< - * Create a statistics counter structure per RRset. - * - * Requires: - *\li 'mctx' must be a valid memory context. - * - *\li 'statsp' != NULL && '*statsp' == NULL. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - -isc_result_t -dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp); -/*%< - * Create a statistics counter structure per opcode. - * - * Requires: - *\li 'mctx' must be a valid memory context. - * - *\li 'statsp' != NULL && '*statsp' == NULL. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - -isc_result_t -dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp); -/*%< - * Create a statistics counter structure per assigned rcode. - * - * Requires: - *\li 'mctx' must be a valid memory context. - * - *\li 'statsp' != NULL && '*statsp' == NULL. - * - * Returns: - *\li ISC_R_SUCCESS -- all ok - * - *\li anything else -- failure - */ - -void -dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp); -/*%< - * Attach to a statistics set. - * - * Requires: - *\li 'stats' is a valid dns_stats_t. - * - *\li 'statsp' != NULL && '*statsp' == NULL - */ - -void -dns_stats_detach(dns_stats_t **statsp); -/*%< - * Detaches from the statistics set. - * - * Requires: - *\li 'statsp' != NULL and '*statsp' is a valid dns_stats_t. - */ - -void -dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter); -/*%< - * Increment the counter-th counter of stats. This function is obsolete. - * A more general function, isc_stats_increment(), should be used. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - * - *\li counter is less than the maximum available ID for the stats specified - * on creation. - */ - -void -dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type); -/*%< - * Increment the statistics counter for 'type'. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_rdatatypestats_create(). - */ - -void -dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype); -/*%< - * Increment the statistics counter for 'rrsettype'. - * - * Note: if 'rrsettype' has the _STALE attribute set the corresponding - * non-stale counter will be decremented. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create(). - */ - -void -dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype); -/*%< - * Decrement the statistics counter for 'rrsettype'. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create(). - */ - -void -dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code); -/*%< - * Increment the statistics counter for 'code'. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_opcodestats_create(). - */ - -void -dns_rcodestats_increment(dns_stats_t *stats, dns_opcode_t code); -/*%< - * Increment the statistics counter for 'code'. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_rcodestats_create(). - */ - -void -dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn, - void *arg, unsigned int options); -/*%< - * Dump the current statistics counters in a specified way. For each counter - * in stats, dump_fn is called with its current value and the given argument - * arg. By default counters that have a value of 0 is skipped; if options has - * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. - * - * This function is obsolete. A more general function, isc_stats_dump(), - * should be used. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - */ - -void -dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, - void *arg, unsigned int options); -/*%< - * Dump the current statistics counters in a specified way. For each counter - * in stats, dump_fn is called with the corresponding type in the form of - * dns_rdatastatstype_t, the current counter value and the given argument - * arg. By default counters that have a value of 0 is skipped; if options has - * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - */ - -void -dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, - void *arg, unsigned int options); -/*%< - * Dump the current statistics counters in a specified way. For each counter - * in stats, dump_fn is called with the corresponding type in the form of - * dns_rdatastatstype_t, the current counter value and the given argument - * arg. By default counters that have a value of 0 is skipped; if options has - * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - */ - -void -dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn, - void *arg, unsigned int options); -/*%< - * Dump the current statistics counters in a specified way. For each counter - * in stats, dump_fn is called with the corresponding opcode, the current - * counter value and the given argument arg. By default counters that have a - * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even - * such counters are dumped. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - */ - -void -dns_rcodestats_dump(dns_stats_t *stats, dns_rcodestats_dumper_t dump_fn, - void *arg, unsigned int options); -/*%< - * Dump the current statistics counters in a specified way. For each counter - * in stats, dump_fn is called with the corresponding rcode, the current - * counter value and the given argument arg. By default counters that have a - * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even - * such counters are dumped. - * - * Requires: - *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). - */ - -isc_result_t -dns_stats_alloccounters(isc_mem_t *mctx, uint64_t **ctrp); -/*%< - * Allocate an array of query statistics counters from the memory - * context 'mctx'. - * - * This function is obsoleted. Use dns_xxxstats_create() instead. - */ - -void -dns_stats_freecounters(isc_mem_t *mctx, uint64_t **ctrp); -/*%< - * Free an array of query statistics counters allocated from the memory - * context 'mctx'. - * - * This function is obsoleted. Use dns_stats_destroy() instead. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_STATS_H */ diff --git a/lib/dns-pkcs11/include/dns/tcpmsg.h b/lib/dns-pkcs11/include/dns/tcpmsg.h deleted file mode 100644 index eb3f5c2..0000000 --- a/lib/dns-pkcs11/include/dns/tcpmsg.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TCPMSG_H -#define DNS_TCPMSG_H 1 - -/*! \file dns/tcpmsg.h */ - -#include - -#include -#include -#include - -typedef struct dns_tcpmsg { - /* private (don't touch!) */ - unsigned int magic; - uint16_t size; - isc_buffer_t buffer; - unsigned int maxsize; - isc_mem_t *mctx; - isc_socket_t *sock; - isc_task_t *task; - isc_taskaction_t action; - void *arg; - isc_event_t event; - /* public (read-only) */ - isc_result_t result; - isc_sockaddr_t address; -} dns_tcpmsg_t; - -ISC_LANG_BEGINDECLS - -void -dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg); -/*%< - * Associate a tcp message state with a given memory context and - * TCP socket. - * - * Requires: - * - *\li "mctx" and "sock" be non-NULL and valid types. - * - *\li "sock" be a read/write TCP socket. - * - *\li "tcpmsg" be non-NULL and an uninitialized or invalidated structure. - * - * Ensures: - * - *\li "tcpmsg" is a valid structure. - */ - -void -dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize); -/*%< - * Set the maximum packet size to "maxsize" - * - * Requires: - * - *\li "tcpmsg" be valid. - * - *\li 512 <= "maxsize" <= 65536 - */ - -isc_result_t -dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, - isc_task_t *task, isc_taskaction_t action, void *arg); -/*%< - * Schedule an event to be delivered when a DNS message is readable, or - * when an error occurs on the socket. - * - * Requires: - * - *\li "tcpmsg" be valid. - * - *\li "task", "taskaction", and "arg" be valid. - * - * Returns: - * - *\li ISC_R_SUCCESS -- no error - *\li Anything that the isc_socket_recv() call can return. XXXMLG - * - * Notes: - * - *\li The event delivered is a fully generic event. It will contain no - * actual data. The sender will be a pointer to the dns_tcpmsg_t. - * The result code inside that structure should be checked to see - * what the final result was. - */ - -void -dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg); -/*%< - * Cancel a readmessage() call. The event will still be posted with a - * CANCELED result code. - * - * Requires: - * - *\li "tcpmsg" be valid. - */ - -void -dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer); -/*%< - * If a dns buffer is to be kept between calls, this function marks the - * internal state-machine buffer as invalid, and copies all the contents - * of the state into "buffer". - * - * Requires: - * - *\li "tcpmsg" be valid. - * - *\li "buffer" be non-NULL. - */ - -void -dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg); -/*%< - * Clean up all allocated state, and invalidate the structure. - * - * Requires: - * - *\li "tcpmsg" be valid. - * - * Ensures: - * - *\li "tcpmsg" is invalidated and disassociated with all memory contexts, - * sockets, etc. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TCPMSG_H */ diff --git a/lib/dns-pkcs11/include/dns/time.h b/lib/dns-pkcs11/include/dns/time.h deleted file mode 100644 index 2e533d6..0000000 --- a/lib/dns-pkcs11/include/dns/time.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TIME_H -#define DNS_TIME_H 1 - -/*! \file dns/time.h */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_time64_fromtext(const char *source, int64_t *target); -/*%< - * Convert a date and time in YYYYMMDDHHMMSS text format at 'source' - * into to a 64-bit count of seconds since Jan 1 1970 0:00 GMT. - * Store the count at 'target'. - */ - -isc_result_t -dns_time32_fromtext(const char *source, uint32_t *target); -/*%< - * Like dns_time64_fromtext, but returns the second count modulo 2^32 - * as per RFC2535. - */ - - -isc_result_t -dns_time64_totext(int64_t value, isc_buffer_t *target); -/*%< - * Convert a 64-bit count of seconds since Jan 1 1970 0:00 GMT into - * a YYYYMMDDHHMMSS text representation and append it to 'target'. - */ - -isc_result_t -dns_time32_totext(uint32_t value, isc_buffer_t *target); -/*%< - * Like dns_time64_totext, but for a 32-bit cyclic time value. - * Of those dates whose counts of seconds since Jan 1 1970 0:00 GMT - * are congruent with 'value' modulo 2^32, the one closest to the - * current date is chosen. - */ - -int64_t -dns_time64_from32(uint32_t value); -/*%< - * Covert a 32-bit cyclic time value into a 64 bit time stamp. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TIME_H */ diff --git a/lib/dns-pkcs11/include/dns/timer.h b/lib/dns-pkcs11/include/dns/timer.h deleted file mode 100644 index 04781b4..0000000 --- a/lib/dns-pkcs11/include/dns/timer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TIMER_H -#define DNS_TIMER_H 1 - -/*! \file dns/timer.h */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime, - unsigned int idletime, bool purge); -/*%< - * Convenience function for setting up simple, one-second-granularity - * idle timers as used by zone transfers. - * \brief - * Set the timer 'timer' to go off after 'idletime' seconds of inactivity, - * or after 'maxtime' at the very latest. Events are purged iff - * 'purge' is true. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TIMER_H */ diff --git a/lib/dns-pkcs11/include/dns/tkey.h b/lib/dns-pkcs11/include/dns/tkey.h deleted file mode 100644 index c316e80..0000000 --- a/lib/dns-pkcs11/include/dns/tkey.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TKEY_H -#define DNS_TKEY_H 1 - -/*! \file dns/tkey.h */ - -#include -#include - -#include - -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/* Key agreement modes */ -#define DNS_TKEYMODE_SERVERASSIGNED 1 -#define DNS_TKEYMODE_DIFFIEHELLMAN 2 -#define DNS_TKEYMODE_GSSAPI 3 -#define DNS_TKEYMODE_RESOLVERASSIGNED 4 -#define DNS_TKEYMODE_DELETE 5 - -struct dns_tkeyctx { - dst_key_t *dhkey; - dns_name_t *domain; - gss_cred_id_t gsscred; - isc_mem_t *mctx; - isc_entropy_t *ectx; - char *gssapi_keytab; -}; - -isc_result_t -dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, - dns_tkeyctx_t **tctxp); -/*%< - * Create an empty TKEY context. - * - * Requires: - *\li 'mctx' is not NULL - *\li 'tctx' is not NULL - *\li '*tctx' is NULL - * - * Returns - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li return codes from dns_name_fromtext() - */ - -void -dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp); -/*%< - * Frees all data associated with the TKEY context - * - * Requires: - *\li 'tctx' is not NULL - *\li '*tctx' is not NULL - */ - -isc_result_t -dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, - dns_tsig_keyring_t *ring); -/*%< - * Processes a query containing a TKEY record, adding or deleting TSIG - * keys if necessary, and modifies the message to contain the response. - * - * Requires: - *\li 'msg' is a valid message - *\li 'tctx' is a valid TKEY context - *\li 'ring' is a valid TSIG keyring - * - * Returns - *\li #ISC_R_SUCCESS msg was updated (the TKEY operation succeeded, - * or msg now includes a TKEY with an error set) - * DNS_R_FORMERR the packet was malformed (missing a TKEY - * or KEY). - *\li other An error occurred while processing the message - */ - -isc_result_t -dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, - dns_name_t *algorithm, isc_buffer_t *nonce, - uint32_t lifetime); -/*%< - * Builds a query containing a TKEY that will generate a shared - * secret using a Diffie-Hellman key exchange. The shared key - * will be of the specified algorithm (only DNS_TSIG_HMACMD5_NAME - * is supported), and will be named either 'name', - * 'name' + server chosen domain, or random data + server chosen domain - * if 'name' == dns_rootname. If nonce is not NULL, it supplies - * random data used in the shared secret computation. The key is - * requested to have the specified lifetime (in seconds) - * - * - * Requires: - *\li 'msg' is a valid message - *\li 'key' is a valid Diffie Hellman dst key - *\li 'name' is a valid name - *\li 'algorithm' is a valid name - * - * Returns: - *\li #ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - *\li other an error occurred while building the message - */ - -isc_result_t -dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname, - isc_buffer_t *intoken, uint32_t lifetime, - gss_ctx_id_t *context, bool win2k, - isc_mem_t *mctx, char **err_message); -/*%< - * Builds a query containing a TKEY that will generate a GSSAPI context. - * The key is requested to have the specified lifetime (in seconds). - * - * Requires: - *\li 'msg' is a valid message - *\li 'name' is a valid name - *\li 'gname' is a valid name - *\li 'context' is a pointer to a valid gss_ctx_id_t - * (which may have the value GSS_C_NO_CONTEXT) - *\li 'win2k' when true says to turn on some hacks to work - * with the non-standard GSS-TSIG of Windows 2000 - * - * Returns: - *\li ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - *\li other an error occurred while building the message - *\li *err_message optional error message - */ - - -isc_result_t -dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key); -/*%< - * Builds a query containing a TKEY record that will delete the - * specified shared secret from the server. - * - * Requires: - *\li 'msg' is a valid message - *\li 'key' is a valid TSIG key - * - * Returns: - *\li #ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - *\li other an error occurred while building the message - */ - -isc_result_t -dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg, - dst_key_t *key, isc_buffer_t *nonce, - dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring); -/*%< - * Processes a response to a query containing a TKEY that was - * designed to generate a shared secret using a Diffie-Hellman key - * exchange. If the query was successful, a new shared key - * is created and added to the list of shared keys. - * - * Requires: - *\li 'qmsg' is a valid message (the query) - *\li 'rmsg' is a valid message (the response) - *\li 'key' is a valid Diffie Hellman dst key - *\li 'outkey' is either NULL or a pointer to NULL - *\li 'ring' is a valid keyring or NULL - * - * Returns: - *\li #ISC_R_SUCCESS the shared key was successfully added - *\li #ISC_R_NOTFOUND an error occurred while looking for a - * component of the query or response - */ - -isc_result_t -dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg, - dns_name_t *gname, gss_ctx_id_t *context, - isc_buffer_t *outtoken, dns_tsigkey_t **outkey, - dns_tsig_keyring_t *ring, char **err_message); -/*%< - * XXX - */ - -isc_result_t -dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg, - dns_tsig_keyring_t *ring); -/*%< - * Processes a response to a query containing a TKEY that was - * designed to delete a shared secret. If the query was successful, - * the shared key is deleted from the list of shared keys. - * - * Requires: - *\li 'qmsg' is a valid message (the query) - *\li 'rmsg' is a valid message (the response) - *\li 'ring' is not NULL - * - * Returns: - *\li #ISC_R_SUCCESS the shared key was successfully deleted - *\li #ISC_R_NOTFOUND an error occurred while looking for a - * component of the query or response - */ - -isc_result_t -dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, - dns_name_t *server, gss_ctx_id_t *context, - dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, - bool win2k, char **err_message); - -/* - * Client side negotiation of GSS-TSIG. Process the response - * to a TKEY, and establish a TSIG key if negotiation was successful. - * Build a response to the input TKEY message. Can take multiple - * calls to successfully establish the context. - * - * Requires: - * 'qmsg' is a valid message, the original TKEY request; - * it will be filled with the new message to send - * 'rmsg' is a valid message, the incoming TKEY message - * 'server' is the server name - * 'context' is the input context handle - * 'outkey' receives the established key, if non-NULL; - * if non-NULL must point to NULL - * 'ring' is the keyring in which to establish the key, - * or NULL - * 'win2k' when true says to turn on some hacks to work - * with the non-standard GSS-TSIG of Windows 2000 - * - * Returns: - * ISC_R_SUCCESS context was successfully established - * ISC_R_NOTFOUND couldn't find a needed part of the query - * or response - * DNS_R_CONTINUE additional context negotiation is required; - * send the new qmsg to the server - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TKEY_H */ diff --git a/lib/dns-pkcs11/include/dns/tsec.h b/lib/dns-pkcs11/include/dns/tsec.h deleted file mode 100644 index 4f27ba3..0000000 --- a/lib/dns-pkcs11/include/dns/tsec.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TSEC_H -#define DNS_TSEC_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * - * \brief - * The TSEC (Transaction Security) module is an abstraction layer for managing - * DNS transaction mechanisms such as TSIG or SIG(0). A TSEC structure is a - * mechanism-independent object containing key information specific to the - * mechanism, and is expected to be used as an argument to other modules - * that use transaction security in a mechanism-independent manner. - * - * MP: - *\li A TSEC structure is expected to be thread-specific. No inter-thread - * synchronization is ensured in multiple access to a single TSEC - * structure. - * - * Resources: - *\li TBS - * - * Security: - *\li This module does not handle any low-level data directly, and so no - * security issue specific to this module is anticipated. - */ - -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -/*% - * Transaction security types. - */ -typedef enum { - dns_tsectype_none, - dns_tsectype_tsig, - dns_tsectype_sig0 -} dns_tsectype_t; - -isc_result_t -dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key, - dns_tsec_t **tsecp); -/*%< - * Create a TSEC structure and stores a type-dependent key structure in it. - * For a TSIG key (type is dns_tsectype_tsig), dns_tsec_create() creates a - * TSIG key structure from '*key' and keeps it in the structure. For other - * types, this function simply retains '*key' in the structure. In either - * case, the ownership of '*key' is transferred to the TSEC module; the caller - * must not modify or destroy it after the call to dns_tsec_create(). - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li 'type' is a valid value of dns_tsectype_t (see above). - * - *\li 'key' is a valid key. - * - *\li tsecp != NULL && *tsecp == NULL. - * - * Returns: - * - *\li #ISC_R_SUCCESS On success. - * - *\li Anything else Failure. - */ - -void -dns_tsec_destroy(dns_tsec_t **tsecp); -/*%< - * Destroy the TSEC structure. The stored key is also detached or destroyed. - * - * Requires - * - *\li '*tsecp' is a valid TSEC structure. - * - * Ensures - * - *\li *tsecp == NULL. - * - */ - -dns_tsectype_t -dns_tsec_gettype(dns_tsec_t *tsec); -/*%< - * Return the TSEC type of '*tsec'. - * - * Requires - * - *\li 'tsec' is a valid TSEC structure. - * - */ - -void -dns_tsec_getkey(dns_tsec_t *tsec, void *keyp); -/*%< - * Return the TSEC key of '*tsec' in '*keyp'. - * - * Requires - * - *\li keyp != NULL - * - * Ensures - * - *\li *tsecp points to a valid key structure depending on the TSEC type. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TSEC_H */ diff --git a/lib/dns-pkcs11/include/dns/tsig.h b/lib/dns-pkcs11/include/dns/tsig.h deleted file mode 100644 index 4c05be4..0000000 --- a/lib/dns-pkcs11/include/dns/tsig.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TSIG_H -#define DNS_TSIG_H 1 - -/*! \file dns/tsig.h */ - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -/* - * Algorithms. - */ -#ifndef PK11_MD5_DISABLE -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacmd5_name; -#define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name -#endif -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name; -#define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name; -#define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name; -#define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name; -#define DNS_TSIG_HMACSHA224_NAME dns_tsig_hmacsha224_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name; -#define DNS_TSIG_HMACSHA256_NAME dns_tsig_hmacsha256_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name; -#define DNS_TSIG_HMACSHA384_NAME dns_tsig_hmacsha384_name -LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name; -#define DNS_TSIG_HMACSHA512_NAME dns_tsig_hmacsha512_name - -/*% - * Default fudge value. - */ -#define DNS_TSIG_FUDGE 300 - -struct dns_tsig_keyring { - dns_rbt_t *keys; - unsigned int writecount; - isc_rwlock_t lock; - isc_mem_t *mctx; - /* - * LRU list of generated key along with a count of the keys on the - * list and a maximum size. - */ - unsigned int generated; - unsigned int maxgenerated; - ISC_LIST(dns_tsigkey_t) lru; - unsigned int references; -}; - -struct dns_tsigkey { - /* Unlocked */ - unsigned int magic; /*%< Magic number. */ - isc_mem_t *mctx; - dst_key_t *key; /*%< Key */ - dns_name_t name; /*%< Key name */ - dns_name_t *algorithm; /*%< Algorithm name */ - dns_name_t *creator; /*%< name that created secret */ - bool generated; /*%< was this generated? */ - isc_stdtime_t inception; /*%< start of validity period */ - isc_stdtime_t expire; /*%< end of validity period */ - dns_tsig_keyring_t *ring; /*%< the enclosing keyring */ - isc_refcount_t refs; /*%< reference counter */ - ISC_LINK(dns_tsigkey_t) link; -}; - -ISC_LANG_BEGINDECLS - -const dns_name_t * -dns_tsigkey_identity(const dns_tsigkey_t *tsigkey); -/*%< - * Returns the identity of the provided TSIG key. - * - * Requires: - *\li 'tsigkey' is a valid TSIG key or NULL - * - * Returns: - *\li NULL if 'tsigkey' was NULL - *\li identity of the provided TSIG key - */ - -isc_result_t -dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm, - unsigned char *secret, int length, bool generated, - dns_name_t *creator, isc_stdtime_t inception, - isc_stdtime_t expire, isc_mem_t *mctx, - dns_tsig_keyring_t *ring, dns_tsigkey_t **key); - -isc_result_t -dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, - dst_key_t *dstkey, bool generated, - dns_name_t *creator, isc_stdtime_t inception, - isc_stdtime_t expire, isc_mem_t *mctx, - dns_tsig_keyring_t *ring, dns_tsigkey_t **key); -/*%< - * Creates a tsig key structure and saves it in the keyring. If key is - * not NULL, *key will contain a copy of the key. The keys validity - * period is specified by (inception, expire), and will not expire if - * inception == expire. If the key was generated, the creating identity, - * if there is one, should be in the creator parameter. Specifying an - * unimplemented algorithm will cause failure only if dstkey != NULL; this - * allows a transient key with an invalid algorithm to exist long enough - * to generate a BADKEY response. - * - * If dns_tsigkey_createfromkey is successful a new reference to 'dstkey' - * will have been made. - * - * Requires: - *\li 'name' is a valid dns_name_t - *\li 'algorithm' is a valid dns_name_t - *\li 'secret' is a valid pointer - *\li 'length' is an integer >= 0 - *\li 'dstkey' is a valid dst key or NULL - *\li 'creator' points to a valid dns_name_t or is NULL - *\li 'mctx' is a valid memory context - *\li 'ring' is a valid TSIG keyring or NULL - *\li 'key' or '*key' must be NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_EXISTS - a key with this name already exists - *\li #ISC_R_NOTIMPLEMENTED - algorithm is not implemented - *\li #ISC_R_NOMEMORY - */ - -void -dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp); -/*%< - * Attach '*targetp' to 'source'. - * - * Requires: - *\li 'key' is a valid TSIG key - * - * Ensures: - *\li *targetp is attached to source. - */ - -void -dns_tsigkey_detach(dns_tsigkey_t **keyp); -/*%< - * Detaches from the tsig key structure pointed to by '*key'. - * - * Requires: - *\li 'keyp' is not NULL and '*keyp' is a valid TSIG key - * - * Ensures: - *\li 'keyp' points to NULL - */ - -void -dns_tsigkey_setdeleted(dns_tsigkey_t *key); -/*%< - * Prevents this key from being used again. It will be deleted when - * no references exist. - * - * Requires: - *\li 'key' is a valid TSIG key on a keyring - */ - -isc_result_t -dns_tsig_sign(dns_message_t *msg); -/*%< - * Generates a TSIG record for this message - * - * Requires: - *\li 'msg' is a valid message - *\li 'msg->tsigkey' is a valid TSIG key - *\li 'msg->tsig' is NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_NOSPACE - *\li #DNS_R_EXPECTEDTSIG - * - this is a response & msg->querytsig is NULL - */ - -isc_result_t -dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, - dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2); -/*%< - * Verifies the TSIG record in this message - * - * Requires: - *\li 'source' is a valid buffer containing the unparsed message - *\li 'msg' is a valid message - *\li 'msg->tsigkey' is a valid TSIG key if this is a response - *\li 'msg->tsig' is NULL - *\li 'msg->querytsig' is not NULL if this is a response - *\li 'ring1' and 'ring2' are each either a valid keyring or NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen - *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - *\li #DNS_R_TSIGERRORSET - the TSIG verified but ->error was set - * and this is a query - *\li #DNS_R_CLOCKSKEW - the TSIG failed to verify because of - * the time was out of the allowed range. - *\li #DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify - *\li #DNS_R_EXPECTEDRESPONSE - the message was set over TCP and - * should have been a response, - * but was not. - */ - -isc_result_t -dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, - dns_name_t *algorithm, dns_tsig_keyring_t *ring); -/*%< - * Returns the TSIG key corresponding to this name and (possibly) - * algorithm. Also increments the key's reference counter. - * - * Requires: - *\li 'tsigkey' is not NULL - *\li '*tsigkey' is NULL - *\li 'name' is a valid dns_name_t - *\li 'algorithm' is a valid dns_name_t or NULL - *\li 'ring' is a valid keyring - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOTFOUND - */ - - -isc_result_t -dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/*%< - * Create an empty TSIG key ring. - * - * Requires: - *\li 'mctx' is not NULL - *\li 'ringp' is not NULL, and '*ringp' is NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name, - dns_tsigkey_t *tkey); -/*%< - * Place a TSIG key onto a key ring. - * - * Requires: - *\li 'ring', 'name' and 'tkey' are not NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li Any other value indicates failure. - */ - - -void -dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target); - -void -dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp); - -isc_result_t -dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp); - -/*%< - * Destroy a TSIG key ring. - * - * Requires: - *\li 'ringp' is not NULL - */ - -void -dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp); - -ISC_LANG_ENDDECLS - -#endif /* DNS_TSIG_H */ diff --git a/lib/dns-pkcs11/include/dns/ttl.h b/lib/dns-pkcs11/include/dns/ttl.h deleted file mode 100644 index d4d59ac..0000000 --- a/lib/dns-pkcs11/include/dns/ttl.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_TTL_H -#define DNS_TTL_H 1 - -/*! \file dns/ttl.h */ - -/*** - *** Imports - ***/ - -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_ttl_totext(uint32_t src, bool verbose, - isc_buffer_t *target); -isc_result_t -dns_ttl_totext2(uint32_t src, bool verbose, - bool upcase, isc_buffer_t *target); -/*%< - * Output a TTL or other time interval in a human-readable form. - * The time interval is given as a count of seconds in 'src'. - * The text representation is appended to 'target'. - * - * If 'verbose' is false, use the terse BIND 8 style, like "1w2d3h4m5s". - * - * If 'verbose' is true, use a verbose style like the SOA comments - * in "dig", like "1 week 2 days 3 hours 4 minutes 5 seconds". - * - * If 'upcase' is true, we conform to the BIND 8 style in which - * the unit letter is capitalized if there is only a single unit - * letter to print (for example, "1m30s", but "2M") - * - * If 'upcase' is false, unit letters are always in lower case. - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOSPACE - */ - -isc_result_t -dns_counter_fromtext(isc_textregion_t *source, uint32_t *ttl); -/*%< - * Converts a counter from either a plain number or a BIND 8 style value. - * - * Returns: - *\li ISC_R_SUCCESS - *\li DNS_R_SYNTAX - */ - -isc_result_t -dns_ttl_fromtext(isc_textregion_t *source, uint32_t *ttl); -/*%< - * Converts a ttl from either a plain number or a BIND 8 style value. - * - * Returns: - *\li ISC_R_SUCCESS - *\li DNS_R_BADTTL - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_TTL_H */ diff --git a/lib/dns-pkcs11/include/dns/types.h b/lib/dns-pkcs11/include/dns/types.h deleted file mode 100644 index 934a641..0000000 --- a/lib/dns-pkcs11/include/dns/types.h +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_TYPES_H -#define DNS_TYPES_H 1 - -/*! \file dns/types.h - * \brief - * Including this file gives you type declarations suitable for use in - * .h files, which lets us avoid circular type reference problems. - * \brief - * To actually use a type or get declarations of its methods, you must - * include the appropriate .h file too. - */ - -#include -#include -#include - -#include - -typedef struct dns_acache dns_acache_t; -typedef struct dns_acacheentry dns_acacheentry_t; -typedef struct dns_acachestats dns_acachestats_t; -typedef struct dns_acl dns_acl_t; -typedef struct dns_aclelement dns_aclelement_t; -typedef struct dns_aclenv dns_aclenv_t; -typedef struct dns_adb dns_adb_t; -typedef struct dns_adbaddrinfo dns_adbaddrinfo_t; -typedef ISC_LIST(dns_adbaddrinfo_t) dns_adbaddrinfolist_t; -typedef struct dns_adbentry dns_adbentry_t; -typedef struct dns_adbfind dns_adbfind_t; -typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t; -typedef struct dns_badcache dns_badcache_t; -typedef struct dns_byaddr dns_byaddr_t; -typedef struct dns_catz_zonemodmethods dns_catz_zonemodmethods_t; -typedef struct dns_catz_entry_options dns_catz_options_t; -typedef struct dns_catz_entry dns_catz_entry_t; -typedef struct dns_catz_zone dns_catz_zone_t; -typedef struct dns_catz_changed dns_catz_changed_t; -typedef struct dns_catz_zones dns_catz_zones_t; -typedef struct dns_client dns_client_t; -typedef void dns_clientrestrans_t; -typedef void dns_clientreqtrans_t; -typedef void dns_clientupdatetrans_t; -typedef struct dns_cache dns_cache_t; -typedef uint16_t dns_cert_t; -typedef struct dns_compress dns_compress_t; -typedef struct dns_db dns_db_t; -typedef struct dns_dbimplementation dns_dbimplementation_t; -typedef struct dns_dbiterator dns_dbiterator_t; -typedef void dns_dbload_t; -typedef void dns_dbnode_t; -typedef struct dns_dbonupdatelistener dns_dbonupdatelistener_t; -typedef struct dns_dbtable dns_dbtable_t; -typedef void dns_dbversion_t; -typedef struct dns_dlzimplementation dns_dlzimplementation_t; -typedef struct dns_dlzdb dns_dlzdb_t; -typedef ISC_LIST(dns_dlzdb_t) dns_dlzdblist_t; -typedef struct dns_dyndbctx dns_dyndbctx_t; -typedef struct dns_sdlzimplementation dns_sdlzimplementation_t; -typedef struct dns_decompress dns_decompress_t; -typedef struct dns_dispatch dns_dispatch_t; -typedef struct dns_dispatchevent dns_dispatchevent_t; -typedef struct dns_dispatchlist dns_dispatchlist_t; -typedef struct dns_dispatchset dns_dispatchset_t; -typedef struct dns_dispatchmgr dns_dispatchmgr_t; -typedef struct dns_dispentry dns_dispentry_t; -typedef struct dns_dns64 dns_dns64_t; -typedef ISC_LIST(dns_dns64_t) dns_dns64list_t; -typedef struct dns_dnsseckey dns_dnsseckey_t; -typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t; -typedef uint8_t dns_dsdigest_t; -typedef struct dns_dtdata dns_dtdata_t; -typedef struct dns_dtenv dns_dtenv_t; -typedef struct dns_dtmsg dns_dtmsg_t; -typedef uint16_t dns_dtmsgtype_t; -typedef struct dns_dumpctx dns_dumpctx_t; -typedef struct dns_ednsopt dns_ednsopt_t; -typedef struct dns_fetch dns_fetch_t; -typedef struct dns_fixedname dns_fixedname_t; -typedef struct dns_forwarders dns_forwarders_t; -typedef struct dns_forwarder dns_forwarder_t; -typedef struct dns_fwdtable dns_fwdtable_t; -typedef struct dns_geoip_databases dns_geoip_databases_t; -typedef struct dns_iptable dns_iptable_t; -typedef uint32_t dns_iterations_t; -typedef uint16_t dns_keyflags_t; -typedef struct dns_keynode dns_keynode_t; -typedef ISC_LIST(dns_keynode_t) dns_keynodelist_t; -typedef struct dns_keytable dns_keytable_t; -typedef uint16_t dns_keytag_t; -typedef struct dns_loadctx dns_loadctx_t; -typedef struct dns_loadmgr dns_loadmgr_t; -typedef struct dns_masterrawheader dns_masterrawheader_t; -typedef uint64_t dns_masterstyle_flags_t; -typedef struct dns_message dns_message_t; -typedef uint16_t dns_messageid_t; -typedef isc_region_t dns_label_t; -typedef struct dns_lookup dns_lookup_t; -typedef struct dns_name dns_name_t; -typedef ISC_LIST(dns_name_t) dns_namelist_t; -typedef struct dns_nta dns_nta_t; -typedef struct dns_ntatable dns_ntatable_t; -typedef uint16_t dns_opcode_t; -typedef unsigned char dns_offsets_t[128]; -typedef struct dns_order dns_order_t; -typedef struct dns_peer dns_peer_t; -typedef struct dns_peerlist dns_peerlist_t; -typedef struct dns_portlist dns_portlist_t; -typedef struct dns_rbt dns_rbt_t; -typedef uint16_t dns_rcode_t; -typedef struct dns_rdata dns_rdata_t; -typedef struct dns_rdatacallbacks dns_rdatacallbacks_t; -typedef uint16_t dns_rdataclass_t; -typedef struct dns_rdatalist dns_rdatalist_t; -typedef struct dns_rdataset dns_rdataset_t; -typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t; -typedef struct dns_rdatasetiter dns_rdatasetiter_t; -typedef uint16_t dns_rdatatype_t; -typedef struct dns_request dns_request_t; -typedef struct dns_requestmgr dns_requestmgr_t; -typedef struct dns_resolver dns_resolver_t; -typedef struct dns_sdbimplementation dns_sdbimplementation_t; -typedef uint8_t dns_secalg_t; -typedef uint8_t dns_secproto_t; -typedef struct dns_signature dns_signature_t; -typedef struct dns_ssurule dns_ssurule_t; -typedef struct dns_ssutable dns_ssutable_t; -typedef struct dns_stats dns_stats_t; -typedef uint32_t dns_rdatastatstype_t; -typedef struct dns_tkeyctx dns_tkeyctx_t; -typedef uint16_t dns_trust_t; -typedef struct dns_tsec dns_tsec_t; -typedef struct dns_tsig_keyring dns_tsig_keyring_t; -typedef struct dns_tsigkey dns_tsigkey_t; -typedef uint32_t dns_ttl_t; -typedef struct dns_update_state dns_update_state_t; -typedef struct dns_validator dns_validator_t; -typedef struct dns_view dns_view_t; -typedef ISC_LIST(dns_view_t) dns_viewlist_t; -typedef struct dns_zone dns_zone_t; -typedef ISC_LIST(dns_zone_t) dns_zonelist_t; -typedef struct dns_zonemgr dns_zonemgr_t; -typedef struct dns_zt dns_zt_t; -typedef struct dns_ipkeylist dns_ipkeylist_t; - -/* - * If we are not using GSSAPI, define the types we use as opaque types here. - */ -#ifndef GSSAPI -typedef struct not_defined_gss_cred_id *gss_cred_id_t; -typedef struct not_defined_gss_ctx *gss_ctx_id_t; -#endif -typedef struct dst_gssapi_signverifyctx dst_gssapi_signverifyctx_t; - -typedef enum { - dns_hash_sha1 = 1 -} dns_hash_t; - -typedef enum { - dns_fwdpolicy_none = 0, - dns_fwdpolicy_first = 1, - dns_fwdpolicy_only = 2 -} dns_fwdpolicy_t; - -typedef enum { - dns_namereln_none = 0, - dns_namereln_contains = 1, - dns_namereln_subdomain = 2, - dns_namereln_equal = 3, - dns_namereln_commonancestor = 4 -} dns_namereln_t; - -typedef enum { - dns_one_answer, dns_many_answers -} dns_transfer_format_t; - -typedef enum { - dns_dbtype_zone = 0, dns_dbtype_cache = 1, dns_dbtype_stub = 3 -} dns_dbtype_t; - -typedef enum { - dns_notifytype_no = 0, - dns_notifytype_yes = 1, - dns_notifytype_explicit = 2, - dns_notifytype_masteronly = 3 -} dns_notifytype_t; - -typedef enum { - dns_minimal_no = 0, - dns_minimal_yes = 1, - dns_minimal_noauth = 2, - dns_minimal_noauthrec = 3 -} dns_minimaltype_t; - -typedef enum { - dns_dialuptype_no = 0, - dns_dialuptype_yes = 1, - dns_dialuptype_notify = 2, - dns_dialuptype_notifypassive = 3, - dns_dialuptype_refresh = 4, - dns_dialuptype_passive = 5 -} dns_dialuptype_t; - -typedef enum { - dns_masterformat_none = 0, - dns_masterformat_text = 1, - dns_masterformat_raw = 2, - dns_masterformat_map = 3 -} dns_masterformat_t; - -typedef enum { - dns_aaaa_ok = 0, - dns_aaaa_filter = 1, - dns_aaaa_break_dnssec = 2 -} dns_aaaa_t; - -/* - * These are generated by gen.c. - */ -#include /* Provides dns_rdatatype_t. */ -#include /* Provides dns_rdataclass_t. */ - -/*% - * rcodes. - */ -enum { - /* - * Standard rcodes. - */ - dns_rcode_noerror = 0, -#define dns_rcode_noerror ((dns_rcode_t)dns_rcode_noerror) - dns_rcode_formerr = 1, -#define dns_rcode_formerr ((dns_rcode_t)dns_rcode_formerr) - dns_rcode_servfail = 2, -#define dns_rcode_servfail ((dns_rcode_t)dns_rcode_servfail) - dns_rcode_nxdomain = 3, -#define dns_rcode_nxdomain ((dns_rcode_t)dns_rcode_nxdomain) - dns_rcode_notimp = 4, -#define dns_rcode_notimp ((dns_rcode_t)dns_rcode_notimp) - dns_rcode_refused = 5, -#define dns_rcode_refused ((dns_rcode_t)dns_rcode_refused) - dns_rcode_yxdomain = 6, -#define dns_rcode_yxdomain ((dns_rcode_t)dns_rcode_yxdomain) - dns_rcode_yxrrset = 7, -#define dns_rcode_yxrrset ((dns_rcode_t)dns_rcode_yxrrset) - dns_rcode_nxrrset = 8, -#define dns_rcode_nxrrset ((dns_rcode_t)dns_rcode_nxrrset) - dns_rcode_notauth = 9, -#define dns_rcode_notauth ((dns_rcode_t)dns_rcode_notauth) - dns_rcode_notzone = 10, -#define dns_rcode_notzone ((dns_rcode_t)dns_rcode_notzone) - /* - * Extended rcodes. - */ - dns_rcode_badvers = 16, -#define dns_rcode_badvers ((dns_rcode_t)dns_rcode_badvers) - dns_rcode_badcookie = 23 -#define dns_rcode_badcookie ((dns_rcode_t)dns_rcode_badcookie) - /* - * Update dns_rcodestats_create() and dns_rcodestats_increment() - * and this comment if a rcode > dns_rcode_badcookie is assigned. - */ - /* Private space [3841..4095] */ -}; - -/*% - * TSIG errors. - */ -enum { - dns_tsigerror_badsig = 16, - dns_tsigerror_badkey = 17, - dns_tsigerror_badtime = 18, - dns_tsigerror_badmode = 19, - dns_tsigerror_badname = 20, - dns_tsigerror_badalg = 21, - dns_tsigerror_badtrunc = 22 -}; - -/*% - * Opcodes. - */ -enum { - dns_opcode_query = 0, -#define dns_opcode_query ((dns_opcode_t)dns_opcode_query) - dns_opcode_iquery = 1, -#define dns_opcode_iquery ((dns_opcode_t)dns_opcode_iquery) - dns_opcode_status = 2, -#define dns_opcode_status ((dns_opcode_t)dns_opcode_status) - dns_opcode_notify = 4, -#define dns_opcode_notify ((dns_opcode_t)dns_opcode_notify) - dns_opcode_update = 5 /* dynamic update */ -#define dns_opcode_update ((dns_opcode_t)dns_opcode_update) -}; - -/*% - * Trust levels. Must be kept in sync with trustnames[] in masterdump.c. - */ -enum { - /* Sentinel value; no data should have this trust level. */ - dns_trust_none = 0, -#define dns_trust_none ((dns_trust_t)dns_trust_none) - - /*% - * Subject to DNSSEC validation but has not yet been validated - * dns_trust_pending_additional (from the additional section). - */ - dns_trust_pending_additional = 1, -#define dns_trust_pending_additional \ - ((dns_trust_t)dns_trust_pending_additional) - - dns_trust_pending_answer = 2, -#define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer) - - /*% Received in the additional section of a response. */ - dns_trust_additional = 3, -#define dns_trust_additional ((dns_trust_t)dns_trust_additional) - - /* Received in a referral response. */ - dns_trust_glue = 4, -#define dns_trust_glue ((dns_trust_t)dns_trust_glue) - - /* Answer from a non-authoritative server */ - dns_trust_answer = 5, -#define dns_trust_answer ((dns_trust_t)dns_trust_answer) - - /* Received in the authority section as part of an - authoritative response */ - dns_trust_authauthority = 6, -#define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority) - - /* Answer from an authoritative server */ - dns_trust_authanswer = 7, -#define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer) - - /* Successfully DNSSEC validated */ - dns_trust_secure = 8, -#define dns_trust_secure ((dns_trust_t)dns_trust_secure) - - /* This server is authoritative */ - dns_trust_ultimate = 9 -#define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate) -}; - -#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \ - (x) == dns_trust_pending_additional) -#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \ - (x) == dns_trust_pending_additional) -#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) -#define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer) - - -/*% - * Name checking severities. - */ -typedef enum { - dns_severity_ignore, - dns_severity_warn, - dns_severity_fail -} dns_severity_t; - -/*% - * DNS Serial Number Update Method. - * - * \li _none: Keep the current serial. - * \li _increment: Add one to the current serial, skipping 0. - * \li _unixtime: Set to the seconds since 00:00 Jan 1, 1970, - * if possible. - * \li _date: Set to today's date in YYYYMMDDVV format: - * (Year, Month, Day, Version) - */ -typedef enum { - dns_updatemethod_none = 0, - dns_updatemethod_increment, - dns_updatemethod_unixtime, - dns_updatemethod_date -} dns_updatemethod_t; - -typedef struct { - const char *string; - size_t count; -} dns_indent_t; - -typedef enum { - dns_stale_answer_no, - dns_stale_answer_yes, - dns_stale_answer_conf -} dns_stale_answer_t; - -/* - * Functions. - */ -typedef void -(*dns_dumpdonefunc_t)(void *, isc_result_t); - -typedef void -(*dns_loaddonefunc_t)(void *, isc_result_t); - -typedef void -(*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *); - -typedef isc_result_t -(*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *); - -typedef isc_result_t -(*dns_additionaldatafunc_t)(void *, dns_name_t *, dns_rdatatype_t); - -typedef isc_result_t -(*dns_digestfunc_t)(void *, isc_region_t *); - -typedef void -(*dns_xfrindone_t)(dns_zone_t *, isc_result_t); - -typedef void -(*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *); - -typedef int -(*dns_rdatasetorderfunc_t)(const dns_rdata_t *, const void *); - -typedef bool -(*dns_checkmxfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); - -typedef bool -(*dns_checksrvfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); - -typedef bool -(*dns_checknsfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *, - dns_rdataset_t *, dns_rdataset_t *); - -typedef bool -(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *, - isc_sockaddr_t *, dns_rdataclass_t, void *); - -typedef isc_result_t -(*dns_deserializefunc_t)(void *, FILE *, off_t); - -typedef void -(*dns_nseclog_t)(void *val, int , const char *, ...); - -#endif /* DNS_TYPES_H */ diff --git a/lib/dns-pkcs11/include/dns/update.h b/lib/dns-pkcs11/include/dns/update.h deleted file mode 100644 index 436b9e2..0000000 --- a/lib/dns-pkcs11/include/dns/update.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_UPDATE_H -#define DNS_UPDATE_H 1 - -/*! \file dns/update.h */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include -#include - -typedef struct { - void (*func)(void *arg, dns_zone_t *zone, int level, - const char *message); - void *arg; -} dns_update_log_t; - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -uint32_t -dns_update_soaserial(uint32_t serial, dns_updatemethod_t method); -/*%< - * Return the next serial number after 'serial', depending on the - * update method 'method': - * - *\li * dns_updatemethod_increment increments the serial number by one - *\li * dns_updatemethod_unixtime sets the serial number to the current - * time (seconds since UNIX epoch) if possible, or increments by one - * if not. - */ - -isc_result_t -dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *oldver, dns_dbversion_t *newver, - dns_diff_t *diff, uint32_t sigvalidityinterval); - -isc_result_t -dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *oldver, dns_dbversion_t *newver, - dns_diff_t *diff, uint32_t sigvalidityinterval, - dns_update_state_t **state); - -ISC_LANG_ENDDECLS - -#endif /* DNS_UPDATE_H */ diff --git a/lib/dns-pkcs11/include/dns/validator.h b/lib/dns-pkcs11/include/dns/validator.h deleted file mode 100644 index cc4478d..0000000 --- a/lib/dns-pkcs11/include/dns/validator.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_VALIDATOR_H -#define DNS_VALIDATOR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/validator.h - * - * \brief - * DNS Validator - * This is the BIND 9 validator, the module responsible for validating the - * rdatasets and negative responses (messages). It makes use of zones in - * the view and may fetch RRset to complete trust chains. It implements - * DNSSEC as specified in RFC 4033, 4034 and 4035. - * - * It can also optionally implement ISC's DNSSEC look-aside validation. - * - * Correct operation is critical to preventing spoofed answers from secure - * zones being accepted. - * - * MP: - *\li The module ensures appropriate synchronization of data structures it - * creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li RFCs: 1034, 1035, 2181, 4033, 4034, 4035. - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include /* for dns_rdata_rrsig_t */ - -#include - -/*% - * A dns_validatorevent_t is sent when a 'validation' completes. - * \brief - * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were - * supplied when dns_validator_create() was called. They are returned to the - * caller so that they may be freed. - * - * If the RESULT is ISC_R_SUCCESS and the answer is secure then - * proofs[] will contain the names of the NSEC records that hold the - * various proofs. Note the same name may appear multiple times. - */ -typedef struct dns_validatorevent { - ISC_EVENT_COMMON(struct dns_validatorevent); - dns_validator_t * validator; - isc_result_t result; - /* - * Name and type of the response to be validated. - */ - dns_name_t * name; - dns_rdatatype_t type; - /* - * Rdata and RRSIG (if any) for positive responses. - */ - dns_rdataset_t * rdataset; - dns_rdataset_t * sigrdataset; - /* - * The full response. Required for negative responses. - * Also required for positive wildcard responses. - */ - dns_message_t * message; - /* - * Proofs to be cached. - */ - dns_name_t * proofs[4]; - /* - * Optout proof seen. - */ - bool optout; - /* - * Answer is secure. - */ - bool secure; -} dns_validatorevent_t; - -#define DNS_VALIDATOR_NOQNAMEPROOF 0 -#define DNS_VALIDATOR_NODATAPROOF 1 -#define DNS_VALIDATOR_NOWILDCARDPROOF 2 -#define DNS_VALIDATOR_CLOSESTENCLOSER 3 - -/*% - * A validator object represents a validation in progress. - * \brief - * Clients are strongly discouraged from using this type directly, with - * the exception of the 'link' field, which may be used directly for - * whatever purpose the client desires. - */ -struct dns_validator { - /* Unlocked. */ - unsigned int magic; - isc_mutex_t lock; - dns_view_t * view; - /* Locked by lock. */ - unsigned int options; - unsigned int attributes; - dns_validatorevent_t * event; - dns_fetch_t * fetch; - dns_validator_t * subvalidator; - dns_validator_t * parent; - dns_keytable_t * keytable; - dns_keynode_t * keynode; - dst_key_t * key; - dns_rdata_rrsig_t * siginfo; - isc_task_t * task; - isc_taskaction_t action; - void * arg; - unsigned int labels; - dns_rdataset_t * currentset; - bool seensig; - dns_rdataset_t * keyset; - dns_rdataset_t * dsset; - dns_rdataset_t * soaset; - dns_rdataset_t * nsecset; - dns_rdataset_t * nsec3set; - dns_name_t * soaname; - dns_rdataset_t frdataset; - dns_rdataset_t fsigrdataset; - dns_fixedname_t fname; - dns_fixedname_t wild; - dns_fixedname_t nearest; - dns_fixedname_t closest; - ISC_LINK(dns_validator_t) link; - dns_rdataset_t dlv; - dns_fixedname_t dlvsep; - bool havedlvsep; - bool mustbesecure; - unsigned int dlvlabels; - unsigned int depth; - unsigned int authcount; - unsigned int authfail; - isc_stdtime_t start; -}; - -/*% - * dns_validator_create() options. - */ -#define DNS_VALIDATOR_DLV 0x0001U -#define DNS_VALIDATOR_DEFER 0x0002U -#define DNS_VALIDATOR_NOCDFLAG 0x0004U -#define DNS_VALIDATOR_NONTA 0x0008U /*% Ignore NTA table */ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_message_t *message, unsigned int options, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_validator_t **validatorp); -/*%< - * Start a DNSSEC validation. - * - * This validates a response to the question given by - * 'name' and 'type'. - * - * To validate a positive response, the response data is - * given by 'rdataset' and 'sigrdataset'. If 'sigrdataset' - * is NULL, the data is presumed insecure and an attempt - * is made to prove its insecurity by finding the appropriate - * null key. - * - * The complete response message may be given in 'message', - * to make available any authority section NSECs that may be - * needed for validation of a response resulting from a - * wildcard expansion (though no such wildcard validation - * is implemented yet). If the complete response message - * is not available, 'message' is NULL. - * - * To validate a negative response, the complete negative response - * message is given in 'message'. The 'rdataset', and - * 'sigrdataset' arguments must be NULL, but the 'name' and 'type' - * arguments must be provided. - * - * The validation is performed in the context of 'view'. - * - * When the validation finishes, a dns_validatorevent_t with - * the given 'action' and 'arg' are sent to 'task'. - * Its 'result' field will be ISC_R_SUCCESS iff the - * response was successfully proven to be either secure or - * part of a known insecure domain. - * - * options: - * If DNS_VALIDATOR_DLV is set the caller knows there is not a - * trusted key and the validator should immediately attempt to validate - * the answer by looking for an appropriate DLV RRset. - */ - -void -dns_validator_send(dns_validator_t *validator); -/*%< - * Send a deferred validation request - * - * Requires: - * 'validator' to points to a valid DNSSEC validator. - */ - -void -dns_validator_cancel(dns_validator_t *validator); -/*%< - * Cancel a DNSSEC validation in progress. - * - * Requires: - *\li 'validator' points to a valid DNSSEC validator, which - * may or may not already have completed. - * - * Ensures: - *\li It the validator has not already sent its completion - * event, it will send it with result code ISC_R_CANCELED. - */ - -void -dns_validator_destroy(dns_validator_t **validatorp); -/*%< - * Destroy a DNSSEC validator. - * - * Requires: - *\li '*validatorp' points to a valid DNSSEC validator. - * \li The validator must have completed and sent its completion - * event. - * - * Ensures: - *\li All resources used by the validator are freed. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_VALIDATOR_H */ diff --git a/lib/dns-pkcs11/include/dns/version.h b/lib/dns-pkcs11/include/dns/version.h deleted file mode 100644 index 9d66a14..0000000 --- a/lib/dns-pkcs11/include/dns/version.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file dns/version.h */ - -#ifndef DNS_VERSION_H -#define DNS_VERSION_H 1 - -#include - -LIBDNS_EXTERNAL_DATA extern const char dns_version[]; -LIBDNS_EXTERNAL_DATA extern const char dns_major[]; -LIBDNS_EXTERNAL_DATA extern const char dns_mapapi[]; - -LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libinterface; -LIBDNS_EXTERNAL_DATA extern const unsigned int dns_librevision; -LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libage; - -#endif /* DNS_VERSION_H */ diff --git a/lib/dns-pkcs11/include/dns/view.h b/lib/dns-pkcs11/include/dns/view.h deleted file mode 100644 index 96148c7..0000000 --- a/lib/dns-pkcs11/include/dns/view.h +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_VIEW_H -#define DNS_VIEW_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/view.h - * \brief - * DNS View - * - * A "view" is a DNS namespace, together with an optional resolver and a - * forwarding policy. A "DNS namespace" is a (possibly empty) set of - * authoritative zones together with an optional cache and optional - * "hints" information. - * - * Views start out "unfrozen". In this state, core attributes like - * the cache, set of zones, and forwarding policy may be set. While - * "unfrozen", the caller (e.g. nameserver configuration loading - * code), must ensure exclusive access to the view. When the view is - * "frozen", the core attributes become immutable, and the view module - * will ensure synchronization. Freezing allows the view's core attributes - * to be accessed without locking. - * - * MP: - *\li Before the view is frozen, the caller must ensure synchronization. - * - *\li After the view is frozen, the module guarantees appropriate - * synchronization of any data structures it creates and manipulates. - * - * Reliability: - *\li No anticipated impact. - * - * Resources: - *\li TBS - * - * Security: - *\li No anticipated impact. - * - * Standards: - *\li None. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -struct dns_view { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - dns_rdataclass_t rdclass; - char * name; - dns_zt_t * zonetable; - dns_resolver_t * resolver; - dns_adb_t * adb; - dns_requestmgr_t * requestmgr; - dns_acache_t * acache; - dns_cache_t * cache; - dns_db_t * cachedb; - dns_db_t * hints; - - /* - * security roots and negative trust anchors. - * internal use only; access via * dns_view_getsecroots() - */ - dns_keytable_t * secroots_priv; - dns_ntatable_t * ntatable_priv; - - isc_mutex_t lock; - bool frozen; - isc_task_t * task; - isc_event_t resevent; - isc_event_t adbevent; - isc_event_t reqevent; - isc_stats_t * adbstats; - isc_stats_t * resstats; - dns_stats_t * resquerystats; - bool cacheshared; - - /* Configurable data. */ - dns_tsig_keyring_t * statickeys; - dns_tsig_keyring_t * dynamickeys; - dns_peerlist_t * peers; - dns_order_t * order; - dns_fwdtable_t * fwdtable; - bool recursion; - bool auth_nxdomain; - bool additionalfromcache; - bool additionalfromauth; - bool minimal_any; - dns_minimaltype_t minimalresponses; - bool enablednssec; - bool enablevalidation; - bool acceptexpired; - bool requireservercookie; - bool trust_anchor_telemetry; - bool root_key_sentinel; - dns_transfer_format_t transfer_format; - dns_acl_t * cacheacl; - dns_acl_t * cacheonacl; - dns_acl_t * queryacl; - dns_acl_t * queryonacl; - dns_acl_t * recursionacl; - dns_acl_t * recursiononacl; - dns_acl_t * sortlist; - dns_acl_t * notifyacl; - dns_acl_t * transferacl; - dns_acl_t * updateacl; - dns_acl_t * upfwdacl; - dns_acl_t * denyansweracl; - dns_acl_t * nocasecompress; - bool msgcompression; - dns_rbt_t * answeracl_exclude; - dns_rbt_t * denyanswernames; - dns_rbt_t * answernames_exclude; - dns_rrl_t * rrl; - bool provideixfr; - bool requestnsid; - bool sendcookie; - dns_ttl_t maxcachettl; - dns_ttl_t maxncachettl; - uint32_t nta_lifetime; - uint32_t nta_recheck; - char *nta_file; - dns_ttl_t prefetch_trigger; - dns_ttl_t prefetch_eligible; - in_port_t dstport; - dns_aclenv_t aclenv; - dns_rdatatype_t preferred_glue; - bool flush; - dns_namelist_t * delonly; - bool rootdelonly; - dns_namelist_t * rootexclude; - bool checknames; - dns_name_t * dlv; - dns_fixedname_t dlv_fixed; - uint16_t maxudp; - uint16_t nocookieudp; - unsigned int maxbits; - dns_aaaa_t v4_aaaa; - dns_aaaa_t v6_aaaa; - dns_acl_t * aaaa_acl; - dns_dns64list_t dns64; - unsigned int dns64cnt; - dns_rpz_zones_t *rpzs; - dns_catz_zones_t *catzs; - dns_dlzdblist_t dlz_searched; - dns_dlzdblist_t dlz_unsearched; - uint32_t fail_ttl; - dns_badcache_t *failcache; - - /* - * Configurable data for server use only, - * locked by server configuration lock. - */ - dns_acl_t * matchclients; - dns_acl_t * matchdestinations; - bool matchrecursiveonly; - - /* Locked by themselves. */ - isc_refcount_t references; - isc_refcount_t weakrefs; - - /* Locked by lock. */ - unsigned int attributes; - /* Under owner's locking control. */ - ISC_LINK(struct dns_view) link; - dns_viewlist_t * viewlist; - - dns_zone_t * managed_keys; - dns_zone_t * redirect; - dns_name_t * redirectzone; /* points to - * redirectfixed - * when valid */ - dns_fixedname_t redirectfixed; - - /* - * File and configuration data for zones added at runtime - * (only used in BIND9). - * - * XXX: This should be a pointer to an opaque type that - * named implements. - */ - char * new_zone_file; - char * new_zone_db; - void * new_zone_dbenv; - uint64_t new_zone_mapsize; - void * new_zone_config; - void (*cfg_destroy)(void **); - isc_mutex_t new_zone_lock; - - unsigned char secret[32]; /* Client secret */ - unsigned int v6bias; - - dns_dtenv_t *dtenv; /* Dnstap environment */ - dns_dtmsgtype_t dttypes; /* Dnstap message types - to log */ - dns_ttl_t staleanswerttl; - dns_stale_answer_t staleanswersok; /* rndc setting */ - bool staleanswersenable; /* named.conf setting */ -}; - -#define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w') -#define DNS_VIEW_VALID(view) ISC_MAGIC_VALID(view, DNS_VIEW_MAGIC) - -#define DNS_VIEWATTR_RESSHUTDOWN 0x01 -#define DNS_VIEWATTR_ADBSHUTDOWN 0x02 -#define DNS_VIEWATTR_REQSHUTDOWN 0x04 - -#ifdef HAVE_LMDB -#include -#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOLOCK) -#ifndef __OpenBSD__ -#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS) -#else /* __OpenBSD__ */ -/* - * OpenBSD does not have a unified buffer cache, which requires both reads and - * writes to be performed using mmap(). - */ -#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS | MDB_WRITEMAP) -#endif /* __OpenBSD__ */ -#endif /* HAVE_LMDB */ - -isc_result_t -dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, - const char *name, dns_view_t **viewp); -/*%< - * Create a view. - * - * Notes: - * - *\li The newly created view has no cache, no resolver, and an empty - * zone table. The view is not frozen. - * - * Requires: - * - *\li 'mctx' is a valid memory context. - * - *\li 'rdclass' is a valid class. - * - *\li 'name' is a valid C string. - * - *\li viewp != NULL && *viewp == NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - * - *\li Other errors are possible. - */ - -void -dns_view_attach(dns_view_t *source, dns_view_t **targetp); -/*%< - * Attach '*targetp' to 'source'. - * - * Requires: - * - *\li 'source' is a valid, frozen view. - * - *\li 'targetp' points to a NULL dns_view_t *. - * - * Ensures: - * - *\li *targetp is attached to source. - * - *\li While *targetp is attached, the view will not shut down. - */ - -void -dns_view_detach(dns_view_t **viewp); -/*%< - * Detach '*viewp' from its view. - * - * Requires: - * - *\li 'viewp' points to a valid dns_view_t * - * - * Ensures: - * - *\li *viewp is NULL. - */ - -void -dns_view_flushanddetach(dns_view_t **viewp); -/*%< - * Detach '*viewp' from its view. If this was the last reference - * uncommitted changed in zones will be flushed to disk. - * - * Requires: - * - *\li 'viewp' points to a valid dns_view_t * - * - * Ensures: - * - *\li *viewp is NULL. - */ - -void -dns_view_weakattach(dns_view_t *source, dns_view_t **targetp); -/*%< - * Weakly attach '*targetp' to 'source'. - * - * Requires: - * - *\li 'source' is a valid, frozen view. - * - *\li 'targetp' points to a NULL dns_view_t *. - * - * Ensures: - * - *\li *targetp is attached to source. - * - * \li While *targetp is attached, the view will not be freed. - */ - -void -dns_view_weakdetach(dns_view_t **targetp); -/*%< - * Detach '*viewp' from its view. - * - * Requires: - * - *\li 'viewp' points to a valid dns_view_t *. - * - * Ensures: - * - *\li *viewp is NULL. - */ - -isc_result_t -dns_view_createzonetable(dns_view_t *view); -/*%< - * Create a zonetable for the view. - * - * Requires: - * - *\li 'view' is a valid, unfrozen view. - * - *\li 'view' does not have a zonetable already. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Any error that dns_zt_create() can return. - */ - -isc_result_t -dns_view_createresolver(dns_view_t *view, - isc_taskmgr_t *taskmgr, - unsigned int ntasks, unsigned int ndisp, - isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, - unsigned int options, - dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, - dns_dispatch_t *dispatchv6); -/*%< - * Create a resolver and address database for the view. - * - * Requires: - * - *\li 'view' is a valid, unfrozen view. - * - *\li 'view' does not have a resolver already. - * - *\li The requirements of dns_resolver_create() apply to 'taskmgr', - * 'ntasks', 'socketmgr', 'timermgr', 'options', 'dispatchv4', and - * 'dispatchv6'. - * - * Returns: - * - *\li #ISC_R_SUCCESS - * - *\li Any error that dns_resolver_create() can return. - */ - -void -dns_view_setcache(dns_view_t *view, dns_cache_t *cache); -void -dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, bool shared); -/*%< - * Set the view's cache database. If 'shared' is true, this means the cache - * is created by another view and is shared with that view. dns_view_setcache() - * is a backward compatible version equivalent to setcache2(..., false). - * - * Requires: - * - *\li 'view' is a valid, unfrozen view. - * - *\li 'cache' is a valid cache. - * - * Ensures: - * - * \li The cache of 'view' is 'cached. - * - *\li If this is not the first call to dns_view_setcache() for this - * view, then previously set cache is detached. - */ - -void -dns_view_sethints(dns_view_t *view, dns_db_t *hints); -/*%< - * Set the view's hints database. - * - * Requires: - * - *\li 'view' is a valid, unfrozen view, whose hints database has not been - * set. - * - *\li 'hints' is a valid zone database. - * - * Ensures: - * - * \li The hints database of 'view' is 'hints'. - */ - -void -dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring); -void -dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring); -/*%< - * Set the view's static TSIG keys - * - * Requires: - * - * \li 'view' is a valid, unfrozen view, whose static TSIG keyring has not - * been set. - * - *\li 'ring' is a valid TSIG keyring - * - * Ensures: - * - *\li The static TSIG keyring of 'view' is 'ring'. - */ - -void -dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp); -/*%< - * Return the views dynamic keys. - * - * \li 'view' is a valid, unfrozen view. - * \li 'ringp' != NULL && ringp == NULL. - */ - -void -dns_view_setdstport(dns_view_t *view, in_port_t dstport); -/*%< - * Set the view's destination port. This is the port to - * which outgoing queries are sent. The default is 53, - * the standard DNS port. - * - * Requires: - * - *\li 'view' is a valid view. - * - *\li 'dstport' is a valid TCP/UDP port number. - * - * Ensures: - *\li External name servers will be assumed to be listening - * on 'dstport'. For servers whose address has already - * obtained obtained at the time of the call, the view may - * continue to use the previously set port until the address - * times out from the view's address database. - */ - - -isc_result_t -dns_view_addzone(dns_view_t *view, dns_zone_t *zone); -/*%< - * Add zone 'zone' to 'view'. - * - * Requires: - * - *\li 'view' is a valid, unfrozen view. - * - *\li 'zone' is a valid zone. - */ - -void -dns_view_freeze(dns_view_t *view); -/*%< - * Freeze view. No changes can be made to view configuration while frozen. - * - * Requires: - * - *\li 'view' is a valid, unfrozen view. - * - * Ensures: - * - *\li 'view' is frozen. - */ - -void -dns_view_thaw(dns_view_t *view); -/*%< - * Thaw view. This allows zones to be added or removed at runtime. This is - * NOT thread-safe; the caller MUST have run isc_task_exclusive() prior to - * thawing the view. - * - * Requires: - * - *\li 'view' is a valid, frozen view. - * - * Ensures: - * - *\li 'view' is no longer frozen. - */ -isc_result_t -dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, - isc_stdtime_t now, unsigned int options, bool use_hints, - dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -isc_result_t -dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, - isc_stdtime_t now, unsigned int options, - bool use_hints, bool use_static_stub, - dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/*%< - * Find an rdataset whose owner name is 'name', and whose type is - * 'type'. - * In general, this function first searches view's zone and cache DBs for the - * best match data against 'name'. If nothing found there, and if 'use_hints' - * is true, the view's hint DB (if configured) is searched. - * If the view is configured with a static-stub zone which gives the longest - * match for 'name' among the zones, however, the cache DB is not consulted - * unless 'use_static_stub' is false (see below about this argument). - * - * dns_view_find() is a backward compatible version equivalent to - * dns_view_find2() with use_static_stub argument being false. - * - * Notes: - * - *\li See the description of dns_db_find() for information about 'options'. - * If the caller sets #DNS_DBFIND_GLUEOK, it must ensure that 'name' - * and 'type' are appropriate for glue retrieval. - * - *\li If 'now' is zero, then the current time will be used. - * - *\li If 'use_hints' is true, and the view has a hints database, then - * it will be searched last. If the answer is found in the hints - * database, the result code will be DNS_R_HINT. If the name is found - * in the hints database but not the type, the result code will be - * #DNS_R_HINTNXRRSET. - * - *\li If 'use_static_stub' is false and the longest match zone for 'name' - * is a static-stub zone, it's ignored and the cache and/or hints will be - * searched. In the majority of the cases this argument should be - * false. The only known usage of this argument being true is - * if this search is for a "bailiwick" glue A or AAAA RRset that may - * best match a static-stub zone. Consider the following example: - * this view is configured with a static-stub zone "example.com", - * and an attempt of recursive resolution needs to send a query for the - * zone. In this case it's quite likely that the resolver is trying to - * find A/AAAA RRs for the apex name "example.com". And, to honor the - * static-stub configuration it needs to return the glue RRs in the - * static-stub zone even if that exact RRs coming from the authoritative - * zone has been cached. - * In other general cases, the requested data is better to be - * authoritative, either locally configured or retrieved from an external - * server, and the data in the static-stub zone should better be ignored. - * - *\li 'foundname' must meet the requirements of dns_db_find(). - * - *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which - * covers 'type', then 'sigrdataset' will be bound to it. - * - * Requires: - * - *\li 'view' is a valid, frozen view. - * - *\li 'name' is valid name. - * - *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type - * except dns_rdatatype_any. - * - *\li dbp == NULL || *dbp == NULL - * - *\li nodep == NULL || *nodep == NULL. If nodep != NULL, dbp != NULL. - * - *\li 'foundname' is a valid name with a dedicated buffer or NULL. - * - *\li 'rdataset' is a valid, disassociated rdataset. - * - *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. - * - * Ensures: - * - *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are - * bound to the found data. - * - *\li If dbp != NULL, it points to the database containing the data. - * - *\li If nodep != NULL, it points to the database node containing the data. - * - *\li If foundname != NULL, it contains the full name of the found data. - * - * Returns: - * - *\li Any result that dns_db_find() can return, with the exception of - * #DNS_R_DELEGATION. - */ - -isc_result_t -dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, - isc_stdtime_t now, unsigned int options, - bool use_hints, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/*%< - * Find an rdataset whose owner name is 'name', and whose type is - * 'type'. - * - * Notes: - * - *\li This routine is appropriate for simple, exact-match queries of the - * view. 'name' must be a canonical name; there is no DNAME or CNAME - * processing. - * - *\li See the description of dns_db_find() for information about 'options'. - * If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name' - * and 'type' are appropriate for glue retrieval. - * - *\li If 'now' is zero, then the current time will be used. - * - *\li If 'use_hints' is true, and the view has a hints database, then - * it will be searched last. If the answer is found in the hints - * database, the result code will be DNS_R_HINT. If the name is found - * in the hints database but not the type, the result code will be - * DNS_R_HINTNXRRSET. - * - *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which - * covers 'type', then 'sigrdataset' will be bound to it. - * - * Requires: - * - *\li 'view' is a valid, frozen view. - * - *\li 'name' is valid name. - * - *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type - * (e.g. dns_rdatatype_any), or dns_rdatatype_rrsig. - * - *\li 'rdataset' is a valid, disassociated rdataset. - * - *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. - * - * Ensures: - * - *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are - * bound to the found data. - * - * Returns: - * - *\li #ISC_R_SUCCESS Success; result is desired type. - *\li DNS_R_GLUE Success; result is glue. - *\li DNS_R_HINT Success; result is a hint. - *\li DNS_R_NCACHENXDOMAIN Success; result is a ncache entry. - *\li DNS_R_NCACHENXRRSET Success; result is a ncache entry. - *\li DNS_R_NXDOMAIN The name does not exist. - *\li DNS_R_NXRRSET The rrset does not exist. - *\li #ISC_R_NOTFOUND No matching data found, - * or an error occurred. - */ - -/*% See dns_view_findzonecut2() */ -isc_result_t -dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, - isc_stdtime_t now, unsigned int options, - bool use_hints, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -isc_result_t -dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, - isc_stdtime_t now, unsigned int options, - bool use_hints, bool use_cache, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/*%< - * Find the best known zonecut containing 'name'. - * - * This uses local authority, cache, and optionally hints data. - * No external queries are performed. - * - * Notes: - * - *\li If 'now' is zero, then the current time will be used. - * - *\li If 'use_hints' is true, and the view has a hints database, then - * it will be searched last. - * - *\li If 'use_cache' is true, and the view has a cache, then it will be - * searched. - * - *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which - * covers 'type', then 'sigrdataset' will be bound to it. - * - *\li If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned - * (if any) will be the deepest known ancestor of 'name'. - * - * Requires: - * - *\li 'view' is a valid, frozen view. - * - *\li 'name' is valid name. - * - *\li 'rdataset' is a valid, disassociated rdataset. - * - *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. - * - * Returns: - * - *\li #ISC_R_SUCCESS Success. - * - *\li Many other results are possible. - */ - -isc_result_t -dns_viewlist_find(dns_viewlist_t *list, const char *name, - dns_rdataclass_t rdclass, dns_view_t **viewp); -/*%< - * Search for a view with name 'name' and class 'rdclass' in 'list'. - * If found, '*viewp' is (strongly) attached to it. - * - * Requires: - * - *\li 'viewp' points to a NULL dns_view_t *. - * - * Returns: - * - *\li #ISC_R_SUCCESS A matching view was found. - *\li #ISC_R_NOTFOUND No matching view was found. - */ - -isc_result_t -dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, bool allclasses, - dns_rdataclass_t rdclass, dns_zone_t **zonep); - -/*%< - * Search zone with 'name' in view with 'rdclass' in viewlist 'list' - * If found, zone is returned in *zonep. If allclasses is set rdclass is ignored - * - * Returns: - *\li #ISC_R_SUCCESS A matching zone was found. - *\li #ISC_R_NOTFOUND No matching zone was found. - *\li #ISC_R_MULTIPLE Multiple zones with the same name were found. - */ - -isc_result_t -dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep); -/*%< - * Search for the zone 'name' in the zone table of 'view'. - * If found, 'zonep' is (strongly) attached to it. There - * are no partial matches. - * - * Requires: - * - *\li 'zonep' points to a NULL dns_zone_t *. - * - * Returns: - *\li #ISC_R_SUCCESS A matching zone was found. - *\li #ISC_R_NOTFOUND No matching zone was found. - *\li others An error occurred. - */ - -isc_result_t -dns_view_load(dns_view_t *view, bool stop); - -isc_result_t -dns_view_loadnew(dns_view_t *view, bool stop); - -isc_result_t -dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg); - -isc_result_t -dns_view_asyncload2(dns_view_t *view, dns_zt_allloaded_t callback, void *arg, - bool newonly); -/*%< - * Load zones attached to this view. dns_view_load() loads - * all zones whose master file has changed since the last - * load; dns_view_loadnew() loads only zones that have never - * been loaded. - * - * dns_view_asyncload() loads zones asynchronously. When all zones - * in the view have finished loading, 'callback' is called with argument - * 'arg' to inform the caller. - * - * If 'stop' is true, stop on the first error and return it. - * If 'stop' is false (or we are loading asynchronously), ignore errors. - * - * Requires: - * - *\li 'view' is valid. - */ - -isc_result_t -dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, - dns_tsigkey_t **keyp); -/*%< - * Find the TSIG key configured in 'view' with name 'keyname', - * if any. - * - * Requires: - *\li keyp points to a NULL dns_tsigkey_t *. - * - * Returns: - *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. - *\li #ISC_R_NOTFOUND No key was found. - *\li others An error occurred. - */ - -isc_result_t -dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, - dns_tsigkey_t **keyp); -/*%< - * Find the TSIG key configured in 'view' for the server whose - * address is 'peeraddr', if any. - * - * Requires: - * keyp points to a NULL dns_tsigkey_t *. - * - * Returns: - *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. - *\li #ISC_R_NOTFOUND No key was found. - *\li others An error occurred. - */ - -isc_result_t -dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg); -/*%< - * Verifies the signature of a message. - * - * Requires: - * - *\li 'view' is a valid view. - *\li 'source' is a valid buffer containing the message - *\li 'msg' is a valid message - * - * Returns: - *\li see dns_tsig_verify() - */ - -void -dns_view_dialup(dns_view_t *view); -/*%< - * Perform dialup-time maintenance on the zones of 'view'. - */ - -isc_result_t -dns_view_dumpdbtostream(dns_view_t *view, FILE *fp); -/*%< - * Dump the current state of the view 'view' to the stream 'fp' - * for purposes of analysis or debugging. - * - * Currently the dumped state includes the view's cache; in the future - * it may also include other state such as the address database. - * It will not not include authoritative data since it is voluminous and - * easily obtainable by other means. - * - * Requires: - * - *\li 'view' is valid. - * - *\li 'fp' refers to a file open for writing. - * - * Returns: - * \li ISC_R_SUCCESS The cache was successfully dumped. - * \li others An error occurred (see dns_master_dump) - */ - -isc_result_t -dns_view_flushcache(dns_view_t *view); -isc_result_t -dns_view_flushcache2(dns_view_t *view, bool fixuponly); -/*%< - * Flush the view's cache (and ADB). If 'fixuponly' is true, it only updates - * the internal reference to the cache DB with omitting actual flush operation. - * 'fixuponly' is intended to be used for a view that shares a cache with - * a different view. dns_view_flushcache() is a backward compatible version - * that always sets fixuponly to false. - * - * Requires: - * 'view' is valid. - * - * No other tasks are executing. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_view_flushnode(dns_view_t *view, dns_name_t *name, bool tree); -/*%< - * Flush the given name from the view's cache (and optionally ADB/badcache). - * - * Flush the given name from the cache, ADB, and bad cache. If 'tree' - * is true, also flush all subdomains of 'name'. - * - * Requires: - *\li 'view' is valid. - *\li 'name' is valid. - * - * Returns: - *\li #ISC_R_SUCCESS - * other returns are failures. - */ - -isc_result_t -dns_view_flushname(dns_view_t *view, dns_name_t *name); -/*%< - * Flush the given name from the view's cache, ADB and badcache. - * Equivalent to dns_view_flushnode(view, name, false). - * - * - * Requires: - *\li 'view' is valid. - *\li 'name' is valid. - * - * Returns: - *\li #ISC_R_SUCCESS - * other returns are failures. - */ - -isc_result_t -dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); -/*%< - * Add the given name to the delegation only table. - * - * Requires: - *\li 'view' is valid. - *\li 'name' is valid. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name); -/*%< - * Add the given name to be excluded from the root-delegation-only. - * - * - * Requires: - *\li 'view' is valid. - *\li 'name' is valid. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -bool -dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name); -/*%< - * Check if 'name' is in the delegation only table or if - * rootdelonly is set that name is not being excluded. - * - * Requires: - *\li 'view' is valid. - *\li 'name' is valid. - * - * Returns: - *\li #true if the name is the table. - *\li #false otherwise. - */ - -void -dns_view_setrootdelonly(dns_view_t *view, bool value); -/*%< - * Set the root delegation only flag. - * - * Requires: - *\li 'view' is valid. - */ - -bool -dns_view_getrootdelonly(dns_view_t *view); -/*%< - * Get the root delegation only flag. - * - * Requires: - *\li 'view' is valid. - */ - -isc_result_t -dns_view_freezezones(dns_view_t *view, bool freeze); -/*%< - * Freeze/thaw updates to master zones. - * - * Requires: - * \li 'view' is valid. - */ - -void -dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats); -/*%< - * Set a adb statistics set 'stats' for 'view'. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li stats is a valid statistics supporting adb statistics - * (see dns/stats.h). - */ - -void -dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp); -/*%< - * Get the adb statistics counter set for 'view'. If a statistics set is - * set '*statsp' will be attached to the set; otherwise, '*statsp' will be - * untouched. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li 'statsp' != NULL && '*statsp' != NULL - */ - -void -dns_view_setresstats(dns_view_t *view, isc_stats_t *stats); -/*%< - * Set a general resolver statistics counter set 'stats' for 'view'. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li stats is a valid statistics supporting resolver statistics counters - * (see dns/stats.h). - */ - -void -dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp); -/*%< - * Get the general statistics counter set for 'view'. If a statistics set is - * set '*statsp' will be attached to the set; otherwise, '*statsp' will be - * untouched. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li 'statsp' != NULL && '*statsp' != NULL - */ - -void -dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats); -/*%< - * Set a statistics counter set of rdata type, 'stats', for 'view'. Once the - * statistic set is installed, view's resolver will count outgoing queries - * per rdata type. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li stats is a valid statistics created by dns_rdatatypestats_create(). - */ - -void -dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp); -/*%< - * Get the rdatatype statistics counter set for 'view'. If a statistics set is - * set '*statsp' will be attached to the set; otherwise, '*statsp' will be - * untouched. - * - * Requires: - * \li 'view' is valid and is not frozen. - * - *\li 'statsp' != NULL && '*statsp' != NULL - */ - -bool -dns_view_iscacheshared(dns_view_t *view); -/*%< - * Check if the view shares the cache created by another view. - * - * Requires: - * \li 'view' is valid. - * - * Returns: - *\li #true if the cache is shared. - *\li #false otherwise. - */ - -isc_result_t -dns_view_initntatable(dns_view_t *view, - isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr); -/*%< - * Initialize the negative trust anchor table for the view. - * - * Requires: - * \li 'view' is valid. - * - * Returns: - *\li ISC_R_SUCCESS - *\li Any other result indicates failure - */ - -isc_result_t -dns_view_getntatable(dns_view_t *view, dns_ntatable_t **ntp); -/*%< - * Get the negative trust anchor table for this view. Returns - * ISC_R_NOTFOUND if the table not been initialized for the view. - * - * '*ntp' is attached on success; the caller is responsible for - * detaching it with dns_ntatable_detach(). - * - * Requires: - * \li 'view' is valid. - * \li 'nta' is not NULL and '*nta' is NULL. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - */ - -isc_result_t -dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx); -/*%< - * Initialize security roots for the view, detaching any previously - * existing security roots first. (Note that secroots_priv is - * NULL until this function is called, so any function using - * security roots must check that they have been initialized first. - * One way to do this is use dns_view_getsecroots() and check its - * return value.) - * - * Requires: - * \li 'view' is valid. - * - * Returns: - *\li ISC_R_SUCCESS - *\li Any other result indicates failure - */ - -isc_result_t -dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp); -/*%< - * Get the security roots for this view. Returns ISC_R_NOTFOUND if - * the security roots keytable has not been initialized for the view. - * - * '*ktp' is attached on success; the caller is responsible for - * detaching it with dns_keytable_detach(). - * - * Requires: - * \li 'view' is valid. - * \li 'ktp' is not NULL and '*ktp' is NULL. - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOTFOUND - */ - -isc_result_t -dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, - isc_stdtime_t now, bool checknta, bool *ntap, - bool *secure_domain); -/*%< - * Is 'name' at or beneath a trusted key, and not covered by a valid - * negative trust anchor? Put answer in '*secure_domain'. - * - * If 'checknta' is false, ignore the NTA table in determining - * whether this is a secure domain. If 'checknta' is not false, and if - * 'ntap' is non-NULL, then '*ntap' will be updated with true if the - * name is covered by an NTA. - * - * Requires: - * \li 'view' is valid. - * - * Returns: - *\li ISC_R_SUCCESS - *\li Any other value indicates failure - */ - -bool -dns_view_ntacovers(dns_view_t *view, isc_stdtime_t now, - dns_name_t *name, dns_name_t *anchor); -/*%< - * Is there a current negative trust anchor above 'name' and below 'anchor'? - * - * Requires: - * \li 'view' is valid. - * - * Returns: - *\li ISC_R_TRUE - *\li ISC_R_FALSE - */ - -void -dns_view_untrust(dns_view_t *view, dns_name_t *keyname, - dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx); -/*%< - * Remove keys that match 'keyname' and 'dnskey' from the views trust - * anchors. - * - * (NOTE: If the configuration specifies that there should be a - * trust anchor at 'keyname', but no keys are left after this - * operation, that is an error. We fail closed, inserting a NULL - * key so as to prevent validation until a legimitate key has been - * provided.) - * - * Requires: - * \li 'view' is valid. - * \li 'keyname' is valid. - * \li 'mctx' is valid. - * \li 'dnskey' is valid. - */ - -isc_result_t -dns_view_setnewzones(dns_view_t *view, bool allow, void *cfgctx, - void (*cfg_destroy)(void **), uint64_t mapsize); -/*%< - * Set whether or not to allow zones to be created or deleted at runtime. - * - * If 'allow' is true, determines the filename into which new zone - * configuration will be written. Preserves the configuration context - * (a pointer to which is passed in 'cfgctx') for use when parsing new - * zone configuration. 'cfg_destroy' points to a callback routine to - * destroy the configuration context when the view is destroyed. (This - * roundabout method is used in order to avoid libdns having a dependency - * on libisccfg and libbind9.) - * - * If 'allow' is false, removes any existing references to - * configuration context and frees any memory. - * - * Requires: - * \li 'view' is valid. - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOSPACE - */ - -void -dns_view_restorekeyring(dns_view_t *view); - -isc_result_t -dns_view_searchdlz(dns_view_t *view, dns_name_t *name, - unsigned int minlabels, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_db_t **dbp); - -/*%< - * Search through the DLZ database(s) in view->dlz_searched to find - * one that can answer a query for 'name', using the DLZ driver's - * findzone method. If successful, '*dbp' is set to point to the - * DLZ database. - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOTFOUND - * - * Requires: - * \li 'view' is valid. - * \li 'name' is not NULL. - * \li 'dbp' is not NULL and *dbp is NULL. - */ - -uint32_t -dns_view_getfailttl(dns_view_t *view); -/*%< - * Get the view's servfail-ttl. zero => no servfail caching. - * - * Requires: - *\li 'view' to be valid. - */ - -void -dns_view_setfailttl(dns_view_t *view, uint32_t failttl); -/*%< - * Set the view's servfail-ttl. zero => no servfail caching. - * - * Requires: - *\li 'view' to be valid. - */ - -isc_result_t -dns_view_saventa(dns_view_t *view); -/*%< - * Save NTA for names in this view to a file. - * - * Requires: - *\li 'view' to be valid. - */ - -isc_result_t -dns_view_loadnta(dns_view_t *view); -/*%< - * Loads NTA for names in this view from a file. - * - * Requires: - *\li 'view' to be valid. - */ - -void -dns_view_setviewcommit(dns_view_t *view); -/*%< - * Commit dns_zone_setview() calls previously made for all zones in this - * view. - * - * Requires: - *\li 'view' to be valid. - */ - -void -dns_view_setviewrevert(dns_view_t *view); -/*%< - * Revert dns_zone_setview() calls previously made for all zones in this - * view. - * - * Requires: - *\li 'view' to be valid. - */ - - -ISC_LANG_ENDDECLS - -#endif /* DNS_VIEW_H */ diff --git a/lib/dns-pkcs11/include/dns/xfrin.h b/lib/dns-pkcs11/include/dns/xfrin.h deleted file mode 100644 index a930834..0000000 --- a/lib/dns-pkcs11/include/dns/xfrin.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_XFRIN_H -#define DNS_XFRIN_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file dns/xfrin.h - * \brief - * Incoming zone transfers (AXFR + IXFR). - */ - -/*** - *** Imports - ***/ - -#include - -#include - -/*** - *** Types - ***/ - -/*% - * A transfer in progress. This is an opaque type. - */ -typedef struct dns_xfrin_ctx dns_xfrin_ctx_t; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -/*% see dns_xfrin_create2() */ -isc_result_t -dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, - isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey, - isc_mem_t *mctx, isc_timermgr_t *timermgr, - isc_socketmgr_t *socketmgr, isc_task_t *task, - dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp); - -isc_result_t -dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, - isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, - dns_tsigkey_t *tsigkey, isc_mem_t *mctx, - isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - isc_task_t *task, dns_xfrindone_t done, - dns_xfrin_ctx_t **xfrp); - -isc_result_t -dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype, - isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, - isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, - isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - isc_task_t *task, dns_xfrindone_t done, - dns_xfrin_ctx_t **xfrp); -/*%< - * Attempt to start an incoming zone transfer of 'zone' - * from 'masteraddr', creating a dns_xfrin_ctx_t object to - * manage it. Attach '*xfrp' to the newly created object. - * - * Iff ISC_R_SUCCESS is returned, '*done' is guaranteed to be - * called in the context of 'task', with 'zone' and a result - * code as arguments when the transfer finishes. - * - * Requires: - *\li 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr - * or dns_rdatatype_soa (soa query followed by axfr if - * serial is greater than current serial). - * - *\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa, - * the zone has a database. - */ - -void -dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr); -/*%< - * If the zone transfer 'xfr' has already finished, - * do nothing. Otherwise, abort it and cause it to call - * its done callback with a status of ISC_R_CANCELED. - */ - -void -dns_xfrin_detach(dns_xfrin_ctx_t **xfrp); -/*%< - * Detach a reference to a zone transfer object. - * Caller to maintain external locking if required. - */ - -void -dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target); -/*%< - * Caller to maintain external locking if required. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_XFRIN_H */ diff --git a/lib/dns-pkcs11/include/dns/zone.h b/lib/dns-pkcs11/include/dns/zone.h deleted file mode 100644 index cd6f72b..0000000 --- a/lib/dns-pkcs11/include/dns/zone.h +++ /dev/null @@ -1,2515 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_ZONE_H -#define DNS_ZONE_H 1 - -/*! \file dns/zone.h */ - -/*** - *** Imports - ***/ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -typedef enum { - dns_zone_none, - dns_zone_master, - dns_zone_slave, - dns_zone_stub, - dns_zone_staticstub, - dns_zone_key, - dns_zone_dlz, - dns_zone_redirect -} dns_zonetype_t; - -typedef enum { - dns_zonestat_none = 0, - dns_zonestat_terse, - dns_zonestat_full -} dns_zonestat_level_t; - -#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */ -#define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */ -#define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */ -#define DNS_ZONEOPT_NOTIFY 0x00000008U /*%< perform NOTIFY */ -#define DNS_ZONEOPT_MANYERRORS 0x00000010U /*%< return many errors on load */ -#define DNS_ZONEOPT_IXFRFROMDIFFS 0x00000020U /*%< calculate differences */ -#define DNS_ZONEOPT_NOMERGE 0x00000040U /*%< don't merge journal */ -#define DNS_ZONEOPT_CHECKNS 0x00000080U /*%< check if NS's are addresses */ -#define DNS_ZONEOPT_FATALNS 0x00000100U /*%< DNS_ZONEOPT_CHECKNS is fatal */ -#define DNS_ZONEOPT_MULTIMASTER 0x00000200U /*%< this zone has multiple masters */ -#define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /*%< use alternate transfer sources */ -#define DNS_ZONEOPT_CHECKNAMES 0x00000800U /*%< check-names */ -#define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /*%< fatal check-name failures */ -#define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /*%< check for internal wildcards */ -#define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */ -#define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */ -#define DNS_ZONEOPT_CHECKINTEGRITY 0x00010000U /*%< perform integrity checks */ -#define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */ -#define DNS_ZONEOPT_NOCHECKNS 0x00040000U /*%< disable IN NS address checks */ -#define DNS_ZONEOPT_WARNMXCNAME 0x00080000U /*%< warn on MX CNAME check */ -#define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */ -#define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */ -#define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */ -#define DNS_ZONEOPT_UPDATECHECKKSK 0x00800000U /*%< check dnskey KSK flag */ -#define DNS_ZONEOPT_TRYTCPREFRESH 0x01000000U /*%< try tcp refresh on udp failure */ -#define DNS_ZONEOPT_NOTIFYTOSOA 0x02000000U /*%< Notify the SOA MNAME */ -#define DNS_ZONEOPT_NSEC3TESTZONE 0x04000000U /*%< nsec3-test-zone */ -#define DNS_ZONEOPT_SECURETOINSECURE 0x08000000U /*%< dnssec-secure-to-insecure */ -#define DNS_ZONEOPT_DNSKEYKSKONLY 0x10000000U /*%< dnssec-dnskey-kskonly */ -#define DNS_ZONEOPT_CHECKDUPRR 0x20000000U /*%< check-dup-records */ -#define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */ -#define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */ - -/* - * The following zone options are shifted left into the - * higher-order 32 bits of the options. - */ -#define DNS_ZONEOPT2_CHECKTTL 0x00000001U /*%< check max-zone-ttl */ -#define DNS_ZONEOPT2_AUTOEMPTY 0x00000002U /*%< automatic empty zone */ - -#ifndef NOMINUM_PUBLIC -/* - * Nominum specific options build down. - */ -#define DNS_ZONEOPT_NOTIFYFORWARD 0x80000000U /* forward notify to master */ -#endif /* NOMINUM_PUBLIC */ - -/* - * Zone key maintenance options - */ -#define DNS_ZONEKEY_ALLOW 0x00000001U /*%< fetch keys on command */ -#define DNS_ZONEKEY_MAINTAIN 0x00000002U /*%< publish/sign on schedule */ -#define DNS_ZONEKEY_CREATE 0x00000004U /*%< make keys when needed */ -#define DNS_ZONEKEY_FULLSIGN 0x00000008U /*%< roll to new keys immediately */ -#define DNS_ZONEKEY_NORESIGN 0x00000010U /*%< no automatic resigning */ - -#ifndef DNS_ZONE_MINREFRESH -#define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */ -#endif -#ifndef DNS_ZONE_MAXREFRESH -#define DNS_ZONE_MAXREFRESH 2419200 /*%< 4 weeks */ -#endif -#ifndef DNS_ZONE_DEFAULTREFRESH -#define DNS_ZONE_DEFAULTREFRESH 3600 /*%< 1 hour */ -#endif -#ifndef DNS_ZONE_MINRETRY -#define DNS_ZONE_MINRETRY 300 /*%< 5 minutes */ -#endif -#ifndef DNS_ZONE_MAXRETRY -#define DNS_ZONE_MAXRETRY 1209600 /*%< 2 weeks */ -#endif -#ifndef DNS_ZONE_DEFAULTRETRY -#define DNS_ZONE_DEFAULTRETRY 60 /*%< 1 minute, subject to - exponential backoff */ -#endif - -#define DNS_ZONESTATE_XFERRUNNING 1 -#define DNS_ZONESTATE_XFERDEFERRED 2 -#define DNS_ZONESTATE_SOAQUERY 3 -#define DNS_ZONESTATE_ANY 4 -#define DNS_ZONESTATE_AUTOMATIC 5 - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx); -/*%< - * Creates a new empty zone and attach '*zonep' to it. - * - * Requires: - *\li 'zonep' to point to a NULL pointer. - *\li 'mctx' to be a valid memory context. - * - * Ensures: - *\li '*zonep' refers to a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li #ISC_R_UNEXPECTED - */ - -void -dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass); -/*%< - * Sets the class of a zone. This operation can only be performed - * once on a zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li dns_zone_setclass() not to have been called since the zone was - * created. - *\li 'rdclass' != dns_rdataclass_none. - */ - -dns_rdataclass_t -dns_zone_getclass(dns_zone_t *zone); -/*%< - * Returns the current zone class. - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_getserial2(dns_zone_t *zone, uint32_t *serialp); - -uint32_t -dns_zone_getserial(dns_zone_t *zone); -/*%< - * Returns the current serial number of the zone. On success, the SOA - * serial of the zone will be copied into '*serialp'. - * dns_zone_getserial() cannot catch failure cases and is deprecated by - * dns_zone_getserial2(). - * - * Requires: - *\li 'zone' to be a valid zone. - *\li 'serialp' to be non NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #DNS_R_NOTLOADED zone DB is not loaded - */ - -void -dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type); -/*%< - * Sets the zone type. This operation can only be performed once on - * a zone. - * - * Requires: - *\li 'zone' to be a valid zone. - *\li dns_zone_settype() not to have been called since the zone was - * created. - *\li 'type' != dns_zone_none - */ - -void -dns_zone_setview(dns_zone_t *zone, dns_view_t *view); -/*%< - * Associate the zone with a view. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -dns_view_t * -dns_zone_getview(dns_zone_t *zone); -/*%< - * Returns the zone's associated view. - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setviewcommit(dns_zone_t *zone); -/*%< - * Commit the previous view saved internally via dns_zone_setview(). - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setviewrevert(dns_zone_t *zone); -/*%< - * Revert the most recent dns_zone_setview() on this zone, - * restoring the previous view. - * - * Require: - *\li 'zone' to be a valid zone. - */ - - -isc_result_t -dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin); -/*%< - * Sets the zones origin to 'origin'. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'origin' to be non NULL. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -dns_name_t * -dns_zone_getorigin(dns_zone_t *zone); -/*%< - * Returns the value of the origin. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setfile(dns_zone_t *zone, const char *file); - -isc_result_t -dns_zone_setfile2(dns_zone_t *zone, const char *file, - dns_masterformat_t format); -isc_result_t -dns_zone_setfile3(dns_zone_t *zone, const char *file, - dns_masterformat_t format, const dns_master_style_t *style); -/*%< - * Sets the name of the master file in the format of 'format' from which - * the zone loads its database to 'file'. - * - * For zones that have no associated master file, 'file' will be NULL. - * - * For zones with persistent databases, the file name - * setting is ignored. - * - * dns_zone_setfile() is a backward-compatible form of - * dns_zone_setfile2(), which always specifies the - * dns_masterformat_text (RFC1035) format. - * - * dns_zone_setfile2() is a backward-compatible form of - * dns_zone_setfile3(), which also specifies the style - * that should be used if a zone using the 'text' - * masterformat is ever dumped. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_NOMEMORY - *\li #ISC_R_SUCCESS - */ - -const char * -dns_zone_getfile(dns_zone_t *zone); -/*%< - * Gets the name of the zone's master file, if any. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - *\li Pointer to null-terminated file name, or NULL. - */ - -void -dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t records); -/*%< - * Sets the maximum number of records permitted in a zone. - * 0 implies unlimited. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - *\li void - */ - -uint32_t -dns_zone_getmaxrecords(dns_zone_t *zone); -/*%< - * Gets the maximum number of records permitted in a zone. - * 0 implies unlimited. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - *\li uint32_t maxrecords. - */ - -void -dns_zone_setmaxttl(dns_zone_t *zone, uint32_t maxttl); -/*%< - * Sets the max ttl of the zone. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - *\li void - */ - -dns_ttl_t -dns_zone_getmaxttl(dns_zone_t *zone); -/*%< - * Gets the max ttl of the zone. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - *\li dns_ttl_t maxttl. - */ - -isc_result_t -dns_zone_load(dns_zone_t *zone); - -isc_result_t -dns_zone_loadnew(dns_zone_t *zone); - -isc_result_t -dns_zone_loadandthaw(dns_zone_t *zone); - -/*%< - * Cause the database to be loaded from its backing store. - * Confirm that the minimum requirements for the zone type are - * met, otherwise DNS_R_BADZONE is returned. - * - * dns_zone_loadnew() only loads zones that are not yet loaded. - * dns_zone_load() also loads zones that are already loaded and - * and whose master file has changed since the last load. - * dns_zone_loadandthaw() is similar to dns_zone_load() but will - * also re-enable DNS UPDATEs when the load completes. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_UNEXPECTED - *\li #ISC_R_SUCCESS - *\li DNS_R_CONTINUE Incremental load has been queued. - *\li DNS_R_UPTODATE The zone has already been loaded based on - * file system timestamps. - *\li DNS_R_BADZONE - *\li Any result value from dns_db_load(). - */ - -isc_result_t -dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg); - -isc_result_t -dns_zone_asyncload2(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg, - bool newonly); -/*%< - * Cause the database to be loaded from its backing store asynchronously. - * Other zone maintenance functions are suspended until this is complete. - * When finished, 'done' is called to inform the caller, with 'arg' as - * its first argument and 'zone' as its second. (Normally, 'arg' is - * expected to point to the zone table but is left undefined for testing - * purposes.) - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_ALREADYRUNNING - *\li #ISC_R_SUCCESS - *\li #ISC_R_FAILURE - *\li #ISC_R_NOMEMORY - */ - -bool -dns__zone_loadpending(dns_zone_t *zone); -/*%< - * Indicates whether the zone is waiting to be loaded asynchronously. - * (Not currently intended for use outside of this module and associated - * tests.) - */ - -void -dns_zone_attach(dns_zone_t *source, dns_zone_t **target); -/*%< - * Attach '*target' to 'source' incrementing its external - * reference count. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_zone_detach(dns_zone_t **zonep); -/*%< - * Detach from a zone decrementing its external reference count. - * If this was the last external reference to the zone it will be - * shut down and eventually freed. - * - * Require: - *\li 'zonep' to point to a valid zone. - */ - -void -dns_zone_iattach(dns_zone_t *source, dns_zone_t **target); -/*%< - * Attach '*target' to 'source' incrementing its internal - * reference count. This is intended for use by operations - * such as zone transfers that need to prevent the zone - * object from being freed but not from shutting down. - * - * Require: - *\li The caller is running in the context of the zone's task. - *\li 'zone' to be a valid zone. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_zone_idetach(dns_zone_t **zonep); -/*%< - * Detach from a zone decrementing its internal reference count. - * If there are no more internal or external references to the - * zone, it will be freed. - * - * Require: - *\li The caller is running in the context of the zone's task. - *\li 'zonep' to point to a valid zone. - */ - -void -dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value); -/*%< - * Sets ('value' == 'true') / clears ('value' == 'IS_FALSE') - * zone flags. Valid flag bits are DNS_ZONE_F_*. - * - * Requires - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp); -/*%< - * Attach '*dbp' to the database to if it exists otherwise - * return DNS_R_NOTLOADED. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'dbp' to be != NULL && '*dbp' == NULL. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li DNS_R_NOTLOADED - */ - -void -dns_zone_setdb(dns_zone_t *zone, dns_db_t *db); -/*%< - * Sets the zone database to 'db'. - * - * This function is expected to be used to configure a zone with a - * database which is not loaded from a file or zone transfer. - * It can be used for a general purpose zone, but right now its use - * is limited to static-stub zones to avoid possible undiscovered - * problems in the general cases. - * - * Require: - *\li 'zone' to be a valid zone of static-stub. - *\li zone doesn't have a database. - */ - -isc_result_t -dns_zone_setdbtype(dns_zone_t *zone, - unsigned int dbargc, const char * const *dbargv); -/*%< - * Sets the database type to dbargv[0] and database arguments - * to subsequent dbargv elements. - * 'db_type' is not checked to see if it is a valid database type. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'database' to be non NULL. - *\li 'dbargc' to be >= 1 - *\li 'dbargv' to point to dbargc NULL-terminated strings - * - * Returns: - *\li #ISC_R_NOMEMORY - *\li #ISC_R_SUCCESS - */ - -isc_result_t -dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx); -/*%< - * Returns the current dbtype. isc_mem_free() should be used - * to free 'argv' after use. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'argv' to be non NULL and *argv to be NULL. - *\li 'mctx' to be valid. - * - * Returns: - *\li #ISC_R_NOMEMORY - *\li #ISC_R_SUCCESS - */ - -void -dns_zone_markdirty(dns_zone_t *zone); -/*%< - * Mark a zone as 'dirty'. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_expire(dns_zone_t *zone); -/*%< - * Mark the zone as expired. If the zone requires dumping cause it to - * be initiated. Set the refresh and retry intervals to there default - * values and unload the zone. - * - * Require - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_refresh(dns_zone_t *zone); -/*%< - * Initiate zone up to date checks. The zone must already be being - * managed. - * - * Require - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_flush(dns_zone_t *zone); -/*%< - * Write the zone to database if there are uncommitted changes. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_dump(dns_zone_t *zone); -/*%< - * Write the zone to database. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_dumptostream(dns_zone_t *zone, FILE *fd); - -isc_result_t -dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, - const dns_master_style_t *style); -isc_result_t -dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, - const dns_master_style_t *style, - const uint32_t rawversion); -/*%< - * Write the zone to stream 'fd' in the specified 'format'. - * If the 'format' is dns_masterformat_text (RFC1035), 'style' also - * specifies the file style (e.g., &dns_master_style_default). - * - * dns_zone_dumptostream() is a backward-compatible form of - * dns_zone_dumptostream2(), which always uses the dns_masterformat_text - * format and the dns_master_style_default style. - * - * dns_zone_dumptostream2() is a backward-compatible form of - * dns_zone_dumptostream3(), which always uses the current - * default raw file format version. - * - * Note that dns_zone_dumptostream3() is the most flexible form. It - * can also provide the functionality of dns_zone_fulldumptostream(). - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'fd' to be a stream open for writing. - */ - -isc_result_t -dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd); -/*%< - * The same as dns_zone_dumptostream, but dumps the zone with - * different dump settings (dns_master_style_full). - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'fd' to be a stream open for writing. - */ - -void -dns_zone_maintenance(dns_zone_t *zone); -/*%< - * Perform regular maintenance on the zone. This is called as a - * result of a zone being managed. - * - * Require - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, - uint32_t count); -isc_result_t -dns_zone_setmasterswithkeys(dns_zone_t *zone, - const isc_sockaddr_t *masters, - dns_name_t **keynames, - uint32_t count); -/*%< - * Set the list of master servers for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'masters' array of isc_sockaddr_t with port set or NULL. - *\li 'count' the number of masters. - *\li 'keynames' array of dns_name_t's for tsig keys or NULL. - * - * \li dns_zone_setmasters() is just a wrapper to setmasterswithkeys(), - * passing NULL in the keynames field. - * - * \li If 'masters' is NULL then 'count' must be zero. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - *\li Any result dns_name_dup() can return, if keynames!=NULL - */ - -isc_result_t -dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, - uint32_t count); -isc_result_t -dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, - dns_name_t **keynames, uint32_t count); -isc_result_t -dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, - const isc_dscp_t *dscps, dns_name_t **keynames, - uint32_t count); -/*%< - * Set the list of additional servers to be notified when - * a zone changes. To clear the list use 'count = 0'. - * - * dns_zone_alsonotifywithkeys() allows each notify address to - * be associated with a TSIG key. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'notify' to be non-NULL if count != 0. - *\li 'count' to be the number of notifiees. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -void -dns_zone_unload(dns_zone_t *zone); -/*%< - * detach the database from the zone structure. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setoption(dns_zone_t *zone, unsigned int option, - bool value); -void -dns_zone_setoption2(dns_zone_t *zone, unsigned int option, - bool value); -/*%< - * Set the given options on ('value' == true) or off - * ('value' == #false). - * - * dns_zone_setoption2() has been introduced because the number - * of options needed now exceeds the 32 bits in the zone->options - * field; it should be used set options with names beginning - * with DNS_ZONEOPT2_. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -unsigned int -dns_zone_getoptions(dns_zone_t *zone); -unsigned int -dns_zone_getoptions2(dns_zone_t *zone); -/*%< - * Returns the current zone options. - * - * Callers should be aware there is now more than one set of zone - * options. dns_zone_getoptions2() has been introduced because the - * number of options needed now exceeds the 32 bits in the - * zone->options field. It returns the options whose names begin - * with DNS_ZONEOPT2_. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setkeyopt(dns_zone_t *zone, unsigned int option, bool value); -/*%< - * Set key options on ('value' == true) or off ('value' == - * #false). - * - * Require: - *\li 'zone' to be a valid zone. - */ - -unsigned int -dns_zone_getkeyopts(dns_zone_t *zone); -/*%< - * Returns the current zone key options. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val); -/*%< - * Set the minimum refresh time. - * - * Requires: - *\li 'zone' is valid. - *\li val > 0. - */ - -void -dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val); -/*%< - * Set the maximum refresh time. - * - * Requires: - *\li 'zone' is valid. - *\li val > 0. - */ - -void -dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val); -/*%< - * Set the minimum retry time. - * - * Requires: - *\li 'zone' is valid. - *\li val > 0. - */ - -void -dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val); -/*%< - * Set the maximum retry time. - * - * Requires: - *\li 'zone' is valid. - * val > 0. - */ - -isc_result_t -dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); -isc_result_t -dns_zone_setaltxfrsource4(dns_zone_t *zone, - const isc_sockaddr_t *xfrsource); -/*%< - * Set the source address to be used in IPv4 zone transfers. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'xfrsource' to contain the address. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_sockaddr_t * -dns_zone_getxfrsource4(dns_zone_t *zone); -isc_sockaddr_t * -dns_zone_getaltxfrsource4(dns_zone_t *zone); -/*%< - * Returns the source address set by a previous dns_zone_setxfrsource4 - * call, or the default of inaddr_any, port 0. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp); -isc_result_t -dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp); -/*%< - * Set the DSCP value associated with the transfer/alt-transfer source. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_dscp_t -dns_zone_getxfrsource4dscp(dns_zone_t *zone); -isc_dscp_t -dns_zone_getaltxfrsource4dscp(dns_zone_t *zone); -/*%/ - * Get the DSCP value associated with the transfer/alt-transfer source. - * - * Require: - *\li 'zone' to be a valid zone. - */ - - -isc_result_t -dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); -isc_result_t -dns_zone_setaltxfrsource6(dns_zone_t *zone, - const isc_sockaddr_t *xfrsource); -/*%< - * Set the source address to be used in IPv6 zone transfers. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'xfrsource' to contain the address. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_sockaddr_t * -dns_zone_getxfrsource6(dns_zone_t *zone); -isc_sockaddr_t * -dns_zone_getaltxfrsource6(dns_zone_t *zone); -/*%< - * Returns the source address set by a previous dns_zone_setxfrsource6 - * call, or the default of in6addr_any, port 0. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_dscp_t -dns_zone_getxfrsource6dscp(dns_zone_t *zone); -isc_dscp_t -dns_zone_getaltxfrsource6dscp(dns_zone_t *zone); -/*%/ - * Get the DSCP value associated with the transfer/alt-transfer source. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp); -isc_result_t -dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp); -/*%< - * Set the DSCP value associated with the transfer/alt-transfer source. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_result_t -dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); -/*%< - * Set the source address to be used with IPv4 NOTIFY messages. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'notifysrc' to contain the address. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_sockaddr_t * -dns_zone_getnotifysrc4(dns_zone_t *zone); -/*%< - * Returns the source address set by a previous dns_zone_setnotifysrc4 - * call, or the default of inaddr_any, port 0. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_dscp_t -dns_zone_getnotifysrc4dscp(dns_zone_t *zone); -/*%/ - * Get the DSCP value associated with the IPv4 notify source. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp); -/*%< - * Set the DSCP value associated with the IPv4 notify source. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_result_t -dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); -/*%< - * Set the source address to be used with IPv6 NOTIFY messages. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'notifysrc' to contain the address. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -isc_sockaddr_t * -dns_zone_getnotifysrc6(dns_zone_t *zone); -/*%< - * Returns the source address set by a previous dns_zone_setnotifysrc6 - * call, or the default of in6addr_any, port 0. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_dscp_t -dns_zone_getnotifysrc6dscp(dns_zone_t *zone); -/*%/ - * Get the DSCP value associated with the IPv6 notify source. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp); -/*%< - * Set the DSCP value associated with the IPv6 notify source. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - */ - -void -dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the notify acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be a valid acl. - */ - -void -dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the query acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be a valid acl. - */ - -void -dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the query-on acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be a valid acl. - */ - -void -dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the update acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be valid acl. - */ - -void -dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the forward unsigned updates acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be valid acl. - */ - -void -dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl); -/*%< - * Sets the transfer acl list for the zone. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'acl' to be valid acl. - */ - -dns_acl_t * -dns_zone_getnotifyacl(dns_zone_t *zone); -/*%< - * Returns the current notify acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -dns_acl_t * -dns_zone_getqueryacl(dns_zone_t *zone); -/*%< - * Returns the current query acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -dns_acl_t * -dns_zone_getqueryonacl(dns_zone_t *zone); -/*%< - * Returns the current query-on acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -dns_acl_t * -dns_zone_getupdateacl(dns_zone_t *zone); -/*%< - * Returns the current update acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -dns_acl_t * -dns_zone_getforwardacl(dns_zone_t *zone); -/*%< - * Returns the current forward unsigned updates acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -dns_acl_t * -dns_zone_getxfracl(dns_zone_t *zone); -/*%< - * Returns the current transfer acl or NULL. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li acl a pointer to the acl. - *\li NULL - */ - -void -dns_zone_clearupdateacl(dns_zone_t *zone); -/*%< - * Clear the current update acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_clearforwardacl(dns_zone_t *zone); -/*%< - * Clear the current forward unsigned updates acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_clearnotifyacl(dns_zone_t *zone); -/*%< - * Clear the current notify acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_clearqueryacl(dns_zone_t *zone); -/*%< - * Clear the current query acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_clearqueryonacl(dns_zone_t *zone); -/*%< - * Clear the current query-on acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_clearxfracl(dns_zone_t *zone); -/*%< - * Clear the current transfer acl. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -bool -dns_zone_getupdatedisabled(dns_zone_t *zone); -/*%< - * Return update disabled. - * Transient unless called when running in isc_task_exclusive() mode. - */ - -void -dns_zone_setupdatedisabled(dns_zone_t *zone, bool state); -/*%< - * Set update disabled. - * Should only be called only when running in isc_task_exclusive() mode. - * Failure to do so may result in updates being committed after the - * call has been made. - */ - -bool -dns_zone_getzeronosoattl(dns_zone_t *zone); -/*%< - * Return zero-no-soa-ttl status. - */ - -void -dns_zone_setzeronosoattl(dns_zone_t *zone, bool state); -/*%< - * Set zero-no-soa-ttl status. - */ - -void -dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity); -/*%< - * Set the severity of name checking when loading a zone. - * - * Require: - * \li 'zone' to be a valid zone. - */ - -dns_severity_t -dns_zone_getchecknames(dns_zone_t *zone); -/*%< - * Return the current severity of name checking. - * - * Require: - *\li 'zone' to be a valid zone. - */ - -void -dns_zone_setjournalsize(dns_zone_t *zone, int32_t size); -/*%< - * Sets the journal size for the zone. - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -int32_t -dns_zone_getjournalsize(dns_zone_t *zone); -/*%< - * Return the journal size as set with a previous call to - * dns_zone_setjournalsize(). - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, - dns_message_t *msg); -isc_result_t -dns_zone_notifyreceive2(dns_zone_t *zone, isc_sockaddr_t *from, - isc_sockaddr_t *to, dns_message_t *msg); -/*%< - * Tell the zone that it has received a NOTIFY message from another - * server. This may cause some zone maintenance activity to occur. - * - * Requires: - *\li 'zone' to be a valid zone. - *\li '*from' to contain the address of the server from which 'msg' - * was received. - *\li 'msg' a message with opcode NOTIFY and qr clear. - * - * Returns: - *\li DNS_R_REFUSED - *\li DNS_R_NOTIMP - *\li DNS_R_FORMERR - *\li DNS_R_SUCCESS - */ - -void -dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin); -/*%< - * Set the maximum time (in seconds) that a zone transfer in (AXFR/IXFR) - * of this zone will use before being aborted. - * - * Requires: - * \li 'zone' to be valid initialised zone. - */ - -uint32_t -dns_zone_getmaxxfrin(dns_zone_t *zone); -/*%< - * Returns the maximum transfer time for this zone. This will be - * either the value set by the last call to dns_zone_setmaxxfrin() or - * the default value of 1 hour. - * - * Requires: - *\li 'zone' to be valid initialised zone. - */ - -void -dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout); -/*%< - * Set the maximum time (in seconds) that a zone transfer out (AXFR/IXFR) - * of this zone will use before being aborted. - * - * Requires: - * \li 'zone' to be valid initialised zone. - */ - -uint32_t -dns_zone_getmaxxfrout(dns_zone_t *zone); -/*%< - * Returns the maximum transfer time for this zone. This will be - * either the value set by the last call to dns_zone_setmaxxfrout() or - * the default value of 1 hour. - * - * Requires: - *\li 'zone' to be valid initialised zone. - */ - -isc_result_t -dns_zone_setjournal(dns_zone_t *zone, const char *myjournal); -/*%< - * Sets the filename used for journaling updates / IXFR transfers. - * The default journal name is set by dns_zone_setfile() to be - * "file.jnl". If 'myjournal' is NULL, the zone will have no - * journal name. - * - * Requires: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #ISC_R_NOMEMORY - */ - -char * -dns_zone_getjournal(dns_zone_t *zone); -/*%< - * Returns the journal name associated with this zone. - * If no journal has been set this will be NULL. - * - * Requires: - *\li 'zone' to be valid initialised zone. - */ - -dns_zonetype_t -dns_zone_gettype(dns_zone_t *zone); -/*%< - * Returns the type of the zone (master/slave/etc.) - * - * Requires: - *\li 'zone' to be valid initialised zone. - */ - -void -dns_zone_settask(dns_zone_t *zone, isc_task_t *task); -/*%< - * Give a zone a task to work with. Any current task will be detached. - * - * Requires: - *\li 'zone' to be valid. - *\li 'task' to be valid. - */ - -void -dns_zone_gettask(dns_zone_t *zone, isc_task_t **target); -/*%< - * Attach '*target' to the zone's task. - * - * Requires: - *\li 'zone' to be valid initialised zone. - *\li 'zone' to have a task. - *\li 'target' to be != NULL && '*target' == NULL. - */ - -void -dns_zone_notify(dns_zone_t *zone); -/*%< - * Generate notify events for this zone. - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump); -/*%< - * Replace the database of "zone" with a new database "db". - * - * If "dump" is true, then the new zone contents are dumped - * into to the zone's master file for persistence. When replacing - * a zone database by one just loaded from a master file, set - * "dump" to false to avoid a redundant redump of the data just - * loaded. Otherwise, it should be set to true. - * - * If the "diff-on-reload" option is enabled in the configuration file, - * the differences between the old and the new database are added to the - * journal file, and the master file dump is postponed. - * - * Requires: - * \li 'zone' to be a valid zone. - * - * Returns: - * \li DNS_R_SUCCESS - * \li DNS_R_BADZONE zone failed basic consistency checks: - * * a single SOA must exist - * * some NS records must exist. - * Others - */ - -uint32_t -dns_zone_getidlein(dns_zone_t *zone); -/*%< - * Requires: - * \li 'zone' to be a valid zone. - * - * Returns: - * \li number of seconds of idle time before we abort the transfer in. - */ - -void -dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein); -/*%< - * \li Set the idle timeout for transfer the. - * \li Zero set the default value, 1 hour. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -uint32_t -dns_zone_getidleout(dns_zone_t *zone); -/*%< - * - * Requires: - * \li 'zone' to be a valid zone. - * - * Returns: - * \li number of seconds of idle time before we abort a transfer out. - */ - -void -dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout); -/*%< - * \li Set the idle timeout for transfers out. - * \li Zero set the default value, 1 hour. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -void -dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table); -/*%< - * Get the simple-secure-update policy table. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -void -dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table); -/*%< - * Set / clear the simple-secure-update policy table. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -isc_mem_t * -dns_zone_getmctx(dns_zone_t *zone); -/*%< - * Get the memory context of a zone. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -dns_zonemgr_t * -dns_zone_getmgr(dns_zone_t *zone); -/*%< - * If 'zone' is managed return the zone manager otherwise NULL. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -void -dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval); -/*%< - * Set the zone's RRSIG validity interval. This is the length of time - * for which DNSSEC signatures created as a result of dynamic updates - * to secure zones will remain valid, in seconds. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -uint32_t -dns_zone_getsigvalidityinterval(dns_zone_t *zone); -/*%< - * Get the zone's RRSIG validity interval. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -void -dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval); -/*%< - * Set the zone's RRSIG re-signing interval. A dynamic zone's RRSIG's - * will be re-signed 'interval' amount of time before they expire. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -uint32_t -dns_zone_getsigresigninginterval(dns_zone_t *zone); -/*%< - * Get the zone's RRSIG re-signing interval. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -void -dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype); -/*%< - * Sets zone notify method to "notifytype" - */ - -isc_result_t -dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, - dns_updatecallback_t callback, void *callback_arg); -/*%< - * Forward 'msg' to each master in turn until we get an answer or we - * have exhausted the list of masters. 'callback' will be called with - * ISC_R_SUCCESS if we get an answer and the returned message will be - * passed as 'answer_message', otherwise a non ISC_R_SUCCESS result code - * will be passed and answer_message will be NULL. The callback function - * is responsible for destroying 'answer_message'. - * (callback)(callback_arg, result, answer_message); - * - * Require: - *\li 'zone' to be valid - *\li 'msg' to be valid. - *\li 'callback' to be non NULL. - * Returns: - *\li #ISC_R_SUCCESS if the message has been forwarded, - *\li #ISC_R_NOMEMORY - *\li Others - */ - -isc_result_t -dns_zone_next(dns_zone_t *zone, dns_zone_t **next); -/*%< - * Find the next zone in the list of managed zones. - * - * Requires: - *\li 'zone' to be valid - *\li The zone manager for the indicated zone MUST be locked - * by the caller. This is not checked. - *\li 'next' be non-NULL, and '*next' be NULL. - * - * Ensures: - *\li 'next' points to a valid zone (result ISC_R_SUCCESS) or to NULL - * (result ISC_R_NOMORE). - */ - - - -isc_result_t -dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first); -/*%< - * Find the first zone in the list of managed zones. - * - * Requires: - *\li 'zonemgr' to be valid - *\li The zone manager for the indicated zone MUST be locked - * by the caller. This is not checked. - *\li 'first' be non-NULL, and '*first' be NULL - * - * Ensures: - *\li 'first' points to a valid zone (result ISC_R_SUCCESS) or to NULL - * (result ISC_R_NOMORE). - */ - -isc_result_t -dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory); -/*%< - * Sets the name of the directory where private keys used for - * online signing of dynamic zones are found. - * - * Require: - *\li 'zone' to be a valid zone. - * - * Returns: - *\li #ISC_R_NOMEMORY - *\li #ISC_R_SUCCESS - */ - -const char * -dns_zone_getkeydirectory(dns_zone_t *zone); -/*%< - * Gets the name of the directory where private keys used for - * online signing of dynamic zones are found. - * - * Requires: - *\li 'zone' to be valid initialised zone. - * - * Returns: - * Pointer to null-terminated file name, or NULL. - */ - - -isc_result_t -dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - dns_zonemgr_t **zmgrp); -/*%< - * Create a zone manager. Note: the zone manager will not be able to - * manage any zones until dns_zonemgr_setsize() has been run. - * - * Requires: - *\li 'mctx' to be a valid memory context. - *\li 'taskmgr' to be a valid task manager. - *\li 'timermgr' to be a valid timer manager. - *\li 'zmgrp' to point to a NULL pointer. - */ - -isc_result_t -dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones); -/*%< - * Set the size of the zone manager task pool. This must be run - * before zmgr can be used for managing zones. Currently, it can only - * be run once; the task pool cannot be resized. - * - * Requires: - *\li zmgr is a valid zone manager. - *\li zmgr->zonetasks has been initialized. - */ - -isc_result_t -dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep); -/*%< - * Allocate a new zone using a memory context from the - * zone manager's memory context pool. - * - * Require: - *\li 'zmgr' to be a valid zone manager. - *\li 'zonep' != NULL and '*zonep' == NULL. - */ - - -isc_result_t -dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); -/*%< - * Bring the zone under control of a zone manager. - * - * Require: - *\li 'zmgr' to be a valid zone manager. - *\li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr); -/*%< - * Force zone maintenance of all loaded zones managed by 'zmgr' - * to take place at the system's earliest convenience. - */ - -void -dns__zonemgr_run(isc_task_t *task, isc_event_t *event); -/*%< - * Event handler to call dns_zonemgr_forcemaint(); used to start - * zone operations from a unit test. Not intended for use outside - * libdns or related tests. - */ - -void -dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr); -/*%< - * Attempt to start any stalled zone transfers. - */ - -void -dns_zonemgr_shutdown(dns_zonemgr_t *zmgr); -/*%< - * Shut down the zone manager. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -void -dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target); -/*%< - * Attach '*target' to 'source' incrementing its external - * reference count. - * - * Require: - *\li 'zone' to be a valid zone. - *\li 'target' to be non NULL and '*target' to be NULL. - */ - -void -dns_zonemgr_detach(dns_zonemgr_t **zmgrp); -/*%< - * Detach from a zone manager. - * - * Requires: - *\li '*zmgrp' is a valid, non-NULL zone manager pointer. - * - * Ensures: - *\li '*zmgrp' is NULL. - */ - -void -dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); -/*%< - * Release 'zone' from the managed by 'zmgr'. 'zmgr' is implicitly - * detached from 'zone'. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'zone' to be a valid zone. - *\li 'zmgr' == 'zone->zmgr' - * - * Ensures: - *\li 'zone->zmgr' == NULL; - */ - -void -dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value); -/*%< - * Set the maximum number of simultaneous transfers in allowed by - * the zone manager. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -uint32_t -dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr); -/*%< - * Return the maximum number of simultaneous transfers in allowed. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -void -dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value); -/*%< - * Set the number of zone transfers allowed per nameserver. - * - * Requires: - *\li 'zmgr' to be a valid zone manager - */ - -uint32_t -dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr); -/*%< - * Return the number of transfers allowed per nameserver. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -void -dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit); -/*%< - * Set the number of simultaneous file descriptors available for - * reading and writing masterfiles. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'iolimit' to be positive. - */ - -uint32_t -dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr); -/*%< - * Get the number of simultaneous file descriptors available for - * reading and writing masterfiles. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -void -dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value); -/*%< - * Set the number of NOTIFY requests sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager - */ - -void -dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value); -/*%< - * Set the number of startup NOTIFY requests sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager - */ - -void -dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value); -/*%< - * Set the number of SOA queries sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager - */ - -unsigned int -dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr); -/*%< - * Return the number of NOTIFY requests sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -unsigned int -dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr); -/*%< - * Return the number of startup NOTIFY requests sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -unsigned int -dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr); -/*%< - * Return the number of SOA queries sent per second. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - */ - -unsigned int -dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state); -/*%< - * Returns the number of zones in the specified state. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'state' to be a valid DNS_ZONESTATE_ constant. - */ - -void -dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, - isc_sockaddr_t *local, isc_time_t *now); -/*%< - * Add the pair of addresses to the unreachable cache. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'remote' to be a valid sockaddr. - *\li 'local' to be a valid sockaddr. - */ - -bool -dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, - isc_sockaddr_t *local, isc_time_t *now); -/*%< - * Returns true if the given local/remote address pair - * is found in the zone maanger's unreachable cache. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'remote' to be a valid sockaddr. - *\li 'local' to be a valid sockaddr. - *\li 'now' != NULL - */ - -void -dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, - isc_sockaddr_t *local); -/*%< - * Remove the pair of addresses from the unreachable cache. - * - * Requires: - *\li 'zmgr' to be a valid zone manager. - *\li 'remote' to be a valid sockaddr. - *\li 'local' to be a valid sockaddr. - */ - -void -dns_zone_forcereload(dns_zone_t *zone); -/*%< - * Force a reload of specified zone. - * - * Requires: - *\li 'zone' to be a valid zone. - */ - -bool -dns_zone_isforced(dns_zone_t *zone); -/*%< - * Check if the zone is waiting a forced reload. - * - * Requires: - * \li 'zone' to be a valid zone. - */ - -isc_result_t -dns_zone_setstatistics(dns_zone_t *zone, bool on); -/*%< - * This function is obsoleted by dns_zone_setrequeststats(). - */ - -uint64_t * -dns_zone_getstatscounters(dns_zone_t *zone); -/*%< - * This function is obsoleted by dns_zone_getrequeststats(). - */ - -void -dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats); -/*%< - * Set a general zone-maintenance statistics set 'stats' for 'zone'. This - * function is expected to be called only on zone creation (when necessary). - * Once installed, it cannot be removed or replaced. Also, there is no - * interface to get the installed stats from the zone; the caller must keep the - * stats to reference (e.g. dump) it later. - * - * Requires: - * \li 'zone' to be a valid zone and does not have a statistics set already - * installed. - * - *\li stats is a valid statistics supporting zone statistics counters - * (see dns/stats.h). - */ - -void -dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats); - -void -dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); -/*%< - * Set additional statistics sets to zone. These are attached to the zone - * but are not counted in the zone module; only the caller updates the - * counters. - * - * Requires: - * \li 'zone' to be a valid zone. - * - *\li stats is a valid statistics. - */ - -isc_stats_t * -dns_zone_getrequeststats(dns_zone_t *zone); - -dns_stats_t * -dns_zone_getrcvquerystats(dns_zone_t *zone); -/*%< - * Get the additional statistics for zone, if one is installed. - * - * Requires: - * \li 'zone' to be a valid zone. - * - * Returns: - * \li when available, a pointer to the statistics set installed in zone; - * otherwise NULL. - */ - -void -dns_zone_dialup(dns_zone_t *zone); -/*%< - * Perform dialup-time maintenance on 'zone'. - */ - -void -dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup); -/*%< - * Set the dialup type of 'zone' to 'dialup'. - * - * Requires: - * \li 'zone' to be valid initialised zone. - *\li 'dialup' to be a valid dialup type. - */ - -void -dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level, - const char *prefix, const char *msg, va_list ap); -/*%< - * Log the message 'msg...' at 'level' using log category 'category', including - * text that identifies the message as applying to 'zone'. If the (optional) - * 'prefix' is not NULL, it will be placed at the start of the entire log line. - */ - -void -dns_zone_log(dns_zone_t *zone, int level, const char *msg, ...) - ISC_FORMAT_PRINTF(3, 4); -/*%< - * Log the message 'msg...' at 'level', including text that identifies - * the message as applying to 'zone'. - */ - -void -dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, - const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); -/*%< - * Log the message 'msg...' at 'level', including text that identifies - * the message as applying to 'zone'. - */ - -void -dns_zone_name(dns_zone_t *zone, char *buf, size_t len); -/*%< - * Return the name of the zone with class and view. - * - * Requires: - *\li 'zone' to be valid. - *\li 'buf' to be non NULL. - */ - -void -dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t len); -/*%< - * Return the name of the zone only. - * - * Requires: - *\li 'zone' to be valid. - *\li 'buf' to be non NULL. - */ - -isc_result_t -dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata); -/*%< - * Check if this record meets the check-names policy. - * - * Requires: - * 'zone' to be valid. - * 'name' to be valid. - * 'rdata' to be valid. - * - * Returns: - * DNS_R_SUCCESS passed checks. - * DNS_R_BADOWNERNAME failed ownername checks. - * DNS_R_BADNAME failed rdata checks. - */ - -void -dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache); -/*%< - * Associate the zone with an additional cache. - * - * Require: - * 'zone' to be a valid zone. - * 'acache' to be a non NULL pointer. - * - * Ensures: - * 'zone' will have a reference to 'acache' - */ - -void -dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx); -/*%< - * Set the post load integrity callback function 'checkmx'. - * 'checkmx' will be called if the MX TARGET is not within the zone. - * - * Require: - * 'zone' to be a valid zone. - */ - -void -dns_zone_setchecksrv(dns_zone_t *zone, dns_checkmxfunc_t checksrv); -/*%< - * Set the post load integrity callback function 'checksrv'. - * 'checksrv' will be called if the SRV TARGET is not within the zone. - * - * Require: - * 'zone' to be a valid zone. - */ - -void -dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns); -/*%< - * Set the post load integrity callback function 'checkns'. - * 'checkns' will be called if the NS TARGET is not within the zone. - * - * Require: - * 'zone' to be a valid zone. - */ - -void -dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay); -/*%< - * Set the minimum delay between sets of notify messages. - * - * Requires: - * 'zone' to be valid. - */ - -uint32_t -dns_zone_getnotifydelay(dns_zone_t *zone); -/*%< - * Get the minimum delay between sets of notify messages. - * - * Requires: - * 'zone' to be valid. - */ - -void -dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg); -/*%< - * Set the isself callback function and argument. - * - * bool - * isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_netaddr_t *srcaddr, - * isc_netaddr_t *destaddr, dns_rdataclass_t rdclass, void *arg); - * - * 'isself' returns true if a non-recursive query from 'srcaddr' to - * 'destaddr' with optional key 'mykey' for class 'rdclass' would be - * delivered to 'myview'. - */ - -void -dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes); -/*%< - * Set the number of nodes that will be checked per quantum. - */ - -void -dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures); -/*%< - * Set the number of signatures that will be generated per quantum. - */ - -uint32_t -dns_zone_getsignatures(dns_zone_t *zone); -/*%< - * Get the number of signatures that will be generated per quantum. - */ - -isc_result_t -dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, - uint16_t keyid, bool deleteit); -/*%< - * Initiate/resume signing of the entire zone with the zone DNSKEY(s) - * that match the given algorithm and keyid. - */ - -isc_result_t -dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param); -/*%< - * Incrementally add a NSEC3 chain that corresponds to 'nsec3param'. - */ - -void -dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type); -dns_rdatatype_t -dns_zone_getprivatetype(dns_zone_t *zone); -/* - * Get/Set the private record type. It is expected that these interfaces - * will not be permanent. - */ - -void -dns_zone_rekey(dns_zone_t *zone, bool fullsign); -/*%< - * Update the zone's DNSKEY set from the key repository. - * - * If 'fullsign' is true, trigger an immediate full signing of - * the zone with the new key. Otherwise, if there are no keys or - * if the new keys are for algorithms that have already signed the - * zone, then the zone can be re-signed incrementally. - */ - -isc_result_t -dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, - unsigned int *errors); -/*% - * Check if the name servers for the zone are sane (have address, don't - * refer to CNAMEs/DNAMEs. The number of constiancy errors detected in - * returned in '*errors' - * - * Requires: - * \li 'zone' to be valid. - * \li 'db' to be valid. - * \li 'version' to be valid or NULL. - * \li 'errors' to be non NULL. - * - * Returns: - * ISC_R_SUCCESS if there were no errors examining the zone contents. - */ - -isc_result_t -dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version); -/*% - * Check if CSD, CDNSKEY and DNSKEY are consistent. - * - * Requires: - * \li 'zone' to be valid. - * \li 'db' to be valid. - * \li 'version' to be valid or NULL. - * - * Returns: - *\li #ISC_R_SUCCESS - *\li #DNS_R_BADCDS - *\li #DNS_R_BADCDNSKEY - * Others - */ - -void -dns_zone_setadded(dns_zone_t *zone, bool added); -/*% - * Sets the value of zone->added, which should be true for - * zones that were originally added by "rndc addzone". - * - * Requires: - * \li 'zone' to be valid. - */ - -bool -dns_zone_getadded(dns_zone_t *zone); -/*% - * Returns true if the zone was originally added at runtime - * using "rndc addzone". - * - * Requires: - * \li 'zone' to be valid. - */ - -void -dns_zone_setautomatic(dns_zone_t *zone, bool automatic); -/*% - * Sets the value of zone->automatic, which should be true for - * zones that were automatically added by named. - * - * Requires: - * \li 'zone' to be valid. - */ - -bool -dns_zone_getautomatic(dns_zone_t *zone); -/*% - * Returns true if the zone was added automatically by named. - * - * Requires: - * \li 'zone' to be valid. - */ - -isc_result_t -dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db); -/*% - * Load the origin names for a writeable DLZ database. - */ - -bool -dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze); -/*% - * Return true iff the zone is "dynamic", in the sense that the zone's - * master file (if any) is written by the server, rather than being - * updated manually and read by the server. - * - * This is true for slave zones, stub zones, key zones, and zones that - * allow dynamic updates either by having an update policy ("ssutable") - * or an "allow-update" ACL with a value other than exactly "{ none; }". - * - * If 'ignore_freeze' is true, then the zone which has had updates disabled - * will still report itself to be dynamic. - * - * Requires: - * \li 'zone' to be valid. - */ - -isc_result_t -dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval); -/*% - * Sets the frequency, in minutes, with which the key repository will be - * checked to see if the keys for this zone have been updated. Any value - * higher than 1440 minutes (24 hours) will be silently reduced. A - * value of zero will return an out-of-range error. - * - * Requires: - * \li 'zone' to be valid. - */ - -bool -dns_zone_getrequestexpire(dns_zone_t *zone); -/*% - * Returns the true/false value of the request-expire option in the zone. - * - * Requires: - * \li 'zone' to be valid. - */ - -void -dns_zone_setrequestexpire(dns_zone_t *zone, bool flag); -/*% - * Sets the request-expire option for the zone. Either true or false. The - * default value is determined by the setting of this option in the view. - * - * Requires: - * \li 'zone' to be valid. - */ - - -bool -dns_zone_getrequestixfr(dns_zone_t *zone); -/*% - * Returns the true/false value of the request-ixfr option in the zone. - * - * Requires: - * \li 'zone' to be valid. - */ - -void -dns_zone_setrequestixfr(dns_zone_t *zone, bool flag); -/*% - * Sets the request-ixfr option for the zone. Either true or false. The - * default value is determined by the setting of this option in the view. - * - * Requires: - * \li 'zone' to be valid. - */ - -void -dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method); -/*% - * Sets the update method to use when incrementing the zone serial number - * due to a DDNS update. Valid options are dns_updatemethod_increment - * and dns_updatemethod_unixtime. - * - * Requires: - * \li 'zone' to be valid. - */ - -dns_updatemethod_t -dns_zone_getserialupdatemethod(dns_zone_t *zone); -/*% - * Returns the update method to be used when incrementing the zone serial - * number due to a DDNS update. - * - * Requires: - * \li 'zone' to be valid. - */ - -isc_result_t -dns_zone_link(dns_zone_t *zone, dns_zone_t *raw); - -void -dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw); - -isc_result_t -dns_zone_keydone(dns_zone_t *zone, const char *data); - -isc_result_t -dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags, - uint16_t iter, uint8_t saltlen, - unsigned char *salt, bool replace); -/*% - * Set the NSEC3 parameters for the zone. - * - * If 'replace' is true, then the existing NSEC3 chain, if any, will - * be replaced with the new one. If 'hash' is zero, then the replacement - * chain will be NSEC rather than NSEC3. - * - * Requires: - * \li 'zone' to be valid. - */ - -void -dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header); -/*% - * Set the data to be included in the header when the zone is dumped in - * binary format. - */ - -isc_result_t -dns_zone_synckeyzone(dns_zone_t *zone); -/*% - * Force the managed key zone to synchronize, and start the key - * maintenance timer. - */ - -isc_result_t -dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime); -/*% - * Return the time when the zone was last loaded. - */ - -isc_result_t -dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime); -/*% - * Return the time when the (slave) zone will need to be refreshed. - */ - -isc_result_t -dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime); -/*% - * Return the time when the (slave) zone will expire. - */ - -isc_result_t -dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime); -/*% - * Return the time of the next scheduled DNSSEC key event. - */ - -unsigned int -dns_zone_getincludes(dns_zone_t *zone, char ***includesp); -/*% - * Return the number include files that were encountered - * during load. If the number is greater than zero, 'includesp' - * will point to an array containing the filenames. - * - * The array and its contents need to be freed using isc_mem_free. - */ - -isc_result_t -dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, - dns_rpz_num_t rpz_num); -/*% - * Set the response policy associated with a zone. - */ - -void -dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db); -/*% - * If a zone is a response policy zone, mark its new database. - */ - -dns_rpz_num_t -dns_zone_get_rpz_num(dns_zone_t *zone); - -void -dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs); -/*%< - * Enable zone as catalog zone. - * - * Requires: - * - * \li 'zone' is a valid zone object - * \li 'catzs' is not NULL - * \li prior to calling, zone->catzs is NULL or is equal to 'catzs' - */ - -void -dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db); -/*%< - * If 'zone' is a catalog zone, then set up a notify-on-update trigger - * in its database. (If not a catalog zone, this function has no effect.) - * - * Requires: - * - * \li 'zone' is a valid zone object - * \li 'db' is not NULL - */ -void -dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz); -/*%< - * Set parent catalog zone for this zone - * - * Requires: - * - * \li 'zone' is a valid zone object - * \li 'catz' is not NULL - */ - -dns_catz_zone_t * -dns_zone_get_parentcatz(const dns_zone_t *zone); -/*%< - * Get parent catalog zone for this zone - * - * Requires: - * - * \li 'zone' is a valid zone object - */ - - -void -dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level); - -dns_zonestat_level_t -dns_zone_getstatlevel(dns_zone_t *zone); -/*% - * Set and get the statistics reporting level for the zone; - * full, terse, or none. - */ - -isc_result_t -dns_zone_setserial(dns_zone_t *zone, uint32_t serial); -/*% - * Set the zone's serial to 'serial'. - */ -ISC_LANG_ENDDECLS - - -#endif /* DNS_ZONE_H */ diff --git a/lib/dns-pkcs11/include/dns/zonekey.h b/lib/dns-pkcs11/include/dns/zonekey.h deleted file mode 100644 index dd45fbc..0000000 --- a/lib/dns-pkcs11/include/dns/zonekey.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ZONEKEY_H -#define DNS_ZONEKEY_H 1 - -/*! \file dns/zonekey.h */ - -#include - -#include - -#include - -ISC_LANG_BEGINDECLS - -bool -dns_zonekey_iszonekey(dns_rdata_t *keyrdata); -/*%< - * Determines if the key record contained in the rdata is a zone key. - * - * Requires: - * 'keyrdata' is not NULL. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ZONEKEY_H */ diff --git a/lib/dns-pkcs11/include/dns/zt.h b/lib/dns-pkcs11/include/dns/zt.h deleted file mode 100644 index e658e5b..0000000 --- a/lib/dns-pkcs11/include/dns/zt.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_ZT_H -#define DNS_ZT_H 1 - -/*! \file dns/zt.h */ - -#include - -#include - -#include - -#define DNS_ZTFIND_NOEXACT 0x01 - -ISC_LANG_BEGINDECLS - -typedef isc_result_t -(*dns_zt_allloaded_t)(void *arg); -/*%< - * Method prototype: when all pending zone loads are complete, - * the zone table can inform the caller via a callback function with - * this signature. - */ - -typedef isc_result_t -(*dns_zt_zoneloaded_t)(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task); -/*%< - * Method prototype: when a zone finishes loading, the zt object - * can be informed via a callback function with this signature. - */ - -isc_result_t -dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **zt); -/*%< - * Creates a new zone table. - * - * Requires: - * \li 'mctx' to be initialized. - * - * Returns: - * \li #ISC_R_SUCCESS on success. - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone); -/*%< - * Mounts the zone on the zone table. - * - * Requires: - * \li 'zt' to be valid - * \li 'zone' to be valid - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_EXISTS - * \li #ISC_R_NOSPACE - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone); -/*%< - * Unmount the given zone from the table. - * - * Requires: - * 'zt' to be valid - * \li 'zone' to be valid - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #ISC_R_NOTFOUND - * \li #ISC_R_NOMEMORY - */ - -isc_result_t -dns_zt_find(dns_zt_t *zt, const dns_name_t *name, unsigned int options, - dns_name_t *foundname, dns_zone_t **zone); -/*%< - * Find the best match for 'name' in 'zt'. If foundname is non NULL - * then the name of the zone found is returned. - * - * Notes: - * \li If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any) - * to 'name' will be returned. - * - * Requires: - * \li 'zt' to be valid - * \li 'name' to be valid - * \li 'foundname' to be initialized and associated with a fixedname or NULL - * \li 'zone' to be non NULL and '*zone' to be NULL - * - * Returns: - * \li #ISC_R_SUCCESS - * \li #DNS_R_PARTIALMATCH - * \li #ISC_R_NOTFOUND - * \li #ISC_R_NOSPACE - */ - -void -dns_zt_detach(dns_zt_t **ztp); -/*%< - * Detach the given zonetable, if the reference count goes to zero the - * zonetable will be freed. In either case 'ztp' is set to NULL. - * - * Requires: - * \li '*ztp' to be valid - */ - -void -dns_zt_flushanddetach(dns_zt_t **ztp); -/*%< - * Detach the given zonetable, if the reference count goes to zero the - * zonetable will be flushed and then freed. In either case 'ztp' is - * set to NULL. - * - * Requires: - * \li '*ztp' to be valid - */ - -void -dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp); -/*%< - * Attach 'zt' to '*ztp'. - * - * Requires: - * \li 'zt' to be valid - * \li '*ztp' to be NULL - */ - -isc_result_t -dns_zt_load(dns_zt_t *zt, bool stop); - -isc_result_t -dns_zt_loadnew(dns_zt_t *zt, bool stop); - -isc_result_t -dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg); - -isc_result_t -dns_zt_asyncload2(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg, - bool newonly); -/*%< - * Load all zones in the table. If 'stop' is true, - * stop on the first error and return it. If 'stop' - * is false, ignore errors. - * - * dns_zt_loadnew() only loads zones that are not yet loaded. - * dns_zt_load() also loads zones that are already loaded and - * and whose master file has changed since the last load. - * dns_zt_asyncload() loads zones asynchronously; when all - * zones in the zone table have finished loaded (or failed due - * to errors), the caller is informed by calling 'alldone' - * with an argument of 'arg'. - * - * Requires: - * \li 'zt' to be valid - */ - -isc_result_t -dns_zt_freezezones(dns_zt_t *zt, bool freeze); -/*%< - * Freeze/thaw updates to master zones. - * Any pending updates will be flushed. - * Zones will be reloaded on thaw. - */ - -isc_result_t -dns_zt_apply(dns_zt_t *zt, bool stop, - isc_result_t (*action)(dns_zone_t *, void *), void *uap); - -isc_result_t -dns_zt_apply2(dns_zt_t *zt, bool stop, isc_result_t *sub, - isc_result_t (*action)(dns_zone_t *, void *), void *uap); -/*%< - * Apply a given 'action' to all zone zones in the table. - * If 'stop' is 'true' then walking the zone tree will stop if - * 'action' does not return ISC_R_SUCCESS. - * - * Requires: - * \li 'zt' to be valid. - * \li 'action' to be non NULL. - * - * Returns: - * \li ISC_R_SUCCESS if action was applied to all nodes. If 'stop' is - * false and 'sub' is non NULL then the first error (if any) - * reported by 'action' is returned in '*sub'; - * any error code from 'action'. - */ - -bool -dns_zt_loadspending(dns_zt_t *zt); -/*%< - * Returns true if and only if there are zones still waiting to - * be loaded in zone table 'zt'. - * - * Requires: - * \li 'zt' to be valid. - */ - -void -dns_zt_setviewcommit(dns_zt_t *zt); -/*%< - * Commit dns_zone_setview() calls previously made for all zones in this - * zone table. - * - * Requires: - *\li 'view' to be valid. - */ - -void -dns_zt_setviewrevert(dns_zt_t *zt); -/*%< - * Revert dns_zone_setview() calls previously made for all zones in this - * zone table. - * - * Requires: - *\li 'view' to be valid. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_ZT_H */ diff --git a/lib/dns-pkcs11/include/dst/Makefile.in b/lib/dns-pkcs11/include/dst/Makefile.in deleted file mode 100644 index 4992483..0000000 --- a/lib/dns-pkcs11/include/dst/Makefile.in +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -VERSION=@BIND9_VERSION@ - -HEADERS = dst.h gssapi.h lib.h result.h - -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/dst - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dst || exit 1; \ - done - -uninstall:: - for i in ${HEADERS}; do \ - rm -f ${DESTDIR}${includedir}/dst/$$i || exit 1; \ - done diff --git a/lib/dns-pkcs11/include/dst/dst.h b/lib/dns-pkcs11/include/dst/dst.h deleted file mode 100644 index 180c841..0000000 --- a/lib/dns-pkcs11/include/dst/dst.h +++ /dev/null @@ -1,1013 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DST_DST_H -#define DST_DST_H 1 - -/*! \file dst/dst.h */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -/*% - * The dst_key structure is opaque. Applications should use the accessor - * functions provided to retrieve key attributes. If an application needs - * to set attributes, new accessor functions will be written. - */ - -typedef struct dst_key dst_key_t; -typedef struct dst_context dst_context_t; - -/* DST algorithm codes */ -#define DST_ALG_UNKNOWN 0 -#define DST_ALG_RSAMD5 1 -#define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */ -#define DST_ALG_DH 2 -#define DST_ALG_DSA 3 -#define DST_ALG_ECC 4 -#define DST_ALG_RSASHA1 5 -#define DST_ALG_NSEC3DSA 6 -#define DST_ALG_NSEC3RSASHA1 7 -#define DST_ALG_RSASHA256 8 -#define DST_ALG_RSASHA512 10 -#define DST_ALG_ECCGOST 12 -#define DST_ALG_ECDSA256 13 -#define DST_ALG_ECDSA384 14 -#define DST_ALG_ED25519 15 -#define DST_ALG_ED448 16 -#define DST_ALG_HMACMD5 157 -#define DST_ALG_GSSAPI 160 -#define DST_ALG_HMACSHA1 161 /* XXXMPA */ -#define DST_ALG_HMACSHA224 162 /* XXXMPA */ -#define DST_ALG_HMACSHA256 163 /* XXXMPA */ -#define DST_ALG_HMACSHA384 164 /* XXXMPA */ -#define DST_ALG_HMACSHA512 165 /* XXXMPA */ -#define DST_ALG_INDIRECT 252 -#define DST_ALG_PRIVATE 254 -#define DST_MAX_ALGS 256 - -/*% A buffer of this size is large enough to hold any key */ -#define DST_KEY_MAXSIZE 1280 - -/*% - * A buffer of this size is large enough to hold the textual representation - * of any key - */ -#define DST_KEY_MAXTEXTSIZE 2048 - -/*% 'Type' for dst_read_key() */ -#define DST_TYPE_KEY 0x1000000 /* KEY key */ -#define DST_TYPE_PRIVATE 0x2000000 -#define DST_TYPE_PUBLIC 0x4000000 - -/* Key timing metadata definitions */ -#define DST_TIME_CREATED 0 -#define DST_TIME_PUBLISH 1 -#define DST_TIME_ACTIVATE 2 -#define DST_TIME_REVOKE 3 -#define DST_TIME_INACTIVE 4 -#define DST_TIME_DELETE 5 -#define DST_TIME_DSPUBLISH 6 -#define DST_TIME_SYNCPUBLISH 7 -#define DST_TIME_SYNCDELETE 8 -#define DST_MAX_TIMES 8 - -/* Numeric metadata definitions */ -#define DST_NUM_PREDECESSOR 0 -#define DST_NUM_SUCCESSOR 1 -#define DST_NUM_MAXTTL 2 -#define DST_NUM_ROLLPERIOD 3 -#define DST_MAX_NUMERIC 3 - -/* - * Current format version number of the private key parser. - * - * When parsing a key file with the same major number but a higher minor - * number, the key parser will ignore any fields it does not recognize. - * Thus, DST_MINOR_VERSION should be incremented whenever new - * fields are added to the private key file (such as new metadata). - * - * When rewriting these keys, those fields will be dropped, and the - * format version set back to the current one.. - * - * When a key is seen with a higher major number, the key parser will - * reject it as invalid. Thus, DST_MAJOR_VERSION should be incremented - * and DST_MINOR_VERSION set to zero whenever there is a format change - * which is not backward compatible to previous versions of the dst_key - * parser, such as change in the syntax of an existing field, the removal - * of a currently mandatory field, or a new field added which would - * alter the functioning of the key if it were absent. - */ -#define DST_MAJOR_VERSION 1 -#define DST_MINOR_VERSION 3 - -/*** - *** Functions - ***/ - -isc_result_t -dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags); - -isc_result_t -dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, - const char *engine, unsigned int eflags); -/*%< - * Initializes the DST subsystem. - * - * Requires: - * \li "mctx" is a valid memory context - * \li "ectx" is a valid entropy context - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - * \li DST_R_NOENGINE - * - * Ensures: - * \li DST is properly initialized. - */ - -void -dst_lib_destroy(void); -/*%< - * Releases all resources allocated by DST. - */ - -isc_result_t -dst_random_getdata(void *data, unsigned int length, - unsigned int *returned, unsigned int flags); -/*%< - * Gets random data from the random generator provided by the - * crypto library, if BIND was built with --enable-crypto-rand. - * - * See isc_entropy_getdata() for parameter usage. Normally when - * this function is available, it will be set up as a hook in the - * entropy context, so that isc_entropy_getdata() is a front-end to - * this function. - * - * Returns: - * \li ISC_R_SUCCESS on success - * \li ISC_R_NOTIMPLEMENTED if BIND is built with --disable-crypto-rand - * \li DST_R_OPENSSLFAILURE, DST_R_CRYPTOFAILURE, or other codes on error - */ - -bool -dst_algorithm_supported(unsigned int alg); -/*%< - * Checks that a given algorithm is supported by DST. - * - * Returns: - * \li true - * \li false - */ - -bool -dst_ds_digest_supported(unsigned int digest_type); -/*%< - * Checks that a given digest algorithm is supported by DST. - * - * Returns: - * \li true - * \li false - */ - -isc_result_t -dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp); - -isc_result_t -dst_context_create2(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, dst_context_t **dctxp); - -isc_result_t -dst_context_create3(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, bool useforsigning, - dst_context_t **dctxp); - -isc_result_t -dst_context_create4(dst_key_t *key, isc_mem_t *mctx, - isc_logcategory_t *category, bool useforsigning, - int maxbits, dst_context_t **dctxp); -/*%< - * Creates a context to be used for a sign or verify operation. - * - * Requires: - * \li "key" is a valid key. - * \li "mctx" is a valid memory context. - * \li dctxp != NULL && *dctxp == NULL - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - * - * Ensures: - * \li *dctxp will contain a usable context. - */ - -void -dst_context_destroy(dst_context_t **dctxp); -/*%< - * Destroys all memory associated with a context. - * - * Requires: - * \li *dctxp != NULL && *dctxp == NULL - * - * Ensures: - * \li *dctxp == NULL - */ - -isc_result_t -dst_context_adddata(dst_context_t *dctx, const isc_region_t *data); -/*%< - * Incrementally adds data to the context to be used in a sign or verify - * operation. - * - * Requires: - * \li "dctx" is a valid context - * \li "data" is a valid region - * - * Returns: - * \li ISC_R_SUCCESS - * \li DST_R_SIGNFAILURE - * \li all other errors indicate failure - */ - -isc_result_t -dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig); -/*%< - * Computes a signature using the data and key stored in the context. - * - * Requires: - * \li "dctx" is a valid context. - * \li "sig" is a valid buffer. - * - * Returns: - * \li ISC_R_SUCCESS - * \li DST_R_VERIFYFAILURE - * \li all other errors indicate failure - * - * Ensures: - * \li "sig" will contain the signature - */ - -isc_result_t -dst_context_verify(dst_context_t *dctx, isc_region_t *sig); - -isc_result_t -dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, - isc_region_t *sig); -/*%< - * Verifies the signature using the data and key stored in the context. - * - * 'maxbits' specifies the maximum number of bits permitted in the RSA - * exponent. - * - * Requires: - * \li "dctx" is a valid context. - * \li "sig" is a valid region. - * - * Returns: - * \li ISC_R_SUCCESS - * \li all other errors indicate failure - * - * Ensures: - * \li "sig" will contain the signature - */ - -isc_result_t -dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, - isc_buffer_t *secret); -/*%< - * Computes a shared secret from two (Diffie-Hellman) keys. - * - * Requires: - * \li "pub" is a valid key that can be used to derive a shared secret - * \li "priv" is a valid private key that can be used to derive a shared secret - * \li "secret" is a valid buffer - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - * \li If successful, secret will contain the derived shared secret. - */ - -isc_result_t -dst_key_getfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg, - int type, const char *directory, - isc_mem_t *mctx, isc_buffer_t *buf); -/*%< - * Generates a key filename for the name, algorithm, and - * id, and places it in the buffer 'buf'. If directory is NULL, the - * current directory is assumed. - * - * Requires: - * \li "name" is a valid absolute dns name. - * \li "id" is a valid key tag identifier. - * \li "alg" is a supported key algorithm. - * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. - * DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * \li "mctx" is a valid memory context. - * \li "buf" is not NULL. - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - */ - -isc_result_t -dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, - const char *directory, isc_mem_t *mctx, dst_key_t **keyp); -/*%< - * Reads a key from permanent storage. The key can either be a public or - * private key, and is specified by name, algorithm, and id. If a private key - * is specified, the public key must also be present. If directory is NULL, - * the current directory is assumed. - * - * Requires: - * \li "name" is a valid absolute dns name. - * \li "id" is a valid key tag identifier. - * \li "alg" is a supported key algorithm. - * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. - * DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * \li "mctx" is a valid memory context. - * \li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - * \li If successful, *keyp will contain a valid key. - */ - -isc_result_t -dst_key_fromnamedfile(const char *filename, const char *dirname, - int type, isc_mem_t *mctx, dst_key_t **keyp); -/*%< - * Reads a key from permanent storage. The key can either be a public or - * key, and is specified by filename. If a private key is specified, the - * public key must also be present. - * - * If 'dirname' is not NULL, and 'filename' is a relative path, - * then the file is looked up relative to the given directory. - * If 'filename' is an absolute path, 'dirname' is ignored. - * - * Requires: - * \li "filename" is not NULL - * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union - * DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * \li "mctx" is a valid memory context - * \li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - * \li If successful, *keyp will contain a valid key. - */ - - -isc_result_t -dst_key_read_public(const char *filename, int type, - isc_mem_t *mctx, dst_key_t **keyp); -/*%< - * Reads a public key from permanent storage. The key must be a public key. - * - * Requires: - * \li "filename" is not NULL - * \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * \li "mctx" is a valid memory context - * \li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - * \li ISC_R_SUCCESS - * \li DST_R_BADKEYTYPE if the key type is not the expected one - * \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key - * \li any other result indicates failure - * - * Ensures: - * \li If successful, *keyp will contain a valid key. - */ - -isc_result_t -dst_key_tofile(const dst_key_t *key, int type, const char *directory); -/*%< - * Writes a key to permanent storage. The key can either be a public or - * private key. Public keys are written in DNS format and private keys - * are written as a set of base64 encoded values. If directory is NULL, - * the current directory is assumed. - * - * Requires: - * \li "key" is a valid key. - * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - */ - -isc_result_t -dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, - isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); -/*%< - * Converts a DNS KEY record into a DST key. - * - * Requires: - * \li "name" is a valid absolute dns name. - * \li "source" is a valid buffer. There must be at least 4 bytes available. - * \li "mctx" is a valid memory context. - * \li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - * \li If successful, *keyp will contain a valid key, and the consumed - * pointer in data will be advanced. - */ - -isc_result_t -dst_key_todns(const dst_key_t *key, isc_buffer_t *target); -/*%< - * Converts a DST key into a DNS KEY record. - * - * Requires: - * \li "key" is a valid key. - * \li "target" is a valid buffer. There must be at least 4 bytes unused. - * - * Returns: - * \li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - * \li If successful, the used pointer in 'target' is advanced by at least 4. - */ - -isc_result_t -dst_key_frombuffer(dns_name_t *name, unsigned int alg, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); -/*%< - * Converts a buffer containing DNS KEY RDATA into a DST key. - * - * Requires: - *\li "name" is a valid absolute dns name. - *\li "alg" is a supported key algorithm. - *\li "source" is a valid buffer. - *\li "mctx" is a valid memory context. - *\li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - *\li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - *\li If successful, *keyp will contain a valid key, and the consumed - * pointer in source will be advanced. - */ - -isc_result_t -dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target); -/*%< - * Converts a DST key into DNS KEY RDATA format. - * - * Requires: - *\li "key" is a valid key. - *\li "target" is a valid buffer. - * - * Returns: - *\li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - *\li If successful, the used pointer in 'target' is advanced. - */ - -isc_result_t -dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer); -/*%< - * Converts a public key into a private key, reading the private key - * information from the buffer. The buffer should contain the same data - * as the .private key file would. - * - * Requires: - *\li "key" is a valid public key. - *\li "buffer" is not NULL. - * - * Returns: - *\li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - *\li If successful, key will contain a valid private key. - */ - -gss_ctx_id_t -dst_key_getgssctx(const dst_key_t *key); -/*%< - * Returns the opaque key data. - * Be cautions when using this value unless you know what you are doing. - * - * Requires: - *\li "key" is not NULL. - * - * Returns: - *\li gssctx key data, possibly NULL. - */ - -isc_result_t -dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, - dst_key_t **keyp, isc_region_t *intoken); -/*%< - * Converts a GSSAPI opaque context id into a DST key. - * - * Requires: - *\li "name" is a valid absolute dns name. - *\li "gssctx" is a GSSAPI context id. - *\li "mctx" is a valid memory context. - *\li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - *\li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - *\li If successful, *keyp will contain a valid key and be responsible for - * the context id. - */ - -#ifdef DST_KEY_INTERNAL -isc_result_t -dst_key_buildinternal(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - void *data, isc_mem_t *mctx, dst_key_t **keyp); -#endif - -isc_result_t -dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - const char *engine, const char *label, const char *pin, - isc_mem_t *mctx, dst_key_t **keyp); - -isc_result_t -dst_key_generate(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int param, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_mem_t *mctx, dst_key_t **keyp); - -isc_result_t -dst_key_generate2(dns_name_t *name, unsigned int alg, - unsigned int bits, unsigned int param, - unsigned int flags, unsigned int protocol, - dns_rdataclass_t rdclass, - isc_mem_t *mctx, dst_key_t **keyp, - void (*callback)(int)); - -/*%< - * Generate a DST key (or keypair) with the supplied parameters. The - * interpretation of the "param" field depends on the algorithm: - * \code - * RSA: exponent - * 0 use exponent 3 - * !0 use Fermat4 (2^16 + 1) - * DH: generator - * 0 default - use well known prime if bits == 768 or 1024, - * otherwise use 2 as the generator. - * !0 use this value as the generator. - * DSA: unused - * HMACMD5: entropy - * 0 default - require good entropy - * !0 lack of good entropy is ok - *\endcode - * - * Requires: - *\li "name" is a valid absolute dns name. - *\li "keyp" is not NULL and "*keyp" is NULL. - * - * Returns: - *\li ISC_R_SUCCESS - * \li any other result indicates failure - * - * Ensures: - *\li If successful, *keyp will contain a valid key. - */ - -bool -dst_key_compare(const dst_key_t *key1, const dst_key_t *key2); -/*%< - * Compares two DST keys. Returns true if they match, false otherwise. - * - * Keys ARE NOT considered to match if one of them is the revoked version - * of the other. - * - * Requires: - *\li "key1" is a valid key. - *\li "key2" is a valid key. - * - * Returns: - *\li true - * \li false - */ - -bool -dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2, - bool match_revoked_key); -/*%< - * Compares only the public portions of two DST keys. Returns true - * if they match, false otherwise. This allows us, for example, to - * determine whether a public key found in a zone matches up with a - * key pair found on disk. - * - * If match_revoked_key is TRUE, then keys ARE considered to match if one - * of them is the revoked version of the other. Otherwise, they are not. - * - * Requires: - *\li "key1" is a valid key. - *\li "key2" is a valid key. - * - * Returns: - *\li true - * \li false - */ - -bool -dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2); -/*%< - * Compares the parameters of two DST keys. This is used to determine if - * two (Diffie-Hellman) keys can be used to derive a shared secret. - * - * Requires: - *\li "key1" is a valid key. - *\li "key2" is a valid key. - * - * Returns: - *\li true - * \li false - */ - -void -dst_key_attach(dst_key_t *source, dst_key_t **target); -/* - * Attach to a existing key increasing the reference count. - * - * Requires: - *\li 'source' to be a valid key. - *\li 'target' to be non-NULL and '*target' to be NULL. - */ - -void -dst_key_free(dst_key_t **keyp); -/*%< - * Decrement the key's reference counter and, when it reaches zero, - * release all memory associated with the key. - * - * Requires: - *\li "keyp" is not NULL and "*keyp" is a valid key. - *\li reference counter greater than zero. - * - * Ensures: - *\li All memory associated with "*keyp" will be freed. - *\li *keyp == NULL - */ - -/*%< - * Accessor functions to obtain key fields. - * - * Require: - *\li "key" is a valid key. - */ -dns_name_t * -dst_key_name(const dst_key_t *key); - -unsigned int -dst_key_size(const dst_key_t *key); - -unsigned int -dst_key_proto(const dst_key_t *key); - -unsigned int -dst_key_alg(const dst_key_t *key); - -uint32_t -dst_key_flags(const dst_key_t *key); - -dns_keytag_t -dst_key_id(const dst_key_t *key); - -dns_keytag_t -dst_key_rid(const dst_key_t *key); - -dns_rdataclass_t -dst_key_class(const dst_key_t *key); - -bool -dst_key_isprivate(const dst_key_t *key); - -bool -dst_key_iszonekey(const dst_key_t *key); - -bool -dst_key_isnullkey(const dst_key_t *key); - -isc_result_t -dst_key_buildfilename(const dst_key_t *key, int type, - const char *directory, isc_buffer_t *out); -/*%< - * Generates the filename used by dst to store the specified key. - * If directory is NULL, the current directory is assumed. - * - * Requires: - *\li "key" is a valid key - *\li "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix. - *\li "out" is a valid buffer - * - * Ensures: - *\li the file name will be written to "out", and the used pointer will - * be advanced. - */ - -isc_result_t -dst_key_sigsize(const dst_key_t *key, unsigned int *n); -/*%< - * Computes the size of a signature generated by the given key. - * - * Requires: - *\li "key" is a valid key. - *\li "n" is not NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li DST_R_UNSUPPORTEDALG - * - * Ensures: - *\li "n" stores the size of a generated signature - */ - -isc_result_t -dst_key_secretsize(const dst_key_t *key, unsigned int *n); -/*%< - * Computes the size of a shared secret generated by the given key. - * - * Requires: - *\li "key" is a valid key. - *\li "n" is not NULL - * - * Returns: - *\li #ISC_R_SUCCESS - *\li DST_R_UNSUPPORTEDALG - * - * Ensures: - *\li "n" stores the size of a generated shared secret - */ - -uint16_t -dst_region_computeid(const isc_region_t *source, unsigned int alg); -uint16_t -dst_region_computerid(const isc_region_t *source, unsigned int alg); -/*%< - * Computes the (revoked) key id of the key stored in the provided - * region with the given algorithm. - * - * Requires: - *\li "source" contains a valid, non-NULL region. - * - * Returns: - *\li the key id - */ - -uint16_t -dst_key_getbits(const dst_key_t *key); -/*%< - * Get the number of digest bits required (0 == MAX). - * - * Requires: - * "key" is a valid key. - */ - -void -dst_key_setbits(dst_key_t *key, uint16_t bits); -/*%< - * Set the number of digest bits required (0 == MAX). - * - * Requires: - * "key" is a valid key. - */ - -void -dst_key_setttl(dst_key_t *key, dns_ttl_t ttl); -/*%< - * Set the default TTL to use when converting the key - * to a KEY or DNSKEY RR. - * - * Requires: - * "key" is a valid key. - */ - -dns_ttl_t -dst_key_getttl(const dst_key_t *key); -/*%< - * Get the default TTL to use when converting the key - * to a KEY or DNSKEY RR. - * - * Requires: - * "key" is a valid key. - */ - -isc_result_t -dst_key_setflags(dst_key_t *key, uint32_t flags); -/* - * Set the key flags, and recompute the key ID. - * - * Requires: - * "key" is a valid key. - */ - -isc_result_t -dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep); -/*%< - * Get a member of the numeric metadata array and place it in '*valuep'. - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC - * "timep" is not null. - */ - -void -dst_key_setnum(dst_key_t *key, int type, uint32_t value); -/*%< - * Set a member of the numeric metadata array. - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC - */ - -void -dst_key_unsetnum(dst_key_t *key, int type); -/*%< - * Flag a member of the numeric metadata array as "not set". - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC - */ - -isc_result_t -dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep); -/*%< - * Get a member of the timing metadata array and place it in '*timep'. - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES - * "timep" is not null. - */ - -void -dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when); -/*%< - * Set a member of the timing metadata array. - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES - */ - -void -dst_key_unsettime(dst_key_t *key, int type); -/*%< - * Flag a member of the timing metadata array as "not set". - * - * Requires: - * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES - */ - -isc_result_t -dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp); -/*%< - * Get the private key format version number. (If the key does not have - * a private key associated with it, the version will be 0.0.) The major - * version number is placed in '*majorp', and the minor version number in - * '*minorp'. - * - * Requires: - * "key" is a valid key. - * "majorp" is not NULL. - * "minorp" is not NULL. - */ - -void -dst_key_setprivateformat(dst_key_t *key, int major, int minor); -/*%< - * Set the private key format version number. - * - * Requires: - * "key" is a valid key. - */ - -#define DST_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + 7) - -void -dst_key_format(const dst_key_t *key, char *cp, unsigned int size); -/*%< - * Write the uniquely identifying information about the key (name, - * algorithm, key ID) into a string 'cp' of size 'size'. - */ - - -isc_buffer_t * -dst_key_tkeytoken(const dst_key_t *key); -/*%< - * Return the token from the TKEY request, if any. If this key was - * not negotiated via TKEY, return NULL. - * - * Requires: - * "key" is a valid key. - */ - - -isc_result_t -dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length); -/*%< - * Allocate 'buffer' and dump the key into it in base64 format. The buffer - * is not NUL terminated. The length of the buffer is returned in *length. - * - * 'buffer' needs to be freed using isc_mem_put(mctx, buffer, length); - * - * Requires: - * 'buffer' to be non NULL and *buffer to be NULL. - * 'length' to be non NULL and *length to be zero. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOTIMPLEMENTED - * others. - */ - -isc_result_t -dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, - unsigned int protocol, dns_rdataclass_t rdclass, - isc_mem_t *mctx, const char *keystr, dst_key_t **keyp); - -bool -dst_key_inactive(const dst_key_t *key); -/*%< - * Determines if the private key is missing due the key being deemed inactive. - * - * Requires: - * 'key' to be valid. - */ - -void -dst_key_setinactive(dst_key_t *key, bool inactive); -/*%< - * Set key inactive state. - * - * Requires: - * 'key' to be valid. - */ - -void -dst_key_setexternal(dst_key_t *key, bool value); - -bool -dst_key_isexternal(dst_key_t *key); - -ISC_LANG_ENDDECLS - -#endif /* DST_DST_H */ diff --git a/lib/dns-pkcs11/include/dst/gssapi.h b/lib/dns-pkcs11/include/dst/gssapi.h deleted file mode 100644 index a70ad7a..0000000 --- a/lib/dns-pkcs11/include/dst/gssapi.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DST_GSSAPI_H -#define DST_GSSAPI_H 1 - -/*! \file dst/gssapi.h */ - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef GSSAPI -#ifdef WIN32 -/* - * MSVC does not like macros in #include lines. - */ -#include -#include -#else -#include ISC_PLATFORM_GSSAPIHEADER -#ifdef ISC_PLATFORM_GSSAPI_KRB5_HEADER -#include ISC_PLATFORM_GSSAPI_KRB5_HEADER -#endif -#endif -#ifndef GSS_SPNEGO_MECHANISM -#define GSS_SPNEGO_MECHANISM ((void*)0) -#endif -#endif - -ISC_LANG_BEGINDECLS - -/*** - *** Types - ***/ - -/*** - *** Functions - ***/ - -isc_result_t -dst_gssapi_acquirecred(dns_name_t *name, bool initiate, - gss_cred_id_t *cred); -/* - * Acquires GSS credentials. - * - * Requires: - * 'name' is a valid name, preferably one known by the GSS provider - * 'initiate' indicates whether the credentials are for initiating or - * accepting contexts - * 'cred' is a pointer to NULL, which will be allocated with the - * credential handle. Call dst_gssapi_releasecred to free - * the memory. - * - * Returns: - * ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - * other an error occurred while building the message - */ - -isc_result_t -dst_gssapi_releasecred(gss_cred_id_t *cred); -/* - * Releases GSS credentials. Calling this function does release the - * memory allocated for the credential in dst_gssapi_acquirecred() - * - * Requires: - * 'mctx' is a valid memory context - * 'cred' is a pointer to the credential to be released - * - * Returns: - * ISC_R_SUCCESS credential was released successfully - * other an error occurred while releaseing - * the credential - */ - -isc_result_t -dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, - isc_buffer_t *outtoken, gss_ctx_id_t *gssctx, - isc_mem_t *mctx, char **err_message); -/* - * Initiates a GSS context. - * - * Requires: - * 'name' is a valid name, preferably one known by the GSS - * provider - * 'intoken' is a token received from the acceptor, or NULL if - * there isn't one - * 'outtoken' is a buffer to receive the token generated by - * gss_init_sec_context() to be sent to the acceptor - * 'context' is a pointer to a valid gss_ctx_id_t - * (which may have the value GSS_C_NO_CONTEXT) - * - * Returns: - * ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - * other an error occurred while building the message - * *err_message optional error message - */ - -isc_result_t -dst_gssapi_acceptctx(gss_cred_id_t cred, - const char *gssapi_keytab, - isc_region_t *intoken, isc_buffer_t **outtoken, - gss_ctx_id_t *context, dns_name_t *principal, - isc_mem_t *mctx); -/* - * Accepts a GSS context. - * - * Requires: - * 'mctx' is a valid memory context - * 'cred' is the acceptor's valid GSS credential handle - * 'intoken' is a token received from the initiator - * 'outtoken' is a pointer a buffer pointer used to return the token - * generated by gss_accept_sec_context() to be sent to the - * initiator - * 'context' is a valid pointer to receive the generated context handle. - * On the initial call, it should be a pointer to NULL, which - * will be allocated as a gss_ctx_id_t. Subsequent calls - * should pass in the handle generated on the first call. - * Call dst_gssapi_releasecred to delete the context and free - * the memory. - * - * Requires: - * 'outtoken' to != NULL && *outtoken == NULL. - * - * Returns: - * ISC_R_SUCCESS msg was successfully updated to include the - * query to be sent - * DNS_R_CONTINUE transaction still in progress - * other an error occurred while building the message - */ - -isc_result_t -dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx); -/* - * Destroys a GSS context. This function deletes the context from the GSS - * provider and then frees the memory used by the context pointer. - * - * Requires: - * 'mctx' is a valid memory context - * 'context' is a valid GSS context - * - * Returns: - * ISC_R_SUCCESS - */ - - -void -gss_log(int level, const char *fmt, ...) -ISC_FORMAT_PRINTF(2, 3); -/* - * Logging function for GSS. - * - * Requires - * 'level' is the log level to be used, as an integer - * 'fmt' is a printf format specifier - */ - -char * -gss_error_tostring(uint32_t major, uint32_t minor, - char *buf, size_t buflen); -/* - * Render a GSS major status/minor status pair into a string - * - * Requires: - * 'major' is a GSS major status code - * 'minor' is a GSS minor status code - * - * Returns: - * A string containing the text representation of the error codes. - * Users should copy the string if they wish to keep it. - */ - -bool -dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, - const dns_name_t *name, - const dns_name_t *realm, - bool subdomain); -/* - * Compare a "signer" (in the format of a Kerberos-format Kerberos5 - * principal: host/example.com@EXAMPLE.COM) to the realm name stored - * in "name" (which represents the realm name). - * - */ - -bool -dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, - const dns_name_t *name, - const dns_name_t *realm, - bool subdomain); -/* - * Compare a "signer" (in the format of a Kerberos-format Kerberos5 - * principal: host/example.com@EXAMPLE.COM) to the realm name stored - * in "name" (which represents the realm name). - * - */ - -ISC_LANG_ENDDECLS - -#endif /* DST_GSSAPI_H */ diff --git a/lib/dns-pkcs11/include/dst/lib.h b/lib/dns-pkcs11/include/dst/lib.h deleted file mode 100644 index 85f799f..0000000 --- a/lib/dns-pkcs11/include/dst/lib.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DST_LIB_H -#define DST_LIB_H 1 - -/*! \file dst/lib.h */ - -#include -#include - -ISC_LANG_BEGINDECLS - -LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dst_msgcat; - -void -dst_lib_initmsgcat(void); -/* - * Initialize the DST library's message catalog, dst_msgcat, if it - * has not already been initialized. - */ - -ISC_LANG_ENDDECLS - -#endif /* DST_LIB_H */ diff --git a/lib/dns-pkcs11/include/dst/result.h b/lib/dns-pkcs11/include/dst/result.h deleted file mode 100644 index edf32e2..0000000 --- a/lib/dns-pkcs11/include/dst/result.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DST_RESULT_H -#define DST_RESULT_H 1 - -/*! \file dst/result.h */ - -#include -#include - -/* - * Nothing in this file truly depends on , but the - * DST result codes are considered to be publicly derived from - * the ISC result codes, so including this file buys you the ISC_R_ - * namespace too. - */ -#include /* Contractual promise. */ - -#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) -#define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1) -/* compat */ -#define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE -#define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2) -#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) -#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) -#define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5) -/* 6 is unused */ -#define DST_R_WRITEERROR (ISC_RESULTCLASS_DST + 7) -#define DST_R_INVALIDPARAM (ISC_RESULTCLASS_DST + 8) -/* 9 is unused */ -/* 10 is unused */ -#define DST_R_SIGNFAILURE (ISC_RESULTCLASS_DST + 11) -/* 12 is unused */ -/* 13 is unused */ -#define DST_R_VERIFYFAILURE (ISC_RESULTCLASS_DST + 14) -#define DST_R_NOTPUBLICKEY (ISC_RESULTCLASS_DST + 15) -#define DST_R_NOTPRIVATEKEY (ISC_RESULTCLASS_DST + 16) -#define DST_R_KEYCANNOTCOMPUTESECRET (ISC_RESULTCLASS_DST + 17) -#define DST_R_COMPUTESECRETFAILURE (ISC_RESULTCLASS_DST + 18) -#define DST_R_NORANDOMNESS (ISC_RESULTCLASS_DST + 19) -#define DST_R_BADKEYTYPE (ISC_RESULTCLASS_DST + 20) -#define DST_R_NOENGINE (ISC_RESULTCLASS_DST + 21) -#define DST_R_EXTERNALKEY (ISC_RESULTCLASS_DST + 22) - -#define DST_R_NRESULTS 23 /* Number of results */ - -ISC_LANG_BEGINDECLS - -const char * -dst_result_totext(isc_result_t); - -void -dst_result_register(void); - -ISC_LANG_ENDDECLS - -#endif /* DST_RESULT_H */ diff --git a/lib/dns-pkcs11/ipkeylist.c b/lib/dns-pkcs11/ipkeylist.c deleted file mode 100644 index 6e97f6d..0000000 --- a/lib/dns-pkcs11/ipkeylist.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include - -#include -#include - -void -dns_ipkeylist_init(dns_ipkeylist_t *ipkl) { - ipkl->count = 0; - ipkl->allocated = 0; - ipkl->addrs = NULL; - ipkl->dscps = NULL; - ipkl->keys = NULL; - ipkl->labels = NULL; -} - -void -dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) { - uint32_t i; - - REQUIRE(ipkl != NULL); - - if (ipkl->allocated == 0) - return; - - if (ipkl->addrs != NULL) - isc_mem_put(mctx, ipkl->addrs, - ipkl->allocated * sizeof(isc_sockaddr_t)); - - if (ipkl->dscps != NULL) - isc_mem_put(mctx, ipkl->dscps, - ipkl->allocated * sizeof(isc_dscp_t)); - - if (ipkl->keys != NULL) { - for (i = 0; i < ipkl->allocated; i++) { - if (ipkl->keys[i] == NULL) - continue; - if (dns_name_dynamic(ipkl->keys[i])) - dns_name_free(ipkl->keys[i], mctx); - isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t)); - } - isc_mem_put(mctx, ipkl->keys, - ipkl->allocated * sizeof(dns_name_t *)); - } - - if (ipkl->labels != NULL) { - for (i = 0; i < ipkl->allocated; i++) { - if (ipkl->labels[i] == NULL) - continue; - if (dns_name_dynamic(ipkl->labels[i])) - dns_name_free(ipkl->labels[i], mctx); - isc_mem_put(mctx, ipkl->labels[i], sizeof(dns_name_t)); - } - isc_mem_put(mctx, ipkl->labels, - ipkl->allocated * sizeof(dns_name_t *)); - } - - dns_ipkeylist_init(ipkl); -} - -isc_result_t -dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, - dns_ipkeylist_t *dst) -{ - isc_result_t result = ISC_R_SUCCESS; - uint32_t i; - - REQUIRE(dst != NULL); - /* dst might be preallocated, we don't care, but it must be empty */ - REQUIRE(dst->count == 0); - - if (src->count == 0) - return (ISC_R_SUCCESS); - - result = dns_ipkeylist_resize(mctx, dst, src->count); - if (result != ISC_R_SUCCESS) - return (result); - - memmove(dst->addrs, src->addrs, src->count * sizeof(isc_sockaddr_t)); - - if (src->dscps != NULL) { - memmove(dst->dscps, src->dscps, - src->count * sizeof(isc_dscp_t)); - } - - if (src->keys != NULL) { - for (i = 0; i < src->count; i++) { - if (src->keys[i] != NULL) { - dst->keys[i] = isc_mem_get(mctx, - sizeof(dns_name_t)); - if (dst->keys[i] == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_keys; - } - dns_name_init(dst->keys[i], NULL); - result = dns_name_dup(src->keys[i], mctx, - dst->keys[i]); - if (result != ISC_R_SUCCESS) - goto cleanup_keys; - } else { - dst->keys[i] = NULL; - } - } - } - - if (src->labels != NULL) { - for (i = 0; i < src->count; i++) { - if (src->labels[i] != NULL) { - dst->labels[i] = isc_mem_get(mctx, - sizeof(dns_name_t)); - if (dst->labels[i] == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_labels; - } - dns_name_init(dst->labels[i], NULL); - result = dns_name_dup(src->labels[i], mctx, - dst->labels[i]); - if (result != ISC_R_SUCCESS) - goto cleanup_labels; - } else { - dst->labels[i] = NULL; - } - } - } - dst->count = src->count; - return (ISC_R_SUCCESS); - - cleanup_labels: - do { - if (dst->labels[i] != NULL) { - if (dns_name_dynamic(dst->labels[i])) - dns_name_free(dst->labels[i], mctx); - isc_mem_put(mctx, dst->labels[i], sizeof(dns_name_t)); - dst->labels[i] = NULL; - } - } while (i-- > 0); - - cleanup_keys: - do { - if (dst->keys[i] != NULL) { - if (dns_name_dynamic(dst->keys[i])) - dns_name_free(dst->keys[i], mctx); - isc_mem_put(mctx, dst->keys[i], sizeof(dns_name_t)); - dst->keys[i] = NULL; - } - } while (i-- > 0); - - return (result); -} - -isc_result_t -dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) { - isc_sockaddr_t *addrs = NULL; - isc_dscp_t *dscps = NULL; - dns_name_t **keys = NULL; - dns_name_t **labels = NULL; - - REQUIRE(ipkl != NULL); - REQUIRE(n > ipkl->count); - - if (n <= ipkl->allocated) - return (ISC_R_SUCCESS); - - addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t)); - if (addrs == NULL) - goto nomemory; - dscps = isc_mem_get(mctx, n * sizeof(isc_dscp_t)); - if (dscps == NULL) - goto nomemory; - keys = isc_mem_get(mctx, n * sizeof(dns_name_t *)); - if (keys == NULL) - goto nomemory; - labels = isc_mem_get(mctx, n * sizeof(dns_name_t *)); - if (labels == NULL) - goto nomemory; - - if (ipkl->addrs != NULL) { - memmove(addrs, ipkl->addrs, - ipkl->allocated * sizeof(isc_sockaddr_t)); - isc_mem_put(mctx, ipkl->addrs, - ipkl->allocated * sizeof(isc_sockaddr_t)); - } - ipkl->addrs = addrs; - memset(&ipkl->addrs[ipkl->allocated], 0, - (n - ipkl->allocated) * sizeof(isc_sockaddr_t)); - - if (ipkl->dscps != NULL) { - memmove(dscps, ipkl->dscps, - ipkl->allocated * sizeof(isc_dscp_t)); - isc_mem_put(mctx, ipkl->dscps, - ipkl->allocated * sizeof(isc_dscp_t)); - } - ipkl->dscps = dscps; - memset(&ipkl->dscps[ipkl->allocated], 0, - (n - ipkl->allocated) * sizeof(isc_dscp_t)); - - if (ipkl->keys) { - memmove(keys, ipkl->keys, - ipkl->allocated * sizeof(dns_name_t *)); - isc_mem_put(mctx, ipkl->keys, - ipkl->allocated * sizeof(dns_name_t *)); - } - ipkl->keys = keys; - memset(&ipkl->keys[ipkl->allocated], 0, - (n - ipkl->allocated) * sizeof(dns_name_t *)); - - if (ipkl->labels != NULL) { - memmove(labels, ipkl->labels, - ipkl->allocated * sizeof(dns_name_t *)); - isc_mem_put(mctx, ipkl->labels, - ipkl->allocated * sizeof(dns_name_t *)); - } - ipkl->labels = labels; - memset(&ipkl->labels[ipkl->allocated], 0, - (n - ipkl->allocated) * sizeof(dns_name_t *)); - - ipkl->allocated = n; - return (ISC_R_SUCCESS); - -nomemory: - if (addrs != NULL) - isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t)); - if (dscps != NULL) - isc_mem_put(mctx, dscps, n * sizeof(isc_dscp_t)); - if (keys != NULL) - isc_mem_put(mctx, keys, n * sizeof(dns_name_t *)); - if (labels != NULL) - isc_mem_put(mctx, labels, n * sizeof(dns_name_t *)); - - return (ISC_R_NOMEMORY); -} diff --git a/lib/dns-pkcs11/iptable.c b/lib/dns-pkcs11/iptable.c deleted file mode 100644 index 909103e..0000000 --- a/lib/dns-pkcs11/iptable.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include - -#include - -static void destroy_iptable(dns_iptable_t *dtab); - -/* - * Create a new IP table and the underlying radix structure - */ -isc_result_t -dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target) { - isc_result_t result; - dns_iptable_t *tab; - - tab = isc_mem_get(mctx, sizeof(*tab)); - if (tab == NULL) - return (ISC_R_NOMEMORY); - tab->mctx = NULL; - isc_mem_attach(mctx, &tab->mctx); - isc_refcount_init(&tab->refcount, 1); - tab->radix = NULL; - tab->magic = DNS_IPTABLE_MAGIC; - - result = isc_radix_create(mctx, &tab->radix, RADIX_MAXBITS); - if (result != ISC_R_SUCCESS) - goto cleanup; - - *target = tab; - return (ISC_R_SUCCESS); - - cleanup: - dns_iptable_detach(&tab); - return (result); -} - -static bool dns_iptable_neg = false; -static bool dns_iptable_pos = true; - -/* - * Add an IP prefix to an existing IP table - */ -isc_result_t -dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr, - uint16_t bitlen, bool pos) -{ - return(dns_iptable_addprefix2(tab, addr, bitlen, pos, false)); -} - -isc_result_t -dns_iptable_addprefix2(dns_iptable_t *tab, isc_netaddr_t *addr, - uint16_t bitlen, bool pos, - bool is_ecs) -{ - isc_result_t result; - isc_prefix_t pfx; - isc_radix_node_t *node = NULL; - int i; - - INSIST(DNS_IPTABLE_VALID(tab)); - INSIST(tab->radix != NULL); - - NETADDR_TO_PREFIX_T(addr, pfx, bitlen, is_ecs); - - result = isc_radix_insert(tab->radix, &node, NULL, &pfx); - if (result != ISC_R_SUCCESS) { - isc_refcount_destroy(&pfx.refcount); - return(result); - } - - /* If a node already contains data, don't overwrite it */ - if (pfx.family == AF_UNSPEC) { - /* "any" or "none" */ - INSIST(pfx.bitlen == 0); - for (i = 0; i < RADIX_FAMILIES; i++) { - if (node->data[i] == NULL) { - node->data[i] = pos ? &dns_iptable_pos - : &dns_iptable_neg; - } - } - } else { - /* any other prefix */ - int fam = ISC_RADIX_FAMILY(&pfx); - if (node->data[fam] == NULL) { - node->data[fam] = pos ? &dns_iptable_pos - : &dns_iptable_neg; - } - } - - isc_refcount_destroy(&pfx.refcount); - return (ISC_R_SUCCESS); -} - -/* - * Merge one IP table into another one. - */ -isc_result_t -dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, bool pos) -{ - isc_result_t result; - isc_radix_node_t *node, *new_node; - int i, max_node = 0; - - RADIX_WALK (source->radix->head, node) { - new_node = NULL; - result = isc_radix_insert (tab->radix, &new_node, node, NULL); - - if (result != ISC_R_SUCCESS) - return(result); - - /* - * If we're negating a nested ACL, then we should - * reverse the sense of every node. However, this - * could lead to a negative node in a nested ACL - * becoming a positive match in the parent, which - * could be a security risk. To prevent this, we - * just leave the negative nodes negative. - */ - for (i = 0; i < RADIX_FAMILIES; i++) { - if (!pos) { - if (node->data[i] && - *(bool *) node->data[i]) - new_node->data[i] = &dns_iptable_neg; - } - if (node->node_num[i] > max_node) - max_node = node->node_num[i]; - } - } RADIX_WALK_END; - - tab->radix->num_added_node += max_node; - return (ISC_R_SUCCESS); -} - -void -dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) { - REQUIRE(DNS_IPTABLE_VALID(source)); - isc_refcount_increment(&source->refcount, NULL); - *target = source; -} - -void -dns_iptable_detach(dns_iptable_t **tabp) { - dns_iptable_t *tab = *tabp; - unsigned int refs; - REQUIRE(DNS_IPTABLE_VALID(tab)); - isc_refcount_decrement(&tab->refcount, &refs); - if (refs == 0) - destroy_iptable(tab); - *tabp = NULL; -} - -static void -destroy_iptable(dns_iptable_t *dtab) { - - REQUIRE(DNS_IPTABLE_VALID(dtab)); - - if (dtab->radix != NULL) { - isc_radix_destroy(dtab->radix, NULL); - dtab->radix = NULL; - } - - isc_refcount_destroy(&dtab->refcount); - dtab->magic = 0; - isc_mem_putanddetach(&dtab->mctx, dtab, sizeof(*dtab)); -} diff --git a/lib/dns-pkcs11/journal.c b/lib/dns-pkcs11/journal.c deleted file mode 100644 index 1f04650..0000000 --- a/lib/dns-pkcs11/journal.c +++ /dev/null @@ -1,2367 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*! \file - * \brief Journaling. - * - * A journal file consists of - * - * \li A fixed-size header of type journal_rawheader_t. - * - * \li The index. This is an unordered array of index entries - * of type journal_rawpos_t giving the locations - * of some arbitrary subset of the journal's addressable - * transactions. The index entries are used as hints to - * speed up the process of locating a transaction with a given - * serial number. Unused index entries have an "offset" - * field of zero. The size of the index can vary between - * journal files, but does not change during the lifetime - * of a file. The size can be zero. - * - * \li The journal data. This consists of one or more transactions. - * Each transaction begins with a transaction header of type - * journal_rawxhdr_t. The transaction header is followed by a - * sequence of RRs, similar in structure to an IXFR difference - * sequence (RFC1995). That is, the pre-transaction SOA, - * zero or more other deleted RRs, the post-transaction SOA, - * and zero or more other added RRs. Unlike in IXFR, each RR - * is prefixed with a 32-bit length. - * - * The journal data part grows as new transactions are - * appended to the file. Only those transactions - * whose serial number is current-(2^31-1) to current - * are considered "addressable" and may be pointed - * to from the header or index. They may be preceded - * by old transactions that are no longer addressable, - * and they may be followed by transactions that were - * appended to the journal but never committed by updating - * the "end" position in the header. The latter will - * be overwritten when new transactions are added. - */ -/*% - * When true, accept IXFR difference sequences where the - * SOA serial number does not change (BIND 8 sends such - * sequences). - */ -static bool bind8_compat = true; /* XXX config */ - -/**************************************************************************/ -/* - * Miscellaneous utilities. - */ - -#define JOURNAL_COMMON_LOGARGS \ - dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL - -#define JOURNAL_DEBUG_LOGARGS(n) \ - JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n) - -/*% - * It would be non-sensical (or at least obtuse) to use FAIL() with an - * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAIL(code) \ - do { result = (code); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define JOURNAL_SERIALSET 0x01U - -static isc_result_t index_to_disk(dns_journal_t *); - -static inline uint32_t -decode_uint32(unsigned char *p) { - return ((p[0] << 24) + - (p[1] << 16) + - (p[2] << 8) + - (p[3] << 0)); -} - -static inline void -encode_uint32(uint32_t val, unsigned char *p) { - p[0] = (uint8_t)(val >> 24); - p[1] = (uint8_t)(val >> 16); - p[2] = (uint8_t)(val >> 8); - p[3] = (uint8_t)(val >> 0); -} - -isc_result_t -dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, - dns_diffop_t op, dns_difftuple_t **tp) -{ - isc_result_t result; - dns_dbnode_t *node; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_fixedname_t fixed; - dns_name_t *zonename; - - zonename = dns_fixedname_initname(&fixed); - dns_name_copy(dns_db_origin(db), zonename, NULL); - - node = NULL; - result = dns_db_findnode(db, zonename, false, &node); - if (result != ISC_R_SUCCESS) - goto nonode; - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, - (isc_stdtime_t)0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto freenode; - - result = dns_rdataset_first(&rdataset); - if (result != ISC_R_SUCCESS) - goto freenode; - - dns_rdataset_current(&rdataset, &rdata); - dns_rdataset_getownercase(&rdataset, zonename); - - result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl, - &rdata, tp); - - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); - - freenode: - dns_db_detachnode(db, &node); - nonode: - UNEXPECTED_ERROR(__FILE__, __LINE__, "missing SOA"); - return (result); -} - -/* Journaling */ - -/*% - * On-disk representation of a "pointer" to a journal entry. - * These are used in the journal header to locate the beginning - * and end of the journal, and in the journal index to locate - * other transactions. - */ -typedef struct { - unsigned char serial[4]; /*%< SOA serial before update. */ - /* - * XXXRTH Should offset be 8 bytes? - * XXXDCL ... probably, since isc_offset_t is 8 bytes on many OSs. - * XXXAG ... but we will not be able to seek >2G anyway on many - * platforms as long as we are using fseek() rather - * than lseek(). - */ - unsigned char offset[4]; /*%< Offset from beginning of file. */ -} journal_rawpos_t; - - -/*% - * The header is of a fixed size, with some spare room for future - * extensions. - */ -#define JOURNAL_HEADER_SIZE 64 /* Bytes. */ - -/*% - * The on-disk representation of the journal header. - * All numbers are stored in big-endian order. - */ -typedef union { - struct { - /*% File format version ID. */ - unsigned char format[16]; - /*% Position of the first addressable transaction */ - journal_rawpos_t begin; - /*% Position of the next (yet nonexistent) transaction. */ - journal_rawpos_t end; - /*% Number of index entries following the header. */ - unsigned char index_size[4]; - /*% Source serial number. */ - unsigned char sourceserial[4]; - unsigned char flags; - } h; - /* Pad the header to a fixed size. */ - unsigned char pad[JOURNAL_HEADER_SIZE]; -} journal_rawheader_t; - -/*% - * The on-disk representation of the transaction header. - * There is one of these at the beginning of each transaction. - */ -typedef struct { - unsigned char size[4]; /*%< In bytes, excluding header. */ - unsigned char serial0[4]; /*%< SOA serial before update. */ - unsigned char serial1[4]; /*%< SOA serial after update. */ -} journal_rawxhdr_t; - -/*% - * The on-disk representation of the RR header. - * There is one of these at the beginning of each RR. - */ -typedef struct { - unsigned char size[4]; /*%< In bytes, excluding header. */ -} journal_rawrrhdr_t; - -/*% - * The in-core representation of the journal header. - */ -typedef struct { - uint32_t serial; - isc_offset_t offset; -} journal_pos_t; - -#define POS_VALID(pos) ((pos).offset != 0) -#define POS_INVALIDATE(pos) ((pos).offset = 0, (pos).serial = 0) - -typedef struct { - unsigned char format[16]; - journal_pos_t begin; - journal_pos_t end; - uint32_t index_size; - uint32_t sourceserial; - bool serialset; -} journal_header_t; - -/*% - * The in-core representation of the transaction header. - */ - -typedef struct { - uint32_t size; - uint32_t serial0; - uint32_t serial1; -} journal_xhdr_t; - -/*% - * The in-core representation of the RR header. - */ -typedef struct { - uint32_t size; -} journal_rrhdr_t; - - -/*% - * Initial contents to store in the header of a newly created - * journal file. - * - * The header starts with the magic string ";BIND LOG V9\n" - * to identify the file as a BIND 9 journal file. An ASCII - * identification string is used rather than a binary magic - * number to be consistent with BIND 8 (BIND 8 journal files - * are ASCII text files). - */ - -static journal_header_t -initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0, 0 }; - -#define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset) - -typedef enum { - JOURNAL_STATE_INVALID, - JOURNAL_STATE_READ, - JOURNAL_STATE_WRITE, - JOURNAL_STATE_TRANSACTION, - JOURNAL_STATE_INLINE -} journal_state_t; - -struct dns_journal { - unsigned int magic; /*%< JOUR */ - isc_mem_t *mctx; /*%< Memory context */ - journal_state_t state; - char *filename; /*%< Journal file name */ - FILE * fp; /*%< File handle */ - isc_offset_t offset; /*%< Current file offset */ - journal_header_t header; /*%< In-core journal header */ - unsigned char *rawindex; /*%< In-core buffer for journal index in on-disk format */ - journal_pos_t *index; /*%< In-core journal index */ - - /*% Current transaction state (when writing). */ - struct { - unsigned int n_soa; /*%< Number of SOAs seen */ - journal_pos_t pos[2]; /*%< Begin/end position */ - } x; - - /*% Iteration state (when reading). */ - struct { - /* These define the part of the journal we iterate over. */ - journal_pos_t bpos; /*%< Position before first, */ - journal_pos_t epos; /*%< and after last transaction */ - /* The rest is iterator state. */ - uint32_t current_serial; /*%< Current SOA serial */ - isc_buffer_t source; /*%< Data from disk */ - isc_buffer_t target; /*%< Data from _fromwire check */ - dns_decompress_t dctx; /*%< Dummy decompression ctx */ - dns_name_t name; /*%< Current domain name */ - dns_rdata_t rdata; /*%< Current rdata */ - uint32_t ttl; /*%< Current TTL */ - unsigned int xsize; /*%< Size of transaction data */ - unsigned int xpos; /*%< Current position in it */ - isc_result_t result; /*%< Result of last call */ - } it; -}; - -#define DNS_JOURNAL_MAGIC ISC_MAGIC('J', 'O', 'U', 'R') -#define DNS_JOURNAL_VALID(t) ISC_MAGIC_VALID(t, DNS_JOURNAL_MAGIC) - -static void -journal_pos_decode(journal_rawpos_t *raw, journal_pos_t *cooked) { - cooked->serial = decode_uint32(raw->serial); - cooked->offset = decode_uint32(raw->offset); -} - -static void -journal_pos_encode(journal_rawpos_t *raw, journal_pos_t *cooked) { - encode_uint32(cooked->serial, raw->serial); - encode_uint32(cooked->offset, raw->offset); -} - -static void -journal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) { - INSIST(sizeof(cooked->format) == sizeof(raw->h.format)); - memmove(cooked->format, raw->h.format, sizeof(cooked->format)); - journal_pos_decode(&raw->h.begin, &cooked->begin); - journal_pos_decode(&raw->h.end, &cooked->end); - cooked->index_size = decode_uint32(raw->h.index_size); - cooked->sourceserial = decode_uint32(raw->h.sourceserial); - cooked->serialset = ((raw->h.flags & JOURNAL_SERIALSET) != 0); -} - -static void -journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) { - unsigned char flags = 0; - - INSIST(sizeof(cooked->format) == sizeof(raw->h.format)); - memset(raw->pad, 0, sizeof(raw->pad)); - memmove(raw->h.format, cooked->format, sizeof(raw->h.format)); - journal_pos_encode(&raw->h.begin, &cooked->begin); - journal_pos_encode(&raw->h.end, &cooked->end); - encode_uint32(cooked->index_size, raw->h.index_size); - encode_uint32(cooked->sourceserial, raw->h.sourceserial); - if (cooked->serialset) { - flags |= JOURNAL_SERIALSET; - } - raw->h.flags = flags; -} - -/* - * Journal file I/O subroutines, with error checking and reporting. - */ -static isc_result_t -journal_seek(dns_journal_t *j, uint32_t offset) { - isc_result_t result; - - result = isc_stdio_seek(j->fp, (off_t)offset, SEEK_SET); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: seek: %s", j->filename, - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - j->offset = offset; - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_read(dns_journal_t *j, void *mem, size_t nbytes) { - isc_result_t result; - - result = isc_stdio_read(mem, 1, nbytes, j->fp, NULL); - if (result != ISC_R_SUCCESS) { - if (result == ISC_R_EOF) - return (ISC_R_NOMORE); - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: read: %s", - j->filename, isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - j->offset += (isc_offset_t)nbytes; - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_write(dns_journal_t *j, void *mem, size_t nbytes) { - isc_result_t result; - - result = isc_stdio_write(mem, 1, nbytes, j->fp, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: write: %s", - j->filename, isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - j->offset += (isc_offset_t)nbytes; - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_fsync(dns_journal_t *j) { - isc_result_t result; - result = isc_stdio_flush(j->fp); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: flush: %s", - j->filename, isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - result = isc_stdio_sync(j->fp); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: fsync: %s", - j->filename, isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - return (ISC_R_SUCCESS); -} - -/* - * Read/write a transaction header at the current file position. - */ - -static isc_result_t -journal_read_xhdr(dns_journal_t *j, journal_xhdr_t *xhdr) { - journal_rawxhdr_t raw; - isc_result_t result; - result = journal_read(j, &raw, sizeof(raw)); - if (result != ISC_R_SUCCESS) - return (result); - xhdr->size = decode_uint32(raw.size); - xhdr->serial0 = decode_uint32(raw.serial0); - xhdr->serial1 = decode_uint32(raw.serial1); - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_write_xhdr(dns_journal_t *j, uint32_t size, - uint32_t serial0, uint32_t serial1) -{ - journal_rawxhdr_t raw; - encode_uint32(size, raw.size); - encode_uint32(serial0, raw.serial0); - encode_uint32(serial1, raw.serial1); - return (journal_write(j, &raw, sizeof(raw))); -} - - -/* - * Read an RR header at the current file position. - */ - -static isc_result_t -journal_read_rrhdr(dns_journal_t *j, journal_rrhdr_t *rrhdr) { - journal_rawrrhdr_t raw; - isc_result_t result; - result = journal_read(j, &raw, sizeof(raw)); - if (result != ISC_R_SUCCESS) - return (result); - rrhdr->size = decode_uint32(raw.size); - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_file_create(isc_mem_t *mctx, const char *filename) { - FILE *fp = NULL; - isc_result_t result; - journal_header_t header; - journal_rawheader_t rawheader; - int index_size = 56; /* XXX configurable */ - int size; - void *mem; /* Memory for temporary index image. */ - - INSIST(sizeof(journal_rawheader_t) == JOURNAL_HEADER_SIZE); - - result = isc_stdio_open(filename, "wb", &fp); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: create: %s", - filename, isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - header = initial_journal_header; - header.index_size = index_size; - journal_header_encode(&header, &rawheader); - - size = sizeof(journal_rawheader_t) + - index_size * sizeof(journal_rawpos_t); - - mem = isc_mem_get(mctx, size); - if (mem == NULL) { - (void)isc_stdio_close(fp); - (void)isc_file_remove(filename); - return (ISC_R_NOMEMORY); - } - memset(mem, 0, size); - memmove(mem, &rawheader, sizeof(rawheader)); - - result = isc_stdio_write(mem, 1, (size_t) size, fp, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: write: %s", - filename, isc_result_totext(result)); - (void)isc_stdio_close(fp); - (void)isc_file_remove(filename); - isc_mem_put(mctx, mem, size); - return (ISC_R_UNEXPECTED); - } - isc_mem_put(mctx, mem, size); - - result = isc_stdio_close(fp); - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: close: %s", - filename, isc_result_totext(result)); - (void)isc_file_remove(filename); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -journal_open(isc_mem_t *mctx, const char *filename, bool writable, - bool create, dns_journal_t **journalp) -{ - FILE *fp = NULL; - isc_result_t result; - journal_rawheader_t rawheader; - dns_journal_t *j; - - INSIST(journalp != NULL && *journalp == NULL); - j = isc_mem_get(mctx, sizeof(*j)); - if (j == NULL) - return (ISC_R_NOMEMORY); - - j->mctx = NULL; - isc_mem_attach(mctx, &j->mctx); - j->state = JOURNAL_STATE_INVALID; - j->fp = NULL; - j->filename = isc_mem_strdup(mctx, filename); - j->index = NULL; - j->rawindex = NULL; - - if (j->filename == NULL) - FAIL(ISC_R_NOMEMORY); - - result = isc_stdio_open(j->filename, writable ? "rb+" : "rb", &fp); - - if (result == ISC_R_FILENOTFOUND) { - if (create) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(1), - "journal file %s does not exist, " - "creating it", j->filename); - CHECK(journal_file_create(mctx, filename)); - /* - * Retry. - */ - result = isc_stdio_open(j->filename, "rb+", &fp); - } else { - FAIL(ISC_R_NOTFOUND); - } - } - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: open: %s", - j->filename, isc_result_totext(result)); - FAIL(ISC_R_UNEXPECTED); - } - - j->fp = fp; - - /* - * Set magic early so that seek/read can succeed. - */ - j->magic = DNS_JOURNAL_MAGIC; - - CHECK(journal_seek(j, 0)); - CHECK(journal_read(j, &rawheader, sizeof(rawheader))); - - if (memcmp(rawheader.h.format, initial_journal_header.format, - sizeof(initial_journal_header.format)) != 0) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal format not recognized", - j->filename); - FAIL(ISC_R_UNEXPECTED); - } - journal_header_decode(&rawheader, &j->header); - - /* - * If there is an index, read the raw index into a dynamically - * allocated buffer and then convert it into a cooked index. - */ - if (j->header.index_size != 0) { - unsigned int i; - unsigned int rawbytes; - unsigned char *p; - - rawbytes = j->header.index_size * sizeof(journal_rawpos_t); - j->rawindex = isc_mem_get(mctx, rawbytes); - if (j->rawindex == NULL) - FAIL(ISC_R_NOMEMORY); - - CHECK(journal_read(j, j->rawindex, rawbytes)); - - j->index = isc_mem_get(mctx, j->header.index_size * - sizeof(journal_pos_t)); - if (j->index == NULL) - FAIL(ISC_R_NOMEMORY); - - p = j->rawindex; - for (i = 0; i < j->header.index_size; i++) { - j->index[i].serial = decode_uint32(p); - p += 4; - j->index[i].offset = decode_uint32(p); - p += 4; - } - INSIST(p == j->rawindex + rawbytes); - } - j->offset = -1; /* Invalid, must seek explicitly. */ - - /* - * Initialize the iterator. - */ - dns_name_init(&j->it.name, NULL); - dns_rdata_init(&j->it.rdata); - - /* - * Set up empty initial buffers for unchecked and checked - * wire format RR data. They will be reallocated - * later. - */ - isc_buffer_init(&j->it.source, NULL, 0); - isc_buffer_init(&j->it.target, NULL, 0); - dns_decompress_init(&j->it.dctx, -1, DNS_DECOMPRESS_NONE); - - j->state = - writable ? JOURNAL_STATE_WRITE : JOURNAL_STATE_READ; - - *journalp = j; - return (ISC_R_SUCCESS); - - failure: - j->magic = 0; - if (j->rawindex != NULL) - isc_mem_put(j->mctx, j->rawindex, j->header.index_size * - sizeof(journal_rawpos_t)); - if (j->index != NULL) - isc_mem_put(j->mctx, j->index, j->header.index_size * - sizeof(journal_pos_t)); - if (j->filename != NULL) - isc_mem_free(j->mctx, j->filename); - if (j->fp != NULL) - (void)isc_stdio_close(j->fp); - isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); - return (result); -} - -isc_result_t -dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, - dns_journal_t **journalp) -{ - isc_result_t result; - size_t namelen; - char backup[1024]; - bool writable, create; - - create = ((mode & DNS_JOURNAL_CREATE) != 0); - writable = ((mode & (DNS_JOURNAL_WRITE|DNS_JOURNAL_CREATE)) != 0); - - result = journal_open(mctx, filename, writable, create, journalp); - if (result == ISC_R_NOTFOUND) { - namelen = strlen(filename); - if (namelen > 4U && strcmp(filename + namelen - 4, ".jnl") == 0) - namelen -= 4; - - result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk", - (int)namelen, filename); - if (result != ISC_R_SUCCESS) - return (result); - result = journal_open(mctx, backup, writable, writable, - journalp); - } - return (result); -} - -/* - * A comparison function defining the sorting order for - * entries in the IXFR-style journal file. - * - * The IXFR format requires that deletions are sorted before - * additions, and within either one, SOA records are sorted - * before others. - * - * Also sort the non-SOA records by type as a courtesy to the - * server receiving the IXFR - it may help reduce the amount of - * rdataset merging it has to do. - */ -static int -ixfr_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - int bop = 0, aop = 0; - - switch (a->op) { - case DNS_DIFFOP_DEL: - case DNS_DIFFOP_DELRESIGN: - aop = 1; - break; - case DNS_DIFFOP_ADD: - case DNS_DIFFOP_ADDRESIGN: - aop = 0; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - switch (b->op) { - case DNS_DIFFOP_DEL: - case DNS_DIFFOP_DELRESIGN: - bop = 1; - break; - case DNS_DIFFOP_ADD: - case DNS_DIFFOP_ADDRESIGN: - bop = 0; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - r = bop - aop; - if (r != 0) - return (r); - - r = (b->rdata.type == dns_rdatatype_soa) - - (a->rdata.type == dns_rdatatype_soa); - if (r != 0) - return (r); - - r = (a->rdata.type - b->rdata.type); - return (r); -} - -/* - * Advance '*pos' to the next journal transaction. - * - * Requires: - * *pos refers to a valid journal transaction. - * - * Ensures: - * When ISC_R_SUCCESS is returned, - * *pos refers to the next journal transaction. - * - * Returns one of: - * - * ISC_R_SUCCESS - * ISC_R_NOMORE *pos pointed at the last transaction - * Other results due to file errors are possible. - */ -static isc_result_t -journal_next(dns_journal_t *j, journal_pos_t *pos) { - isc_result_t result; - journal_xhdr_t xhdr; - REQUIRE(DNS_JOURNAL_VALID(j)); - - result = journal_seek(j, pos->offset); - if (result != ISC_R_SUCCESS) - return (result); - - if (pos->serial == j->header.end.serial) - return (ISC_R_NOMORE); - /* - * Read the header of the current transaction. - * This will return ISC_R_NOMORE if we are at EOF. - */ - result = journal_read_xhdr(j, &xhdr); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Check serial number consistency. - */ - if (xhdr.serial0 != pos->serial) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal file corrupt: " - "expected serial %u, got %u", - j->filename, pos->serial, xhdr.serial0); - return (ISC_R_UNEXPECTED); - } - - /* - * Check for offset wraparound. - */ - if ((isc_offset_t)(pos->offset + sizeof(journal_rawxhdr_t) + xhdr.size) - < pos->offset) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: offset too large", j->filename); - return (ISC_R_UNEXPECTED); - } - - pos->offset += sizeof(journal_rawxhdr_t) + xhdr.size; - pos->serial = xhdr.serial1; - return (ISC_R_SUCCESS); -} - -/* - * If the index of the journal 'j' contains an entry "better" - * than '*best_guess', replace '*best_guess' with it. - * - * "Better" means having a serial number closer to 'serial' - * but not greater than 'serial'. - */ -static void -index_find(dns_journal_t *j, uint32_t serial, journal_pos_t *best_guess) { - unsigned int i; - if (j->index == NULL) - return; - for (i = 0; i < j->header.index_size; i++) { - if (POS_VALID(j->index[i]) && - DNS_SERIAL_GE(serial, j->index[i].serial) && - DNS_SERIAL_GT(j->index[i].serial, best_guess->serial)) - *best_guess = j->index[i]; - } -} - -/* - * Add a new index entry. If there is no room, make room by removing - * the odd-numbered entries and compacting the others into the first - * half of the index. This decimates old index entries exponentially - * over time, so that the index always contains a much larger fraction - * of recent serial numbers than of old ones. This is deliberate - - * most index searches are for outgoing IXFR, and IXFR tends to request - * recent versions more often than old ones. - */ -static void -index_add(dns_journal_t *j, journal_pos_t *pos) { - unsigned int i; - if (j->index == NULL) - return; - /* - * Search for a vacant position. - */ - for (i = 0; i < j->header.index_size; i++) { - if (! POS_VALID(j->index[i])) - break; - } - if (i == j->header.index_size) { - unsigned int k = 0; - /* - * Found no vacant position. Make some room. - */ - for (i = 0; i < j->header.index_size; i += 2) { - j->index[k++] = j->index[i]; - } - i = k; /* 'i' identifies the first vacant position. */ - while (k < j->header.index_size) { - POS_INVALIDATE(j->index[k]); - k++; - } - } - INSIST(i < j->header.index_size); - INSIST(! POS_VALID(j->index[i])); - - /* - * Store the new index entry. - */ - j->index[i] = *pos; -} - -/* - * Invalidate any existing index entries that could become - * ambiguous when a new transaction with number 'serial' is added. - */ -static void -index_invalidate(dns_journal_t *j, uint32_t serial) { - unsigned int i; - if (j->index == NULL) - return; - for (i = 0; i < j->header.index_size; i++) { - if (! DNS_SERIAL_GT(serial, j->index[i].serial)) - POS_INVALIDATE(j->index[i]); - } -} - -/* - * Try to find a transaction with initial serial number 'serial' - * in the journal 'j'. - * - * If found, store its position at '*pos' and return ISC_R_SUCCESS. - * - * If 'serial' is current (= the ending serial number of the - * last transaction in the journal), set '*pos' to - * the position immediately following the last transaction and - * return ISC_R_SUCCESS. - * - * If 'serial' is within the range of addressable serial numbers - * covered by the journal but that particular serial number is missing - * (from the journal, not just from the index), return ISC_R_NOTFOUND. - * - * If 'serial' is outside the range of addressable serial numbers - * covered by the journal, return ISC_R_RANGE. - * - */ -static isc_result_t -journal_find(dns_journal_t *j, uint32_t serial, journal_pos_t *pos) { - isc_result_t result; - journal_pos_t current_pos; - REQUIRE(DNS_JOURNAL_VALID(j)); - - if (DNS_SERIAL_GT(j->header.begin.serial, serial)) - return (ISC_R_RANGE); - if (DNS_SERIAL_GT(serial, j->header.end.serial)) - return (ISC_R_RANGE); - if (serial == j->header.end.serial) { - *pos = j->header.end; - return (ISC_R_SUCCESS); - } - - current_pos = j->header.begin; - index_find(j, serial, ¤t_pos); - - while (current_pos.serial != serial) { - if (DNS_SERIAL_GT(current_pos.serial, serial)) - return (ISC_R_NOTFOUND); - result = journal_next(j, ¤t_pos); - if (result != ISC_R_SUCCESS) - return (result); - } - *pos = current_pos; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_journal_begin_transaction(dns_journal_t *j) { - uint32_t offset; - isc_result_t result; - journal_rawxhdr_t hdr; - - REQUIRE(DNS_JOURNAL_VALID(j)); - REQUIRE(j->state == JOURNAL_STATE_WRITE || - j->state == JOURNAL_STATE_INLINE); - - /* - * Find the file offset where the new transaction should - * be written, and seek there. - */ - if (JOURNAL_EMPTY(&j->header)) { - offset = sizeof(journal_rawheader_t) + - j->header.index_size * sizeof(journal_rawpos_t); - } else { - offset = j->header.end.offset; - } - j->x.pos[0].offset = offset; - j->x.pos[1].offset = offset; /* Initial value, will be incremented. */ - j->x.n_soa = 0; - - CHECK(journal_seek(j, offset)); - - /* - * Write a dummy transaction header of all zeroes to reserve - * space. It will be filled in when the transaction is - * finished. - */ - memset(&hdr, 0, sizeof(hdr)); - CHECK(journal_write(j, &hdr, sizeof(hdr))); - j->x.pos[1].offset = j->offset; - - j->state = JOURNAL_STATE_TRANSACTION; - result = ISC_R_SUCCESS; - failure: - return (result); -} - -isc_result_t -dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) { - dns_difftuple_t *t; - isc_buffer_t buffer; - void *mem = NULL; - uint64_t size; - isc_result_t result; - isc_region_t used; - - REQUIRE(DNS_DIFF_VALID(diff)); - REQUIRE(j->state == JOURNAL_STATE_TRANSACTION); - - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "writing to journal"); - (void)dns_diff_print(diff, NULL); - - /* - * Pass 1: determine the buffer size needed, and - * keep track of SOA serial numbers. - */ - size = 0; - for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - if (t->rdata.type == dns_rdatatype_soa) { - if (j->x.n_soa < 2) - j->x.pos[j->x.n_soa].serial = - dns_soa_getserial(&t->rdata); - j->x.n_soa++; - } - size += sizeof(journal_rawrrhdr_t); - size += t->name.length; /* XXX should have access macro? */ - size += 10; - size += t->rdata.length; - } - - if (size >= INT32_MAX) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "dns_journal_writediff: %s: journal entry " - "too big to be stored: %" PRIu64 " bytes", - j->filename, size); - return (ISC_R_NOSPACE); - } - - mem = isc_mem_get(j->mctx, size); - if (mem == NULL) - return (ISC_R_NOMEMORY); - - isc_buffer_init(&buffer, mem, size); - - /* - * Pass 2. Write RRs to buffer. - */ - for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - /* - * Write the RR header. - */ - isc_buffer_putuint32(&buffer, t->name.length + 10 + - t->rdata.length); - /* - * Write the owner name, RR header, and RR data. - */ - isc_buffer_putmem(&buffer, t->name.ndata, t->name.length); - isc_buffer_putuint16(&buffer, t->rdata.type); - isc_buffer_putuint16(&buffer, t->rdata.rdclass); - isc_buffer_putuint32(&buffer, t->ttl); - INSIST(t->rdata.length < 65536); - isc_buffer_putuint16(&buffer, (uint16_t)t->rdata.length); - INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length); - isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length); - } - - isc_buffer_usedregion(&buffer, &used); - INSIST(used.length == size); - - j->x.pos[1].offset += used.length; - - /* - * Write the buffer contents to the journal file. - */ - CHECK(journal_write(j, used.base, used.length)); - - result = ISC_R_SUCCESS; - - failure: - if (mem != NULL) - isc_mem_put(j->mctx, mem, size); - return (result); - -} - -isc_result_t -dns_journal_commit(dns_journal_t *j) { - isc_result_t result; - journal_rawheader_t rawheader; - uint64_t total; - - REQUIRE(DNS_JOURNAL_VALID(j)); - REQUIRE(j->state == JOURNAL_STATE_TRANSACTION || - j->state == JOURNAL_STATE_INLINE); - - /* - * Just write out a updated header. - */ - if (j->state == JOURNAL_STATE_INLINE) { - CHECK(journal_fsync(j)); - journal_header_encode(&j->header, &rawheader); - CHECK(journal_seek(j, 0)); - CHECK(journal_write(j, &rawheader, sizeof(rawheader))); - CHECK(journal_fsync(j)); - j->state = JOURNAL_STATE_WRITE; - return (ISC_R_SUCCESS); - } - - /* - * Perform some basic consistency checks. - */ - if (j->x.n_soa != 2) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: malformed transaction: %d SOAs", - j->filename, j->x.n_soa); - return (ISC_R_UNEXPECTED); - } - if (! (DNS_SERIAL_GT(j->x.pos[1].serial, j->x.pos[0].serial) || - (bind8_compat && - j->x.pos[1].serial == j->x.pos[0].serial))) - { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: malformed transaction: serial number " - "would decrease", j->filename); - return (ISC_R_UNEXPECTED); - } - if (! JOURNAL_EMPTY(&j->header)) { - if (j->x.pos[0].serial != j->header.end.serial) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "malformed transaction: " - "%s last serial %u != " - "transaction first serial %u", - j->filename, - j->header.end.serial, - j->x.pos[0].serial); - return (ISC_R_UNEXPECTED); - } - } - - /* - * We currently don't support huge journal entries. - */ - total = j->x.pos[1].offset - j->x.pos[0].offset; - if (total >= INT32_MAX) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "transaction too big to be stored in journal: " - "%" PRIu64 "b (max is %" PRIu64 "b)", total, - (uint64_t)INT32_MAX); - return (ISC_R_UNEXPECTED); - } - - /* - * Some old journal entries may become non-addressable - * when we increment the current serial number. Purge them - * by stepping header.begin forward to the first addressable - * transaction. Also purge them from the index. - */ - if (! JOURNAL_EMPTY(&j->header)) { - while (! DNS_SERIAL_GT(j->x.pos[1].serial, - j->header.begin.serial)) { - CHECK(journal_next(j, &j->header.begin)); - } - index_invalidate(j, j->x.pos[1].serial); - } -#ifdef notyet - if (DNS_SERIAL_GT(last_dumped_serial, j->x.pos[1].serial)) { - force_dump(...); - } -#endif - - /* - * Commit the transaction data to stable storage. - */ - CHECK(journal_fsync(j)); - - if (j->state == JOURNAL_STATE_TRANSACTION) { - isc_offset_t offset; - offset = (j->x.pos[1].offset - j->x.pos[0].offset) - - sizeof(journal_rawxhdr_t); - /* - * Update the transaction header. - */ - CHECK(journal_seek(j, j->x.pos[0].offset)); - CHECK(journal_write_xhdr(j, offset, j->x.pos[0].serial, - j->x.pos[1].serial)); - } - - /* - * Update the journal header. - */ - if (JOURNAL_EMPTY(&j->header)) - j->header.begin = j->x.pos[0]; - j->header.end = j->x.pos[1]; - journal_header_encode(&j->header, &rawheader); - CHECK(journal_seek(j, 0)); - CHECK(journal_write(j, &rawheader, sizeof(rawheader))); - - /* - * Update the index. - */ - index_add(j, &j->x.pos[0]); - - /* - * Convert the index into on-disk format and write - * it to disk. - */ - CHECK(index_to_disk(j)); - - /* - * Commit the header to stable storage. - */ - CHECK(journal_fsync(j)); - - /* - * We no longer have a transaction open. - */ - j->state = JOURNAL_STATE_WRITE; - - result = ISC_R_SUCCESS; - - failure: - return (result); -} - -isc_result_t -dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff) { - isc_result_t result; - CHECK(dns_diff_sort(diff, ixfr_order)); - CHECK(dns_journal_begin_transaction(j)); - CHECK(dns_journal_writediff(j, diff)); - CHECK(dns_journal_commit(j)); - result = ISC_R_SUCCESS; - failure: - return (result); -} - -void -dns_journal_destroy(dns_journal_t **journalp) { - dns_journal_t *j = *journalp; - REQUIRE(DNS_JOURNAL_VALID(j)); - - j->it.result = ISC_R_FAILURE; - dns_name_invalidate(&j->it.name); - dns_decompress_invalidate(&j->it.dctx); - if (j->rawindex != NULL) - isc_mem_put(j->mctx, j->rawindex, j->header.index_size * - sizeof(journal_rawpos_t)); - if (j->index != NULL) - isc_mem_put(j->mctx, j->index, j->header.index_size * - sizeof(journal_pos_t)); - if (j->it.target.base != NULL) - isc_mem_put(j->mctx, j->it.target.base, j->it.target.length); - if (j->it.source.base != NULL) - isc_mem_put(j->mctx, j->it.source.base, j->it.source.length); - if (j->filename != NULL) - isc_mem_free(j->mctx, j->filename); - if (j->fp != NULL) - (void)isc_stdio_close(j->fp); - j->magic = 0; - isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); - *journalp = NULL; -} - -/* - * Roll the open journal 'j' into the database 'db'. - * A new database version will be created. - */ - -/* XXX Share code with incoming IXFR? */ - -static isc_result_t -roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) { - isc_buffer_t source; /* Transaction data from disk */ - isc_buffer_t target; /* Ditto after _fromwire check */ - uint32_t db_serial; /* Database SOA serial */ - uint32_t end_serial; /* Last journal SOA serial */ - isc_result_t result; - dns_dbversion_t *ver = NULL; - journal_pos_t pos; - dns_diff_t diff; - unsigned int n_soa = 0; - unsigned int n_put = 0; - dns_diffop_t op; - - REQUIRE(DNS_JOURNAL_VALID(j)); - REQUIRE(DNS_DB_VALID(db)); - - dns_diff_init(j->mctx, &diff); - - /* - * Set up empty initial buffers for unchecked and checked - * wire format transaction data. They will be reallocated - * later. - */ - isc_buffer_init(&source, NULL, 0); - isc_buffer_init(&target, NULL, 0); - - /* - * Create the new database version. - */ - CHECK(dns_db_newversion(db, &ver)); - - /* - * Get the current database SOA serial number. - */ - CHECK(dns_db_getsoaserial(db, ver, &db_serial)); - - /* - * Locate a journal entry for the current database serial. - */ - CHECK(journal_find(j, db_serial, &pos)); - /* - * XXX do more drastic things, like marking zone stale, - * if this fails? - */ - /* - * XXXRTH The zone code should probably mark the zone as bad and - * scream loudly into the log if this is a dynamic update - * log reply that failed. - */ - - end_serial = dns_journal_last_serial(j); - if (db_serial == end_serial) - CHECK(DNS_R_UPTODATE); - - CHECK(dns_journal_iter_init(j, db_serial, end_serial)); - - for (result = dns_journal_first_rr(j); - result == ISC_R_SUCCESS; - result = dns_journal_next_rr(j)) - { - dns_name_t *name; - uint32_t ttl; - dns_rdata_t *rdata; - dns_difftuple_t *tuple = NULL; - - name = NULL; - rdata = NULL; - dns_journal_current_rr(j, &name, &ttl, &rdata); - - if (rdata->type == dns_rdatatype_soa) { - n_soa++; - if (n_soa == 2) - db_serial = j->it.current_serial; - } - - if (n_soa == 3) - n_soa = 1; - if (n_soa == 0) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal file corrupt: missing " - "initial SOA", j->filename); - FAIL(ISC_R_UNEXPECTED); - } - if ((options & DNS_JOURNALOPT_RESIGN) != 0) - op = (n_soa == 1) ? DNS_DIFFOP_DELRESIGN : - DNS_DIFFOP_ADDRESIGN; - else - op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; - - CHECK(dns_difftuple_create(diff.mctx, op, name, ttl, rdata, - &tuple)); - dns_diff_append(&diff, &tuple); - - if (++n_put > 100) { - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), - "%s: applying diff to database (%u)", - j->filename, db_serial); - (void)dns_diff_print(&diff, NULL); - CHECK(dns_diff_apply(&diff, db, ver)); - dns_diff_clear(&diff); - n_put = 0; - } - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - CHECK(result); - - if (n_put != 0) { - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), - "%s: applying final diff to database (%u)", - j->filename, db_serial); - (void)dns_diff_print(&diff, NULL); - CHECK(dns_diff_apply(&diff, db, ver)); - dns_diff_clear(&diff); - } - - failure: - if (ver != NULL) - dns_db_closeversion(db, &ver, result == ISC_R_SUCCESS ? - true : false); - - if (source.base != NULL) - isc_mem_put(j->mctx, source.base, source.length); - if (target.base != NULL) - isc_mem_put(j->mctx, target.base, target.length); - - dns_diff_clear(&diff); - - INSIST(ver == NULL); - - return (result); -} - -isc_result_t -dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, - const char *filename) -{ - dns_journal_t *j; - isc_result_t result; - - REQUIRE(DNS_DB_VALID(db)); - REQUIRE(filename != NULL); - - j = NULL; - result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); - if (result == ISC_R_NOTFOUND) { - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), - "no journal file, but that's OK"); - return (DNS_R_NOJOURNAL); - } - if (result != ISC_R_SUCCESS) - return (result); - if (JOURNAL_EMPTY(&j->header)) - result = DNS_R_UPTODATE; - else - result = roll_forward(j, db, options); - - dns_journal_destroy(&j); - - return (result); -} - -isc_result_t -dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) { - dns_journal_t *j; - isc_buffer_t source; /* Transaction data from disk */ - isc_buffer_t target; /* Ditto after _fromwire check */ - uint32_t start_serial; /* Database SOA serial */ - uint32_t end_serial; /* Last journal SOA serial */ - isc_result_t result; - dns_diff_t diff; - unsigned int n_soa = 0; - unsigned int n_put = 0; - - REQUIRE(filename != NULL); - - j = NULL; - result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); - if (result == ISC_R_NOTFOUND) { - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file"); - return (DNS_R_NOJOURNAL); - } - - if (result != ISC_R_SUCCESS) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "journal open failure: %s: %s", - isc_result_totext(result), filename); - return (result); - } - - if (j->header.serialset) - fprintf(file, "Source serial = %u\n", j->header.sourceserial); - dns_diff_init(j->mctx, &diff); - - /* - * Set up empty initial buffers for unchecked and checked - * wire format transaction data. They will be reallocated - * later. - */ - isc_buffer_init(&source, NULL, 0); - isc_buffer_init(&target, NULL, 0); - - start_serial = dns_journal_first_serial(j); - end_serial = dns_journal_last_serial(j); - - CHECK(dns_journal_iter_init(j, start_serial, end_serial)); - - for (result = dns_journal_first_rr(j); - result == ISC_R_SUCCESS; - result = dns_journal_next_rr(j)) - { - dns_name_t *name; - uint32_t ttl; - dns_rdata_t *rdata; - dns_difftuple_t *tuple = NULL; - - name = NULL; - rdata = NULL; - dns_journal_current_rr(j, &name, &ttl, &rdata); - - if (rdata->type == dns_rdatatype_soa) - n_soa++; - - if (n_soa == 3) - n_soa = 1; - if (n_soa == 0) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal file corrupt: missing " - "initial SOA", j->filename); - FAIL(ISC_R_UNEXPECTED); - } - CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ? - DNS_DIFFOP_DEL : DNS_DIFFOP_ADD, - name, ttl, rdata, &tuple)); - dns_diff_append(&diff, &tuple); - - if (++n_put > 100) { - result = dns_diff_print(&diff, file); - dns_diff_clear(&diff); - n_put = 0; - if (result != ISC_R_SUCCESS) - break; - } - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - CHECK(result); - - if (n_put != 0) { - result = dns_diff_print(&diff, file); - dns_diff_clear(&diff); - } - goto cleanup; - - failure: - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: cannot print: journal file corrupt", j->filename); - - cleanup: - if (source.base != NULL) - isc_mem_put(j->mctx, source.base, source.length); - if (target.base != NULL) - isc_mem_put(j->mctx, target.base, target.length); - - dns_diff_clear(&diff); - dns_journal_destroy(&j); - - return (result); -} - -/**************************************************************************/ -/* - * Miscellaneous accessors. - */ -uint32_t -dns_journal_first_serial(dns_journal_t *j) { - return (j->header.begin.serial); -} - -uint32_t -dns_journal_last_serial(dns_journal_t *j) { - return (j->header.end.serial); -} - -void -dns_journal_set_sourceserial(dns_journal_t *j, uint32_t sourceserial) { - - REQUIRE(j->state == JOURNAL_STATE_WRITE || - j->state == JOURNAL_STATE_INLINE || - j->state == JOURNAL_STATE_TRANSACTION); - - j->header.sourceserial = sourceserial; - j->header.serialset = true; - if (j->state == JOURNAL_STATE_WRITE) - j->state = JOURNAL_STATE_INLINE; -} - -bool -dns_journal_get_sourceserial(dns_journal_t *j, uint32_t *sourceserial) { - REQUIRE(sourceserial != NULL); - - if (!j->header.serialset) - return (false); - *sourceserial = j->header.sourceserial; - return (true); -} - -/**************************************************************************/ -/* - * Iteration support. - * - * When serving an outgoing IXFR, we transmit a part the journal starting - * at the serial number in the IXFR request and ending at the serial - * number that is current when the IXFR request arrives. The ending - * serial number is not necessarily at the end of the journal: - * the journal may grow while the IXFR is in progress, but we stop - * when we reach the serial number that was current when the IXFR started. - */ - -static isc_result_t read_one_rr(dns_journal_t *j); - -/* - * Make sure the buffer 'b' is has at least 'size' bytes - * allocated, and clear it. - * - * Requires: - * Either b->base is NULL, or it points to b->length bytes of memory - * previously allocated by isc_mem_get(). - */ - -static isc_result_t -size_buffer(isc_mem_t *mctx, isc_buffer_t *b, unsigned size) { - if (b->length < size) { - void *mem = isc_mem_get(mctx, size); - if (mem == NULL) - return (ISC_R_NOMEMORY); - if (b->base != NULL) - isc_mem_put(mctx, b->base, b->length); - b->base = mem; - b->length = size; - } - isc_buffer_clear(b); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_journal_iter_init(dns_journal_t *j, - uint32_t begin_serial, uint32_t end_serial) -{ - isc_result_t result; - - CHECK(journal_find(j, begin_serial, &j->it.bpos)); - INSIST(j->it.bpos.serial == begin_serial); - - CHECK(journal_find(j, end_serial, &j->it.epos)); - INSIST(j->it.epos.serial == end_serial); - - result = ISC_R_SUCCESS; - failure: - j->it.result = result; - return (j->it.result); -} - - -isc_result_t -dns_journal_first_rr(dns_journal_t *j) { - isc_result_t result; - - /* - * Seek to the beginning of the first transaction we are - * interested in. - */ - CHECK(journal_seek(j, j->it.bpos.offset)); - j->it.current_serial = j->it.bpos.serial; - - j->it.xsize = 0; /* We have no transaction data yet... */ - j->it.xpos = 0; /* ...and haven't used any of it. */ - - return (read_one_rr(j)); - - failure: - return (result); -} - -static isc_result_t -read_one_rr(dns_journal_t *j) { - isc_result_t result; - - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - unsigned int rdlen; - uint32_t ttl; - journal_xhdr_t xhdr; - journal_rrhdr_t rrhdr; - - if (j->offset > j->it.epos.offset) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal corrupt: possible integer overflow", - j->filename); - return (ISC_R_UNEXPECTED); - } - if (j->offset == j->it.epos.offset) - return (ISC_R_NOMORE); - if (j->it.xpos == j->it.xsize) { - /* - * We are at a transaction boundary. - * Read another transaction header. - */ - CHECK(journal_read_xhdr(j, &xhdr)); - if (xhdr.size == 0) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal corrupt: empty transaction", - j->filename); - FAIL(ISC_R_UNEXPECTED); - } - if (xhdr.serial0 != j->it.current_serial) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal file corrupt: " - "expected serial %u, got %u", - j->filename, - j->it.current_serial, xhdr.serial0); - FAIL(ISC_R_UNEXPECTED); - } - j->it.xsize = xhdr.size; - j->it.xpos = 0; - } - /* - * Read an RR. - */ - CHECK(journal_read_rrhdr(j, &rrhdr)); - /* - * Perform a sanity check on the journal RR size. - * The smallest possible RR has a 1-byte owner name - * and a 10-byte header. The largest possible - * RR has 65535 bytes of data, a header, and a maximum- - * size owner name, well below 70 k total. - */ - if (rrhdr.size < 1+10 || rrhdr.size > 70000) { - isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, - "%s: journal corrupt: impossible RR size " - "(%d bytes)", j->filename, rrhdr.size); - FAIL(ISC_R_UNEXPECTED); - } - - CHECK(size_buffer(j->mctx, &j->it.source, rrhdr.size)); - CHECK(journal_read(j, j->it.source.base, rrhdr.size)); - isc_buffer_add(&j->it.source, rrhdr.size); - - /* - * The target buffer is made the same size - * as the source buffer, with the assumption that when - * no compression in present, the output of dns_*_fromwire() - * is no larger than the input. - */ - CHECK(size_buffer(j->mctx, &j->it.target, rrhdr.size)); - - /* - * Parse the owner name. We don't know where it - * ends yet, so we make the entire "remaining" - * part of the buffer "active". - */ - isc_buffer_setactive(&j->it.source, - j->it.source.used - j->it.source.current); - CHECK(dns_name_fromwire(&j->it.name, &j->it.source, - &j->it.dctx, 0, &j->it.target)); - - /* - * Check that the RR header is there, and parse it. - */ - if (isc_buffer_remaininglength(&j->it.source) < 10) - FAIL(DNS_R_FORMERR); - - rdtype = isc_buffer_getuint16(&j->it.source); - rdclass = isc_buffer_getuint16(&j->it.source); - ttl = isc_buffer_getuint32(&j->it.source); - rdlen = isc_buffer_getuint16(&j->it.source); - - /* - * Parse the rdata. - */ - if (isc_buffer_remaininglength(&j->it.source) != rdlen) - FAIL(DNS_R_FORMERR); - isc_buffer_setactive(&j->it.source, rdlen); - dns_rdata_reset(&j->it.rdata); - CHECK(dns_rdata_fromwire(&j->it.rdata, rdclass, - rdtype, &j->it.source, &j->it.dctx, - 0, &j->it.target)); - j->it.ttl = ttl; - - j->it.xpos += sizeof(journal_rawrrhdr_t) + rrhdr.size; - if (rdtype == dns_rdatatype_soa) { - /* XXX could do additional consistency checks here */ - j->it.current_serial = dns_soa_getserial(&j->it.rdata); - } - - result = ISC_R_SUCCESS; - - failure: - j->it.result = result; - return (result); -} - -isc_result_t -dns_journal_next_rr(dns_journal_t *j) { - j->it.result = read_one_rr(j); - return (j->it.result); -} - -void -dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, uint32_t *ttl, - dns_rdata_t **rdata) -{ - REQUIRE(j->it.result == ISC_R_SUCCESS); - *name = &j->it.name; - *ttl = j->it.ttl; - *rdata = &j->it.rdata; -} - -/**************************************************************************/ -/* - * Generating diffs from databases - */ - -/* - * Construct a diff containing all the RRs at the current name of the - * database iterator 'dbit' in database 'db', version 'ver'. - * Set '*name' to the current name, and append the diff to 'diff'. - * All new tuples will have the operation 'op'. - * - * Requires: 'name' must have buffer large enough to hold the name. - * Typically, a dns_fixedname_t would be used. - */ -static isc_result_t -get_name_diff(dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now, - dns_dbiterator_t *dbit, dns_name_t *name, dns_diffop_t op, - dns_diff_t *diff) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdatasetiter_t *rdsiter = NULL; - dns_difftuple_t *tuple = NULL; - - result = dns_dbiterator_current(dbit, &node, name); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_allrdatasets(db, node, ver, now, &rdsiter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) - { - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(rdsiter, &rdataset); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = dns_difftuple_create(diff->mctx, op, name, - rdataset.ttl, &rdata, - &tuple); - if (result != ISC_R_SUCCESS) { - dns_rdataset_disassociate(&rdataset); - goto cleanup_iterator; - } - dns_diff_append(diff, &tuple); - } - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_NOMORE) - goto cleanup_iterator; - } - if (result != ISC_R_NOMORE) - goto cleanup_iterator; - - result = ISC_R_SUCCESS; - - cleanup_iterator: - dns_rdatasetiter_destroy(&rdsiter); - - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/* - * Comparison function for use by dns_diff_subtract when sorting - * the diffs to be subtracted. The sort keys are the rdata type - * and the rdata itself. The owner name is ignored, because - * it is known to be the same for all tuples. - */ -static int -rdata_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - r = (b->rdata.type - a->rdata.type); - if (r != 0) - return (r); - r = dns_rdata_compare(&a->rdata, &b->rdata); - return (r); -} - -static isc_result_t -dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { - isc_result_t result; - dns_difftuple_t *p[2]; - int i, t; - bool append; - - CHECK(dns_diff_sort(&diff[0], rdata_order)); - CHECK(dns_diff_sort(&diff[1], rdata_order)); - - for (;;) { - p[0] = ISC_LIST_HEAD(diff[0].tuples); - p[1] = ISC_LIST_HEAD(diff[1].tuples); - if (p[0] == NULL && p[1] == NULL) - break; - - for (i = 0; i < 2; i++) - if (p[!i] == NULL) { - ISC_LIST_UNLINK(diff[i].tuples, p[i], link); - ISC_LIST_APPEND(r->tuples, p[i], link); - goto next; - } - t = rdata_order(&p[0], &p[1]); - if (t < 0) { - ISC_LIST_UNLINK(diff[0].tuples, p[0], link); - ISC_LIST_APPEND(r->tuples, p[0], link); - goto next; - } - if (t > 0) { - ISC_LIST_UNLINK(diff[1].tuples, p[1], link); - ISC_LIST_APPEND(r->tuples, p[1], link); - goto next; - } - INSIST(t == 0); - /* - * Identical RRs in both databases; skip them both - * if the ttl differs. - */ - append = (p[0]->ttl != p[1]->ttl); - for (i = 0; i < 2; i++) { - ISC_LIST_UNLINK(diff[i].tuples, p[i], link); - if (append) { - ISC_LIST_APPEND(r->tuples, p[i], link); - } else { - dns_difftuple_free(&p[i]); - } - } - next: ; - } - result = ISC_R_SUCCESS; - failure: - return (result); -} - -static isc_result_t -diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - unsigned int options, dns_diff_t *resultdiff) -{ - dns_db_t *db[2]; - dns_dbversion_t *ver[2]; - dns_dbiterator_t *dbit[2] = { NULL, NULL }; - bool have[2] = { false, false }; - dns_fixedname_t fixname[2]; - isc_result_t result, itresult[2]; - dns_diff_t diff[2]; - int i, t; - - db[0] = dba, db[1] = dbb; - ver[0] = dbvera, ver[1] = dbverb; - - dns_diff_init(resultdiff->mctx, &diff[0]); - dns_diff_init(resultdiff->mctx, &diff[1]); - - dns_fixedname_init(&fixname[0]); - dns_fixedname_init(&fixname[1]); - - result = dns_db_createiterator(db[0], options, &dbit[0]); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_db_createiterator(db[1], options, &dbit[1]); - if (result != ISC_R_SUCCESS) - goto cleanup_iterator; - - itresult[0] = dns_dbiterator_first(dbit[0]); - itresult[1] = dns_dbiterator_first(dbit[1]); - - for (;;) { - for (i = 0; i < 2; i++) { - if (! have[i] && itresult[i] == ISC_R_SUCCESS) { - CHECK(get_name_diff(db[i], ver[i], 0, dbit[i], - dns_fixedname_name(&fixname[i]), - i == 0 ? - DNS_DIFFOP_ADD : - DNS_DIFFOP_DEL, - &diff[i])); - itresult[i] = dns_dbiterator_next(dbit[i]); - have[i] = true; - } - } - - if (! have[0] && ! have[1]) { - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - break; - } - - for (i = 0; i < 2; i++) { - if (! have[!i]) { - ISC_LIST_APPENDLIST(resultdiff->tuples, - diff[i].tuples, link); - INSIST(ISC_LIST_EMPTY(diff[i].tuples)); - have[i] = false; - goto next; - } - } - - t = dns_name_compare(dns_fixedname_name(&fixname[0]), - dns_fixedname_name(&fixname[1])); - if (t < 0) { - ISC_LIST_APPENDLIST(resultdiff->tuples, - diff[0].tuples, link); - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - have[0] = false; - continue; - } - if (t > 0) { - ISC_LIST_APPENDLIST(resultdiff->tuples, - diff[1].tuples, link); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - have[1] = false; - continue; - } - INSIST(t == 0); - CHECK(dns_diff_subtract(diff, resultdiff)); - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - have[0] = have[1] = false; - next: ; - } - if (itresult[0] != ISC_R_NOMORE) - FAIL(itresult[0]); - if (itresult[1] != ISC_R_NOMORE) - FAIL(itresult[1]); - - INSIST(ISC_LIST_EMPTY(diff[0].tuples)); - INSIST(ISC_LIST_EMPTY(diff[1].tuples)); - - failure: - dns_dbiterator_destroy(&dbit[1]); - - cleanup_iterator: - dns_dbiterator_destroy(&dbit[0]); - dns_diff_clear(&diff[0]); - dns_diff_clear(&diff[1]); - return (result); -} - -/* - * Compare the databases 'dba' and 'dbb' and generate a journal - * entry containing the changes to make 'dba' from 'dbb' (note - * the order). This journal entry will consist of a single, - * possibly very large transaction. - */ -isc_result_t -dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) -{ - isc_result_t result; - dns_diff_t diff; - - dns_diff_init(mctx, &diff); - - result = dns_db_diffx(&diff, dba, dbvera, dbb, dbverb, filename); - - dns_diff_clear(&diff); - - return (result); -} - -isc_result_t -dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) -{ - isc_result_t result; - dns_journal_t *journal = NULL; - - if (filename != NULL) { - result = dns_journal_open(diff->mctx, filename, - DNS_JOURNAL_CREATE, &journal); - if (result != ISC_R_SUCCESS) - return (result); - } - - CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NONSEC3, diff)); - CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NSEC3ONLY, diff)); - - if (journal != NULL) { - if (ISC_LIST_EMPTY(diff->tuples)) - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); - else - CHECK(dns_journal_write_transaction(journal, diff)); - } - - failure: - if (journal != NULL) - dns_journal_destroy(&journal); - return (result); -} - -isc_result_t -dns_journal_compact(isc_mem_t *mctx, char *filename, uint32_t serial, - uint32_t target_size) -{ - unsigned int i; - journal_pos_t best_guess; - journal_pos_t current_pos; - dns_journal_t *j1 = NULL; - dns_journal_t *j2 = NULL; - journal_rawheader_t rawheader; - unsigned int copy_length; - size_t namelen; - char *buf = NULL; - unsigned int size = 0; - isc_result_t result; - unsigned int indexend; - char newname[1024]; - char backup[1024]; - bool is_backup = false; - - REQUIRE(filename != NULL); - - namelen = strlen(filename); - if (namelen > 4U && strcmp(filename + namelen - 4, ".jnl") == 0) - namelen -= 4; - - result = isc_string_printf(newname, sizeof(newname), "%.*s.jnw", - (int)namelen, filename); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk", - (int)namelen, filename); - if (result != ISC_R_SUCCESS) - return (result); - - result = journal_open(mctx, filename, false, false, &j1); - if (result == ISC_R_NOTFOUND) { - is_backup = true; - result = journal_open(mctx, backup, false, false, &j1); - } - if (result != ISC_R_SUCCESS) - return (result); - - if (JOURNAL_EMPTY(&j1->header)) { - dns_journal_destroy(&j1); - return (ISC_R_SUCCESS); - } - - if (DNS_SERIAL_GT(j1->header.begin.serial, serial) || - DNS_SERIAL_GT(serial, j1->header.end.serial)) { - dns_journal_destroy(&j1); - return (ISC_R_RANGE); - } - - /* - * Cope with very small target sizes. - */ - indexend = sizeof(journal_rawheader_t) + - j1->header.index_size * sizeof(journal_rawpos_t); - if (target_size < indexend * 2) - target_size = target_size/2 + indexend; - - /* - * See if there is any work to do. - */ - if ((uint32_t) j1->header.end.offset < target_size) { - dns_journal_destroy(&j1); - return (ISC_R_SUCCESS); - } - - CHECK(journal_open(mctx, newname, true, true, &j2)); - - /* - * Remove overhead so space test below can succeed. - */ - if (target_size >= indexend) - target_size -= indexend; - - /* - * Find if we can create enough free space. - */ - best_guess = j1->header.begin; - for (i = 0; i < j1->header.index_size; i++) { - if (POS_VALID(j1->index[i]) && - DNS_SERIAL_GE(serial, j1->index[i].serial) && - ((uint32_t)(j1->header.end.offset - j1->index[i].offset) - >= target_size / 2) && - j1->index[i].offset > best_guess.offset) - best_guess = j1->index[i]; - } - - current_pos = best_guess; - while (current_pos.serial != serial) { - CHECK(journal_next(j1, ¤t_pos)); - if (current_pos.serial == j1->header.end.serial) - break; - - if (DNS_SERIAL_GE(serial, current_pos.serial) && - ((uint32_t)(j1->header.end.offset - current_pos.offset) - >= (target_size / 2)) && - current_pos.offset > best_guess.offset) - best_guess = current_pos; - else - break; - } - - INSIST(best_guess.serial != j1->header.end.serial); - if (best_guess.serial != serial) - CHECK(journal_next(j1, &best_guess)); - - /* - * We should now be roughly half target_size provided - * we did not reach 'serial'. If not we will just copy - * all uncommitted deltas regardless of the size. - */ - copy_length = j1->header.end.offset - best_guess.offset; - - if (copy_length != 0) { - /* - * Copy best_guess to end into space just freed. - */ - size = 64*1024; - if (copy_length < size) - size = copy_length; - buf = isc_mem_get(mctx, size); - if (buf == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - - CHECK(journal_seek(j1, best_guess.offset)); - CHECK(journal_seek(j2, indexend)); - for (i = 0; i < copy_length; i += size) { - unsigned int len = (copy_length - i) > size ? size : - (copy_length - i); - CHECK(journal_read(j1, buf, len)); - CHECK(journal_write(j2, buf, len)); - } - - CHECK(journal_fsync(j2)); - - /* - * Compute new header. - */ - j2->header.begin.serial = best_guess.serial; - j2->header.begin.offset = indexend; - j2->header.end.serial = j1->header.end.serial; - j2->header.end.offset = indexend + copy_length; - j2->header.sourceserial = j1->header.sourceserial; - j2->header.serialset = j1->header.serialset; - - /* - * Update the journal header. - */ - journal_header_encode(&j2->header, &rawheader); - CHECK(journal_seek(j2, 0)); - CHECK(journal_write(j2, &rawheader, sizeof(rawheader))); - CHECK(journal_fsync(j2)); - - /* - * Build new index. - */ - current_pos = j2->header.begin; - while (current_pos.serial != j2->header.end.serial) { - index_add(j2, ¤t_pos); - CHECK(journal_next(j2, ¤t_pos)); - } - - /* - * Write index. - */ - CHECK(index_to_disk(j2)); - CHECK(journal_fsync(j2)); - - indexend = j2->header.end.offset; - POST(indexend); - } - - /* - * Close both journals before trying to rename files (this is - * necessary on WIN32). - */ - dns_journal_destroy(&j1); - dns_journal_destroy(&j2); - - /* - * With a UFS file system this should just succeed and be atomic. - * Any IXFR outs will just continue and the old journal will be - * removed on final close. - * - * With MSDOS / NTFS we need to do a two stage rename, triggered - * by EEXIST. (If any IXFR's are running in other threads, however, - * this will fail, and the journal will not be compacted. But - * if so, hopefully they'll be finished by the next time we - * compact.) - */ - if (rename(newname, filename) == -1) { - if (errno == EEXIST && !is_backup) { - result = isc_file_remove(backup); - if (result != ISC_R_SUCCESS && - result != ISC_R_FILENOTFOUND) - goto failure; - if (rename(filename, backup) == -1) - goto maperrno; - if (rename(newname, filename) == -1) - goto maperrno; - (void)isc_file_remove(backup); - } else { - maperrno: - result = ISC_R_FAILURE; - goto failure; - } - } - - result = ISC_R_SUCCESS; - - failure: - (void)isc_file_remove(newname); - if (buf != NULL) - isc_mem_put(mctx, buf, size); - if (j1 != NULL) - dns_journal_destroy(&j1); - if (j2 != NULL) - dns_journal_destroy(&j2); - return (result); -} - -static isc_result_t -index_to_disk(dns_journal_t *j) { - isc_result_t result = ISC_R_SUCCESS; - - if (j->header.index_size != 0) { - unsigned int i; - unsigned char *p; - unsigned int rawbytes; - - rawbytes = j->header.index_size * sizeof(journal_rawpos_t); - - p = j->rawindex; - for (i = 0; i < j->header.index_size; i++) { - encode_uint32(j->index[i].serial, p); - p += 4; - encode_uint32(j->index[i].offset, p); - p += 4; - } - INSIST(p == j->rawindex + rawbytes); - - CHECK(journal_seek(j, sizeof(journal_rawheader_t))); - CHECK(journal_write(j, j->rawindex, rawbytes)); - } -failure: - return (result); -} diff --git a/lib/dns-pkcs11/key.c b/lib/dns-pkcs11/key.c deleted file mode 100644 index f09e84e..0000000 --- a/lib/dns-pkcs11/key.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "dst_internal.h" - -uint16_t -dst_region_computeid(const isc_region_t *source, unsigned int alg) { - uint32_t ac; - const unsigned char *p; - int size; - - REQUIRE(source != NULL); - REQUIRE(source->length >= 4); - - p = source->base; - size = source->length; - - if (alg == DST_ALG_RSAMD5) - return ((p[size - 3] << 8) + p[size - 2]); - - for (ac = 0; size > 1; size -= 2, p += 2) - ac += ((*p) << 8) + *(p + 1); - - if (size > 0) - ac += ((*p) << 8); - ac += (ac >> 16) & 0xffff; - - return ((uint16_t)(ac & 0xffff)); -} - -uint16_t -dst_region_computerid(const isc_region_t *source, unsigned int alg) { - uint32_t ac; - const unsigned char *p; - int size; - - REQUIRE(source != NULL); - REQUIRE(source->length >= 4); - - p = source->base; - size = source->length; - - if (alg == DST_ALG_RSAMD5) - return ((p[size - 3] << 8) + p[size - 2]); - - ac = ((*p) << 8) + *(p + 1); - ac |= DNS_KEYFLAG_REVOKE; - for (size -= 2, p +=2; size > 1; size -= 2, p += 2) - ac += ((*p) << 8) + *(p + 1); - - if (size > 0) - ac += ((*p) << 8); - ac += (ac >> 16) & 0xffff; - - return ((uint16_t)(ac & 0xffff)); -} - -dns_name_t * -dst_key_name(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_name); -} - -unsigned int -dst_key_size(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_size); -} - -unsigned int -dst_key_proto(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_proto); -} - -unsigned int -dst_key_alg(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_alg); -} - -uint32_t -dst_key_flags(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_flags); -} - -dns_keytag_t -dst_key_id(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_id); -} - -dns_keytag_t -dst_key_rid(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_rid); -} - -dns_rdataclass_t -dst_key_class(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_class); -} - -bool -dst_key_iszonekey(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - - if ((key->key_flags & DNS_KEYTYPE_NOAUTH) != 0) - return (false); - if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) - return (false); - if (key->key_proto != DNS_KEYPROTO_DNSSEC && - key->key_proto != DNS_KEYPROTO_ANY) - return (false); - return (true); -} - -bool -dst_key_isnullkey(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - - if ((key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) - return (false); - if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) - return (false); - if (key->key_proto != DNS_KEYPROTO_DNSSEC && - key->key_proto != DNS_KEYPROTO_ANY) - return (false); - return (true); -} - -void -dst_key_setbits(dst_key_t *key, uint16_t bits) { - unsigned int maxbits; - REQUIRE(VALID_KEY(key)); - if (bits != 0) { - RUNTIME_CHECK(dst_key_sigsize(key, &maxbits) == ISC_R_SUCCESS); - maxbits *= 8; - REQUIRE(bits <= maxbits); - } - key->key_bits = bits; -} - -uint16_t -dst_key_getbits(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_bits); -} - -void -dst_key_setttl(dst_key_t *key, dns_ttl_t ttl) { - REQUIRE(VALID_KEY(key)); - key->key_ttl = ttl; -} - -dns_ttl_t -dst_key_getttl(const dst_key_t *key) { - REQUIRE(VALID_KEY(key)); - return (key->key_ttl); -} - -/*! \file */ diff --git a/lib/dns-pkcs11/keydata.c b/lib/dns-pkcs11/keydata.c deleted file mode 100644 index 3e7d537..0000000 --- a/lib/dns-pkcs11/keydata.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include - -isc_result_t -dns_keydata_todnskey(dns_rdata_keydata_t *keydata, - dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) -{ - REQUIRE(keydata != NULL && dnskey != NULL); - - dnskey->common.rdtype = dns_rdatatype_dnskey; - dnskey->common.rdclass = keydata->common.rdclass; - dnskey->mctx = mctx; - dnskey->flags = keydata->flags; - dnskey->protocol = keydata->protocol; - dnskey->algorithm = keydata->algorithm; - - dnskey->datalen = keydata->datalen; - - if (mctx == NULL) - dnskey->data = keydata->data; - else { - dnskey->data = isc_mem_allocate(mctx, dnskey->datalen); - if (dnskey->data == NULL) - return (ISC_R_NOMEMORY); - memmove(dnskey->data, keydata->data, dnskey->datalen); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata, - dns_rdata_dnskey_t *dnskey, - uint32_t refresh, uint32_t addhd, - uint32_t removehd, isc_mem_t *mctx) -{ - REQUIRE(keydata != NULL && dnskey != NULL); - - keydata->common.rdtype = dns_rdatatype_keydata; - keydata->common.rdclass = dnskey->common.rdclass; - keydata->mctx = mctx; - keydata->refresh = refresh; - keydata->addhd = addhd; - keydata->removehd = removehd; - keydata->flags = dnskey->flags; - keydata->protocol = dnskey->protocol; - keydata->algorithm = dnskey->algorithm; - - keydata->datalen = dnskey->datalen; - if (mctx == NULL) - keydata->data = dnskey->data; - else { - keydata->data = isc_mem_allocate(mctx, keydata->datalen); - if (keydata->data == NULL) - return (ISC_R_NOMEMORY); - memmove(keydata->data, dnskey->data, keydata->datalen); - } - - return (ISC_R_SUCCESS); -} diff --git a/lib/dns-pkcs11/keytable.c b/lib/dns-pkcs11/keytable.c deleted file mode 100644 index 37bfa9b..0000000 --- a/lib/dns-pkcs11/keytable.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include - -#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l') -#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC) - -#define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd') -#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC) - -struct dns_keytable { - /* Unlocked. */ - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t active_nodes; - isc_refcount_t references; - isc_rwlock_t rwlock; - /* Locked by rwlock. */ - dns_rbt_t *table; -}; - -struct dns_keynode { - unsigned int magic; - isc_refcount_t refcount; - dst_key_t * key; - bool managed; - struct dns_keynode * next; -}; - -static void -free_keynode(void *node, void *arg) { - dns_keynode_t *keynode = node; - isc_mem_t *mctx = arg; - - dns_keynode_detachall(mctx, &keynode); -} - -isc_result_t -dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) { - dns_keytable_t *keytable; - isc_result_t result; - - /* - * Create a keytable. - */ - - REQUIRE(keytablep != NULL && *keytablep == NULL); - - keytable = isc_mem_get(mctx, sizeof(*keytable)); - if (keytable == NULL) { - return (ISC_R_NOMEMORY); - } - - keytable->table = NULL; - result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table); - if (result != ISC_R_SUCCESS) { - goto cleanup_keytable; - } - - result = isc_rwlock_init(&keytable->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - goto cleanup_rbt; - } - - result = isc_refcount_init(&keytable->active_nodes, 0); - if (result != ISC_R_SUCCESS) { - goto cleanup_rwlock; - } - - result = isc_refcount_init(&keytable->references, 1); - if (result != ISC_R_SUCCESS) { - goto cleanup_active_nodes; - } - - keytable->mctx = NULL; - isc_mem_attach(mctx, &keytable->mctx); - keytable->magic = KEYTABLE_MAGIC; - *keytablep = keytable; - - return (ISC_R_SUCCESS); - - cleanup_active_nodes: - isc_refcount_destroy(&keytable->active_nodes); - - cleanup_rwlock: - isc_rwlock_destroy(&keytable->rwlock); - - cleanup_rbt: - dns_rbt_destroy(&keytable->table); - - cleanup_keytable: - isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable)); - - return (result); -} - -void -dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) { - - /* - * Attach *targetp to source. - */ - - REQUIRE(VALID_KEYTABLE(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - isc_refcount_increment(&source->references, NULL); - - *targetp = source; -} - -void -dns_keytable_detach(dns_keytable_t **keytablep) { - dns_keytable_t *keytable; - unsigned int refs; - - /* - * Detach *keytablep from its keytable. - */ - - REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep)); - - keytable = *keytablep; - *keytablep = NULL; - - isc_refcount_decrement(&keytable->references, &refs); - if (refs == 0) { - INSIST(isc_refcount_current(&keytable->active_nodes) == 0); - isc_refcount_destroy(&keytable->active_nodes); - isc_refcount_destroy(&keytable->references); - dns_rbt_destroy(&keytable->table); - isc_rwlock_destroy(&keytable->rwlock); - keytable->magic = 0; - isc_mem_putanddetach(&keytable->mctx, - keytable, sizeof(*keytable)); - } -} - -static isc_result_t -insert(dns_keytable_t *keytable, bool managed, - dns_name_t *keyname, dst_key_t **keyp) -{ - isc_result_t result; - dns_keynode_t *knode = NULL; - dns_rbtnode_t *node; - - REQUIRE(keyp == NULL || *keyp != NULL); - REQUIRE(VALID_KEYTABLE(keytable)); - - result = dns_keynode_create(keytable->mctx, &knode); - if (result != ISC_R_SUCCESS) - return (result); - - knode->managed = managed; - - RWLOCK(&keytable->rwlock, isc_rwlocktype_write); - - node = NULL; - result = dns_rbt_addnode(keytable->table, keyname, &node); - - if (keyp != NULL) { - if (result == ISC_R_EXISTS) { - /* Key already in table? */ - dns_keynode_t *k; - for (k = node->data; k != NULL; k = k->next) { - if (k->key == NULL) { - k->key = *keyp; - *keyp = NULL; /* transfer ownership */ - break; - } - if (dst_key_compare(k->key, *keyp) == true) - break; - } - - if (k == NULL) - result = ISC_R_SUCCESS; - else if (*keyp != NULL) - dst_key_free(keyp); - } - - if (result == ISC_R_SUCCESS) { - knode->key = *keyp; - knode->next = node->data; - *keyp = NULL; - } - } - - if (result == ISC_R_SUCCESS) { - node->data = knode; - knode = NULL; - } - - /* Key was already there? That's the same as a success */ - if (result == ISC_R_EXISTS) - result = ISC_R_SUCCESS; - - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); - - if (knode != NULL) - dns_keynode_detach(keytable->mctx, &knode); - - return (result); -} - -isc_result_t -dns_keytable_add(dns_keytable_t *keytable, bool managed, - dst_key_t **keyp) -{ - REQUIRE(keyp != NULL && *keyp != NULL); - return (insert(keytable, managed, dst_key_name(*keyp), keyp)); -} - -isc_result_t -dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name) { - return (insert(keytable, true, name, NULL)); -} - -isc_result_t -dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname) { - isc_result_t result; - dns_rbtnode_t *node = NULL; - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(keyname != NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_write); - result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - if (result == ISC_R_SUCCESS) { - if (node->data != NULL) - result = dns_rbt_deletenode(keytable->table, - node, false); - else - result = ISC_R_NOTFOUND; - } else if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); - - return (result); -} - -isc_result_t -dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) { - isc_result_t result; - dns_name_t *keyname; - dns_rbtnode_t *node = NULL; - dns_keynode_t *knode = NULL, **kprev = NULL; - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(dstkey != NULL); - - keyname = dst_key_name(dstkey); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_write); - result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - if (result != ISC_R_SUCCESS) - goto finish; - - if (node->data == NULL) { - result = ISC_R_NOTFOUND; - goto finish; - } - - knode = node->data; - if (knode->next == NULL && knode->key != NULL && - dst_key_compare(knode->key, dstkey) == true) - { - result = dns_rbt_deletenode(keytable->table, node, false); - goto finish; - } - - kprev = (dns_keynode_t **) &node->data; - while (knode != NULL) { - if (knode->key != NULL && - dst_key_compare(knode->key, dstkey) == true) - break; - kprev = &knode->next; - knode = knode->next; - } - - if (knode != NULL) { - if (knode->key != NULL) - dst_key_free(&knode->key); - /* - * This is equivalent to: - * dns_keynode_attach(knode->next, &tmp); - * dns_keynode_detach(kprev); - * dns_keynode_attach(tmp, &kprev); - * dns_keynode_detach(&tmp); - */ - *kprev = knode->next; - knode->next = NULL; - dns_keynode_detach(keytable->mctx, &knode); - } else - result = DNS_R_PARTIALMATCH; - finish: - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); - return (result); -} - -isc_result_t -dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, - dns_keynode_t **keynodep) -{ - isc_result_t result; - dns_rbtnode_t *node = NULL; - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(keyname != NULL); - REQUIRE(keynodep != NULL && *keynodep == NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - if (result == ISC_R_SUCCESS) { - if (node->data != NULL) { - isc_refcount_increment0(&keytable->active_nodes, NULL); - dns_keynode_attach(node->data, keynodep); - } else - result = ISC_R_NOTFOUND; - } else if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - - return (result); -} - -isc_result_t -dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, - dns_keynode_t **nextnodep) -{ - /* - * Return the next key after 'keynode', regardless of - * properties. - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(VALID_KEYNODE(keynode)); - REQUIRE(nextnodep != NULL && *nextnodep == NULL); - - if (keynode->next == NULL) - return (ISC_R_NOTFOUND); - - dns_keynode_attach(keynode->next, nextnodep); - isc_refcount_increment(&keytable->active_nodes, NULL); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, - dns_secalg_t algorithm, dns_keytag_t tag, - dns_keynode_t **keynodep) -{ - isc_result_t result; - dns_keynode_t *knode; - void *data; - - /* - * Search for a key named 'name', matching 'algorithm' and 'tag' in - * 'keytable'. - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(keynodep != NULL && *keynodep == NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - - /* - * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname() - * as that indicates that 'name' was not found. - * - * DNS_R_PARTIALMATCH indicates that the name was found but we - * didn't get a match on algorithm and key id arguments. - */ - knode = NULL; - data = NULL; - result = dns_rbt_findname(keytable->table, name, 0, NULL, &data); - - if (result == ISC_R_SUCCESS) { - INSIST(data != NULL); - for (knode = data; knode != NULL; knode = knode->next) { - if (knode->key == NULL) { - knode = NULL; - break; - } - if (algorithm == dst_key_alg(knode->key) - && tag == dst_key_id(knode->key)) - break; - } - if (knode != NULL) { - isc_refcount_increment0(&keytable->active_nodes, NULL); - dns_keynode_attach(knode, keynodep); - } else - result = DNS_R_PARTIALMATCH; - } else if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - - return (result); -} - -isc_result_t -dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, - dns_keynode_t **nextnodep) -{ - isc_result_t result; - dns_keynode_t *knode; - - /* - * Search for the next key with the same properties as 'keynode' in - * 'keytable'. - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(VALID_KEYNODE(keynode)); - REQUIRE(nextnodep != NULL && *nextnodep == NULL); - - for (knode = keynode->next; knode != NULL; knode = knode->next) { - if (knode->key == NULL) { - knode = NULL; - break; - } - if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) && - dst_key_id(keynode->key) == dst_key_id(knode->key)) - break; - } - if (knode != NULL) { - isc_refcount_increment(&keytable->active_nodes, NULL); - result = ISC_R_SUCCESS; - dns_keynode_attach(knode, nextnodep); - } else - result = ISC_R_NOTFOUND; - - return (result); -} - -isc_result_t -dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, - dns_name_t *foundname) -{ - isc_result_t result; - void *data; - - /* - * Search for the deepest match in 'keytable'. - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(foundname != NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - - data = NULL; - result = dns_rbt_findname(keytable->table, name, 0, foundname, &data); - - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - result = ISC_R_SUCCESS; - - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - - return (result); -} - -void -dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, - dns_keynode_t **target) -{ - /* - * Give back a keynode found via dns_keytable_findkeynode(). - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(VALID_KEYNODE(source)); - REQUIRE(target != NULL && *target == NULL); - - isc_refcount_increment(&keytable->active_nodes, NULL); - - dns_keynode_attach(source, target); -} - -void -dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep) -{ - /* - * Give back a keynode found via dns_keytable_findkeynode(). - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep)); - - isc_refcount_decrement(&keytable->active_nodes, NULL); - dns_keynode_detach(keytable->mctx, keynodep); -} - -isc_result_t -dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, - dns_name_t *foundname, bool *wantdnssecp) -{ - isc_result_t result; - dns_rbtnode_t *node = NULL; - - /* - * Is 'name' at or beneath a trusted key? - */ - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(wantdnssecp != NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - - result = dns_rbt_findnode(keytable->table, name, foundname, &node, - NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { - INSIST(node->data != NULL); - *wantdnssecp = true; - result = ISC_R_SUCCESS; - } else if (result == ISC_R_NOTFOUND) { - *wantdnssecp = false; - result = ISC_R_SUCCESS; - } - - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - - return (result); -} - -static isc_result_t -putstr(isc_buffer_t **b, const char *str) { - isc_result_t result; - - result = isc_buffer_reserve(b, strlen(str)); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_putstr(*b, str); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) { - isc_result_t result; - isc_buffer_t *text = NULL; - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(fp != NULL); - - result = isc_buffer_allocate(keytable->mctx, &text, 4096); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_keytable_totext(keytable, &text); - - if (isc_buffer_usedlength(text) != 0) { - (void) putstr(&text, "\n"); - } else if (result == ISC_R_SUCCESS) - (void) putstr(&text, "none"); - else { - (void) putstr(&text, "could not dump key table: "); - (void) putstr(&text, isc_result_totext(result)); - } - - fprintf(fp, "%.*s", (int) isc_buffer_usedlength(text), - (char *) isc_buffer_base(text)); - - isc_buffer_free(&text); - return (result); -} - -isc_result_t -dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) { - isc_result_t result; - dns_keynode_t *knode; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - - REQUIRE(VALID_KEYTABLE(keytable)); - REQUIRE(text != NULL && *text != NULL); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, keytable->mctx); - result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - goto cleanup; - } - for (;;) { - char pbuf[DST_KEY_FORMATSIZE]; - - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - for (knode = node->data; knode != NULL; knode = knode->next) { - char obuf[DNS_NAME_FORMATSIZE + 200]; - if (knode->key == NULL) - continue; - dst_key_format(knode->key, pbuf, sizeof(pbuf)); - snprintf(obuf, sizeof(obuf), "%s ; %s\n", pbuf, - knode->managed ? "managed" : "trusted"); - result = putstr(text, obuf); - if (result != ISC_R_SUCCESS) - break; - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - return (result); -} - -isc_result_t -dns_keytable_forall(dns_keytable_t *keytable, - void (*func)(dns_keytable_t *, dns_keynode_t *, void *), - void *arg) -{ - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - - REQUIRE(VALID_KEYTABLE(keytable)); - - RWLOCK(&keytable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, keytable->mctx); - result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - goto cleanup; - } - isc_refcount_increment0(&keytable->active_nodes, NULL); - for (;;) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) - (*func)(keytable, node->data, arg); - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - isc_refcount_decrement(&keytable->active_nodes, NULL); - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); - return (result); -} - -dst_key_t * -dns_keynode_key(dns_keynode_t *keynode) { - - /* - * Get the DST key associated with keynode. - */ - - REQUIRE(VALID_KEYNODE(keynode)); - - return (keynode->key); -} - -bool -dns_keynode_managed(dns_keynode_t *keynode) { - /* - * Is this a managed key? - */ - REQUIRE(VALID_KEYNODE(keynode)); - - return (keynode->managed); -} - -isc_result_t -dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) { - isc_result_t result; - dns_keynode_t *knode; - - REQUIRE(target != NULL && *target == NULL); - - knode = isc_mem_get(mctx, sizeof(dns_keynode_t)); - if (knode == NULL) - return (ISC_R_NOMEMORY); - - knode->magic = KEYNODE_MAGIC; - knode->managed = false; - knode->key = NULL; - knode->next = NULL; - - result = isc_refcount_init(&knode->refcount, 1); - if (result != ISC_R_SUCCESS) - return (result); - - *target = knode; - return (ISC_R_SUCCESS); -} - -void -dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) { - REQUIRE(VALID_KEYNODE(source)); - isc_refcount_increment(&source->refcount, NULL); - *target = source; -} - -void -dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) { - unsigned int refs; - dns_keynode_t *node = *keynode; - REQUIRE(VALID_KEYNODE(node)); - isc_refcount_decrement(&node->refcount, &refs); - if (refs == 0) { - if (node->key != NULL) - dst_key_free(&node->key); - isc_refcount_destroy(&node->refcount); - isc_mem_put(mctx, node, sizeof(dns_keynode_t)); - } - *keynode = NULL; -} - -void -dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **keynode) { - dns_keynode_t *next = NULL, *node = *keynode; - REQUIRE(VALID_KEYNODE(node)); - while (node != NULL) { - next = node->next; - dns_keynode_detach(mctx, &node); - node = next; - } - *keynode = NULL; -} diff --git a/lib/dns-pkcs11/lib.c b/lib/dns-pkcs11/lib.c deleted file mode 100644 index 0dc935d..0000000 --- a/lib/dns-pkcs11/lib.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -/*** - *** Globals - ***/ - -LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U; -LIBDNS_EXTERNAL_DATA isc_msgcat_t * dns_msgcat = NULL; - - -/*** - *** Private - ***/ - -static isc_once_t msgcat_once = ISC_ONCE_INIT; - - -/*** - *** Functions - ***/ - -static void -open_msgcat(void) { - isc_msgcat_open("libdns.cat", &dns_msgcat); -} - -void -dns_lib_initmsgcat(void) { - - /* - * Initialize the DNS library's message catalog, dns_msgcat, if it - * has not already been initialized. - */ - - RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); -} - -static isc_once_t init_once = ISC_ONCE_INIT; -static isc_mem_t *dns_g_mctx = NULL; -static dns_dbimplementation_t *dbimp = NULL; -static bool initialize_done = false; -static isc_mutex_t reflock; -static unsigned int references = 0; - -static void -initialize(void) { - isc_result_t result; - isc_entropy_t *ectx = NULL; - - REQUIRE(initialize_done == false); - - result = isc_mem_create(0, 0, &dns_g_mctx); - if (result != ISC_R_SUCCESS) - return; - dns_result_register(); - result = dns_ecdb_register(dns_g_mctx, &dbimp); - if (result != ISC_R_SUCCESS) - goto cleanup_mctx; - result = isc_entropy_create(dns_g_mctx, &ectx); - if (result != ISC_R_SUCCESS) - goto cleanup_db; - result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - goto cleanup_ectx; - - result = dst_lib_init(dns_g_mctx, ectx, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_hash; - - result = isc_mutex_init(&reflock); - if (result != ISC_R_SUCCESS) - goto cleanup_dst; - - isc_hash_init(); - isc_entropy_detach(&ectx); - - initialize_done = true; - return; - - cleanup_dst: - dst_lib_destroy(); - cleanup_ectx: - if (ectx != NULL) - isc_entropy_detach(&ectx); - cleanup_hash: - isc_hash_destroy(); - cleanup_db: - if (dbimp != NULL) - dns_ecdb_unregister(&dbimp); - cleanup_mctx: - if (dns_g_mctx != NULL) - isc_mem_detach(&dns_g_mctx); -} - -isc_result_t -dns_lib_init(void) { - isc_result_t result; - - /* - * Since this routine is expected to be used by a normal application, - * it should be better to return an error, instead of an emergency - * abort, on any failure. - */ - result = isc_once_do(&init_once, initialize); - if (result != ISC_R_SUCCESS) - return (result); - - if (!initialize_done) - return (ISC_R_FAILURE); - - LOCK(&reflock); - references++; - UNLOCK(&reflock); - - return (ISC_R_SUCCESS); -} - -void -dns_lib_shutdown(void) { - bool cleanup_ok = false; - - LOCK(&reflock); - if (--references == 0) - cleanup_ok = true; - UNLOCK(&reflock); - - if (!cleanup_ok) - return; - - dst_lib_destroy(); - - if (isc_hashctx != NULL) - isc_hash_destroy(); - if (dbimp != NULL) - dns_ecdb_unregister(&dbimp); - if (dns_g_mctx != NULL) - isc_mem_detach(&dns_g_mctx); -} diff --git a/lib/dns-pkcs11/log.c b/lib/dns-pkcs11/log.c deleted file mode 100644 index 31d099e..0000000 --- a/lib/dns-pkcs11/log.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include - -/*% - * When adding a new category, be sure to add the appropriate - * \#define to . - */ -LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = { - { "notify", 0 }, - { "database", 0 }, - { "security", 0 }, - { "_placeholder", 0 }, - { "dnssec", 0 }, - { "resolver", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "dispatch", 0 }, - { "lame-servers", 0 }, - { "delegation-only", 0 }, - { "edns-disabled", 0 }, - { "rpz", 0 }, - { "rate-limit", 0 }, - { "cname", 0 }, - { "spill", 0 }, - { "dnstap", 0 }, - { NULL, 0 } -}; - -/*% - * When adding a new module, be sure to add the appropriate - * \#define to . - */ -LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { - { "dns/db", 0 }, - { "dns/rbtdb", 0 }, - { "dns/rbtdb64", 0 }, - { "dns/rbt", 0 }, - { "dns/rdata", 0 }, - { "dns/master", 0 }, - { "dns/message", 0 }, - { "dns/cache", 0 }, - { "dns/config", 0 }, - { "dns/resolver", 0 }, - { "dns/zone", 0 }, - { "dns/journal", 0 }, - { "dns/adb", 0 }, - { "dns/xfrin", 0 }, - { "dns/xfrout", 0 }, - { "dns/acl", 0 }, - { "dns/validator", 0 }, - { "dns/dispatch", 0 }, - { "dns/request", 0 }, - { "dns/masterdump", 0 }, - { "dns/tsig", 0 }, - { "dns/tkey", 0 }, - { "dns/sdb", 0 }, - { "dns/diff", 0 }, - { "dns/hints", 0 }, - { "dns/acache", 0 }, - { "dns/dlz", 0 }, - { "dns/dnssec", 0 }, - { "dns/crypto", 0 }, - { "dns/packets", 0 }, - { "dns/nta", 0 }, - { "dns/dyndb", 0 }, - { "dns/dnstap", 0 }, - { "dns/ssu", 0 }, - { NULL, 0 } -}; - -LIBDNS_EXTERNAL_DATA isc_log_t *dns_lctx = NULL; - -void -dns_log_init(isc_log_t *lctx) { - REQUIRE(lctx != NULL); - - isc_log_registercategories(lctx, dns_categories); - isc_log_registermodules(lctx, dns_modules); -} - -void -dns_log_setcontext(isc_log_t *lctx) { - dns_lctx = lctx; -} diff --git a/lib/dns-pkcs11/lookup.c b/lib/dns-pkcs11/lookup.c deleted file mode 100644 index 43a7ec7..0000000 --- a/lib/dns-pkcs11/lookup.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include /* Required for HP/UX (and others?) */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct dns_lookup { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_mutex_t lock; - dns_rdatatype_t type; - dns_fixedname_t name; - /* Locked by lock. */ - unsigned int options; - isc_task_t * task; - dns_view_t * view; - dns_lookupevent_t * event; - dns_fetch_t * fetch; - unsigned int restarts; - bool canceled; - dns_rdataset_t rdataset; - dns_rdataset_t sigrdataset; -}; - -#define LOOKUP_MAGIC ISC_MAGIC('l', 'o', 'o', 'k') -#define VALID_LOOKUP(l) ISC_MAGIC_VALID((l), LOOKUP_MAGIC) - -#define MAX_RESTARTS 16 - -static void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event); - -static void -fetch_done(isc_task_t *task, isc_event_t *event) { - dns_lookup_t *lookup = event->ev_arg; - dns_fetchevent_t *fevent; - - UNUSED(task); - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - REQUIRE(VALID_LOOKUP(lookup)); - REQUIRE(lookup->task == task); - fevent = (dns_fetchevent_t *)event; - REQUIRE(fevent->fetch == lookup->fetch); - - lookup_find(lookup, fevent); -} - -static inline isc_result_t -start_fetch(dns_lookup_t *lookup) { - isc_result_t result; - - /* - * The caller must be holding the lookup's lock. - */ - - REQUIRE(lookup->fetch == NULL); - - result = dns_resolver_createfetch(lookup->view->resolver, - dns_fixedname_name(&lookup->name), - lookup->type, - NULL, NULL, NULL, 0, - lookup->task, fetch_done, lookup, - &lookup->rdataset, - &lookup->sigrdataset, - &lookup->fetch); - - return (result); -} - -static isc_result_t -build_event(dns_lookup_t *lookup) { - dns_name_t *name = NULL; - dns_rdataset_t *rdataset = NULL; - dns_rdataset_t *sigrdataset = NULL; - isc_result_t result; - - name = isc_mem_get(lookup->mctx, sizeof(dns_name_t)); - if (name == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - dns_name_init(name, NULL); - result = dns_name_dup(dns_fixedname_name(&lookup->name), - lookup->mctx, name); - if (result != ISC_R_SUCCESS) - goto fail; - - if (dns_rdataset_isassociated(&lookup->rdataset)) { - rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t)); - if (rdataset == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - dns_rdataset_init(rdataset); - dns_rdataset_clone(&lookup->rdataset, rdataset); - } - - if (dns_rdataset_isassociated(&lookup->sigrdataset)) { - sigrdataset = isc_mem_get(lookup->mctx, - sizeof(dns_rdataset_t)); - if (sigrdataset == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - dns_rdataset_init(sigrdataset); - dns_rdataset_clone(&lookup->sigrdataset, sigrdataset); - } - - lookup->event->name = name; - lookup->event->rdataset = rdataset; - lookup->event->sigrdataset = sigrdataset; - - return (ISC_R_SUCCESS); - - fail: - if (name != NULL) { - if (dns_name_dynamic(name)) - dns_name_free(name, lookup->mctx); - isc_mem_put(lookup->mctx, name, sizeof(dns_name_t)); - } - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t)); - } - return (result); -} - -static isc_result_t -view_find(dns_lookup_t *lookup, dns_name_t *foundname) { - isc_result_t result; - dns_name_t *name = dns_fixedname_name(&lookup->name); - dns_rdatatype_t type; - - if (lookup->type == dns_rdatatype_rrsig) - type = dns_rdatatype_any; - else - type = lookup->type; - - result = dns_view_find(lookup->view, name, type, 0, 0, false, - &lookup->event->db, &lookup->event->node, - foundname, &lookup->rdataset, - &lookup->sigrdataset); - return (result); -} - -static void -lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) { - isc_result_t result; - bool want_restart; - bool send_event; - dns_name_t *name, *fname, *prefix; - dns_fixedname_t foundname, fixed; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned int nlabels; - int order; - dns_namereln_t namereln; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - - REQUIRE(VALID_LOOKUP(lookup)); - - LOCK(&lookup->lock); - - result = ISC_R_SUCCESS; - name = dns_fixedname_name(&lookup->name); - - do { - lookup->restarts++; - want_restart = false; - send_event = true; - - if (event == NULL && !lookup->canceled) { - fname = dns_fixedname_initname(&foundname); - INSIST(!dns_rdataset_isassociated(&lookup->rdataset)); - INSIST(!dns_rdataset_isassociated - (&lookup->sigrdataset)); - /* - * If we have restarted then clear the old node. */ - if (lookup->event->node != NULL) { - INSIST(lookup->event->db != NULL); - dns_db_detachnode(lookup->event->db, - &lookup->event->node); - } - if (lookup->event->db != NULL) - dns_db_detach(&lookup->event->db); - result = view_find(lookup, fname); - if (result == ISC_R_NOTFOUND) { - /* - * We don't know anything about the name. - * Launch a fetch. - */ - if (lookup->event->node != NULL) { - INSIST(lookup->event->db != NULL); - dns_db_detachnode(lookup->event->db, - &lookup->event->node); - } - if (lookup->event->db != NULL) - dns_db_detach(&lookup->event->db); - result = start_fetch(lookup); - if (result == ISC_R_SUCCESS) - send_event = false; - goto done; - } - } else if (event != NULL) { - result = event->result; - fname = dns_fixedname_name(&event->foundname); - dns_resolver_destroyfetch(&lookup->fetch); - INSIST(event->rdataset == &lookup->rdataset); - INSIST(event->sigrdataset == &lookup->sigrdataset); - } else - fname = NULL; /* Silence compiler warning. */ - - /* - * If we've been canceled, forget about the result. - */ - if (lookup->canceled) - result = ISC_R_CANCELED; - - switch (result) { - case ISC_R_SUCCESS: - result = build_event(lookup); - if (event == NULL) - break; - if (event->db != NULL) - dns_db_attach(event->db, &lookup->event->db); - if (event->node != NULL) - dns_db_attachnode(lookup->event->db, - event->node, - &lookup->event->node); - break; - case DNS_R_CNAME: - /* - * Copy the CNAME's target into the lookup's - * query name and start over. - */ - result = dns_rdataset_first(&lookup->rdataset); - if (result != ISC_R_SUCCESS) - break; - dns_rdataset_current(&lookup->rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - dns_rdata_reset(&rdata); - if (result != ISC_R_SUCCESS) - break; - result = dns_name_copy(&cname.cname, name, NULL); - dns_rdata_freestruct(&cname); - if (result == ISC_R_SUCCESS) { - want_restart = true; - send_event = false; - } - break; - case DNS_R_DNAME: - namereln = dns_name_fullcompare(name, fname, &order, - &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Get the target name of the DNAME. - */ - result = dns_rdataset_first(&lookup->rdataset); - if (result != ISC_R_SUCCESS) - break; - dns_rdataset_current(&lookup->rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dname, NULL); - dns_rdata_reset(&rdata); - if (result != ISC_R_SUCCESS) - break; - /* - * Construct the new query name and start over. - */ - prefix = dns_fixedname_initname(&fixed); - dns_name_split(name, nlabels, prefix, NULL); - result = dns_name_concatenate(prefix, &dname.dname, - name, NULL); - dns_rdata_freestruct(&dname); - if (result == ISC_R_SUCCESS) { - want_restart = true; - send_event = false; - } - break; - default: - send_event = true; - } - - if (dns_rdataset_isassociated(&lookup->rdataset)) - dns_rdataset_disassociate(&lookup->rdataset); - if (dns_rdataset_isassociated(&lookup->sigrdataset)) - dns_rdataset_disassociate(&lookup->sigrdataset); - - done: - if (event != NULL) { - if (event->node != NULL) - dns_db_detachnode(event->db, &event->node); - if (event->db != NULL) - dns_db_detach(&event->db); - isc_event_free(ISC_EVENT_PTR(&event)); - } - - /* - * Limit the number of restarts. - */ - if (want_restart && lookup->restarts == MAX_RESTARTS) { - want_restart = false; - result = ISC_R_QUOTA; - send_event = true; - } - - } while (want_restart); - - if (send_event) { - lookup->event->result = result; - lookup->event->ev_sender = lookup; - isc_task_sendanddetach(&lookup->task, - (isc_event_t **)&lookup->event); - dns_view_detach(&lookup->view); - } - - UNLOCK(&lookup->lock); -} - -static void -levent_destroy(isc_event_t *event) { - dns_lookupevent_t *levent; - isc_mem_t *mctx; - - REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); - mctx = event->ev_destroy_arg; - levent = (dns_lookupevent_t *)event; - - if (levent->name != NULL) { - if (dns_name_dynamic(levent->name)) - dns_name_free(levent->name, mctx); - isc_mem_put(mctx, levent->name, sizeof(dns_name_t)); - } - if (levent->rdataset != NULL) { - dns_rdataset_disassociate(levent->rdataset); - isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t)); - } - if (levent->sigrdataset != NULL) { - dns_rdataset_disassociate(levent->sigrdataset); - isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t)); - } - if (levent->node != NULL) - dns_db_detachnode(levent->db, &levent->node); - if (levent->db != NULL) - dns_db_detach(&levent->db); - isc_mem_put(mctx, event, event->ev_size); -} - -isc_result_t -dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type, - dns_view_t *view, unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, dns_lookup_t **lookupp) -{ - isc_result_t result; - dns_lookup_t *lookup; - isc_event_t *ievent; - - lookup = isc_mem_get(mctx, sizeof(*lookup)); - if (lookup == NULL) - return (ISC_R_NOMEMORY); - lookup->mctx = NULL; - isc_mem_attach(mctx, &lookup->mctx); - lookup->options = options; - - ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE, - action, arg, sizeof(*lookup->event)); - if (ievent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_lookup; - } - lookup->event = (dns_lookupevent_t *)ievent; - lookup->event->ev_destroy = levent_destroy; - lookup->event->ev_destroy_arg = mctx; - lookup->event->result = ISC_R_FAILURE; - lookup->event->name = NULL; - lookup->event->rdataset = NULL; - lookup->event->sigrdataset = NULL; - lookup->event->db = NULL; - lookup->event->node = NULL; - - lookup->task = NULL; - isc_task_attach(task, &lookup->task); - - result = isc_mutex_init(&lookup->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_event; - - dns_fixedname_init(&lookup->name); - - result = dns_name_copy(name, dns_fixedname_name(&lookup->name), NULL); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - lookup->type = type; - lookup->view = NULL; - dns_view_attach(view, &lookup->view); - lookup->fetch = NULL; - lookup->restarts = 0; - lookup->canceled = false; - dns_rdataset_init(&lookup->rdataset); - dns_rdataset_init(&lookup->sigrdataset); - lookup->magic = LOOKUP_MAGIC; - - *lookupp = lookup; - - lookup_find(lookup, NULL); - - return (ISC_R_SUCCESS); - - cleanup_lock: - DESTROYLOCK(&lookup->lock); - - cleanup_event: - ievent = (isc_event_t *)lookup->event; - isc_event_free(&ievent); - lookup->event = NULL; - - isc_task_detach(&lookup->task); - - cleanup_lookup: - isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup)); - - return (result); -} - -void -dns_lookup_cancel(dns_lookup_t *lookup) { - REQUIRE(VALID_LOOKUP(lookup)); - - LOCK(&lookup->lock); - - if (!lookup->canceled) { - lookup->canceled = true; - if (lookup->fetch != NULL) { - INSIST(lookup->view != NULL); - dns_resolver_cancelfetch(lookup->fetch); - } - } - - UNLOCK(&lookup->lock); -} - -void -dns_lookup_destroy(dns_lookup_t **lookupp) { - dns_lookup_t *lookup; - - REQUIRE(lookupp != NULL); - lookup = *lookupp; - REQUIRE(VALID_LOOKUP(lookup)); - REQUIRE(lookup->event == NULL); - REQUIRE(lookup->task == NULL); - REQUIRE(lookup->view == NULL); - if (dns_rdataset_isassociated(&lookup->rdataset)) - dns_rdataset_disassociate(&lookup->rdataset); - if (dns_rdataset_isassociated(&lookup->sigrdataset)) - dns_rdataset_disassociate(&lookup->sigrdataset); - - DESTROYLOCK(&lookup->lock); - lookup->magic = 0; - isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup)); - - *lookupp = NULL; -} diff --git a/lib/dns-pkcs11/mapapi b/lib/dns-pkcs11/mapapi deleted file mode 100644 index 90bf250..0000000 --- a/lib/dns-pkcs11/mapapi +++ /dev/null @@ -1,16 +0,0 @@ -# This value should be increased whenever changing the structure of -# any object that will appear in a type 'map' master file (which -# contains a working memory image of an RBT database), as loading -# an incorrect memory image produces an inconsistent and probably -# nonfunctional database. These structures include but are not -# necessarily limited to dns_masterrawheader, rbtdb_file_header, -# rbt_file_header, dns_rbtdb, dns_rbt, dns_rbtnode, rdatasetheader. -# -# Err on the side of caution: if anything in the RBTDB is changed, -# bump the value. Making map files unreadable protects the system -# from instability; it's a feature not a bug. -# -# Whenever releasing a new major release of BIND9, set this value -# back to 1.0 when releasing the first alpha. Fast files are *never* -# compatible across major releases. -MAPAPI=1.0 diff --git a/lib/dns-pkcs11/master.c b/lib/dns-pkcs11/master.c deleted file mode 100644 index 36999b5..0000000 --- a/lib/dns-pkcs11/master.c +++ /dev/null @@ -1,3257 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures - * by these sizes when we need to. - * - */ -/*% RDLSZ reflects the number of different types with the same name expected. */ -#define RDLSZ 32 -/*% - * RDSZ reflects the number of rdata expected at a give name that can fit into - * 64k. - */ -#define RDSZ 512 - -#define NBUFS 4 -#define MAXWIRESZ 255 - -/*% - * Target buffer size and minimum target size. - * MINTSIZ must be big enough to hold the largest rdata record. - * \brief - * TSIZ >= MINTSIZ - */ -#define TSIZ (128*1024) -/*% - * max message size - header - root - type - class - ttl - rdlen - */ -#define MINTSIZ DNS_RDATA_MAXLENGTH -/*% - * Size for tokens in the presentation format, - * The largest tokens are the base64 blocks in KEY and CERT records, - * Largest key allowed is about 1372 bytes but - * there is no fixed upper bound on CERT records. - * 2K is too small for some X.509s, 8K is overkill. - */ -#define TOKENSIZ (8*1024) - -/*% - * Buffers sizes for $GENERATE. - */ -#define DNS_MASTER_LHS 2048 -#define DNS_MASTER_RHS MINTSIZ - -#define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0) - -typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; - -typedef struct dns_incctx dns_incctx_t; - -/*% - * Master file load state. - */ - -struct dns_loadctx { - unsigned int magic; - isc_mem_t *mctx; - dns_masterformat_t format; - - dns_rdatacallbacks_t *callbacks; - isc_task_t *task; - dns_loaddonefunc_t done; - void *done_arg; - - /* Common methods */ - isc_result_t (*openfile)(dns_loadctx_t *lctx, - const char *filename); - isc_result_t (*load)(dns_loadctx_t *lctx); - - /* Members used by all formats */ - uint32_t maxttl; - - /* Members specific to the text format: */ - isc_lex_t *lex; - bool keep_lex; - unsigned int options; - bool ttl_known; - bool default_ttl_known; - bool warn_1035; - bool warn_tcr; - bool warn_sigexpired; - bool seen_include; - uint32_t ttl; - uint32_t default_ttl; - dns_rdataclass_t zclass; - dns_fixedname_t fixed_top; - dns_name_t *top; /*%< top of zone */ - - /* Members specific to the raw format: */ - FILE *f; - bool first; - dns_masterrawheader_t header; - - /* Which fixed buffers we are using? */ - unsigned int loop_cnt; /*% records per quantum, - * 0 => all. */ - bool canceled; - isc_mutex_t lock; - isc_result_t result; - /* locked by lock */ - uint32_t references; - dns_incctx_t *inc; - uint32_t resign; - isc_stdtime_t now; - - dns_masterincludecb_t include_cb; - void *include_arg; -}; - -struct dns_incctx { - dns_incctx_t *parent; - dns_name_t *origin; - dns_name_t *current; - dns_name_t *glue; - dns_fixedname_t fixed[NBUFS]; /* working buffers */ - unsigned int in_use[NBUFS]; /* covert to bitmap? */ - int glue_in_use; - int current_in_use; - int origin_in_use; - bool origin_changed; - bool drop; - unsigned int glue_line; - unsigned int current_line; -}; - -#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x') -#define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC) - -#define DNS_AS_STR(t) ((t).value.as_textregion.base) - -static isc_result_t -openfile_text(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_text(dns_loadctx_t *lctx); - -static isc_result_t -openfile_raw(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_raw(dns_loadctx_t *lctx); - -static isc_result_t -openfile_map(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_map(dns_loadctx_t *lctx); - -static isc_result_t -pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx); - -static isc_result_t -commit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *, - dns_name_t *, const char *, unsigned int); - -static bool -is_glue(rdatalist_head_t *, dns_name_t *); - -static dns_rdatalist_t * -grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *, - rdatalist_head_t *, isc_mem_t *mctx); - -static dns_rdata_t * -grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *, - isc_mem_t *); - -static void -load_quantum(isc_task_t *task, isc_event_t *event); - -static isc_result_t -task_send(dns_loadctx_t *lctx); - -static void -loadctx_destroy(dns_loadctx_t *lctx); - -#define GETTOKENERR(lexer, options, token, eol, err) \ - do { \ - result = gettoken(lexer, options, token, eol, callbacks); \ - switch (result) { \ - case ISC_R_SUCCESS: \ - break; \ - case ISC_R_UNEXPECTED: \ - goto insist_and_cleanup; \ - default: \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = true; \ - err \ - goto next_line; \ - } else \ - goto log_and_cleanup; \ - } \ - if ((token)->type == isc_tokentype_special) { \ - result = DNS_R_SYNTAX; \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = true; \ - goto next_line; \ - } else \ - goto log_and_cleanup; \ - } \ - } while (0) -#define GETTOKEN(lexer, options, token, eol) \ - GETTOKENERR(lexer, options, token, eol, {} ) - -#define COMMITALL \ - do { \ - result = commit(callbacks, lctx, ¤t_list, \ - ictx->current, source, ictx->current_line); \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - } else if (result != ISC_R_SUCCESS) \ - goto insist_and_cleanup; \ - result = commit(callbacks, lctx, &glue_list, \ - ictx->glue, source, ictx->glue_line); \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - } else if (result != ISC_R_SUCCESS) \ - goto insist_and_cleanup; \ - rdcount = 0; \ - rdlcount = 0; \ - isc_buffer_init(&target, target_mem, target_size); \ - rdcount_save = rdcount; \ - rdlcount_save = rdlcount; \ - } while (0) - -#define WARNUNEXPECTEDEOF(lexer) \ - do { \ - if (isc_lex_isfile(lexer)) \ - (*callbacks->warn)(callbacks, \ - "%s: file does not end with newline", \ - source); \ - } while (0) - -#define EXPECTEOL \ - do { \ - GETTOKEN(lctx->lex, 0, &token, true); \ - if (token.type != isc_tokentype_eol) { \ - isc_lex_ungettoken(lctx->lex, &token); \ - result = DNS_R_EXTRATOKEN; \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = true; \ - break; \ - } else if (result != ISC_R_SUCCESS) \ - goto log_and_cleanup; \ - } \ - } while (0) - -#define MANYERRS(lctx, result) \ - ((result != ISC_R_SUCCESS) && \ - (result != ISC_R_IOERROR) && \ - ((lctx)->options & DNS_MASTER_MANYERRORS) != 0) - -#define SETRESULT(lctx, r) \ - do { \ - if ((lctx)->result == ISC_R_SUCCESS) \ - (lctx)->result = r; \ - } while (0) - -#define LOGITFILE(result, filename) \ - if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \ - result == ISC_R_IOERROR || result == ISC_R_TOOMANYOPENFILES || \ - result == ISC_R_NOPERM) \ - (*callbacks->error)(callbacks, "%s: %s:%lu: %s: %s", \ - "dns_master_load", source, line, \ - filename, dns_result_totext(result)); \ - else LOGIT(result) - -#define LOGIT(result) \ - if (result == ISC_R_NOMEMORY) \ - (*callbacks->error)(callbacks, "dns_master_load: %s", \ - dns_result_totext(result)); \ - else \ - (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \ - "dns_master_load", \ - source, line, dns_result_totext(result)) - - -static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; -static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; -static dns_name_t const in_addr_arpa = - DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets); - -static unsigned char ip6_int_data[] = "\003IP6\003INT"; -static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; -static dns_name_t const ip6_int = - DNS_NAME_INITABSOLUTE(ip6_int_data, ip6_int_offsets); - -static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; -static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; -static dns_name_t const ip6_arpa = - DNS_NAME_INITABSOLUTE(ip6_arpa_data, ip6_arpa_offsets); - -static inline isc_result_t -gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, - bool eol, dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result; - - options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | - ISC_LEXOPT_ESCAPE; - result = isc_lex_gettoken(lex, options, token); - if (result != ISC_R_SUCCESS) { - switch (result) { - case ISC_R_NOMEMORY: - return (ISC_R_NOMEMORY); - default: - (*callbacks->error)(callbacks, - "dns_master_load: %s:%lu:" - " isc_lex_gettoken() failed: %s", - isc_lex_getsourcename(lex), - isc_lex_getsourceline(lex), - isc_result_totext(result)); - return (result); - } - /*NOTREACHED*/ - } - if (eol != true) - if (token->type == isc_tokentype_eol || - token->type == isc_tokentype_eof) { - unsigned long int line; - const char *what; - const char *file; - file = isc_lex_getsourcename(lex); - line = isc_lex_getsourceline(lex); - if (token->type == isc_tokentype_eol) { - line--; - what = "line"; - } else - what = "file"; - (*callbacks->error)(callbacks, - "dns_master_load: %s:%lu: unexpected end of %s", - file, line, what); - return (ISC_R_UNEXPECTEDEND); - } - return (ISC_R_SUCCESS); -} - - -void -dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) { - - REQUIRE(target != NULL && *target == NULL); - REQUIRE(DNS_LCTX_VALID(source)); - - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); /* Overflow? */ - UNLOCK(&source->lock); - - *target = source; -} - -void -dns_loadctx_detach(dns_loadctx_t **lctxp) { - dns_loadctx_t *lctx; - bool need_destroy = false; - - REQUIRE(lctxp != NULL); - lctx = *lctxp; - REQUIRE(DNS_LCTX_VALID(lctx)); - - LOCK(&lctx->lock); - INSIST(lctx->references > 0); - lctx->references--; - if (lctx->references == 0) - need_destroy = true; - UNLOCK(&lctx->lock); - - if (need_destroy) - loadctx_destroy(lctx); - *lctxp = NULL; -} - -static void -incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) { - dns_incctx_t *parent; - - again: - parent = ictx->parent; - ictx->parent = NULL; - - isc_mem_put(mctx, ictx, sizeof(*ictx)); - - if (parent != NULL) { - ictx = parent; - goto again; - } -} - -static void -loadctx_destroy(dns_loadctx_t *lctx) { - isc_mem_t *mctx; - isc_result_t result; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - lctx->magic = 0; - if (lctx->inc != NULL) - incctx_destroy(lctx->mctx, lctx->inc); - - if (lctx->f != NULL) { - result = isc_stdio_close(lctx->f); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_close() failed: %s", - isc_result_totext(result)); - } - } - - /* isc_lex_destroy() will close all open streams */ - if (lctx->lex != NULL && !lctx->keep_lex) - isc_lex_destroy(&lctx->lex); - - if (lctx->task != NULL) - isc_task_detach(&lctx->task); - DESTROYLOCK(&lctx->lock); - mctx = NULL; - isc_mem_attach(lctx->mctx, &mctx); - isc_mem_detach(&lctx->mctx); - isc_mem_put(mctx, lctx, sizeof(*lctx)); - isc_mem_detach(&mctx); -} - -static isc_result_t -incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) { - dns_incctx_t *ictx; - isc_region_t r; - int i; - - ictx = isc_mem_get(mctx, sizeof(*ictx)); - if (ictx == NULL) - return (ISC_R_NOMEMORY); - - for (i = 0; i < NBUFS; i++) { - dns_fixedname_init(&ictx->fixed[i]); - ictx->in_use[i] = false; - } - - ictx->origin_in_use = 0; - ictx->origin = dns_fixedname_name(&ictx->fixed[ictx->origin_in_use]); - ictx->in_use[ictx->origin_in_use] = true; - dns_name_toregion(origin, &r); - dns_name_fromregion(ictx->origin, &r); - - ictx->glue = NULL; - ictx->current = NULL; - ictx->glue_in_use = -1; - ictx->current_in_use = -1; - ictx->parent = NULL; - ictx->drop = false; - ictx->glue_line = 0; - ictx->current_line = 0; - ictx->origin_changed = true; - - *ictxp = ictx; - return (ISC_R_SUCCESS); -} - -static isc_result_t -loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, - unsigned int options, uint32_t resign, dns_name_t *top, - dns_rdataclass_t zclass, dns_name_t *origin, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_masterincludecb_t include_cb, void *include_arg, - isc_lex_t *lex, dns_loadctx_t **lctxp) -{ - dns_loadctx_t *lctx; - isc_result_t result; - isc_region_t r; - isc_lexspecials_t specials; - - REQUIRE(lctxp != NULL && *lctxp == NULL); - REQUIRE(callbacks != NULL); - REQUIRE(callbacks->add != NULL); - REQUIRE(callbacks->error != NULL); - REQUIRE(callbacks->warn != NULL); - REQUIRE(mctx != NULL); - REQUIRE(dns_name_isabsolute(top)); - REQUIRE(dns_name_isabsolute(origin)); - REQUIRE((task == NULL && done == NULL) || - (task != NULL && done != NULL)); - - lctx = isc_mem_get(mctx, sizeof(*lctx)); - if (lctx == NULL) - return (ISC_R_NOMEMORY); - result = isc_mutex_init(&lctx->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, lctx, sizeof(*lctx)); - return (result); - } - - lctx->inc = NULL; - result = incctx_create(mctx, origin, &lctx->inc); - if (result != ISC_R_SUCCESS) - goto cleanup_ctx; - - lctx->maxttl = 0; - - lctx->format = format; - switch (format) { - case dns_masterformat_text: - lctx->openfile = openfile_text; - lctx->load = load_text; - break; - case dns_masterformat_raw: - lctx->openfile = openfile_raw; - lctx->load = load_raw; - break; - case dns_masterformat_map: - lctx->openfile = openfile_map; - lctx->load = load_map; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (lex != NULL) { - lctx->lex = lex; - lctx->keep_lex = true; - } else { - lctx->lex = NULL; - result = isc_lex_create(mctx, TOKENSIZ, &lctx->lex); - if (result != ISC_R_SUCCESS) - goto cleanup_inc; - lctx->keep_lex = false; - /* - * If specials change update dns_test_rdatafromstring() - * in lib/dns/tests/dnstest.c. - */ - memset(specials, 0, sizeof(specials)); - specials[0] = 1; - specials['('] = 1; - specials[')'] = 1; - specials['"'] = 1; - isc_lex_setspecials(lctx->lex, specials); - isc_lex_setcomments(lctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE); - } - - lctx->ttl_known = ((options & DNS_MASTER_NOTTL) != 0); - lctx->ttl = 0; - lctx->default_ttl_known = lctx->ttl_known; - lctx->default_ttl = 0; - lctx->warn_1035 = true; /* XXX Argument? */ - lctx->warn_tcr = true; /* XXX Argument? */ - lctx->warn_sigexpired = true; /* XXX Argument? */ - lctx->options = options; - lctx->seen_include = false; - lctx->zclass = zclass; - lctx->resign = resign; - lctx->result = ISC_R_SUCCESS; - lctx->include_cb = include_cb; - lctx->include_arg = include_arg; - isc_stdtime_get(&lctx->now); - - lctx->top = dns_fixedname_initname(&lctx->fixed_top); - dns_name_toregion(top, &r); - dns_name_fromregion(lctx->top, &r); - - lctx->f = NULL; - lctx->first = true; - dns_master_initrawheader(&lctx->header); - - lctx->loop_cnt = (done != NULL) ? 100 : 0; - lctx->callbacks = callbacks; - lctx->task = NULL; - if (task != NULL) - isc_task_attach(task, &lctx->task); - lctx->done = done; - lctx->done_arg = done_arg; - lctx->canceled = false; - lctx->mctx = NULL; - isc_mem_attach(mctx, &lctx->mctx); - lctx->references = 1; /* Implicit attach. */ - lctx->magic = DNS_LCTX_MAGIC; - *lctxp = lctx; - return (ISC_R_SUCCESS); - - cleanup_inc: - incctx_destroy(mctx, lctx->inc); - cleanup_ctx: - isc_mem_put(mctx, lctx, sizeof(*lctx)); - return (result); -} - -static const char *hex = "0123456789abcdef0123456789ABCDEF"; - -/*% - * Convert value into a nibble sequence from least significant to most - * significant nibble. Zero fill upper most significant nibbles if - * required to make the width. - * - * Returns the number of characters that should have been written without - * counting the terminating NUL. - */ -static unsigned int -nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) { - unsigned int count = 0; - - /* - * This reserve space for the NUL string terminator. - */ - if (length > 0U) { - *numbuf = '\0'; - length--; - } - do { - char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)]; - value >>= 4; - if (length > 0U) { - *numbuf++ = val; - *numbuf = '\0'; - length--; - } - if (width > 0) - width--; - count++; - /* - * If width is non zero then we need to add a label separator. - * If value is non zero then we need to add another label and - * that requires a label separator. - */ - if (width > 0 || value != 0) { - if (length > 0U) { - *numbuf++ = '.'; - *numbuf = '\0'; - length--; - } - if (width > 0) - width--; - count++; - } - } while (value != 0 || width > 0); - return (count); -} - -static isc_result_t -genname(char *name, int it, char *buffer, size_t length) { - char fmt[sizeof("%04000000000d")]; - char numbuf[128]; - char *cp; - char mode[2]; - int delta = 0; - isc_textregion_t r; - unsigned int n; - unsigned int width; - bool nibblemode; - - r.base = buffer; - r.length = (unsigned int)length; - - while (*name != '\0') { - if (*name == '$') { - name++; - if (*name == '$') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - continue; - } - nibblemode = false; - strlcpy(fmt, "%d", sizeof(fmt)); - /* Get format specifier. */ - if (*name == '{' ) { - n = sscanf(name, "{%d,%u,%1[doxXnN]}", - &delta, &width, mode); - switch (n) { - case 1: - break; - case 2: - n = snprintf(fmt, sizeof(fmt), - "%%0%ud", width); - break; - case 3: - if (mode[0] == 'n' || mode[0] == 'N') - nibblemode = true; - n = snprintf(fmt, sizeof(fmt), - "%%0%u%c", width, mode[0]); - break; - default: - return (DNS_R_SYNTAX); - } - if (n >= sizeof(fmt)) - return (ISC_R_NOSPACE); - /* Skip past closing brace. */ - while (*name != '\0' && *name++ != '}') - continue; - } - if (nibblemode) - n = nibbles(numbuf, sizeof(numbuf), width, - mode[0], it + delta); - else - n = snprintf(numbuf, sizeof(numbuf), fmt, - it + delta); - if (n >= sizeof(numbuf)) - return (ISC_R_NOSPACE); - cp = numbuf; - while (*cp != '\0') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *cp++; - isc_textregion_consume(&r, 1); - } - } else if (*name == '\\') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - if (*name == '\0') - continue; - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - } else { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - } - } - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = '\0'; - return (ISC_R_SUCCESS); -} - -static isc_result_t -generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, - const char *source, unsigned int line) -{ - char *target_mem = NULL; - char *lhsbuf = NULL; - char *rhsbuf = NULL; - dns_fixedname_t ownerfixed; - dns_name_t *owner; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatacallbacks_t *callbacks; - dns_rdatalist_t rdatalist; - dns_rdatatype_t type; - rdatalist_head_t head; - int target_size = MINTSIZ; /* only one rdata at a time */ - isc_buffer_t buffer; - isc_buffer_t target; - isc_result_t result; - isc_textregion_t r; - int i, n, start, stop, step = 0; - dns_incctx_t *ictx; - char dummy[2]; - - ictx = lctx->inc; - callbacks = lctx->callbacks; - owner = dns_fixedname_initname(&ownerfixed); - ISC_LIST_INIT(head); - - target_mem = isc_mem_get(lctx->mctx, target_size); - rhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_RHS); - lhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_LHS); - if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) { - result = ISC_R_NOMEMORY; - goto error_cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - - n = sscanf(range, "%d-%d%1[/]%d", &start, &stop, dummy, &step); - if ((n != 2 && n != 4) || (start < 0) || (stop < 0) || - (n == 4 && step < 1) || (stop < start)) - { - (*callbacks->error)(callbacks, - "%s: %s:%lu: invalid range '%s'", - "$GENERATE", source, line, range); - result = DNS_R_SYNTAX; - goto insist_cleanup; - } - if (n == 2) - step = 1; - - /* - * Get type. - */ - r.base = gtype; - r.length = strlen(gtype); - result = dns_rdatatype_fromtext(&type, &r); - if (result != ISC_R_SUCCESS) { - (*callbacks->error)(callbacks, - "%s: %s:%lu: unknown RR type '%s'", - "$GENERATE", source, line, gtype); - goto insist_cleanup; - } - - /* - * RFC2930: TKEY and TSIG are not allowed to be loaded - * from master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - dns_rdatatype_ismeta(type)) - { - (*callbacks->error)(callbacks, - "%s: %s:%lu: meta RR type '%s'", - "$GENERATE", - source, line, gtype); - result = DNS_R_METATYPE; - goto insist_cleanup; - } - - for (i = start; i <= stop; i += step) { - result = genname(lhs, i, lhsbuf, DNS_MASTER_LHS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf)); - isc_buffer_add(&buffer, strlen(lhsbuf)); - isc_buffer_setactive(&buffer, strlen(lhsbuf)); - result = dns_name_fromtext(owner, &buffer, ictx->origin, - 0, NULL); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (lctx->options & DNS_MASTER_KEY) == 0 && - !dns_name_issubdomain(owner, lctx->top)) - { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(owner, namebuf, sizeof(namebuf)); - /* - * Ignore out-of-zone data. - */ - (*callbacks->warn)(callbacks, - "%s:%lu: " - "ignoring out-of-zone data (%s)", - source, line, namebuf); - continue; - } - - isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf)); - isc_buffer_add(&buffer, strlen(rhsbuf)); - isc_buffer_setactive(&buffer, strlen(rhsbuf)); - - result = isc_lex_openbuffer(lctx->lex, &buffer); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - isc_buffer_init(&target, target_mem, target_size); - result = dns_rdata_fromtext(&rdata, lctx->zclass, type, - lctx->lex, ictx->origin, 0, - lctx->mctx, &target, callbacks); - RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - dns_rdatalist_init(&rdatalist); - rdatalist.type = type; - rdatalist.rdclass = lctx->zclass; - rdatalist.ttl = lctx->ttl; - ISC_LIST_PREPEND(head, &rdatalist, link); - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - result = commit(callbacks, lctx, &head, owner, source, line); - ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - dns_rdata_reset(&rdata); - } - result = ISC_R_SUCCESS; - goto cleanup; - - error_cleanup: - if (result == ISC_R_NOMEMORY) - (*callbacks->error)(callbacks, "$GENERATE: %s", - dns_result_totext(result)); - else - (*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s", - source, line, dns_result_totext(result)); - - insist_cleanup: - INSIST(result != ISC_R_SUCCESS); - - cleanup: - if (target_mem != NULL) - isc_mem_put(lctx->mctx, target_mem, target_size); - if (lhsbuf != NULL) - isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_LHS); - if (rhsbuf != NULL) - isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_RHS); - return (result); -} - -static void -limit_ttl(dns_rdatacallbacks_t *callbacks, const char *source, - unsigned int line, uint32_t *ttlp) -{ - if (*ttlp > 0x7fffffffUL) { - (callbacks->warn)(callbacks, - "%s: %s:%lu: " - "$TTL %lu > MAXTTL, " - "setting $TTL to 0", - "dns_master_load", - source, line, - *ttlp); - *ttlp = 0; - } -} - -static isc_result_t -check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source, - unsigned long line) -{ - char *tmp = NULL; - isc_result_t result = ISC_R_SUCCESS; - void (*callback)(struct dns_rdatacallbacks *, const char *, ...); - - if ((lctx->options & DNS_MASTER_FATALNS) != 0) - callback = lctx->callbacks->error; - else - callback = lctx->callbacks->warn; - - if (token->type == isc_tokentype_string) { - struct in_addr addr; - struct in6_addr addr6; - - tmp = isc_mem_strdup(lctx->mctx, DNS_AS_STR(*token)); - if (tmp == NULL) - return (ISC_R_NOMEMORY); - /* - * Catch both "1.2.3.4" and "1.2.3.4." - */ - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - result = DNS_R_NSISADDRESS; - } - if (result != ISC_R_SUCCESS) - (*callback)(lctx->callbacks, "%s:%lu: NS record '%s' " - "appears to be an address", - source, line, DNS_AS_STR(*token)); - if (tmp != NULL) - isc_mem_free(lctx->mctx, tmp); - return (result); -} - -static void -check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, - dns_rdatacallbacks_t *callbacks) -{ - dns_name_t *name; - - name = (ictx->glue != NULL) ? ictx->glue : ictx->current; - if (dns_name_internalwildcard(name)) { - char namebuf[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername " - "'%s' contains an non-terminal wildcard", - source, line, namebuf); - } -} - -static isc_result_t -openfile_text(dns_loadctx_t *lctx, const char *master_file) { - return (isc_lex_openfile(lctx->lex, master_file)); -} - -static int -find_free_name(dns_incctx_t *incctx) { - int i; - - for (i = 0; i < (NBUFS - 1); i++) { - if (!incctx->in_use[i]) { - break; - } - } - INSIST(!incctx->in_use[i]); - return (i); -} - -static isc_result_t -load_text(dns_loadctx_t *lctx) { - dns_rdataclass_t rdclass; - dns_rdatatype_t type, covers; - uint32_t ttl_offset = 0; - dns_name_t *new_name; - bool current_has_delegation = false; - bool done = false; - bool finish_origin = false; - bool finish_include = false; - bool read_till_eol = false; - bool initialws; - char *include_file = NULL; - isc_token_t token; - isc_result_t result = ISC_R_UNEXPECTED; - rdatalist_head_t glue_list; - rdatalist_head_t current_list; - dns_rdatalist_t *this; - dns_rdatalist_t *rdatalist = NULL; - dns_rdatalist_t *new_rdatalist; - int rdlcount = 0; - int rdlcount_save = 0; - int rdatalist_size = 0; - isc_buffer_t buffer; - isc_buffer_t target; - isc_buffer_t target_ft; - isc_buffer_t target_save; - dns_rdata_t *rdata = NULL; - dns_rdata_t *new_rdata; - int rdcount = 0; - int rdcount_save = 0; - int rdata_size = 0; - unsigned char *target_mem = NULL; - int target_size = TSIZ; - int new_in_use; - unsigned int loop_cnt = 0; - isc_mem_t *mctx; - dns_rdatacallbacks_t *callbacks; - dns_incctx_t *ictx; - char *range = NULL; - char *lhs = NULL; - char *gtype = NULL; - char *rhs = NULL; - const char *source = ""; - unsigned long line = 0; - bool explicit_ttl; - char classname1[DNS_RDATACLASS_FORMATSIZE]; - char classname2[DNS_RDATACLASS_FORMATSIZE]; - unsigned int options = 0; - - REQUIRE(DNS_LCTX_VALID(lctx)); - callbacks = lctx->callbacks; - mctx = lctx->mctx; - ictx = lctx->inc; - - ISC_LIST_INIT(glue_list); - ISC_LIST_INIT(current_list); - - - /* - * Allocate target_size of buffer space. This is greater than twice - * the maximum individual RR data size. - */ - target_mem = isc_mem_get(mctx, target_size); - if (target_mem == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - target_save = target; - - if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) - options |= DNS_RDATA_CHECKNAMES; - if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) - options |= DNS_RDATA_CHECKNAMESFAIL; - if ((lctx->options & DNS_MASTER_CHECKMX) != 0) - options |= DNS_RDATA_CHECKMX; - if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) - options |= DNS_RDATA_CHECKMXFAIL; - source = isc_lex_getsourcename(lctx->lex); - do { - initialws = false; - line = isc_lex_getsourceline(lctx->lex); - GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING, - &token, true); - line = isc_lex_getsourceline(lctx->lex); - - if (token.type == isc_tokentype_eof) { - if (read_till_eol) - WARNUNEXPECTEDEOF(lctx->lex); - /* Pop the include stack? */ - if (ictx->parent != NULL) { - COMMITALL; - lctx->inc = ictx->parent; - ictx->parent = NULL; - incctx_destroy(lctx->mctx, ictx); - RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - source = isc_lex_getsourcename(lctx->lex); - ictx = lctx->inc; - continue; - } - done = true; - continue; - } - - if (token.type == isc_tokentype_eol) { - read_till_eol = false; - continue; /* blank line */ - } - - if (read_till_eol) - continue; - - if (token.type == isc_tokentype_initialws) { - /* - * Still working on the same name. - */ - initialws = true; - } else if (token.type == isc_tokentype_string || - token.type == isc_tokentype_qstring) { - - /* - * "$" Support. - * - * "$ORIGIN" and "$INCLUDE" can both take domain names. - * The processing of "$ORIGIN" and "$INCLUDE" extends - * across the normal domain name processing. - */ - - if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) { - GETTOKEN(lctx->lex, 0, &token, false); - finish_origin = true; - } else if (strcasecmp(DNS_AS_STR(token), - "$TTL") == 0) { - GETTOKENERR(lctx->lex, 0, &token, false, - lctx->ttl = 0; - lctx->default_ttl_known = true;); - result = - dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - limit_ttl(callbacks, source, line, &lctx->ttl); - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = true; - EXPECTEOL; - continue; - } else if (strcasecmp(DNS_AS_STR(token), - "$INCLUDE") == 0) { - COMMITALL; - if ((lctx->options & DNS_MASTER_NOINCLUDE) - != 0) - { - (callbacks->error)(callbacks, - "%s: %s:%lu: $INCLUDE not allowed", - "dns_master_load", - source, line); - result = DNS_R_REFUSED; - goto insist_and_cleanup; - } - if (ttl_offset != 0) { - (callbacks->error)(callbacks, - "%s: %s:%lu: $INCLUDE " - "may not be used with $DATE", - "dns_master_load", - source, line); - result = DNS_R_SYNTAX; - goto insist_and_cleanup; - } - GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, - false); - if (include_file != NULL) - isc_mem_free(mctx, include_file); - include_file = isc_mem_strdup(mctx, - DNS_AS_STR(token)); - if (include_file == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - GETTOKEN(lctx->lex, 0, &token, true); - - if (token.type == isc_tokentype_eol || - token.type == isc_tokentype_eof) { - if (token.type == isc_tokentype_eof) - WARNUNEXPECTEDEOF(lctx->lex); - /* - * No origin field. - */ - result = pushfile(include_file, - ictx->origin, lctx); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGITFILE(result, include_file); - continue; - } else if (result != ISC_R_SUCCESS) { - LOGITFILE(result, include_file); - goto insist_and_cleanup; - } - ictx = lctx->inc; - source = - isc_lex_getsourcename(lctx->lex); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - continue; - } - /* - * There is an origin field. Fall through - * to domain name processing code and do - * the actual inclusion later. - */ - finish_include = true; - } else if (strcasecmp(DNS_AS_STR(token), - "$DATE") == 0) { - int64_t dump_time64; - isc_stdtime_t dump_time, current_time; - GETTOKEN(lctx->lex, 0, &token, false); - isc_stdtime_get(¤t_time); - result = dns_time64_fromtext(DNS_AS_STR(token), - &dump_time64); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - dump_time64 = 0; - } else if (result != ISC_R_SUCCESS) - goto log_and_cleanup; - dump_time = (isc_stdtime_t)dump_time64; - if (dump_time != dump_time64) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: %s:%lu: $DATE outside epoch", - "dns_master_load", source, line); - result = ISC_R_UNEXPECTED; - goto insist_and_cleanup; - } - if (dump_time > current_time) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: %s:%lu: " - "$DATE in future, using current date", - "dns_master_load", source, line); - dump_time = current_time; - } - ttl_offset = current_time - dump_time; - EXPECTEOL; - continue; - } else if (strcasecmp(DNS_AS_STR(token), - "$GENERATE") == 0) { - /* - * Lazy cleanup. - */ - if (range != NULL) - isc_mem_free(mctx, range); - if (lhs != NULL) - isc_mem_free(mctx, lhs); - if (gtype != NULL) - isc_mem_free(mctx, gtype); - if (rhs != NULL) - isc_mem_free(mctx, rhs); - range = lhs = gtype = rhs = NULL; - /* RANGE */ - GETTOKEN(lctx->lex, 0, &token, false); - range = isc_mem_strdup(mctx, - DNS_AS_STR(token)); - if (range == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - /* LHS */ - GETTOKEN(lctx->lex, 0, &token, false); - lhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); - if (lhs == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdclass = 0; - explicit_ttl = false; - /* CLASS? */ - GETTOKEN(lctx->lex, 0, &token, false); - if (dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) { - GETTOKEN(lctx->lex, 0, &token, - false); - } - /* TTL? */ - if (dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl) - == ISC_R_SUCCESS) { - limit_ttl(callbacks, source, line, - &lctx->ttl); - lctx->ttl_known = true; - explicit_ttl = true; - GETTOKEN(lctx->lex, 0, &token, - false); - } - /* CLASS? */ - if (rdclass == 0 && - dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, - false); - /* TYPE */ - gtype = isc_mem_strdup(mctx, - DNS_AS_STR(token)); - if (gtype == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - /* RHS */ - GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, - &token, false); - rhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); - if (rhs == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - if (!lctx->ttl_known && - !lctx->default_ttl_known) { - (*callbacks->error)(callbacks, - "%s: %s:%lu: no TTL specified", - "dns_master_load", source, line); - result = DNS_R_NOTTL; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else { - goto insist_and_cleanup; - } - } else if (!explicit_ttl && - lctx->default_ttl_known) { - lctx->ttl = lctx->default_ttl; - } - /* - * If the class specified does not match the - * zone's class print out a error message and - * exit. - */ - if (rdclass != 0 && rdclass != lctx->zclass) { - goto bad_class; - } - result = generate(lctx, range, lhs, gtype, rhs, - source, line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - EXPECTEOL; - continue; - } else if (strncasecmp(DNS_AS_STR(token), - "$", 1) == 0) { - (callbacks->error)(callbacks, - "%s: %s:%lu: " - "unknown $ directive '%s'", - "dns_master_load", source, line, - DNS_AS_STR(token)); - result = DNS_R_SYNTAX; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else { - goto insist_and_cleanup; - } - } - - /* - * Normal processing resumes. - */ - new_in_use = find_free_name(ictx); - new_name = - dns_fixedname_initname(&ictx->fixed[new_in_use]); - isc_buffer_init(&buffer, token.value.as_region.base, - token.value.as_region.length); - isc_buffer_add(&buffer, token.value.as_region.length); - isc_buffer_setactive(&buffer, - token.value.as_region.length); - result = dns_name_fromtext(new_name, &buffer, - ictx->origin, 0, NULL); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - read_till_eol = true; - continue; - } else if (result != ISC_R_SUCCESS) - goto log_and_cleanup; - - /* - * Finish $ORIGIN / $INCLUDE processing if required. - */ - if (finish_origin) { - if (ictx->origin_in_use != -1) - ictx->in_use[ictx->origin_in_use] = - false; - ictx->origin_in_use = new_in_use; - ictx->in_use[ictx->origin_in_use] = true; - ictx->origin = new_name; - ictx->origin_changed = true; - finish_origin = false; - EXPECTEOL; - continue; - } - if (finish_include) { - finish_include = false; - EXPECTEOL; - result = pushfile(include_file, new_name, lctx); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGITFILE(result, include_file); - continue; - } else if (result != ISC_R_SUCCESS) { - LOGITFILE(result, include_file); - goto insist_and_cleanup; - } - ictx = lctx->inc; - ictx->origin_changed = true; - source = isc_lex_getsourcename(lctx->lex); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - continue; - } - - /* - * "$" Processing Finished - */ - - /* - * If we are processing glue and the new name does - * not match the current glue name, commit the glue - * and pop stacks leaving us in 'normal' processing - * state. Linked lists are undone by commit(). - */ - if (ictx->glue != NULL && - !dns_name_caseequal(ictx->glue, new_name)) { - result = commit(callbacks, lctx, &glue_list, - ictx->glue, source, - ictx->glue_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - if (ictx->glue_in_use != -1) - ictx->in_use[ictx->glue_in_use] = - false; - ictx->glue_in_use = -1; - ictx->glue = NULL; - rdcount = rdcount_save; - rdlcount = rdlcount_save; - target = target_save; - } - - /* - * If we are in 'normal' processing state and the new - * name does not match the current name, see if the - * new name is for glue and treat it as such, - * otherwise we have a new name so commit what we - * have. - */ - if ((ictx->glue == NULL) && (ictx->current == NULL || - !dns_name_caseequal(ictx->current, new_name))) { - if (current_has_delegation && - is_glue(¤t_list, new_name)) { - rdcount_save = rdcount; - rdlcount_save = rdlcount; - target_save = target; - ictx->glue = new_name; - ictx->glue_in_use = new_in_use; - ictx->in_use[ictx->glue_in_use] = - true; - } else { - result = commit(callbacks, lctx, - ¤t_list, - ictx->current, - source, - ictx->current_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - rdcount = 0; - rdlcount = 0; - if (ictx->current_in_use != -1) - ictx->in_use[ictx->current_in_use] = - false; - ictx->current_in_use = new_in_use; - ictx->in_use[ictx->current_in_use] = - true; - ictx->current = new_name; - current_has_delegation = false; - isc_buffer_init(&target, target_mem, - target_size); - } - /* - * Check for internal wildcards. - */ - if ((lctx->options & DNS_MASTER_CHECKWILDCARD) - != 0) - check_wildcard(ictx, source, line, - callbacks); - - } - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (lctx->options & DNS_MASTER_KEY) == 0 && - !dns_name_issubdomain(new_name, lctx->top)) - { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(new_name, namebuf, - sizeof(namebuf)); - /* - * Ignore out-of-zone data. - */ - (*callbacks->warn)(callbacks, - "%s:%lu: " - "ignoring out-of-zone data (%s)", - source, line, namebuf); - ictx->drop = true; - } else - ictx->drop = false; - } else { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s:%lu: isc_lex_gettoken() returned " - "unexpected token type (%d)", - source, line, token.type); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - continue; - } else { - goto insist_and_cleanup; - } - } - - /* - * Find TTL, class and type. Both TTL and class are optional - * and may occur in any order if they exist. TTL and class - * come before type which must exist. - * - * [] [] - * [] [] - */ - - type = 0; - rdclass = 0; - - GETTOKEN(lctx->lex, 0, &token, initialws); - - if (initialws) { - if (token.type == isc_tokentype_eol) { - read_till_eol = false; - continue; /* blank line */ - } - - if (token.type == isc_tokentype_eof) { - WARNUNEXPECTEDEOF(lctx->lex); - read_till_eol = false; - isc_lex_ungettoken(lctx->lex, &token); - continue; - } - - if (ictx->current == NULL) { - (*callbacks->error)(callbacks, - "%s:%lu: no current owner name", - source, line); - result = DNS_R_NOOWNER; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (ictx->origin_changed) { - char cbuf[DNS_NAME_FORMATSIZE]; - char obuf[DNS_NAME_FORMATSIZE]; - dns_name_format(ictx->current, cbuf, - sizeof(cbuf)); - dns_name_format(ictx->origin, obuf, - sizeof(obuf)); - (*callbacks->warn)(callbacks, - "%s:%lu: record with inherited " - "owner (%s) immediately after " - "$ORIGIN (%s)", source, line, - cbuf, obuf); - } - } - - ictx->origin_changed = false; - - if (dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, false); - - explicit_ttl = false; - result = dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl); - if (result == ISC_R_SUCCESS) { - limit_ttl(callbacks, source, line, &lctx->ttl); - explicit_ttl = true; - lctx->ttl_known = true; - GETTOKEN(lctx->lex, 0, &token, false); - } - - if (token.type != isc_tokentype_string) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_lex_gettoken() returned unexpected token type"); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (rdclass == 0 && - dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, false); - - if (token.type != isc_tokentype_string) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_lex_gettoken() returned unexpected token type"); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - continue; - } else { - goto insist_and_cleanup; - } - } - - result = dns_rdatatype_fromtext(&type, - &token.value.as_textregion); - if (result != ISC_R_SUCCESS) { - (*callbacks->warn)(callbacks, - "%s:%lu: unknown RR type '%.*s'", - source, line, - token.value.as_textregion.length, - token.value.as_textregion.base); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - continue; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - } - - /* - * If the class specified does not match the zone's class - * print out a error message and exit. - */ - if (rdclass != 0 && rdclass != lctx->zclass) { - bad_class: - - dns_rdataclass_format(rdclass, classname1, - sizeof(classname1)); - dns_rdataclass_format(lctx->zclass, classname2, - sizeof(classname2)); - (*callbacks->error)(callbacks, - "%s:%lu: class '%s' != " - "zone class '%s'", - source, line, - classname1, classname2); - result = DNS_R_BADCLASS; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (type == dns_rdatatype_ns && ictx->glue == NULL) - current_has_delegation = true; - - /* - * RFC1123: MD and MF are not allowed to be loaded from - * master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (type == dns_rdatatype_md || type == dns_rdatatype_mf)) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - result = DNS_R_OBSOLETE; - - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - (*callbacks->error)(callbacks, - "%s:%lu: %s '%s': %s", - source, line, - "type", typebuf, - dns_result_totext(result)); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else - goto insist_and_cleanup; - } - - /* - * RFC2930: TKEY and TSIG are not allowed to be loaded - * from master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - dns_rdatatype_ismeta(type)) - { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - result = DNS_R_METATYPE; - - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - (*callbacks->error)(callbacks, - "%s:%lu: %s '%s': %s", - source, line, - "type", typebuf, - dns_result_totext(result)); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else - goto insist_and_cleanup; - } - - /* - * Find a rdata structure. - */ - if (rdcount == rdata_size) { - new_rdata = grow_rdata(rdata_size + RDSZ, rdata, - rdata_size, ¤t_list, - &glue_list, mctx); - if (new_rdata == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdata_size += RDSZ; - rdata = new_rdata; - } - - /* - * Peek at the NS record. - */ - if (type == dns_rdatatype_ns && - lctx->zclass == dns_rdataclass_in && - (lctx->options & DNS_MASTER_CHECKNS) != 0) { - - GETTOKEN(lctx->lex, 0, &token, false); - result = check_ns(lctx, &token, source, line); - isc_lex_ungettoken(lctx->lex, &token); - if ((lctx->options & DNS_MASTER_FATALNS) != 0) { - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - } - } - - /* - * Check owner name. - */ - options &= ~DNS_RDATA_CHECKREVERSE; - if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) { - bool ok; - dns_name_t *name; - - name = (ictx->glue != NULL) ? ictx->glue : - ictx->current; - ok = dns_rdata_checkowner(name, lctx->zclass, type, - true); - if (!ok) { - char namebuf[DNS_NAME_FORMATSIZE]; - const char *desc; - dns_name_format(name, namebuf, sizeof(namebuf)); - result = DNS_R_BADOWNERNAME; - desc = dns_result_totext(result); - if (CHECKNAMESFAIL(lctx->options) || - type == dns_rdatatype_nsec3) { - (*callbacks->error)(callbacks, - "%s:%lu: %s: %s", - source, line, - namebuf, desc); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else { - goto cleanup; - } - } else { - (*callbacks->warn)(callbacks, - "%s:%lu: %s: %s", - source, line, - namebuf, desc); - } - } - if (type == dns_rdatatype_ptr && - !dns_name_isdnssd(name) && - (dns_name_issubdomain(name, &in_addr_arpa) || - dns_name_issubdomain(name, &ip6_arpa) || - dns_name_issubdomain(name, &ip6_int))) - options |= DNS_RDATA_CHECKREVERSE; - } - - /* - * Read rdata contents. - */ - dns_rdata_init(&rdata[rdcount]); - target_ft = target; - result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass, - type, lctx->lex, ictx->origin, - options, lctx->mctx, &target, - callbacks); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - continue; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - - if (ictx->drop) { - target = target_ft; - continue; - } - - if (type == dns_rdatatype_soa && - (lctx->options & DNS_MASTER_ZONE) != 0 && - !dns_name_equal(ictx->current, lctx->top)) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(ictx->current, namebuf, - sizeof(namebuf)); - (*callbacks->error)(callbacks, "%s:%lu: SOA " - "record not at top of zone (%s)", - source, line, namebuf); - result = DNS_R_NOTZONETOP; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = true; - target = target_ft; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&rdata[rdcount]); - else - covers = 0; - - if (!lctx->ttl_known && !lctx->default_ttl_known) { - if (type == dns_rdatatype_soa) { - (*callbacks->warn)(callbacks, - "%s:%lu: no TTL specified; " - "using SOA MINTTL instead", - source, line); - lctx->ttl = dns_soa_getminimum(&rdata[rdcount]); - limit_ttl(callbacks, source, line, &lctx->ttl); - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = true; - } else if ((lctx->options & DNS_MASTER_HINT) != 0) { - /* - * Zero TTL's are fine for hints. - */ - lctx->ttl = 0; - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = true; - } else { - (*callbacks->warn)(callbacks, - "%s:%lu: no TTL specified; " - "zone rejected", - source, line); - result = DNS_R_NOTTL; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else { - goto insist_and_cleanup; - } - } - } else if (!explicit_ttl && lctx->default_ttl_known) { - lctx->ttl = lctx->default_ttl; - } else if (!explicit_ttl && lctx->warn_1035) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "using RFC1035 TTL semantics", - source, line); - lctx->warn_1035 = false; - } - - if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) { - dns_rdata_rrsig_t sig; - result = dns_rdata_tostruct(&rdata[rdcount], &sig, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (isc_serial_lt(sig.timeexpire, lctx->now)) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "signature has expired", - source, line); - lctx->warn_sigexpired = false; - } - } - - if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) && - lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0) { - (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC " - " zone detected", source, line); - lctx->warn_tcr = false; - } - - if ((lctx->options & DNS_MASTER_AGETTL) != 0) { - /* - * Adjust the TTL for $DATE. If the RR has - * already expired, set its TTL to 0. This - * should be okay even if the TTL stretching - * feature is not in effect, because it will - * just be quickly expired by the cache, and the - * way this was written before the patch it - * could potentially add 0 TTLs anyway. - */ - if (lctx->ttl < ttl_offset) - lctx->ttl = 0; - else - lctx->ttl -= ttl_offset; - } - - /* - * Find type in rdatalist. - * If it does not exist create new one and prepend to list - * as this will minimise list traversal. - */ - if (ictx->glue != NULL) - this = ISC_LIST_HEAD(glue_list); - else - this = ISC_LIST_HEAD(current_list); - - while (this != NULL) { - if (this->type == type && this->covers == covers) - break; - this = ISC_LIST_NEXT(this, link); - } - - if (this == NULL) { - if (rdlcount == rdatalist_size) { - new_rdatalist = - grow_rdatalist(rdatalist_size + RDLSZ, - rdatalist, - rdatalist_size, - ¤t_list, - &glue_list, - mctx); - if (new_rdatalist == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdatalist = new_rdatalist; - rdatalist_size += RDLSZ; - } - this = &rdatalist[rdlcount++]; - dns_rdatalist_init(this); - this->type = type; - this->covers = covers; - this->rdclass = lctx->zclass; - this->ttl = lctx->ttl; - if (ictx->glue != NULL) - ISC_LIST_INITANDPREPEND(glue_list, this, link); - else - ISC_LIST_INITANDPREPEND(current_list, this, - link); - } else if (this->ttl != lctx->ttl) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "TTL set to prior TTL (%lu)", - source, line, this->ttl); - lctx->ttl = this->ttl; - } - - if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && - lctx->ttl > lctx->maxttl) - { - (callbacks->error)(callbacks, - "dns_master_load: %s:%lu: " - "TTL %d exceeds configured max-zone-ttl %d", - source, line, lctx->ttl, lctx->maxttl); - result = ISC_R_RANGE; - goto log_and_cleanup; - } - - ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link); - if (ictx->glue != NULL) - ictx->glue_line = line; - else - ictx->current_line = line; - rdcount++; - - /* - * We must have at least 64k as rdlen is 16 bits. - * If we don't commit everything we have so far. - */ - if ((target.length - target.used) < MINTSIZ) - COMMITALL; - next_line: - ; - } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt)); - - /* - * Commit what has not yet been committed. - */ - result = commit(callbacks, lctx, ¤t_list, ictx->current, - source, ictx->current_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - result = commit(callbacks, lctx, &glue_list, ictx->glue, - source, ictx->glue_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - - if (!done) { - INSIST(lctx->done != NULL && lctx->task != NULL); - result = DNS_R_CONTINUE; - } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) { - result = lctx->result; - } else if (result == ISC_R_SUCCESS && lctx->seen_include) - result = DNS_R_SEENINCLUDE; - goto cleanup; - - log_and_cleanup: - LOGIT(result); - - insist_and_cleanup: - INSIST(result != ISC_R_SUCCESS); - - cleanup: - while ((this = ISC_LIST_HEAD(current_list)) != NULL) - ISC_LIST_UNLINK(current_list, this, link); - while ((this = ISC_LIST_HEAD(glue_list)) != NULL) - ISC_LIST_UNLINK(glue_list, this, link); - if (rdatalist != NULL) - isc_mem_put(mctx, rdatalist, - rdatalist_size * sizeof(*rdatalist)); - if (rdata != NULL) - isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); - if (target_mem != NULL) - isc_mem_put(mctx, target_mem, target_size); - if (include_file != NULL) - isc_mem_free(mctx, include_file); - if (range != NULL) - isc_mem_free(mctx, range); - if (lhs != NULL) - isc_mem_free(mctx, lhs); - if (gtype != NULL) - isc_mem_free(mctx, gtype); - if (rhs != NULL) - isc_mem_free(mctx, rhs); - return (result); -} - -static isc_result_t -pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { - isc_result_t result; - dns_incctx_t *ictx; - dns_incctx_t *newctx = NULL; - isc_region_t r; - - REQUIRE(master_file != NULL); - REQUIRE(DNS_LCTX_VALID(lctx)); - - ictx = lctx->inc; - lctx->seen_include = true; - - result = incctx_create(lctx->mctx, origin, &newctx); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Push origin_changed. - */ - newctx->origin_changed = ictx->origin_changed; - - /* Set current domain. */ - if (ictx->glue != NULL || ictx->current != NULL) { - newctx->current_in_use = find_free_name(newctx); - newctx->current = - dns_fixedname_name(&newctx->fixed[newctx->current_in_use]); - newctx->in_use[newctx->current_in_use] = true; - dns_name_toregion((ictx->glue != NULL) ? - ictx->glue : ictx->current, &r); - dns_name_fromregion(newctx->current, &r); - newctx->drop = ictx->drop; - } - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - newctx->parent = ictx; - lctx->inc = newctx; - - if (lctx->include_cb != NULL) - lctx->include_cb(master_file, lctx->include_arg); - return (ISC_R_SUCCESS); - - cleanup: - incctx_destroy(lctx->mctx, newctx); - return (result); -} - -/* - * Fill/check exists buffer with 'len' bytes. Track remaining bytes to be - * read when incrementally filling the buffer. - */ -static inline isc_result_t -read_and_check(bool do_read, isc_buffer_t *buffer, - size_t len, FILE *f, uint32_t *totallen) -{ - isc_result_t result; - - REQUIRE(totallen != NULL); - - if (do_read) { - INSIST(isc_buffer_availablelength(buffer) >= len); - result = isc_stdio_read(isc_buffer_used(buffer), 1, len, - f, NULL); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_add(buffer, (unsigned int)len); - if (*totallen < len) - return (ISC_R_RANGE); - *totallen -= (uint32_t)len; - } else if (isc_buffer_remaininglength(buffer) < len) - return (ISC_R_RANGE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_header(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - dns_masterrawheader_t header; - dns_rdatacallbacks_t *callbacks; - size_t commonlen = sizeof(header.format) + sizeof(header.version); - size_t remainder; - unsigned char data[sizeof(header)]; - isc_buffer_t target; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - if (lctx->format != dns_masterformat_raw && - lctx->format != dns_masterformat_map) - return (ISC_R_NOTIMPLEMENTED); - - callbacks = lctx->callbacks; - dns_master_initrawheader(&header); - - INSIST(commonlen <= sizeof(header)); - isc_buffer_init(&target, data, sizeof(data)); - - result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_read failed: %s", - isc_result_totext(result)); - return (result); - } - - isc_buffer_add(&target, (unsigned int)commonlen); - header.format = isc_buffer_getuint32(&target); - if (header.format != lctx->format) { - (*callbacks->error)(callbacks, "dns_master_load: " - "file format mismatch (not %s)", - lctx->format == dns_masterformat_map - ? "map" - : "raw"); - return (ISC_R_NOTIMPLEMENTED); - } - - header.version = isc_buffer_getuint32(&target); - - switch (header.version) { - case 0: - remainder = sizeof(header.dumptime); - break; - case DNS_RAWFORMAT_VERSION: - remainder = sizeof(header) - commonlen; - break; - default: - (*callbacks->error)(callbacks, - "dns_master_load: " - "unsupported file format version"); - return (ISC_R_NOTIMPLEMENTED); - } - - result = isc_stdio_read(data + commonlen, 1, remainder, lctx->f, NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_read failed: %s", - isc_result_totext(result)); - return (result); - } - - isc_buffer_add(&target, (unsigned int)remainder); - header.dumptime = isc_buffer_getuint32(&target); - if (header.version == DNS_RAWFORMAT_VERSION) { - header.flags = isc_buffer_getuint32(&target); - header.sourceserial = isc_buffer_getuint32(&target); - header.lastxfrin = isc_buffer_getuint32(&target); - } - - lctx->first = false; - lctx->header = header; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openfile_map(dns_loadctx_t *lctx, const char *master_file) { - isc_result_t result; - - result = isc_stdio_open(master_file, "rb", &lctx->f); - if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_open() failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -/* - * Load a map format file, using mmap() to access RBT trees directly - */ -static isc_result_t -load_map(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - dns_rdatacallbacks_t *callbacks; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - callbacks = lctx->callbacks; - - if (lctx->first) { - result = load_header(lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = (*callbacks->deserialize) - (callbacks->deserialize_private, - lctx->f, sizeof(dns_masterrawheader_t)); - } - - return (result); -} - -static isc_result_t -openfile_raw(dns_loadctx_t *lctx, const char *master_file) { - isc_result_t result; - - result = isc_stdio_open(master_file, "rb", &lctx->f); - if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_open() failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -static isc_result_t -load_raw(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - bool done = false; - unsigned int loop_cnt = 0; - dns_rdatacallbacks_t *callbacks; - unsigned char namebuf[DNS_NAME_MAXWIRE]; - dns_fixedname_t fixed; - dns_name_t *name; - rdatalist_head_t head, dummy; - dns_rdatalist_t rdatalist; - isc_mem_t *mctx = lctx->mctx; - dns_rdata_t *rdata = NULL; - unsigned int rdata_size = 0; - int target_size = TSIZ; - isc_buffer_t target, buf; - unsigned char *target_mem = NULL; - dns_decompress_t dctx; - - callbacks = lctx->callbacks; - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); - - if (lctx->first) { - result = load_header(lctx); - if (result != ISC_R_SUCCESS) - return (result); - } - - ISC_LIST_INIT(head); - ISC_LIST_INIT(dummy); - - /* - * Allocate target_size of buffer space. This is greater than twice - * the maximum individual RR data size. - */ - target_mem = isc_mem_get(mctx, target_size); - if (target_mem == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - - name = dns_fixedname_initname(&fixed); - - /* - * In the following loop, we regard any error fatal regardless of - * whether "MANYERRORS" is set in the context option. This is because - * normal errors should already have been checked at creation time. - * Besides, it is very unlikely that we can recover from an error - * in this format, and so trying to continue parsing erroneous data - * does not really make sense. - */ - for (loop_cnt = 0; - (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); - loop_cnt++) { - unsigned int i, rdcount; - uint16_t namelen; - uint32_t totallen; - size_t minlen, readlen; - bool sequential_read = false; - - /* Read the data length */ - isc_buffer_clear(&target); - INSIST(isc_buffer_availablelength(&target) >= - sizeof(totallen)); - result = isc_stdio_read(target.base, 1, sizeof(totallen), - lctx->f, NULL); - if (result == ISC_R_EOF) { - result = ISC_R_SUCCESS; - done = true; - break; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_add(&target, sizeof(totallen)); - totallen = isc_buffer_getuint32(&target); - - /* - * Validation: the input data must at least contain the common - * header. - */ - minlen = sizeof(totallen) + sizeof(uint16_t) + - sizeof(uint16_t) + sizeof(uint16_t) + - sizeof(uint32_t) + sizeof(uint32_t); - if (totallen < minlen) { - result = ISC_R_RANGE; - goto cleanup; - } - totallen -= sizeof(totallen); - - isc_buffer_clear(&target); - if (totallen > isc_buffer_availablelength(&target)) { - /* - * The default buffer size should typically be large - * enough to store the entire RRset. We could try to - * allocate enough space if this is not the case, but - * it might cause a hazardous result when "totallen" - * is forged. Thus, we'd rather take an inefficient - * but robust approach in this atypical case: read - * data step by step, and commit partial data when - * necessary. Note that the buffer must be large - * enough to store the "header part", owner name, and - * at least one rdata (however large it is). - */ - sequential_read = true; - readlen = minlen - sizeof(totallen); - } else { - /* - * Typical case. We can read the whole RRset at once - * with the default buffer. - */ - readlen = totallen; - } - result = isc_stdio_read(target.base, 1, readlen, - lctx->f, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_add(&target, (unsigned int)readlen); - totallen -= (uint32_t)readlen; - - /* Construct RRset headers */ - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = isc_buffer_getuint16(&target); - if (lctx->zclass != rdatalist.rdclass) { - result = DNS_R_BADCLASS; - goto cleanup; - } - rdatalist.type = isc_buffer_getuint16(&target); - rdatalist.covers = isc_buffer_getuint16(&target); - rdatalist.ttl = isc_buffer_getuint32(&target); - rdcount = isc_buffer_getuint32(&target); - if (rdcount == 0 || rdcount > 0xffff) { - result = ISC_R_RANGE; - goto cleanup; - } - INSIST(isc_buffer_consumedlength(&target) <= readlen); - - /* Owner name: length followed by name */ - result = read_and_check(sequential_read, &target, - sizeof(namelen), lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - namelen = isc_buffer_getuint16(&target); - if (namelen > sizeof(namebuf)) { - result = ISC_R_RANGE; - goto cleanup; - } - - result = read_and_check(sequential_read, &target, namelen, - lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - - isc_buffer_setactive(&target, (unsigned int)namelen); - result = dns_name_fromwire(name, &target, &dctx, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && - rdatalist.ttl > lctx->maxttl) - { - (callbacks->error)(callbacks, - "dns_master_load: " - "TTL %d exceeds configured " - "max-zone-ttl %d", - rdatalist.ttl, lctx->maxttl); - result = ISC_R_RANGE; - goto cleanup; - } - - /* Rdata contents. */ - if (rdcount > rdata_size) { - dns_rdata_t *new_rdata = NULL; - - new_rdata = grow_rdata(rdcount + RDSZ, rdata, - rdata_size, &head, - &dummy, mctx); - if (new_rdata == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - rdata_size = rdcount + RDSZ; - rdata = new_rdata; - } - - continue_read: - for (i = 0; i < rdcount; i++) { - uint16_t rdlen; - - dns_rdata_init(&rdata[i]); - - if (sequential_read && - isc_buffer_availablelength(&target) < MINTSIZ) { - unsigned int j; - - INSIST(i > 0); /* detect an infinite loop */ - - /* Partial Commit. */ - ISC_LIST_APPEND(head, &rdatalist, link); - result = commit(callbacks, lctx, &head, name, - NULL, 0); - for (j = 0; j < i; j++) { - ISC_LIST_UNLINK(rdatalist.rdata, - &rdata[j], link); - dns_rdata_reset(&rdata[j]); - } - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* Rewind the buffer and continue */ - isc_buffer_clear(&target); - - rdcount -= i; - - goto continue_read; - } - - /* rdata length */ - result = read_and_check(sequential_read, &target, - sizeof(rdlen), lctx->f, - &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - rdlen = isc_buffer_getuint16(&target); - - /* rdata */ - result = read_and_check(sequential_read, &target, - rdlen, lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_setactive(&target, (unsigned int)rdlen); - /* - * It is safe to have the source active region and - * the target available region be the same if - * decompression is disabled (see dctx above) and we - * are not downcasing names (options == 0). - */ - isc_buffer_init(&buf, isc_buffer_current(&target), - (unsigned int)rdlen); - result = dns_rdata_fromwire(&rdata[i], - rdatalist.rdclass, - rdatalist.type, &target, - &dctx, 0, &buf); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); - } - - /* - * Sanity check. Still having remaining space is not - * necessarily critical, but it very likely indicates broken - * or malformed data. - */ - if (isc_buffer_remaininglength(&target) != 0 || totallen != 0) { - result = ISC_R_RANGE; - goto cleanup; - } - - ISC_LIST_APPEND(head, &rdatalist, link); - - /* Commit this RRset. rdatalist will be unlinked. */ - result = commit(callbacks, lctx, &head, name, NULL, 0); - - for (i = 0; i < rdcount; i++) { - ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); - dns_rdata_reset(&rdata[i]); - } - - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (!done) { - INSIST(lctx->done != NULL && lctx->task != NULL); - result = DNS_R_CONTINUE; - } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) - result = lctx->result; - - if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL) - (*callbacks->rawdata)(callbacks->zone, &lctx->header); - - cleanup: - if (rdata != NULL) - isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); - if (target_mem != NULL) - isc_mem_put(mctx, target_mem, target_size); - if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) { - (*callbacks->error)(callbacks, "dns_master_load: %s", - dns_result_totext(result)); - } - - return (result); -} - -isc_result_t -dns_master_loadfile(const char *master_file, dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, 0, callbacks, NULL, NULL, - mctx, dns_masterformat_text, 0)); -} - -isc_result_t -dns_master_loadfile2(const char *master_file, dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, - dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, 0, callbacks, NULL, NULL, - mctx, format, 0)); -} - -isc_result_t -dns_master_loadfile3(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, - dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, resign, callbacks, NULL, NULL, - mctx, format, 0)); -} - -isc_result_t -dns_master_loadfile4(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, resign, callbacks, - include_cb, include_arg, - mctx, format, 0)); -} - -isc_result_t -dns_master_loadfile5(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format, - dns_ttl_t maxttl) -{ - dns_loadctx_t *lctx = NULL; - isc_result_t result; - - result = loadctx_create(format, mctx, options, resign, top, zclass, - origin, callbacks, NULL, NULL, NULL, - include_cb, include_arg, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - lctx->maxttl = maxttl; - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadfileinc(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, 0, callbacks, task, done, - done_arg, lctxp, NULL, NULL, mctx, - dns_masterformat_text)); -} - -isc_result_t -dns_master_loadfileinc2(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx, - dns_masterformat_t format) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, 0, callbacks, task, done, - done_arg, lctxp, NULL, NULL, mctx, - format)); -} - -isc_result_t -dns_master_loadfileinc3(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp, isc_mem_t *mctx, - dns_masterformat_t format) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, resign, callbacks, task, - done, done_arg, lctxp, NULL, NULL, - mctx, format)); -} - -isc_result_t -dns_master_loadfileinc4(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format) -{ - options &= ~DNS_MASTER_CHECKTTL; - return (dns_master_loadfileinc5(master_file, top, origin, zclass, - options, resign, callbacks, task, - done, done_arg, lctxp, include_cb, - include_arg, mctx, format, 0)); -} - -isc_result_t -dns_master_loadfileinc5(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, - dns_masterincludecb_t include_cb, void *include_arg, - isc_mem_t *mctx, dns_masterformat_t format, - uint32_t maxttl) -{ - dns_loadctx_t *lctx = NULL; - isc_result_t result; - - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(format, mctx, options, resign, top, zclass, - origin, callbacks, task, done, done_arg, - include_cb, include_arg, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - lctx->maxttl = maxttl; - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(stream != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_lex_openstream(lctx->lex, stream); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - if (lctx != NULL) - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(stream != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_lex_openstream(lctx->lex, stream); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - if (lctx != NULL) - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(buffer != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_lex_openbuffer(lctx->lex, buffer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(buffer != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_lex_openbuffer(lctx->lex, buffer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(lex != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, lex, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp, isc_mem_t *mctx) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(lex != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, lex, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - dns_loadctx_detach(&lctx); - return (result); -} - -/* - * Grow the slab of dns_rdatalist_t structures. - * Re-link glue and current list. - */ -static dns_rdatalist_t * -grow_rdatalist(int new_len, dns_rdatalist_t *oldlist, int old_len, - rdatalist_head_t *current, rdatalist_head_t *glue, - isc_mem_t *mctx) -{ - dns_rdatalist_t *newlist; - int rdlcount = 0; - ISC_LIST(dns_rdatalist_t) save; - dns_rdatalist_t *this; - - newlist = isc_mem_get(mctx, new_len * sizeof(*newlist)); - if (newlist == NULL) - return (NULL); - - ISC_LIST_INIT(save); - while ((this = ISC_LIST_HEAD(*current)) != NULL) { - ISC_LIST_UNLINK(*current, this, link); - ISC_LIST_APPEND(save, this, link); - } - while ((this = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, this, link); - INSIST(rdlcount < new_len); - newlist[rdlcount] = *this; - ISC_LIST_APPEND(*current, &newlist[rdlcount], link); - rdlcount++; - } - - ISC_LIST_INIT(save); - while ((this = ISC_LIST_HEAD(*glue)) != NULL) { - ISC_LIST_UNLINK(*glue, this, link); - ISC_LIST_APPEND(save, this, link); - } - while ((this = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, this, link); - INSIST(rdlcount < new_len); - newlist[rdlcount] = *this; - ISC_LIST_APPEND(*glue, &newlist[rdlcount], link); - rdlcount++; - } - - INSIST(rdlcount == old_len); - if (oldlist != NULL) - isc_mem_put(mctx, oldlist, old_len * sizeof(*oldlist)); - return (newlist); -} - -/* - * Grow the slab of rdata structs. - * Re-link the current and glue chains. - */ -static dns_rdata_t * -grow_rdata(int new_len, dns_rdata_t *oldlist, int old_len, - rdatalist_head_t *current, rdatalist_head_t *glue, - isc_mem_t *mctx) -{ - dns_rdata_t *newlist; - int rdcount = 0; - ISC_LIST(dns_rdata_t) save; - dns_rdatalist_t *this; - dns_rdata_t *rdata; - - newlist = isc_mem_get(mctx, new_len * sizeof(*newlist)); - if (newlist == NULL) - return (NULL); - memset(newlist, 0, new_len * sizeof(*newlist)); - - /* - * Copy current relinking. - */ - this = ISC_LIST_HEAD(*current); - while (this != NULL) { - ISC_LIST_INIT(save); - while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { - ISC_LIST_UNLINK(this->rdata, rdata, link); - ISC_LIST_APPEND(save, rdata, link); - } - while ((rdata = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, rdata, link); - INSIST(rdcount < new_len); - newlist[rdcount] = *rdata; - ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link); - rdcount++; - } - this = ISC_LIST_NEXT(this, link); - } - - /* - * Copy glue relinking. - */ - this = ISC_LIST_HEAD(*glue); - while (this != NULL) { - ISC_LIST_INIT(save); - while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { - ISC_LIST_UNLINK(this->rdata, rdata, link); - ISC_LIST_APPEND(save, rdata, link); - } - while ((rdata = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, rdata, link); - INSIST(rdcount < new_len); - newlist[rdcount] = *rdata; - ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link); - rdcount++; - } - this = ISC_LIST_NEXT(this, link); - } - INSIST(rdcount == old_len || rdcount == 0); - if (oldlist != NULL) - isc_mem_put(mctx, oldlist, old_len * sizeof(*oldlist)); - return (newlist); -} - -static uint32_t -resign_fromlist(dns_rdatalist_t *this, dns_loadctx_t *lctx) { - dns_rdata_t *rdata; - dns_rdata_rrsig_t sig; - uint32_t when; - - rdata = ISC_LIST_HEAD(this->rdata); - INSIST(rdata != NULL); - (void)dns_rdata_tostruct(rdata, &sig, NULL); - if (isc_serial_gt(sig.timesigned, lctx->now)) - when = lctx->now; - else - when = sig.timeexpire - lctx->resign; - - /* cppcheck-suppress nullPointerRedundantCheck */ - rdata = ISC_LIST_NEXT(rdata, link); - /* cppcheck-suppress nullPointerRedundantCheck */ - while (rdata != NULL) { - (void)dns_rdata_tostruct(rdata, &sig, NULL); - if (isc_serial_gt(sig.timesigned, lctx->now)) - when = lctx->now; - else if (sig.timeexpire - lctx->resign < when) - when = sig.timeexpire - lctx->resign; - rdata = ISC_LIST_NEXT(rdata, link); - } - return (when); -} - -/* - * Convert each element from a rdatalist_t to rdataset then call commit. - * Unlink each element as we go. - */ - -static isc_result_t -commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, - rdatalist_head_t *head, dns_name_t *owner, - const char *source, unsigned int line) -{ - dns_rdatalist_t *this; - dns_rdataset_t dataset; - isc_result_t result; - char namebuf[DNS_NAME_FORMATSIZE]; - void (*error)(struct dns_rdatacallbacks *, const char *, ...); - - this = ISC_LIST_HEAD(*head); - error = callbacks->error; - - if (this == NULL) - return (ISC_R_SUCCESS); - do { - dns_rdataset_init(&dataset); - RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset) - == ISC_R_SUCCESS); - dataset.trust = dns_trust_ultimate; - /* - * If this is a secure dynamic zone set the re-signing time. - */ - if (dataset.type == dns_rdatatype_rrsig && - (lctx->options & DNS_MASTER_RESIGN) != 0) { - dataset.attributes |= DNS_RDATASETATTR_RESIGN; - dataset.resign = resign_fromlist(this, lctx); - } - result = ((*callbacks->add)(callbacks->add_private, owner, - &dataset)); - if (result == ISC_R_NOMEMORY) { - (*error)(callbacks, "dns_master_load: %s", - dns_result_totext(result)); - } else if (result != ISC_R_SUCCESS) { - dns_name_format(owner, namebuf, sizeof(namebuf)); - if (source != NULL) { - (*error)(callbacks, "%s: %s:%lu: %s: %s", - "dns_master_load", source, line, - namebuf, dns_result_totext(result)); - } else { - (*error)(callbacks, "%s: %s: %s", - "dns_master_load", namebuf, - dns_result_totext(result)); - } - } - if (MANYERRS(lctx, result)) - SETRESULT(lctx, result); - else if (result != ISC_R_SUCCESS) - return (result); - ISC_LIST_UNLINK(*head, this, link); - this = ISC_LIST_HEAD(*head); - } while (this != NULL); - return (ISC_R_SUCCESS); -} - -/* - * Returns true if one of the NS rdata's contains 'owner'. - */ - -static bool -is_glue(rdatalist_head_t *head, dns_name_t *owner) { - dns_rdatalist_t *this; - dns_rdata_t *rdata; - isc_region_t region; - dns_name_t name; - - /* - * Find NS rrset. - */ - this = ISC_LIST_HEAD(*head); - while (this != NULL) { - if (this->type == dns_rdatatype_ns) - break; - this = ISC_LIST_NEXT(this, link); - } - if (this == NULL) - return (false); - - rdata = ISC_LIST_HEAD(this->rdata); - while (rdata != NULL) { - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - if (dns_name_equal(&name, owner)) { - return (true); - } - rdata = ISC_LIST_NEXT(rdata, link); - } - return (false); -} - -static void -load_quantum(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_loadctx_t *lctx; - - REQUIRE(event != NULL); - REQUIRE(DNS_LCTX_VALID(event->ev_arg)); - - lctx = event->ev_arg; - - if (lctx->canceled) - result = ISC_R_CANCELED; - else - result = (lctx->load)(lctx); - if (result == DNS_R_CONTINUE) { - event->ev_arg = lctx; - isc_task_send(task, &event); - } else { - (lctx->done)(lctx->done_arg, result); - isc_event_free(&event); - dns_loadctx_detach(&lctx); - } -} - -static isc_result_t -task_send(dns_loadctx_t *lctx) { - isc_event_t *event; - - event = isc_event_allocate(lctx->mctx, NULL, - DNS_EVENT_MASTERQUANTUM, - load_quantum, lctx, sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - isc_task_send(lctx->task, &event); - return (ISC_R_SUCCESS); -} - -void -dns_loadctx_cancel(dns_loadctx_t *lctx) { - REQUIRE(DNS_LCTX_VALID(lctx)); - - LOCK(&lctx->lock); - lctx->canceled = true; - UNLOCK(&lctx->lock); -} - -void -dns_master_initrawheader(dns_masterrawheader_t *header) { - memset(header, 0, sizeof(dns_masterrawheader_t)); -} diff --git a/lib/dns-pkcs11/masterdump.c b/lib/dns-pkcs11/masterdump.c deleted file mode 100644 index 91b3cab..0000000 --- a/lib/dns-pkcs11/masterdump.c +++ /dev/null @@ -1,2132 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DNS_DCTX_MAGIC ISC_MAGIC('D', 'c', 't', 'x') -#define DNS_DCTX_VALID(d) ISC_MAGIC_VALID(d, DNS_DCTX_MAGIC) - -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -#define CHECK(x) do { \ - if ((x) != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -struct dns_master_style { - dns_masterstyle_flags_t flags; /* DNS_STYLEFLAG_* */ - unsigned int ttl_column; - unsigned int class_column; - unsigned int type_column; - unsigned int rdata_column; - unsigned int line_length; - unsigned int tab_width; - unsigned int split_width; -}; - -/*% - * The maximum length of the newline+indentation that is output - * when inserting a line break in an RR. This effectively puts an - * upper limits on the value of "rdata_column", because if it is - * very large, the tabs and spaces needed to reach it will not fit. - */ -#define DNS_TOTEXT_LINEBREAK_MAXLEN 100 - -/*% Does the rdataset 'r' contain a stale answer? */ -#define STALE(r) (((r)->attributes & DNS_RDATASETATTR_STALE) != 0) - -/*% - * Context structure for a masterfile dump in progress. - */ -typedef struct dns_totext_ctx { - dns_master_style_t style; - bool class_printed; - char * linebreak; - char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN]; - dns_name_t * origin; - dns_name_t * neworigin; - dns_fixedname_t origin_fixname; - uint32_t current_ttl; - bool current_ttl_valid; - dns_ttl_t serve_stale_ttl; -} dns_totext_ctx_t; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_keyzone = { - DNS_STYLEFLAG_OMIT_OWNER | - DNS_STYLEFLAG_OMIT_CLASS | - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_REL_DATA | - DNS_STYLEFLAG_OMIT_TTL | - DNS_STYLEFLAG_TTL | - DNS_STYLEFLAG_COMMENT | - DNS_STYLEFLAG_RRCOMMENT | - DNS_STYLEFLAG_MULTILINE | - DNS_STYLEFLAG_KEYDATA, - 24, 24, 24, 32, 80, 8, UINT_MAX -}; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_default = { - DNS_STYLEFLAG_OMIT_OWNER | - DNS_STYLEFLAG_OMIT_CLASS | - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_REL_DATA | - DNS_STYLEFLAG_OMIT_TTL | - DNS_STYLEFLAG_TTL | - DNS_STYLEFLAG_COMMENT | - DNS_STYLEFLAG_RRCOMMENT | - DNS_STYLEFLAG_MULTILINE, - 24, 24, 24, 32, 80, 8, UINT_MAX -}; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_full = { - DNS_STYLEFLAG_COMMENT | - DNS_STYLEFLAG_RESIGN, - 46, 46, 46, 64, 120, 8, UINT_MAX -}; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_explicitttl = { - DNS_STYLEFLAG_OMIT_OWNER | - DNS_STYLEFLAG_OMIT_CLASS | - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_REL_DATA | - DNS_STYLEFLAG_COMMENT | - DNS_STYLEFLAG_RRCOMMENT | - DNS_STYLEFLAG_MULTILINE, - 24, 32, 32, 40, 80, 8, UINT_MAX -}; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_cache = { - DNS_STYLEFLAG_OMIT_OWNER | - DNS_STYLEFLAG_OMIT_CLASS | - DNS_STYLEFLAG_MULTILINE | - DNS_STYLEFLAG_RRCOMMENT | - DNS_STYLEFLAG_TRUST | - DNS_STYLEFLAG_NCACHE, - 24, 32, 32, 40, 80, 8, UINT_MAX -}; - -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_simple = { - 0, - 24, 32, 32, 40, 80, 8, UINT_MAX -}; - -/*% - * A style suitable for dns_rdataset_totext(). - */ -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_debug = { - DNS_STYLEFLAG_REL_OWNER, - 24, 32, 40, 48, 80, 8, UINT_MAX -}; - -/*% - * Similar, but indented (i.e., prepended with dns_master_indentstr). - */ -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_indent = { - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_INDENT, - 24, 32, 40, 48, 80, 8, UINT_MAX -}; - -/*% - * Similar, but with each line commented out. - */ -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_comment = { - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_MULTILINE | - DNS_STYLEFLAG_RRCOMMENT | - DNS_STYLEFLAG_COMMENTDATA, - 24, 32, 40, 48, 80, 8, UINT_MAX -}; - -/*% - * YAML style - */ -LIBDNS_EXTERNAL_DATA const dns_master_style_t -dns_master_style_yaml = { - DNS_STYLEFLAG_YAML | - DNS_STYLEFLAG_REL_OWNER | - DNS_STYLEFLAG_INDENT, - 24, 32, 40, 48, 80, 8, UINT_MAX -}; - -/*% - * Default indent string. - */ -LIBDNS_EXTERNAL_DATA const char *dns_master_indentstr = "\t"; -LIBDNS_EXTERNAL_DATA unsigned int dns_master_indent = 1; - -#define N_SPACES 10 -static char spaces[N_SPACES+1] = " "; - -#define N_TABS 10 -static char tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t"; - -struct dns_dumpctx { - unsigned int magic; - isc_mem_t *mctx; - isc_mutex_t lock; - unsigned int references; - bool canceled; - bool first; - bool do_date; - isc_stdtime_t now; - FILE *f; - dns_db_t *db; - dns_dbversion_t *version; - dns_dbiterator_t *dbiter; - dns_totext_ctx_t tctx; - isc_task_t *task; - dns_dumpdonefunc_t done; - void *done_arg; - unsigned int nodes; - /* dns_master_dumpinc() */ - char *file; - char *tmpfile; - dns_masterformat_t format; - dns_masterrawheader_t header; - isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name, - dns_rdatasetiter_t *rdsiter, - dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f); -}; - -#define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) - -/*% - * Output tabs and spaces to go from column '*current' to - * column 'to', and update '*current' to reflect the new - * current column. - */ -static isc_result_t -indent(unsigned int *current, unsigned int to, int tabwidth, - isc_buffer_t *target) -{ - isc_region_t r; - unsigned char *p; - unsigned int from; - int ntabs, nspaces, t; - - from = *current; - - if (to < from + 1) - to = from + 1; - - ntabs = to / tabwidth - from / tabwidth; - if (ntabs < 0) - ntabs = 0; - - if (ntabs > 0) { - isc_buffer_availableregion(target, &r); - if (r.length < (unsigned) ntabs) - return (ISC_R_NOSPACE); - p = r.base; - - t = ntabs; - while (t) { - int n = t; - if (n > N_TABS) - n = N_TABS; - memmove(p, tabs, n); - p += n; - t -= n; - } - isc_buffer_add(target, ntabs); - from = (to / tabwidth) * tabwidth; - } - - nspaces = to - from; - INSIST(nspaces >= 0); - - isc_buffer_availableregion(target, &r); - if (r.length < (unsigned) nspaces) - return (ISC_R_NOSPACE); - p = r.base; - - t = nspaces; - while (t) { - int n = t; - if (n > N_SPACES) - n = N_SPACES; - memmove(p, spaces, n); - p += n; - t -= n; - } - isc_buffer_add(target, nspaces); - - *current = to; - return (ISC_R_SUCCESS); -} - -static isc_result_t -totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) { - isc_result_t result; - - REQUIRE(style->tab_width != 0); - - ctx->style = *style; - ctx->class_printed = false; - - dns_fixedname_init(&ctx->origin_fixname); - - /* - * Set up the line break string if needed. - */ - if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) { - isc_buffer_t buf; - unsigned int col = 0; - - isc_buffer_init(&buf, ctx->linebreak_buf, - sizeof(ctx->linebreak_buf)); - - if (isc_buffer_availablelength(&buf) < 1) { - return (DNS_R_TEXTTOOLONG); - } - isc_buffer_putuint8(&buf, '\n'); - - if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 || - (ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) - { - unsigned int i, len = strlen(dns_master_indentstr); - for (i = 0; i < dns_master_indent; i++) { - if (isc_buffer_availablelength(&buf) < len) - return (DNS_R_TEXTTOOLONG); - isc_buffer_putstr(&buf, dns_master_indentstr); - } - } - - if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) { - if (isc_buffer_availablelength(&buf) < 1) { - return (DNS_R_TEXTTOOLONG); - } - isc_buffer_putuint8(&buf, ';'); - } - - result = indent(&col, ctx->style.rdata_column, - ctx->style.tab_width, &buf); - /* - * Do not return ISC_R_NOSPACE if the line break string - * buffer is too small, because that would just make - * dump_rdataset() retry indefinitely with ever - * bigger target buffers. That's a different buffer, - * so it won't help. Use DNS_R_TEXTTOOLONG as a substitute. - */ - if (result == ISC_R_NOSPACE) - return (DNS_R_TEXTTOOLONG); - if (result != ISC_R_SUCCESS) - return (result); - - if (isc_buffer_availablelength(&buf) < 1) { - return (DNS_R_TEXTTOOLONG); - } - isc_buffer_putuint8(&buf, '\0'); - ctx->linebreak = ctx->linebreak_buf; - } else { - ctx->linebreak = NULL; - } - - ctx->origin = NULL; - ctx->neworigin = NULL; - ctx->current_ttl = 0; - ctx->current_ttl_valid = false; - ctx->serve_stale_ttl = 0; - - return (ISC_R_SUCCESS); -} - -#define INDENT_TO(col) \ - do { \ - if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) { \ - if ((result = str_totext(" ", target)) \ - != ISC_R_SUCCESS) \ - return (result); \ - } else if ((result = indent(&column, ctx->style.col, \ - ctx->style.tab_width, target)) \ - != ISC_R_SUCCESS) \ - return (result); \ - } while (0) - - -static isc_result_t -str_totext(const char *source, isc_buffer_t *target) { - unsigned int l; - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - l = strlen(source); - - if (l > region.length) - return (ISC_R_NOSPACE); - - memmove(region.base, source, l); - isc_buffer_add(target, l); - return (ISC_R_SUCCESS); -} - -static isc_result_t -ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot, - isc_buffer_t *target) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_rdataset_t rds; - dns_name_t name; - - dns_rdataset_init(&rds); - dns_name_init(&name, NULL); - - do { - dns_ncache_current(rdataset, &name, &rds); - for (result = dns_rdataset_first(&rds); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rds)) { - CHECK(str_totext("; ", target)); - CHECK(dns_name_totext(&name, omit_final_dot, target)); - CHECK(str_totext(" ", target)); - CHECK(dns_rdatatype_totext(rds.type, target)); - if (rds.type == dns_rdatatype_rrsig) { - CHECK(str_totext(" ", target)); - CHECK(dns_rdatatype_totext(rds.covers, target)); - CHECK(str_totext(" ...\n", target)); - } else { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rds, &rdata); - CHECK(str_totext(" ", target)); - CHECK(dns_rdata_tofmttext(&rdata, dns_rootname, - 0, 0, 0, " ", target)); - CHECK(str_totext("\n", target)); - } - } - dns_rdataset_disassociate(&rds); - result = dns_rdataset_next(rdataset); - } while (result == ISC_R_SUCCESS); - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - cleanup: - if (dns_rdataset_isassociated(&rds)) - dns_rdataset_disassociate(&rds); - - return (result); -} - -/* - * Convert 'rdataset' to master file text format according to 'ctx', - * storing the result in 'target'. If 'owner_name' is NULL, it - * is omitted; otherwise 'owner_name' must be valid and have at least - * one label. - */ - -static isc_result_t -rdataset_totext(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - dns_totext_ctx_t *ctx, - bool omit_final_dot, - isc_buffer_t *target) -{ - isc_result_t result; - unsigned int column; - bool first = true; - uint32_t current_ttl; - bool current_ttl_valid; - dns_rdatatype_t type; - unsigned int type_start; - dns_fixedname_t fixed; - dns_name_t *name = NULL; - unsigned int i; - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - - rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; - result = dns_rdataset_first(rdataset); - - current_ttl = ctx->current_ttl; - current_ttl_valid = ctx->current_ttl_valid; - - if (owner_name != NULL) { - name = dns_fixedname_initname(&fixed); - dns_name_copy(owner_name, name, NULL); - dns_rdataset_getownercase(rdataset, name); - } - - while (result == ISC_R_SUCCESS) { - column = 0; - - /* - * Indent? - */ - if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 || - (ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) - for (i = 0; i < dns_master_indent; i++) - RETERR(str_totext(dns_master_indentstr, - target)); - - /* - * YAML enumerator? - */ - if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) { - RETERR(str_totext("- ", target)); - } - - /* - * Comment? - */ - if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) - RETERR(str_totext(";", target)); - - /* - * Owner name. - */ - if (name != NULL && - ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 && - !first)) - { - unsigned int name_start = target->used; - RETERR(dns_name_totext(name, omit_final_dot, target)); - column += target->used - name_start; - } - - /* - * TTL. - */ - if ((ctx->style.flags & DNS_STYLEFLAG_NO_TTL) == 0 && - !((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 && - current_ttl_valid && - rdataset->ttl == current_ttl)) - { - char ttlbuf[64]; - isc_region_t r; - unsigned int length; - - INDENT_TO(ttl_column); - if ((ctx->style.flags & DNS_STYLEFLAG_TTL_UNITS) != 0) { - length = target->used; - result = dns_ttl_totext2(rdataset->ttl, - false, false, - target); - if (result != ISC_R_SUCCESS) - return (result); - column += target->used - length; - } else { - length = snprintf(ttlbuf, sizeof(ttlbuf), "%u", - rdataset->ttl); - INSIST(length <= sizeof(ttlbuf)); - isc_buffer_availableregion(target, &r); - if (r.length < length) - return (ISC_R_NOSPACE); - memmove(r.base, ttlbuf, length); - isc_buffer_add(target, length); - column += length; - } - - /* - * If the $TTL directive is not in use, the TTL we - * just printed becomes the default for subsequent RRs. - */ - if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) { - current_ttl = rdataset->ttl; - current_ttl_valid = true; - } - } - - /* - * Class. - */ - if ((ctx->style.flags & DNS_STYLEFLAG_NO_CLASS) == 0 && - ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 || - ctx->class_printed == false)) - { - unsigned int class_start; - INDENT_TO(class_column); - class_start = target->used; - if ((ctx->style.flags & DNS_STYLEFLAG_UNKNOWNFORMAT) != 0) - result = dns_rdataclass_tounknowntext - (rdataset->rdclass, target); - else - result = dns_rdataclass_totext - (rdataset->rdclass, target); - if (result != ISC_R_SUCCESS) - return (result); - column += (target->used - class_start); - } - - /* - * Type. - */ - - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - type = rdataset->covers; - } else { - type = rdataset->type; - } - - INDENT_TO(type_column); - type_start = target->used; - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) - RETERR(str_totext("\\-", target)); - switch (type) { - case dns_rdatatype_keydata: -#define KEYDATA "KEYDATA" - if ((ctx->style.flags & DNS_STYLEFLAG_KEYDATA) != 0) { - if (isc_buffer_availablelength(target) < - (sizeof(KEYDATA) - 1)) - return (ISC_R_NOSPACE); - isc_buffer_putstr(target, KEYDATA); - break; - } - /* FALLTHROUGH */ - default: - if ((ctx->style.flags & DNS_STYLEFLAG_UNKNOWNFORMAT) != 0) - result = dns_rdatatype_tounknowntext(type, target); - else - result = dns_rdatatype_totext(type, target); - if (result != ISC_R_SUCCESS) - return (result); - } - column += (target->used - type_start); - - /* - * Rdata. - */ - INDENT_TO(rdata_column); - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 || - (ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) - { - for (i = 0; i < dns_master_indent; i++) - RETERR(str_totext(dns_master_indentstr, - target)); - } - if (NXDOMAIN(rdataset)) - RETERR(str_totext(";-$NXDOMAIN\n", target)); - else - RETERR(str_totext(";-$NXRRSET\n", target)); - /* - * Print a summary of the cached records which make - * up the negative response. - */ - RETERR(ncache_summary(rdataset, omit_final_dot, - target)); - break; - } else { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(rdataset, &rdata); - - RETERR(dns_rdata_tofmttext(&rdata, - ctx->origin, - (unsigned int) - ctx->style.flags, - ctx->style.line_length - - ctx->style.rdata_column, - ctx->style.split_width, - ctx->linebreak, - target)); - - if (isc_buffer_availablelength(target) < 1) { - return (ISC_R_NOSPACE); - } - isc_buffer_putuint8(target, '\n'); - } - - first = false; - result = dns_rdataset_next(rdataset); - } - - if (result != ISC_R_NOMORE) - return (result); - - /* - * Update the ctx state to reflect what we just printed. - * This is done last, only when we are sure we will return - * success, because this function may be called multiple - * times with increasing buffer sizes until it succeeds, - * and failed attempts must not update the state prematurely. - */ - ctx->class_printed = true; - ctx->current_ttl= current_ttl; - ctx->current_ttl_valid = current_ttl_valid; - - return (ISC_R_SUCCESS); -} - -/* - * Print the name, type, and class of an empty rdataset, - * such as those used to represent the question section - * of a DNS message. - */ -static isc_result_t -question_totext(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - dns_totext_ctx_t *ctx, - bool omit_final_dot, - isc_buffer_t *target) -{ - unsigned int column; - isc_result_t result; - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - result = dns_rdataset_first(rdataset); - REQUIRE(result == ISC_R_NOMORE); - - column = 0; - - /* Owner name */ - { - unsigned int name_start = target->used; - RETERR(dns_name_totext(owner_name, - omit_final_dot, - target)); - column += target->used - name_start; - } - - /* Class */ - { - unsigned int class_start; - INDENT_TO(class_column); - class_start = target->used; - if ((ctx->style.flags & DNS_STYLEFLAG_UNKNOWNFORMAT) != 0) - result = dns_rdataclass_tounknowntext(rdataset->rdclass, - target); - else - result = dns_rdataclass_totext(rdataset->rdclass, - target); - if (result != ISC_R_SUCCESS) - return (result); - column += (target->used - class_start); - } - - /* Type */ - { - unsigned int type_start; - INDENT_TO(type_column); - type_start = target->used; - if ((ctx->style.flags & DNS_STYLEFLAG_UNKNOWNFORMAT) != 0) - result = dns_rdatatype_tounknowntext(rdataset->type, - target); - else - result = dns_rdatatype_totext(rdataset->type, - target); - if (result != ISC_R_SUCCESS) - return (result); - column += (target->used - type_start); - } - - if (isc_buffer_availablelength(target) < 1) { - return (ISC_R_NOSPACE); - } - isc_buffer_putuint8(target, '\n'); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdataset_totext(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - bool omit_final_dot, - bool question, - isc_buffer_t *target) -{ - dns_totext_ctx_t ctx; - isc_result_t result; - result = totext_ctx_init(&dns_master_style_debug, &ctx); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "could not set master file style"); - return (ISC_R_UNEXPECTED); - } - - /* - * The caller might want to give us an empty owner - * name (e.g. if they are outputting into a master - * file and this rdataset has the same name as the - * previous one.) - */ - if (dns_name_countlabels(owner_name) == 0) - owner_name = NULL; - - if (question) - return (question_totext(rdataset, owner_name, &ctx, - omit_final_dot, target)); - else - return (rdataset_totext(rdataset, owner_name, &ctx, - omit_final_dot, target)); -} - -isc_result_t -dns_master_rdatasettotext(dns_name_t *owner_name, - dns_rdataset_t *rdataset, - const dns_master_style_t *style, - isc_buffer_t *target) -{ - dns_totext_ctx_t ctx; - isc_result_t result; - result = totext_ctx_init(style, &ctx); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "could not set master file style"); - return (ISC_R_UNEXPECTED); - } - - return (rdataset_totext(rdataset, owner_name, &ctx, - false, target)); -} - -isc_result_t -dns_master_questiontotext(dns_name_t *owner_name, - dns_rdataset_t *rdataset, - const dns_master_style_t *style, - isc_buffer_t *target) -{ - dns_totext_ctx_t ctx; - isc_result_t result; - result = totext_ctx_init(style, &ctx); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "could not set master file style"); - return (ISC_R_UNEXPECTED); - } - - return (question_totext(rdataset, owner_name, &ctx, - false, target)); -} - -/* - * Print an rdataset. 'buffer' is a scratch buffer, which must have been - * dynamically allocated by the caller. It must be large enough to - * hold the result from dns_ttl_totext(). If more than that is needed, - * the buffer will be grown automatically. - */ - -static isc_result_t -dump_rdataset(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, - dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) -{ - isc_region_t r; - isc_result_t result; - - REQUIRE(buffer->length > 0); - - /* - * Output a $TTL directive if needed. - */ - - if ((ctx->style.flags & DNS_STYLEFLAG_TTL) != 0) { - if (ctx->current_ttl_valid == false || - ctx->current_ttl != rdataset->ttl) - { - if ((ctx->style.flags & DNS_STYLEFLAG_COMMENT) != 0) - { - isc_buffer_clear(buffer); - result = dns_ttl_totext(rdataset->ttl, - true, buffer); - INSIST(result == ISC_R_SUCCESS); - isc_buffer_usedregion(buffer, &r); - fprintf(f, "$TTL %u\t; %.*s\n", rdataset->ttl, - (int) r.length, (char *) r.base); - } else { - fprintf(f, "$TTL %u\n", rdataset->ttl); - } - ctx->current_ttl = rdataset->ttl; - ctx->current_ttl_valid = true; - } - } - - isc_buffer_clear(buffer); - - /* - * Generate the text representation of the rdataset into - * the buffer. If the buffer is too small, grow it. - */ - for (;;) { - int newlength; - void *newmem; - result = rdataset_totext(rdataset, name, ctx, - false, buffer); - if (result != ISC_R_NOSPACE) - break; - - newlength = buffer->length * 2; - newmem = isc_mem_get(mctx, newlength); - if (newmem == NULL) - return (ISC_R_NOMEMORY); - isc_mem_put(mctx, buffer->base, buffer->length); - isc_buffer_init(buffer, newmem, newlength); - } - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Write the buffer contents to the master file. - */ - isc_buffer_usedregion(buffer, &r); - result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "master file write failed: %s", - isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -/* - * Define the order in which rdatasets should be printed in zone - * files. We will print SOA and NS records before others, SIGs - * immediately following the things they sign, and order everything - * else by RR number. This is all just for aesthetics and - * compatibility with buggy software that expects the SOA to be first; - * the DNS specifications allow any order. - */ - -static int -dump_order(const dns_rdataset_t *rds) { - int t; - int sig; - if (rds->type == dns_rdatatype_rrsig) { - t = rds->covers; - sig = 1; - } else { - t = rds->type; - sig = 0; - } - switch (t) { - case dns_rdatatype_soa: - t = 0; - break; - case dns_rdatatype_ns: - t = 1; - break; - default: - t += 2; - break; - } - return (t << 1) + sig; -} - -static int -dump_order_compare(const void *a, const void *b) { - return (dump_order(*((const dns_rdataset_t * const *) a)) - - dump_order(*((const dns_rdataset_t * const *) b))); -} - -/* - * Dump all the rdatasets of a domain name to a master file. We make - * a "best effort" attempt to sort the RRsets in a nice order, but if - * there are more than MAXSORT RRsets, we punt and only sort them in - * groups of MAXSORT. This is not expected to ever happen in practice - * since much less than 64 RR types have been registered with the - * IANA, so far, and the output will be correct (though not - * aesthetically pleasing) even if it does happen. - */ - -#define MAXSORT 64 - -static isc_result_t -dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name, - dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) -{ - isc_result_t itresult, dumpresult; - isc_region_t r; - dns_rdataset_t rdatasets[MAXSORT]; - dns_rdataset_t *sorted[MAXSORT]; - int i, n; - - itresult = dns_rdatasetiter_first(rdsiter); - dumpresult = ISC_R_SUCCESS; - - if (itresult == ISC_R_SUCCESS && ctx->neworigin != NULL) { - isc_buffer_clear(buffer); - itresult = dns_name_totext(ctx->neworigin, false, buffer); - RUNTIME_CHECK(itresult == ISC_R_SUCCESS); - isc_buffer_usedregion(buffer, &r); - fprintf(f, "$ORIGIN %.*s\n", (int) r.length, (char *) r.base); - ctx->neworigin = NULL; - } - - again: - for (i = 0; - itresult == ISC_R_SUCCESS && i < MAXSORT; - itresult = dns_rdatasetiter_next(rdsiter), i++) { - dns_rdataset_init(&rdatasets[i]); - dns_rdatasetiter_current(rdsiter, &rdatasets[i]); - sorted[i] = &rdatasets[i]; - } - n = i; - INSIST(n <= MAXSORT); - - qsort(sorted, n, sizeof(sorted[0]), dump_order_compare); - - for (i = 0; i < n; i++) { - dns_rdataset_t *rds = sorted[i]; - if ((ctx->style.flags & DNS_STYLEFLAG_TRUST) != 0) { - if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 || - (ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) - { - unsigned int j; - for (j = 0; j < dns_master_indent; j++) - fprintf(f, "%s", dns_master_indentstr); - } - fprintf(f, "; %s\n", dns_trust_totext(rds->trust)); - } - if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) && - (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { - /* Omit negative cache entries */ - } else { - if (STALE(rds)) { - fprintf(f, "; stale (for %u more seconds)\n", - (rds->stale_ttl - - ctx->serve_stale_ttl)); - } - isc_result_t result = - dump_rdataset(mctx, name, rds, ctx, - buffer, f); - if (result != ISC_R_SUCCESS) - dumpresult = result; - if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0) - name = NULL; - } - if (((ctx->style.flags & DNS_STYLEFLAG_RESIGN) != 0) && - ((rds->attributes & DNS_RDATASETATTR_RESIGN) != 0)) { - isc_buffer_t b; - char buf[sizeof("YYYYMMDDHHMMSS")]; - memset(buf, 0, sizeof(buf)); - isc_buffer_init(&b, buf, sizeof(buf) - 1); - dns_time64_totext((uint64_t)rds->resign, &b); - if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 || - (ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) - { - unsigned int j; - for (j = 0; j < dns_master_indent; j++) - fprintf(f, "%s", dns_master_indentstr); - } - fprintf(f, "; resign=%s\n", buf); - } - dns_rdataset_disassociate(rds); - } - - if (dumpresult != ISC_R_SUCCESS) - return (dumpresult); - - /* - * If we got more data than could be sorted at once, - * go handle the rest. - */ - if (itresult == ISC_R_SUCCESS) - goto again; - - if (itresult == ISC_R_NOMORE) - itresult = ISC_R_SUCCESS; - - return (itresult); -} - -/* - * Dump given RRsets in the "raw" format. - */ -static isc_result_t -dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, - isc_buffer_t *buffer, FILE *f) -{ - isc_result_t result; - uint32_t totallen; - uint16_t dlen; - isc_region_t r, r_hdr; - - REQUIRE(buffer->length > 0); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - - rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; - restart: - totallen = 0; - result = dns_rdataset_first(rdataset); - REQUIRE(result == ISC_R_SUCCESS); - - isc_buffer_clear(buffer); - - /* - * Common header and owner name (length followed by name) - * These fields should be in a moderate length, so we assume we - * can store all of them in the initial buffer. - */ - isc_buffer_availableregion(buffer, &r_hdr); - INSIST(r_hdr.length >= sizeof(dns_masterrawrdataset_t)); - isc_buffer_putuint32(buffer, totallen); /* XXX: leave space */ - isc_buffer_putuint16(buffer, rdataset->rdclass); /* 16-bit class */ - isc_buffer_putuint16(buffer, rdataset->type); /* 16-bit type */ - isc_buffer_putuint16(buffer, rdataset->covers); /* same as type */ - isc_buffer_putuint32(buffer, rdataset->ttl); /* 32-bit TTL */ - isc_buffer_putuint32(buffer, dns_rdataset_count(rdataset)); - totallen = isc_buffer_usedlength(buffer); - INSIST(totallen <= sizeof(dns_masterrawrdataset_t)); - - dns_name_toregion(name, &r); - INSIST(isc_buffer_availablelength(buffer) >= - (sizeof(dlen) + r.length)); - dlen = (uint16_t)r.length; - isc_buffer_putuint16(buffer, dlen); - isc_buffer_copyregion(buffer, &r); - totallen += sizeof(dlen) + r.length; - - do { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - INSIST(r.length <= 0xffffU); - dlen = (uint16_t)r.length; - - /* - * Copy the rdata into the buffer. If the buffer is too small, - * grow it. This should be rare, so we'll simply restart the - * entire procedure (or should we copy the old data and - * continue?). - */ - if (isc_buffer_availablelength(buffer) < - sizeof(dlen) + r.length) { - int newlength; - void *newmem; - - newlength = buffer->length * 2; - newmem = isc_mem_get(mctx, newlength); - if (newmem == NULL) - return (ISC_R_NOMEMORY); - isc_mem_put(mctx, buffer->base, buffer->length); - isc_buffer_init(buffer, newmem, newlength); - goto restart; - } - isc_buffer_putuint16(buffer, dlen); - isc_buffer_copyregion(buffer, &r); - totallen += sizeof(dlen) + r.length; - - result = dns_rdataset_next(rdataset); - } while (result == ISC_R_SUCCESS); - - if (result != ISC_R_NOMORE) - return (result); - - /* - * Fill in the total length field. - * XXX: this is a bit tricky. Since we have already "used" the space - * for the total length in the buffer, we first remember the entire - * buffer length in the region, "rewind", and then write the value. - */ - isc_buffer_usedregion(buffer, &r); - isc_buffer_clear(buffer); - isc_buffer_putuint32(buffer, totallen); - INSIST(isc_buffer_usedlength(buffer) < totallen); - - /* - * Write the buffer contents to the raw master file. - */ - result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); - - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "raw master file write failed: %s", - isc_result_totext(result)); - return (result); - } - - return (result); -} - -static isc_result_t -dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *owner_name, - dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) -{ - isc_result_t result; - dns_rdataset_t rdataset; - dns_fixedname_t fixed; - dns_name_t *name; - - name = dns_fixedname_initname(&fixed); - dns_name_copy(owner_name, name, NULL); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(rdsiter, &rdataset); - - dns_rdataset_getownercase(&rdataset, name); - - if (((rdataset.attributes & DNS_RDATASETATTR_NEGATIVE) != 0) && - (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { - /* Omit negative cache entries */ - } else { - result = dump_rdataset_raw(mctx, name, &rdataset, - buffer, f); - } - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) - return (result); - } - - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - return (result); -} - -static isc_result_t -dump_rdatasets_map(isc_mem_t *mctx, dns_name_t *name, - dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) -{ - UNUSED(mctx); - UNUSED(name); - UNUSED(rdsiter); - UNUSED(ctx); - UNUSED(buffer); - UNUSED(f); - - return (ISC_R_NOTIMPLEMENTED); -} - -/* - * Initial size of text conversion buffer. The buffer is used - * for several purposes: converting origin names, rdatasets, - * $DATE timestamps, and comment strings for $TTL directives. - * - * When converting rdatasets, it is dynamically resized, but - * when converting origins, timestamps, etc it is not. Therefore, - * the initial size must large enough to hold the longest possible - * text representation of any domain name (for $ORIGIN). - */ -static const int initial_buffer_length = 1200; - -static isc_result_t -dumptostreaminc(dns_dumpctx_t *dctx); - -static void -dumpctx_destroy(dns_dumpctx_t *dctx) { - - dctx->magic = 0; - DESTROYLOCK(&dctx->lock); - dns_dbiterator_destroy(&dctx->dbiter); - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, false); - dns_db_detach(&dctx->db); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - if (dctx->file != NULL) - isc_mem_free(dctx->mctx, dctx->file); - if (dctx->tmpfile != NULL) - isc_mem_free(dctx->mctx, dctx->tmpfile); - isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx)); -} - -void -dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) { - - REQUIRE(DNS_DCTX_VALID(source)); - REQUIRE(target != NULL && *target == NULL); - - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); /* Overflow? */ - UNLOCK(&source->lock); - - *target = source; -} - -void -dns_dumpctx_detach(dns_dumpctx_t **dctxp) { - dns_dumpctx_t *dctx; - bool need_destroy = false; - - REQUIRE(dctxp != NULL); - dctx = *dctxp; - REQUIRE(DNS_DCTX_VALID(dctx)); - - *dctxp = NULL; - - LOCK(&dctx->lock); - INSIST(dctx->references != 0); - dctx->references--; - if (dctx->references == 0) - need_destroy = true; - UNLOCK(&dctx->lock); - if (need_destroy) - dumpctx_destroy(dctx); -} - -dns_dbversion_t * -dns_dumpctx_version(dns_dumpctx_t *dctx) { - REQUIRE(DNS_DCTX_VALID(dctx)); - return (dctx->version); -} - -dns_db_t * -dns_dumpctx_db(dns_dumpctx_t *dctx) { - REQUIRE(DNS_DCTX_VALID(dctx)); - return (dctx->db); -} - -void -dns_dumpctx_cancel(dns_dumpctx_t *dctx) { - REQUIRE(DNS_DCTX_VALID(dctx)); - - LOCK(&dctx->lock); - dctx->canceled = true; - UNLOCK(&dctx->lock); -} - -static isc_result_t -flushandsync(FILE *f, isc_result_t result, const char *temp) { - bool logit = (result == ISC_R_SUCCESS); - - if (result == ISC_R_SUCCESS) - result = isc_stdio_flush(f); - if (result != ISC_R_SUCCESS && logit) { - if (temp != NULL) - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping to master file: %s: flush: %s", - temp, isc_result_totext(result)); - else - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping to stream: flush: %s", - isc_result_totext(result)); - logit = false; - } - - if (result == ISC_R_SUCCESS) - result = isc_stdio_sync(f); - if (result != ISC_R_SUCCESS && logit) { - if (temp != NULL) - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping to master file: %s: fsync: %s", - temp, isc_result_totext(result)); - else - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping to stream: fsync: %s", - isc_result_totext(result)); - } - return (result); -} - -static isc_result_t -closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file) -{ - isc_result_t tresult; - bool logit = (result == ISC_R_SUCCESS); - - result = flushandsync(f, result, temp); - if (result != ISC_R_SUCCESS) - logit = false; - - tresult = isc_stdio_close(f); - if (result == ISC_R_SUCCESS) - result = tresult; - if (result != ISC_R_SUCCESS && logit) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: fclose: %s", - temp, isc_result_totext(result)); - logit = false; - } - if (result == ISC_R_SUCCESS) - result = isc_file_rename(temp, file); - else - (void)isc_file_remove(temp); - if (result != ISC_R_SUCCESS && logit) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: rename: %s: %s", - file, isc_result_totext(result)); - } - return (result); -} - -static void -dump_quantum(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - isc_result_t tresult; - dns_dumpctx_t *dctx; - - REQUIRE(event != NULL); - dctx = event->ev_arg; - REQUIRE(DNS_DCTX_VALID(dctx)); - if (dctx->canceled) - result = ISC_R_CANCELED; - else - result = dumptostreaminc(dctx); - if (result == DNS_R_CONTINUE) { - event->ev_arg = dctx; - isc_task_send(task, &event); - return; - } - - if (dctx->file != NULL) { - tresult = closeandrename(dctx->f, result, - dctx->tmpfile, dctx->file); - if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) - result = tresult; - } else - result = flushandsync(dctx->f, result, NULL); - (dctx->done)(dctx->done_arg, result); - isc_event_free(&event); - dns_dumpctx_detach(&dctx); -} - -static isc_result_t -task_send(dns_dumpctx_t *dctx) { - isc_event_t *event; - - event = isc_event_allocate(dctx->mctx, NULL, DNS_EVENT_DUMPQUANTUM, - dump_quantum, dctx, sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - isc_task_send(dctx->task, &event); - return (ISC_R_SUCCESS); -} - -static isc_result_t -dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp, - dns_masterformat_t format, dns_masterrawheader_t *header) -{ - dns_dumpctx_t *dctx; - isc_result_t result; - unsigned int options; - - dctx = isc_mem_get(mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - dctx->mctx = NULL; - dctx->f = f; - dctx->dbiter = NULL; - dctx->db = NULL; - dctx->version = NULL; - dctx->done = NULL; - dctx->done_arg = NULL; - dctx->task = NULL; - dctx->nodes = 0; - dctx->first = true; - dctx->canceled = false; - dctx->file = NULL; - dctx->tmpfile = NULL; - dctx->format = format; - if (header == NULL) - dns_master_initrawheader(&dctx->header); - else - dctx->header = *header; - - switch (format) { - case dns_masterformat_text: - dctx->dumpsets = dump_rdatasets_text; - break; - case dns_masterformat_raw: - dctx->dumpsets = dump_rdatasets_raw; - break; - case dns_masterformat_map: - dctx->dumpsets = dump_rdatasets_map; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - result = totext_ctx_init(style, &dctx->tctx); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "could not set master file style"); - goto cleanup; - } - - isc_stdtime_get(&dctx->now); - dns_db_attach(db, &dctx->db); - - dctx->do_date = dns_db_iscache(dctx->db); - if (dctx->do_date) { - /* - * Adjust the date backwards by the serve-stale TTL, if any. - * This is so the TTL will be loaded correctly when next - * started. - */ - (void)dns_db_getservestalettl(dctx->db, - &dctx->tctx.serve_stale_ttl); - dctx->now -= dctx->tctx.serve_stale_ttl; - } - - if (dctx->format == dns_masterformat_text && - (dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) { - options = DNS_DB_RELATIVENAMES; - } else - options = 0; - result = dns_db_createiterator(dctx->db, options, &dctx->dbiter); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_mutex_init(&dctx->lock); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (version != NULL) - dns_db_attachversion(dctx->db, version, &dctx->version); - else if (!dns_db_iscache(db)) - dns_db_currentversion(dctx->db, &dctx->version); - isc_mem_attach(mctx, &dctx->mctx); - dctx->references = 1; - dctx->magic = DNS_DCTX_MAGIC; - *dctxp = dctx; - return (ISC_R_SUCCESS); - - cleanup: - if (dctx->dbiter != NULL) - dns_dbiterator_destroy(&dctx->dbiter); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx != NULL) - isc_mem_put(mctx, dctx, sizeof(*dctx)); - return (result); -} - -static isc_result_t -writeheader(dns_dumpctx_t *dctx) { - isc_result_t result = ISC_R_SUCCESS; - isc_buffer_t buffer; - char *bufmem; - isc_region_t r; - dns_masterrawheader_t rawheader; - uint32_t rawversion, now32; - - bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); - if (bufmem == NULL) - return (ISC_R_NOMEMORY); - - isc_buffer_init(&buffer, bufmem, initial_buffer_length); - - switch (dctx->format) { - case dns_masterformat_text: - /* - * If the database has cache semantics, output an - * RFC2540 $DATE directive so that the TTLs can be - * adjusted when it is reloaded. For zones it is not - * really needed, and it would make the file - * incompatible with pre-RFC2540 software, so we omit - * it in the zone case. - */ - if (dctx->do_date) { - fprintf(dctx->f, - "; using a %d second stale ttl\n", - dctx->tctx.serve_stale_ttl); - result = dns_time32_totext(dctx->now, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_usedregion(&buffer, &r); - fprintf(dctx->f, "$DATE %.*s\n", - (int) r.length, (char *) r.base); - } - break; - case dns_masterformat_raw: - case dns_masterformat_map: - r.base = (unsigned char *)&rawheader; - r.length = sizeof(rawheader); - isc_buffer_region(&buffer, &r); - now32 = dctx->now; - rawversion = 1; - if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0) - rawversion = 0; - - isc_buffer_putuint32(&buffer, dctx->format); - isc_buffer_putuint32(&buffer, rawversion); - isc_buffer_putuint32(&buffer, now32); - - if (rawversion == 1) { - isc_buffer_putuint32(&buffer, dctx->header.flags); - isc_buffer_putuint32(&buffer, - dctx->header.sourceserial); - isc_buffer_putuint32(&buffer, dctx->header.lastxfrin); - } - - INSIST(isc_buffer_usedlength(&buffer) <= sizeof(rawheader)); - result = isc_stdio_write(buffer.base, 1, - isc_buffer_usedlength(&buffer), - dctx->f, NULL); - if (result != ISC_R_SUCCESS) - break; - - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - isc_mem_put(dctx->mctx, buffer.base, buffer.length); - return (result); -} - -static isc_result_t -dumptostreaminc(dns_dumpctx_t *dctx) { - isc_result_t result = ISC_R_SUCCESS; - isc_buffer_t buffer; - char *bufmem; - dns_name_t *name; - dns_fixedname_t fixname; - unsigned int nodes; - isc_time_t start; - - bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); - if (bufmem == NULL) - return (ISC_R_NOMEMORY); - - isc_buffer_init(&buffer, bufmem, initial_buffer_length); - - name = dns_fixedname_initname(&fixname); - - if (dctx->first) { - CHECK(writeheader(dctx)); - - /* - * Fast format is not currently written incrementally, - * so we make the call to dns_db_serialize() here. - * If the database is anything other than an rbtdb, - * this should result in not implemented - */ - if (dctx->format == dns_masterformat_map) { - result = dns_db_serialize(dctx->db, dctx->version, - dctx->f); - goto cleanup; - } - - result = dns_dbiterator_first(dctx->dbiter); - if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) - goto cleanup; - - dctx->first = false; - } else - result = ISC_R_SUCCESS; - - nodes = dctx->nodes; - isc_time_now(&start); - while (result == ISC_R_SUCCESS && (dctx->nodes == 0 || nodes--)) { - dns_rdatasetiter_t *rdsiter = NULL; - dns_dbnode_t *node = NULL; - - result = dns_dbiterator_current(dctx->dbiter, &node, name); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) - break; - if (result == DNS_R_NEWORIGIN) { - dns_name_t *origin = - dns_fixedname_name(&dctx->tctx.origin_fixname); - result = dns_dbiterator_origin(dctx->dbiter, origin); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if ((dctx->tctx.style.flags & - DNS_STYLEFLAG_REL_DATA) != 0) - dctx->tctx.origin = origin; - dctx->tctx.neworigin = origin; - } - result = dns_db_allrdatasets(dctx->db, node, dctx->version, - dctx->now, &rdsiter); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(dctx->db, &node); - goto cleanup; - } - result = (dctx->dumpsets)(dctx->mctx, name, rdsiter, - &dctx->tctx, &buffer, dctx->f); - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(dctx->db, &node); - goto cleanup; - } - dns_db_detachnode(dctx->db, &node); - result = dns_dbiterator_next(dctx->dbiter); - } - - /* - * Work out how many nodes can be written in the time between - * two requests to the nameserver. Smooth the resulting number and - * use it as a estimate for the number of nodes to be written in the - * next iteration. - */ - if (dctx->nodes != 0 && result == ISC_R_SUCCESS) { - unsigned int pps = dns_pps; /* packets per second */ - unsigned int interval; - uint64_t usecs; - isc_time_t end; - - isc_time_now(&end); - if (pps < 100) - pps = 100; - interval = 1000000 / pps; /* interval in usecs */ - if (interval == 0) - interval = 1; - usecs = isc_time_microdiff(&end, &start); - if (usecs == 0) { - dctx->nodes = dctx->nodes * 2; - if (dctx->nodes > 1000) - dctx->nodes = 1000; - } else { - nodes = dctx->nodes * interval; - nodes /= (unsigned int)usecs; - if (nodes == 0) - nodes = 1; - else if (nodes > 1000) - nodes = 1000; - - /* Smooth and assign. */ - dctx->nodes = (nodes + dctx->nodes * 7) / 8; - - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, - ISC_LOG_DEBUG(1), - "dumptostreaminc(%p) new nodes -> %d", - dctx, dctx->nodes); - } - result = DNS_R_CONTINUE; - } else if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - cleanup: - RUNTIME_CHECK(dns_dbiterator_pause(dctx->dbiter) == ISC_R_SUCCESS); - isc_mem_put(dctx->mctx, buffer.base, buffer.length); - return (result); -} - -isc_result_t -dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - FILE *f, isc_task_t *task, - dns_dumpdonefunc_t done, void *done_arg, - dns_dumpctx_t **dctxp) -{ - dns_dumpctx_t *dctx = NULL; - isc_result_t result; - - REQUIRE(task != NULL); - REQUIRE(f != NULL); - REQUIRE(done != NULL); - - result = dumpctx_create(mctx, db, version, style, f, &dctx, - dns_masterformat_text, NULL); - if (result != ISC_R_SUCCESS) - return (result); - isc_task_attach(task, &dctx->task); - dctx->done = done; - dctx->done_arg = done_arg; - dctx->nodes = 100; - - result = task_send(dctx); - if (result == ISC_R_SUCCESS) { - dns_dumpctx_attach(dctx, dctxp); - return (DNS_R_CONTINUE); - } - - dns_dumpctx_detach(&dctx); - return (result); -} - -/* - * Dump an entire database into a master file. - */ -isc_result_t -dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - FILE *f) -{ - return (dns_master_dumptostream3(mctx, db, version, style, - dns_masterformat_text, NULL, f)); -} - -isc_result_t -dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - dns_masterformat_t format, FILE *f) -{ - return (dns_master_dumptostream3(mctx, db, version, style, - format, NULL, f)); -} - -isc_result_t -dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - const dns_master_style_t *style, - dns_masterformat_t format, - dns_masterrawheader_t *header, FILE *f) -{ - dns_dumpctx_t *dctx = NULL; - isc_result_t result; - - result = dumpctx_create(mctx, db, version, style, f, &dctx, - format, header); - if (result != ISC_R_SUCCESS) - return (result); - - result = dumptostreaminc(dctx); - INSIST(result != DNS_R_CONTINUE); - dns_dumpctx_detach(&dctx); - - result = flushandsync(f, result, NULL); - return (result); -} - -static isc_result_t -opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file, - char **tempp, FILE **fp) { - FILE *f = NULL; - isc_result_t result; - char *tempname = NULL; - int tempnamelen; - - tempnamelen = strlen(file) + 20; - tempname = isc_mem_allocate(mctx, tempnamelen); - if (tempname == NULL) - return (ISC_R_NOMEMORY); - - result = isc_file_mktemplate(file, tempname, tempnamelen); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (format == dns_masterformat_text) - result = isc_file_openunique(tempname, &f); - else - result = isc_file_bopenunique(tempname, &f); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: open: %s", - tempname, isc_result_totext(result)); - goto cleanup; - } - *tempp = tempname; - *fp = f; - return (ISC_R_SUCCESS); - -cleanup: - isc_mem_free(mctx, tempname); - return (result); -} - -isc_result_t -dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, - dns_dumpctx_t **dctxp) -{ - return (dns_master_dumpinc3(mctx, db, version, style, filename, task, - done, done_arg, dctxp, - dns_masterformat_text, NULL)); -} - -isc_result_t -dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, - dns_dumpctx_t **dctxp, dns_masterformat_t format) -{ - return (dns_master_dumpinc3(mctx, db, version, style, filename, task, - done, done_arg, dctxp, format, NULL)); -} - -isc_result_t -dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, - dns_dumpctx_t **dctxp, dns_masterformat_t format, - dns_masterrawheader_t *header) -{ - FILE *f = NULL; - isc_result_t result; - char *tempname = NULL; - char *file = NULL; - dns_dumpctx_t *dctx = NULL; - - file = isc_mem_strdup(mctx, filename); - if (file == NULL) - return (ISC_R_NOMEMORY); - - result = opentmp(mctx, format, filename, &tempname, &f); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dumpctx_create(mctx, db, version, style, f, &dctx, - format, header); - if (result != ISC_R_SUCCESS) { - (void)isc_stdio_close(f); - (void)isc_file_remove(tempname); - goto cleanup; - } - - isc_task_attach(task, &dctx->task); - dctx->done = done; - dctx->done_arg = done_arg; - dctx->nodes = 100; - dctx->file = file; - file = NULL; - dctx->tmpfile = tempname; - tempname = NULL; - - result = task_send(dctx); - if (result == ISC_R_SUCCESS) { - dns_dumpctx_attach(dctx, dctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - if (dctx != NULL) - dns_dumpctx_detach(&dctx); - if (file != NULL) - isc_mem_free(mctx, file); - if (tempname != NULL) - isc_mem_free(mctx, tempname); - return (result); -} - -isc_result_t -dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename) -{ - return (dns_master_dump3(mctx, db, version, style, filename, - dns_masterformat_text, NULL)); -} - -isc_result_t -dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - dns_masterformat_t format) -{ - return (dns_master_dump3(mctx, db, version, style, filename, - format, NULL)); -} - -isc_result_t -dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, const char *filename, - dns_masterformat_t format, dns_masterrawheader_t *header) -{ - FILE *f = NULL; - isc_result_t result; - char *tempname; - dns_dumpctx_t *dctx = NULL; - - result = opentmp(mctx, format, filename, &tempname, &f); - if (result != ISC_R_SUCCESS) - return (result); - - result = dumpctx_create(mctx, db, version, style, f, &dctx, - format, header); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dumptostreaminc(dctx); - INSIST(result != DNS_R_CONTINUE); - dns_dumpctx_detach(&dctx); - - result = closeandrename(f, result, tempname, filename); - - cleanup: - isc_mem_free(mctx, tempname); - return (result); -} - -/* - * Dump a database node into a master file. - * XXX: this function assumes the text format. - */ -isc_result_t -dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *name, - const dns_master_style_t *style, - FILE *f) -{ - isc_result_t result; - isc_buffer_t buffer; - char *bufmem; - isc_stdtime_t now; - dns_totext_ctx_t ctx; - dns_rdatasetiter_t *rdsiter = NULL; - - result = totext_ctx_init(style, &ctx); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "could not set master file style"); - return (ISC_R_UNEXPECTED); - } - - isc_stdtime_get(&now); - - bufmem = isc_mem_get(mctx, initial_buffer_length); - if (bufmem == NULL) - return (ISC_R_NOMEMORY); - - isc_buffer_init(&buffer, bufmem, initial_buffer_length); - - result = dns_db_allrdatasets(db, node, version, now, &rdsiter); - if (result != ISC_R_SUCCESS) - goto failure; - result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdatasetiter_destroy(&rdsiter); - - result = ISC_R_SUCCESS; - - failure: - isc_mem_put(mctx, buffer.base, buffer.length); - return (result); -} - -isc_result_t -dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *name, - const dns_master_style_t *style, const char *filename) -{ - FILE *f = NULL; - isc_result_t result; - - result = isc_stdio_open(filename, "w", &f); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping node to file: %s: open: %s", filename, - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = dns_master_dumpnodetostream(mctx, db, version, node, name, - style, f); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: dump: %s", filename, - isc_result_totext(result)); - (void)isc_stdio_close(f); - return (ISC_R_UNEXPECTED); - } - - result = isc_stdio_close(f); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: close: %s", filename, - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - return (result); -} - -dns_masterstyle_flags_t -dns_master_styleflags(const dns_master_style_t *style) { - REQUIRE(style != NULL); - return (style->flags); -} - -isc_result_t -dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags, - unsigned int ttl_column, unsigned int class_column, - unsigned int type_column, unsigned int rdata_column, - unsigned int line_length, unsigned int tab_width, - isc_mem_t *mctx) -{ - return (dns_master_stylecreate2(stylep, flags, ttl_column, - class_column, type_column, - rdata_column, line_length, - tab_width, 0xffffffff, mctx)); -} - -isc_result_t -dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags, - unsigned int ttl_column, unsigned int class_column, - unsigned int type_column, unsigned int rdata_column, - unsigned int line_length, unsigned int tab_width, - unsigned int split_width, isc_mem_t *mctx) -{ - dns_master_style_t *style; - - REQUIRE(stylep != NULL && *stylep == NULL); - style = isc_mem_get(mctx, sizeof(*style)); - if (style == NULL) - return (ISC_R_NOMEMORY); - - style->flags = flags; - style->ttl_column = ttl_column; - style->class_column = class_column; - style->type_column = type_column; - style->rdata_column = rdata_column; - style->line_length = line_length; - style->tab_width = tab_width; - style->split_width = split_width; - *stylep = style; - return (ISC_R_SUCCESS); -} - -void -dns_master_styledestroy(dns_master_style_t **stylep, isc_mem_t *mctx) { - dns_master_style_t *style; - - REQUIRE(stylep != NULL && *stylep != NULL); - style = *stylep; - *stylep = NULL; - isc_mem_put(mctx, style, sizeof(*style)); -} diff --git a/lib/dns-pkcs11/message.c b/lib/dns-pkcs11/message.c deleted file mode 100644 index 2812ab5..0000000 --- a/lib/dns-pkcs11/message.c +++ /dev/null @@ -1,4622 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -/*** - *** Imports - ***/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef SKAN_MSG_DEBUG -static void -hexdump(const char *msg, const char *msg2, void *base, size_t len) { - unsigned char *p; - unsigned int cnt; - - p = base; - cnt = 0; - - printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, (unsigned)len, base); - - while (cnt < len) { - if (cnt % 16 == 0) - printf("%p: ", p); - else if (cnt % 8 == 0) - printf(" |"); - printf(" %02x %c", *p, (isprint(*p) ? *p : ' ')); - p++; - cnt++; - - if (cnt % 16 == 0) - printf("\n"); - } - - if (cnt % 16 != 0) - printf("\n"); -} -#endif - -#define DNS_MESSAGE_OPCODE_MASK 0x7800U -#define DNS_MESSAGE_OPCODE_SHIFT 11 -#define DNS_MESSAGE_RCODE_MASK 0x000fU -#define DNS_MESSAGE_FLAG_MASK 0x8ff0U -#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U -#define DNS_MESSAGE_EDNSRCODE_SHIFT 24 -#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U -#define DNS_MESSAGE_EDNSVERSION_SHIFT 16 - -#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \ - && ((s) < DNS_SECTION_MAX)) -#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \ - && ((s) < DNS_SECTION_MAX)) -#define ADD_STRING(b, s) {if (strlen(s) >= \ - isc_buffer_availablelength(b)) { \ - result = ISC_R_NOSPACE; \ - goto cleanup; \ - } else \ - isc_buffer_putstr(b, s);} -#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \ - && ((s) < DNS_PSEUDOSECTION_MAX)) - -#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0) - -/*% - * This is the size of each individual scratchpad buffer, and the numbers - * of various block allocations used within the server. - * XXXMLG These should come from a config setting. - */ -#define SCRATCHPAD_SIZE 512 -#define NAME_COUNT 64 -#define OFFSET_COUNT 4 -#define RDATA_COUNT 8 -#define RDATALIST_COUNT 8 -#define RDATASET_COUNT 64 - -/*% - * Text representation of the different items, for message_totext - * functions. - */ -static const char *sectiontext[] = { - "QUESTION", - "ANSWER", - "AUTHORITY", - "ADDITIONAL" -}; - -static const char *updsectiontext[] = { - "ZONE", - "PREREQUISITE", - "UPDATE", - "ADDITIONAL" -}; - -static const char *opcodetext[] = { - "QUERY", - "IQUERY", - "STATUS", - "RESERVED3", - "NOTIFY", - "UPDATE", - "RESERVED6", - "RESERVED7", - "RESERVED8", - "RESERVED9", - "RESERVED10", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15" -}; - -static const char *edetext[] = { "Other", - "Unsupported DNSKEY Algorithm", - "Unsupported DS Digest Type", - "Stale Answer", - "Forged Answer", - "DNSSEC Indeterminate", - "DNSSEC Bogus", - "Signature Expired", - "Signature Not Yet Valid", - "DNSKEY Missing", - "RRSIGs Missing", - "No Zone Key Bit Set", - "NSEC Missing", - "Cached Error", - "Not Ready", - "Blocked", - "Censored", - "Filtered", - "Prohibited", - "Stale NXDOMAIN Answer", - "Not Authoritative", - "Not Supported", - "No Reachable Authority", - "Network Error", - "Invalid Data" }; - -/*% - * "helper" type, which consists of a block of some type, and is linkable. - * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer - * size, or the allocated elements will not be aligned correctly. - */ -struct dns_msgblock { - unsigned int count; - unsigned int remaining; - ISC_LINK(dns_msgblock_t) link; -}; /* dynamically sized */ - -static inline dns_msgblock_t * -msgblock_allocate(isc_mem_t *, unsigned int, unsigned int); - -#define msgblock_get(block, type) \ - ((type *)msgblock_internalget(block, sizeof(type))) - -static inline void * -msgblock_internalget(dns_msgblock_t *, unsigned int); - -static inline void -msgblock_reset(dns_msgblock_t *); - -static inline void -msgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int); - -static void -logfmtpacket(dns_message_t *message, const char *description, - isc_sockaddr_t *address, isc_logcategory_t *category, - isc_logmodule_t *module, const dns_master_style_t *style, - int level, isc_mem_t *mctx); - -/* - * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory - * is free, return NULL. - */ -static inline dns_msgblock_t * -msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type, - unsigned int count) -{ - dns_msgblock_t *block; - unsigned int length; - - length = sizeof(dns_msgblock_t) + (sizeof_type * count); - - block = isc_mem_get(mctx, length); - if (block == NULL) - return (NULL); - - block->count = count; - block->remaining = count; - - ISC_LINK_INIT(block, link); - - return (block); -} - -/* - * Return an element from the msgblock. If no more are available, return - * NULL. - */ -static inline void * -msgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) { - void *ptr; - - if (block == NULL || block->remaining == 0) - return (NULL); - - block->remaining--; - - ptr = (((unsigned char *)block) - + sizeof(dns_msgblock_t) - + (sizeof_type * block->remaining)); - - return (ptr); -} - -static inline void -msgblock_reset(dns_msgblock_t *block) { - block->remaining = block->count; -} - -/* - * Release memory associated with a message block. - */ -static inline void -msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type) -{ - unsigned int length; - - length = sizeof(dns_msgblock_t) + (sizeof_type * block->count); - - isc_mem_put(mctx, block, length); -} - -/* - * Allocate a new dynamic buffer, and attach it to this message as the - * "current" buffer. (which is always the last on the list, for our - * uses) - */ -static inline isc_result_t -newbuffer(dns_message_t *msg, unsigned int size) { - isc_result_t result; - isc_buffer_t *dynbuf; - - dynbuf = NULL; - result = isc_buffer_allocate(msg->mctx, &dynbuf, size); - if (result != ISC_R_SUCCESS) - return (ISC_R_NOMEMORY); - - ISC_LIST_APPEND(msg->scratchpad, dynbuf, link); - return (ISC_R_SUCCESS); -} - -static inline isc_buffer_t * -currentbuffer(dns_message_t *msg) { - isc_buffer_t *dynbuf; - - dynbuf = ISC_LIST_TAIL(msg->scratchpad); - INSIST(dynbuf != NULL); - - return (dynbuf); -} - -static inline void -releaserdata(dns_message_t *msg, dns_rdata_t *rdata) { - ISC_LIST_PREPEND(msg->freerdata, rdata, link); -} - -static inline dns_rdata_t * -newrdata(dns_message_t *msg) { - dns_msgblock_t *msgblock; - dns_rdata_t *rdata; - - rdata = ISC_LIST_HEAD(msg->freerdata); - if (rdata != NULL) { - ISC_LIST_UNLINK(msg->freerdata, rdata, link); - return (rdata); - } - - msgblock = ISC_LIST_TAIL(msg->rdatas); - rdata = msgblock_get(msgblock, dns_rdata_t); - if (rdata == NULL) { - msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t), - RDATA_COUNT); - if (msgblock == NULL) - return (NULL); - - ISC_LIST_APPEND(msg->rdatas, msgblock, link); - - rdata = msgblock_get(msgblock, dns_rdata_t); - } - - dns_rdata_init(rdata); - return (rdata); -} - -static inline void -releaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) { - ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link); -} - -static inline dns_rdatalist_t * -newrdatalist(dns_message_t *msg) { - dns_msgblock_t *msgblock; - dns_rdatalist_t *rdatalist; - - rdatalist = ISC_LIST_HEAD(msg->freerdatalist); - if (rdatalist != NULL) { - ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link); - goto out; - } - - msgblock = ISC_LIST_TAIL(msg->rdatalists); - rdatalist = msgblock_get(msgblock, dns_rdatalist_t); - if (rdatalist == NULL) { - msgblock = msgblock_allocate(msg->mctx, - sizeof(dns_rdatalist_t), - RDATALIST_COUNT); - if (msgblock == NULL) - return (NULL); - - ISC_LIST_APPEND(msg->rdatalists, msgblock, link); - - rdatalist = msgblock_get(msgblock, dns_rdatalist_t); - } - out: - if (rdatalist != NULL) - dns_rdatalist_init(rdatalist); - - return (rdatalist); -} - -static inline dns_offsets_t * -newoffsets(dns_message_t *msg) { - dns_msgblock_t *msgblock; - dns_offsets_t *offsets; - - msgblock = ISC_LIST_TAIL(msg->offsets); - offsets = msgblock_get(msgblock, dns_offsets_t); - if (offsets == NULL) { - msgblock = msgblock_allocate(msg->mctx, - sizeof(dns_offsets_t), - OFFSET_COUNT); - if (msgblock == NULL) - return (NULL); - - ISC_LIST_APPEND(msg->offsets, msgblock, link); - - offsets = msgblock_get(msgblock, dns_offsets_t); - } - - return (offsets); -} - -static inline void -msginitheader(dns_message_t *m) { - m->id = 0; - m->flags = 0; - m->rcode = 0; - m->opcode = 0; - m->rdclass = 0; -} - -static inline void -msginitprivate(dns_message_t *m) { - unsigned int i; - - for (i = 0; i < DNS_SECTION_MAX; i++) { - m->cursors[i] = NULL; - m->counts[i] = 0; - } - m->opt = NULL; - m->sig0 = NULL; - m->sig0name = NULL; - m->tsig = NULL; - 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; -} - -static inline void -msginittsig(dns_message_t *m) { - m->tsigstatus = dns_rcode_noerror; - m->querytsigstatus = dns_rcode_noerror; - m->tsigkey = NULL; - m->tsigctx = NULL; - m->sigstart = -1; - m->sig0key = NULL; - m->sig0status = dns_rcode_noerror; - m->timeadjust = 0; -} - -/* - * Init elements to default state. Used both when allocating a new element - * and when resetting one. - */ -static inline void -msginit(dns_message_t *m) { - msginitheader(m); - msginitprivate(m); - msginittsig(m); - m->header_ok = 0; - m->question_ok = 0; - m->tcp_continuation = 0; - m->verified_sig = 0; - m->verify_attempted = 0; - m->order = NULL; - m->order_arg = NULL; - m->query.base = NULL; - m->query.length = 0; - m->free_query = 0; - m->saved.base = NULL; - m->saved.length = 0; - m->free_saved = 0; - m->cc_ok = 0; - m->cc_bad = 0; - m->tkey = 0; - m->rdclass_set = 0; - m->querytsig = NULL; - m->indent.string = dns_master_indentstr; - m->indent.count = dns_master_indent; -} - -static inline void -msgresetnames(dns_message_t *msg, unsigned int first_section) { - unsigned int i; - dns_name_t *name, *next_name; - dns_rdataset_t *rds, *next_rds; - - /* - * Clean up name lists by calling the rdataset disassociate function. - */ - for (i = first_section; i < DNS_SECTION_MAX; i++) { - name = ISC_LIST_HEAD(msg->sections[i]); - while (name != NULL) { - next_name = ISC_LIST_NEXT(name, link); - ISC_LIST_UNLINK(msg->sections[i], name, link); - - rds = ISC_LIST_HEAD(name->list); - while (rds != NULL) { - next_rds = ISC_LIST_NEXT(rds, link); - ISC_LIST_UNLINK(name->list, rds, link); - - INSIST(dns_rdataset_isassociated(rds)); - dns_rdataset_disassociate(rds); - isc_mempool_put(msg->rdspool, rds); - rds = next_rds; - } - if (dns_name_dynamic(name)) - dns_name_free(name, msg->mctx); - isc_mempool_put(msg->namepool, name); - name = next_name; - } - } -} - -static void -msgresetopt(dns_message_t *msg) -{ - if (msg->opt != NULL) { - if (msg->opt_reserved > 0) { - dns_message_renderrelease(msg, msg->opt_reserved); - msg->opt_reserved = 0; - } - INSIST(dns_rdataset_isassociated(msg->opt)); - dns_rdataset_disassociate(msg->opt); - isc_mempool_put(msg->rdspool, msg->opt); - msg->opt = NULL; - msg->cc_ok = 0; - msg->cc_bad = 0; - } -} - -static void -msgresetsigs(dns_message_t *msg, bool replying) { - if (msg->sig_reserved > 0) { - dns_message_renderrelease(msg, msg->sig_reserved); - msg->sig_reserved = 0; - } - if (msg->tsig != NULL) { - INSIST(dns_rdataset_isassociated(msg->tsig)); - INSIST(msg->namepool != NULL); - if (replying) { - INSIST(msg->querytsig == NULL); - msg->querytsig = msg->tsig; - } else { - dns_rdataset_disassociate(msg->tsig); - isc_mempool_put(msg->rdspool, msg->tsig); - if (msg->querytsig != NULL) { - dns_rdataset_disassociate(msg->querytsig); - isc_mempool_put(msg->rdspool, msg->querytsig); - } - } - if (dns_name_dynamic(msg->tsigname)) - dns_name_free(msg->tsigname, msg->mctx); - isc_mempool_put(msg->namepool, msg->tsigname); - msg->tsig = NULL; - msg->tsigname = NULL; - } else if (msg->querytsig != NULL && !replying) { - dns_rdataset_disassociate(msg->querytsig); - isc_mempool_put(msg->rdspool, msg->querytsig); - msg->querytsig = NULL; - } - if (msg->sig0 != NULL) { - INSIST(dns_rdataset_isassociated(msg->sig0)); - dns_rdataset_disassociate(msg->sig0); - isc_mempool_put(msg->rdspool, msg->sig0); - if (msg->sig0name != NULL) { - if (dns_name_dynamic(msg->sig0name)) - dns_name_free(msg->sig0name, msg->mctx); - isc_mempool_put(msg->namepool, msg->sig0name); - } - msg->sig0 = NULL; - msg->sig0name = NULL; - } -} - -/* - * Free all but one (or everything) for this message. This is used by - * both dns_message_reset() and dns__message_destroy(). - */ -static void -msgreset(dns_message_t *msg, bool everything) { - dns_msgblock_t *msgblock, *next_msgblock; - isc_buffer_t *dynbuf, *next_dynbuf; - dns_rdata_t *rdata; - dns_rdatalist_t *rdatalist; - - msgresetnames(msg, 0); - msgresetopt(msg); - msgresetsigs(msg, false); - - /* - * Clean up linked lists. - */ - - /* - * Run through the free lists, and just unlink anything found there. - * The memory isn't lost since these are part of message blocks we - * have allocated. - */ - rdata = ISC_LIST_HEAD(msg->freerdata); - while (rdata != NULL) { - ISC_LIST_UNLINK(msg->freerdata, rdata, link); - rdata = ISC_LIST_HEAD(msg->freerdata); - } - rdatalist = ISC_LIST_HEAD(msg->freerdatalist); - while (rdatalist != NULL) { - ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link); - rdatalist = ISC_LIST_HEAD(msg->freerdatalist); - } - - dynbuf = ISC_LIST_HEAD(msg->scratchpad); - INSIST(dynbuf != NULL); - if (!everything) { - isc_buffer_clear(dynbuf); - dynbuf = ISC_LIST_NEXT(dynbuf, link); - } - while (dynbuf != NULL) { - next_dynbuf = ISC_LIST_NEXT(dynbuf, link); - ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link); - isc_buffer_free(&dynbuf); - dynbuf = next_dynbuf; - } - - msgblock = ISC_LIST_HEAD(msg->rdatas); - if (!everything && msgblock != NULL) { - msgblock_reset(msgblock); - msgblock = ISC_LIST_NEXT(msgblock, link); - } - while (msgblock != NULL) { - next_msgblock = ISC_LIST_NEXT(msgblock, link); - ISC_LIST_UNLINK(msg->rdatas, msgblock, link); - msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t)); - msgblock = next_msgblock; - } - - /* - * rdatalists could be empty. - */ - - msgblock = ISC_LIST_HEAD(msg->rdatalists); - if (!everything && msgblock != NULL) { - msgblock_reset(msgblock); - msgblock = ISC_LIST_NEXT(msgblock, link); - } - while (msgblock != NULL) { - next_msgblock = ISC_LIST_NEXT(msgblock, link); - ISC_LIST_UNLINK(msg->rdatalists, msgblock, link); - msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t)); - msgblock = next_msgblock; - } - - msgblock = ISC_LIST_HEAD(msg->offsets); - if (!everything && msgblock != NULL) { - msgblock_reset(msgblock); - msgblock = ISC_LIST_NEXT(msgblock, link); - } - while (msgblock != NULL) { - next_msgblock = ISC_LIST_NEXT(msgblock, link); - ISC_LIST_UNLINK(msg->offsets, msgblock, link); - msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t)); - msgblock = next_msgblock; - } - - if (msg->tsigkey != NULL) { - dns_tsigkey_detach(&msg->tsigkey); - msg->tsigkey = NULL; - } - - if (msg->tsigctx != NULL) - dst_context_destroy(&msg->tsigctx); - - if (msg->query.base != NULL) { - if (msg->free_query != 0) - isc_mem_put(msg->mctx, msg->query.base, - msg->query.length); - msg->query.base = NULL; - msg->query.length = 0; - } - - if (msg->saved.base != NULL) { - if (msg->free_saved != 0) - isc_mem_put(msg->mctx, msg->saved.base, - msg->saved.length); - msg->saved.base = NULL; - msg->saved.length = 0; - } - - /* - * cleanup the buffer cleanup list - */ - dynbuf = ISC_LIST_HEAD(msg->cleanup); - while (dynbuf != NULL) { - next_dynbuf = ISC_LIST_NEXT(dynbuf, link); - ISC_LIST_UNLINK(msg->cleanup, dynbuf, link); - isc_buffer_free(&dynbuf); - dynbuf = next_dynbuf; - } - - /* - * Set other bits to normal default values. - */ - if (!everything) - msginit(msg); - - ENSURE(isc_mempool_getallocated(msg->namepool) == 0); - ENSURE(isc_mempool_getallocated(msg->rdspool) == 0); -} - -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 - * 2 bytes for the rdlength - * n2 bytes for the algorithm name - * 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) - * --------------------------------- - * 26 + 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 (26 + r1.length + r2.length + x + otherlen); -} - -isc_result_t -dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) -{ - dns_message_t *m; - isc_result_t result; - isc_buffer_t *dynbuf; - unsigned int i; - - REQUIRE(mctx != NULL); - REQUIRE(msgp != NULL); - REQUIRE(*msgp == NULL); - REQUIRE(intent == DNS_MESSAGE_INTENTPARSE - || intent == DNS_MESSAGE_INTENTRENDER); - - m = isc_mem_get(mctx, sizeof(dns_message_t)); - if (m == NULL) - return (ISC_R_NOMEMORY); - - /* - * No allocations until further notice. Just initialize all lists - * and other members that are freed in the cleanup phase here. - */ - - m->magic = DNS_MESSAGE_MAGIC; - m->from_to_wire = intent; - msginit(m); - - for (i = 0; i < DNS_SECTION_MAX; i++) - ISC_LIST_INIT(m->sections[i]); - - m->mctx = NULL; - isc_mem_attach(mctx, &m->mctx); - - ISC_LIST_INIT(m->scratchpad); - ISC_LIST_INIT(m->cleanup); - m->namepool = NULL; - m->rdspool = NULL; - ISC_LIST_INIT(m->rdatas); - ISC_LIST_INIT(m->rdatalists); - ISC_LIST_INIT(m->offsets); - ISC_LIST_INIT(m->freerdata); - ISC_LIST_INIT(m->freerdatalist); - - /* - * Ok, it is safe to allocate (and then "goto cleanup" if failure) - */ - - result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_mempool_setfillcount(m->namepool, NAME_COUNT); - isc_mempool_setfreemax(m->namepool, NAME_COUNT); - isc_mempool_setname(m->namepool, "msg:names"); - - result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t), - &m->rdspool); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_mempool_setfillcount(m->rdspool, RDATASET_COUNT); - isc_mempool_setfreemax(m->rdspool, RDATASET_COUNT); - isc_mempool_setname(m->rdspool, "msg:rdataset"); - - dynbuf = NULL; - result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(m->scratchpad, dynbuf, link); - - m->cctx = NULL; - - isc_refcount_init(&m->refcount, 1); - - *msgp = m; - return (ISC_R_SUCCESS); - - /* - * Cleanup for error returns. - */ - cleanup: - dynbuf = ISC_LIST_HEAD(m->scratchpad); - if (dynbuf != NULL) { - ISC_LIST_UNLINK(m->scratchpad, dynbuf, link); - isc_buffer_free(&dynbuf); - } - if (m->namepool != NULL) - isc_mempool_destroy(&m->namepool); - if (m->rdspool != NULL) - isc_mempool_destroy(&m->rdspool); - m->magic = 0; - isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t)); - - return (ISC_R_NOMEMORY); -} - -void -dns_message_reset(dns_message_t *msg, unsigned int intent) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(intent == DNS_MESSAGE_INTENTPARSE - || intent == DNS_MESSAGE_INTENTRENDER); - - msgreset(msg, false); - msg->from_to_wire = intent; -} - -static void -dns__message_destroy(dns_message_t *msg) { - REQUIRE(msg != NULL); - REQUIRE(DNS_MESSAGE_VALID(msg)); - - msgreset(msg, true); - isc_mempool_destroy(&msg->namepool); - isc_mempool_destroy(&msg->rdspool); - isc_refcount_destroy(&msg->refcount); - msg->magic = 0; - isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t)); -} - -void -dns_message_attach(dns_message_t *source, dns_message_t **target) { - REQUIRE(DNS_MESSAGE_VALID(source)); - - isc_refcount_increment(&source->refcount, NULL); - *target = source; -} - -void -dns_message_detach(dns_message_t **messagep) { - REQUIRE(messagep != NULL && DNS_MESSAGE_VALID(*messagep)); - dns_message_t *msg = *messagep; - *messagep = NULL; - int32_t refs; - - isc_refcount_decrement(&msg->refcount, &refs); - if (refs == 0) { - dns__message_destroy(msg); - } -} - -static isc_result_t -findname(dns_name_t **foundname, dns_name_t *target, - dns_namelist_t *section) -{ - dns_name_t *curr; - - for (curr = ISC_LIST_TAIL(*section); - curr != NULL; - curr = ISC_LIST_PREV(curr, link)) { - if (dns_name_equal(curr, target)) { - if (foundname != NULL) - *foundname = curr; - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, - dns_rdatatype_t type, dns_rdatatype_t covers, - dns_rdataset_t **rdataset) -{ - dns_rdataset_t *curr; - - REQUIRE(name != NULL); - REQUIRE(rdataset == NULL || *rdataset == NULL); - - for (curr = ISC_LIST_TAIL(name->list); - curr != NULL; - curr = ISC_LIST_PREV(curr, link)) { - if (curr->rdclass == rdclass && - curr->type == type && curr->covers == covers) { - if (rdataset != NULL) - *rdataset = curr; - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, - dns_rdatatype_t covers, dns_rdataset_t **rdataset) -{ - dns_rdataset_t *curr; - - REQUIRE(name != NULL); - REQUIRE(rdataset == NULL || *rdataset == NULL); - - for (curr = ISC_LIST_TAIL(name->list); - curr != NULL; - curr = ISC_LIST_PREV(curr, link)) { - if (curr->type == type && curr->covers == covers) { - if (ISC_UNLIKELY(rdataset != NULL)) - *rdataset = curr; - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_NOTFOUND); -} - -/* - * Read a name from buffer "source". - */ -static isc_result_t -getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg, - dns_decompress_t *dctx) -{ - isc_buffer_t *scratch; - isc_result_t result; - unsigned int tries; - - scratch = currentbuffer(msg); - - /* - * First try: use current buffer. - * Second try: allocate a new buffer and use that. - */ - tries = 0; - while (tries < 2) { - result = dns_name_fromwire(name, source, dctx, 0, - scratch); - - if (result == ISC_R_NOSPACE) { - tries++; - - result = newbuffer(msg, SCRATCHPAD_SIZE); - if (result != ISC_R_SUCCESS) - return (result); - - scratch = currentbuffer(msg); - dns_name_reset(name); - } else { - return (result); - } - } - - INSIST(0); - ISC_UNREACHABLE(); -} - -static isc_result_t -getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, - dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, - unsigned int rdatalen, dns_rdata_t *rdata) -{ - isc_buffer_t *scratch; - isc_result_t result; - unsigned int tries; - unsigned int trysize; - - scratch = currentbuffer(msg); - - isc_buffer_setactive(source, rdatalen); - - /* - * First try: use current buffer. - * Second try: allocate a new buffer of size - * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen) - * (the data will fit if it was not more than 50% compressed) - * Subsequent tries: double buffer size on each try. - */ - tries = 0; - trysize = 0; - /* XXX possibly change this to a while (tries < 2) loop */ - for (;;) { - result = dns_rdata_fromwire(rdata, rdclass, rdtype, - source, dctx, 0, - scratch); - - if (result == ISC_R_NOSPACE) { - if (tries == 0) { - trysize = 2 * rdatalen; - if (trysize < SCRATCHPAD_SIZE) - trysize = SCRATCHPAD_SIZE; - } else { - INSIST(trysize != 0); - if (trysize >= 65535) - return (ISC_R_NOSPACE); - /* XXX DNS_R_RRTOOLONG? */ - trysize *= 2; - } - tries++; - result = newbuffer(msg, trysize); - if (result != ISC_R_SUCCESS) - return (result); - - scratch = currentbuffer(msg); - } else { - return (result); - } - } -} - -#define DO_ERROR(r) \ - do { \ - if (best_effort) \ - seen_problem = true; \ - else { \ - result = r; \ - goto cleanup; \ - } \ - } while (0) - -static isc_result_t -getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, - unsigned int options) -{ - isc_region_t r; - unsigned int count; - dns_name_t *name; - dns_name_t *name2; - dns_offsets_t *offsets; - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - isc_result_t result; - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - dns_namelist_t *section; - bool free_name; - bool best_effort; - bool seen_problem; - - section = &msg->sections[DNS_SECTION_QUESTION]; - - best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); - seen_problem = false; - - name = NULL; - rdataset = NULL; - rdatalist = NULL; - - for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) { - name = isc_mempool_get(msg->namepool); - if (name == NULL) - return (ISC_R_NOMEMORY); - free_name = true; - - offsets = newoffsets(msg); - if (offsets == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - dns_name_init(name, *offsets); - - /* - * Parse the name out of this packet. - */ - isc_buffer_remainingregion(source, &r); - isc_buffer_setactive(source, r.length); - result = getname(name, source, msg, dctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Run through the section, looking to see if this name - * is already there. If it is found, put back the allocated - * name since we no longer need it, and set our name pointer - * to point to the name we found. - */ - result = findname(&name2, name, section); - - /* - * If it is the first name in the section, accept it. - * - * If it is not, but is not the same as the name already - * in the question section, append to the section. Note that - * here in the question section this is illegal, so return - * FORMERR. In the future, check the opcode to see if - * this should be legal or not. In either case we no longer - * need this name pointer. - */ - if (result != ISC_R_SUCCESS) { - if (!ISC_LIST_EMPTY(*section)) - DO_ERROR(DNS_R_FORMERR); - ISC_LIST_APPEND(*section, name, link); - free_name = false; - } else { - isc_mempool_put(msg->namepool, name); - name = name2; - name2 = NULL; - free_name = false; - } - - /* - * Get type and class. - */ - isc_buffer_remainingregion(source, &r); - if (r.length < 4) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - rdtype = isc_buffer_getuint16(source); - rdclass = isc_buffer_getuint16(source); - - /* - * If this class is different than the one we already read, - * this is an error. - */ - if (msg->rdclass_set == 0) { - msg->rdclass = rdclass; - msg->rdclass_set = 1; - } else if (msg->rdclass != rdclass) - DO_ERROR(DNS_R_FORMERR); - - /* - * Is this a TKEY query? - */ - if (rdtype == dns_rdatatype_tkey) - msg->tkey = 1; - - /* - * Can't ask the same question twice. - */ - result = dns_message_find(name, rdclass, rdtype, 0, NULL); - if (result == ISC_R_SUCCESS) - DO_ERROR(DNS_R_FORMERR); - - /* - * Allocate a new rdatalist. - */ - rdatalist = newrdatalist(msg); - if (rdatalist == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - rdataset = isc_mempool_get(msg->rdspool); - if (rdataset == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - /* - * Convert rdatalist to rdataset, and attach the latter to - * the name. - */ - rdatalist->type = rdtype; - rdatalist->rdclass = rdclass; - - dns_rdataset_init(rdataset); - result = dns_rdatalist_tordataset(rdatalist, rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rdataset->attributes |= DNS_RDATASETATTR_QUESTION; - - ISC_LIST_APPEND(name->list, rdataset, link); - rdataset = NULL; - } - - if (seen_problem) - return (DNS_R_RECOVERABLE); - return (ISC_R_SUCCESS); - - cleanup: - if (rdataset != NULL) { - INSIST(!dns_rdataset_isassociated(rdataset)); - isc_mempool_put(msg->rdspool, rdataset); - } -#if 0 - if (rdatalist != NULL) - isc_mempool_put(msg->rdlpool, rdatalist); -#endif - if (free_name) - isc_mempool_put(msg->namepool, name); - - return (result); -} - -static bool -update(dns_section_t section, dns_rdataclass_t rdclass) { - if (section == DNS_SECTION_PREREQUISITE) - return (rdclass == dns_rdataclass_any || - rdclass == dns_rdataclass_none); - if (section == DNS_SECTION_UPDATE) - return (rdclass == dns_rdataclass_any); - return (false); -} - -/* - * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have - * covering RRSIGs. - */ -static bool -auth_signed(dns_namelist_t *section) { - dns_name_t *name; - - for (name = ISC_LIST_HEAD(*section); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - { - int auth_dnssec = 0, auth_rrsig = 0; - dns_rdataset_t *rds; - - for (rds = ISC_LIST_HEAD(name->list); - rds != NULL; - rds = ISC_LIST_NEXT(rds, link)) - { - switch (rds->type) { - case dns_rdatatype_ds: - auth_dnssec |= 0x1; - break; - case dns_rdatatype_nsec: - auth_dnssec |= 0x2; - break; - case dns_rdatatype_nsec3: - auth_dnssec |= 0x4; - break; - case dns_rdatatype_rrsig: - break; - default: - continue; - } - - switch (rds->covers) { - case dns_rdatatype_ds: - auth_rrsig |= 0x1; - break; - case dns_rdatatype_nsec: - auth_rrsig |= 0x2; - break; - case dns_rdatatype_nsec3: - auth_rrsig |= 0x4; - break; - default: - break; - } - } - - if (auth_dnssec != auth_rrsig) - return (false); - } - - return (true); -} - -static isc_result_t -getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, - dns_section_t sectionid, unsigned int options) -{ - isc_region_t r; - unsigned int count, rdatalen; - dns_name_t *name = NULL; - dns_name_t *name2 = NULL; - dns_offsets_t *offsets; - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - isc_result_t result; - dns_rdatatype_t rdtype, covers; - dns_rdataclass_t rdclass; - dns_rdata_t *rdata; - dns_ttl_t ttl; - dns_namelist_t *section; - bool free_name = false, free_rdataset = false; - bool preserve_order, best_effort, seen_problem; - bool isedns, issigzero, istsig; - - preserve_order = ((options & DNS_MESSAGEPARSE_PRESERVEORDER) != 0); - best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); - seen_problem = false; - - section = &msg->sections[sectionid]; - - for (count = 0; count < msg->counts[sectionid]; count++) { - int recstart = source->current; - bool skip_name_search, skip_type_search; - - skip_name_search = false; - skip_type_search = false; - free_rdataset = false; - isedns = false; - issigzero = false; - istsig = false; - - name = isc_mempool_get(msg->namepool); - if (name == NULL) - return (ISC_R_NOMEMORY); - free_name = true; - - offsets = newoffsets(msg); - if (offsets == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - dns_name_init(name, *offsets); - - /* - * Parse the name out of this packet. - */ - isc_buffer_remainingregion(source, &r); - isc_buffer_setactive(source, r.length); - result = getname(name, source, msg, dctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Get type, class, ttl, and rdatalen. Verify that at least - * rdatalen bytes remain. (Some of this is deferred to - * later.) - */ - isc_buffer_remainingregion(source, &r); - if (r.length < 2 + 2 + 4 + 2) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - rdtype = isc_buffer_getuint16(source); - rdclass = isc_buffer_getuint16(source); - - /* - * If there was no question section, we may not yet have - * established a class. Do so now. - */ - if (msg->rdclass_set == 0 && - rdtype != dns_rdatatype_opt && /* class is UDP SIZE */ - rdtype != dns_rdatatype_tsig && /* class is ANY */ - rdtype != dns_rdatatype_tkey) { /* class is undefined */ - msg->rdclass = rdclass; - msg->rdclass_set = 1; - } - - /* - * If this class is different than the one in the question - * section, bail. - */ - if (msg->opcode != dns_opcode_update - && rdtype != dns_rdatatype_tsig - && rdtype != dns_rdatatype_opt - && rdtype != dns_rdatatype_key /* in a TKEY query */ - && rdtype != dns_rdatatype_sig /* SIG(0) */ - && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */ - && msg->rdclass != dns_rdataclass_any - && msg->rdclass != rdclass) - DO_ERROR(DNS_R_FORMERR); - - /* - * If this is not a TKEY query/response then the KEY - * record's class needs to match. - */ - if (msg->opcode != dns_opcode_update && !msg->tkey && - rdtype == dns_rdatatype_key && - msg->rdclass != dns_rdataclass_any && - msg->rdclass != rdclass) - DO_ERROR(DNS_R_FORMERR); - - /* - * Special type handling for TSIG, OPT, and TKEY. - */ - if (rdtype == dns_rdatatype_tsig) { - /* - * If it is a tsig, verify that it is in the - * additional data section. - */ - if (sectionid != DNS_SECTION_ADDITIONAL || - rdclass != dns_rdataclass_any || - count != msg->counts[sectionid] - 1) { - DO_ERROR(DNS_R_BADTSIG); - } else { - skip_name_search = true; - skip_type_search = true; - istsig = true; - } - } else if (rdtype == dns_rdatatype_opt) { - /* - * The name of an OPT record must be ".", it - * must be in the additional data section, and - * it must be the first OPT we've seen. - */ - if (!dns_name_equal(dns_rootname, name) || - sectionid != DNS_SECTION_ADDITIONAL || - msg->opt != NULL) { - DO_ERROR(DNS_R_FORMERR); - } else { - skip_name_search = true; - skip_type_search = true; - isedns = true; - } - } else if (rdtype == dns_rdatatype_tkey) { - /* - * A TKEY must be in the additional section if this - * is a query, and the answer section if this is a - * response. Unless it's a Win2000 client. - * - * Its class is ignored. - */ - dns_section_t tkeysection; - - if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0) - tkeysection = DNS_SECTION_ADDITIONAL; - else - tkeysection = DNS_SECTION_ANSWER; - if (sectionid != tkeysection && - sectionid != DNS_SECTION_ANSWER) - DO_ERROR(DNS_R_FORMERR); - } - - /* - * ... now get ttl and rdatalen, and check buffer. - */ - ttl = isc_buffer_getuint32(source); - rdatalen = isc_buffer_getuint16(source); - r.length -= (2 + 2 + 4 + 2); - if (r.length < rdatalen) { - result = ISC_R_UNEXPECTEDEND; - goto cleanup; - } - - /* - * Read the rdata from the wire format. Interpret the - * rdata according to its actual class, even if it had a - * DynDNS meta-class in the packet (unless this is a TSIG). - * Then put the meta-class back into the finished rdata. - */ - rdata = newrdata(msg); - if (rdata == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - if (msg->opcode == dns_opcode_update && - update(sectionid, rdclass)) { - if (rdatalen != 0) { - result = DNS_R_FORMERR; - goto cleanup; - } - /* - * When the rdata is empty, the data pointer is - * never dereferenced, but it must still be non-NULL. - * Casting 1 rather than "" avoids warnings about - * discarding the const attribute of a string, - * for compilers that would warn about such things. - */ - rdata->data = (unsigned char *)1; - rdata->length = 0; - rdata->rdclass = rdclass; - rdata->type = rdtype; - rdata->flags = DNS_RDATA_UPDATE; - result = ISC_R_SUCCESS; - } else if (rdclass == dns_rdataclass_none && - msg->opcode == dns_opcode_update && - sectionid == DNS_SECTION_UPDATE) { - result = getrdata(source, msg, dctx, msg->rdclass, - rdtype, rdatalen, rdata); - } else - result = getrdata(source, msg, dctx, rdclass, - rdtype, rdatalen, rdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - rdata->rdclass = rdclass; - if (rdtype == dns_rdatatype_rrsig && - rdata->flags == 0) { - covers = dns_rdata_covers(rdata); - if (covers == 0) - DO_ERROR(DNS_R_FORMERR); - } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ && - rdata->flags == 0) { - covers = dns_rdata_covers(rdata); - if (covers == 0) { - if (sectionid != DNS_SECTION_ADDITIONAL || - count != msg->counts[sectionid] - 1) { - DO_ERROR(DNS_R_BADSIG0); - } else { - skip_name_search = true; - skip_type_search = true; - issigzero = true; - } - } else { - if (msg->rdclass != dns_rdataclass_any && - msg->rdclass != rdclass) - DO_ERROR(DNS_R_FORMERR); - } - } else - covers = 0; - - /* - * Check the ownername of NSEC3 records - */ - if (rdtype == dns_rdatatype_nsec3 && - !dns_rdata_checkowner(name, msg->rdclass, rdtype, - false)) { - result = DNS_R_BADOWNERNAME; - goto cleanup; - } - - /* - * If we are doing a dynamic update or this is a meta-type, - * don't bother searching for a name, just append this one - * to the end of the message. - */ - if (preserve_order || msg->opcode == dns_opcode_update || - skip_name_search) { - if (!isedns && !istsig && !issigzero) { - ISC_LIST_APPEND(*section, name, link); - free_name = false; - } - } else { - /* - * Run through the section, looking to see if this name - * is already there. If it is found, put back the - * allocated name since we no longer need it, and set - * our name pointer to point to the name we found. - */ - result = findname(&name2, name, section); - - /* - * If it is a new name, append to the section. - */ - if (result == ISC_R_SUCCESS) { - isc_mempool_put(msg->namepool, name); - name = name2; - } else { - ISC_LIST_APPEND(*section, name, link); - } - free_name = false; - } - - /* - * Search name for the particular type and class. - * Skip this stage if in update mode or this is a meta-type. - */ - if (preserve_order || msg->opcode == dns_opcode_update || - skip_type_search) - result = ISC_R_NOTFOUND; - else { - /* - * If this is a type that can only occur in - * the question section, fail. - */ - if (dns_rdatatype_questiononly(rdtype)) - DO_ERROR(DNS_R_FORMERR); - - rdataset = NULL; - result = dns_message_find(name, rdclass, rdtype, - covers, &rdataset); - } - - /* - * If we found an rdataset that matches, we need to - * append this rdata to that set. If we did not, we need - * to create a new rdatalist, store the important bits there, - * convert it to an rdataset, and link the latter to the name. - * Yuck. When appending, make certain that the type isn't - * a singleton type, such as SOA or CNAME. - * - * Note that this check will be bypassed when preserving order, - * the opcode is an update, or the type search is skipped. - */ - if (result == ISC_R_SUCCESS) { - if (dns_rdatatype_issingleton(rdtype)) { - dns_rdata_t *first; - dns_rdatalist_fromrdataset(rdataset, - &rdatalist); - first = ISC_LIST_HEAD(rdatalist->rdata); - INSIST(first != NULL); - if (dns_rdata_compare(rdata, first) != 0) - DO_ERROR(DNS_R_FORMERR); - } - } - - if (result == ISC_R_NOTFOUND) { - rdataset = isc_mempool_get(msg->rdspool); - if (rdataset == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - free_rdataset = true; - - rdatalist = newrdatalist(msg); - if (rdatalist == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - rdatalist->type = rdtype; - rdatalist->covers = covers; - rdatalist->rdclass = rdclass; - rdatalist->ttl = ttl; - - dns_rdataset_init(rdataset); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, - rdataset) - == ISC_R_SUCCESS); - dns_rdataset_setownercase(rdataset, name); - - if (!isedns && !istsig && !issigzero) { - ISC_LIST_APPEND(name->list, rdataset, link); - free_rdataset = false; - } - } - - /* - * Minimize TTLs. - * - * Section 5.2 of RFC2181 says we should drop - * nonauthoritative rrsets where the TTLs differ, but we - * currently treat them the as if they were authoritative and - * minimize them. - */ - if (ttl != rdataset->ttl) { - rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED; - if (ttl < rdataset->ttl) - rdataset->ttl = ttl; - } - - /* Append this rdata to the rdataset. */ - dns_rdatalist_fromrdataset(rdataset, &rdatalist); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - - /* - * If this is an OPT, SIG(0) or TSIG record, remember it. - * Also, set the extended rcode for TSIG. - * - * Note msg->opt, msg->sig0 and msg->tsig will only be - * already set if best-effort parsing is enabled otherwise - * there will only be at most one of each. - */ - if (isedns) { - dns_rcode_t ercode; - - msg->opt = rdataset; - rdataset = NULL; - free_rdataset = false; - ercode = (dns_rcode_t) - ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK) - >> 20); - msg->rcode |= ercode; - isc_mempool_put(msg->namepool, name); - free_name = false; - } else if (issigzero) { - msg->sig0 = rdataset; - msg->sig0name = name; - msg->sigstart = recstart; - rdataset = NULL; - free_rdataset = false; - free_name = false; - } else if (istsig) { - msg->tsig = rdataset; - msg->tsigname = name; - msg->sigstart = recstart; - /* - * Windows doesn't like TSIG names to be compressed. - */ - msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; - rdataset = NULL; - free_rdataset = false; - free_name = false; - } - - if (seen_problem) { - if (free_name) - isc_mempool_put(msg->namepool, name); - if (free_rdataset) - isc_mempool_put(msg->rdspool, rdataset); - free_name = free_rdataset = false; - } - INSIST(free_name == false); - INSIST(free_rdataset == false); - } - - /* - * If any of DS, NSEC or NSEC3 appeared in the - * authority section of a query response without - * a covering RRSIG, FORMERR - */ - if (sectionid == DNS_SECTION_AUTHORITY && - msg->opcode == dns_opcode_query && - ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) && - ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && - !preserve_order && - !auth_signed(section)) - DO_ERROR(DNS_R_FORMERR); - - if (seen_problem) - return (DNS_R_RECOVERABLE); - return (ISC_R_SUCCESS); - - cleanup: - if (free_name) - isc_mempool_put(msg->namepool, name); - if (free_rdataset) - isc_mempool_put(msg->rdspool, rdataset); - - return (result); -} - -isc_result_t -dns_message_parse(dns_message_t *msg, isc_buffer_t *source, - unsigned int options) -{ - isc_region_t r; - dns_decompress_t dctx; - isc_result_t ret; - uint16_t tmpflags; - isc_buffer_t origsource; - bool seen_problem; - bool ignore_tc; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(source != NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); - - seen_problem = false; - ignore_tc = ((options & DNS_MESSAGEPARSE_IGNORETRUNCATION) != 0); - - origsource = *source; - - msg->header_ok = 0; - msg->question_ok = 0; - - if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) { - isc_buffer_usedregion(&origsource, &msg->saved); - } else { - msg->saved.length = isc_buffer_usedlength(&origsource); - msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); - if (msg->saved.base == NULL) { - return (ISC_R_NOMEMORY); - } - memmove(msg->saved.base, isc_buffer_base(&origsource), - msg->saved.length); - msg->free_saved = 1; - } - - isc_buffer_remainingregion(source, &r); - if (r.length < DNS_MESSAGE_HEADERLEN) - return (ISC_R_UNEXPECTEDEND); - - msg->id = isc_buffer_getuint16(source); - tmpflags = isc_buffer_getuint16(source); - msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK) - >> DNS_MESSAGE_OPCODE_SHIFT); - msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK); - msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK); - msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source); - msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source); - msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source); - msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source); - - msg->header_ok = 1; - msg->state = DNS_SECTION_QUESTION; - - /* - * -1 means no EDNS. - */ - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); - - dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14); - - ret = getquestions(source, msg, &dctx, options); - if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) - goto truncated; - if (ret == DNS_R_RECOVERABLE) { - seen_problem = true; - ret = ISC_R_SUCCESS; - } - if (ret != ISC_R_SUCCESS) - return (ret); - msg->question_ok = 1; - - ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options); - if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) - goto truncated; - if (ret == DNS_R_RECOVERABLE) { - seen_problem = true; - ret = ISC_R_SUCCESS; - } - if (ret != ISC_R_SUCCESS) - return (ret); - - ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options); - if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) - goto truncated; - if (ret == DNS_R_RECOVERABLE) { - seen_problem = true; - ret = ISC_R_SUCCESS; - } - if (ret != ISC_R_SUCCESS) - return (ret); - - ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options); - if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) - goto truncated; - if (ret == DNS_R_RECOVERABLE) { - seen_problem = true; - ret = ISC_R_SUCCESS; - } - if (ret != ISC_R_SUCCESS) - return (ret); - - isc_buffer_remainingregion(source, &r); - if (r.length != 0) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MESSAGE, ISC_LOG_DEBUG(3), - "message has %u byte(s) of trailing garbage", - r.length); - } - - truncated: - - if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) - return (DNS_R_RECOVERABLE); - if (seen_problem == true) - return (DNS_R_RECOVERABLE); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, - isc_buffer_t *buffer) -{ - isc_region_t r; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(buffer != NULL); - REQUIRE(msg->buffer == NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - - msg->cctx = cctx; - - /* - * Erase the contents of this buffer. - */ - isc_buffer_clear(buffer); - - /* - * Make certain there is enough for at least the header in this - * buffer. - */ - isc_buffer_availableregion(buffer, &r); - if (r.length < DNS_MESSAGE_HEADERLEN) - return (ISC_R_NOSPACE); - - if (r.length - DNS_MESSAGE_HEADERLEN < msg->reserved) - return (ISC_R_NOSPACE); - - /* - * Reserve enough space for the header in this buffer. - */ - isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN); - - msg->buffer = buffer; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) { - isc_region_t r, rn; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(buffer != NULL); - REQUIRE(msg->buffer != NULL); - - /* - * Ensure that the new buffer is empty, and has enough space to - * hold the current contents. - */ - isc_buffer_clear(buffer); - - isc_buffer_availableregion(buffer, &rn); - isc_buffer_usedregion(msg->buffer, &r); - REQUIRE(rn.length > r.length); - - /* - * Copy the contents from the old to the new buffer. - */ - isc_buffer_add(buffer, r.length); - memmove(rn.base, r.base, r.length); - - msg->buffer = buffer; - - return (ISC_R_SUCCESS); -} - -void -dns_message_renderrelease(dns_message_t *msg, unsigned int space) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(space <= msg->reserved); - - msg->reserved -= space; -} - -isc_result_t -dns_message_renderreserve(dns_message_t *msg, unsigned int space) { - isc_region_t r; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - - if (msg->buffer != NULL) { - isc_buffer_availableregion(msg->buffer, &r); - if (r.length < (space + msg->reserved)) - return (ISC_R_NOSPACE); - } - - msg->reserved += space; - - return (ISC_R_SUCCESS); -} - -static inline bool -wrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) { - int pass_needed; - - /* - * If we are not rendering class IN, this ordering is bogus. - */ - if (rds->rdclass != dns_rdataclass_in) - return (false); - - switch (rds->type) { - case dns_rdatatype_a: - case dns_rdatatype_aaaa: - if (preferred_glue == rds->type) - pass_needed = 4; - else - pass_needed = 3; - break; - case dns_rdatatype_rrsig: - case dns_rdatatype_dnskey: - pass_needed = 2; - break; - default: - pass_needed = 1; - } - - if (pass_needed >= pass) - return (false); - - return (true); -} - -#ifdef ALLOW_FILTER_AAAA -/* - * Decide whether to not answer with an AAAA record and its RRSIG - */ -static inline bool -norender_rdataset(const dns_rdataset_t *rdataset, unsigned int options, - dns_section_t sectionid) -{ - if (sectionid == DNS_SECTION_QUESTION) - return (false); - - switch (rdataset->type) { - case dns_rdatatype_ns: - if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 || - sectionid != DNS_SECTION_AUTHORITY) - return (false); - break; - - case dns_rdatatype_aaaa: - if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0) - return (false); - break; - - case dns_rdatatype_rrsig: - if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 || - (rdataset->covers != dns_rdatatype_ns && - rdataset->covers != dns_rdatatype_aaaa)) - return (false); - if ((rdataset->covers == dns_rdatatype_ns) && - (sectionid != DNS_SECTION_AUTHORITY)) - return (false); - break; - - default: - return (false); - } - - if (rdataset->rdclass != dns_rdataclass_in) - return (false); - - return (true); -} -#endif - -static isc_result_t -renderset(dns_rdataset_t *rdataset, dns_name_t *owner_name, - dns_compress_t *cctx, isc_buffer_t *target, - unsigned int reserved, unsigned int options, unsigned int *countp) -{ - isc_result_t result; - - /* - * Shrink the space in the buffer by the reserved amount. - */ - if (target->length - target->used < reserved) - return (ISC_R_NOSPACE); - - target->length -= reserved; - result = dns_rdataset_towire(rdataset, owner_name, - cctx, target, options, countp); - target->length += reserved; - - return (result); -} - -static void -maybe_clear_ad(dns_message_t *msg, dns_section_t sectionid) { - if (msg->counts[sectionid] == 0 && - (sectionid == DNS_SECTION_ANSWER || - (sectionid == DNS_SECTION_AUTHORITY && - msg->counts[DNS_SECTION_ANSWER] == 0))) - msg->flags &= ~DNS_MESSAGEFLAG_AD; -} - -isc_result_t -dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, - unsigned int options) -{ - dns_namelist_t *section; - dns_name_t *name, *next_name; - dns_rdataset_t *rdataset, *next_rdataset; - unsigned int count, total; - isc_result_t result; - isc_buffer_t st; /* for rollbacks */ - int pass; - bool partial = false; - unsigned int rd_options; - dns_rdatatype_t preferred_glue = 0; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(msg->buffer != NULL); - REQUIRE(VALID_NAMED_SECTION(sectionid)); - - section = &msg->sections[sectionid]; - - if ((sectionid == DNS_SECTION_ADDITIONAL) - && (options & DNS_MESSAGERENDER_ORDERED) == 0) { - if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) { - preferred_glue = dns_rdatatype_a; - pass = 4; - } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) { - preferred_glue = dns_rdatatype_aaaa; - pass = 4; - } else - pass = 3; - } else - pass = 1; - - if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0) - rd_options = 0; - else - rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC; - - /* - * Shrink the space in the buffer by the reserved amount. - */ - if (msg->buffer->length - msg->buffer->used < msg->reserved) - return (ISC_R_NOSPACE); - msg->buffer->length -= msg->reserved; - - total = 0; - if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0) - partial = true; - - /* - * Render required glue first. Set TC if it won't fit. - */ - name = ISC_LIST_HEAD(*section); - if (name != NULL) { - rdataset = ISC_LIST_HEAD(name->list); - if (rdataset != NULL && - (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 && - (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) { - const void *order_arg = msg->order_arg; - st = *(msg->buffer); - count = 0; - if (partial) - result = dns_rdataset_towirepartial(rdataset, - name, - msg->cctx, - msg->buffer, - msg->order, - order_arg, - rd_options, - &count, - NULL); - else - result = dns_rdataset_towiresorted(rdataset, - name, - msg->cctx, - msg->buffer, - msg->order, - order_arg, - rd_options, - &count); - total += count; - if (partial && result == ISC_R_NOSPACE) { - msg->flags |= DNS_MESSAGEFLAG_TC; - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - return (result); - } - if (result == ISC_R_NOSPACE) - msg->flags |= DNS_MESSAGEFLAG_TC; - if (result != ISC_R_SUCCESS) { - INSIST(st.used < 65536); - dns_compress_rollback(msg->cctx, - (uint16_t)st.used); - *(msg->buffer) = st; /* rollback */ - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - return (result); - } - rdataset->attributes |= DNS_RDATASETATTR_RENDERED; - } - } - - do { - name = ISC_LIST_HEAD(*section); - if (name == NULL) { - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - return (ISC_R_SUCCESS); - } - - while (name != NULL) { - next_name = ISC_LIST_NEXT(name, link); - - rdataset = ISC_LIST_HEAD(name->list); - while (rdataset != NULL) { - next_rdataset = ISC_LIST_NEXT(rdataset, link); - - if ((rdataset->attributes & - DNS_RDATASETATTR_RENDERED) != 0) - goto next; - - if (((options & DNS_MESSAGERENDER_ORDERED) - == 0) - && (sectionid == DNS_SECTION_ADDITIONAL) - && wrong_priority(rdataset, pass, - preferred_glue)) - goto next; - -#ifdef ALLOW_FILTER_AAAA - /* - * Suppress AAAAs if asked and we are - * not doing DNSSEC or are breaking DNSSEC. - * Say so in the AD bit if we break DNSSEC. - */ - if (norender_rdataset(rdataset, options, sectionid)) { - if (sectionid == DNS_SECTION_ANSWER || - sectionid == DNS_SECTION_AUTHORITY) - msg->flags &= ~DNS_MESSAGEFLAG_AD; - if (OPTOUT(rdataset)) - msg->flags &= ~DNS_MESSAGEFLAG_AD; - goto next; - } - -#endif - st = *(msg->buffer); - - count = 0; - if (partial) - result = dns_rdataset_towirepartial( - rdataset, - name, - msg->cctx, - msg->buffer, - msg->order, - msg->order_arg, - rd_options, - &count, - NULL); - else - result = dns_rdataset_towiresorted( - rdataset, - name, - msg->cctx, - msg->buffer, - msg->order, - msg->order_arg, - rd_options, - &count); - - total += count; - - /* - * If out of space, record stats on what we - * rendered so far, and return that status. - * - * XXXMLG Need to change this when - * dns_rdataset_towire() can render partial - * sets starting at some arbitrary point in the - * set. This will include setting a bit in the - * rdataset to indicate that a partial - * rendering was done, and some state saved - * somewhere (probably in the message struct) - * to indicate where to continue from. - */ - if (partial && result == ISC_R_NOSPACE) { - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - return (result); - } - if (result != ISC_R_SUCCESS) { - INSIST(st.used < 65536); - dns_compress_rollback(msg->cctx, - (uint16_t)st.used); - *(msg->buffer) = st; /* rollback */ - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - maybe_clear_ad(msg, sectionid); - return (result); - } - - /* - * If we have rendered non-validated data, - * ensure that the AD bit is not set. - */ - if (rdataset->trust != dns_trust_secure && - (sectionid == DNS_SECTION_ANSWER || - sectionid == DNS_SECTION_AUTHORITY)) - msg->flags &= ~DNS_MESSAGEFLAG_AD; - if (OPTOUT(rdataset)) - msg->flags &= ~DNS_MESSAGEFLAG_AD; - - rdataset->attributes |= - DNS_RDATASETATTR_RENDERED; - - next: - rdataset = next_rdataset; - } - - name = next_name; - } - } while (--pass != 0); - - msg->buffer->length += msg->reserved; - msg->counts[sectionid] += total; - - return (ISC_R_SUCCESS); -} - -void -dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) { - uint16_t tmp; - isc_region_t r; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(target != NULL); - - isc_buffer_availableregion(target, &r); - REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN); - - isc_buffer_putuint16(target, msg->id); - - tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT) - & DNS_MESSAGE_OPCODE_MASK); - tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK); - tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK); - - INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 && - msg->counts[DNS_SECTION_ANSWER] < 65536 && - msg->counts[DNS_SECTION_AUTHORITY] < 65536 && - msg->counts[DNS_SECTION_ADDITIONAL] < 65536); - - isc_buffer_putuint16(target, tmp); - isc_buffer_putuint16(target, - (uint16_t)msg->counts[DNS_SECTION_QUESTION]); - isc_buffer_putuint16(target, - (uint16_t)msg->counts[DNS_SECTION_ANSWER]); - isc_buffer_putuint16(target, - (uint16_t)msg->counts[DNS_SECTION_AUTHORITY]); - isc_buffer_putuint16(target, - (uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]); -} - -isc_result_t -dns_message_renderend(dns_message_t *msg) { - isc_buffer_t tmpbuf; - isc_region_t r; - int result; - unsigned int count; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(msg->buffer != NULL); - - if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) { - /* - * We have an extended rcode but are not using EDNS. - */ - return (DNS_R_FORMERR); - } - - /* - * If we're adding a OPT, TSIG or SIG(0) to a truncated message, - * clear all rdatasets from the message except for the question - * before adding the OPT, TSIG or SIG(0). If the question doesn't - * fit, don't include it. - */ - if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) && - (msg->flags & DNS_MESSAGEFLAG_TC) != 0) - { - isc_buffer_t *buf; - - msgresetnames(msg, DNS_SECTION_ANSWER); - buf = msg->buffer; - dns_message_renderreset(msg); - msg->buffer = buf; - isc_buffer_clear(msg->buffer); - isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN); - dns_compress_rollback(msg->cctx, 0); - result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, - 0); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - return (result); - } - - /* - * If we've got an OPT record, render it. - */ - if (msg->opt != NULL) { - dns_message_renderrelease(msg, msg->opt_reserved); - msg->opt_reserved = 0; - /* - * Set the extended rcode. Cast msg->rcode to dns_ttl_t - * so that we do a unsigned shift. - */ - msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK; - msg->opt->ttl |= (((dns_ttl_t)(msg->rcode) << 20) & - DNS_MESSAGE_EDNSRCODE_MASK); - /* - * Render. - */ - count = 0; - result = renderset(msg->opt, dns_rootname, msg->cctx, - msg->buffer, msg->reserved, 0, &count); - msg->counts[DNS_SECTION_ADDITIONAL] += count; - if (result != ISC_R_SUCCESS) - return (result); - } - - /* - * If we're adding a TSIG record, generate and render it. - */ - if (msg->tsigkey != NULL) { - dns_message_renderrelease(msg, msg->sig_reserved); - msg->sig_reserved = 0; - result = dns_tsig_sign(msg); - if (result != ISC_R_SUCCESS) - return (result); - count = 0; - result = renderset(msg->tsig, msg->tsigname, msg->cctx, - msg->buffer, msg->reserved, 0, &count); - msg->counts[DNS_SECTION_ADDITIONAL] += count; - if (result != ISC_R_SUCCESS) - return (result); - } - - /* - * If we're adding a SIG(0) record, generate and render it. - */ - 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); - count = 0; - /* - * Note: dns_rootname is used here, not msg->sig0name, since - * the owner name of a SIG(0) is irrelevant, and will not - * be set in a message being rendered. - */ - result = renderset(msg->sig0, dns_rootname, msg->cctx, - msg->buffer, msg->reserved, 0, &count); - msg->counts[DNS_SECTION_ADDITIONAL] += count; - if (result != ISC_R_SUCCESS) - return (result); - } - - isc_buffer_usedregion(msg->buffer, &r); - isc_buffer_init(&tmpbuf, r.base, r.length); - - dns_message_renderheader(msg, &tmpbuf); - - msg->buffer = NULL; /* forget about this buffer only on success XXX */ - - return (ISC_R_SUCCESS); -} - -void -dns_message_renderreset(dns_message_t *msg) { - unsigned int i; - dns_name_t *name; - dns_rdataset_t *rds; - - /* - * Reset the message so that it may be rendered again. - */ - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - - msg->buffer = NULL; - - for (i = 0; i < DNS_SECTION_MAX; i++) { - msg->cursors[i] = NULL; - msg->counts[i] = 0; - for (name = ISC_LIST_HEAD(msg->sections[i]); - name != NULL; - name = ISC_LIST_NEXT(name, link)) { - for (rds = ISC_LIST_HEAD(name->list); - rds != NULL; - rds = ISC_LIST_NEXT(rds, link)) { - rds->attributes &= ~DNS_RDATASETATTR_RENDERED; - } - } - } - if (msg->tsigname != NULL) - dns_message_puttempname(msg, &msg->tsigname); - if (msg->tsig != NULL) { - dns_rdataset_disassociate(msg->tsig); - dns_message_puttemprdataset(msg, &msg->tsig); - } - if (msg->sig0 != NULL) { - dns_rdataset_disassociate(msg->sig0); - dns_message_puttemprdataset(msg, &msg->sig0); - } -} - -isc_result_t -dns_message_firstname(dns_message_t *msg, dns_section_t section) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(VALID_NAMED_SECTION(section)); - - msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]); - - if (msg->cursors[section] == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_nextname(dns_message_t *msg, dns_section_t section) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(VALID_NAMED_SECTION(section)); - REQUIRE(msg->cursors[section] != NULL); - - msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link); - - if (msg->cursors[section] == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -void -dns_message_currentname(dns_message_t *msg, dns_section_t section, - dns_name_t **name) -{ - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(VALID_NAMED_SECTION(section)); - REQUIRE(name != NULL && *name == NULL); - REQUIRE(msg->cursors[section] != NULL); - - *name = msg->cursors[section]; -} - -isc_result_t -dns_message_findname(dns_message_t *msg, dns_section_t section, - dns_name_t *target, dns_rdatatype_t type, - dns_rdatatype_t covers, dns_name_t **name, - dns_rdataset_t **rdataset) -{ - dns_name_t *foundname; - isc_result_t result; - - /* - * XXX These requirements are probably too intensive, especially - * where things can be NULL, but as they are they ensure that if - * something is NON-NULL, indicating that the caller expects it - * to be filled in, that we can in fact fill it in. - */ - REQUIRE(msg != NULL); - REQUIRE(VALID_SECTION(section)); - REQUIRE(target != NULL); - REQUIRE(name == NULL || *name == NULL); - - if (type == dns_rdatatype_any) { - REQUIRE(rdataset == NULL); - } else { - REQUIRE(rdataset == NULL || *rdataset == NULL); - } - - result = findname(&foundname, target, - &msg->sections[section]); - - if (result == ISC_R_NOTFOUND) - return (DNS_R_NXDOMAIN); - else if (result != ISC_R_SUCCESS) - return (result); - - if (name != NULL) - *name = foundname; - - /* - * And now look for the type. - */ - if (ISC_UNLIKELY(type == dns_rdatatype_any)) - return (ISC_R_SUCCESS); - - result = dns_message_findtype(foundname, type, covers, rdataset); - if (result == ISC_R_NOTFOUND) - return (DNS_R_NXRRSET); - - return (result); -} - -void -dns_message_movename(dns_message_t *msg, dns_name_t *name, - dns_section_t fromsection, - dns_section_t tosection) -{ - REQUIRE(msg != NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - REQUIRE(name != NULL); - REQUIRE(VALID_NAMED_SECTION(fromsection)); - REQUIRE(VALID_NAMED_SECTION(tosection)); - - /* - * Unlink the name from the old section - */ - ISC_LIST_UNLINK(msg->sections[fromsection], name, link); - ISC_LIST_APPEND(msg->sections[tosection], name, link); -} - -void -dns_message_addname(dns_message_t *msg, dns_name_t *name, - dns_section_t section) -{ - REQUIRE(msg != NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - REQUIRE(name != NULL); - REQUIRE(VALID_NAMED_SECTION(section)); - - ISC_LIST_APPEND(msg->sections[section], name, link); -} - -void -dns_message_removename(dns_message_t *msg, dns_name_t *name, - dns_section_t section) -{ - REQUIRE(msg != NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - REQUIRE(name != NULL); - REQUIRE(VALID_NAMED_SECTION(section)); - - ISC_LIST_UNLINK(msg->sections[section], name, link); -} - -isc_result_t -dns_message_gettempname(dns_message_t *msg, dns_name_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = isc_mempool_get(msg->namepool); - if (*item == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(*item, NULL); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = newoffsets(msg); - if (*item == NULL) - return (ISC_R_NOMEMORY); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = newrdata(msg); - if (*item == NULL) - return (ISC_R_NOMEMORY); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = isc_mempool_get(msg->rdspool); - if (*item == NULL) - return (ISC_R_NOMEMORY); - - dns_rdataset_init(*item); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = newrdatalist(msg); - if (*item == NULL) - return (ISC_R_NOMEMORY); - - return (ISC_R_SUCCESS); -} - -void -dns_message_puttempname(dns_message_t *msg, dns_name_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item != NULL); - - if (dns_name_dynamic(*item)) - dns_name_free(*item, msg->mctx); - isc_mempool_put(msg->namepool, *item); - *item = NULL; -} - -void -dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item != NULL); - - releaserdata(msg, *item); - *item = NULL; -} - -void -dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item != NULL); - - REQUIRE(!dns_rdataset_isassociated(*item)); - isc_mempool_put(msg->rdspool, *item); - *item = NULL; -} - -void -dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item != NULL); - - releaserdatalist(msg, *item); - *item = NULL; -} - -isc_result_t -dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, - unsigned int *flagsp) -{ - isc_region_t r; - isc_buffer_t buffer; - dns_messageid_t id; - unsigned int flags; - - REQUIRE(source != NULL); - - buffer = *source; - - isc_buffer_remainingregion(&buffer, &r); - if (r.length < DNS_MESSAGE_HEADERLEN) - return (ISC_R_UNEXPECTEDEND); - - id = isc_buffer_getuint16(&buffer); - flags = isc_buffer_getuint16(&buffer); - flags &= DNS_MESSAGE_FLAG_MASK; - - if (flagsp != NULL) - *flagsp = flags; - if (idp != NULL) - *idp = id; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_reply(dns_message_t *msg, bool want_question_section) { - unsigned int clear_from; - isc_result_t result; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0); - - if (!msg->header_ok) - return (DNS_R_FORMERR); - if (msg->opcode != dns_opcode_query && - msg->opcode != dns_opcode_notify) - want_question_section = false; - if (msg->opcode == dns_opcode_update) - clear_from = DNS_SECTION_PREREQUISITE; - else if (want_question_section) { - if (!msg->question_ok) - return (DNS_R_FORMERR); - clear_from = DNS_SECTION_ANSWER; - } else - clear_from = DNS_SECTION_QUESTION; - msg->from_to_wire = DNS_MESSAGE_INTENTRENDER; - msgresetnames(msg, clear_from); - msgresetopt(msg); - msgresetsigs(msg, true); - msginitprivate(msg); - /* - * We now clear most flags and then set QR, ensuring that the - * reply's flags will be in a reasonable state. - */ - if (msg->opcode == dns_opcode_query) - msg->flags &= DNS_MESSAGE_REPLYPRESERVE; - else - msg->flags = 0; - msg->flags |= DNS_MESSAGEFLAG_QR; - - /* - * This saves the query TSIG status, if the query was signed, and - * reserves space in the reply for the TSIG. - */ - if (msg->tsigkey != 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.base != NULL) { - msg->query.base = msg->saved.base; - msg->query.length = msg->saved.length; - msg->free_query = msg->free_saved; - msg->saved.base = NULL; - msg->saved.length = 0; - msg->free_saved = 0; - } - - return (ISC_R_SUCCESS); -} - -dns_rdataset_t * -dns_message_getopt(dns_message_t *msg) { - - /* - * Get the OPT record for 'msg'. - */ - - REQUIRE(DNS_MESSAGE_VALID(msg)); - - return (msg->opt); -} - -isc_result_t -dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) { - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - - /* - * Set the OPT record for 'msg'. - */ - - /* - * The space required for an OPT 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 rdata length - * --------------------------------- - * 11 bytes - * - * plus the length of the rdata. - */ - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(opt->type == dns_rdatatype_opt); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); - REQUIRE(msg->state == DNS_SECTION_ANY); - - msgresetopt(msg); - - result = dns_rdataset_first(opt); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_current(opt, &rdata); - msg->opt_reserved = 11 + rdata.length; - result = dns_message_renderreserve(msg, msg->opt_reserved); - if (result != ISC_R_SUCCESS) { - msg->opt_reserved = 0; - goto cleanup; - } - - msg->opt = opt; - - return (ISC_R_SUCCESS); - - cleanup: - dns_rdataset_disassociate(opt); - dns_message_puttemprdataset(msg, &opt); - return (result); -} - -dns_rdataset_t * -dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) { - - /* - * Get the TSIG record and owner for 'msg'. - */ - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(owner == NULL || *owner == NULL); - - if (owner != NULL) - *owner = msg->tsigname; - return (msg->tsig); -} - -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)); - - if (key == NULL && msg->tsigkey != NULL) { - if (msg->sig_reserved != 0) { - dns_message_renderrelease(msg, msg->sig_reserved); - msg->sig_reserved = 0; - } - dns_tsigkey_detach(&msg->tsigkey); - } - if (key != NULL) { - REQUIRE(msg->tsigkey == NULL && msg->sig0key == 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) { - dns_tsigkey_detach(&msg->tsigkey); - msg->sig_reserved = 0; - return (result); - } - } - } - return (ISC_R_SUCCESS); -} - -dns_tsigkey_t * -dns_message_gettsigkey(dns_message_t *msg) { - - /* - * Get the TSIG key for 'msg' - */ - - REQUIRE(DNS_MESSAGE_VALID(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->querytsig == 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_APPEND(list->rdata, rdata, link); - result = dns_rdatalist_tordataset(list, set); - if (result != ISC_R_SUCCESS) - goto cleanup; - - msg->querytsig = 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 = DNS_RDATA_INIT; - isc_region_t r; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(mctx != NULL); - REQUIRE(querytsig != NULL && *querytsig == NULL); - - if (msg->tsig == NULL) - return (ISC_R_SUCCESS); - - result = dns_rdataset_first(msg->tsig); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_current(msg->tsig, &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) { - - /* - * Get the SIG(0) record for 'msg'. - */ - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(owner == NULL || *owner == NULL); - - if (msg->sig0 != NULL && owner != NULL) { - /* If dns_message_getsig0 is called on a rendered message - * after the SIG(0) has been applied, we need to return the - * root name, not NULL. - */ - if (msg->sig0name == NULL) - *owner = dns_rootname; - else - *owner = msg->sig0name; - } - return (msg->sig0); -} - -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->state == DNS_SECTION_ANY); - - if (key != NULL) { - REQUIRE(msg->sig0key == NULL && msg->tsigkey == 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); - } - msg->sig0key = key; - } - 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)); - REQUIRE(buffer != NULL); - REQUIRE(ISC_BUFFER_VALID(*buffer)); - - ISC_LIST_APPEND(msg->cleanup, *buffer, link); - *buffer = NULL; -} - -isc_result_t -dns_message_signer(dns_message_t *msg, dns_name_t *signer) { - isc_result_t result = ISC_R_SUCCESS; - dns_rdata_t rdata = DNS_RDATA_INIT; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(signer != NULL); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); - - if (msg->tsig == NULL && msg->sig0 == NULL) - return (ISC_R_NOTFOUND); - - if (msg->verify_attempted == 0) - return (DNS_R_NOTVERIFIEDYET); - - if (!dns_name_hasbuffer(signer)) { - isc_buffer_t *dynbuf = NULL; - result = isc_buffer_allocate(msg->mctx, &dynbuf, 512); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_setbuffer(signer, dynbuf); - dns_message_takebuffer(msg, &dynbuf); - } - - if (msg->sig0 != NULL) { - 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, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - if (msg->verified_sig && msg->sig0status == dns_rcode_noerror) - result = ISC_R_SUCCESS; - else - result = DNS_R_SIGINVALID; - dns_name_clone(&sig.signer, signer); - dns_rdata_freestruct(&sig); - } else { - const dns_name_t *identity; - dns_rdata_any_tsig_t tsig; - - result = dns_rdataset_first(msg->tsig); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(msg->tsig, &rdata); - - result = dns_rdata_tostruct(&rdata, &tsig, NULL); - INSIST(result == ISC_R_SUCCESS); - if (msg->verified_sig && - msg->tsigstatus == dns_rcode_noerror && - tsig.error == dns_rcode_noerror) - { - result = ISC_R_SUCCESS; - } else if ((!msg->verified_sig) || - (msg->tsigstatus != dns_rcode_noerror)) - { - result = DNS_R_TSIGVERIFYFAILURE; - } else { - INSIST(tsig.error != dns_rcode_noerror); - result = DNS_R_TSIGERRORSET; - } - dns_rdata_freestruct(&tsig); - - if (msg->tsigkey == NULL) { - /* - * If msg->tsigstatus & tsig.error are both - * dns_rcode_noerror, the message must have been - * verified, which means msg->tsigkey will be - * non-NULL. - */ - INSIST(result != ISC_R_SUCCESS); - } else { - identity = dns_tsigkey_identity(msg->tsigkey); - if (identity == NULL) { - if (result == ISC_R_SUCCESS) - result = DNS_R_NOIDENTITY; - identity = &msg->tsigkey->name; - } - dns_name_clone(identity, signer); - } - } - - return (result); -} - -void -dns_message_resetsig(dns_message_t *msg) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - msg->verified_sig = 0; - msg->verify_attempted = 0; - msg->tsigstatus = dns_rcode_noerror; - msg->sig0status = dns_rcode_noerror; - msg->timeadjust = 0; - if (msg->tsigkey != NULL) { - dns_tsigkey_detach(&msg->tsigkey); - msg->tsigkey = NULL; - } -} - -isc_result_t -dns_message_rechecksig(dns_message_t *msg, dns_view_t *view) { - dns_message_resetsig(msg); - return (dns_message_checksig(msg, view)); -} - -#ifdef SKAN_MSG_DEBUG -void -dns_message_dumpsig(dns_message_t *msg, char *txt1) { - dns_rdata_t querytsigrdata = DNS_RDATA_INIT; - dns_rdata_any_tsig_t querytsig; - isc_result_t result; - - if (msg->tsig != NULL) { - result = dns_rdataset_first(msg->tsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(msg->tsig, &querytsigrdata); - result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - hexdump(txt1, "TSIG", querytsig.signature, - querytsig.siglen); - } - - if (msg->querytsig != NULL) { - result = dns_rdataset_first(msg->querytsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(msg->querytsig, &querytsigrdata); - result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - hexdump(txt1, "QUERYTSIG", querytsig.signature, - querytsig.siglen); - } -} -#endif - -isc_result_t -dns_message_checksig(dns_message_t *msg, dns_view_t *view) { - isc_buffer_t b, msgb; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - - if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) - return (ISC_R_SUCCESS); - - INSIST(msg->saved.base != NULL); - isc_buffer_init(&msgb, msg->saved.base, msg->saved.length); - isc_buffer_add(&msgb, msg->saved.length); - if (msg->tsigkey != NULL || msg->tsig != NULL) { -#ifdef SKAN_MSG_DEBUG - dns_message_dumpsig(msg, "dns_message_checksig#1"); -#endif - if (view != NULL) - return (dns_view_checksig(view, &msgb, msg)); - else - return (dns_tsig_verify(&msgb, msg, NULL, NULL)); - } else { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_sig_t sig; - dns_rdataset_t keyset; - isc_result_t result; - - result = dns_rdataset_first(msg->sig0); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(msg->sig0, &rdata); - - /* - * This can occur when the message is a dynamic update, since - * the rdata length checking is relaxed. This should not - * happen in a well-formed message, since the SIG(0) is only - * looked for in the additional section, and the dynamic update - * meta-records are in the prerequisite and update sections. - */ - if (rdata.length == 0) - return (ISC_R_UNEXPECTEDEND); - - result = dns_rdata_tostruct(&rdata, &sig, msg->mctx); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&keyset); - if (view == NULL) - return (DNS_R_KEYUNAUTHORIZED); - result = dns_view_simplefind(view, &sig.signer, - dns_rdatatype_key /* SIG(0) */, - 0, 0, false, &keyset, NULL); - - if (result != ISC_R_SUCCESS) { - /* XXXBEW Should possibly create a fetch here */ - result = DNS_R_KEYUNAUTHORIZED; - goto freesig; - } else if (keyset.trust < dns_trust_secure) { - /* XXXBEW Should call a validator here */ - result = DNS_R_KEYUNAUTHORIZED; - goto freesig; - } - result = dns_rdataset_first(&keyset); - INSIST(result == ISC_R_SUCCESS); - for (; - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keyset)) - { - dst_key_t *key = NULL; - - dns_rdata_reset(&rdata); - dns_rdataset_current(&keyset, &rdata); - isc_buffer_init(&b, rdata.data, rdata.length); - isc_buffer_add(&b, rdata.length); - - result = dst_key_fromdns(&sig.signer, rdata.rdclass, - &b, view->mctx, &key); - if (result != ISC_R_SUCCESS) - continue; - if (dst_key_alg(key) != sig.algorithm || - dst_key_id(key) != sig.keyid || - !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC || - dst_key_proto(key) == DNS_KEYPROTO_ANY)) - { - dst_key_free(&key); - continue; - } - result = dns_dnssec_verifymessage(&msgb, msg, key); - dst_key_free(&key); - if (result == ISC_R_SUCCESS) - break; - } - if (result == ISC_R_NOMORE) - result = DNS_R_KEYUNAUTHORIZED; - - freesig: - if (dns_rdataset_isassociated(&keyset)) - dns_rdataset_disassociate(&keyset); - dns_rdata_freestruct(&sig); - return (result); - } -} - -#define INDENT(sp) \ - do { \ - unsigned int __i; \ - dns_masterstyle_flags_t __flags = dns_master_styleflags(sp); \ - if ((__flags & DNS_STYLEFLAG_INDENT) == 0ULL && \ - (__flags & DNS_STYLEFLAG_YAML) == 0ULL) \ - break; \ - for (__i = 0; __i < msg->indent.count; __i++) { \ - ADD_STRING(target, msg->indent.string); \ - } \ - } while (0) - -isc_result_t -dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, - const dns_master_style_t *style, - dns_messagetextflag_t flags, - isc_buffer_t *target) { - dns_name_t *name, empty_name; - dns_rdataset_t *rdataset; - isc_result_t result = ISC_R_SUCCESS; - bool seensoa = false; - unsigned int saveindent; - dns_masterstyle_flags_t sflags; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(target != NULL); - REQUIRE(VALID_SECTION(section)); - - saveindent = msg->indent.count; - sflags = dns_master_styleflags(style); - if (ISC_LIST_EMPTY(msg->sections[section])) - goto cleanup; - - - INDENT(style); - if ((sflags & DNS_STYLEFLAG_YAML) != 0) { - if (msg->opcode != dns_opcode_update) { - ADD_STRING(target, sectiontext[section]); - } else { - ADD_STRING(target, updsectiontext[section]); - } - ADD_STRING(target, "_SECTION:\n"); - } else if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) { - ADD_STRING(target, ";; "); - if (msg->opcode != dns_opcode_update) { - ADD_STRING(target, sectiontext[section]); - } else { - ADD_STRING(target, updsectiontext[section]); - } - ADD_STRING(target, " SECTION:\n"); - } - - dns_name_init(&empty_name, NULL); - result = dns_message_firstname(msg, section); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - if ((sflags & DNS_STYLEFLAG_YAML) != 0) { - msg->indent.count++; - } - do { - name = NULL; - dns_message_currentname(msg, section, &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (section == DNS_SECTION_ANSWER && - rdataset->type == dns_rdatatype_soa) { - if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0) - continue; - if (seensoa && - (flags & DNS_MESSAGETEXTFLAG_ONESOA) != 0) - continue; - seensoa = true; - } - if (section == DNS_SECTION_QUESTION) { - INDENT(style); - if ((sflags & DNS_STYLEFLAG_YAML) != 0) { - ADD_STRING(target, "- "); - } else { - ADD_STRING(target, ";"); - } - result = dns_master_questiontotext(name, - rdataset, - style, - target); - } else { - result = dns_master_rdatasettotext(name, - rdataset, - style, - target); - } - if (result != ISC_R_SUCCESS) - goto cleanup; - } - result = dns_message_nextname(msg, section); - } while (result == ISC_R_SUCCESS); - if ((sflags & DNS_STYLEFLAG_YAML) != 0) { - msg->indent.count--; - } - if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && - (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 && - (sflags & DNS_STYLEFLAG_YAML) == 0) - { - INDENT(style); - ADD_STRING(target, "\n"); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup: - msg->indent.count = saveindent; - return (result); -} - -static isc_result_t -render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) { - int i; - char addr[16], addr_text[64]; - uint16_t family; - uint8_t addrlen, addrbytes, scopelen; - isc_result_t result; - - /* - * Note: This routine needs to handle malformed ECS options. - */ - - if (isc_buffer_remaininglength(ecsbuf) < 4) - return (DNS_R_OPTERR); - family = isc_buffer_getuint16(ecsbuf); - addrlen = isc_buffer_getuint8(ecsbuf); - scopelen = isc_buffer_getuint8(ecsbuf); - - addrbytes = (addrlen + 7) / 8; - if (isc_buffer_remaininglength(ecsbuf) < addrbytes) - return (DNS_R_OPTERR); - - if (addrbytes > sizeof(addr)) - return (DNS_R_OPTERR); - - memset(addr, 0, sizeof(addr)); - for (i = 0; i < addrbytes; i ++) - addr[i] = isc_buffer_getuint8(ecsbuf); - - switch (family) { - case 0: - if (addrlen != 0U || scopelen != 0U) - return (DNS_R_OPTERR); - strlcpy(addr_text, "0", sizeof(addr_text)); - break; - case 1: - if (addrlen > 32 || scopelen > 32) - return (DNS_R_OPTERR); - inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text)); - break; - case 2: - if (addrlen > 128 || scopelen > 128) - return (DNS_R_OPTERR); - inet_ntop(AF_INET6, addr, addr_text, sizeof(addr_text)); - break; - default: - return (DNS_R_OPTERR); - } - - ADD_STRING(target, ": "); - ADD_STRING(target, addr_text); - snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen); - ADD_STRING(target, addr_text); - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -static isc_result_t -render_llq(isc_buffer_t *optbuf, isc_buffer_t *target) { - char buf[sizeof("18446744073709551615")]; /* 2^64-1 */ - isc_result_t result = ISC_R_SUCCESS; - uint32_t u; - uint64_t q; - - u = isc_buffer_getuint16(optbuf); - ADD_STRING(target, " Version: "); - snprintf(buf, sizeof(buf), "%u", u); - ADD_STRING(target, buf); - - u = isc_buffer_getuint16(optbuf); - ADD_STRING(target, ", Opcode: "); - snprintf(buf, sizeof(buf), "%u", u); - ADD_STRING(target, buf); - - u = isc_buffer_getuint16(optbuf); - ADD_STRING(target, ", Error: "); - snprintf(buf, sizeof(buf), "%u", u); - ADD_STRING(target, buf); - - q = isc_buffer_getuint32(optbuf); - q <<= 32; - q |= isc_buffer_getuint32(optbuf); - ADD_STRING(target, ", Identifier: "); - snprintf(buf, sizeof(buf), "%" PRIu64, q); - ADD_STRING(target, buf); - - u = isc_buffer_getuint32(optbuf); - ADD_STRING(target, ", Lifetime: "); - snprintf(buf, sizeof(buf), "%u", u); - ADD_STRING(target, buf); - cleanup: - return (result); -} - -static isc_result_t -dns_message_pseudosectiontoyaml(dns_message_t *msg, - dns_pseudosection_t section, - const dns_master_style_t *style, - dns_messagetextflag_t flags, - isc_buffer_t *target) -{ - dns_rdataset_t *ps = NULL; - dns_name_t *name = NULL; - isc_result_t result = ISC_R_SUCCESS; - char buf[sizeof("1234567890")]; - uint32_t mbz; - dns_rdata_t rdata; - isc_buffer_t optbuf; - uint16_t optcode, optlen; - unsigned char *optdata; - unsigned int saveindent = msg->indent.count; - unsigned int optindent; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(target != NULL); - REQUIRE(VALID_PSEUDOSECTION(section)); - - switch (section) { - case DNS_PSEUDOSECTION_OPT: - ps = dns_message_getopt(msg); - if (ps == NULL) { - goto cleanup; - } - - INDENT(style); - ADD_STRING(target, "OPT_PSEUDOSECTION:\n"); - msg->indent.count++; - - INDENT(style); - ADD_STRING(target, "EDNS:\n"); - msg->indent.count++; - - INDENT(style); - ADD_STRING(target, "version: "); - snprintf(buf, sizeof(buf), "%u", - (unsigned int)((ps->ttl & 0x00ff0000) >> 16)); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, "flags:"); - if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0) - ADD_STRING(target, " do"); - ADD_STRING(target, "\n"); - mbz = ps->ttl & 0xffff; - mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */ - if (mbz != 0) { - INDENT(style); - ADD_STRING(target, "MBZ: "); - snprintf(buf, sizeof(buf), "0x%.4x", mbz); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - } - INDENT(style); - ADD_STRING(target, "udp: "); - snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass); - ADD_STRING(target, buf); - result = dns_rdataset_first(ps); - if (result != ISC_R_SUCCESS) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - /* - * Print EDNS info, if any. - * - * WARNING: The option contents may be malformed as - * dig +ednsopt=value: does not perform validity - * checking. - */ - dns_rdata_init(&rdata); - dns_rdataset_current(ps, &rdata); - - isc_buffer_init(&optbuf, rdata.data, rdata.length); - isc_buffer_add(&optbuf, rdata.length); - optindent = msg->indent.count; - while (isc_buffer_remaininglength(&optbuf) != 0) { - bool extra_text = false; - msg->indent.count = optindent; - INSIST(isc_buffer_remaininglength(&optbuf) >= 4U); - optcode = isc_buffer_getuint16(&optbuf); - optlen = isc_buffer_getuint16(&optbuf); - INSIST(isc_buffer_remaininglength(&optbuf) >= optlen); - - if (optcode == DNS_OPT_LLQ) { - INDENT(style); - if (optlen == 18U) { - ADD_STRING(target, "LLQ: "); - result = render_llq(&optbuf, target); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - ADD_STRING(target, "\n"); - continue; - } - ADD_STRING(target, "LLQ"); - } else if (optcode == DNS_OPT_NSID) { - INDENT(style); - ADD_STRING(target, "NSID"); - } else if (optcode == DNS_OPT_COOKIE) { - INDENT(style); - ADD_STRING(target, "COOKIE"); - } else if (optcode == DNS_OPT_CLIENT_SUBNET) { - isc_buffer_t ecsbuf; - INDENT(style); - ADD_STRING(target, "CLIENT-SUBNET"); - isc_buffer_init(&ecsbuf, - isc_buffer_current(&optbuf), - optlen); - isc_buffer_add(&ecsbuf, optlen); - result = render_ecs(&ecsbuf, target); - if (result == ISC_R_NOSPACE) - goto cleanup; - if (result == ISC_R_SUCCESS) { - isc_buffer_forward(&optbuf, optlen); - ADD_STRING(target, "\n"); - continue; - } - ADD_STRING(target, "\n"); - } else if (optcode == DNS_OPT_EXPIRE) { - if (optlen == 4) { - uint32_t secs; - secs = isc_buffer_getuint32(&optbuf); - INDENT(style); - ADD_STRING(target, "EXPIRE: "); - snprintf(buf, sizeof(buf), "%u", secs); - ADD_STRING(target, buf); - ADD_STRING(target, " ("); - result = dns_ttl_totext(secs, - true, - target); - if (result != ISC_R_SUCCESS) - goto cleanup; - ADD_STRING(target, ")\n"); - continue; - } - INDENT(style); - ADD_STRING(target, "EXPIRE"); - } else if (optcode == DNS_OPT_PAD) { - INDENT(style); - ADD_STRING(target, "PAD"); - } else if (optcode == DNS_OPT_KEY_TAG) { - INDENT(style); - ADD_STRING(target, "KEY-TAG"); - if (optlen > 0U && (optlen % 2U) == 0U) { - const char *sep = ": "; - uint16_t id; - while (optlen > 0U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), "%s%u", - sep, id); - ADD_STRING(target, buf); - sep = ", "; - optlen -= 2; - } - ADD_STRING(target, "\n"); - continue; - } - } else if (optcode == DNS_OPT_EDE) { - INDENT(style); - ADD_STRING(target, "EDE"); - if (optlen >= 2U) { - uint16_t ede; - ADD_STRING(target, ":\n"); - msg->indent.count++; - INDENT(style); - ADD_STRING(target, "INFO-CODE:"); - ede = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), " %u", ede); - ADD_STRING(target, buf); - if (ede < ARRAY_SIZE(edetext)) { - ADD_STRING(target, " ("); - ADD_STRING(target, - edetext[ede]); - ADD_STRING(target, ")"); - } - ADD_STRING(target, "\n"); - optlen -= 2; - if (optlen != 0) { - INDENT(style); - ADD_STRING(target, - "EXTRA-TEXT"); - extra_text = true; - } - } - } else if (optcode == DNS_OPT_CLIENT_TAG) { - uint16_t id; - INDENT(style); - ADD_STRING(target, "CLIENT-TAG"); - if (optlen == 2U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), ": %u\n", - id); - ADD_STRING(target, buf); - optlen -= 2; - POST(optlen); - continue; - } - } else if (optcode == DNS_OPT_SERVER_TAG) { - uint16_t id; - INDENT(style); - ADD_STRING(target, "SERVER-TAG"); - if (optlen == 2U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), ": %u\n", - id); - ADD_STRING(target, buf); - optlen -= 2; - POST(optlen); - continue; - } - } else { - INDENT(style); - ADD_STRING(target, "OPT: "); - snprintf(buf, sizeof(buf), "%u", optcode); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - } - - if (optlen != 0) { - int i; - bool utf8ok = false; - - ADD_STRING(target, ": "); - - optdata = isc_buffer_current(&optbuf); - if (extra_text) { - utf8ok = isc_utf8_valid(optdata, - optlen); - } - if (!utf8ok) { - for (i = 0; i < optlen; i++) { - const char *sep; - switch (optcode) { - case DNS_OPT_COOKIE: - sep = ""; - break; - default: - sep = " "; - break; - } - snprintf(buf, sizeof(buf), - "%02x%s", optdata[i], - sep); - ADD_STRING(target, buf); - } - } - - isc_buffer_forward(&optbuf, optlen); - - if (optcode == DNS_OPT_COOKIE) { - /* - * Valid server cookie? - */ - if (msg->cc_ok && optlen >= 16) - ADD_STRING(target, " (good)"); - /* - * Server cookie is not valid but - * we had our cookie echoed back. - */ - if (msg->cc_ok && optlen < 16) - ADD_STRING(target, " (echoed)"); - /* - * We didn't get our cookie echoed - * back. - */ - if (msg->cc_bad) - ADD_STRING(target, " (bad)"); - ADD_STRING(target, "\n"); - continue; - } - - if (optcode == DNS_OPT_CLIENT_SUBNET) { - ADD_STRING(target, "\n"); - continue; - } - - /* - * For non-COOKIE options, add a printable - * version - */ - if (!extra_text) { - ADD_STRING(target, "(\""); - } else { - ADD_STRING(target, "\""); - } - if (isc_buffer_availablelength(target) < optlen) - { - result = ISC_R_NOSPACE; - goto cleanup; - } - for (i = 0; i < optlen; i++) { - if (isprint(optdata[i]) || - (utf8ok && optdata[i] > 127)) { - isc_buffer_putmem( - target, &optdata[i], 1); - } else { - isc_buffer_putstr(target, "."); - } - } - if (!extra_text) { - ADD_STRING(target, "\")"); - } else { - ADD_STRING(target, "\""); - } - } - ADD_STRING(target, "\n"); - } - msg->indent.count = optindent; - result = ISC_R_SUCCESS; - goto cleanup; - case DNS_PSEUDOSECTION_TSIG: - ps = dns_message_gettsig(msg, &name); - if (ps == NULL) { - result = ISC_R_SUCCESS; - goto cleanup; - } - INDENT(style); - ADD_STRING(target, "TSIG_PSEUDOSECTION:\n"); - result = dns_master_rdatasettotext(name, ps, style, target); - ADD_STRING(target, "\n"); - goto cleanup; - case DNS_PSEUDOSECTION_SIG0: - ps = dns_message_getsig0(msg, &name); - if (ps == NULL) { - result = ISC_R_SUCCESS; - goto cleanup; - } - INDENT(style); - ADD_STRING(target, "SIG0_PSEUDOSECTION:\n"); - result = dns_master_rdatasettotext(name, ps, style, target); - if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && - (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) - ADD_STRING(target, "\n"); - goto cleanup; - } - - result = ISC_R_UNEXPECTED; - - cleanup: - msg->indent.count = saveindent; - return (result); -} - -isc_result_t -dns_message_pseudosectiontotext(dns_message_t *msg, - dns_pseudosection_t section, - const dns_master_style_t *style, - dns_messagetextflag_t flags, - isc_buffer_t *target) -{ - dns_rdataset_t *ps = NULL; - dns_name_t *name = NULL; - isc_result_t result; - char buf[sizeof("1234567890 ")]; - uint32_t mbz; - dns_rdata_t rdata; - isc_buffer_t optbuf; - uint16_t optcode, optlen; - unsigned char *optdata; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(target != NULL); - REQUIRE(VALID_PSEUDOSECTION(section)); - - if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0) - return (dns_message_pseudosectiontoyaml(msg, section, style, - flags, target)); - switch (section) { - case DNS_PSEUDOSECTION_OPT: - ps = dns_message_getopt(msg); - if (ps == NULL) - return (ISC_R_SUCCESS); - if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) { - INDENT(style); - ADD_STRING(target, ";; OPT PSEUDOSECTION:\n"); - } - - INDENT(style); - ADD_STRING(target, "; EDNS: version: "); - snprintf(buf, sizeof(buf), "%u", - (unsigned int)((ps->ttl & 0x00ff0000) >> 16)); - ADD_STRING(target, buf); - ADD_STRING(target, ", flags:"); - if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0) - ADD_STRING(target, " do"); - mbz = ps->ttl & 0xffff; - mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */ - if (mbz != 0) { - ADD_STRING(target, "; MBZ: "); - snprintf(buf, sizeof(buf), "0x%.4x", mbz); - ADD_STRING(target, buf); - ADD_STRING(target, ", udp: "); - } else - ADD_STRING(target, "; udp: "); - snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass); - ADD_STRING(target, buf); - - result = dns_rdataset_first(ps); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - /* - * Print EDNS info, if any. - * - * WARNING: The option contents may be malformed as - * dig +ednsopt=value: does not validity - * checking. - */ - dns_rdata_init(&rdata); - dns_rdataset_current(ps, &rdata); - - isc_buffer_init(&optbuf, rdata.data, rdata.length); - isc_buffer_add(&optbuf, rdata.length); - while (isc_buffer_remaininglength(&optbuf) != 0) { - INSIST(isc_buffer_remaininglength(&optbuf) >= 4U); - optcode = isc_buffer_getuint16(&optbuf); - optlen = isc_buffer_getuint16(&optbuf); - INSIST(isc_buffer_remaininglength(&optbuf) >= optlen); - - INDENT(style); - - if (optcode == DNS_OPT_LLQ) { - if (optlen == 18U) { - ADD_STRING(target, "; LLQ:"); - result = render_llq(&optbuf, target); - if (result != ISC_R_SUCCESS) { - return (result); - } - ADD_STRING(target, "\n"); - continue; - } - ADD_STRING(target, "; LLQ"); - } else if (optcode == DNS_OPT_NSID) { - ADD_STRING(target, "; NSID"); - } else if (optcode == DNS_OPT_COOKIE) { - ADD_STRING(target, "; COOKIE"); - } else if (optcode == DNS_OPT_CLIENT_SUBNET) { - isc_buffer_t ecsbuf; - - ADD_STRING(target, "; CLIENT-SUBNET"); - isc_buffer_init(&ecsbuf, - isc_buffer_current(&optbuf), - optlen); - isc_buffer_add(&ecsbuf, optlen); - result = render_ecs(&ecsbuf, target); - if (result == ISC_R_NOSPACE) - return (result); - if (result == ISC_R_SUCCESS) { - isc_buffer_forward(&optbuf, optlen); - ADD_STRING(target, "\n"); - continue; - } - } else if (optcode == DNS_OPT_EXPIRE) { - if (optlen == 4) { - uint32_t secs; - secs = isc_buffer_getuint32(&optbuf); - ADD_STRING(target, "; EXPIRE: "); - snprintf(buf, sizeof(buf), "%u", secs); - ADD_STRING(target, buf); - ADD_STRING(target, " ("); - result = dns_ttl_totext(secs, - true, - target); - if (result != ISC_R_SUCCESS) - return (result); - ADD_STRING(target, ")\n"); - continue; - } - ADD_STRING(target, "; EXPIRE"); - } else if (optcode == DNS_OPT_PAD) { - ADD_STRING(target, "; PAD"); - } else if (optcode == DNS_OPT_KEY_TAG) { - ADD_STRING(target, "; KEY-TAG"); - if (optlen > 0U && (optlen % 2U) == 0U) { - const char *sep = ": "; - uint16_t id; - while (optlen > 0U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), "%s%u", - sep, id); - ADD_STRING(target, buf); - sep = ", "; - optlen -= 2; - } - ADD_STRING(target, "\n"); - continue; - } - } else if (optcode == DNS_OPT_EDE) { - ADD_STRING(target, "; EDE"); - if (optlen >= 2U) { - uint16_t ede; - ede = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), ": %u", ede); - ADD_STRING(target, buf); - if (ede < ARRAY_SIZE(edetext)) { - ADD_STRING(target, " ("); - ADD_STRING(target, - edetext[ede]); - ADD_STRING(target, ")"); - } - optlen -= 2; - } else if (optlen == 1U) { - /* Malformed */ - optdata = isc_buffer_current(&optbuf); - snprintf(buf, sizeof(buf), - ": %02x (\"%c\")\n", - optdata[0], - isprint(optdata[0]) - ? optdata[0] - : '.'); - isc_buffer_forward(&optbuf, optlen); - ADD_STRING(target, buf); - continue; - } - } else if (optcode == DNS_OPT_CLIENT_TAG) { - uint16_t id; - ADD_STRING(target, "; CLIENT-TAG"); - if (optlen == 2U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), ": %u\n", - id); - ADD_STRING(target, buf); - optlen -= 2; - POST(optlen); - continue; - } - } else if (optcode == DNS_OPT_SERVER_TAG) { - uint16_t id; - ADD_STRING(target, "; SERVER-TAG"); - if (optlen == 2U) { - id = isc_buffer_getuint16(&optbuf); - snprintf(buf, sizeof(buf), ": %u\n", - id); - ADD_STRING(target, buf); - optlen -= 2; - POST(optlen); - continue; - } - } else { - ADD_STRING(target, "; OPT="); - snprintf(buf, sizeof(buf), "%u", optcode); - ADD_STRING(target, buf); - } - - if (optlen != 0) { - int i; - bool utf8ok = false; - ADD_STRING(target, ": "); - - optdata = isc_buffer_current(&optbuf); - if (optcode == DNS_OPT_EDE) { - utf8ok = isc_utf8_valid(optdata, - optlen); - } - if (!utf8ok) { - for (i = 0; i < optlen; i++) { - const char *sep; - switch (optcode) { - case DNS_OPT_COOKIE: - sep = ""; - break; - default: - sep = " "; - break; - } - snprintf(buf, sizeof(buf), - "%02x%s", optdata[i], - sep); - ADD_STRING(target, buf); - } - } - - isc_buffer_forward(&optbuf, optlen); - - if (optcode == DNS_OPT_COOKIE) { - /* - * Valid server cookie? - */ - if (msg->cc_ok && optlen >= 16) - ADD_STRING(target, " (good)"); - /* - * Server cookie is not valid but - * we had our cookie echoed back. - */ - if (msg->cc_ok && optlen < 16) - ADD_STRING(target, " (echoed)"); - /* - * We didn't get our cookie echoed - * back. - */ - if (msg->cc_bad) - ADD_STRING(target, " (bad)"); - ADD_STRING(target, "\n"); - continue; - } - - if (optcode == DNS_OPT_CLIENT_SUBNET) { - ADD_STRING(target, "\n"); - continue; - } - - /* - * For non-COOKIE options, add a printable - * version. - */ - if (optcode != DNS_OPT_EDE) { - ADD_STRING(target, "(\""); - } else { - ADD_STRING(target, "("); - } - if (isc_buffer_availablelength(target) < optlen) - return (ISC_R_NOSPACE); - for (i = 0; i < optlen; i++) { - if (isprint(optdata[i]) || - (utf8ok && optdata[i] > 127)) { - isc_buffer_putmem( - target, &optdata[i], 1); - } else { - isc_buffer_putstr(target, "."); - } - } - if (optcode != DNS_OPT_EDE) { - ADD_STRING(target, "\")"); - } else { - ADD_STRING(target, ")"); - } - } - ADD_STRING(target, "\n"); - } - return (ISC_R_SUCCESS); - case DNS_PSEUDOSECTION_TSIG: - ps = dns_message_gettsig(msg, &name); - if (ps == NULL) - return (ISC_R_SUCCESS); - INDENT(style); - if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) - ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n"); - result = dns_master_rdatasettotext(name, ps, style, target); - if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && - (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) - ADD_STRING(target, "\n"); - return (result); - case DNS_PSEUDOSECTION_SIG0: - ps = dns_message_getsig0(msg, &name); - if (ps == NULL) - return (ISC_R_SUCCESS); - INDENT(style); - if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) - ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n"); - result = dns_master_rdatasettotext(name, ps, style, target); - if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && - (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) - ADD_STRING(target, "\n"); - return (result); - } - result = ISC_R_UNEXPECTED; - cleanup: - return (result); -} - -isc_result_t -dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, - dns_messagetextflag_t flags, isc_buffer_t *target) -{ - char buf[sizeof("1234567890")]; - isc_result_t result; - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(target != NULL); - - if (((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) && - (dns_master_styleflags(style) & DNS_STYLEFLAG_YAML)) - { - INDENT(style); - ADD_STRING(target, "opcode: "); - ADD_STRING(target, opcodetext[msg->opcode]); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, "status: "); - result = dns_rcode_totext(msg->rcode, target); - if (result != ISC_R_SUCCESS) - return (result); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, "id: "); - snprintf(buf, sizeof(buf), "%6u", msg->id); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, "flags:"); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) - ADD_STRING(target, " qr"); - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) - ADD_STRING(target, " aa"); - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) - ADD_STRING(target, " tc"); - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) - ADD_STRING(target, " rd"); - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) - ADD_STRING(target, " ra"); - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) - ADD_STRING(target, " ad"); - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) - ADD_STRING(target, " cd"); - ADD_STRING(target, "\n"); - /* - * The final unnamed flag must be zero. - */ - if ((msg->flags & 0x0040U) != 0) { - INDENT(style); - ADD_STRING(target, "MBZ: 0x4"); - ADD_STRING(target, "\n"); - } - if (msg->opcode != dns_opcode_update) { - INDENT(style); - ADD_STRING(target, "QUESTION: "); - } else { - ADD_STRING(target, "ZONE: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_QUESTION]); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - if (msg->opcode != dns_opcode_update) { - INDENT(style); - ADD_STRING(target, "ANSWER: "); - } else { - INDENT(style); - ADD_STRING(target, "PREREQ: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_ANSWER]); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - if (msg->opcode != dns_opcode_update) { - INDENT(style); - ADD_STRING(target, "AUTHORITY: "); - } else { - INDENT(style); - ADD_STRING(target, "UPDATE: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_AUTHORITY]); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, "ADDITIONAL: "); - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_ADDITIONAL]); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - } else if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) { - INDENT(style); - ADD_STRING(target, ";; ->>HEADER<<- opcode: "); - ADD_STRING(target, opcodetext[msg->opcode]); - ADD_STRING(target, ", status: "); - result = dns_rcode_totext(msg->rcode, target); - if (result != ISC_R_SUCCESS) - return (result); - ADD_STRING(target, ", id: "); - snprintf(buf, sizeof(buf), "%6u", msg->id); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - INDENT(style); - ADD_STRING(target, ";; flags:"); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) - ADD_STRING(target, " qr"); - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) - ADD_STRING(target, " aa"); - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) - ADD_STRING(target, " tc"); - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) - ADD_STRING(target, " rd"); - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) - ADD_STRING(target, " ra"); - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) - ADD_STRING(target, " ad"); - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) - ADD_STRING(target, " cd"); - /* - * The final unnamed flag must be zero. - */ - if ((msg->flags & 0x0040U) != 0) { - INDENT(style); - ADD_STRING(target, "; MBZ: 0x4"); - } - if (msg->opcode != dns_opcode_update) { - INDENT(style); - ADD_STRING(target, "; QUESTION: "); - } else { - INDENT(style); - ADD_STRING(target, "; ZONE: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_QUESTION]); - ADD_STRING(target, buf); - if (msg->opcode != dns_opcode_update) { - ADD_STRING(target, ", ANSWER: "); - } else { - ADD_STRING(target, ", PREREQ: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_ANSWER]); - ADD_STRING(target, buf); - if (msg->opcode != dns_opcode_update) { - ADD_STRING(target, ", AUTHORITY: "); - } else { - ADD_STRING(target, ", UPDATE: "); - } - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_AUTHORITY]); - ADD_STRING(target, buf); - ADD_STRING(target, ", ADDITIONAL: "); - snprintf(buf, sizeof(buf), "%1u", - msg->counts[DNS_SECTION_ADDITIONAL]); - ADD_STRING(target, buf); - ADD_STRING(target, "\n"); - } - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_OPT, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_TSIG, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_SIG0, - style, flags, target); - if (result != ISC_R_SUCCESS) - return (result); - - cleanup: - return (result); -} - -isc_region_t * -dns_message_getrawmessage(dns_message_t *msg) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - return (&msg->saved); -} - -void -dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, - const void *order_arg) -{ - REQUIRE(DNS_MESSAGE_VALID(msg)); - msg->order = order; - msg->order_arg = order_arg; -} - -void -dns_message_settimeadjust(dns_message_t *msg, int timeadjust) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - msg->timeadjust = timeadjust; -} - -int -dns_message_gettimeadjust(dns_message_t *msg) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - return (msg->timeadjust); -} - -isc_result_t -dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) { - - REQUIRE(opcode < 16); - - if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode])) - return (ISC_R_NOSPACE); - isc_buffer_putstr(target, opcodetext[opcode]); - return (ISC_R_SUCCESS); -} - -void -dns_message_logpacket(dns_message_t *message, const char *description, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, isc_mem_t *mctx) -{ - logfmtpacket(message, description, NULL, category, module, - &dns_master_style_debug, level, mctx); -} - -void -dns_message_logpacket2(dns_message_t *message, - const char *description, isc_sockaddr_t *address, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, isc_mem_t *mctx) -{ - REQUIRE(address != NULL); - - logfmtpacket(message, description, address, category, module, - &dns_master_style_debug, level, mctx); -} - -void -dns_message_logfmtpacket(dns_message_t *message, const char *description, - isc_logcategory_t *category, isc_logmodule_t *module, - const dns_master_style_t *style, int level, - isc_mem_t *mctx) -{ - logfmtpacket(message, description, NULL, category, module, style, - level, mctx); -} - -void -dns_message_logfmtpacket2(dns_message_t *message, - const char *description, isc_sockaddr_t *address, - isc_logcategory_t *category, isc_logmodule_t *module, - const dns_master_style_t *style, int level, - isc_mem_t *mctx) -{ - REQUIRE(address != NULL); - - logfmtpacket(message, description, address, category, module, style, - level, mctx); -} - -static void -logfmtpacket(dns_message_t *message, const char *description, - isc_sockaddr_t *address, isc_logcategory_t *category, - isc_logmodule_t *module, const dns_master_style_t *style, - int level, isc_mem_t *mctx) -{ - char addrbuf[ISC_SOCKADDR_FORMATSIZE] = { 0 }; - const char *newline = "\n"; - const char *space = " "; - isc_buffer_t buffer; - char *buf = NULL; - int len = 1024; - isc_result_t result; - - if (! isc_log_wouldlog(dns_lctx, level)) - return; - - /* - * Note that these are multiline debug messages. We want a newline - * to appear in the log after each message. - */ - - if (address != NULL) - isc_sockaddr_format(address, addrbuf, sizeof(addrbuf)); - else - newline = space = ""; - - do { - buf = isc_mem_get(mctx, len); - if (buf == NULL) - break; - isc_buffer_init(&buffer, buf, len); - result = dns_message_totext(message, style, 0, &buffer); - if (result == ISC_R_NOSPACE) { - isc_mem_put(mctx, buf, len); - len += 1024; - } else if (result == ISC_R_SUCCESS) - isc_log_write(dns_lctx, category, module, level, - "%s%s%s%s%.*s", description, space, - addrbuf, newline, - (int)isc_buffer_usedlength(&buffer), - buf); - } while (result == ISC_R_NOSPACE); - - if (buf != NULL) - isc_mem_put(mctx, buf, len); -} - -isc_result_t -dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp, - unsigned int version, uint16_t udpsize, - unsigned int flags, dns_ednsopt_t *ednsopts, size_t count) -{ - dns_rdataset_t *rdataset = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdata_t *rdata = NULL; - isc_result_t result; - unsigned int len = 0, i; - - REQUIRE(DNS_MESSAGE_VALID(message)); - REQUIRE(rdatasetp != NULL && *rdatasetp == NULL); - - result = dns_message_gettemprdatalist(message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_gettemprdata(message, &rdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(message, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rdatalist->type = dns_rdatatype_opt; - - /* - * Set Maximum UDP buffer size. - */ - rdatalist->rdclass = udpsize; - - /* - * Set EXTENDED-RCODE and Z to 0. - */ - rdatalist->ttl = (version << 16); - rdatalist->ttl |= (flags & 0xffff); - - /* - * Set EDNS options if applicable - */ - if (count != 0U) { - isc_buffer_t *buf = NULL; - for (i = 0; i < count; i++) - len += ednsopts[i].length + 4; - - if (len > 0xffffU) { - result = ISC_R_NOSPACE; - goto cleanup; - } - - result = isc_buffer_allocate(message->mctx, &buf, len); - if (result != ISC_R_SUCCESS) - goto cleanup; - - for (i = 0; i < count; i++) { - isc_buffer_putuint16(buf, ednsopts[i].code); - isc_buffer_putuint16(buf, ednsopts[i].length); - if (ednsopts[i].length != 0) { - isc_buffer_putmem(buf, ednsopts[i].value, - ednsopts[i].length); - } - } - rdata->data = isc_buffer_base(buf); - rdata->length = len; - dns_message_takebuffer(message, &buf); - } else { - rdata->data = NULL; - rdata->length = 0; - } - - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatalist->type; - rdata->flags = 0; - - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - result = dns_rdatalist_tordataset(rdatalist, rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - *rdatasetp = rdataset; - return (ISC_R_SUCCESS); - - cleanup: - if (rdata != NULL) - dns_message_puttemprdata(message, &rdata); - if (rdataset != NULL) - dns_message_puttemprdataset(message, &rdataset); - if (rdatalist != NULL) - dns_message_puttemprdatalist(message, &rdatalist); - return (result); -} - -void -dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) { - - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); - REQUIRE(msg->state == DNS_SECTION_ANY); - REQUIRE(msg->rdclass_set == 0); - - msg->rdclass = rdclass; - msg->rdclass_set = 1; -} diff --git a/lib/dns-pkcs11/name.c b/lib/dns-pkcs11/name.c deleted file mode 100644 index 0c61029..0000000 --- a/lib/dns-pkcs11/name.c +++ /dev/null @@ -1,2732 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC) - -typedef enum { - ft_init = 0, - ft_start, - ft_ordinary, - ft_initialescape, - ft_escape, - ft_escdecimal, - ft_at -} ft_state; - -typedef enum { - fw_start = 0, - fw_ordinary, - fw_newcurrent -} fw_state; - -static 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*/ -}; - -static unsigned char maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -#define CONVERTTOASCII(c) -#define CONVERTFROMASCII(c) - -#define INIT_OFFSETS(name, var, default_offsets) \ - if ((name)->offsets != NULL) \ - var = (name)->offsets; \ - else \ - var = (default_offsets); - -#define SETUP_OFFSETS(name, var, default_offsets) \ - if ((name)->offsets != NULL) \ - var = (name)->offsets; \ - else { \ - var = (default_offsets); \ - set_offsets(name, var, NULL); \ - } - -/*% - * Note: If additional attributes are added that should not be set for - * empty names, MAKE_EMPTY() must be changed so it clears them. - */ -#define MAKE_EMPTY(name) \ -do { \ - name->ndata = NULL; \ - name->length = 0; \ - name->labels = 0; \ - name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ -} while (0); - -/*% - * A name is "bindable" if it can be set to point to a new value, i.e. - * name->ndata and name->length may be changed. - */ -#define BINDABLE(name) \ - ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \ - == 0) - -/*% - * Note that the name data must be a char array, not a string - * literal, to avoid compiler warnings about discarding - * the const attribute of a string. - */ -static unsigned char root_ndata[] = { "" }; -static unsigned char root_offsets[] = { 0 }; - -static dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets); -LIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root; - -static unsigned char wild_ndata[] = { "\001*" }; -static unsigned char wild_offsets[] = { 0 }; - -static dns_name_t wild = - DNS_NAME_INITNONABSOLUTE(wild_ndata, wild_offsets); - -/* XXXDCL make const? */ -LIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild; - -unsigned int -dns_fullname_hash(dns_name_t *name, bool case_sensitive); - -/* - * dns_name_t to text post-conversion procedure. - */ -#ifdef ISC_PLATFORM_USETHREADS -static int thread_key_initialized = 0; -static isc_mutex_t thread_key_mutex; -static isc_mem_t *thread_key_mctx = NULL; -static isc_thread_key_t totext_filter_proc_key; -static isc_once_t once = ISC_ONCE_INIT; -#else -static dns_name_totextfilter_t totext_filter_proc = NULL; -#endif - -static void -set_offsets(const dns_name_t *name, unsigned char *offsets, - dns_name_t *set_name); - -void -dns_name_init(dns_name_t *name, unsigned char *offsets) { - /* - * Initialize 'name'. - */ - DNS_NAME_INIT(name, offsets); -} - -void -dns_name_reset(dns_name_t *name) { - REQUIRE(VALID_NAME(name)); - REQUIRE(BINDABLE(name)); - - DNS_NAME_RESET(name); -} - -void -dns_name_invalidate(dns_name_t *name) { - /* - * Make 'name' invalid. - */ - - REQUIRE(VALID_NAME(name)); - - name->magic = 0; - name->ndata = NULL; - name->length = 0; - name->labels = 0; - name->attributes = 0; - name->offsets = NULL; - name->buffer = NULL; - ISC_LINK_INIT(name, link); -} - -bool -dns_name_isvalid(const dns_name_t *name) { - unsigned char *ndata, *offsets; - unsigned int offset, count, length, nlabels; - - if (!VALID_NAME(name)) - return (false); - - if (name->length > 255U || name->labels > 127U) - return (false); - - ndata = name->ndata; - length = name->length; - offsets = name->offsets; - offset = 0; - nlabels = 0; - - while (offset != length) { - count = *ndata; - if (count > 63U) - return (false); - if (offsets != NULL && offsets[nlabels] != offset) - return (false); - - nlabels++; - offset += count + 1; - ndata += count + 1; - if (offset > length) - return (false); - - if (count == 0) - break; - } - - if (nlabels != name->labels || offset != name->length) - return (false); - - return (true); -} - -void -dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) { - /* - * Dedicate a buffer for use with 'name'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE((buffer != NULL && name->buffer == NULL) || - (buffer == NULL)); - - name->buffer = buffer; -} - -bool -dns_name_hasbuffer(const dns_name_t *name) { - /* - * Does 'name' have a dedicated buffer? - */ - - REQUIRE(VALID_NAME(name)); - - if (name->buffer != NULL) - return (true); - - return (false); -} - -bool -dns_name_isabsolute(const dns_name_t *name) { - - /* - * Does 'name' end in the root label? - */ - - REQUIRE(VALID_NAME(name)); - - if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - return (true); - return (false); -} - -#define hyphenchar(c) ((c) == 0x2d) -#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) - -bool -dns_name_ismailbox(const dns_name_t *name) { - unsigned char *ndata, ch; - unsigned int n; - bool first; - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); - - /* - * Root label. - */ - if (name->length == 1) - return (true); - - ndata = name->ndata; - n = *ndata++; - INSIST(n <= 63); - while (n--) { - ch = *ndata++; - if (!domainchar(ch)) - return (false); - } - - if (ndata == name->ndata + name->length) - return (false); - - /* - * RFC292/RFC1123 hostname. - */ - while (ndata < (name->ndata + name->length)) { - n = *ndata++; - INSIST(n <= 63); - first = true; - while (n--) { - ch = *ndata++; - if (first || n == 0) { - if (!borderchar(ch)) - return (false); - } else { - if (!middlechar(ch)) - return (false); - } - first = false; - } - } - return (true); -} - -bool -dns_name_ishostname(const dns_name_t *name, bool wildcard) { - unsigned char *ndata, ch; - unsigned int n; - bool first; - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); - - /* - * Root label. - */ - if (name->length == 1) - return (true); - - /* - * Skip wildcard if this is a ownername. - */ - ndata = name->ndata; - if (wildcard && ndata[0] == 1 && ndata[1] == '*') - ndata += 2; - - /* - * RFC292/RFC1123 hostname. - */ - while (ndata < (name->ndata + name->length)) { - n = *ndata++; - INSIST(n <= 63); - first = true; - while (n--) { - ch = *ndata++; - if (first || n == 0) { - if (!borderchar(ch)) - return (false); - } else { - if (!middlechar(ch)) - return (false); - } - first = false; - } - } - return (true); -} - -bool -dns_name_iswildcard(const dns_name_t *name) { - unsigned char *ndata; - - /* - * Is 'name' a wildcard name? - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - - if (name->length >= 2) { - ndata = name->ndata; - if (ndata[0] == 1 && ndata[1] == '*') - return (true); - } - - return (false); -} - -bool -dns_name_internalwildcard(const dns_name_t *name) { - unsigned char *ndata; - unsigned int count; - unsigned int label; - - /* - * Does 'name' contain a internal wildcard? - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - - /* - * Skip first label. - */ - ndata = name->ndata; - count = *ndata++; - INSIST(count <= 63); - ndata += count; - label = 1; - /* - * Check all but the last of the remaining labels. - */ - while (label + 1 < name->labels) { - count = *ndata++; - INSIST(count <= 63); - if (count == 1 && *ndata == '*') - return (true); - ndata += count; - label++; - } - return (false); -} - -unsigned int -dns_name_hash(dns_name_t *name, bool case_sensitive) { - unsigned int length; - - /* - * Provide a hash value for 'name'. - */ - REQUIRE(VALID_NAME(name)); - - if (name->labels == 0) - return (0); - - length = name->length; - if (length > 16) - length = 16; - - return (isc_hash_function_reverse(name->ndata, length, - case_sensitive, NULL)); -} - -unsigned int -dns_name_fullhash(dns_name_t *name, bool case_sensitive) { - /* - * Provide a hash value for 'name'. - */ - REQUIRE(VALID_NAME(name)); - - if (name->labels == 0) - return (0); - - return (isc_hash_function_reverse(name->ndata, name->length, - case_sensitive, NULL)); -} - -unsigned int -dns_fullname_hash(dns_name_t *name, bool case_sensitive) { - /* - * This function was deprecated due to the breakage of the name space - * convention. We only keep this internally to provide binary backward - * compatibility. - */ - return (dns_name_fullhash(name, case_sensitive)); -} - -unsigned int -dns_name_hashbylabel(dns_name_t *name, bool case_sensitive) { - unsigned char *offsets; - dns_offsets_t odata; - dns_name_t tname; - unsigned int h = 0; - unsigned int i; - - /* - * Provide a hash value for 'name'. - */ - REQUIRE(VALID_NAME(name)); - - if (name->labels == 0) - return (0); - else if (name->labels == 1) - return (isc_hash_function_reverse(name->ndata, name->length, - case_sensitive, NULL)); - - SETUP_OFFSETS(name, offsets, odata); - DNS_NAME_INIT(&tname, NULL); - tname.labels = 1; - h = 0; - for (i = 0; i < name->labels; i++) { - tname.ndata = name->ndata + offsets[i]; - if (i == name->labels - 1) - tname.length = name->length - offsets[i]; - else - tname.length = offsets[i + 1] - offsets[i]; - h += isc_hash_function_reverse(tname.ndata, tname.length, - case_sensitive, NULL); - } - - return (h); -} - -dns_namereln_t -dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, - int *orderp, unsigned int *nlabelsp) -{ - unsigned int l1, l2, l, count1, count2, count, nlabels; - int cdiff, ldiff, chdiff; - unsigned char *label1, *label2; - unsigned char *offsets1, *offsets2; - dns_offsets_t odata1, odata2; - dns_namereln_t namereln = dns_namereln_none; - - /* - * Determine the relative ordering under the DNSSEC order relation of - * 'name1' and 'name2', and also determine the hierarchical - * relationship of the names. - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - */ - - REQUIRE(VALID_NAME(name1)); - REQUIRE(VALID_NAME(name2)); - REQUIRE(orderp != NULL); - REQUIRE(nlabelsp != NULL); - /* - * Either name1 is absolute and name2 is absolute, or neither is. - */ - REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == - (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); - - if (ISC_UNLIKELY(name1 == name2)) { - *orderp = 0; - *nlabelsp = name1->labels; - return (dns_namereln_equal); - } - - SETUP_OFFSETS(name1, offsets1, odata1); - SETUP_OFFSETS(name2, offsets2, odata2); - - nlabels = 0; - l1 = name1->labels; - l2 = name2->labels; - if (l2 > l1) { - l = l1; - ldiff = 0 - (l2 - l1); - } else { - l = l2; - ldiff = l1 - l2; - } - - offsets1 += l1; - offsets2 += l2; - - while (ISC_LIKELY(l > 0)) { - l--; - offsets1--; - offsets2--; - label1 = &name1->ndata[*offsets1]; - label2 = &name2->ndata[*offsets2]; - count1 = *label1++; - count2 = *label2++; - - /* - * We dropped bitstring labels, and we don't support any - * other extended label types. - */ - INSIST(count1 <= 63 && count2 <= 63); - - cdiff = (int)count1 - (int)count2; - if (cdiff < 0) - count = count1; - else - count = count2; - - /* Loop unrolled for performance */ - while (ISC_LIKELY(count > 3)) { - chdiff = (int)maptolower[label1[0]] - - (int)maptolower[label2[0]]; - if (chdiff != 0) { - *orderp = chdiff; - goto done; - } - chdiff = (int)maptolower[label1[1]] - - (int)maptolower[label2[1]]; - if (chdiff != 0) { - *orderp = chdiff; - goto done; - } - chdiff = (int)maptolower[label1[2]] - - (int)maptolower[label2[2]]; - if (chdiff != 0) { - *orderp = chdiff; - goto done; - } - chdiff = (int)maptolower[label1[3]] - - (int)maptolower[label2[3]]; - if (chdiff != 0) { - *orderp = chdiff; - goto done; - } - count -= 4; - label1 += 4; - label2 += 4; - } - while (ISC_LIKELY(count-- > 0)) { - chdiff = (int)maptolower[*label1++] - - (int)maptolower[*label2++]; - if (chdiff != 0) { - *orderp = chdiff; - goto done; - } - } - if (cdiff != 0) { - *orderp = cdiff; - goto done; - } - nlabels++; - } - - *orderp = ldiff; - if (ldiff < 0) - namereln = dns_namereln_contains; - else if (ldiff > 0) - namereln = dns_namereln_subdomain; - else - namereln = dns_namereln_equal; - *nlabelsp = nlabels; - return (namereln); - - done: - *nlabelsp = nlabels; - if (nlabels > 0) - namereln = dns_namereln_commonancestor; - - return (namereln); -} - -int -dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) { - int order; - unsigned int nlabels; - - /* - * Determine the relative ordering under the DNSSEC order relation of - * 'name1' and 'name2'. - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - */ - - (void)dns_name_fullcompare(name1, name2, &order, &nlabels); - - return (order); -} - -bool -dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { - unsigned int l, count; - unsigned char c; - unsigned char *label1, *label2; - - /* - * Are 'name1' and 'name2' equal? - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - */ - - REQUIRE(VALID_NAME(name1)); - REQUIRE(VALID_NAME(name2)); - /* - * Either name1 is absolute and name2 is absolute, or neither is. - */ - REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == - (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); - - if (ISC_UNLIKELY(name1 == name2)) - return (true); - - if (name1->length != name2->length) - return (false); - - l = name1->labels; - - if (l != name2->labels) - return (false); - - label1 = name1->ndata; - label2 = name2->ndata; - while (ISC_LIKELY(l-- > 0)) { - count = *label1++; - if (count != *label2++) - return (false); - - INSIST(count <= 63); /* no bitstring support */ - - /* Loop unrolled for performance */ - while (ISC_LIKELY(count > 3)) { - c = maptolower[label1[0]]; - if (c != maptolower[label2[0]]) - return (false); - c = maptolower[label1[1]]; - if (c != maptolower[label2[1]]) - return (false); - c = maptolower[label1[2]]; - if (c != maptolower[label2[2]]) - return (false); - c = maptolower[label1[3]]; - if (c != maptolower[label2[3]]) - return (false); - count -= 4; - label1 += 4; - label2 += 4; - } - while (ISC_LIKELY(count-- > 0)) { - c = maptolower[*label1++]; - if (c != maptolower[*label2++]) - return (false); - } - } - - return (true); -} - -bool -dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) { - - /* - * Are 'name1' and 'name2' equal? - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - */ - - REQUIRE(VALID_NAME(name1)); - REQUIRE(VALID_NAME(name2)); - /* - * Either name1 is absolute and name2 is absolute, or neither is. - */ - REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == - (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); - - if (name1->length != name2->length) - return (false); - - if (memcmp(name1->ndata, name2->ndata, name1->length) != 0) - return (false); - - return (true); -} - -int -dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { - unsigned int l1, l2, l, count1, count2, count; - unsigned char c1, c2; - unsigned char *label1, *label2; - - /* - * Compare two absolute names as rdata. - */ - - REQUIRE(VALID_NAME(name1)); - REQUIRE(name1->labels > 0); - REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); - REQUIRE(VALID_NAME(name2)); - REQUIRE(name2->labels > 0); - REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); - - l1 = name1->labels; - l2 = name2->labels; - - l = (l1 < l2) ? l1 : l2; - - label1 = name1->ndata; - label2 = name2->ndata; - while (l > 0) { - l--; - count1 = *label1++; - count2 = *label2++; - - /* no bitstring support */ - INSIST(count1 <= 63 && count2 <= 63); - - if (count1 != count2) - return ((count1 < count2) ? -1 : 1); - count = count1; - while (count > 0) { - count--; - c1 = maptolower[*label1++]; - c2 = maptolower[*label2++]; - if (c1 < c2) - return (-1); - else if (c1 > c2) - return (1); - } - } - - /* - * If one name had more labels than the other, their common - * prefix must have been different because the shorter name - * ended with the root label and the longer one can't have - * a root label in the middle of it. Therefore, if we get - * to this point, the lengths must be equal. - */ - INSIST(l1 == l2); - - return (0); -} - -bool -dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) { - int order; - unsigned int nlabels; - dns_namereln_t namereln; - - /* - * Is 'name1' a subdomain of 'name2'? - * - * Note: It makes no sense for one of the names to be relative and the - * other absolute. If both names are relative, then to be meaningfully - * compared the caller must ensure that they are both relative to the - * same domain. - */ - - namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); - if (namereln == dns_namereln_subdomain || - namereln == dns_namereln_equal) - return (true); - - return (false); -} - -bool -dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { - int order; - unsigned int nlabels, labels; - dns_name_t tname; - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - REQUIRE(VALID_NAME(wname)); - labels = wname->labels; - REQUIRE(labels > 0); - REQUIRE(dns_name_iswildcard(wname)); - -#if defined(__clang__) && \ - ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) - memset(&tname, 0, sizeof(tname)); -#endif - DNS_NAME_INIT(&tname, NULL); - dns_name_getlabelsequence(wname, 1, labels - 1, &tname); - if (dns_name_fullcompare(name, &tname, &order, &nlabels) == - dns_namereln_subdomain) - return (true); - return (false); -} - -unsigned int -dns_name_countlabels(const dns_name_t *name) { - /* - * How many labels does 'name' have? - */ - - REQUIRE(VALID_NAME(name)); - - ENSURE(name->labels <= 128); - - return (name->labels); -} - -void -dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) { - unsigned char *offsets; - dns_offsets_t odata; - - /* - * Make 'label' refer to the 'n'th least significant label of 'name'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(name->labels > 0); - REQUIRE(n < name->labels); - REQUIRE(label != NULL); - - SETUP_OFFSETS(name, offsets, odata); - - label->base = &name->ndata[offsets[n]]; - if (n == name->labels - 1) - label->length = name->length - offsets[n]; - else - label->length = offsets[n + 1] - offsets[n]; -} - -void -dns_name_getlabelsequence(const dns_name_t *source, - unsigned int first, unsigned int n, - dns_name_t *target) -{ - unsigned char *p, l; - unsigned int firstoffset, endoffset; - unsigned int i; - - /* - * Make 'target' refer to the 'n' labels including and following - * 'first' in 'source'. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(VALID_NAME(target)); - REQUIRE(first <= source->labels); - REQUIRE(n <= source->labels - first); /* note first+n could overflow */ - REQUIRE(BINDABLE(target)); - - p = source->ndata; - if (ISC_UNLIKELY(first == source->labels)) { - firstoffset = source->length; - } else { - for (i = 0; i < first; i++) { - l = *p; - p += l + 1; - } - firstoffset = p - source->ndata; - } - - if (ISC_LIKELY(first + n == source->labels)) - endoffset = source->length; - else { - for (i = 0; i < n; i++) { - l = *p; - p += l + 1; - } - endoffset = p - source->ndata; - } - - target->ndata = &source->ndata[firstoffset]; - target->length = endoffset - firstoffset; - - if (first + n == source->labels && n > 0 && - (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - target->attributes |= DNS_NAMEATTR_ABSOLUTE; - else - target->attributes &= ~DNS_NAMEATTR_ABSOLUTE; - - target->labels = n; - - /* - * If source and target are the same, and we're making target - * a prefix of source, the offsets table is correct already - * so we don't need to call set_offsets(). - */ - if (target->offsets != NULL && - (target != source || first != 0)) - set_offsets(target, target->offsets, NULL); -} - -void -dns_name_clone(const dns_name_t *source, dns_name_t *target) { - - /* - * Make 'target' refer to the same name as 'source'. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(VALID_NAME(target)); - REQUIRE(BINDABLE(target)); - - target->ndata = source->ndata; - target->length = source->length; - target->labels = source->labels; - target->attributes = source->attributes & - (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC | - DNS_NAMEATTR_DYNOFFSETS); - if (target->offsets != NULL && source->labels > 0) { - if (source->offsets != NULL) - memmove(target->offsets, source->offsets, - source->labels); - else - set_offsets(target, target->offsets, NULL); - } -} - -void -dns_name_fromregion(dns_name_t *name, const isc_region_t *r) { - unsigned char *offsets; - dns_offsets_t odata; - unsigned int len; - isc_region_t r2; - - /* - * Make 'name' refer to region 'r'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(r != NULL); - REQUIRE(BINDABLE(name)); - - INIT_OFFSETS(name, offsets, odata); - - if (name->buffer != NULL) { - isc_buffer_clear(name->buffer); - isc_buffer_availableregion(name->buffer, &r2); - len = (r->length < r2.length) ? r->length : r2.length; - if (len > DNS_NAME_MAXWIRE) - len = DNS_NAME_MAXWIRE; - if (len != 0) - memmove(r2.base, r->base, len); - name->ndata = r2.base; - name->length = len; - } else { - name->ndata = r->base; - name->length = (r->length <= DNS_NAME_MAXWIRE) ? - r->length : DNS_NAME_MAXWIRE; - } - - if (r->length > 0) - set_offsets(name, offsets, name); - else { - name->labels = 0; - name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; - } - - if (name->buffer != NULL) - isc_buffer_add(name->buffer, name->length); -} - -void -dns_name_toregion(dns_name_t *name, isc_region_t *r) { - /* - * Make 'r' refer to 'name'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(r != NULL); - - DNS_NAME_TOREGION(name, r); -} - -isc_result_t -dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, - const dns_name_t *origin, unsigned int options, - isc_buffer_t *target) -{ - unsigned char *ndata, *label = NULL; - char *tdata; - char c; - ft_state state; - unsigned int value = 0, count = 0; - unsigned int n1 = 0, n2 = 0; - unsigned int tlen, nrem, nused, digits = 0, labels, tused; - bool done; - unsigned char *offsets; - dns_offsets_t odata; - bool downcase; - - /* - * Convert the textual representation of a DNS name at source - * into uncompressed wire form stored in target. - * - * Notes: - * Relative domain names will have 'origin' appended to them - * unless 'origin' is NULL, in which case relative domain names - * will remain relative. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(ISC_BUFFER_VALID(source)); - REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || - (target == NULL && ISC_BUFFER_VALID(name->buffer))); - - downcase = ((options & DNS_NAME_DOWNCASE) != 0); - - if (target == NULL && name->buffer != NULL) { - target = name->buffer; - isc_buffer_clear(target); - } - - REQUIRE(BINDABLE(name)); - - INIT_OFFSETS(name, offsets, odata); - offsets[0] = 0; - - /* - * Make 'name' empty in case of failure. - */ - MAKE_EMPTY(name); - - /* - * Set up the state machine. - */ - tdata = (char *)source->base + source->current; - tlen = isc_buffer_remaininglength(source); - tused = 0; - ndata = isc_buffer_used(target); - nrem = isc_buffer_availablelength(target); - if (nrem > 255) - nrem = 255; - nused = 0; - labels = 0; - done = false; - state = ft_init; - - while (nrem > 0 && tlen > 0 && !done) { - c = *tdata++; - tlen--; - tused++; - - switch (state) { - case ft_init: - /* - * Is this the root name? - */ - if (c == '.') { - if (tlen != 0) - return (DNS_R_EMPTYLABEL); - labels++; - *ndata++ = 0; - nrem--; - nused++; - done = true; - break; - } - if (c == '@' && tlen == 0) { - state = ft_at; - break; - } - - /* FALLTHROUGH */ - case ft_start: - label = ndata; - ndata++; - nrem--; - nused++; - count = 0; - if (c == '\\') { - state = ft_initialescape; - break; - } - state = ft_ordinary; - if (nrem == 0) - return (ISC_R_NOSPACE); - /* FALLTHROUGH */ - case ft_ordinary: - if (c == '.') { - if (count == 0) - return (DNS_R_EMPTYLABEL); - *label = count; - labels++; - INSIST(labels <= 127); - offsets[labels] = nused; - if (tlen == 0) { - labels++; - *ndata++ = 0; - nrem--; - nused++; - done = true; - } - state = ft_start; - } else if (c == '\\') { - state = ft_escape; - } else { - if (count >= 63) - return (DNS_R_LABELTOOLONG); - count++; - CONVERTTOASCII(c); - if (downcase) - c = maptolower[c & 0xff]; - *ndata++ = c; - nrem--; - nused++; - } - break; - case ft_initialescape: - if (c == '[') { - /* - * This looks like a bitstring label, which - * was deprecated. Intentionally drop it. - */ - return (DNS_R_BADLABELTYPE); - } - state = ft_escape; - POST(state); - /* FALLTHROUGH */ - case ft_escape: - if (!isdigit(c & 0xff)) { - if (count >= 63) - return (DNS_R_LABELTOOLONG); - count++; - CONVERTTOASCII(c); - if (downcase) - c = maptolower[c & 0xff]; - *ndata++ = c; - nrem--; - nused++; - state = ft_ordinary; - break; - } - digits = 0; - value = 0; - state = ft_escdecimal; - /* FALLTHROUGH */ - case ft_escdecimal: - if (!isdigit(c & 0xff)) - return (DNS_R_BADESCAPE); - value *= 10; - value += digitvalue[c & 0xff]; - digits++; - if (digits == 3) { - if (value > 255) - return (DNS_R_BADESCAPE); - if (count >= 63) - return (DNS_R_LABELTOOLONG); - count++; - if (downcase) - value = maptolower[value]; - *ndata++ = value; - nrem--; - nused++; - state = ft_ordinary; - } - break; - default: - FATAL_ERROR(__FILE__, __LINE__, - "Unexpected state %d", state); - /* Does not return. */ - } - } - - if (!done) { - if (nrem == 0) - return (ISC_R_NOSPACE); - INSIST(tlen == 0); - if (state != ft_ordinary && state != ft_at) - return (ISC_R_UNEXPECTEDEND); - if (state == ft_ordinary) { - INSIST(count != 0); - *label = count; - labels++; - INSIST(labels <= 127); - offsets[labels] = nused; - } - if (origin != NULL) { - if (nrem < origin->length) - return (ISC_R_NOSPACE); - label = origin->ndata; - n1 = origin->length; - nrem -= n1; - POST(nrem); - while (n1 > 0) { - n2 = *label++; - INSIST(n2 <= 63); /* no bitstring support */ - *ndata++ = n2; - n1 -= n2 + 1; - nused += n2 + 1; - while (n2 > 0) { - c = *label++; - if (downcase) - c = maptolower[c & 0xff]; - *ndata++ = c; - n2--; - } - labels++; - if (n1 > 0) { - INSIST(labels <= 127); - offsets[labels] = nused; - } - } - if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - name->attributes |= DNS_NAMEATTR_ABSOLUTE; - } - } else - name->attributes |= DNS_NAMEATTR_ABSOLUTE; - - name->ndata = (unsigned char *)target->base + target->used; - name->labels = labels; - name->length = nused; - - isc_buffer_forward(source, tused); - isc_buffer_add(target, name->length); - - return (ISC_R_SUCCESS); -} - -#ifdef ISC_PLATFORM_USETHREADS -static void -free_specific(void *arg) { - dns_name_totextfilter_t *mem = arg; - isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); - /* Stop use being called again. */ - (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL); -} - -static void -thread_key_mutex_init(void) { - RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS); -} - -static isc_result_t -totext_filter_proc_key_init(void) { - isc_result_t result; - - /* - * We need the call to isc_once_do() to support profiled mutex - * otherwise thread_key_mutex could be initialized at compile time. - */ - result = isc_once_do(&once, thread_key_mutex_init); - if (result != ISC_R_SUCCESS) - return (result); - - if (!thread_key_initialized) { - LOCK(&thread_key_mutex); - if (thread_key_mctx == NULL) - result = isc_mem_create2(0, 0, &thread_key_mctx, 0); - if (result != ISC_R_SUCCESS) - goto unlock; - isc_mem_setname(thread_key_mctx, "threadkey", NULL); - isc_mem_setdestroycheck(thread_key_mctx, false); - - if (!thread_key_initialized && - isc_thread_key_create(&totext_filter_proc_key, - free_specific) != 0) { - result = ISC_R_FAILURE; - isc_mem_detach(&thread_key_mctx); - } else - thread_key_initialized = 1; - unlock: - UNLOCK(&thread_key_mutex); - } - return (result); -} -#endif - -isc_result_t -dns_name_totext(const dns_name_t *name, bool omit_final_dot, - isc_buffer_t *target) -{ - unsigned int options = DNS_NAME_MASTERFILE; - - if (omit_final_dot) - options |= DNS_NAME_OMITFINALDOT; - return (dns_name_totext2(name, options, target)); -} - -isc_result_t -dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) { - return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target)); -} - -isc_result_t -dns_name_totext2(const dns_name_t *name, unsigned int options, - isc_buffer_t *target) -{ - unsigned char *ndata; - char *tdata; - unsigned int nlen, tlen; - unsigned char c; - unsigned int trem, count; - unsigned int labels; - bool saw_root = false; - unsigned int oused; -#ifdef ISC_PLATFORM_USETHREADS - dns_name_totextfilter_t *mem; - dns_name_totextfilter_t totext_filter_proc = NULL; - isc_result_t result; -#endif - bool omit_final_dot = ((options & DNS_NAME_OMITFINALDOT) != 0); - - /* - * This function assumes the name is in proper uncompressed - * wire format. - */ - REQUIRE(VALID_NAME(name)); - REQUIRE(ISC_BUFFER_VALID(target)); - - oused = target->used; - -#ifdef ISC_PLATFORM_USETHREADS - result = totext_filter_proc_key_init(); - if (result != ISC_R_SUCCESS) - return (result); -#endif - ndata = name->ndata; - nlen = name->length; - labels = name->labels; - tdata = isc_buffer_used(target); - tlen = isc_buffer_availablelength(target); - - trem = tlen; - - if (labels == 0 && nlen == 0) { - /* - * Special handling for an empty name. - */ - if (trem == 0) - return (ISC_R_NOSPACE); - - /* - * The names of these booleans are misleading in this case. - * This empty name is not necessarily from the root node of - * the DNS root zone, nor is a final dot going to be included. - * They need to be set this way, though, to keep the "@" - * from being trounced. - */ - saw_root = true; - omit_final_dot = false; - *tdata++ = '@'; - trem--; - - /* - * Skip the while() loop. - */ - nlen = 0; - } else if (nlen == 1 && labels == 1 && *ndata == '\0') { - /* - * Special handling for the root label. - */ - if (trem == 0) - return (ISC_R_NOSPACE); - - saw_root = true; - omit_final_dot = false; - *tdata++ = '.'; - trem--; - - /* - * Skip the while() loop. - */ - nlen = 0; - } - - while (labels > 0 && nlen > 0 && trem > 0) { - labels--; - count = *ndata++; - nlen--; - if (count == 0) { - saw_root = true; - break; - } - if (count < 64) { - INSIST(nlen >= count); - while (count > 0) { - c = *ndata; - switch (c) { - /* Special modifiers in zone files. */ - case 0x40: /* '@' */ - case 0x24: /* '$' */ - if ((options & DNS_NAME_MASTERFILE) == 0) - goto no_escape; - /* FALLTHROUGH */ - case 0x22: /* '"' */ - case 0x28: /* '(' */ - case 0x29: /* ')' */ - case 0x2E: /* '.' */ - case 0x3B: /* ';' */ - case 0x5C: /* '\\' */ - if (trem < 2) - return (ISC_R_NOSPACE); - *tdata++ = '\\'; - CONVERTFROMASCII(c); - *tdata++ = c; - ndata++; - trem -= 2; - nlen--; - break; - no_escape: - default: - if (c > 0x20 && c < 0x7f) { - if (trem == 0) - return (ISC_R_NOSPACE); - CONVERTFROMASCII(c); - *tdata++ = c; - ndata++; - trem--; - nlen--; - } else { - if (trem < 4) - return (ISC_R_NOSPACE); - *tdata++ = 0x5c; - *tdata++ = 0x30 + - ((c / 100) % 10); - *tdata++ = 0x30 + - ((c / 10) % 10); - *tdata++ = 0x30 + (c % 10); - trem -= 4; - ndata++; - nlen--; - } - } - count--; - } - } else { - FATAL_ERROR(__FILE__, __LINE__, - "Unexpected label type %02x", count); - /* NOTREACHED */ - } - - /* - * The following assumes names are absolute. If not, we - * fix things up later. Note that this means that in some - * cases one more byte of text buffer is required than is - * needed in the final output. - */ - if (trem == 0) - return (ISC_R_NOSPACE); - *tdata++ = '.'; - trem--; - } - - if (nlen != 0 && trem == 0) - return (ISC_R_NOSPACE); - - if (!saw_root || omit_final_dot) { - trem++; - tdata--; - } - if (trem > 0) { - *tdata = 0; - } - isc_buffer_add(target, tlen - trem); - -#ifdef ISC_PLATFORM_USETHREADS - mem = isc_thread_key_getspecific(totext_filter_proc_key); - if (mem != NULL) - totext_filter_proc = *mem; -#endif - if (totext_filter_proc != NULL) - return ((*totext_filter_proc)(target, oused, saw_root)); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_name_tofilenametext(dns_name_t *name, bool omit_final_dot, - isc_buffer_t *target) -{ - unsigned char *ndata; - char *tdata; - unsigned int nlen, tlen; - unsigned char c; - unsigned int trem, count; - unsigned int labels; - - /* - * This function assumes the name is in proper uncompressed - * wire format. - */ - REQUIRE(VALID_NAME(name)); - REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); - REQUIRE(ISC_BUFFER_VALID(target)); - - ndata = name->ndata; - nlen = name->length; - labels = name->labels; - tdata = isc_buffer_used(target); - tlen = isc_buffer_availablelength(target); - - trem = tlen; - - if (nlen == 1 && labels == 1 && *ndata == '\0') { - /* - * Special handling for the root label. - */ - if (trem == 0) - return (ISC_R_NOSPACE); - - omit_final_dot = false; - *tdata++ = '.'; - trem--; - - /* - * Skip the while() loop. - */ - nlen = 0; - } - - while (labels > 0 && nlen > 0 && trem > 0) { - labels--; - count = *ndata++; - nlen--; - if (count == 0) - break; - if (count < 64) { - INSIST(nlen >= count); - while (count > 0) { - c = *ndata; - if ((c >= 0x30 && c <= 0x39) || /* digit */ - (c >= 0x41 && c <= 0x5A) || /* uppercase */ - (c >= 0x61 && c <= 0x7A) || /* lowercase */ - c == 0x2D || /* hyphen */ - c == 0x5F) /* underscore */ - { - if (trem == 0) - return (ISC_R_NOSPACE); - /* downcase */ - if (c >= 0x41 && c <= 0x5A) - c += 0x20; - CONVERTFROMASCII(c); - *tdata++ = c; - ndata++; - trem--; - nlen--; - } else { - if (trem < 4) - return (ISC_R_NOSPACE); - snprintf(tdata, trem, "%%%02X", c); - tdata += 3; - trem -= 3; - ndata++; - nlen--; - } - count--; - } - } else { - FATAL_ERROR(__FILE__, __LINE__, - "Unexpected label type %02x", count); - /* NOTREACHED */ - } - - /* - * The following assumes names are absolute. If not, we - * fix things up later. Note that this means that in some - * cases one more byte of text buffer is required than is - * needed in the final output. - */ - if (trem == 0) - return (ISC_R_NOSPACE); - *tdata++ = '.'; - trem--; - } - - if (nlen != 0 && trem == 0) - return (ISC_R_NOSPACE); - - if (omit_final_dot) - trem++; - - isc_buffer_add(target, tlen - trem); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) { - unsigned char *sndata, *ndata; - unsigned int nlen, count, labels; - isc_buffer_t buffer; - - /* - * Downcase 'source'. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(VALID_NAME(name)); - if (source == name) { - REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0); - isc_buffer_init(&buffer, source->ndata, source->length); - target = &buffer; - ndata = source->ndata; - } else { - REQUIRE(BINDABLE(name)); - REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || - (target == NULL && ISC_BUFFER_VALID(name->buffer))); - if (target == NULL) { - target = name->buffer; - isc_buffer_clear(name->buffer); - } - ndata = (unsigned char *)target->base + target->used; - name->ndata = ndata; - } - - sndata = source->ndata; - nlen = source->length; - labels = source->labels; - - if (nlen > (target->length - target->used)) { - MAKE_EMPTY(name); - return (ISC_R_NOSPACE); - } - - while (labels > 0 && nlen > 0) { - labels--; - count = *sndata++; - *ndata++ = count; - nlen--; - if (count < 64) { - INSIST(nlen >= count); - while (count > 0) { - *ndata++ = maptolower[(*sndata++)]; - nlen--; - count--; - } - } else { - FATAL_ERROR(__FILE__, __LINE__, - "Unexpected label type %02x", count); - /* Does not return. */ - } - } - - if (source != name) { - name->labels = source->labels; - name->length = source->length; - if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - name->attributes = DNS_NAMEATTR_ABSOLUTE; - else - name->attributes = 0; - if (name->labels > 0 && name->offsets != NULL) - set_offsets(name, name->offsets, NULL); - } - - isc_buffer_add(target, name->length); - - return (ISC_R_SUCCESS); -} - -static void -set_offsets(const dns_name_t *name, unsigned char *offsets, - dns_name_t *set_name) -{ - unsigned int offset, count, length, nlabels; - unsigned char *ndata; - bool absolute; - - ndata = name->ndata; - length = name->length; - offset = 0; - nlabels = 0; - absolute = false; - while (ISC_LIKELY(offset != length)) { - INSIST(nlabels < 128); - offsets[nlabels++] = offset; - count = *ndata; - INSIST(count <= 63); - offset += count + 1; - ndata += count + 1; - INSIST(offset <= length); - if (ISC_UNLIKELY(count == 0)) { - absolute = true; - break; - } - } - if (set_name != NULL) { - INSIST(set_name == name); - - set_name->labels = nlabels; - set_name->length = offset; - if (absolute) - set_name->attributes |= DNS_NAMEATTR_ABSOLUTE; - else - set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; - } - INSIST(nlabels == name->labels); - INSIST(offset == name->length); -} - -isc_result_t -dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, - dns_decompress_t *dctx, unsigned int options, - isc_buffer_t *target) -{ - unsigned char *cdata, *ndata; - unsigned int cused; /* Bytes of compressed name data used */ - unsigned int nused, labels, n, nmax; - unsigned int current, new_current, biggest_pointer; - bool done; - fw_state state = fw_start; - unsigned int c; - unsigned char *offsets; - dns_offsets_t odata; - bool downcase; - bool seen_pointer; - - /* - * Copy the possibly-compressed name at source into target, - * decompressing it. Loop prevention is performed by checking - * the new pointer against biggest_pointer. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || - (target == NULL && ISC_BUFFER_VALID(name->buffer))); - - downcase = ((options & DNS_NAME_DOWNCASE) != 0); - - if (target == NULL && name->buffer != NULL) { - target = name->buffer; - isc_buffer_clear(target); - } - - REQUIRE(dctx != NULL); - REQUIRE(BINDABLE(name)); - - INIT_OFFSETS(name, offsets, odata); - - /* - * Make 'name' empty in case of failure. - */ - MAKE_EMPTY(name); - - /* - * Initialize things to make the compiler happy; they're not required. - */ - n = 0; - new_current = 0; - - /* - * Set up. - */ - labels = 0; - done = false; - - ndata = isc_buffer_used(target); - nused = 0; - seen_pointer = false; - - /* - * Find the maximum number of uncompressed target name - * bytes we are willing to generate. This is the smaller - * of the available target buffer length and the - * maximum legal domain name length (255). - */ - nmax = isc_buffer_availablelength(target); - if (nmax > DNS_NAME_MAXWIRE) - nmax = DNS_NAME_MAXWIRE; - - cdata = isc_buffer_current(source); - cused = 0; - - current = source->current; - biggest_pointer = current; - - /* - * Note: The following code is not optimized for speed, but - * rather for correctness. Speed will be addressed in the future. - */ - - while (current < source->active && !done) { - c = *cdata++; - current++; - if (!seen_pointer) - cused++; - - switch (state) { - case fw_start: - if (c < 64) { - offsets[labels] = nused; - labels++; - if (nused + c + 1 > nmax) - goto full; - nused += c + 1; - *ndata++ = c; - if (c == 0) - done = true; - n = c; - state = fw_ordinary; - } else if (c >= 128 && c < 192) { - /* - * 14 bit local compression pointer. - * Local compression is no longer an - * IETF draft. - */ - return (DNS_R_BADLABELTYPE); - } else if (c >= 192) { - /* - * Ordinary 14-bit pointer. - */ - if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) == 0) - { - return (DNS_R_DISALLOWED); - } - new_current = c & 0x3F; - state = fw_newcurrent; - } else - return (DNS_R_BADLABELTYPE); - break; - case fw_ordinary: - if (downcase) - c = maptolower[c]; - *ndata++ = c; - n--; - if (n == 0) - state = fw_start; - break; - case fw_newcurrent: - new_current *= 256; - new_current += c; - if (new_current >= biggest_pointer) - return (DNS_R_BADPOINTER); - biggest_pointer = new_current; - current = new_current; - cdata = (unsigned char *)source->base + current; - seen_pointer = true; - state = fw_start; - break; - default: - FATAL_ERROR(__FILE__, __LINE__, - "Unknown state %d", state); - /* Does not return. */ - } - } - - if (!done) - return (ISC_R_UNEXPECTEDEND); - - name->ndata = (unsigned char *)target->base + target->used; - name->labels = labels; - name->length = nused; - name->attributes |= DNS_NAMEATTR_ABSOLUTE; - - isc_buffer_forward(source, cused); - isc_buffer_add(target, name->length); - - return (ISC_R_SUCCESS); - - full: - if (nmax == DNS_NAME_MAXWIRE) - /* - * The name did not fit even though we had a buffer - * big enough to fit a maximum-length name. - */ - return (DNS_R_NAMETOOLONG); - else - /* - * The name might fit if only the caller could give us a - * big enough buffer. - */ - return (ISC_R_NOSPACE); -} - -isc_result_t -dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, - isc_buffer_t *target) -{ - unsigned int methods; - uint16_t offset; - dns_name_t gp; /* Global compression prefix */ - bool gf; /* Global compression target found */ - uint16_t go; /* Global compression offset */ - dns_offsets_t clo; - dns_name_t clname; - - /* - * Convert 'name' into wire format, compressing it as specified by the - * compression context 'cctx', and storing the result in 'target'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(cctx != NULL); - REQUIRE(ISC_BUFFER_VALID(target)); - - /* - * If 'name' doesn't have an offsets table, make a clone which - * has one. - */ - if (name->offsets == NULL) { -#if defined(__clang__) && \ - ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) - memset(&clname, 0, sizeof(clname)); -#endif - DNS_NAME_INIT(&clname, clo); - dns_name_clone(name, &clname); - name = &clname; - } - DNS_NAME_INIT(&gp, NULL); - - offset = target->used; /*XXX*/ - - methods = dns_compress_getmethods(cctx); - - if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 && - (methods & DNS_COMPRESS_GLOBAL14) != 0) - gf = dns_compress_findglobal(cctx, name, &gp, &go); - else - gf = false; - - /* - * If the offset is too high for 14 bit global compression, we're - * out of luck. - */ - if (gf && go >= 0x4000) - gf = false; - - /* - * Will the compression pointer reduce the message size? - */ - if (gf && (gp.length + 2) >= name->length) - gf = false; - - if (gf) { - if (target->length - target->used < gp.length) - return (ISC_R_NOSPACE); - if (gp.length != 0) { - unsigned char *base = target->base; - (void)memmove(base + target->used, gp.ndata, - (size_t)gp.length); - } - isc_buffer_add(target, gp.length); - go |= 0xc000; - if (target->length - target->used < 2) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(target, go); - if (gp.length != 0) - dns_compress_add(cctx, name, &gp, offset); - } else { - if (target->length - target->used < name->length) - return (ISC_R_NOSPACE); - if (name->length != 0) { - unsigned char *base = target->base; - (void)memmove(base + target->used, name->ndata, - (size_t)name->length); - } - isc_buffer_add(target, name->length); - dns_compress_add(cctx, name, name, offset); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, - isc_buffer_t *target) -{ - unsigned char *ndata, *offsets; - unsigned int nrem, labels, prefix_length, length; - bool copy_prefix = true; - bool copy_suffix = true; - bool absolute = false; - dns_name_t tmp_name; - dns_offsets_t odata; - - /* - * Concatenate 'prefix' and 'suffix'. - */ - - REQUIRE(prefix == NULL || VALID_NAME(prefix)); - REQUIRE(suffix == NULL || VALID_NAME(suffix)); - REQUIRE(name == NULL || VALID_NAME(name)); - REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || - (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer))); - if (prefix == NULL || prefix->labels == 0) - copy_prefix = false; - if (suffix == NULL || suffix->labels == 0) - copy_suffix = false; - if (copy_prefix && - (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { - absolute = true; - REQUIRE(!copy_suffix); - } - if (name == NULL) { - DNS_NAME_INIT(&tmp_name, odata); - name = &tmp_name; - } - if (target == NULL) { - INSIST(name->buffer != NULL); - target = name->buffer; - isc_buffer_clear(name->buffer); - } - - REQUIRE(BINDABLE(name)); - - /* - * Set up. - */ - nrem = target->length - target->used; - ndata = (unsigned char *)target->base + target->used; - if (nrem > DNS_NAME_MAXWIRE) - nrem = DNS_NAME_MAXWIRE; - length = 0; - prefix_length = 0; - labels = 0; - if (copy_prefix) { - prefix_length = prefix->length; - length += prefix_length; - labels += prefix->labels; - } - if (copy_suffix) { - length += suffix->length; - labels += suffix->labels; - } - if (length > DNS_NAME_MAXWIRE) { - MAKE_EMPTY(name); - return (DNS_R_NAMETOOLONG); - } - if (length > nrem) { - MAKE_EMPTY(name); - return (ISC_R_NOSPACE); - } - - if (copy_suffix) { - if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - absolute = true; - memmove(ndata + prefix_length, suffix->ndata, suffix->length); - } - - /* - * If 'prefix' and 'name' are the same object, and the object has - * a dedicated buffer, and we're using it, then we don't have to - * copy anything. - */ - if (copy_prefix && (prefix != name || prefix->buffer != target)) - memmove(ndata, prefix->ndata, prefix_length); - - name->ndata = ndata; - name->labels = labels; - name->length = length; - if (absolute) - name->attributes = DNS_NAMEATTR_ABSOLUTE; - else - name->attributes = 0; - - if (name->labels > 0 && name->offsets != NULL) { - INIT_OFFSETS(name, offsets, odata); - set_offsets(name, offsets, NULL); - } - - isc_buffer_add(target, name->length); - - return (ISC_R_SUCCESS); -} - -void -dns_name_split(dns_name_t *name, unsigned int suffixlabels, - dns_name_t *prefix, dns_name_t *suffix) - -{ - unsigned int splitlabel; - - REQUIRE(VALID_NAME(name)); - REQUIRE(suffixlabels > 0); - REQUIRE(suffixlabels <= name->labels); - REQUIRE(prefix != NULL || suffix != NULL); - REQUIRE(prefix == NULL || - (VALID_NAME(prefix) && - BINDABLE(prefix))); - REQUIRE(suffix == NULL || - (VALID_NAME(suffix) && - BINDABLE(suffix))); - - splitlabel = name->labels - suffixlabels; - - if (prefix != NULL) - dns_name_getlabelsequence(name, 0, splitlabel, prefix); - - if (suffix != NULL) - dns_name_getlabelsequence(name, splitlabel, - suffixlabels, suffix); - - return; -} - -isc_result_t -dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, - dns_name_t *target) -{ - /* - * Make 'target' a dynamically allocated copy of 'source'. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(source->length > 0); - REQUIRE(VALID_NAME(target)); - REQUIRE(BINDABLE(target)); - - /* - * Make 'target' empty in case of failure. - */ - MAKE_EMPTY(target); - - target->ndata = isc_mem_get(mctx, source->length); - if (target->ndata == NULL) - return (ISC_R_NOMEMORY); - - memmove(target->ndata, source->ndata, source->length); - - target->length = source->length; - target->labels = source->labels; - target->attributes = DNS_NAMEATTR_DYNAMIC; - if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - target->attributes |= DNS_NAMEATTR_ABSOLUTE; - if (target->offsets != NULL) { - if (source->offsets != NULL) - memmove(target->offsets, source->offsets, - source->labels); - else - set_offsets(target, target->offsets, NULL); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, - dns_name_t *target) -{ - /* - * Make 'target' a read-only dynamically allocated copy of 'source'. - * 'target' will also have a dynamically allocated offsets table. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(source->length > 0); - REQUIRE(VALID_NAME(target)); - REQUIRE(BINDABLE(target)); - REQUIRE(target->offsets == NULL); - - /* - * Make 'target' empty in case of failure. - */ - MAKE_EMPTY(target); - - target->ndata = isc_mem_get(mctx, source->length + source->labels); - if (target->ndata == NULL) - return (ISC_R_NOMEMORY); - - memmove(target->ndata, source->ndata, source->length); - - target->length = source->length; - target->labels = source->labels; - target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS | - DNS_NAMEATTR_READONLY; - if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - target->attributes |= DNS_NAMEATTR_ABSOLUTE; - target->offsets = target->ndata + source->length; - if (source->offsets != NULL) - memmove(target->offsets, source->offsets, source->labels); - else - set_offsets(target, target->offsets, NULL); - - return (ISC_R_SUCCESS); -} - -void -dns_name_free(dns_name_t *name, isc_mem_t *mctx) { - size_t size; - - /* - * Free 'name'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0); - - size = name->length; - if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0) - size += name->labels; - isc_mem_put(mctx, name->ndata, size); - dns_name_invalidate(name); -} - -isc_result_t -dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { - dns_name_t downname; - unsigned char data[256]; - isc_buffer_t buffer; - isc_result_t result; - isc_region_t r; - - /* - * Send 'name' in DNSSEC canonical form to 'digest'. - */ - - REQUIRE(VALID_NAME(name)); - REQUIRE(digest != NULL); - -#if defined(__clang__) && \ - ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) - memset(&downname, 0, sizeof(downname)); -#endif - DNS_NAME_INIT(&downname, NULL); - - isc_buffer_init(&buffer, data, sizeof(data)); - - result = dns_name_downcase(name, &downname, &buffer); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_usedregion(&buffer, &r); - - return ((digest)(arg, &r)); -} - -bool -dns_name_dynamic(dns_name_t *name) { - REQUIRE(VALID_NAME(name)); - - /* - * Returns whether there is dynamic memory associated with this name. - */ - - return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ? - true : false); -} - -isc_result_t -dns_name_print(dns_name_t *name, FILE *stream) { - isc_result_t result; - isc_buffer_t b; - isc_region_t r; - char t[1024]; - - /* - * Print 'name' on 'stream'. - */ - - REQUIRE(VALID_NAME(name)); - - isc_buffer_init(&b, t, sizeof(t)); - result = dns_name_totext(name, false, &b); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_usedregion(&b, &r); - fprintf(stream, "%.*s", (int)r.length, (char *)r.base); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_name_settotextfilter(dns_name_totextfilter_t proc) { -#ifdef ISC_PLATFORM_USETHREADS - isc_result_t result; - dns_name_totextfilter_t *mem; - int res; - - result = totext_filter_proc_key_init(); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * If we already have been here set / clear as appropriate. - * Otherwise allocate memory. - */ - mem = isc_thread_key_getspecific(totext_filter_proc_key); - if (mem != NULL && proc != NULL) { - *mem = proc; - return (ISC_R_SUCCESS); - } - if (proc == NULL) { - if (mem != NULL) - isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); - res = isc_thread_key_setspecific(totext_filter_proc_key, NULL); - if (res != 0) - result = ISC_R_UNEXPECTED; - return (result); - } - - mem = isc_mem_get(thread_key_mctx, sizeof(*mem)); - if (mem == NULL) - return (ISC_R_NOMEMORY); - *mem = proc; - if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) { - isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); - result = ISC_R_UNEXPECTED; - } - return (result); -#else - totext_filter_proc = proc; - return (ISC_R_SUCCESS); -#endif -} - -void -dns_name_format(const dns_name_t *name, char *cp, unsigned int size) { - isc_result_t result; - isc_buffer_t buf; - - REQUIRE(size > 0); - - /* - * Leave room for null termination after buffer. - */ - isc_buffer_init(&buf, cp, size - 1); - result = dns_name_totext(name, true, &buf); - if (result == ISC_R_SUCCESS) { - isc_buffer_putuint8(&buf, (uint8_t)'\0'); - } else { - snprintf(cp, size, ""); - } -} - -/* - * dns_name_tostring() -- similar to dns_name_format() but allocates its own - * memory. - */ -isc_result_t -dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) { - isc_result_t result; - isc_buffer_t buf; - isc_region_t reg; - char *p, txt[DNS_NAME_FORMATSIZE]; - - REQUIRE(VALID_NAME(name)); - REQUIRE(target != NULL && *target == NULL); - - isc_buffer_init(&buf, txt, sizeof(txt)); - result = dns_name_totext(name, false, &buf); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_usedregion(&buf, ®); - p = isc_mem_allocate(mctx, reg.length + 1); - if (p == NULL) - return (ISC_R_NOMEMORY); - memmove(p, (char *) reg.base, (int) reg.length); - p[reg.length] = '\0'; - - *target = p; - return (ISC_R_SUCCESS); -} - -/* - * dns_name_fromstring() -- convert directly from a string to a name, - * allocating memory as needed - */ -isc_result_t -dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options, - isc_mem_t *mctx) -{ - return (dns_name_fromstring2(target, src, dns_rootname, options, mctx)); -} - -isc_result_t -dns_name_fromstring2(dns_name_t *target, const char *src, - const dns_name_t *origin, unsigned int options, - isc_mem_t *mctx) -{ - isc_result_t result; - isc_buffer_t buf; - dns_fixedname_t fn; - dns_name_t *name; - - REQUIRE(src != NULL); - - isc_buffer_constinit(&buf, src, strlen(src)); - isc_buffer_add(&buf, strlen(src)); - if (BINDABLE(target) && target->buffer != NULL) - name = target; - else { - name = dns_fixedname_initname(&fn); - } - - result = dns_name_fromtext(name, &buf, origin, options, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - if (name != target) - result = dns_name_dupwithoffsets(name, mctx, target); - return (result); -} - -isc_result_t -dns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) { - unsigned char *ndata; - - /* - * Make dest a copy of source. - */ - - REQUIRE(VALID_NAME(source)); - REQUIRE(VALID_NAME(dest)); - REQUIRE(target != NULL || dest->buffer != NULL); - - if (target == NULL) { - target = dest->buffer; - isc_buffer_clear(dest->buffer); - } - - REQUIRE(BINDABLE(dest)); - - /* - * Set up. - */ - if (target->length - target->used < source->length) - return (ISC_R_NOSPACE); - - ndata = (unsigned char *)target->base + target->used; - dest->ndata = target->base; - - if (source->length != 0) - memmove(ndata, source->ndata, source->length); - - dest->ndata = ndata; - dest->labels = source->labels; - dest->length = source->length; - if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) - dest->attributes = DNS_NAMEATTR_ABSOLUTE; - else - dest->attributes = 0; - - if (dest->labels > 0 && dest->offsets != NULL) { - if (source->offsets != NULL) - memmove(dest->offsets, source->offsets, source->labels); - else - set_offsets(dest, dest->offsets, NULL); - } - - isc_buffer_add(target, dest->length); - - return (ISC_R_SUCCESS); -} - -void -dns_name_destroy(void) { -#ifdef ISC_PLATFORM_USETHREADS - RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init) - == ISC_R_SUCCESS); - - LOCK(&thread_key_mutex); - if (thread_key_initialized) { - isc_mem_detach(&thread_key_mctx); - isc_thread_key_delete(totext_filter_proc_key); - thread_key_initialized = 0; - } - UNLOCK(&thread_key_mutex); - -#endif -} - -/* - * Service Discovery Prefixes RFC 6763. - */ -static unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp"; -static unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 }; -static unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp"; -static unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 }; -static unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp"; -static unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 }; -static unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp"; -static unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 }; -static unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp"; -static unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 }; - -static dns_name_t const dns_sd[] = { - DNS_NAME_INITNONABSOLUTE(b_dns_sd_udp_data, b_dns_sd_udp_offsets), - DNS_NAME_INITNONABSOLUTE(db_dns_sd_udp_data, db_dns_sd_udp_offsets), - DNS_NAME_INITNONABSOLUTE(r_dns_sd_udp_data, r_dns_sd_udp_offsets), - DNS_NAME_INITNONABSOLUTE(dr_dns_sd_udp_data, dr_dns_sd_udp_offsets), - DNS_NAME_INITNONABSOLUTE(lb_dns_sd_udp_data, lb_dns_sd_udp_offsets) -}; - -bool -dns_name_isdnssd(const dns_name_t *name) { - size_t i; - dns_name_t prefix; - - if (dns_name_countlabels(name) > 3U) { - dns_name_init(&prefix, NULL); - dns_name_getlabelsequence(name, 0, 3, &prefix); - for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++) - if (dns_name_equal(&prefix, &dns_sd[i])) - return (true); - } - - return (false); -} - -static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; -static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; -static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; - -static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; - -static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; - -static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; - -static dns_name_t const rfc1918names[] = { - DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets), - DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets), - DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets) -}; - -bool -dns_name_isrfc1918(const dns_name_t *name) { - size_t i; - - for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) - if (dns_name_issubdomain(name, &rfc1918names[i])) - return (true); - return (false); -} - -static unsigned char ulaoffsets[] = { 0, 2, 4, 8, 13 }; -static unsigned char ip6fc[] = "\001c\001f\003ip6\004ARPA"; -static unsigned char ip6fd[] = "\001d\001f\003ip6\004ARPA"; - -static dns_name_t const ulanames[] = { - DNS_NAME_INITABSOLUTE(ip6fc, ulaoffsets), - DNS_NAME_INITABSOLUTE(ip6fd, ulaoffsets) -}; - -bool -dns_name_isula(const dns_name_t *name) { - size_t i; - - for (i = 0; i < (sizeof(ulanames)/sizeof(*ulanames)); i++) - if (dns_name_issubdomain(name, &ulanames[i])) - return (true); - return (false); -} - -/* - * Use a simple table as we don't want all the locale stuff - * associated with ishexdigit(). - */ -const char -ishex[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -bool -dns_name_istat(const dns_name_t *name) { - unsigned char len; - const unsigned char *ndata; - - REQUIRE(VALID_NAME(name)); - - if (name->labels < 1) - return (false); - - ndata = name->ndata; - len = ndata[0]; - INSIST(len <= name->length); - ndata++; - - /* - * Is there at least one trust anchor reported and is the - * label length consistent with a trust-anchor-telemetry label. - */ - if ((len < 8) || (len - 3) % 5 != 0) { - return (false); - } - - if (ndata[0] != '_' || - maptolower[ndata[1]] != 't' || - maptolower[ndata[2]] != 'a') { - return (false); - } - ndata += 3; - len -= 3; - - while (len > 0) { - INSIST(len >= 5); - if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] || - !ishex[ndata[3]] || !ishex[ndata[4]]) { - return (false); - } - ndata += 5; - len -= 5; - } - return (true); -} diff --git a/lib/dns-pkcs11/ncache.c b/lib/dns-pkcs11/ncache.c deleted file mode 100644 index 7d41771..0000000 --- a/lib/dns-pkcs11/ncache.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define DNS_NCACHE_RDATA 100U - -/* - * The format of an ncache rdata is a sequence of zero or more records of - * the following format: - * - * owner name - * type - * trust - * rdata count - * rdata length These two occur 'rdata count' - * rdata times. - * - */ - -static isc_result_t -addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, bool secure, - dns_rdataset_t *addedrdataset); - -static inline isc_result_t -copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) { - isc_result_t result; - unsigned int count; - isc_region_t ar, r; - dns_rdata_t rdata = DNS_RDATA_INIT; - - /* - * Copy the rdataset count to the buffer. - */ - isc_buffer_availableregion(buffer, &ar); - if (ar.length < 2) - return (ISC_R_NOSPACE); - count = dns_rdataset_count(rdataset); - INSIST(count <= 65535); - isc_buffer_putuint16(buffer, (uint16_t)count); - - result = dns_rdataset_first(rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - INSIST(r.length <= 65535); - isc_buffer_availableregion(buffer, &ar); - if (ar.length < 2) - return (ISC_R_NOSPACE); - /* - * Copy the rdata length to the buffer. - */ - isc_buffer_putuint16(buffer, (uint16_t)r.length); - /* - * Copy the rdata to the buffer. - */ - result = isc_buffer_copyregion(buffer, &r); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(rdataset); - } - if (result != ISC_R_NOMORE) - return (result); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - dns_rdataset_t *addedrdataset) -{ - return (addoptout(message, cache, node, covers, now, maxttl, - false, false, addedrdataset)); -} - -isc_result_t -dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, - dns_dbnode_t *node, dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, dns_rdataset_t *addedrdataset) -{ - return (addoptout(message, cache, node, covers, now, maxttl, - optout, true, addedrdataset)); -} - -static isc_result_t -addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, bool secure, - dns_rdataset_t *addedrdataset) -{ - isc_result_t result; - isc_buffer_t buffer; - isc_region_t r; - dns_rdataset_t *rdataset; - dns_rdatatype_t type; - dns_name_t *name; - dns_ttl_t ttl; - dns_trust_t trust; - dns_rdata_t rdata[DNS_NCACHE_RDATA]; - dns_rdataset_t ncrdataset; - dns_rdatalist_t ncrdatalist; - unsigned char data[65536]; - unsigned int next = 0; - - /* - * Convert the authority data from 'message' into a negative cache - * rdataset, and store it in 'cache' at 'node'. - */ - - REQUIRE(message != NULL); - - /* - * We assume that all data in the authority section has been - * validated by the caller. - */ - - /* - * Initialize the list. - */ - dns_rdatalist_init(&ncrdatalist); - ncrdatalist.rdclass = dns_db_class(cache); - ncrdatalist.covers = covers; - ncrdatalist.ttl = maxttl; - - /* - * Build an ncache rdatas into buffer. - */ - ttl = maxttl; - trust = 0xffff; - isc_buffer_init(&buffer, data, sizeof(data)); - if (message->counts[DNS_SECTION_AUTHORITY]) - result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - else - result = ISC_R_NOMORE; - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, - &name); - if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if ((rdataset->attributes & - DNS_RDATASETATTR_NCACHE) == 0) - continue; - type = rdataset->type; - if (type == dns_rdatatype_rrsig) - type = rdataset->covers; - if (type == dns_rdatatype_soa || - type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3) { - if (ttl > rdataset->ttl) - ttl = rdataset->ttl; - if (trust > rdataset->trust) - trust = rdataset->trust; - /* - * Copy the owner name to the buffer. - */ - dns_name_toregion(name, &r); - result = isc_buffer_copyregion(&buffer, - &r); - if (result != ISC_R_SUCCESS) - return (result); - /* - * Copy the type to the buffer. - */ - isc_buffer_availableregion(&buffer, - &r); - if (r.length < 3) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(&buffer, - rdataset->type); - isc_buffer_putuint8(&buffer, - (unsigned char)rdataset->trust); - /* - * Copy the rdataset into the buffer. - */ - result = copy_rdataset(rdataset, - &buffer); - if (result != ISC_R_SUCCESS) - return (result); - - if (next >= DNS_NCACHE_RDATA) - return (ISC_R_NOSPACE); - dns_rdata_init(&rdata[next]); - isc_buffer_remainingregion(&buffer, &r); - rdata[next].data = r.base; - rdata[next].length = r.length; - rdata[next].rdclass = - ncrdatalist.rdclass; - rdata[next].type = 0; - rdata[next].flags = 0; - ISC_LIST_APPEND(ncrdatalist.rdata, - &rdata[next], link); - isc_buffer_forward(&buffer, r.length); - next++; - } - } - } - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); - } - if (result != ISC_R_NOMORE) - return (result); - - if (trust == 0xffff) { - if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 && - message->counts[DNS_SECTION_ANSWER] == 0) { - /* - * The response has aa set and we haven't followed - * any CNAME or DNAME chains. - */ - trust = dns_trust_authauthority; - } else - trust = dns_trust_additional; - ttl = 0; - } - - INSIST(trust != 0xffff); - - ncrdatalist.ttl = ttl; - - dns_rdataset_init(&ncrdataset); - RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset) - == ISC_R_SUCCESS); - if (!secure && trust > dns_trust_answer) - trust = dns_trust_answer; - ncrdataset.trust = trust; - ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE; - if (message->rcode == dns_rcode_nxdomain) - ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN; - if (optout) - ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT; - - return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset, - 0, addedrdataset)); -} - -isc_result_t -dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, - isc_buffer_t *target, unsigned int options, - unsigned int *countp) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - isc_region_t remaining, tavailable; - isc_buffer_t source, savedbuffer, rdlen; - dns_name_t name; - dns_rdatatype_t type; - unsigned int i, rcount, count; - - /* - * Convert the negative caching rdataset 'rdataset' to wire format, - * compressing names as specified in 'cctx', and storing the result in - * 'target'. - */ - - REQUIRE(rdataset != NULL); - REQUIRE(rdataset->type == 0); - REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); - - savedbuffer = *target; - count = 0; - - result = dns_rdataset_first(rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - isc_buffer_init(&source, rdata.data, rdata.length); - isc_buffer_add(&source, rdata.length); - dns_name_init(&name, NULL); - isc_buffer_remainingregion(&source, &remaining); - dns_name_fromregion(&name, &remaining); - INSIST(remaining.length >= name.length); - isc_buffer_forward(&source, name.length); - remaining.length -= name.length; - - INSIST(remaining.length >= 5); - type = isc_buffer_getuint16(&source); - isc_buffer_forward(&source, 1); - rcount = isc_buffer_getuint16(&source); - - for (i = 0; i < rcount; i++) { - /* - * Get the length of this rdata and set up an - * rdata structure for it. - */ - isc_buffer_remainingregion(&source, &remaining); - INSIST(remaining.length >= 2); - dns_rdata_reset(&rdata); - rdata.length = isc_buffer_getuint16(&source); - isc_buffer_remainingregion(&source, &remaining); - rdata.data = remaining.base; - rdata.type = type; - rdata.rdclass = rdataset->rdclass; - INSIST(remaining.length >= rdata.length); - isc_buffer_forward(&source, rdata.length); - - if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 && - dns_rdatatype_isdnssec(type)) - continue; - - /* - * Write the name. - */ - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - result = dns_name_towire(&name, cctx, target); - if (result != ISC_R_SUCCESS) - goto rollback; - - /* - * See if we have space for type, class, ttl, and - * rdata length. Write the type, class, and ttl. - */ - isc_buffer_availableregion(target, &tavailable); - if (tavailable.length < 10) { - result = ISC_R_NOSPACE; - goto rollback; - } - isc_buffer_putuint16(target, type); - isc_buffer_putuint16(target, rdataset->rdclass); - isc_buffer_putuint32(target, rdataset->ttl); - - /* - * Save space for rdata length. - */ - rdlen = *target; - isc_buffer_add(target, 2); - - /* - * Write the rdata. - */ - result = dns_rdata_towire(&rdata, cctx, target); - if (result != ISC_R_SUCCESS) - goto rollback; - - /* - * Set the rdata length field to the compressed - * length. - */ - INSIST((target->used >= rdlen.used + 2) && - (target->used - rdlen.used - 2 < 65536)); - isc_buffer_putuint16(&rdlen, - (uint16_t)(target->used - - rdlen.used - 2)); - - count++; - } - INSIST(isc_buffer_remaininglength(&source) == 0); - result = dns_rdataset_next(rdataset); - dns_rdata_reset(&rdata); - } - if (result != ISC_R_NOMORE) - goto rollback; - - *countp = count; - - return (ISC_R_SUCCESS); - - rollback: - INSIST(savedbuffer.used < 65536); - dns_compress_rollback(cctx, (uint16_t)savedbuffer.used); - *countp = 0; - *target = savedbuffer; - - return (result); -} - -static void -rdataset_disassociate(dns_rdataset_t *rdataset) { - UNUSED(rdataset); -} - -static isc_result_t -rdataset_first(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - if (count == 0) { - rdataset->private5 = NULL; - return (ISC_R_NOMORE); - } - raw += 2; - /* - * The privateuint4 field is the number of rdata beyond the cursor - * position, so we decrement the total count by one before storing - * it. - */ - count--; - rdataset->privateuint4 = count; - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdataset_next(dns_rdataset_t *rdataset) { - unsigned int count; - unsigned int length; - unsigned char *raw; - - count = rdataset->privateuint4; - if (count == 0) - return (ISC_R_NOMORE); - count--; - rdataset->privateuint4 = count; - raw = rdataset->private5; - length = raw[0] * 256 + raw[1]; - raw += length + 2; - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static void -rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - unsigned char *raw = rdataset->private5; - isc_region_t r; - - REQUIRE(raw != NULL); - - r.length = raw[0] * 256 + raw[1]; - raw += 2; - r.base = raw; - dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - *target = *source; - - /* - * Reset iterator state. - */ - target->privateuint4 = 0; - target->private5 = NULL; -} - -static unsigned int -rdataset_count(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - - return (count); -} - -static void -rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { - unsigned char *raw = rdataset->private3; - - raw[-1] = (unsigned char)trust; -} - -static dns_rdatasetmethods_t rdataset_methods = { - rdataset_disassociate, - rdataset_first, - rdataset_next, - rdataset_current, - rdataset_clone, - rdataset_count, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - rdataset_settrust, - NULL, - NULL, - NULL, - NULL -}; - -isc_result_t -dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, - dns_rdatatype_t type, dns_rdataset_t *rdataset) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_region_t remaining; - isc_buffer_t source; - dns_name_t tname; - dns_rdatatype_t ttype; - dns_trust_t trust = dns_trust_none; - dns_rdataset_t rclone; - - REQUIRE(ncacherdataset != NULL); - REQUIRE(ncacherdataset->type == 0); - REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); - REQUIRE(name != NULL); - REQUIRE(!dns_rdataset_isassociated(rdataset)); - REQUIRE(type != dns_rdatatype_rrsig); - - dns_rdataset_init(&rclone); - dns_rdataset_clone(ncacherdataset, &rclone); - result = dns_rdataset_first(&rclone); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&rclone, &rdata); - isc_buffer_init(&source, rdata.data, rdata.length); - isc_buffer_add(&source, rdata.length); - dns_name_init(&tname, NULL); - isc_buffer_remainingregion(&source, &remaining); - dns_name_fromregion(&tname, &remaining); - INSIST(remaining.length >= tname.length); - isc_buffer_forward(&source, tname.length); - remaining.length -= tname.length; - - INSIST(remaining.length >= 3); - ttype = isc_buffer_getuint16(&source); - - if (ttype == type && dns_name_equal(&tname, name)) { - trust = isc_buffer_getuint8(&source); - INSIST(trust <= dns_trust_ultimate); - isc_buffer_remainingregion(&source, &remaining); - break; - } - result = dns_rdataset_next(&rclone); - dns_rdata_reset(&rdata); - } - dns_rdataset_disassociate(&rclone); - if (result == ISC_R_NOMORE) - return (ISC_R_NOTFOUND); - if (result != ISC_R_SUCCESS) - return (result); - - INSIST(remaining.length != 0); - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = ncacherdataset->rdclass; - rdataset->type = type; - rdataset->covers = 0; - rdataset->ttl = ncacherdataset->ttl; - rdataset->trust = trust; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - - rdataset->private3 = remaining.base; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - rdataset->private6 = NULL; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, - dns_rdatatype_t covers, dns_rdataset_t *rdataset) -{ - dns_name_t tname; - dns_rdata_rrsig_t rrsig; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rclone; - dns_rdatatype_t type; - dns_trust_t trust = dns_trust_none; - isc_buffer_t source; - isc_region_t remaining, sigregion; - isc_result_t result; - unsigned char *raw; - unsigned int count; - - REQUIRE(ncacherdataset != NULL); - REQUIRE(ncacherdataset->type == 0); - REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); - REQUIRE(name != NULL); - REQUIRE(!dns_rdataset_isassociated(rdataset)); - - dns_rdataset_init(&rclone); - dns_rdataset_clone(ncacherdataset, &rclone); - result = dns_rdataset_first(&rclone); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&rclone, &rdata); - isc_buffer_init(&source, rdata.data, rdata.length); - isc_buffer_add(&source, rdata.length); - dns_name_init(&tname, NULL); - isc_buffer_remainingregion(&source, &remaining); - dns_name_fromregion(&tname, &remaining); - INSIST(remaining.length >= tname.length); - isc_buffer_forward(&source, tname.length); - isc_region_consume(&remaining, tname.length); - - INSIST(remaining.length >= 2); - type = isc_buffer_getuint16(&source); - isc_region_consume(&remaining, 2); - - if (type != dns_rdatatype_rrsig || - !dns_name_equal(&tname, name)) { - result = dns_rdataset_next(&rclone); - dns_rdata_reset(&rdata); - continue; - } - - INSIST(remaining.length >= 1); - trust = isc_buffer_getuint8(&source); - INSIST(trust <= dns_trust_ultimate); - isc_region_consume(&remaining, 1); - - raw = remaining.base; - count = raw[0] * 256 + raw[1]; - INSIST(count > 0); - raw += 2; - sigregion.length = raw[0] * 256 + raw[1]; - raw += 2; - sigregion.base = raw; - dns_rdata_reset(&rdata); - dns_rdata_fromregion(&rdata, rdataset->rdclass, - dns_rdatatype_rrsig, &sigregion); - (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); - if (rrsig.covered == covers) { - isc_buffer_remainingregion(&source, &remaining); - break; - } - - result = dns_rdataset_next(&rclone); - dns_rdata_reset(&rdata); - } - dns_rdataset_disassociate(&rclone); - if (result == ISC_R_NOMORE) - return (ISC_R_NOTFOUND); - if (result != ISC_R_SUCCESS) - return (result); - - INSIST(remaining.length != 0); - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = ncacherdataset->rdclass; - rdataset->type = dns_rdatatype_rrsig; - rdataset->covers = covers; - rdataset->ttl = ncacherdataset->ttl; - rdataset->trust = trust; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - - rdataset->private3 = remaining.base; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - rdataset->private6 = NULL; - return (ISC_R_SUCCESS); -} - -void -dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, - dns_rdataset_t *rdataset) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_trust_t trust; - isc_region_t remaining, sigregion; - isc_buffer_t source; - dns_name_t tname; - dns_rdatatype_t type; - unsigned int count; - dns_rdata_rrsig_t rrsig; - unsigned char *raw; - - REQUIRE(ncacherdataset != NULL); - REQUIRE(ncacherdataset->type == 0); - REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); - REQUIRE(found != NULL); - REQUIRE(!dns_rdataset_isassociated(rdataset)); - - dns_rdataset_current(ncacherdataset, &rdata); - isc_buffer_init(&source, rdata.data, rdata.length); - isc_buffer_add(&source, rdata.length); - - dns_name_init(&tname, NULL); - isc_buffer_remainingregion(&source, &remaining); - dns_name_fromregion(found, &remaining); - INSIST(remaining.length >= found->length); - isc_buffer_forward(&source, found->length); - remaining.length -= found->length; - - INSIST(remaining.length >= 5); - type = isc_buffer_getuint16(&source); - trust = isc_buffer_getuint8(&source); - INSIST(trust <= dns_trust_ultimate); - isc_buffer_remainingregion(&source, &remaining); - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = ncacherdataset->rdclass; - rdataset->type = type; - if (type == dns_rdatatype_rrsig) { - /* - * Extract covers from RRSIG. - */ - raw = remaining.base; - count = raw[0] * 256 + raw[1]; - INSIST(count > 0); - raw += 2; - sigregion.length = raw[0] * 256 + raw[1]; - raw += 2; - sigregion.base = raw; - dns_rdata_reset(&rdata); - dns_rdata_fromregion(&rdata, rdataset->rdclass, - rdataset->type, &sigregion); - (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); - rdataset->covers = rrsig.covered; - } else - rdataset->covers = 0; - rdataset->ttl = ncacherdataset->ttl; - rdataset->trust = trust; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - - rdataset->private3 = remaining.base; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - rdataset->private6 = NULL; -} diff --git a/lib/dns-pkcs11/nsec.c b/lib/dns-pkcs11/nsec.c deleted file mode 100644 index d90c385..0000000 --- a/lib/dns-pkcs11/nsec.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -void -dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) { - unsigned int shift, mask; - - shift = 7 - (type % 8); - mask = 1 << shift; - - if (bit != 0) - array[type / 8] |= mask; - else - array[type / 8] &= (~mask & 0xFF); -} - -bool -dns_nsec_isset(const unsigned char *array, unsigned int type) { - unsigned int byte, shift, mask; - - byte = array[type / 8]; - shift = 7 - (type % 8); - mask = 1 << shift; - - return ((byte & mask) != 0); -} - -unsigned int -dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, - unsigned int max_type) -{ - unsigned char *start = map; - unsigned int window; - int octet; - - if (raw == NULL) - return (0); - - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (*(raw + octet) != 0) - break; - if (octet < 0) { - raw += 32; - continue; - } - *map++ = window; - *map++ = octet + 1; - /* - * Note: potential overlapping move. - */ - memmove(map, raw, octet + 1); - map += octet + 1; - raw += 32; - } - return (unsigned int)(map - start); -} - -isc_result_t -dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, dns_name_t *target, - unsigned char *buffer, dns_rdata_t *rdata) -{ - isc_result_t result; - dns_rdataset_t rdataset; - isc_region_t r; - unsigned int i; - - unsigned char *nsec_bits, *bm; - unsigned int max_type; - dns_rdatasetiter_t *rdsiter; - - REQUIRE(target != NULL); - - memset(buffer, 0, DNS_NSEC_BUFFERSIZE); - dns_name_toregion(target, &r); - memmove(buffer, r.base, r.length); - r.base = buffer; - /* - * Use the end of the space for a raw bitmap leaving enough - * space for the window identifiers and length octets. - */ - bm = r.base + r.length + 512; - nsec_bits = r.base + r.length; - dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); - dns_nsec_setbit(bm, dns_rdatatype_nsec, 1); - max_type = dns_rdatatype_nsec; - dns_rdataset_init(&rdataset); - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - if (result != ISC_R_SUCCESS) - return (result); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) - { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_nsec && - rdataset.type != dns_rdatatype_nsec3 && - rdataset.type != dns_rdatatype_rrsig) { - if (rdataset.type > max_type) - max_type = rdataset.type; - dns_nsec_setbit(bm, rdataset.type, 1); - } - dns_rdataset_disassociate(&rdataset); - } - - /* - * At zone cuts, deny the existence of glue in the parent zone. - */ - if (dns_nsec_isset(bm, dns_rdatatype_ns) && - ! dns_nsec_isset(bm, dns_rdatatype_soa)) { - for (i = 0; i <= max_type; i++) { - if (dns_nsec_isset(bm, i) && - ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - dns_nsec_setbit(bm, i, 0); - } - } - - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_NOMORE) - return (result); - - nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); - - r.length = (unsigned int)(nsec_bits - r.base); - INSIST(r.length <= DNS_NSEC_BUFFERSIZE); - dns_rdata_fromregion(rdata, - dns_db_class(db), - dns_rdatatype_nsec, - &r); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, - dns_name_t *target, dns_ttl_t ttl) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char data[DNS_NSEC_BUFFERSIZE]; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdata_init(&rdata); - - RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata)); - - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = dns_db_class(db); - rdatalist.type = dns_rdatatype_nsec; - rdatalist.ttl = ttl; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset)); - result = dns_db_addrdataset(db, node, version, 0, &rdataset, - 0, NULL); - if (result == DNS_R_UNCHANGED) - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (result); -} - -bool -dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) { - dns_rdata_nsec_t nsecstruct; - isc_result_t result; - bool present; - unsigned int i, len, window; - - REQUIRE(nsec != NULL); - REQUIRE(nsec->type == dns_rdatatype_nsec); - - /* This should never fail */ - result = dns_rdata_tostruct(nsec, &nsecstruct, NULL); - INSIST(result == ISC_R_SUCCESS); - - present = false; - for (i = 0; i < nsecstruct.len; i += len) { - INSIST(i + 2 <= nsecstruct.len); - window = nsecstruct.typebits[i]; - len = nsecstruct.typebits[i + 1]; - INSIST(len > 0 && len <= 32); - i += 2; - INSIST(i + len <= nsecstruct.len); - if (window * 256 > type) - break; - if ((window + 1) * 256 <= type) - continue; - if (type < (window * 256) + len * 8) - present = dns_nsec_isset(&nsecstruct.typebits[i], - type % 256); - break; - } - dns_rdata_freestruct(&nsecstruct); - return (present); -} - -isc_result_t -dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, - bool *answer) -{ - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_dnskey_t dnskey; - isc_result_t result; - - REQUIRE(answer != NULL); - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, - 0, 0, &rdataset, NULL); - dns_db_detachnode(db, &node); - - if (result == ISC_R_NOTFOUND) - *answer = false; - if (result != ISC_R_SUCCESS) - return (result); - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dnskey, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (dnskey.algorithm == DST_ALG_RSAMD5 || - dnskey.algorithm == DST_ALG_RSASHA1 || - dnskey.algorithm == DST_ALG_DSA || - dnskey.algorithm == DST_ALG_ECC) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) - *answer = true; - if (result == ISC_R_NOMORE) { - *answer = false; - result = ISC_R_SUCCESS; - } - return (result); -} - -/*% - * Return ISC_R_SUCCESS if we can determine that the name doesn't exist - * or we can determine whether there is data or not at the name. - * If the name does not exist return the wildcard name. - * - * Return ISC_R_IGNORE when the NSEC is not the appropriate one. - */ -isc_result_t -dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, - dns_name_t *nsecname, dns_rdataset_t *nsecset, - bool *exists, bool *data, - dns_name_t *wild, dns_nseclog_t logit, void *arg) -{ - int order; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_namereln_t relation; - unsigned int olabels, nlabels, labels; - dns_rdata_nsec_t nsec; - bool atparent; - bool ns; - bool soa; - - REQUIRE(exists != NULL); - REQUIRE(data != NULL); - REQUIRE(nsecset != NULL && - nsecset->type == dns_rdatatype_nsec); - - result = dns_rdataset_first(nsecset); - if (result != ISC_R_SUCCESS) { - (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC set"); - return (result); - } - dns_rdataset_current(nsecset, &rdata); - - (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC"); - relation = dns_name_fullcompare(name, nsecname, &order, &olabels); - - if (order < 0) { - /* - * The name is not within the NSEC range. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC does not cover name, before NSEC"); - return (ISC_R_IGNORE); - } - - if (order == 0) { - /* - * The names are the same. If we are validating "." - * then atparent should not be set as there is no parent. - */ - atparent = (olabels != 1) && dns_rdatatype_atparent(type); - ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); - soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); - if (ns && !soa) { - if (!atparent) { - /* - * This NSEC record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring parent nsec"); - return (ISC_R_IGNORE); - } - } else if (atparent && ns && soa) { - /* - * This NSEC record is from the child. - * It can not be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring child nsec"); - return (ISC_R_IGNORE); - } - if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt || - type == dns_rdatatype_nsec || type == dns_rdatatype_key || - !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = true; - *data = dns_nsec_typepresent(&rdata, type); - (*logit)(arg, ISC_LOG_DEBUG(3), - "nsec proves name exists (owner) data=%d", - *data); - return (ISC_R_SUCCESS); - } - (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists"); - return (ISC_R_IGNORE); - } - - if (relation == dns_namereln_subdomain && - dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && - !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) - { - /* - * This NSEC record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec"); - return (ISC_R_IGNORE); - } - - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - if (result != ISC_R_SUCCESS) - return (result); - relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels); - if (order == 0) { - dns_rdata_freestruct(&nsec); - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring nsec matches next name"); - return (ISC_R_IGNORE); - } - - if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) { - /* - * The name is not within the NSEC range. - */ - dns_rdata_freestruct(&nsec); - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring nsec because name is past end of range"); - return (ISC_R_IGNORE); - } - - if (order > 0 && relation == dns_namereln_subdomain) { - (*logit)(arg, ISC_LOG_DEBUG(3), - "nsec proves name exist (empty)"); - dns_rdata_freestruct(&nsec); - *exists = true; - *data = false; - return (ISC_R_SUCCESS); - } - if (wild != NULL) { - dns_name_t common; - dns_name_init(&common, NULL); - if (olabels > nlabels) { - labels = dns_name_countlabels(nsecname); - dns_name_getlabelsequence(nsecname, labels - olabels, - olabels, &common); - } else { - labels = dns_name_countlabels(&nsec.next); - dns_name_getlabelsequence(&nsec.next, labels - nlabels, - nlabels, &common); - } - result = dns_name_concatenate(dns_wildcardname, &common, - wild, NULL); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&nsec); - (*logit)(arg, ISC_LOG_DEBUG(3), - "failure generating wildcard name"); - return (result); - } - } - dns_rdata_freestruct(&nsec); - (*logit)(arg, ISC_LOG_DEBUG(3), "nsec range ok"); - *exists = false; - return (ISC_R_SUCCESS); -} diff --git a/lib/dns-pkcs11/nsec3.c b/lib/dns-pkcs11/nsec3.c deleted file mode 100644 index 97e5278..0000000 --- a/lib/dns-pkcs11/nsec3.c +++ /dev/null @@ -1,2122 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) -#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) -#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) -#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) - -isc_result_t -dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, - dns_dbnode_t *node, unsigned int hashalg, - unsigned int flags, unsigned int iterations, - const unsigned char *salt, size_t salt_length, - const unsigned char *nexthash, size_t hash_length, - unsigned char *buffer, dns_rdata_t *rdata) -{ - isc_result_t result; - dns_rdataset_t rdataset; - isc_region_t r; - unsigned int i; - bool found; - bool found_ns; - bool need_rrsig; - - unsigned char *nsec_bits, *bm; - unsigned int max_type; - dns_rdatasetiter_t *rdsiter; - unsigned char *p; - - REQUIRE(salt_length < 256U); - REQUIRE(hash_length < 256U); - REQUIRE(flags <= 0xffU); - REQUIRE(hashalg <= 0xffU); - REQUIRE(iterations <= 0xffffU); - - switch (hashalg) { - case dns_hash_sha1: - REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH); - break; - } - - memset(buffer, 0, DNS_NSEC3_BUFFERSIZE); - - p = buffer; - - *p++ = hashalg; - *p++ = flags; - - *p++ = iterations >> 8; - *p++ = iterations; - - *p++ = (unsigned char)salt_length; - memmove(p, salt, salt_length); - p += salt_length; - - *p++ = (unsigned char)hash_length; - memmove(p, nexthash, hash_length); - p += hash_length; - - r.length = (unsigned int)(p - buffer); - r.base = buffer; - - /* - * Use the end of the space for a raw bitmap leaving enough - * space for the window identifiers and length octets. - */ - bm = r.base + r.length + 512; - nsec_bits = r.base + r.length; - max_type = 0; - if (node == NULL) - goto collapse_bitmap; - dns_rdataset_init(&rdataset); - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - if (result != ISC_R_SUCCESS) - return (result); - found = found_ns = need_rrsig = false; - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) - { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_nsec && - rdataset.type != dns_rdatatype_nsec3 && - rdataset.type != dns_rdatatype_rrsig) { - if (rdataset.type > max_type) - max_type = rdataset.type; - dns_nsec_setbit(bm, rdataset.type, 1); - /* - * Work out if we need to set the RRSIG bit for - * this node. We set the RRSIG bit if either of - * the following conditions are met: - * 1) We have a SOA or DS then we need to set - * the RRSIG bit as both always will be signed. - * 2) We set the RRSIG bit if we don't have - * a NS record but do have other data. - */ - if (rdataset.type == dns_rdatatype_soa || - rdataset.type == dns_rdatatype_ds) - need_rrsig = true; - else if (rdataset.type == dns_rdatatype_ns) - found_ns = true; - else - found = true; - } - dns_rdataset_disassociate(&rdataset); - } - if ((found && !found_ns) || need_rrsig) { - if (dns_rdatatype_rrsig > max_type) - max_type = dns_rdatatype_rrsig; - dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); - } - - /* - * At zone cuts, deny the existence of glue in the parent zone. - */ - if (dns_nsec_isset(bm, dns_rdatatype_ns) && - ! dns_nsec_isset(bm, dns_rdatatype_soa)) { - for (i = 0; i <= max_type; i++) { - if (dns_nsec_isset(bm, i) && - ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - dns_nsec_setbit(bm, i, 0); - } - } - - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_NOMORE) - return (result); - - collapse_bitmap: - nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); - r.length = (unsigned int)(nsec_bits - r.base); - INSIST(r.length <= DNS_NSEC3_BUFFERSIZE); - dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r); - - return (ISC_R_SUCCESS); -} - -bool -dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) { - dns_rdata_nsec3_t nsec3; - isc_result_t result; - bool present; - unsigned int i, len, window; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsec3); - - /* This should never fail */ - result = dns_rdata_tostruct(rdata, &nsec3, NULL); - INSIST(result == ISC_R_SUCCESS); - - present = false; - for (i = 0; i < nsec3.len; i += len) { - INSIST(i + 2 <= nsec3.len); - window = nsec3.typebits[i]; - len = nsec3.typebits[i + 1]; - INSIST(len > 0 && len <= 32); - i += 2; - INSIST(i + len <= nsec3.len); - if (window * 256 > type) - break; - if ((window + 1) * 256 <= type) - continue; - if (type < (window * 256) + len * 8) - present = dns_nsec_isset(&nsec3.typebits[i], - type % 256); - break; - } - dns_rdata_freestruct(&nsec3); - return (present); -} - -isc_result_t -dns_nsec3_hashname(dns_fixedname_t *result, - unsigned char rethash[NSEC3_MAX_HASH_LENGTH], - size_t *hash_length, dns_name_t *name, dns_name_t *origin, - dns_hash_t hashalg, unsigned int iterations, - const unsigned char *salt, size_t saltlength) -{ - unsigned char hash[NSEC3_MAX_HASH_LENGTH]; - unsigned char nametext[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fixed; - dns_name_t *downcased; - isc_buffer_t namebuffer; - isc_region_t region; - size_t len; - - if (rethash == NULL) - rethash = hash; - - memset(rethash, 0, NSEC3_MAX_HASH_LENGTH); - - downcased = dns_fixedname_initname(&fixed); - dns_name_downcase(name, downcased, NULL); - - /* hash the node name */ - len = isc_iterated_hash(rethash, hashalg, iterations, - salt, (int)saltlength, - downcased->ndata, downcased->length); - if (len == 0U) - return (DNS_R_BADALG); - - if (hash_length != NULL) - *hash_length = len; - - /* convert the hash to base32hex non-padded */ - region.base = rethash; - region.length = (unsigned int)len; - isc_buffer_init(&namebuffer, nametext, sizeof nametext); - isc_base32hexnp_totext(®ion, 1, "", &namebuffer); - - /* convert the hex to a domain name */ - dns_fixedname_init(result); - return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer, - origin, 0, NULL)); -} - -unsigned int -dns_nsec3_hashlength(dns_hash_t hash) { - - switch (hash) { - case dns_hash_sha1: - return(ISC_SHA1_DIGESTLENGTH); - } - return (0); -} - -bool -dns_nsec3_supportedhash(dns_hash_t hash) { - switch (hash) { - case dns_hash_sha1: - return (true); - } - return (false); -} - -/*% - * Update a single RR in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li '*tuple' == NULL. Either the tuple is freed, or its - * ownership has been transferred to the diff. - */ -static isc_result_t -do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - dns_diff_t temp_diff; - isc_result_t result; - - /* - * Create a singleton diff. - */ - dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); - - /* - * Apply it to the database. - */ - result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); - if (result != ISC_R_SUCCESS) { - dns_difftuple_free(tuple); - return (result); - } - - /* - * Merge it into the current pending journal entry. - */ - dns_diff_appendminimal(diff, tuple); - - /* - * Do not clear temp_diff. - */ - return (ISC_R_SUCCESS); -} - -/*% - * Set '*exists' to true iff the given name exists, to false otherwise. - */ -static isc_result_t -name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - bool *exists) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdatasetiter_t *iter = NULL; - - result = dns_db_findnode(db, name, false, &node); - if (result == ISC_R_NOTFOUND) { - *exists = false; - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_allrdatasets(db, node, version, - (isc_stdtime_t) 0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - result = dns_rdatasetiter_first(iter); - if (result == ISC_R_SUCCESS) { - *exists = true; - } else if (result == ISC_R_NOMORE) { - *exists = false; - result = ISC_R_SUCCESS; - } else - *exists = false; - dns_rdatasetiter_destroy(&iter); - - cleanup_node: - dns_db_detachnode(db, &node); - return (result); -} - -static bool -match_nsec3param(const dns_rdata_nsec3_t *nsec3, - const dns_rdata_nsec3param_t *nsec3param) -{ - if (nsec3->hash == nsec3param->hash && - nsec3->iterations == nsec3param->iterations && - nsec3->salt_length == nsec3param->salt_length && - !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length)) - return (true); - return (false); -} - -/*% - * Delete NSEC3 records at "name" which match "param", recording the - * change in "diff". - */ -static isc_result_t -delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) -{ - dns_dbnode_t *node = NULL ; - dns_difftuple_t *tuple = NULL; - dns_rdata_nsec3_t nsec3; - dns_rdataset_t rdataset; - isc_result_t result; - - result = dns_db_findnsec3node(db, name, false, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, &rdataset, NULL); - - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_node; - } - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); - - if (!match_nsec3param(&nsec3, nsec3param)) - continue; - - result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, - rdataset.ttl, &rdata, &tuple); - if (result != ISC_R_SUCCESS) - goto failure; - result = do_one_tuple(&tuple, db, version, diff); - if (result != ISC_R_SUCCESS) - goto failure; - } - if (result != ISC_R_NOMORE) - goto failure; - result = ISC_R_SUCCESS; - - failure: - dns_rdataset_disassociate(&rdataset); - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -static bool -better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) { - dns_rdataset_t rdataset; - isc_result_t result; - - if (REMOVE(param->data[1])) - return (true); - - dns_rdataset_init(&rdataset); - dns_rdataset_clone(nsec3paramset, &rdataset); - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - - if (rdataset.type != dns_rdatatype_nsec3param) { - dns_rdata_t tmprdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &tmprdata); - if (!dns_nsec3param_fromprivate(&tmprdata, &rdata, - buf, sizeof(buf))) - continue; - } else - dns_rdataset_current(&rdataset, &rdata); - - if (rdata.length != param->length) - continue; - if (rdata.data[0] != param->data[0] || - REMOVE(rdata.data[1]) || - rdata.data[2] != param->data[2] || - rdata.data[3] != param->data[3] || - rdata.data[4] != param->data[4] || - memcmp(&rdata.data[5], ¶m->data[5], param->data[4])) - continue; - if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) { - dns_rdataset_disassociate(&rdataset); - return (true); - } - } - dns_rdataset_disassociate(&rdataset); - return (false); -} - -static isc_result_t -find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset, - const dns_rdata_nsec3param_t *nsec3param) -{ - isc_result_t result; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL)); - dns_rdata_reset(&rdata); - if (match_nsec3param(nsec3, nsec3param)) - break; - } - failure: - return (result); -} - -isc_result_t -dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, - dns_ttl_t nsecttl, bool unsecure, dns_diff_t *diff) -{ - dns_dbiterator_t *dbit = NULL; - dns_dbnode_t *node = NULL; - dns_dbnode_t *newnode = NULL; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixed; - dns_fixedname_t fprev; - dns_hash_t hash; - dns_name_t *hashname; - dns_name_t *origin; - dns_name_t *prev; - dns_name_t empty; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - int pass; - bool exists = false; - bool maybe_remove_unsecure = false; - uint8_t flags; - isc_buffer_t buffer; - isc_result_t result; - unsigned char *old_next; - unsigned char *salt; - unsigned char nexthash[NSEC3_MAX_HASH_LENGTH]; - unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE]; - unsigned int iterations; - unsigned int labels; - size_t next_length; - unsigned int old_length; - unsigned int salt_length; - - hashname = dns_fixedname_initname(&fixed); - prev = dns_fixedname_initname(&fprev); - - dns_rdataset_init(&rdataset); - - origin = dns_db_origin(db); - - /* - * Chain parameters. - */ - hash = nsec3param->hash; - iterations = nsec3param->iterations; - salt_length = nsec3param->salt_length; - salt = nsec3param->salt; - - /* - * Default flags for a new chain. - */ - flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT; - - /* - * If this is the first NSEC3 in the chain nexthash will - * remain pointing to itself. - */ - next_length = sizeof(nexthash); - CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, - name, origin, hash, iterations, - salt, salt_length)); - INSIST(next_length <= sizeof(nexthash)); - - /* - * Create the node if it doesn't exist and hold - * a reference to it until we have added the NSEC3. - */ - CHECK(dns_db_findnsec3node(db, hashname, true, &newnode)); - - /* - * Seek the iterator to the 'newnode'. - */ - CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit)); - CHECK(dns_dbiterator_seek(dbit, hashname)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - /* - * If we updating a existing NSEC3 then find its - * next field. - */ - if (result == ISC_R_SUCCESS) { - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_SUCCESS) { - if (!CREATE(nsec3param->flags)) - flags = nsec3.flags; - next_length = nsec3.next_length; - INSIST(next_length <= sizeof(nexthash)); - memmove(nexthash, nsec3.next, next_length); - dns_rdataset_disassociate(&rdataset); - /* - * If the NSEC3 is not for a unsecure delegation then - * we are just updating it. If it is for a unsecure - * delegation then we need find out if we need to - * remove the NSEC3 record or not by examining the - * previous NSEC3 record. - */ - if (!unsecure) - goto addnsec3; - else if (CREATE(nsec3param->flags) && OPTOUT(flags)) { - result = dns_nsec3_delnsec3(db, version, name, - nsec3param, diff); - goto failure; - } else - maybe_remove_unsecure = true; - } else { - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_NOMORE) - goto failure; - } - } - - /* - * Find the previous NSEC3 (if any) and update it if required. - */ - pass = 0; - do { - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - pass++; - CHECK(dns_dbiterator_last(dbit)); - } - CHECK(dns_dbiterator_current(dbit, &node, prev)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, &rdataset, - NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - continue; - - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&rdataset); - continue; - } - if (result != ISC_R_SUCCESS) - goto failure; - - if (maybe_remove_unsecure) { - dns_rdataset_disassociate(&rdataset); - /* - * If we have OPTOUT set in the previous NSEC3 record - * we actually need to delete the NSEC3 record. - * Otherwise we just need to replace the NSEC3 record. - */ - if (OPTOUT(nsec3.flags)) { - result = dns_nsec3_delnsec3(db, version, name, - nsec3param, diff); - goto failure; - } - goto addnsec3; - } else { - /* - * Is this is a unsecure delegation we are adding? - * If so no change is required. - */ - if (OPTOUT(nsec3.flags) && unsecure) { - dns_rdataset_disassociate(&rdataset); - goto failure; - } - } - - old_next = nsec3.next; - old_length = nsec3.next_length; - - /* - * Delete the old previous NSEC3. - */ - CHECK(delnsec3(db, version, prev, nsec3param, diff)); - - /* - * Fixup the previous NSEC3. - */ - nsec3.next = nexthash; - nsec3.next_length = (unsigned char)next_length; - isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); - CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, - dns_rdatatype_nsec3, &nsec3, - &buffer)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, - rdataset.ttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - INSIST(old_length <= sizeof(nexthash)); - memmove(nexthash, old_next, old_length); - if (!CREATE(nsec3param->flags)) - flags = nsec3.flags; - dns_rdata_reset(&rdata); - dns_rdataset_disassociate(&rdataset); - break; - } while (pass < 2); - - addnsec3: - /* - * Create the NSEC3 RDATA. - */ - CHECK(dns_db_findnode(db, name, false, &node)); - CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations, - salt, salt_length, nexthash, next_length, - nsec3buf, &rdata)); - dns_db_detachnode(db, &node); - - /* - * Delete the old NSEC3 and record the change. - */ - CHECK(delnsec3(db, version, hashname, nsec3param, diff)); - /* - * Add the new NSEC3 and record the change. - */ - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - hashname, nsecttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - INSIST(tuple == NULL); - dns_rdata_reset(&rdata); - dns_db_detachnode(db, &newnode); - - /* - * Add missing NSEC3 records for empty nodes - */ - dns_name_init(&empty, NULL); - dns_name_clone(name, &empty); - do { - labels = dns_name_countlabels(&empty) - 1; - if (labels <= dns_name_countlabels(origin)) - break; - dns_name_getlabelsequence(&empty, 1, labels, &empty); - CHECK(name_exists(db, version, &empty, &exists)); - if (exists) - break; - CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, - &empty, origin, hash, iterations, - salt, salt_length)); - - /* - * Create the node if it doesn't exist and hold - * a reference to it until we have added the NSEC3 - * or we discover we don't need to add make a change. - */ - CHECK(dns_db_findnsec3node(db, hashname, true, &newnode)); - result = dns_db_findrdataset(db, newnode, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, &rdataset, - NULL); - if (result == ISC_R_SUCCESS) { - result = find_nsec3(&nsec3, &rdataset, nsec3param); - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - dns_db_detachnode(db, &newnode); - break; - } - if (result != ISC_R_NOMORE) - goto failure; - } - - /* - * Find the previous NSEC3 and update it. - */ - CHECK(dns_dbiterator_seek(dbit, hashname)); - pass = 0; - do { - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - pass++; - CHECK(dns_dbiterator_last(dbit)); - } - CHECK(dns_dbiterator_current(dbit, &node, prev)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, - &rdataset, NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - continue; - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&rdataset); - continue; - } - if (result != ISC_R_SUCCESS) - goto failure; - - old_next = nsec3.next; - old_length = nsec3.next_length; - - /* - * Delete the old previous NSEC3. - */ - CHECK(delnsec3(db, version, prev, nsec3param, diff)); - - /* - * Fixup the previous NSEC3. - */ - nsec3.next = nexthash; - nsec3.next_length = (unsigned char)next_length; - isc_buffer_init(&buffer, nsec3buf, - sizeof(nsec3buf)); - CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, - dns_rdatatype_nsec3, &nsec3, - &buffer)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - prev, rdataset.ttl, &rdata, - &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - INSIST(old_length <= sizeof(nexthash)); - memmove(nexthash, old_next, old_length); - if (!CREATE(nsec3param->flags)) - flags = nsec3.flags; - dns_rdata_reset(&rdata); - dns_rdataset_disassociate(&rdataset); - break; - } while (pass < 2); - - INSIST(pass < 2); - - /* - * Create the NSEC3 RDATA for the empty node. - */ - CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags, - iterations, salt, salt_length, - nexthash, next_length, nsec3buf, - &rdata)); - /* - * Delete the old NSEC3 and record the change. - */ - CHECK(delnsec3(db, version, hashname, nsec3param, diff)); - - /* - * Add the new NSEC3 and record the change. - */ - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - hashname, nsecttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - INSIST(tuple == NULL); - dns_rdata_reset(&rdata); - dns_db_detachnode(db, &newnode); - } while (1); - - /* result cannot be ISC_R_NOMORE here */ - INSIST(result != ISC_R_NOMORE); - - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - if (newnode != NULL) - dns_db_detachnode(db, &newnode); - return (result); -} - -/*% - * Add NSEC3 records for "name", recording the change in "diff". - * The existing NSEC3 records are removed. - */ -isc_result_t -dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, dns_ttl_t nsecttl, - bool unsecure, dns_diff_t *diff) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - dns_rdataset_t rdataset; - isc_result_t result; - - dns_rdataset_init(&rdataset); - - /* - * Find the NSEC3 parameters for this zone. - */ - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3param, 0, 0, - &rdataset, NULL); - dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Update each active NSEC3 chain. - */ - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - - if (nsec3param.flags != 0) - continue; - /* - * We have a active chain. Update it. - */ - CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, - nsecttl, unsecure, diff)); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (result); -} - -bool -dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, - unsigned char *buf, size_t buflen) -{ - dns_decompress_t dctx; - isc_result_t result; - isc_buffer_t buf1; - isc_buffer_t buf2; - - /* - * Algorithm 0 (reserved by RFC 4034) is used to identify - * NSEC3PARAM records from DNSKEY pointers. - */ - if (src->length < 1 || src->data[0] != 0) - return (false); - - isc_buffer_init(&buf1, src->data + 1, src->length - 1); - isc_buffer_add(&buf1, src->length - 1); - isc_buffer_setactive(&buf1, src->length - 1); - isc_buffer_init(&buf2, buf, (unsigned int)buflen); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); - result = dns_rdata_fromwire(target, src->rdclass, - dns_rdatatype_nsec3param, - &buf1, &dctx, 0, &buf2); - dns_decompress_invalidate(&dctx); - - return (result == ISC_R_SUCCESS); -} - -void -dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, - dns_rdatatype_t privatetype, - unsigned char *buf, size_t buflen) -{ - REQUIRE(buflen >= src->length + 1); - - REQUIRE(DNS_RDATA_INITIALIZED(target)); - - memmove(buf + 1, src->data, src->length); - buf[0] = 0; - target->data = buf; - target->length = src->length + 1; - target->type = privatetype; - target->rdclass = src->rdclass; - target->flags = 0; - ISC_LINK_INIT(target, link); -} - -static isc_result_t -rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - const dns_rdata_t *rdata, bool *flag) -{ - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - isc_result_t result; - - dns_rdataset_init(&rdataset); - if (rdata->type == dns_rdatatype_nsec3) - CHECK(dns_db_findnsec3node(db, name, false, &node)); - else - CHECK(dns_db_findnode(db, name, false, &node)); - result = dns_db_findrdataset(db, node, ver, rdata->type, 0, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - *flag = false; - result = ISC_R_SUCCESS; - goto failure; - } - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t myrdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &myrdata); - if (!dns_rdata_casecompare(&myrdata, rdata)) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - *flag = true; - } else if (result == ISC_R_NOMORE) { - *flag = false; - result = ISC_R_SUCCESS; - } - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -isc_result_t -dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst, - size_t dstlen) -{ - isc_result_t result; - isc_region_t r; - isc_buffer_t b; - - REQUIRE(nsec3param != NULL); - REQUIRE(dst != NULL); - - if (nsec3param->salt_length == 0) { - if (dstlen < 2U) { - return (ISC_R_NOSPACE); - } - strlcpy(dst, "-", dstlen); - return (ISC_R_SUCCESS); - } - - r.base = nsec3param->salt; - r.length = nsec3param->salt_length; - isc_buffer_init(&b, dst, (unsigned int)dstlen); - - result = isc_hex_totext(&r, 2, "", &b); - if (result != ISC_R_SUCCESS) { - return (result); - } - - if (isc_buffer_availablelength(&b) < 1) { - return (ISC_R_NOSPACE); - } - isc_buffer_putuint8(&b, 0); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, - dns_zone_t *zone, bool nonsec, - dns_diff_t *diff) -{ - dns_dbnode_t *node = NULL; - dns_difftuple_t *tuple = NULL; - dns_name_t next; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - bool flag; - isc_result_t result = ISC_R_SUCCESS; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1]; - dns_name_t *origin = dns_zone_getorigin(zone); - dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); - - dns_name_init(&next, NULL); - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Cause all NSEC3 chains to be deleted. - */ - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto try_private; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t private = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, - rdataset.ttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - - dns_nsec3param_toprivate(&rdata, &private, privatetype, - buf, sizeof(buf)); - buf[2] = DNS_NSEC3FLAG_REMOVE; - if (nonsec) - buf[2] |= DNS_NSEC3FLAG_NONSEC; - - CHECK(rr_exists(db, ver, origin, &private, &flag)); - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - origin, 0, &private, - &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - } - dns_rdata_reset(&rdata); - } - if (result != ISC_R_NOMORE) - goto failure; - - dns_rdataset_disassociate(&rdataset); - - try_private: - if (privatetype == 0) - goto success; - result = dns_db_findrdataset(db, node, ver, privatetype, 0, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rdataset, &rdata); - INSIST(rdata.length <= sizeof(buf)); - memmove(buf, rdata.data, rdata.length); - - /* - * Private NSEC3 record length >= 6. - * <0(1), hash(1), flags(1), iterations(2), saltlen(1)> - */ - if (rdata.length < 6 || buf[0] != 0 || - (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 || - (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0)) - continue; - - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, - 0, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - - rdata.data = buf; - buf[2] = DNS_NSEC3FLAG_REMOVE; - if (nonsec) - buf[2] |= DNS_NSEC3FLAG_NONSEC; - - CHECK(rr_exists(db, ver, origin, &rdata, &flag)); - - if (!flag) { - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - origin, 0, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - } - } - if (result != ISC_R_NOMORE) - goto failure; - success: - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); -} - -isc_result_t -dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version, - dns_name_t *name, dns_ttl_t nsecttl, - bool unsecure, dns_rdatatype_t type, - dns_diff_t *diff) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - dns_rdataset_t rdataset; - dns_rdataset_t prdataset; - isc_result_t result; - - dns_rdataset_init(&rdataset); - dns_rdataset_init(&prdataset); - - /* - * Find the NSEC3 parameters for this zone. - */ - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_findrdataset(db, node, version, type, 0, 0, - &prdataset, NULL); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto failure; - - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3param, 0, 0, - &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto try_private; - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Update each active NSEC3 chain. - */ - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - - if (nsec3param.flags != 0) - continue; - - /* - * We have a active chain. Update it. - */ - CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, - nsecttl, unsecure, diff)); - } - if (result != ISC_R_NOMORE) - goto failure; - - dns_rdataset_disassociate(&rdataset); - - try_private: - if (!dns_rdataset_isassociated(&prdataset)) - goto success; - /* - * Update each active NSEC3 chain. - */ - for (result = dns_rdataset_first(&prdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&prdataset)) { - dns_rdata_t rdata1 = DNS_RDATA_INIT; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - - dns_rdataset_current(&prdataset, &rdata1); - if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, - buf, sizeof(buf))) - continue; - CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL)); - - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (better_param(&prdataset, &rdata2)) - continue; - - /* - * We have a active chain. Update it. - */ - CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, - nsecttl, unsecure, diff)); - } - if (result == ISC_R_NOMORE) - success: - result = ISC_R_SUCCESS; - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (dns_rdataset_isassociated(&prdataset)) - dns_rdataset_disassociate(&prdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (result); -} - -/*% - * Determine whether any NSEC3 records that were associated with - * 'name' should be deleted or if they should continue to exist. - * true indicates they should be deleted. - * false indicates they should be retained. - */ -static isc_result_t -deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - bool *yesno) -{ - isc_result_t result; - dns_fixedname_t foundname; - dns_fixedname_init(&foundname); - - result = dns_db_find(db, name, ver, dns_rdatatype_any, - DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, - (isc_stdtime_t) 0, NULL, - dns_fixedname_name(&foundname), - NULL, NULL); - if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT) { - *yesno = false; - return (ISC_R_SUCCESS); - } - if (result == DNS_R_GLUE || result == DNS_R_DNAME || - result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) { - *yesno = true; - return (ISC_R_SUCCESS); - } - /* - * Silence compiler. - */ - *yesno = true; - return (result); -} - -isc_result_t -dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) -{ - dns_dbiterator_t *dbit = NULL; - dns_dbnode_t *node = NULL; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixed; - dns_fixedname_t fprev; - dns_hash_t hash; - dns_name_t *hashname; - dns_name_t *origin; - dns_name_t *prev; - dns_name_t empty; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - int pass; - bool yesno; - isc_buffer_t buffer; - isc_result_t result; - unsigned char *salt; - unsigned char nexthash[NSEC3_MAX_HASH_LENGTH]; - unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE]; - unsigned int iterations; - unsigned int labels; - size_t next_length; - unsigned int salt_length; - - hashname = dns_fixedname_initname(&fixed); - prev = dns_fixedname_initname(&fprev); - - dns_rdataset_init(&rdataset); - - origin = dns_db_origin(db); - - /* - * Chain parameters. - */ - hash = nsec3param->hash; - iterations = nsec3param->iterations; - salt_length = nsec3param->salt_length; - salt = nsec3param->salt; - - /* - * If this is the first NSEC3 in the chain nexthash will - * remain pointing to itself. - */ - next_length = sizeof(nexthash); - CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, - name, origin, hash, iterations, - salt, salt_length)); - - CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit)); - - result = dns_dbiterator_seek(dbit, hashname); - if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - CHECK(dns_dbiterator_current(dbit, &node, NULL)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, - 0, (isc_stdtime_t) 0, &rdataset, NULL); - dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * If we find a existing NSEC3 for this chain then save the - * next field. - */ - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_SUCCESS) { - next_length = nsec3.next_length; - INSIST(next_length <= sizeof(nexthash)); - memmove(nexthash, nsec3.next, next_length); - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_NOMORE) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Find the previous NSEC3 and update it. - */ - pass = 0; - do { - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - pass++; - CHECK(dns_dbiterator_last(dbit)); - } - CHECK(dns_dbiterator_current(dbit, &node, prev)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, &rdataset, - NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - continue; - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&rdataset); - continue; - } - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Delete the old previous NSEC3. - */ - CHECK(delnsec3(db, version, prev, nsec3param, diff)); - - /* - * Fixup the previous NSEC3. - */ - nsec3.next = nexthash; - nsec3.next_length = (unsigned char)next_length; - if (CREATE(nsec3param->flags)) - nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT; - isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); - CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, - dns_rdatatype_nsec3, &nsec3, - &buffer)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, - rdataset.ttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - dns_rdata_reset(&rdata); - dns_rdataset_disassociate(&rdataset); - break; - } while (pass < 2); - - /* - * Delete the old NSEC3 and record the change. - */ - CHECK(delnsec3(db, version, hashname, nsec3param, diff)); - - /* - * Delete NSEC3 records for now non active nodes. - */ - dns_name_init(&empty, NULL); - dns_name_clone(name, &empty); - do { - labels = dns_name_countlabels(&empty) - 1; - if (labels <= dns_name_countlabels(origin)) - break; - dns_name_getlabelsequence(&empty, 1, labels, &empty); - CHECK(deleteit(db, version, &empty, &yesno)); - if (!yesno) - break; - - CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, - &empty, origin, hash, iterations, - salt, salt_length)); - result = dns_dbiterator_seek(dbit, hashname); - if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - CHECK(dns_dbiterator_current(dbit, &node, NULL)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, &rdataset, - NULL); - dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_SUCCESS) { - next_length = nsec3.next_length; - INSIST(next_length <= sizeof(nexthash)); - memmove(nexthash, nsec3.next, next_length); - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_NOMORE) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - pass = 0; - do { - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - pass++; - CHECK(dns_dbiterator_last(dbit)); - } - CHECK(dns_dbiterator_current(dbit, &node, prev)); - CHECK(dns_dbiterator_pause(dbit)); - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3, 0, - (isc_stdtime_t) 0, - &rdataset, NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - continue; - result = find_nsec3(&nsec3, &rdataset, nsec3param); - if (result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&rdataset); - continue; - } - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Delete the old previous NSEC3. - */ - CHECK(delnsec3(db, version, prev, nsec3param, diff)); - - /* - * Fixup the previous NSEC3. - */ - nsec3.next = nexthash; - nsec3.next_length = (unsigned char)next_length; - isc_buffer_init(&buffer, nsec3buf, - sizeof(nsec3buf)); - CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, - dns_rdatatype_nsec3, &nsec3, - &buffer)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, - prev, rdataset.ttl, &rdata, - &tuple)); - CHECK(do_one_tuple(&tuple, db, version, diff)); - dns_rdata_reset(&rdata); - dns_rdataset_disassociate(&rdataset); - break; - } while (pass < 2); - - INSIST(pass < 2); - - /* - * Delete the old NSEC3 and record the change. - */ - CHECK(delnsec3(db, version, hashname, nsec3param, diff)); - } while (1); - - success: - result = ISC_R_SUCCESS; - - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -isc_result_t -dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_diff_t *diff) -{ - return (dns_nsec3_delnsec3sx(db, version, name, 0, diff)); -} - -isc_result_t -dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, - dns_rdatatype_t privatetype, dns_diff_t *diff) -{ - dns_dbnode_t *node = NULL; - dns_rdata_nsec3param_t nsec3param; - dns_rdataset_t rdataset; - isc_result_t result; - - dns_rdataset_init(&rdataset); - - /* - * Find the NSEC3 parameters for this zone. - */ - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3param, 0, 0, - &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto try_private; - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Update each active NSEC3 chain. - */ - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - - if (nsec3param.flags != 0) - continue; - /* - * We have a active chain. Update it. - */ - CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff)); - } - dns_rdataset_disassociate(&rdataset); - - try_private: - if (privatetype == 0) - goto success; - result = dns_db_findrdataset(db, node, version, privatetype, 0, 0, - &rdataset, NULL); - if (result == ISC_R_NOTFOUND) - goto success; - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Update each NSEC3 chain being built. - */ - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata1 = DNS_RDATA_INIT; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - - dns_rdataset_current(&rdataset, &rdata1); - if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, - buf, sizeof(buf))) - continue; - CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL)); - - if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) - continue; - if (better_param(&rdataset, &rdata2)) - continue; - - /* - * We have a active chain. Update it. - */ - CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff)); - } - if (result == ISC_R_NOMORE) - success: - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (result); -} - -isc_result_t -dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, - bool complete, bool *answer) -{ - return (dns_nsec3_activex(db, version, complete, 0, answer)); -} - -isc_result_t -dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, - bool complete, dns_rdatatype_t privatetype, - bool *answer) -{ - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_nsec3param_t nsec3param; - isc_result_t result; - - REQUIRE(answer != NULL); - - dns_rdataset_init(&rdataset); - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec3param, 0, 0, - &rdataset, NULL); - - if (result == ISC_R_NOTFOUND) - goto try_private; - - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - return (result); - } - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (nsec3param.flags == 0) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - *answer = true; - return (ISC_R_SUCCESS); - } - if (result == ISC_R_NOMORE) - *answer = false; - - try_private: - if (privatetype == 0 || complete) { - *answer = false; - return (ISC_R_SUCCESS); - } - result = dns_db_findrdataset(db, node, version, privatetype, 0, 0, - &rdataset, NULL); - - dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) { - *answer = false; - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) - return (result); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata1 = DNS_RDATA_INIT; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - - dns_rdataset_current(&rdataset, &rdata1); - if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, - buf, sizeof(buf))) - continue; - result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - if (!complete && CREATE(nsec3param.flags)) - break; - } - dns_rdataset_disassociate(&rdataset); - if (result == ISC_R_SUCCESS) { - *answer = true; - result = ISC_R_SUCCESS; - } - if (result == ISC_R_NOMORE) { - *answer = false; - result = ISC_R_SUCCESS; - } - - return (result); -} - -isc_result_t -dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, - isc_mem_t *mctx, unsigned int *iterationsp) -{ - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dst_key_t *key = NULL; - isc_buffer_t buffer; - isc_result_t result; - unsigned int bits, minbits = 4096; - - result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, - 0, 0, &rdataset, NULL); - dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) { - *iterationsp = 0; - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - - REQUIRE(rdata.type == dns_rdatatype_key || - rdata.type == dns_rdatatype_dnskey); - REQUIRE(rdata.length > 3); - - /* Skip unsupported algorithms when - * calculating the maximum iterations. - */ - if (!dst_algorithm_supported(rdata.data[3])) - continue; - - isc_buffer_init(&buffer, rdata.data, rdata.length); - isc_buffer_add(&buffer, rdata.length); - CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass, - &buffer, mctx, &key)); - bits = dst_key_size(key); - dst_key_free(&key); - if (minbits > bits) - minbits = bits; - } - if (result != ISC_R_NOMORE) - goto failure; - - if (minbits <= 1024) - *iterationsp = 150; - else if (minbits <= 2048) - *iterationsp = 500; - else - *iterationsp = 2500; - result = ISC_R_SUCCESS; - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (result); -} - -isc_result_t -dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, - dns_name_t *nsec3name, dns_rdataset_t *nsec3set, - dns_name_t *zonename, bool *exists, - bool *data, bool *optout, - bool *unknown, bool *setclosest, - bool *setnearest, dns_name_t *closest, - dns_name_t *nearest, dns_nseclog_t logit, void *arg) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - dns_fixedname_t fzone; - dns_fixedname_t qfixed; - dns_label_t hashlabel; - dns_name_t *qname; - dns_name_t *zone; - dns_rdata_nsec3_t nsec3; - dns_rdata_t rdata = DNS_RDATA_INIT; - int order; - int scope; - bool atparent; - bool first; - bool ns; - bool soa; - isc_buffer_t buffer; - isc_result_t answer = ISC_R_IGNORE; - isc_result_t result; - unsigned char hash[NSEC3_MAX_HASH_LENGTH]; - unsigned char owner[NSEC3_MAX_HASH_LENGTH]; - unsigned int length; - unsigned int qlabels; - unsigned int zlabels; - - REQUIRE((exists == NULL && data == NULL) || - (exists != NULL && data != NULL)); - REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3); - REQUIRE((setclosest == NULL && closest == NULL) || - (setclosest != NULL && closest != NULL)); - REQUIRE((setnearest == NULL && nearest == NULL) || - (setnearest != NULL && nearest != NULL)); - - result = dns_rdataset_first(nsec3set); - if (result != ISC_R_SUCCESS) { - (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set"); - return (result); - } - - dns_rdataset_current(nsec3set, &rdata); - - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3"); - - zone = dns_fixedname_initname(&fzone); - zlabels = dns_name_countlabels(nsec3name); - - /* - * NSEC3 records must have two or more labels to be valid. - */ - if (zlabels < 2) - return (ISC_R_IGNORE); - - /* - * Strip off the NSEC3 hash to get the zone. - */ - zlabels--; - dns_name_split(nsec3name, zlabels, NULL, zone); - - /* - * If not below the zone name we can ignore this record. - */ - if (!dns_name_issubdomain(name, zone)) - return (ISC_R_IGNORE); - - /* - * Is this zone the same or deeper than the current zone? - */ - if (dns_name_countlabels(zonename) == 0 || - dns_name_issubdomain(zone, zonename)) - dns_name_copy(zone, zonename, NULL); - - if (!dns_name_equal(zone, zonename)) - return (ISC_R_IGNORE); - - /* - * Are we only looking for the most enclosing zone? - */ - if (exists == NULL || data == NULL) - return (ISC_R_SUCCESS); - - /* - * Only set unknown once we are sure that this NSEC3 is from - * the deepest covering zone. - */ - if (!dns_nsec3_supportedhash(nsec3.hash)) { - if (unknown != NULL) - *unknown = true; - return (ISC_R_IGNORE); - } - - /* - * Recover the hash from the first label. - */ - dns_name_getlabel(nsec3name, 0, &hashlabel); - isc_region_consume(&hashlabel, 1); - isc_buffer_init(&buffer, owner, sizeof(owner)); - result = isc_base32hex_decoderegion(&hashlabel, &buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * The hash lengths should match. If not ignore the record. - */ - if (isc_buffer_usedlength(&buffer) != nsec3.next_length) - return (ISC_R_IGNORE); - - /* - * Work out what this NSEC3 covers. - * Inside (<0) or outside (>=0). - */ - scope = isc_safe_memcompare(owner, nsec3.next, nsec3.next_length); - - /* - * Prepare to compute all the hashes. - */ - qname = dns_fixedname_initname(&qfixed); - dns_name_downcase(name, qname, NULL); - qlabels = dns_name_countlabels(qname); - first = true; - - while (qlabels >= zlabels) { - length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations, - nsec3.salt, nsec3.salt_length, - qname->ndata, qname->length); - /* - * The computed hash length should match. - */ - if (length != nsec3.next_length) { - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring NSEC bad length %u vs %u", - length, nsec3.next_length); - return (ISC_R_IGNORE); - } - - order = isc_safe_memcompare(hash, owner, length); - if (first && order == 0) { - /* - * The hashes are the same. - */ - atparent = dns_rdatatype_atparent(type); - ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns); - soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa); - if (ns && !soa) { - if (!atparent) { - /* - * This NSEC3 record is from somewhere - * higher in the DNS, and at the - * parent of a delegation. It can not - * be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring parent NSEC3"); - return (ISC_R_IGNORE); - } - } else if (atparent && ns && soa) { - /* - * This NSEC3 record is from the child. - * It can not be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring child NSEC3"); - return (ISC_R_IGNORE); - } - if (type == dns_rdatatype_cname || - type == dns_rdatatype_nxt || - type == dns_rdatatype_nsec || - type == dns_rdatatype_key || - !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = true; - *data = dns_nsec3_typepresent(&rdata, type); - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC3 proves name exists (owner) " - "data=%d", *data); - return (ISC_R_SUCCESS); - } - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC3 proves CNAME exists"); - return (ISC_R_IGNORE); - } - - if (order == 0 && - dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa)) - { - /* - * This NSEC3 record is from somewhere higher in - * the DNS, and at the parent of a delegation. - * It can not be legitimately used here. - */ - (*logit)(arg, ISC_LOG_DEBUG(3), - "ignoring parent NSEC3"); - return (ISC_R_IGNORE); - } - - /* - * Potential closest encloser. - */ - if (order == 0) { - if (closest != NULL && - (dns_name_countlabels(closest) == 0 || - dns_name_issubdomain(qname, closest)) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) && - !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) && - (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) || - !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns))) - { - - dns_name_format(qname, namebuf, - sizeof(namebuf)); - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC3 indicates potential closest " - "encloser: '%s'", namebuf); - dns_name_copy(qname, closest, NULL); - *setclosest = true; - } - dns_name_format(qname, namebuf, sizeof(namebuf)); - (*logit)(arg, ISC_LOG_DEBUG(3), - "NSEC3 at super-domain %s", namebuf); - return (answer); - } - - /* - * Find if the name does not exist. - * - * We continue as we need to find the name closest to the - * closest encloser that doesn't exist. - * - * We also need to continue to ensure that we are not - * proving the non-existence of a record in a sub-zone. - * If that would be the case we will return ISC_R_IGNORE - * above. - */ - if ((scope < 0 && order > 0 && - memcmp(hash, nsec3.next, length) < 0) || - (scope >= 0 && (order > 0 || - memcmp(hash, nsec3.next, length) < 0))) - { - dns_name_format(qname, namebuf, sizeof(namebuf)); - (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves " - "name does not exist: '%s'", namebuf); - if (nearest != NULL && - (dns_name_countlabels(nearest) == 0 || - dns_name_issubdomain(nearest, qname))) { - dns_name_copy(qname, nearest, NULL); - *setnearest = true; - } - - *exists = false; - *data = false; - if (optout != NULL) { - *optout = ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) - != 0); - (*logit)(arg, ISC_LOG_DEBUG(3), - (*optout - ? "NSEC3 indicates optout" - : "NSEC3 indicates secure range")); - } - answer = ISC_R_SUCCESS; - } - - qlabels--; - if (qlabels > 0) - dns_name_split(qname, qlabels, NULL, qname); - first = false; - } - return (answer); -} diff --git a/lib/dns-pkcs11/nta.c b/lib/dns-pkcs11/nta.c deleted file mode 100644 index 73febe4..0000000 --- a/lib/dns-pkcs11/nta.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct dns_nta { - unsigned int magic; - isc_refcount_t refcount; - dns_ntatable_t *ntatable; - bool forced; - isc_timer_t *timer; - dns_fetch_t *fetch; - dns_rdataset_t rdataset; - dns_rdataset_t sigrdataset; - dns_fixedname_t fn; - dns_name_t *name; - isc_stdtime_t expiry; -}; - -#define NTA_MAGIC ISC_MAGIC('N', 'T', 'A', 'n') -#define VALID_NTA(nn) ISC_MAGIC_VALID(nn, NTA_MAGIC) - -/* - * Obtain a reference to the nta object. Released by - * nta_detach. - */ -static void -nta_ref(dns_nta_t *nta) { - isc_refcount_increment(&nta->refcount, NULL); -} - -static void -nta_detach(isc_mem_t *mctx, dns_nta_t **ntap) { - unsigned int refs; - dns_nta_t *nta = *ntap; - - REQUIRE(VALID_NTA(nta)); - - *ntap = NULL; - isc_refcount_decrement(&nta->refcount, &refs); - if (refs == 0) { - nta->magic = 0; - if (nta->timer != NULL) { - (void) isc_timer_reset(nta->timer, - isc_timertype_inactive, - NULL, NULL, true); - isc_timer_detach(&nta->timer); - } - isc_refcount_destroy(&nta->refcount); - if (dns_rdataset_isassociated(&nta->rdataset)) - dns_rdataset_disassociate(&nta->rdataset); - if (dns_rdataset_isassociated(&nta->sigrdataset)) - dns_rdataset_disassociate(&nta->sigrdataset); - if (nta->fetch != NULL) { - dns_resolver_cancelfetch(nta->fetch); - dns_resolver_destroyfetch(&nta->fetch); - } - isc_mem_put(mctx, nta, sizeof(dns_nta_t)); - } -} - -static void -free_nta(void *data, void *arg) { - dns_nta_t *nta = (dns_nta_t *) data; - isc_mem_t *mctx = (isc_mem_t *) arg; - - nta_detach(mctx, &nta); -} - -isc_result_t -dns_ntatable_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, - dns_ntatable_t **ntatablep) -{ - dns_ntatable_t *ntatable; - isc_result_t result; - - REQUIRE(ntatablep != NULL && *ntatablep == NULL); - - ntatable = isc_mem_get(view->mctx, sizeof(*ntatable)); - if (ntatable == NULL) - return (ISC_R_NOMEMORY); - - ntatable->task = NULL; - result = isc_task_create(taskmgr, 0, &ntatable->task); - if (result != ISC_R_SUCCESS) - goto cleanup_ntatable; - isc_task_setname(ntatable->task, "ntatable", ntatable); - - ntatable->table = NULL; - result = dns_rbt_create(view->mctx, free_nta, view->mctx, - &ntatable->table); - if (result != ISC_R_SUCCESS) - goto cleanup_task; - - result = isc_rwlock_init(&ntatable->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_rbt; - - ntatable->shuttingdown = false; - ntatable->timermgr = timermgr; - ntatable->taskmgr = taskmgr; - - ntatable->view = view; - ntatable->references = 1; - - ntatable->magic = NTATABLE_MAGIC; - *ntatablep = ntatable; - - return (ISC_R_SUCCESS); - - cleanup_rbt: - dns_rbt_destroy(&ntatable->table); - - cleanup_task: - isc_task_detach(&ntatable->task); - - cleanup_ntatable: - isc_mem_put(view->mctx, ntatable, sizeof(*ntatable)); - - return (result); -} - -void -dns_ntatable_attach(dns_ntatable_t *source, dns_ntatable_t **targetp) { - REQUIRE(VALID_NTATABLE(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - RWLOCK(&source->rwlock, isc_rwlocktype_write); - - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); - - RWUNLOCK(&source->rwlock, isc_rwlocktype_write); - - *targetp = source; -} - -void -dns_ntatable_detach(dns_ntatable_t **ntatablep) { - bool destroy = false; - dns_ntatable_t *ntatable; - - REQUIRE(ntatablep != NULL && VALID_NTATABLE(*ntatablep)); - - ntatable = *ntatablep; - *ntatablep = NULL; - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_write); - INSIST(ntatable->references > 0); - ntatable->references--; - if (ntatable->references == 0) - destroy = true; - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write); - - if (destroy) { - dns_rbt_destroy(&ntatable->table); - isc_rwlock_destroy(&ntatable->rwlock); - if (ntatable->task != NULL) - isc_task_detach(&ntatable->task); - ntatable->timermgr = NULL; - ntatable->taskmgr = NULL; - ntatable->magic = 0; - isc_mem_put(ntatable->view->mctx, ntatable, sizeof(*ntatable)); - } -} - -static void -fetch_done(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - dns_nta_t *nta = devent->ev_arg; - isc_result_t eresult = devent->result; - dns_ntatable_t *ntatable = nta->ntatable; - dns_view_t *view = ntatable->view; - isc_stdtime_t now; - - UNUSED(task); - - if (dns_rdataset_isassociated(&nta->rdataset)) - dns_rdataset_disassociate(&nta->rdataset); - if (dns_rdataset_isassociated(&nta->sigrdataset)) - dns_rdataset_disassociate(&nta->sigrdataset); - if (nta->fetch == devent->fetch) - nta->fetch = NULL; - dns_resolver_destroyfetch(&devent->fetch); - - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - - isc_event_free(&event); - isc_stdtime_get(&now); - - switch (eresult) { - case ISC_R_SUCCESS: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXRRSET: - case DNS_R_NXRRSET: - if (nta->expiry > now) - nta->expiry = now; - break; - default: - break; - } - - /* - * If we're expiring before the next recheck, we might - * as well stop the timer now. - */ - if (nta->timer != NULL && nta->expiry - now < view->nta_recheck) - (void) isc_timer_reset(nta->timer, isc_timertype_inactive, - NULL, NULL, true); - nta_detach(view->mctx, &nta); - dns_view_weakdetach(&view); -} - -static void -checkbogus(isc_task_t *task, isc_event_t *event) { - dns_nta_t *nta = event->ev_arg; - dns_ntatable_t *ntatable = nta->ntatable; - dns_view_t *view = NULL; - isc_result_t result; - - if (nta->fetch != NULL) { - dns_resolver_cancelfetch(nta->fetch); - nta->fetch = NULL; - } - if (dns_rdataset_isassociated(&nta->rdataset)) { - dns_rdataset_disassociate(&nta->rdataset); - } - if (dns_rdataset_isassociated(&nta->sigrdataset)) { - dns_rdataset_disassociate(&nta->sigrdataset); - } - - isc_event_free(&event); - - nta_ref(nta); - dns_view_weakattach(ntatable->view, &view); - result = dns_resolver_createfetch(view->resolver, nta->name, - dns_rdatatype_nsec, - NULL, NULL, NULL, - DNS_FETCHOPT_NONTA, - task, fetch_done, nta, - &nta->rdataset, - &nta->sigrdataset, - &nta->fetch); - if (result != ISC_R_SUCCESS) { - nta_detach(view->mctx, &nta); - dns_view_weakdetach(&view); - } -} - -static isc_result_t -settimer(dns_ntatable_t *ntatable, dns_nta_t *nta, uint32_t lifetime) { - isc_result_t result; - isc_interval_t interval; - dns_view_t *view; - - REQUIRE(VALID_NTATABLE(ntatable)); - REQUIRE(VALID_NTA(nta)); - - if (ntatable->timermgr == NULL) - return (ISC_R_SUCCESS); - - view = ntatable->view; - if (view->nta_recheck == 0 || lifetime <= view->nta_recheck) - return (ISC_R_SUCCESS); - - isc_interval_set(&interval, view->nta_recheck, 0); - result = isc_timer_create(ntatable->timermgr, isc_timertype_ticker, - NULL, &interval, ntatable->task, - checkbogus, nta, &nta->timer); - return (result); -} - -static isc_result_t -nta_create(dns_ntatable_t *ntatable, dns_name_t *name, dns_nta_t **target) { - isc_result_t result; - dns_nta_t *nta = NULL; - dns_view_t *view; - - REQUIRE(VALID_NTATABLE(ntatable)); - REQUIRE(target != NULL && *target == NULL); - - view = ntatable->view; - - nta = isc_mem_get(view->mctx, sizeof(dns_nta_t)); - if (nta == NULL) - return (ISC_R_NOMEMORY); - - nta->ntatable = ntatable; - nta->expiry = 0; - nta->timer = NULL; - nta->fetch = NULL; - dns_rdataset_init(&nta->rdataset); - dns_rdataset_init(&nta->sigrdataset); - - result = isc_refcount_init(&nta->refcount, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(view->mctx, nta, sizeof(dns_nta_t)); - return (result); - } - - nta->name = dns_fixedname_initname(&nta->fn); - dns_name_copy(name, nta->name, NULL); - - nta->magic = NTA_MAGIC; - - *target = nta; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_ntatable_add(dns_ntatable_t *ntatable, dns_name_t *name, bool force, - isc_stdtime_t now, uint32_t lifetime) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_nta_t *nta = NULL; - dns_rbtnode_t *node; - dns_view_t *view; - - REQUIRE(VALID_NTATABLE(ntatable)); - - view = ntatable->view; - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_write); - - if (ntatable->shuttingdown) { - goto unlock; - } - - result = nta_create(ntatable, name, &nta); - if (result != ISC_R_SUCCESS) { - goto unlock; - } - - nta->expiry = now + lifetime; - nta->forced = force; - - node = NULL; - result = dns_rbt_addnode(ntatable->table, name, &node); - if (result == ISC_R_SUCCESS) { - if (!force) { - (void)settimer(ntatable, nta, lifetime); - } - node->data = nta; - nta = NULL; - } else if (result == ISC_R_EXISTS) { - dns_nta_t *n = node->data; - if (n == NULL) { - if (!force) { - (void)settimer(ntatable, nta, lifetime); - } - node->data = nta; - nta = NULL; - } else { - n->expiry = nta->expiry; - nta_detach(view->mctx, &nta); - } - result = ISC_R_SUCCESS; - } - -unlock: - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write); - - if (nta != NULL) { - nta_detach(view->mctx, &nta); - } - - return (result); -} - -/* - * Caller must hold a write lock on rwlock. - */ -static isc_result_t -deletenode(dns_ntatable_t *ntatable, const dns_name_t *name) { - isc_result_t result; - dns_rbtnode_t *node = NULL; - - REQUIRE(VALID_NTATABLE(ntatable)); - REQUIRE(name != NULL); - - result = dns_rbt_findnode(ntatable->table, name, NULL, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - if (result == ISC_R_SUCCESS) { - if (node->data != NULL) - result = dns_rbt_deletenode(ntatable->table, - node, false); - else - result = ISC_R_NOTFOUND; - } else if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - - return (result); -} - -isc_result_t -dns_ntatable_delete(dns_ntatable_t *ntatable, dns_name_t *name) { - isc_result_t result; - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_write); - result = deletenode(ntatable, name); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write); - - return (result); -} - -bool -dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now, - dns_name_t *name, dns_name_t *anchor) -{ - isc_result_t result; - dns_fixedname_t fn; - dns_rbtnode_t *node; - dns_name_t *foundname; - dns_nta_t *nta = NULL; - bool answer = false; - isc_rwlocktype_t locktype = isc_rwlocktype_read; - - REQUIRE(ntatable == NULL || VALID_NTATABLE(ntatable)); - REQUIRE(dns_name_isabsolute(name)); - - if (ntatable == NULL) - return (false); - - foundname = dns_fixedname_initname(&fn); - - relock: - RWLOCK(&ntatable->rwlock, locktype); - again: - node = NULL; - result = dns_rbt_findnode(ntatable->table, name, foundname, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - if (result == DNS_R_PARTIALMATCH) { - if (dns_name_issubdomain(foundname, anchor)) - result = ISC_R_SUCCESS; - } - if (result == ISC_R_SUCCESS) { - nta = (dns_nta_t *) node->data; - answer = (nta->expiry > now); - } - - /* Deal with expired NTA */ - if (result == ISC_R_SUCCESS && !answer) { - char nb[DNS_NAME_FORMATSIZE]; - - if (locktype == isc_rwlocktype_read) { - RWUNLOCK(&ntatable->rwlock, locktype); - locktype = isc_rwlocktype_write; - goto relock; - } - - dns_name_format(foundname, nb, sizeof(nb)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, - DNS_LOGMODULE_NTA, ISC_LOG_INFO, - "deleting expired NTA at %s", nb); - - if (nta->timer != NULL) { - (void) isc_timer_reset(nta->timer, - isc_timertype_inactive, - NULL, NULL, true); - isc_timer_detach(&nta->timer); - } - - result = deletenode(ntatable, foundname); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, - DNS_LOGMODULE_NTA, ISC_LOG_INFO, - "deleting NTA failed: %s", - isc_result_totext(result)); - } - goto again; - } - RWUNLOCK(&ntatable->rwlock, locktype); - - return (answer); -} - -static isc_result_t -putstr(isc_buffer_t **b, const char *str) { - isc_result_t result; - - result = isc_buffer_reserve(b, strlen(str)); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_putstr(*b, str); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) { - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - bool first = true; - isc_stdtime_t now; - - REQUIRE(VALID_NTATABLE(ntatable)); - - isc_stdtime_get(&now); - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, ntatable->view->mctx); - result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - goto cleanup; - } - for (;;) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) { - dns_nta_t *n = (dns_nta_t *) node->data; - char nbuf[DNS_NAME_FORMATSIZE]; - char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char obuf[DNS_NAME_FORMATSIZE + - ISC_FORMATHTTPTIMESTAMP_SIZE + - sizeof("expired: \n")]; - dns_fixedname_t fn; - dns_name_t *name; - isc_time_t t; - - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - dns_name_format(name, nbuf, sizeof(nbuf)); - isc_time_set(&t, n->expiry, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); - - snprintf(obuf, sizeof(obuf), "%s%s: %s %s", - first ? "" : "\n", nbuf, - n->expiry <= now ? "expired" : "expiry", - tbuf); - first = false; - result = putstr(buf, obuf); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read); - return (result); -} - -#if 0 -isc_result_t -dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) { - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - isc_stdtime_t now; - - REQUIRE(VALID_NTATABLE(ntatable)); - - isc_stdtime_get(&now); - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, ntatable->view->mctx); - result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) - goto cleanup; - for (;;) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) { - dns_nta_t *n = (dns_nta_t *) node->data; - char nbuf[DNS_NAME_FORMATSIZE], tbuf[80]; - dns_fixedname_t fn; - dns_name_t *name; - isc_time_t t; - - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - dns_name_format(name, nbuf, sizeof(nbuf)); - isc_time_set(&t, n->expiry, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); - fprintf(fp, "%s: %s %s\n", nbuf, - n->expiry <= now ? "expired" : "expiry", - tbuf); - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read); - return (result); -} -#endif - -isc_result_t -dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) { - isc_result_t result; - isc_buffer_t *text = NULL; - int len = 4096; - - result = isc_buffer_allocate(ntatable->view->mctx, &text, len); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_ntatable_totext(ntatable, &text); - - if (isc_buffer_usedlength(text) != 0) { - (void) putstr(&text, "\n"); - } else if (result == ISC_R_SUCCESS) { - (void) putstr(&text, "none"); - } else { - (void) putstr(&text, "could not dump NTA table: "); - (void) putstr(&text, isc_result_totext(result)); - } - - fprintf(fp, "%.*s", (int) isc_buffer_usedlength(text), - (char *) isc_buffer_base(text)); - isc_buffer_free(&text); - return (result); -} - -isc_result_t -dns_ntatable_save(dns_ntatable_t *ntatable, FILE *fp) { - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - isc_stdtime_t now; - bool written = false; - - REQUIRE(VALID_NTATABLE(ntatable)); - - isc_stdtime_get(&now); - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, ntatable->view->mctx); - result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) - goto cleanup; - - for (;;) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) { - dns_nta_t *n = (dns_nta_t *) node->data; - if (n->expiry > now) { - isc_buffer_t b; - char nbuf[DNS_NAME_FORMATSIZE + 1], tbuf[80]; - dns_fixedname_t fn; - dns_name_t *name; - - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - - isc_buffer_init(&b, nbuf, sizeof(nbuf)); - result = dns_name_totext(name, false, &b); - if (result != ISC_R_SUCCESS) - goto skip; - - /* Zero terminate. */ - isc_buffer_putuint8(&b, 0); - - isc_buffer_init(&b, tbuf, sizeof(tbuf)); - dns_time32_totext(n->expiry, &b); - - /* Zero terminate. */ - isc_buffer_putuint8(&b, 0); - - fprintf(fp, "%s %s %s\n", nbuf, - n->forced ? "forced" : "regular", - tbuf); - written = true; - } - } - skip: - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read); - - if (result != ISC_R_SUCCESS) - return (result); - else - return (written ? ISC_R_SUCCESS : ISC_R_NOTFOUND); -} - -void -dns_ntatable_shutdown(dns_ntatable_t *ntatable) { - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - - REQUIRE(VALID_NTATABLE(ntatable)); - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_write); - ntatable->shuttingdown = true; - - dns_rbtnodechain_init(&chain, ntatable->view->mctx); - result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL); - while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) { - dns_nta_t *nta = (dns_nta_t *)node->data; - if (nta->timer != NULL) { - (void)isc_timer_reset(nta->timer, - isc_timertype_inactive, - NULL, NULL, true); - } - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - } - - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write); -} diff --git a/lib/dns-pkcs11/openssl_link.c b/lib/dns-pkcs11/openssl_link.c deleted file mode 100644 index c7ac214..0000000 --- a/lib/dns-pkcs11/openssl_link.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -#ifdef OPENSSL - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "dst_internal.h" -#include "dst_openssl.h" - -#if !defined(OPENSSL_NO_ENGINE) -#include -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static isc_mutex_t *locks = NULL; -static int nlocks; -#endif - -#if !defined(OPENSSL_NO_ENGINE) -static ENGINE *e = NULL; -#endif - -#ifndef ISC_PLATFORM_CRYPTORANDOM -static RAND_METHOD *rm = NULL; - -static int -entropy_get(unsigned char *buf, int num) { - isc_result_t result; - if (num < 0) - return (-1); - result = dst__entropy_getdata(buf, (unsigned int) num, false); - return (result == ISC_R_SUCCESS ? 1 : -1); -} - -static int -entropy_status(void) { - return (dst__entropy_status() > 32); -} - -static int -entropy_getpseudo(unsigned char *buf, int num) { - isc_result_t result; - if (num < 0) - return (-1); - result = dst__entropy_getdata(buf, (unsigned int) num, true); - return (result == ISC_R_SUCCESS ? 1 : -1); -} - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static void -entropy_add(const void *buf, int num, double entropy) { - /* - * Do nothing. The only call to this provides no useful data anyway. - */ - UNUSED(buf); - UNUSED(num); - UNUSED(entropy); -} -#else -static int -entropy_add(const void *buf, int num, double entropy) { - /* - * Do nothing. The only call to this provides no useful data anyway. - */ - UNUSED(buf); - UNUSED(num); - UNUSED(entropy); - return (1); -} -#endif -#endif /* !ISC_PLATFORM_CRYPTORANDOM */ - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static void -lock_callback(int mode, int type, const char *file, int line) { - UNUSED(file); - UNUSED(line); - if ((mode & CRYPTO_LOCK) != 0) - LOCK(&locks[type]); - else - UNLOCK(&locks[type]); -} -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10000000L || defined(LIBRESSL_VERSION_NUMBER) -static unsigned long -id_callback(void) { - return ((unsigned long)isc_thread_self()); -} -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - -#define FLARG -#define FILELINE -#if ISC_MEM_TRACKLINES -#define FLARG_PASS , __FILE__, __LINE__ -#else -#define FLARG_PASS -#endif - -#else - -#define FLARG , const char *file, int line -#define FILELINE , __FILE__, __LINE__ -#if ISC_MEM_TRACKLINES -#define FLARG_PASS , file, line -#else -#define FLARG_PASS -#endif - -#endif - -static void * -mem_alloc(size_t size FLARG) { -#ifdef OPENSSL_LEAKS - void *ptr; - - INSIST(dst__memory_pool != NULL); - ptr = isc__mem_allocate(dst__memory_pool, size FLARG_PASS); - return (ptr); -#else - INSIST(dst__memory_pool != NULL); - return (isc__mem_allocate(dst__memory_pool, size FLARG_PASS)); -#endif -} - -static void -mem_free(void *ptr FLARG) { - if (ptr != NULL) { - INSIST(dst__memory_pool != NULL); - - isc__mem_free(dst__memory_pool, ptr FLARG_PASS); - } -} - -static void * -mem_realloc(void *ptr, size_t size FLARG) { -#ifdef OPENSSL_LEAKS - void *rptr; - - INSIST(dst__memory_pool != NULL); - rptr = isc__mem_reallocate(dst__memory_pool, ptr, size FLARG_PASS); - return (rptr); -#else - INSIST(dst__memory_pool != NULL); - return (isc__mem_reallocate(dst__memory_pool, ptr, size FLARG_PASS)); -#endif -} - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L -static void -_set_thread_id(CRYPTO_THREADID *id) -{ - CRYPTO_THREADID_set_numeric(id, (unsigned long)isc_thread_self()); -} -#endif - -isc_result_t -dst__openssl_init(const char *engine) { - isc_result_t result; -#if !defined(OPENSSL_NO_ENGINE) && !defined(ISC_PLATFORM_CRYPTORANDOM) - ENGINE *re; -#else - UNUSED(engine); -#endif - -#ifdef DNS_CRYPTO_LEAKS - CRYPTO_malloc_debug_init(); - CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); -#endif - CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - nlocks = CRYPTO_num_locks(); - locks = mem_alloc(sizeof(isc_mutex_t) * nlocks FILELINE); - if (locks == NULL) - return (ISC_R_NOMEMORY); - result = isc_mutexblock_init(locks, nlocks); - if (result != ISC_R_SUCCESS) - goto cleanup_mutexalloc; - CRYPTO_set_locking_callback(lock_callback); -# if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L - CRYPTO_THREADID_set_callback(_set_thread_id); -# else - CRYPTO_set_id_callback(id_callback); -# endif - - ERR_load_crypto_strings(); -#endif - -#ifndef ISC_PLATFORM_CRYPTORANDOM - rm = mem_alloc(sizeof(RAND_METHOD) FILELINE); - if (rm == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_mutexinit; - } - rm->seed = NULL; - rm->bytes = entropy_get; - rm->cleanup = NULL; - rm->add = entropy_add; - rm->pseudorand = entropy_getpseudo; - rm->status = entropy_status; -#endif - -#if !defined(OPENSSL_NO_ENGINE) -#if !defined(CONF_MFLAGS_DEFAULT_SECTION) - OPENSSL_config(NULL); -#else - /* - * OPENSSL_config() can only be called a single time as of - * 1.0.2e so do the steps individually. - */ - OPENSSL_load_builtin_modules(); - ENGINE_load_builtin_engines(); - ERR_clear_error(); - CONF_modules_load_file(NULL, NULL, - CONF_MFLAGS_DEFAULT_SECTION | - CONF_MFLAGS_IGNORE_MISSING_FILE); -#endif - - if (engine != NULL && *engine == '\0') - engine = NULL; - - if (engine != NULL) { - e = ENGINE_by_id(engine); - if (e == NULL) { - result = DST_R_NOENGINE; - goto cleanup_rm; - } - /* This will init the engine. */ - if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { - result = DST_R_NOENGINE; - goto cleanup_rm; - } - } - -#ifndef ISC_PLATFORM_CRYPTORANDOM - re = ENGINE_get_default_RAND(); - if (re == NULL) { - re = ENGINE_new(); - if (re == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_rm; - } - ENGINE_set_RAND(re, rm); - ENGINE_set_default_RAND(re); - ENGINE_free(re); - } else - ENGINE_finish(re); -#endif -#else -#ifndef ISC_PLATFORM_CRYPTORANDOM - RAND_set_rand_method(rm); -#endif -#endif /* !defined(OPENSSL_NO_ENGINE) */ - -#ifdef ISC_PLATFORM_USETHREADS - /* Protect ourselves against unseeded PRNG */ - if (RAND_status() != 1) { - FATAL_ERROR(__FILE__, __LINE__, - "OpenSSL pseudorandom number generator " - "cannot be initialized (see the `PRNG not " - "seeded' message in the OpenSSL FAQ)"); - } -#endif /* ISC_PLATFORM_USETHREADS */ - - return (ISC_R_SUCCESS); - -#if !defined(OPENSSL_NO_ENGINE) - cleanup_rm: - if (e != NULL) - ENGINE_free(e); - e = NULL; -#ifndef ISC_PLATFORM_CRYPTORANDOM - mem_free(rm FILELINE); - rm = NULL; -#endif -#endif -#ifndef ISC_PLATFORM_CRYPTORANDOM - cleanup_mutexinit: -#endif -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - CRYPTO_set_locking_callback(NULL); - DESTROYMUTEXBLOCK(locks, nlocks); - cleanup_mutexalloc: - mem_free(locks FILELINE); - locks = NULL; -#endif - return (result); -} - -void -dst__openssl_destroy(void) { -#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L) - OPENSSL_cleanup(); -#ifndef ISC_PLATFORM_CRYPTORANDOM - if (rm != NULL) { - mem_free(rm FILELINE); - rm = NULL; - } -#endif -#else - /* - * Sequence taken from apps_shutdown() in . - */ -#ifndef ISC_PLATFORM_CRYPTORANDOM - if (rm != NULL) { -#if OPENSSL_VERSION_NUMBER >= 0x00907000L - RAND_cleanup(); -#endif - mem_free(rm FILELINE); - rm = NULL; - } -#endif -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - CONF_modules_free(); -#endif - OBJ_cleanup(); - EVP_cleanup(); -#if !defined(OPENSSL_NO_ENGINE) - if (e != NULL) - ENGINE_free(e); - e = NULL; -#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L - ENGINE_cleanup(); -#endif -#endif -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - CRYPTO_cleanup_all_ex_data(); -#endif - ERR_clear_error(); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L - ERR_remove_thread_state(NULL); -#elif OPENSSL_VERSION_NUMBER < 0x10000000L || defined(LIBRESSL_VERSION_NUMBER) - ERR_remove_state(0); -#endif - ERR_free_strings(); - -#ifdef DNS_CRYPTO_LEAKS - CRYPTO_mem_leaks_fp(stderr); -#endif - - if (locks != NULL) { - CRYPTO_set_locking_callback(NULL); - DESTROYMUTEXBLOCK(locks, nlocks); - mem_free(locks FILELINE); - locks = NULL; - } -#endif -} - -static isc_result_t -toresult(isc_result_t fallback) { - isc_result_t result = fallback; - unsigned long err = ERR_peek_error(); -#if defined(HAVE_OPENSSL_ECDSA) && \ - defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) - int lib = ERR_GET_LIB(err); -#endif - int reason = ERR_GET_REASON(err); - - switch (reason) { - /* - * ERR_* errors are globally unique; others - * are unique per sublibrary - */ - case ERR_R_MALLOC_FAILURE: - result = ISC_R_NOMEMORY; - break; - default: -#if defined(HAVE_OPENSSL_ECDSA) && \ - defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) - if (lib == ERR_R_ECDSA_LIB && - reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) { - result = ISC_R_NOENTROPY; - break; - } -#endif - break; - } - - return (result); -} - -isc_result_t -dst__openssl_toresult(isc_result_t fallback) { - isc_result_t result; - - result = toresult(fallback); - - ERR_clear_error(); - return (result); -} - -isc_result_t -dst__openssl_toresult2(const char *funcname, isc_result_t fallback) { - return (dst__openssl_toresult3(DNS_LOGCATEGORY_GENERAL, - funcname, fallback)); -} - -isc_result_t -dst__openssl_toresult3(isc_logcategory_t *category, - const char *funcname, isc_result_t fallback) { - isc_result_t result; - unsigned long err; - const char *file, *data; - int line, flags; - char buf[256]; - - result = toresult(fallback); - - isc_log_write(dns_lctx, category, - DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, - "%s failed (%s)", funcname, - isc_result_totext(result)); - - if (result == ISC_R_NOMEMORY) - goto done; - - for (;;) { - err = ERR_get_error_line_data(&file, &line, &data, &flags); - if (err == 0U) - goto done; - ERR_error_string_n(err, buf, sizeof(buf)); - isc_log_write(dns_lctx, category, - DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, - "%s:%s:%d:%s", buf, file, line, - ((flags & ERR_TXT_STRING) != 0) ? data : ""); - } - - done: - ERR_clear_error(); - return (result); -} - -#if !defined(OPENSSL_NO_ENGINE) -ENGINE * -dst__openssl_getengine(const char *engine) { - - if (engine == NULL) - return (NULL); - if (e == NULL) - return (NULL); - if (strcmp(engine, ENGINE_get_id(e)) == 0) - return (e); - return (NULL); -} -#endif - -isc_result_t -dst_random_getdata(void *data, unsigned int length, - unsigned int *returned, unsigned int flags) -{ -#ifdef ISC_PLATFORM_CRYPTORANDOM -#ifndef DONT_REQUIRE_DST_LIB_INIT - INSIST(dst__memory_pool != NULL); -#endif - REQUIRE(data != NULL); - REQUIRE(length > 0); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - if ((flags & ISC_ENTROPY_GOODONLY) == 0) { - if (RAND_pseudo_bytes((unsigned char *)data, (int)length) < 0) - return (dst__openssl_toresult2("RAND_pseudo_bytes", - DST_R_OPENSSLFAILURE)); - } else { - if (RAND_bytes((unsigned char *)data, (int)length) != 1) - return (dst__openssl_toresult2("RAND_bytes", - DST_R_OPENSSLFAILURE)); - } -#else - UNUSED(flags); - - if (RAND_bytes((unsigned char *)data, (int)length) != 1) - return (dst__openssl_toresult2("RAND_bytes", - DST_R_OPENSSLFAILURE)); -#endif - if (returned != NULL) - *returned = length; - return (ISC_R_SUCCESS); -#else - UNUSED(data); - UNUSED(length); - UNUSED(returned); - UNUSED(flags); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -#endif /* OPENSSL */ -/*! \file */ diff --git a/lib/dns-pkcs11/openssldh_link.c b/lib/dns-pkcs11/openssldh_link.c deleted file mode 100644 index eb042ce..0000000 --- a/lib/dns-pkcs11/openssldh_link.c +++ /dev/null @@ -1,800 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -#ifdef OPENSSL - -#include - -#include - -#ifndef PK11_DH_DISABLE - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" - -#define PRIME2 "02" - -#define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \ - "A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \ - "F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF" - -#define PRIME1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \ - "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF2" \ - "5F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406" \ - "B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" - -#define PRIME1536 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ - "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" - - -static isc_result_t openssldh_todns(const dst_key_t *key, isc_buffer_t *data); - -static BIGNUM *bn2 = NULL, *bn768 = NULL, *bn1024 = NULL, *bn1536 = NULL; - -#if !defined(HAVE_DH_GET0_KEY) -/* - * DH_get0_key, DH_set0_key, DH_get0_pqg and DH_set0_pqg - * are from OpenSSL 1.1.0. - */ -static void -DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { - if (pub_key != NULL) { - *pub_key = dh->pub_key; - } - if (priv_key != NULL) { - *priv_key = dh->priv_key; - } -} - -static int -DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { - if (pub_key != NULL) { - BN_free(dh->pub_key); - dh->pub_key = pub_key; - } - - if (priv_key != NULL) { - BN_free(dh->priv_key); - dh->priv_key = priv_key; - } - - return (1); -} - -static void -DH_get0_pqg(const DH *dh, - const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) { - *p = dh->p; - } - if (q != NULL) { - *q = dh->q; - } - if (g != NULL) { - *g = dh->g; - } -} - -static int -DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) -{ - /* If the fields p and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. q may remain NULL. - */ - if ((dh->p == NULL && p == NULL) - || (dh->g == NULL && g == NULL)) - { - return 0; - } - - if (p != NULL) { - BN_free(dh->p); - dh->p = p; - } - if (q != NULL) { - BN_free(dh->q); - dh->q = q; - } - if (g != NULL) { - BN_free(dh->g); - dh->g = g; - } - - if (q != NULL) { - dh->length = BN_num_bits(q); - } - - return (1); -} - -#define DH_clear_flags(d, f) (d)->flags &= ~(f) - -#endif - -static isc_result_t -openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, - isc_buffer_t *secret) -{ - DH *dhpub, *dhpriv; - const BIGNUM *pub_key = NULL; - int ret; - isc_region_t r; - unsigned int len; - - REQUIRE(pub->keydata.dh != NULL); - REQUIRE(priv->keydata.dh != NULL); - - dhpub = pub->keydata.dh; - dhpriv = priv->keydata.dh; - - len = DH_size(dhpriv); - isc_buffer_availableregion(secret, &r); - if (r.length < len) - return (ISC_R_NOSPACE); - - DH_get0_key(dhpub, &pub_key, NULL); - ret = DH_compute_key(r.base, pub_key, dhpriv); - if (ret <= 0) - return (dst__openssl_toresult2("DH_compute_key", - DST_R_COMPUTESECRETFAILURE)); - isc_buffer_add(secret, len); - return (ISC_R_SUCCESS); -} - -static bool -openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) { - DH *dh1, *dh2; - const BIGNUM *pub_key1 = NULL, *pub_key2 = NULL; - const BIGNUM *priv_key1 = NULL, *priv_key2 = NULL; - const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; - - dh1 = key1->keydata.dh; - dh2 = key2->keydata.dh; - - if (dh1 == NULL && dh2 == NULL) - return (true); - else if (dh1 == NULL || dh2 == NULL) - return (false); - - DH_get0_key(dh1, &pub_key1, &priv_key1); - DH_get0_key(dh2, &pub_key2, &priv_key2); - DH_get0_pqg(dh1, &p1, NULL, &g1); - DH_get0_pqg(dh2, &p2, NULL, &g2); - - if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0 || - BN_cmp(pub_key1, pub_key2) != 0) - return (false); - - if (priv_key1 != NULL || priv_key2 != NULL) { - if (priv_key1 == NULL || priv_key2 == NULL) - return (false); - if (BN_cmp(priv_key1, priv_key2) != 0) - return (false); - } - return (true); -} - -static bool -openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { - DH *dh1, *dh2; - const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; - - dh1 = key1->keydata.dh; - dh2 = key2->keydata.dh; - - if (dh1 == NULL && dh2 == NULL) - return (true); - else if (dh1 == NULL || dh2 == NULL) - return (false); - - DH_get0_pqg(dh1, &p1, NULL, &g1); - DH_get0_pqg(dh2, &p2, NULL, &g2); - - if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0) - return (false); - return (true); -} - -#if OPENSSL_VERSION_NUMBER > 0x00908000L -static int -progress_cb(int p, int n, BN_GENCB *cb) { - union { - void *dptr; - void (*fptr)(int); - } u; - - UNUSED(n); - - u.dptr = BN_GENCB_get_arg(cb); - if (u.fptr != NULL) - u.fptr(p); - return (1); -} -#endif - -static isc_result_t -openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { - DH *dh = NULL; -#if OPENSSL_VERSION_NUMBER > 0x00908000L - BN_GENCB *cb; -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - BN_GENCB _cb; -#endif - union { - void *dptr; - void (*fptr)(int); - } u; -#else - - UNUSED(callback); -#endif - - if (generator == 0) { - if (key->key_size == 768 || - key->key_size == 1024 || - key->key_size == 1536) - { - BIGNUM *p, *g; - dh = DH_new(); - if (key->key_size == 768) - p = BN_dup(bn768); - else if (key->key_size == 1024) - p = BN_dup(bn1024); - else - p = BN_dup(bn1536); - g = BN_dup(bn2); - if (dh == NULL || p == NULL || g == NULL) { - if (dh != NULL) - DH_free(dh); - if (p != NULL) - BN_free(p); - if (g != NULL) - BN_free(g); - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - } - DH_set0_pqg(dh, p, NULL, g); - } else - generator = 2; - } - - if (generator != 0) { -#if OPENSSL_VERSION_NUMBER > 0x00908000L - dh = DH_new(); - if (dh == NULL) - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - cb = BN_GENCB_new(); -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) - if (cb == NULL) { - DH_free(dh); - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - } -#endif - if (callback == NULL) { - BN_GENCB_set_old(cb, NULL, NULL); - } else { - u.fptr = callback; - BN_GENCB_set(cb, &progress_cb, u.dptr); - } - - if (!DH_generate_parameters_ex(dh, key->key_size, generator, - cb)) { - DH_free(dh); - BN_GENCB_free(cb); - return (dst__openssl_toresult2( - "DH_generate_parameters_ex", - DST_R_OPENSSLFAILURE)); - } - BN_GENCB_free(cb); - cb = NULL; -#else - dh = DH_generate_parameters(key->key_size, generator, - NULL, NULL); - if (dh == NULL) - return (dst__openssl_toresult2( - "DH_generate_parameters", - DST_R_OPENSSLFAILURE)); -#endif - } - - if (DH_generate_key(dh) == 0) { - DH_free(dh); - return (dst__openssl_toresult2("DH_generate_key", - DST_R_OPENSSLFAILURE)); - } - DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); - key->keydata.dh = dh; - - return (ISC_R_SUCCESS); -} - -static bool -openssldh_isprivate(const dst_key_t *key) { - DH *dh = key->keydata.dh; - const BIGNUM *priv_key = NULL; - - DH_get0_key(dh, NULL, &priv_key); - return (dh != NULL && priv_key != NULL); -} - -static void -openssldh_destroy(dst_key_t *key) { - DH *dh = key->keydata.dh; - - if (dh == NULL) - return; - - DH_free(dh); - key->keydata.dh = NULL; -} - -static void -uint16_toregion(uint16_t val, isc_region_t *region) { - *region->base = (val & 0xff00) >> 8; - isc_region_consume(region, 1); - *region->base = (val & 0x00ff); - isc_region_consume(region, 1); -} - -static uint16_t -uint16_fromregion(isc_region_t *region) { - uint16_t val; - unsigned char *cp = region->base; - - val = ((unsigned int)(cp[0])) << 8; - val |= ((unsigned int)(cp[1])); - - isc_region_consume(region, 2); - - return (val); -} - -static isc_result_t -openssldh_todns(const dst_key_t *key, isc_buffer_t *data) { - DH *dh; - const BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; - isc_region_t r; - uint16_t dnslen, plen, glen, publen; - - REQUIRE(key->keydata.dh != NULL); - - dh = key->keydata.dh; - - isc_buffer_availableregion(data, &r); - - DH_get0_pqg(dh, &p, NULL, &g); - if (BN_cmp(g, bn2) == 0 && - (BN_cmp(p, bn768) == 0 || - BN_cmp(p, bn1024) == 0 || - BN_cmp(p, bn1536) == 0)) { - plen = 1; - glen = 0; - } - else { - plen = BN_num_bytes(p); - glen = BN_num_bytes(g); - } - DH_get0_key(dh, &pub_key, NULL); - publen = BN_num_bytes(pub_key); - dnslen = plen + glen + publen + 6; - if (r.length < (unsigned int) dnslen) - return (ISC_R_NOSPACE); - - uint16_toregion(plen, &r); - if (plen == 1) { - if (BN_cmp(p, bn768) == 0) - *r.base = 1; - else if (BN_cmp(p, bn1024) == 0) - *r.base = 2; - else - *r.base = 3; - } else - BN_bn2bin(p, r.base); - isc_region_consume(&r, plen); - - uint16_toregion(glen, &r); - if (glen > 0) - BN_bn2bin(g, r.base); - isc_region_consume(&r, glen); - - uint16_toregion(publen, &r); - BN_bn2bin(pub_key, r.base); - isc_region_consume(&r, publen); - - isc_buffer_add(data, dnslen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { - DH *dh; - BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; - isc_region_t r; - uint16_t plen, glen, publen; - int special = 0; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - dh = DH_new(); - if (dh == NULL) - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); - - /* - * Read the prime length. 1 & 2 are table entries, > 16 means a - * prime follows, otherwise an error. - */ - if (r.length < 2) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - plen = uint16_fromregion(&r); - if (plen < 16 && plen != 1 && plen != 2) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - if (r.length < plen) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - if (plen == 1 || plen == 2) { - if (plen == 1) { - special = *r.base; - isc_region_consume(&r, 1); - } else { - special = uint16_fromregion(&r); - } - switch (special) { - case 1: - p = BN_dup(bn768); - break; - case 2: - p = BN_dup(bn1024); - break; - case 3: - p = BN_dup(bn1536); - break; - default: - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - } else { - p = BN_bin2bn(r.base, plen, NULL); - isc_region_consume(&r, plen); - } - - /* - * Read the generator length. This should be 0 if the prime was - * special, but it might not be. If it's 0 and the prime is not - * special, we have a problem. - */ - if (r.length < 2) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - glen = uint16_fromregion(&r); - if (r.length < glen) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - if (special != 0) { - if (glen == 0) - g = BN_dup(bn2); - else { - g = BN_bin2bn(r.base, glen, NULL); - if (g != NULL && BN_cmp(g, bn2) != 0) { - DH_free(dh); - BN_free(g); - return (DST_R_INVALIDPUBLICKEY); - } - } - } else { - if (glen == 0) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - g = BN_bin2bn(r.base, glen, NULL); - } - isc_region_consume(&r, glen); - - if (p == NULL || g == NULL) { - DH_free(dh); - if (p != NULL) - BN_free(p); - if (g != NULL) - BN_free(g); - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - } - DH_set0_pqg(dh, p, NULL, g); - - if (r.length < 2) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - publen = uint16_fromregion(&r); - if (r.length < publen) { - DH_free(dh); - return (DST_R_INVALIDPUBLICKEY); - } - pub_key = BN_bin2bn(r.base, publen, NULL); - if (pub_key == NULL) { - DH_free(dh); - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - } -#if (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) && (LIBRESSL_VERSION_NUMBER <= 0x2070200fL) - /* - * LibreSSL << 2.7.3 DH_get0_key requires priv_key to be set when - * DH structure is empty, hence we cannot use DH_get0_key(). - */ - dh->pub_key = pub_key; -#else /* LIBRESSL_VERSION_NUMBER */ - DH_set0_key(dh, pub_key, NULL); -#endif /* LIBRESSL_VERSION_NUMBER */ - isc_region_consume(&r, publen); - - key->key_size = BN_num_bits(p); - - isc_buffer_forward(data, plen + glen + publen + 6); - - key->keydata.dh = dh; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssldh_tofile(const dst_key_t *key, const char *directory) { - int i; - DH *dh; - const BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; - dst_private_t priv; - unsigned char *bufs[4]; - isc_result_t result; - - if (key->keydata.dh == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - dh = key->keydata.dh; - DH_get0_key(dh, &pub_key, &priv_key); - DH_get0_pqg(dh, &p, NULL, &g); - - memset(bufs, 0, sizeof(bufs)); - for (i = 0; i < 4; i++) { - bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(p)); - if (bufs[i] == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - } - - i = 0; - - priv.elements[i].tag = TAG_DH_PRIME; - priv.elements[i].length = BN_num_bytes(p); - BN_bn2bin(p, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_GENERATOR; - priv.elements[i].length = BN_num_bytes(g); - BN_bn2bin(g, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_PRIVATE; - priv.elements[i].length = BN_num_bytes(priv_key); - BN_bn2bin(priv_key, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_PUBLIC; - priv.elements[i].length = BN_num_bytes(pub_key); - BN_bn2bin(pub_key, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - priv.nelements = i; - result = dst__privstruct_writefile(key, &priv, directory); - fail: - for (i = 0; i < 4; i++) { - if (bufs[i] == NULL) - break; - isc_mem_put(key->mctx, bufs[i], BN_num_bytes(p)); - } - return (result); -} - -static isc_result_t -openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - DH *dh = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; - isc_mem_t *mctx; -#define DST_RET(a) {ret = a; goto err;} - - UNUSED(pub); - mctx = key->mctx; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) - DST_RET(DST_R_EXTERNALKEY); - - dh = DH_new(); - if (dh == NULL) - DST_RET(ISC_R_NOMEMORY); - DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); - key->keydata.dh = dh; - - for (i = 0; i < priv.nelements; i++) { - BIGNUM *bn; - bn = BN_bin2bn(priv.elements[i].data, - priv.elements[i].length, NULL); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - - switch (priv.elements[i].tag) { - case TAG_DH_PRIME: - p = bn; - break; - case TAG_DH_GENERATOR: - g = bn; - break; - case TAG_DH_PRIVATE: - priv_key = bn; - break; - case TAG_DH_PUBLIC: - pub_key = bn; - break; - } - } - dst__privstruct_free(&priv, mctx); - DH_set0_key(dh, pub_key, priv_key); - DH_set0_pqg(dh, p, NULL, g); - - key->key_size = BN_num_bits(p); - return (ISC_R_SUCCESS); - - err: - if (p != NULL) - BN_free(p); - if (g != NULL) - BN_free(g); - if (pub_key != NULL) - BN_free(pub_key); - if (priv_key != NULL) - BN_free(priv_key); - openssldh_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static void -openssldh_cleanup(void) { - BN_free(bn2); - bn2 = NULL; - - BN_free(bn768); - bn768 = NULL; - - BN_free(bn1024); - bn1024 = NULL; - - BN_free(bn1536); - bn1536 = NULL; -} - -static dst_func_t openssldh_functions = { - NULL, /*%< createctx */ - NULL, /*%< createctx2 */ - NULL, /*%< destroyctx */ - NULL, /*%< adddata */ - NULL, /*%< openssldh_sign */ - NULL, /*%< openssldh_verify */ - NULL, /*%< openssldh_verify2 */ - openssldh_computesecret, - openssldh_compare, - openssldh_paramcompare, - openssldh_generate, - openssldh_isprivate, - openssldh_destroy, - openssldh_todns, - openssldh_fromdns, - openssldh_tofile, - openssldh_parse, - openssldh_cleanup, - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__openssldh_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) { - if (BN_hex2bn(&bn2, PRIME2) == 0 || bn2 == NULL) { - goto cleanup; - } - if (BN_hex2bn(&bn768, PRIME768) == 0 || bn768 == NULL) { - goto cleanup; - } - if (BN_hex2bn(&bn1024, PRIME1024) == 0 || bn1024 == NULL) { - goto cleanup; - } - if (BN_hex2bn(&bn1536, PRIME1536) == 0 || bn1536 == NULL) { - goto cleanup; - } - *funcp = &openssldh_functions; - } - return (ISC_R_SUCCESS); - - cleanup: - if (bn2 != NULL) BN_free(bn2); - if (bn768 != NULL) BN_free(bn768); - if (bn1024 != NULL) BN_free(bn1024); - if (bn1536 != NULL) BN_free(bn1536); - return (ISC_R_NOMEMORY); -} -#endif /* !PK11_DH_DISABLE */ - -#else /* OPENSSL */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* OPENSSL */ -/*! \file */ diff --git a/lib/dns-pkcs11/openssldsa_link.c b/lib/dns-pkcs11/openssldsa_link.c deleted file mode 100644 index 2420d0f..0000000 --- a/lib/dns-pkcs11/openssldsa_link.c +++ /dev/null @@ -1,815 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - * - * Portions Copyright (C) Network Associates, Inc. - * - * Permission to use, copy, modify, and/or 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 NETWORK ASSOCIATES 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. - */ - -#ifdef OPENSSL -#ifndef USE_EVP -#define USE_EVP 1 -#endif - -#include - -#include - -#ifndef PK11_DSA_DISABLE - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" - -#include - -static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data); - -#if !defined(HAVE_DSA_GET0_PQG) -static void -DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, - const BIGNUM **g) -{ - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; -} - -static int -DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { - if (p == NULL || q == NULL || g == NULL) - return 0; - BN_free(d->p); - BN_free(d->q); - BN_free(d->g); - d->p = p; - d->q = q; - d->g = g; - - return 1; -} - -static void -DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) { - if (pub_key != NULL) - *pub_key = d->pub_key; - if (priv_key != NULL) - *priv_key = d->priv_key; -} - -static int -DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { - /* Note that it is valid for priv_key to be NULL */ - if (pub_key == NULL) - return 0; - - BN_free(d->pub_key); - BN_free(d->priv_key); - d->pub_key = pub_key; - d->priv_key = priv_key; - - return 1; -} - -static void -DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { - *pr = sig->r; - *ps = sig->s; -} - -static int -DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) { - if (r == NULL || s == NULL) - return 0; - - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - - return 1; -} - - -#define DSA_clear_flags(d, x) (d)->flags &= ~(x) - -#endif - -static isc_result_t -openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx; - - UNUSED(key); - - evp_md_ctx = EVP_MD_CTX_create(); - if (evp_md_ctx == NULL) - return (ISC_R_NOMEMORY); - - if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) { - EVP_MD_CTX_destroy(evp_md_ctx); - return (ISC_R_FAILURE); - } - - dctx->ctxdata.evp_md_ctx = evp_md_ctx; - - return (ISC_R_SUCCESS); -#else - isc_sha1_t *sha1ctx; - - UNUSED(key); - - sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); - if (sha1ctx == NULL) - return (ISC_R_NOMEMORY); - isc_sha1_init(sha1ctx); - dctx->ctxdata.sha1ctx = sha1ctx; - return (ISC_R_SUCCESS); -#endif -} - -static void -openssldsa_destroyctx(dst_context_t *dctx) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - if (evp_md_ctx != NULL) { - EVP_MD_CTX_destroy(evp_md_ctx); - dctx->ctxdata.evp_md_ctx = NULL; - } -#else - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - if (sha1ctx != NULL) { - isc_sha1_invalidate(sha1ctx); - isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); - dctx->ctxdata.sha1ctx = NULL; - } -#endif -} - -static isc_result_t -openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (ISC_R_FAILURE); - } -#else - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - isc_sha1_update(sha1ctx, data->base, data->length); -#endif - return (ISC_R_SUCCESS); -} - -static int -BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) { - int bytes = size - BN_num_bytes(bn); - while (bytes-- > 0) - *buf++ = 0; - BN_bn2bin(bn, buf); - return (size); -} - -static isc_result_t -openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_key_t *key = dctx->key; - DSA *dsa = key->keydata.dsa; - isc_region_t region; - DSA_SIG *dsasig; - const BIGNUM *r = 0, *s = NULL; - unsigned int klen; -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey; - unsigned char *sigbuf; - const unsigned char *sb; - unsigned int siglen; -#else - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; -#endif - - isc_buffer_availableregion(sig, ®ion); - if (region.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) - return (ISC_R_NOSPACE); - -#if USE_EVP - pkey = EVP_PKEY_new(); - if (pkey == NULL) - return (ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_DSA(pkey, dsa)) { - EVP_PKEY_free(pkey); - return (ISC_R_FAILURE); - } - sigbuf = malloc(EVP_PKEY_size(pkey)); - if (sigbuf == NULL) { - EVP_PKEY_free(pkey); - return (ISC_R_NOMEMORY); - } - if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { - EVP_PKEY_free(pkey); - free(sigbuf); - return (dst__openssl_toresult3(dctx->category, - "EVP_SignFinal", - ISC_R_FAILURE)); - } - INSIST(EVP_PKEY_size(pkey) >= (int) siglen); - EVP_PKEY_free(pkey); - /* Convert from Dss-Sig-Value (RFC2459). */ - dsasig = DSA_SIG_new(); - if (dsasig == NULL) { - free(sigbuf); - return (ISC_R_NOMEMORY); - } - sb = sigbuf; - if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { - free(sigbuf); - return (dst__openssl_toresult3(dctx->category, - "d2i_DSA_SIG", - ISC_R_FAILURE)); - } - free(sigbuf); - -#elif 0 - /* Only use EVP for the Digest */ - if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { - return (dst__openssl_toresult3(dctx->category, - "EVP_DigestFinal_ex", - ISC_R_FAILURE)); - } - dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); - if (dsasig == NULL) - return (dst__openssl_toresult3(dctx->category, - "DSA_do_sign", - DST_R_SIGNFAILURE)); -#else - isc_sha1_final(sha1ctx, digest); - - dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); - if (dsasig == NULL) - return (dst__openssl_toresult3(dctx->category, - "DSA_do_sign", - DST_R_SIGNFAILURE)); -#endif - - klen = (key->key_size - 512)/64; - if (klen > 255) - return (ISC_R_FAILURE); - *region.base = klen; - isc_region_consume(®ion, 1); - - DSA_SIG_get0(dsasig, &r, &s); - BN_bn2bin_fixed(r, region.base, ISC_SHA1_DIGESTLENGTH); - isc_region_consume(®ion, ISC_SHA1_DIGESTLENGTH); - BN_bn2bin_fixed(s, region.base, ISC_SHA1_DIGESTLENGTH); - isc_region_consume(®ion, ISC_SHA1_DIGESTLENGTH); - DSA_SIG_free(dsasig); - isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - dst_key_t *key = dctx->key; - DSA *dsa = key->keydata.dsa; - BIGNUM *r = NULL, *s = NULL; - int status = 0; - unsigned char *cp = sig->base; - DSA_SIG *dsasig; -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; -#if 0 - EVP_PKEY *pkey; - unsigned char *sigbuf; -#endif - unsigned int siglen; -#else - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; -#endif - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - - -#if USE_EVP -#if 1 - /* Only use EVP for the digest */ - if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { - return (ISC_R_FAILURE); - } -#endif -#else - isc_sha1_final(sha1ctx, digest); -#endif - - if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) { - return (DST_R_VERIFYFAILURE); - } - - cp++; /*%< Skip T */ - dsasig = DSA_SIG_new(); - if (dsasig == NULL) - return (ISC_R_NOMEMORY); - r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); - cp += ISC_SHA1_DIGESTLENGTH; - s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); - DSA_SIG_set0(dsasig, r, s); - -#if 0 - pkey = EVP_PKEY_new(); - if (pkey == NULL) - return (ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_DSA(pkey, dsa)) { - EVP_PKEY_free(pkey); - return (ISC_R_FAILURE); - } - /* Convert to Dss-Sig-Value (RFC2459). */ - sigbuf = malloc(EVP_PKEY_size(pkey) + 50); - if (sigbuf == NULL) { - EVP_PKEY_free(pkey); - return (ISC_R_NOMEMORY); - } - siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf); - INSIST(EVP_PKEY_size(pkey) >= (int) siglen); - status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey); - EVP_PKEY_free(pkey); - free(sigbuf); -#else - status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); -#endif - DSA_SIG_free(dsasig); - switch (status) { - case 1: - return (ISC_R_SUCCESS); - case 0: - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - default: - return (dst__openssl_toresult3(dctx->category, - "DSA_do_verify", - DST_R_VERIFYFAILURE)); - } -} - -static bool -openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - DSA *dsa1, *dsa2; - const BIGNUM *pub_key1 = NULL, *priv_key1 = NULL; - const BIGNUM *pub_key2 = NULL, *priv_key2 = NULL; - const BIGNUM *p1 = NULL, *q1 = NULL, *g1 = NULL; - const BIGNUM *p2 = NULL, *q2 = NULL, *g2 = NULL; - - dsa1 = key1->keydata.dsa; - dsa2 = key2->keydata.dsa; - - if (dsa1 == NULL && dsa2 == NULL) - return (true); - else if (dsa1 == NULL || dsa2 == NULL) - return (false); - - DSA_get0_key(dsa1, &pub_key1, &priv_key1); - DSA_get0_key(dsa2, &pub_key2, &priv_key2); - DSA_get0_pqg(dsa1, &p1, &q1, &g1); - DSA_get0_pqg(dsa2, &p2, &q2, &g2); - - if (BN_cmp(p1, p2) != 0 || BN_cmp(q1, q2) != 0 || - BN_cmp(g1, g2) != 0 || BN_cmp(pub_key1, pub_key2) != 0) - return (false); - - if (priv_key1 != NULL || priv_key2 != NULL) { - if (priv_key1 == NULL || priv_key2 == NULL) - return (false); - if (BN_cmp(priv_key1, priv_key2)) - return (false); - } - return (true); -} - -#if OPENSSL_VERSION_NUMBER > 0x00908000L -static int -progress_cb(int p, int n, BN_GENCB *cb) { - union { - void *dptr; - void (*fptr)(int); - } u; - - UNUSED(n); - - u.dptr = BN_GENCB_get_arg(cb); - if (u.fptr != NULL) - u.fptr(p); - return (1); -} -#endif - -static isc_result_t -openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - DSA *dsa; - unsigned char rand_array[ISC_SHA1_DIGESTLENGTH]; - isc_result_t result; -#if OPENSSL_VERSION_NUMBER > 0x00908000L - BN_GENCB *cb; -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - BN_GENCB _cb; -#endif - union { - void *dptr; - void (*fptr)(int); - } u; - -#else - - UNUSED(callback); -#endif - UNUSED(unused); - - result = dst__entropy_getdata(rand_array, sizeof(rand_array), - false); - if (result != ISC_R_SUCCESS) - return (result); - -#if OPENSSL_VERSION_NUMBER > 0x00908000L - dsa = DSA_new(); - if (dsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - cb = BN_GENCB_new(); -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) - if (cb == NULL) { - DSA_free(dsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } -#endif - if (callback == NULL) { - BN_GENCB_set_old(cb, NULL, NULL); - } else { - u.fptr = callback; - BN_GENCB_set(cb, &progress_cb, u.dptr); - } - - if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array, - ISC_SHA1_DIGESTLENGTH, NULL, NULL, - cb)) - { - DSA_free(dsa); - BN_GENCB_free(cb); - return (dst__openssl_toresult2("DSA_generate_parameters_ex", - DST_R_OPENSSLFAILURE)); - } - BN_GENCB_free(cb); - cb = NULL; -#else - dsa = DSA_generate_parameters(key->key_size, rand_array, - ISC_SHA1_DIGESTLENGTH, NULL, NULL, - NULL, NULL); - if (dsa == NULL) - return (dst__openssl_toresult2("DSA_generate_parameters", - DST_R_OPENSSLFAILURE)); -#endif - - if (DSA_generate_key(dsa) == 0) { - DSA_free(dsa); - return (dst__openssl_toresult2("DSA_generate_key", - DST_R_OPENSSLFAILURE)); - } - - DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P); - - key->keydata.dsa = dsa; - - return (ISC_R_SUCCESS); -} - -static bool -openssldsa_isprivate(const dst_key_t *key) { - DSA *dsa = key->keydata.dsa; - const BIGNUM *priv_key = NULL; - - DSA_get0_key(dsa, NULL, &priv_key); - return (dsa != NULL && priv_key != NULL); -} - -static void -openssldsa_destroy(dst_key_t *key) { - DSA *dsa = key->keydata.dsa; - DSA_free(dsa); - key->keydata.dsa = NULL; -} - - -static isc_result_t -openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) { - DSA *dsa; - const BIGNUM *pub_key, *p = NULL, *q = NULL, *g = NULL; - isc_region_t r; - int dnslen; - unsigned int t, p_bytes; - - REQUIRE(key->keydata.dsa != NULL); - - dsa = key->keydata.dsa; - - isc_buffer_availableregion(data, &r); - - DSA_get0_key(dsa, &pub_key, NULL); - DSA_get0_pqg(dsa, &p, &q, &g); - - t = (BN_num_bytes(p) - 64) / 8; - if (t > 8) - return (DST_R_INVALIDPUBLICKEY); - p_bytes = 64 + 8 * t; - - dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; - if (r.length < (unsigned int) dnslen) - return (ISC_R_NOSPACE); - - *r.base = t; - isc_region_consume(&r, 1); - - BN_bn2bin_fixed(q, r.base, ISC_SHA1_DIGESTLENGTH); - isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); - BN_bn2bin_fixed(p, r.base, key->key_size/8); - isc_region_consume(&r, p_bytes); - BN_bn2bin_fixed(g, r.base, key->key_size/8); - isc_region_consume(&r, p_bytes); - BN_bn2bin_fixed(pub_key, r.base, key->key_size/8); - isc_region_consume(&r, p_bytes); - - isc_buffer_add(data, dnslen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - DSA *dsa; - BIGNUM *pub_key, *p, *q, *g; - isc_region_t r; - unsigned int t, p_bytes; - isc_mem_t *mctx = key->mctx; - - UNUSED(mctx); - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - dsa = DSA_new(); - if (dsa == NULL) - return (ISC_R_NOMEMORY); - DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P); - - t = (unsigned int) *r.base; - isc_region_consume(&r, 1); - if (t > 8) { - DSA_free(dsa); - return (DST_R_INVALIDPUBLICKEY); - } - p_bytes = 64 + 8 * t; - - if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { - DSA_free(dsa); - return (DST_R_INVALIDPUBLICKEY); - } - - q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL); - isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); - - p = BN_bin2bn(r.base, p_bytes, NULL); - isc_region_consume(&r, p_bytes); - - g = BN_bin2bn(r.base, p_bytes, NULL); - isc_region_consume(&r, p_bytes); - - pub_key = BN_bin2bn(r.base, p_bytes, NULL); - isc_region_consume(&r, p_bytes); - - if (pub_key == NULL || p == NULL || q == NULL || g == NULL) { - DSA_free(dsa); - if (p != NULL) BN_free(p); - if (q != NULL) BN_free(q); - if (g != NULL) BN_free(g); - return (ISC_R_NOMEMORY); - } - - DSA_set0_key(dsa, pub_key, NULL); - DSA_set0_pqg(dsa, p, q, g); - - key->key_size = p_bytes * 8; - - isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); - - key->keydata.dsa = dsa; - - return (ISC_R_SUCCESS); -} - - -static isc_result_t -openssldsa_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - DSA *dsa; - const BIGNUM *pub_key = NULL, *priv_key = NULL; - const BIGNUM *p = NULL, *q = NULL, *g = NULL; - dst_private_t priv; - unsigned char bufs[5][128]; - - if (key->keydata.dsa == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - dsa = key->keydata.dsa; - - DSA_get0_key(dsa, &pub_key, &priv_key); - DSA_get0_pqg(dsa, &p, &q, &g); - - priv.elements[cnt].tag = TAG_DSA_PRIME; - priv.elements[cnt].length = BN_num_bytes(p); - BN_bn2bin(p, bufs[cnt]); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_SUBPRIME; - priv.elements[cnt].length = BN_num_bytes(q); - BN_bn2bin(q, bufs[cnt]); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_BASE; - priv.elements[cnt].length = BN_num_bytes(g); - BN_bn2bin(g, bufs[cnt]); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_PRIVATE; - priv.elements[cnt].length = BN_num_bytes(priv_key); - BN_bn2bin(priv_key, bufs[cnt]); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_PUBLIC; - priv.elements[cnt].length = BN_num_bytes(pub_key); - BN_bn2bin(pub_key, bufs[cnt]); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - DSA *dsa = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL; - BIGNUM *p = NULL, *q = NULL, *g = NULL; - isc_mem_t *mctx = key->mctx; -#define DST_RET(a) {ret = a; goto err;} - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - - dsa = DSA_new(); - if (dsa == NULL) - DST_RET(ISC_R_NOMEMORY); - DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P); - key->keydata.dsa = dsa; - - for (i = 0; i < priv.nelements; i++) { - BIGNUM *bn; - bn = BN_bin2bn(priv.elements[i].data, - priv.elements[i].length, NULL); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - - switch (priv.elements[i].tag) { - case TAG_DSA_PRIME: - p = bn; - break; - case TAG_DSA_SUBPRIME: - q = bn; - break; - case TAG_DSA_BASE: - g = bn; - break; - case TAG_DSA_PRIVATE: - priv_key = bn; - break; - case TAG_DSA_PUBLIC: - pub_key = bn; - break; - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - DSA_set0_key(dsa, pub_key, priv_key); - DSA_set0_pqg(dsa, p, q, g); - key->key_size = BN_num_bits(p); - return (ISC_R_SUCCESS); - - err: - if (p != NULL) - BN_free(p); - if (q != NULL) - BN_free(q); - if (g != NULL) - BN_free(g); - openssldsa_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t openssldsa_functions = { - openssldsa_createctx, - NULL, /*%< createctx2 */ - openssldsa_destroyctx, - openssldsa_adddata, - openssldsa_sign, - openssldsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - openssldsa_compare, - NULL, /*%< paramcompare */ - openssldsa_generate, - openssldsa_isprivate, - openssldsa_destroy, - openssldsa_todns, - openssldsa_fromdns, - openssldsa_tofile, - openssldsa_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__openssldsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &openssldsa_functions; - return (ISC_R_SUCCESS); -} -#endif /* !PK11_DSA_DISABLE */ - -#else /* OPENSSL */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* OPENSSL */ -/*! \file */ diff --git a/lib/dns-pkcs11/opensslecdsa_link.c b/lib/dns-pkcs11/opensslecdsa_link.c deleted file mode 100644 index 83b5b51..0000000 --- a/lib/dns-pkcs11/opensslecdsa_link.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(OPENSSL) && defined(HAVE_OPENSSL_ECDSA) - -#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) -#error "ECDSA without EVP for SHA2?" -#endif - -#include - - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" - -#include -#include -#include -#include - -#ifndef NID_X9_62_prime256v1 -#error "P-256 group is not known (NID_X9_62_prime256v1)" -#endif -#ifndef NID_secp384r1 -#error "P-384 group is not known (NID_secp384r1)" -#endif - -#define DST_RET(a) {ret = a; goto err;} - -#if !defined(HAVE_ECDSA_SIG_GET0) -/* From OpenSSL 1.1 */ -static void -ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { - if (pr != NULL) { - *pr = sig->r; - } - if (ps != NULL) { - *ps = sig->s; - } -} - -static int -ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { - if (r == NULL || s == NULL) { - return 0; - } - - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - - return 1; -} -#endif - -static isc_result_t opensslecdsa_todns(const dst_key_t *key, - isc_buffer_t *data); - -static isc_result_t -opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { - EVP_MD_CTX *evp_md_ctx; - const EVP_MD *type = NULL; - - UNUSED(key); - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - - evp_md_ctx = EVP_MD_CTX_create(); - if (evp_md_ctx == NULL) - return (ISC_R_NOMEMORY); - if (dctx->key->key_alg == DST_ALG_ECDSA256) - type = EVP_sha256(); - else - type = EVP_sha384(); - - if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { - EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult3(dctx->category, - "EVP_DigestInit_ex", - ISC_R_FAILURE)); - } - - dctx->ctxdata.evp_md_ctx = evp_md_ctx; - - return (ISC_R_SUCCESS); -} - -static void -opensslecdsa_destroyctx(dst_context_t *dctx) { - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - - if (evp_md_ctx != NULL) { - EVP_MD_CTX_destroy(evp_md_ctx); - dctx->ctxdata.evp_md_ctx = NULL; - } -} - -static isc_result_t -opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - - if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) - return (dst__openssl_toresult3(dctx->category, - "EVP_DigestUpdate", - ISC_R_FAILURE)); - - return (ISC_R_SUCCESS); -} - -static int -BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) { - int bytes = size - BN_num_bytes(bn); - - while (bytes-- > 0) - *buf++ = 0; - BN_bn2bin(bn, buf); - return (size); -} - -static isc_result_t -opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_result_t ret; - dst_key_t *key = dctx->key; - isc_region_t region; - ECDSA_SIG *ecdsasig; - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; - EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); - unsigned int dgstlen, siglen; - unsigned char digest[EVP_MAX_MD_SIZE]; - const BIGNUM *r, *s; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - if (eckey == NULL) - return (ISC_R_FAILURE); - - if (key->key_alg == DST_ALG_ECDSA256) - siglen = DNS_SIG_ECDSA256SIZE; - else - siglen = DNS_SIG_ECDSA384SIZE; - - isc_buffer_availableregion(sig, ®ion); - if (region.length < siglen) - DST_RET(ISC_R_NOSPACE); - - if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) - DST_RET(dst__openssl_toresult3(dctx->category, - "EVP_DigestFinal", - ISC_R_FAILURE)); - - ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); - if (ecdsasig == NULL) - DST_RET(dst__openssl_toresult3(dctx->category, - "ECDSA_do_sign", - DST_R_SIGNFAILURE)); - ECDSA_SIG_get0(ecdsasig, &r, &s); - BN_bn2bin_fixed(r, region.base, siglen / 2); - isc_region_consume(®ion, siglen / 2); - BN_bn2bin_fixed(s, region.base, siglen / 2); - isc_region_consume(®ion, siglen / 2); - ECDSA_SIG_free(ecdsasig); - isc_buffer_add(sig, siglen); - ret = ISC_R_SUCCESS; - - err: - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static isc_result_t -opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_result_t ret; - dst_key_t *key = dctx->key; - int status; - unsigned char *cp = sig->base; - ECDSA_SIG *ecdsasig = NULL; - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; - EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); - unsigned int dgstlen, siglen; - unsigned char digest[EVP_MAX_MD_SIZE]; - BIGNUM *r = NULL, *s = NULL ; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - if (eckey == NULL) - return (ISC_R_FAILURE); - - if (key->key_alg == DST_ALG_ECDSA256) - siglen = DNS_SIG_ECDSA256SIZE; - else - siglen = DNS_SIG_ECDSA384SIZE; - - if (sig->length != siglen) - return (DST_R_VERIFYFAILURE); - - if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) - DST_RET (dst__openssl_toresult3(dctx->category, - "EVP_DigestFinal_ex", - ISC_R_FAILURE)); - - ecdsasig = ECDSA_SIG_new(); - if (ecdsasig == NULL) - DST_RET (ISC_R_NOMEMORY); - r = BN_bin2bn(cp, siglen / 2, NULL); - cp += siglen / 2; - s = BN_bin2bn(cp, siglen / 2, NULL); - ECDSA_SIG_set0(ecdsasig, r, s); - /* cp += siglen / 2; */ - - status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey); - switch (status) { - case 1: - ret = ISC_R_SUCCESS; - break; - case 0: - ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); - break; - default: - ret = dst__openssl_toresult3(dctx->category, - "ECDSA_do_verify", - DST_R_VERIFYFAILURE); - break; - } - - err: - if (ecdsasig != NULL) - ECDSA_SIG_free(ecdsasig); - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static bool -opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - bool ret; - int status; - EVP_PKEY *pkey1 = key1->keydata.pkey; - EVP_PKEY *pkey2 = key2->keydata.pkey; - EC_KEY *eckey1 = NULL; - EC_KEY *eckey2 = NULL; - const BIGNUM *priv1, *priv2; - - if (pkey1 == NULL && pkey2 == NULL) - return (true); - else if (pkey1 == NULL || pkey2 == NULL) - return (false); - - eckey1 = EVP_PKEY_get1_EC_KEY(pkey1); - eckey2 = EVP_PKEY_get1_EC_KEY(pkey2); - if (eckey1 == NULL && eckey2 == NULL) { - DST_RET (true); - } else if (eckey1 == NULL || eckey2 == NULL) - DST_RET (false); - - status = EVP_PKEY_cmp(pkey1, pkey2); - if (status != 1) - DST_RET (false); - - priv1 = EC_KEY_get0_private_key(eckey1); - priv2 = EC_KEY_get0_private_key(eckey2); - if (priv1 != NULL || priv2 != NULL) { - if (priv1 == NULL || priv2 == NULL) - DST_RET (false); - if (BN_cmp(priv1, priv2) != 0) - DST_RET (false); - } - ret = true; - - err: - if (eckey1 != NULL) - EC_KEY_free(eckey1); - if (eckey2 != NULL) - EC_KEY_free(eckey2); - return (ret); -} - -static isc_result_t -opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - isc_result_t ret; - EVP_PKEY *pkey; - EC_KEY *eckey = NULL; - int group_nid; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - UNUSED(unused); - UNUSED(callback); - - if (key->key_alg == DST_ALG_ECDSA256) { - group_nid = NID_X9_62_prime256v1; - key->key_size = DNS_KEY_ECDSA256SIZE * 4; - } else { - group_nid = NID_secp384r1; - key->key_size = DNS_KEY_ECDSA384SIZE * 4; - } - - eckey = EC_KEY_new_by_curve_name(group_nid); - if (eckey == NULL) - return (dst__openssl_toresult2("EC_KEY_new_by_curve_name", - DST_R_OPENSSLFAILURE)); - - if (EC_KEY_generate_key(eckey) != 1) - DST_RET (dst__openssl_toresult2("EC_KEY_generate_key", - DST_R_OPENSSLFAILURE)); - - pkey = EVP_PKEY_new(); - if (pkey == NULL) - DST_RET (ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { - EVP_PKEY_free(pkey); - DST_RET (ISC_R_FAILURE); - } - key->keydata.pkey = pkey; - ret = ISC_R_SUCCESS; - - err: - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static bool -opensslecdsa_isprivate(const dst_key_t *key) { - bool ret; - EVP_PKEY *pkey = key->keydata.pkey; - EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); - - ret = (eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL); - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static void -opensslecdsa_destroy(dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - - EVP_PKEY_free(pkey); - key->keydata.pkey = NULL; -} - -static isc_result_t -opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { - isc_result_t ret; - EVP_PKEY *pkey; - EC_KEY *eckey = NULL; - isc_region_t r; - int len; - unsigned char *cp; - unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; - - REQUIRE(key->keydata.pkey != NULL); - - pkey = key->keydata.pkey; - eckey = EVP_PKEY_get1_EC_KEY(pkey); - if (eckey == NULL) - return (dst__openssl_toresult(ISC_R_FAILURE)); - len = i2o_ECPublicKey(eckey, NULL); - /* skip form */ - len--; - - isc_buffer_availableregion(data, &r); - if (r.length < (unsigned int) len) - DST_RET (ISC_R_NOSPACE); - cp = buf; - if (!i2o_ECPublicKey(eckey, &cp)) - DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); - memmove(r.base, buf + 1, len); - isc_buffer_add(data, len); - ret = ISC_R_SUCCESS; - - err: - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static isc_result_t -opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - isc_result_t ret; - EVP_PKEY *pkey; - EC_KEY *eckey = NULL; - isc_region_t r; - int group_nid; - unsigned int len; - const unsigned char *cp; - unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - if (key->key_alg == DST_ALG_ECDSA256) { - len = DNS_KEY_ECDSA256SIZE; - group_nid = NID_X9_62_prime256v1; - } else { - len = DNS_KEY_ECDSA384SIZE; - group_nid = NID_secp384r1; - } - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - if (r.length < len) - return (DST_R_INVALIDPUBLICKEY); - - eckey = EC_KEY_new_by_curve_name(group_nid); - if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - - buf[0] = POINT_CONVERSION_UNCOMPRESSED; - memmove(buf + 1, r.base, len); - cp = buf; - if (o2i_ECPublicKey(&eckey, - (const unsigned char **) &cp, - (long) len + 1) == NULL) - DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); - if (EC_KEY_check_key(eckey) != 1) - DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); - - pkey = EVP_PKEY_new(); - if (pkey == NULL) - DST_RET (ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { - EVP_PKEY_free(pkey); - DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); - } - - isc_buffer_forward(data, len); - key->keydata.pkey = pkey; - key->key_size = len * 4; - ret = ISC_R_SUCCESS; - - err: - if (eckey != NULL) - EC_KEY_free(eckey); - return (ret); -} - -static isc_result_t -opensslecdsa_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - EVP_PKEY *pkey; - EC_KEY *eckey = NULL; - const BIGNUM *privkey; - dst_private_t priv; - unsigned char *buf = NULL; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - pkey = key->keydata.pkey; - eckey = EVP_PKEY_get1_EC_KEY(pkey); - if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - privkey = EC_KEY_get0_private_key(eckey); - if (privkey == NULL) - DST_RET (ISC_R_FAILURE); - - buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); - if (buf == NULL) - DST_RET (ISC_R_NOMEMORY); - - priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY; - priv.elements[0].length = BN_num_bytes(privkey); - BN_bn2bin(privkey, buf); - priv.elements[0].data = buf; - priv.nelements = 1; - ret = dst__privstruct_writefile(key, &priv, directory); - - err: - if (eckey != NULL) - EC_KEY_free(eckey); - if (buf != NULL) - isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); - return (ret); -} - -static isc_result_t -ecdsa_check(EC_KEY *eckey, dst_key_t *pub) -{ - isc_result_t ret = ISC_R_FAILURE; - EVP_PKEY *pkey; - EC_KEY *pubeckey = NULL; - const EC_POINT *pubkey; - - if (pub == NULL) - return (ISC_R_SUCCESS); - pkey = pub->keydata.pkey; - if (pkey == NULL) - return (ISC_R_SUCCESS); - pubeckey = EVP_PKEY_get1_EC_KEY(pkey); - if (pubeckey == NULL) - return (ISC_R_SUCCESS); - pubkey = EC_KEY_get0_public_key(pubeckey); - if (pubkey == NULL) - DST_RET (ISC_R_SUCCESS); - if (EC_KEY_set_public_key(eckey, pubkey) != 1) - DST_RET (ISC_R_SUCCESS); - if (EC_KEY_check_key(eckey) == 1) - DST_RET (ISC_R_SUCCESS); - - err: - if (pubeckey != NULL) - EC_KEY_free(pubeckey); - return (ret); -} - -static isc_result_t -opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - EVP_PKEY *pkey; - EC_KEY *eckey = NULL; - BIGNUM *privkey = NULL; - int group_nid; - isc_mem_t *mctx = key->mctx; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - goto err; - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - - if (key->key_alg == DST_ALG_ECDSA256) - group_nid = NID_X9_62_prime256v1; - else - group_nid = NID_secp384r1; - - eckey = EC_KEY_new_by_curve_name(group_nid); - if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - - privkey = BN_bin2bn(priv.elements[0].data, - priv.elements[0].length, NULL); - if (privkey == NULL) - DST_RET(ISC_R_NOMEMORY); - if (!EC_KEY_set_private_key(eckey, privkey)) - DST_RET(ISC_R_NOMEMORY); - if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - pkey = EVP_PKEY_new(); - if (pkey == NULL) - DST_RET (ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { - EVP_PKEY_free(pkey); - DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } - key->keydata.pkey = pkey; - if (key->key_alg == DST_ALG_ECDSA256) - key->key_size = DNS_KEY_ECDSA256SIZE * 4; - else - key->key_size = DNS_KEY_ECDSA384SIZE * 4; - ret = ISC_R_SUCCESS; - - err: - if (privkey != NULL) - BN_clear_free(privkey); - if (eckey != NULL) - EC_KEY_free(eckey); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t opensslecdsa_functions = { - opensslecdsa_createctx, - NULL, /*%< createctx2 */ - opensslecdsa_destroyctx, - opensslecdsa_adddata, - opensslecdsa_sign, - opensslecdsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - opensslecdsa_compare, - NULL, /*%< paramcompare */ - opensslecdsa_generate, - opensslecdsa_isprivate, - opensslecdsa_destroy, - opensslecdsa_todns, - opensslecdsa_fromdns, - opensslecdsa_tofile, - opensslecdsa_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__opensslecdsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &opensslecdsa_functions; - return (ISC_R_SUCCESS); -} - -#else /* HAVE_OPENSSL_ECDSA */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* HAVE_OPENSSL_ECDSA */ -/*! \file */ diff --git a/lib/dns-pkcs11/openssleddsa_link.c b/lib/dns-pkcs11/openssleddsa_link.c deleted file mode 100644 index 8b115ec..0000000 --- a/lib/dns-pkcs11/openssleddsa_link.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(OPENSSL) && \ - (defined(HAVE_OPENSSL_ED25519) || defined(HAVE_OPENSSL_ED448)) - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" - -#include -#include -#include -#include - -#ifndef NID_ED25519 -#error "Ed25519 group is not known (NID_ED25519)" -#endif -#ifndef NID_ED448 -#error "Ed448 group is not known (NID_ED448)" -#endif - -#define DST_RET(a) {ret = a; goto err;} - -/* OpenSSL doesn't provide direct access to key values */ - -#define PUBPREFIXLEN 12 - -static const unsigned char ed25519_pub_prefix[] = { - 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, - 0x70, 0x03, 0x21, 0x00 -}; - -static EVP_PKEY *pub_ed25519_to_ossl(const unsigned char *key) -{ - unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE]; - const unsigned char *p; - - memmove(buf, ed25519_pub_prefix, PUBPREFIXLEN); - memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED25519SIZE); - p = buf; - return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED25519SIZE)); -} - -static isc_result_t pub_ed25519_from_ossl(EVP_PKEY *pkey, - unsigned char *key) -{ - unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE]; - unsigned char *p; - int len; - - len = i2d_PUBKEY(pkey, NULL); - if ((len <= DNS_KEY_ED25519SIZE) || - (len > PUBPREFIXLEN + DNS_KEY_ED25519SIZE)) - return (DST_R_OPENSSLFAILURE); - p = buf; - len = i2d_PUBKEY(pkey, &p); - if ((len <= DNS_KEY_ED25519SIZE) || - (len > PUBPREFIXLEN + DNS_KEY_ED25519SIZE)) - return (DST_R_OPENSSLFAILURE); - memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE); - return (ISC_R_SUCCESS); -} - -static const unsigned char ed448_pub_prefix[] = { - 0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, - 0x71, 0x03, 0x3a, 0x00 -}; - -static EVP_PKEY *pub_ed448_to_ossl(const unsigned char *key) -{ - unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE]; - const unsigned char *p; - - memmove(buf, ed448_pub_prefix, PUBPREFIXLEN); - memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED448SIZE); - p = buf; - return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED448SIZE)); -} - -static isc_result_t pub_ed448_from_ossl(EVP_PKEY *pkey, - unsigned char *key) -{ - unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE]; - unsigned char *p; - int len; - - len = i2d_PUBKEY(pkey, NULL); - if ((len <= DNS_KEY_ED448SIZE) || - (len > PUBPREFIXLEN + DNS_KEY_ED448SIZE)) - return (DST_R_OPENSSLFAILURE); - p = buf; - len = i2d_PUBKEY(pkey, &p); - if ((len <= DNS_KEY_ED448SIZE) || - (len > PUBPREFIXLEN + DNS_KEY_ED448SIZE)) - return (DST_R_OPENSSLFAILURE); - memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE); - return (ISC_R_SUCCESS); -} - -#define PRIVPREFIXLEN 16 - -static const unsigned char ed25519_priv_prefix[] = { - 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, - 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20 -}; - -static EVP_PKEY *priv_ed25519_to_ossl(const unsigned char *key) -{ - unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE]; - const unsigned char *p; - - memmove(buf, ed25519_priv_prefix, PRIVPREFIXLEN); - memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED25519SIZE); - p = buf; - return (d2i_PrivateKey(NID_ED25519, NULL, &p, - PRIVPREFIXLEN + DNS_KEY_ED25519SIZE)); -} - -static isc_result_t priv_ed25519_from_ossl(EVP_PKEY *pkey, - unsigned char *key) -{ - unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE]; - unsigned char *p; - int len; - - len = i2d_PrivateKey(pkey, NULL); - if ((len <= DNS_KEY_ED25519SIZE) || - (len > PRIVPREFIXLEN + DNS_KEY_ED25519SIZE)) - return (DST_R_OPENSSLFAILURE); - p = buf; - len = i2d_PrivateKey(pkey, &p); - if ((len <= DNS_KEY_ED25519SIZE) || - (len > PRIVPREFIXLEN + DNS_KEY_ED25519SIZE)) - return (DST_R_OPENSSLFAILURE); - memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE); - return (ISC_R_SUCCESS); -} - -static const unsigned char ed448_priv_prefix[] = { - 0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, - 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39 -}; - -static EVP_PKEY *priv_ed448_to_ossl(const unsigned char *key) -{ - unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE]; - const unsigned char *p; - - memmove(buf, ed448_priv_prefix, PRIVPREFIXLEN); - memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED448SIZE); - p = buf; - return (d2i_PrivateKey(NID_ED448, NULL, &p, - PRIVPREFIXLEN + DNS_KEY_ED448SIZE)); -} - -static isc_result_t priv_ed448_from_ossl(EVP_PKEY *pkey, - unsigned char *key) -{ - unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE]; - unsigned char *p; - int len; - - len = i2d_PrivateKey(pkey, NULL); - if ((len <= DNS_KEY_ED448SIZE) || - (len > PRIVPREFIXLEN + DNS_KEY_ED448SIZE)) - return (DST_R_OPENSSLFAILURE); - p = buf; - len = i2d_PrivateKey(pkey, &p); - if ((len <= DNS_KEY_ED448SIZE) || - (len > PRIVPREFIXLEN + DNS_KEY_ED448SIZE)) - return (DST_R_OPENSSLFAILURE); - memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE); - return (ISC_R_SUCCESS); -} - -static isc_result_t openssleddsa_todns(const dst_key_t *key, - isc_buffer_t *data); - -static isc_result_t -openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_buffer_t *buf = NULL; - isc_result_t result; - - UNUSED(key); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - - result = isc_buffer_allocate(dctx->mctx, &buf, 64); - dctx->ctxdata.generic = buf; - - return (result); -} - -static void -openssleddsa_destroyctx(dst_context_t *dctx) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - if (buf != NULL) - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; -} - -static isc_result_t -openssleddsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - isc_buffer_t *nbuf = NULL; - isc_region_t r; - unsigned int length; - isc_result_t result; - - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - - result = isc_buffer_copyregion(buf, data); - if (result == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - length = isc_buffer_length(buf) + data->length + 64; - result = isc_buffer_allocate(dctx->mctx, &nbuf, length); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_usedregion(buf, &r); - (void) isc_buffer_copyregion(nbuf, &r); - (void) isc_buffer_copyregion(nbuf, data); - isc_buffer_free(&buf); - dctx->ctxdata.generic = nbuf; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_result_t ret; - dst_key_t *key = dctx->key; - isc_region_t tbsreg; - isc_region_t sigreg; - EVP_PKEY *pkey = key->keydata.pkey; - EVP_MD_CTX* ctx = EVP_MD_CTX_new(); - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - size_t siglen; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (ctx == NULL) - return (ISC_R_NOMEMORY); - - if (key->key_alg == DST_ALG_ED25519) - siglen = DNS_SIG_ED25519SIZE; - else - siglen = DNS_SIG_ED448SIZE; - - isc_buffer_availableregion(sig, &sigreg); - if (sigreg.length < (unsigned int) siglen) - DST_RET(ISC_R_NOSPACE); - - isc_buffer_usedregion(buf, &tbsreg); - - if (!EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey)) - DST_RET(dst__openssl_toresult3(dctx->category, - "EVP_DigestSignInit", - ISC_R_FAILURE)); - if (!EVP_DigestSign(ctx, sigreg.base, &siglen, - tbsreg.base, tbsreg.length)) - DST_RET(dst__openssl_toresult3(dctx->category, - "EVP_DigestSign", - DST_R_SIGNFAILURE)); - isc_buffer_add(sig, (unsigned int) siglen); - ret = ISC_R_SUCCESS; - - err: - if (ctx != NULL) - EVP_MD_CTX_free(ctx); - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; - - return (ret); -} - -static isc_result_t -openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_result_t ret; - dst_key_t *key = dctx->key; - int status; - isc_region_t tbsreg; - EVP_PKEY *pkey = key->keydata.pkey; - EVP_MD_CTX* ctx = EVP_MD_CTX_new(); - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - unsigned int siglen; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (ctx == NULL) - return (ISC_R_NOMEMORY); - - if (key->key_alg == DST_ALG_ED25519) - siglen = DNS_SIG_ED25519SIZE; - else - siglen = DNS_SIG_ED448SIZE; - - if (sig->length != siglen) - return (DST_R_VERIFYFAILURE); - - isc_buffer_usedregion(buf, &tbsreg); - - if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey)) - DST_RET(dst__openssl_toresult3(dctx->category, - "EVP_DigestVerifyInit", - ISC_R_FAILURE)); - - status = EVP_DigestVerify(ctx, sig->base, siglen, - tbsreg.base, tbsreg.length); - - switch (status) { - case 1: - ret = ISC_R_SUCCESS; - break; - case 0: - ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); - break; - default: - ret = dst__openssl_toresult3(dctx->category, - "EVP_DigestVerify", - DST_R_VERIFYFAILURE); - break; - } - - err: - if (ctx != NULL) - EVP_MD_CTX_free(ctx); - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; - - return (ret); -} - -static bool -openssleddsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - int status; - EVP_PKEY *pkey1 = key1->keydata.pkey; - EVP_PKEY *pkey2 = key2->keydata.pkey; - - if (pkey1 == NULL && pkey2 == NULL) - return (true); - else if (pkey1 == NULL || pkey2 == NULL) - return (false); - - status = EVP_PKEY_cmp(pkey1, pkey2); - if (status == 1) - return (true); - return (false); -} - -static isc_result_t -openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - isc_result_t ret; - EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *ctx = NULL; - int nid, status; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - UNUSED(unused); - UNUSED(callback); - - if (key->key_alg == DST_ALG_ED25519) { - nid = NID_ED25519; - key->key_size = DNS_KEY_ED25519SIZE; - } else { - nid = NID_ED448; - key->key_size = DNS_KEY_ED448SIZE; - } - - ctx = EVP_PKEY_CTX_new_id(nid, NULL); - if (ctx == NULL) - return (dst__openssl_toresult2("EVP_PKEY_CTX_new_id", - DST_R_OPENSSLFAILURE)); - - status = EVP_PKEY_keygen_init(ctx); - if (status != 1) - DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen_init", - DST_R_OPENSSLFAILURE)); - - status = EVP_PKEY_keygen(ctx, &pkey); - if (status != 1) - DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen", - DST_R_OPENSSLFAILURE)); - - key->keydata.pkey = pkey; - ret = ISC_R_SUCCESS; - - err: - if (ctx != NULL) - EVP_PKEY_CTX_free(ctx); - return (ret); -} - -static bool -openssleddsa_isprivate(const dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - int len; - - if (pkey == NULL) - return (false); - - len = i2d_PrivateKey(pkey, NULL); - if (len > 0) - return (true); - /* can check if first error is EC_R_INVALID_PRIVATE_KEY */ - while (ERR_get_error() != 0) { - /**/; - } - - return (false); -} - -static void -openssleddsa_destroy(dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - - EVP_PKEY_free(pkey); - key->keydata.pkey = NULL; -} - -static isc_result_t -openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { - EVP_PKEY *pkey = key->keydata.pkey; - isc_region_t r; - isc_result_t result; - - REQUIRE(pkey != NULL); - - pkey = key->keydata.pkey; - switch (key->key_alg) { - case DST_ALG_ED25519: - isc_buffer_availableregion(data, &r); - if (r.length < DNS_KEY_ED25519SIZE) - return (ISC_R_NOSPACE); - result = pub_ed25519_from_ossl(pkey, r.base); - if (result == ISC_R_SUCCESS) - isc_buffer_add(data, DNS_KEY_ED25519SIZE); - return (result); - case DST_ALG_ED448: - isc_buffer_availableregion(data, &r); - if (r.length < DNS_KEY_ED448SIZE) - return (ISC_R_NOSPACE); - result = pub_ed448_from_ossl(pkey, r.base); - if (result == ISC_R_SUCCESS) - isc_buffer_add(data, DNS_KEY_ED448SIZE); - return (result); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static isc_result_t -openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - EVP_PKEY *pkey; - isc_region_t r; - unsigned int len; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - if (r.length < len) - return (DST_R_INVALIDPUBLICKEY); - pkey = pub_ed25519_to_ossl(r.base); - } else { - len = DNS_KEY_ED448SIZE; - if (r.length < len) - return (DST_R_INVALIDPUBLICKEY); - pkey = pub_ed448_to_ossl(r.base); - } - if (pkey == NULL) - return (dst__openssl_toresult(ISC_R_FAILURE)); - isc_buffer_forward(data, len); - key->keydata.pkey = pkey; - key->key_size = len; - return (ISC_R_SUCCESS); -} - -static isc_result_t -openssleddsa_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - EVP_PKEY *pkey; - dst_private_t priv; - unsigned char *buf = NULL; - unsigned int len; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - pkey = key->keydata.pkey; - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - buf = isc_mem_get(key->mctx, len); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[0].tag = TAG_EDDSA_PRIVATEKEY; - priv.elements[0].length = len; - ret = priv_ed25519_from_ossl(pkey, buf); - if (ret != ISC_R_SUCCESS) - DST_RET (dst__openssl_toresult(ret)); - priv.elements[0].data = buf; - priv.nelements = 1; - ret = dst__privstruct_writefile(key, &priv, directory); - } else { - len = DNS_KEY_ED448SIZE; - buf = isc_mem_get(key->mctx, len); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[0].tag = TAG_EDDSA_PRIVATEKEY; - priv.elements[0].length = len; - ret = priv_ed448_from_ossl(pkey, buf); - if (ret != ISC_R_SUCCESS) - DST_RET (dst__openssl_toresult(ret)); - priv.elements[0].data = buf; - priv.nelements = 1; - ret = dst__privstruct_writefile(key, &priv, directory); - } - - err: - if (buf != NULL) - isc_mem_put(key->mctx, buf, len); - return (ret); -} - -static isc_result_t -eddsa_check(EVP_PKEY *privkey, dst_key_t *pub) -{ - EVP_PKEY *pkey; - - if (pub == NULL) - return (ISC_R_SUCCESS); - pkey = pub->keydata.pkey; - if (pkey == NULL) - return (ISC_R_SUCCESS); - if (EVP_PKEY_cmp(privkey, pkey) == 1) - return (ISC_R_SUCCESS); - return (ISC_R_FAILURE); -} - -static isc_result_t -openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - EVP_PKEY *pkey = NULL; - unsigned int len; - isc_mem_t *mctx = key->mctx; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - goto err; - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - if (priv.elements[0].length < len) - DST_RET(DST_R_INVALIDPRIVATEKEY); - pkey = priv_ed25519_to_ossl(priv.elements[0].data); - } else { - len = DNS_KEY_ED448SIZE; - if (priv.elements[0].length < len) - DST_RET(DST_R_INVALIDPRIVATEKEY); - pkey = priv_ed448_to_ossl(priv.elements[0].data); - } - if (pkey == NULL) - DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - if (eddsa_check(pkey, pub) != ISC_R_SUCCESS) { - EVP_PKEY_free(pkey); - DST_RET(DST_R_INVALIDPRIVATEKEY); - } - key->keydata.pkey = pkey; - key->key_size = len; - ret = ISC_R_SUCCESS; - - err: - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t openssleddsa_functions = { - openssleddsa_createctx, - NULL, /*%< createctx2 */ - openssleddsa_destroyctx, - openssleddsa_adddata, - openssleddsa_sign, - openssleddsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - openssleddsa_compare, - NULL, /*%< paramcompare */ - openssleddsa_generate, - openssleddsa_isprivate, - openssleddsa_destroy, - openssleddsa_todns, - openssleddsa_fromdns, - openssleddsa_tofile, - openssleddsa_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__openssleddsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &openssleddsa_functions; - return (ISC_R_SUCCESS); -} - -#else /* HAVE_OPENSSL_EDxxx */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* HAVE_OPENSSL_EDxxx */ -/*! \file */ diff --git a/lib/dns-pkcs11/opensslgost_link.c b/lib/dns-pkcs11/opensslgost_link.c deleted file mode 100644 index 2cd90bb..0000000 --- a/lib/dns-pkcs11/opensslgost_link.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(OPENSSL) && defined(HAVE_OPENSSL_GOST) - -#include - -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" -#include "dst_gost.h" - -#include -#include -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -#define EVP_MD_CTX_new() &(ctx->_ctx), EVP_MD_CTX_init(&(ctx->_ctx)) -#define EVP_MD_CTX_free(ptr) EVP_MD_CTX_cleanup(ptr) -#endif - -static ENGINE *e = NULL; -static const EVP_MD *opensslgost_digest; -extern const EVP_MD *EVP_gost(void); - -const EVP_MD *EVP_gost(void) { - return (opensslgost_digest); -} - -/* ISC methods */ - -isc_result_t -isc_gost_init(isc_gost_t *ctx) { - const EVP_MD *md; - int ret; - - INSIST(ctx != NULL); - - md = EVP_gost(); - if (md == NULL) - return (DST_R_CRYPTOFAILURE); - ctx->ctx = EVP_MD_CTX_new(); - if (ctx->ctx == NULL) - return (ISC_R_NOMEMORY); - ret = EVP_DigestInit(ctx->ctx, md); - if (ret != 1) - return (DST_R_CRYPTOFAILURE); - return (ISC_R_SUCCESS); -} - -void -isc_gost_invalidate(isc_gost_t *ctx) { - EVP_MD_CTX_free(ctx->ctx); - ctx->ctx = NULL; -} - -isc_result_t -isc_gost_update(isc_gost_t *ctx, const unsigned char *data, - unsigned int len) -{ - int ret; - - INSIST(ctx != NULL); - INSIST(ctx->ctx != NULL); - INSIST(data != NULL); - - ret = EVP_DigestUpdate(ctx->ctx, (const void *) data, (size_t) len); - if (ret != 1) - return (DST_R_CRYPTOFAILURE); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { - int ret; - - INSIST(ctx != NULL); - INSIST(ctx->ctx != NULL); - INSIST(digest != NULL); - - ret = EVP_DigestFinal(ctx->ctx, digest, NULL); - EVP_MD_CTX_free(ctx->ctx); - ctx->ctx = NULL; - if (ret != 1) - return (DST_R_CRYPTOFAILURE); - return (ISC_R_SUCCESS); -} - -/* DST methods */ - -#define DST_RET(a) {ret = a; goto err;} - -static isc_result_t opensslgost_todns(const dst_key_t *key, - isc_buffer_t *data); - -static isc_result_t -opensslgost_createctx(dst_key_t *key, dst_context_t *dctx) { - EVP_MD_CTX *evp_md_ctx; - const EVP_MD *md = EVP_gost(); - - UNUSED(key); - - if (md == NULL) - return (DST_R_OPENSSLFAILURE); - - evp_md_ctx = EVP_MD_CTX_create(); - if (evp_md_ctx == NULL) - return (ISC_R_NOMEMORY); - - if (!EVP_DigestInit_ex(evp_md_ctx, md, NULL)) { - EVP_MD_CTX_destroy(evp_md_ctx); - return (ISC_R_FAILURE); - } - dctx->ctxdata.evp_md_ctx = evp_md_ctx; - - return (ISC_R_SUCCESS); -} - -static void -opensslgost_destroyctx(dst_context_t *dctx) { - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - if (evp_md_ctx != NULL) { - EVP_MD_CTX_destroy(evp_md_ctx); - dctx->ctxdata.evp_md_ctx = NULL; - } -} - -static isc_result_t -opensslgost_adddata(dst_context_t *dctx, const isc_region_t *data) { - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - - if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) - return (ISC_R_FAILURE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_key_t *key = dctx->key; - isc_region_t r; - unsigned int siglen = 0; - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; - - isc_buffer_availableregion(sig, &r); - - if (r.length < (unsigned int) EVP_PKEY_size(pkey)) - return (ISC_R_NOSPACE); - - if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) - return (ISC_R_FAILURE); - - isc_buffer_add(sig, siglen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { - dst_key_t *key = dctx->key; - int status = 0; - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; - - status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); - switch (status) { - case 1: - return (ISC_R_SUCCESS); - case 0: - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - default: - return (dst__openssl_toresult3(dctx->category, - "EVP_VerifyFinal", - DST_R_VERIFYFAILURE)); - } -} - -static bool -opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) { - EVP_PKEY *pkey1, *pkey2; - - pkey1 = key1->keydata.pkey; - pkey2 = key2->keydata.pkey; - - if (pkey1 == NULL && pkey2 == NULL) - return (true); - else if (pkey1 == NULL || pkey2 == NULL) - return (false); - - if (EVP_PKEY_cmp(pkey1, pkey2) != 1) - return (false); - return (true); -} - -static int -progress_cb(EVP_PKEY_CTX *ctx) -{ - union { - void *dptr; - void (*fptr)(int); - } u; - int p; - - u.dptr = EVP_PKEY_CTX_get_app_data(ctx); - p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - if (u.fptr != NULL) - u.fptr(p); - return (1); -} - -static isc_result_t -opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { - EVP_PKEY_CTX *ctx; - union { - void *dptr; - void (*fptr)(int); - } u; - EVP_PKEY *pkey = NULL; - isc_result_t ret; - - UNUSED(unused); - ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); - if (ctx == NULL) - DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id", - DST_R_OPENSSLFAILURE)); - if (callback != NULL) { - u.fptr = callback; - EVP_PKEY_CTX_set_app_data(ctx, u.dptr); - EVP_PKEY_CTX_set_cb(ctx, &progress_cb); - } - if (EVP_PKEY_keygen_init(ctx) <= 0) - DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", - DST_R_OPENSSLFAILURE)); - if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) - DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str", - DST_R_OPENSSLFAILURE)); - if (EVP_PKEY_keygen(ctx, &pkey) <= 0) - DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", - DST_R_OPENSSLFAILURE)); - key->keydata.pkey = pkey; - key->key_size = EVP_PKEY_bits(pkey); - EVP_PKEY_CTX_free(ctx); - return (ISC_R_SUCCESS); - -err: - if (pkey != NULL) - EVP_PKEY_free(pkey); - if (ctx != NULL) - EVP_PKEY_CTX_free(ctx); - return (ret); -} - -static bool -opensslgost_isprivate(const dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - EC_KEY *ec; - - INSIST(pkey != NULL); - - ec = EVP_PKEY_get0(pkey); - return (ec != NULL && EC_KEY_get0_private_key(ec) != NULL); -} - -static void -opensslgost_destroy(dst_key_t *key) { - EVP_PKEY *pkey = key->keydata.pkey; - - EVP_PKEY_free(pkey); - key->keydata.pkey = NULL; -} - -static const unsigned char gost_prefix[37] = { - 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, - 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, - 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, - 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, - 0x03, 0x43, 0x00, 0x04, 0x40 -}; - -static isc_result_t -opensslgost_todns(const dst_key_t *key, isc_buffer_t *data) { - EVP_PKEY *pkey; - isc_region_t r; - unsigned char der[37 + 64], *p; - int len; - - REQUIRE(key->keydata.pkey != NULL); - - pkey = key->keydata.pkey; - - isc_buffer_availableregion(data, &r); - if (r.length < 64) - return (ISC_R_NOSPACE); - - p = der; - len = i2d_PUBKEY(pkey, &p); - INSIST(len == sizeof(der)); - INSIST(isc_safe_memequal(gost_prefix, der, 37)); - memmove(r.base, der + 37, 64); - isc_buffer_add(data, 64); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { - isc_region_t r; - EVP_PKEY *pkey = NULL; - unsigned char der[37 + 64]; - const unsigned char *p; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - if (r.length != 64) - return (DST_R_INVALIDPUBLICKEY); - memmove(der, gost_prefix, 37); - memmove(der + 37, r.base, 64); - isc_buffer_forward(data, 64); - - p = der; - if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) - return (dst__openssl_toresult2("d2i_PUBKEY", - DST_R_OPENSSLFAILURE)); - key->keydata.pkey = pkey; - key->key_size = EVP_PKEY_bits(pkey); - - return (ISC_R_SUCCESS); -} - -#ifdef PREFER_GOSTASN1 - -static isc_result_t -opensslgost_tofile(const dst_key_t *key, const char *directory) { - EVP_PKEY *pkey; - dst_private_t priv; - isc_result_t result; - unsigned char *der, *p; - int len; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - pkey = key->keydata.pkey; - - len = i2d_PrivateKey(pkey, NULL); - der = isc_mem_get(key->mctx, (size_t) len); - if (der == NULL) - return (ISC_R_NOMEMORY); - - p = der; - if (i2d_PrivateKey(pkey, &p) != len) { - result = dst__openssl_toresult2("i2d_PrivateKey", - DST_R_OPENSSLFAILURE); - goto fail; - } - - priv.elements[0].tag = TAG_GOST_PRIVASN1; - priv.elements[0].length = len; - priv.elements[0].data = der; - priv.nelements = 1; - - result = dst__privstruct_writefile(key, &priv, directory); - fail: - if (der != NULL) - isc_mem_put(key->mctx, der, (size_t) len); - return (result); -} - -#else - -static isc_result_t -opensslgost_tofile(const dst_key_t *key, const char *directory) { - EVP_PKEY *pkey; - EC_KEY *eckey; - const BIGNUM *privkey; - dst_private_t priv; - isc_result_t ret; - unsigned char *buf = NULL; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - pkey = key->keydata.pkey; - eckey = EVP_PKEY_get0(pkey); - if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - privkey = EC_KEY_get0_private_key(eckey); - if (privkey == NULL) - return (ISC_R_FAILURE); - - buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); - if (buf == NULL) - return (ISC_R_NOMEMORY); - - priv.elements[0].tag = TAG_GOST_PRIVRAW; - priv.elements[0].length = BN_num_bytes(privkey); - BN_bn2bin(privkey, buf); - priv.elements[0].data = buf; - priv.nelements = 1; - - ret = dst__privstruct_writefile(key, &priv, directory); - - if (buf != NULL) - isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); - return (ret); -} -#endif - -static unsigned char gost_dummy_key[71] = { - 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, - 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, - 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, - 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, - 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b, - 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, - 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, - 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, - 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 -}; - -static isc_result_t -opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - isc_mem_t *mctx = key->mctx; - EVP_PKEY *pkey = NULL; - EC_KEY *eckey; - const EC_POINT *pubkey = NULL; - BIGNUM *privkey = NULL; - const unsigned char *p; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - - INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || - (priv.elements[0].tag == TAG_GOST_PRIVRAW)); - - if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { - p = priv.elements[0].data; - if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) priv.elements[0].length) == NULL) - DST_RET(dst__openssl_toresult2( - "d2i_PrivateKey", - DST_R_INVALIDPRIVATEKEY)); - } else { - if ((pub != NULL) && (pub->keydata.pkey != NULL)) { - eckey = EVP_PKEY_get0(pub->keydata.pkey); - pubkey = EC_KEY_get0_public_key(eckey); - } - - privkey = BN_bin2bn(priv.elements[0].data, - priv.elements[0].length, NULL); - if (privkey == NULL) - DST_RET(ISC_R_NOMEMORY); - - /* can't create directly the whole key */ - p = gost_dummy_key; - if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) sizeof(gost_dummy_key)) == NULL) - DST_RET(dst__openssl_toresult2( - "d2i_PrivateKey", - DST_R_INVALIDPRIVATEKEY)); - - eckey = EVP_PKEY_get0(pkey); - if (eckey == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - if (!EC_KEY_set_private_key(eckey, privkey)) - DST_RET(ISC_R_NOMEMORY); - - /* have to (re)set the public key */ -#ifdef notyet - (void) gost2001_compute_public(eckey); -#else - if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey)) - DST_RET(ISC_R_NOMEMORY); -#endif - BN_clear_free(privkey); - privkey = NULL; - } - key->keydata.pkey = pkey; - key->key_size = EVP_PKEY_bits(pkey); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - - err: - if (privkey != NULL) - BN_clear_free(privkey); - if (pkey != NULL) - EVP_PKEY_free(pkey); - opensslgost_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static void -opensslgost_cleanup(void) { - if (e != NULL) { - ENGINE_finish(e); - ENGINE_free(e); - e = NULL; - } -} - -static dst_func_t opensslgost_functions = { - opensslgost_createctx, - NULL, /*%< createctx2 */ - opensslgost_destroyctx, - opensslgost_adddata, - opensslgost_sign, - opensslgost_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - opensslgost_compare, - NULL, /*%< paramcompare */ - opensslgost_generate, - opensslgost_isprivate, - opensslgost_destroy, - opensslgost_todns, - opensslgost_fromdns, - opensslgost_tofile, - opensslgost_parse, - opensslgost_cleanup, - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL /*%< restore */ -}; - -isc_result_t -dst__opensslgost_init(dst_func_t **funcp) { - isc_result_t ret; - - REQUIRE(funcp != NULL); - - /* check if the gost engine works properly */ - e = ENGINE_by_id("gost"); - if (e == NULL) - return (dst__openssl_toresult2("ENGINE_by_id", - DST_R_OPENSSLFAILURE)); - if (ENGINE_init(e) <= 0) { - ENGINE_free(e); - e = NULL; - return (dst__openssl_toresult2("ENGINE_init", - DST_R_OPENSSLFAILURE)); - } - /* better than to rely on digest_gost symbol */ - opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94); - if (opensslgost_digest == NULL) - DST_RET(dst__openssl_toresult2("ENGINE_get_digest", - DST_R_OPENSSLFAILURE)); - /* from openssl.cnf */ - if (ENGINE_register_pkey_asn1_meths(e) <= 0) - DST_RET(dst__openssl_toresult2( - "ENGINE_register_pkey_asn1_meths", - DST_R_OPENSSLFAILURE)); - if (ENGINE_ctrl_cmd_string(e, - "CRYPT_PARAMS", - "id-Gost28147-89-CryptoPro-A-ParamSet", - 0) <= 0) - DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string", - DST_R_OPENSSLFAILURE)); - - if (*funcp == NULL) - *funcp = &opensslgost_functions; - return (ISC_R_SUCCESS); - - err: - ENGINE_finish(e); - ENGINE_free(e); - e = NULL; - return (ret); -} - -#else /* HAVE_OPENSSL_GOST */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* HAVE_OPENSSL_GOST */ -/*! \file */ diff --git a/lib/dns-pkcs11/opensslrsa_link.c b/lib/dns-pkcs11/opensslrsa_link.c deleted file mode 100644 index 6d80d25..0000000 --- a/lib/dns-pkcs11/opensslrsa_link.c +++ /dev/null @@ -1,1840 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifdef OPENSSL -#include - -#ifndef USE_EVP -#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512) -#define USE_EVP 0 -#else -#define USE_EVP 1 -#endif -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "dst_internal.h" -#include "dst_openssl.h" -#include "dst_parse.h" - -#include -#include -#include -#if OPENSSL_VERSION_NUMBER > 0x00908000L -#include -#endif -#if !defined(OPENSSL_NO_ENGINE) -#include -#endif - -/* - * Limit the size of public exponents. - */ -#ifndef RSA_MAX_PUBEXP_BITS -#define RSA_MAX_PUBEXP_BITS 35 -#endif - -/* - * We don't use configure for windows so enforce the OpenSSL version - * here. Unlike with configure we don't support overriding this test. - */ -#ifdef WIN32 -#if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \ - OPENSSL_VERSION_NUMBER < 0x00908000L) || \ - (OPENSSL_VERSION_NUMBER >= 0x0090804fL && \ - OPENSSL_VERSION_NUMBER < 0x10002000L) || \ - OPENSSL_VERSION_NUMBER >= 0x1000205fL) -#error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater. -#endif -#endif - - - /* - * XXXMPA Temporarily disable RSA_BLINDING as it requires - * good quality random data that cannot currently be guaranteed. - * XXXMPA Find which versions of openssl use pseudo random data - * and set RSA_FLAG_BLINDING for those. - */ - -#if 0 -#if OPENSSL_VERSION_NUMBER < 0x0090601fL -#define SET_FLAGS(rsa) \ - do { \ - (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \ - (rsa)->flags |= RSA_FLAG_BLINDING; \ - } while (0) -#else -#define SET_FLAGS(rsa) \ - do { \ - (rsa)->flags |= RSA_FLAG_BLINDING; \ - } while (0) -#endif -#endif - -#if OPENSSL_VERSION_NUMBER < 0x0090601fL -#define SET_FLAGS(rsa) \ - do { \ - (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \ - (rsa)->flags &= ~RSA_FLAG_BLINDING; \ - } while (0) -#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -#if defined(RSA_FLAG_NO_BLINDING) -#define SET_FLAGS(rsa) \ - do { \ - (rsa)->flags &= ~RSA_FLAG_BLINDING; \ - (rsa)->flags |= RSA_FLAG_NO_BLINDING; \ - } while (0) -#else -#define SET_FLAGS(rsa) \ - do { \ - (rsa)->flags &= ~RSA_FLAG_BLINDING; \ - } while (0) -#endif -#else -#define SET_FLAGS(rsa) \ - do { \ - RSA_clear_flags(rsa, RSA_FLAG_BLINDING); \ - RSA_set_flags(rsa, RSA_FLAG_NO_BLINDING); \ - } while (0) -#endif -#define DST_RET(a) {ret = a; goto err;} - -#if !defined(HAVE_RSA_SET0_KEY) -/* From OpenSSL 1.1.0 */ -static int -RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - - /* - * If the fields n and e in r are NULL, the corresponding input - * parameters MUST be non-NULL for n and e. d may be - * left NULL (in case only the public key is used). - */ - if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) { - return 0; - } - - if (n != NULL) { - BN_free(r->n); - r->n = n; - } - if (e != NULL) { - BN_free(r->e); - r->e = e; - } - if (d != NULL) { - BN_free(r->d); - r->d = d; - } - - return 1; -} - -static int -RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { - - /* - * If the fields p and q in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) { - return 0; - } - - if (p != NULL) { - BN_free(r->p); - r->p = p; - } - if (q != NULL) { - BN_free(r->q); - r->q = q; - } - - return 1; -} - -static int -RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { - /* - * If the fields dmp1, dmq1 and iqmp in r are NULL, the - * corresponding input parameters MUST be non-NULL. - */ - if ((r->dmp1 == NULL && dmp1 == NULL) || - (r->dmq1 == NULL && dmq1 == NULL) || - (r->iqmp == NULL && iqmp == NULL)) - { - return 0; - } - - if (dmp1 != NULL) { - BN_free(r->dmp1); - r->dmp1 = dmp1; - } - if (dmq1 != NULL) { - BN_free(r->dmq1); - r->dmq1 = dmq1; - } - if (iqmp != NULL) { - BN_free(r->iqmp); - r->iqmp = iqmp; - } - - return 1; -} - -static void -RSA_get0_key(const RSA *r, - const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) { - *n = r->n; - } - if (e != NULL) { - *e = r->e; - } - if (d != NULL) { - *d = r->d; - } -} - -static void -RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) { - if (p != NULL) { - *p = r->p; - } - if (q != NULL) { - *q = r->q; - } -} - -static void -RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, - const BIGNUM **iqmp) -{ - if (dmp1 != NULL) { - *dmp1 = r->dmp1; - } - if (dmq1 != NULL) { - *dmq1 = r->dmq1; - } - if (iqmp != NULL) { - *iqmp = r->iqmp; - } -} - -static int -RSA_test_flags(const RSA *r, int flags) { - return (r->flags & flags); -} - -#endif - -static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data); - -static isc_result_t -opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx; - const EVP_MD *type = NULL; -#endif - - UNUSED(key); -#ifndef PK11_MD5_DISABLE - REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || - dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#endif - - /* - * Reject incorrect RSA key lengths. - */ - switch (dctx->key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (dctx->key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((dctx->key->key_size < 512) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((dctx->key->key_size < 1024) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - -#if USE_EVP - evp_md_ctx = EVP_MD_CTX_create(); - if (evp_md_ctx == NULL) - return (ISC_R_NOMEMORY); - - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - type = EVP_md5(); /* MD5 + RSA */ - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - type = EVP_sha1(); /* SHA1 + RSA */ - break; -#ifdef HAVE_EVP_SHA256 - case DST_ALG_RSASHA256: - type = EVP_sha256(); /* SHA256 + RSA */ - break; -#endif -#ifdef HAVE_EVP_SHA512 - case DST_ALG_RSASHA512: - type = EVP_sha512(); - break; -#endif - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { - EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult3(dctx->category, - "EVP_DigestInit_ex", - ISC_R_FAILURE)); - } - dctx->ctxdata.evp_md_ctx = evp_md_ctx; -#else - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - { - isc_md5_t *md5ctx; - - md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); - if (md5ctx == NULL) - return (ISC_R_NOMEMORY); - isc_md5_init(md5ctx); - dctx->ctxdata.md5ctx = md5ctx; - } - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - { - isc_sha1_t *sha1ctx; - - sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); - if (sha1ctx == NULL) - return (ISC_R_NOMEMORY); - isc_sha1_init(sha1ctx); - dctx->ctxdata.sha1ctx = sha1ctx; - } - break; - case DST_ALG_RSASHA256: - { - isc_sha256_t *sha256ctx; - - sha256ctx = isc_mem_get(dctx->mctx, - sizeof(isc_sha256_t)); - if (sha256ctx == NULL) - return (ISC_R_NOMEMORY); - isc_sha256_init(sha256ctx); - dctx->ctxdata.sha256ctx = sha256ctx; - } - break; - case DST_ALG_RSASHA512: - { - isc_sha512_t *sha512ctx; - - sha512ctx = isc_mem_get(dctx->mctx, - sizeof(isc_sha512_t)); - if (sha512ctx == NULL) - return (ISC_R_NOMEMORY); - isc_sha512_init(sha512ctx); - dctx->ctxdata.sha512ctx = sha512ctx; - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -#endif - - return (ISC_R_SUCCESS); -} - -static void -opensslrsa_destroyctx(dst_context_t *dctx) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; -#endif - -#ifndef PK11_MD5_DISABLE - REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || - dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#endif - -#if USE_EVP - if (evp_md_ctx != NULL) { - EVP_MD_CTX_destroy(evp_md_ctx); - dctx->ctxdata.evp_md_ctx = NULL; - } -#else - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - - if (md5ctx != NULL) { - isc_md5_invalidate(md5ctx); - isc_mem_put(dctx->mctx, md5ctx, - sizeof(isc_md5_t)); - dctx->ctxdata.md5ctx = NULL; - } - } - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - if (sha1ctx != NULL) { - isc_sha1_invalidate(sha1ctx); - isc_mem_put(dctx->mctx, sha1ctx, - sizeof(isc_sha1_t)); - dctx->ctxdata.sha1ctx = NULL; - } - } - break; - case DST_ALG_RSASHA256: - { - isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; - - if (sha256ctx != NULL) { - isc_sha256_invalidate(sha256ctx); - isc_mem_put(dctx->mctx, sha256ctx, - sizeof(isc_sha256_t)); - dctx->ctxdata.sha256ctx = NULL; - } - } - break; - case DST_ALG_RSASHA512: - { - isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; - - if (sha512ctx != NULL) { - isc_sha512_invalidate(sha512ctx); - isc_mem_put(dctx->mctx, sha512ctx, - sizeof(isc_sha512_t)); - dctx->ctxdata.sha512ctx = NULL; - } - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -#endif -} - -static isc_result_t -opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; -#endif - -#ifndef PK11_MD5_DISABLE - REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || - dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#endif - -#if USE_EVP - if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (dst__openssl_toresult3(dctx->category, - "EVP_DigestUpdate", - ISC_R_FAILURE)); - } -#else - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - - isc_md5_update(md5ctx, data->base, data->length); - } - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - isc_sha1_update(sha1ctx, data->base, data->length); - } - break; - case DST_ALG_RSASHA256: - { - isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; - - isc_sha256_update(sha256ctx, data->base, data->length); - } - break; - case DST_ALG_RSASHA512: - { - isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; - - isc_sha512_update(sha512ctx, data->base, data->length); - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -#endif - return (ISC_R_SUCCESS); -} - -#if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L -/* - * Digest prefixes from RFC 5702. - */ -static unsigned char sha256_prefix[] = - { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; -static unsigned char sha512_prefix[] = - { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; -#define PREFIXLEN sizeof(sha512_prefix) -#else -#define PREFIXLEN 0 -#endif - -static isc_result_t -opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_key_t *key = dctx->key; - isc_region_t r; - unsigned int siglen = 0; -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; -#else - RSA *rsa = key->keydata.rsa; - /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ - unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH]; - int status; - int type = 0; - unsigned int digestlen = 0; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - unsigned int prefixlen = 0; - const unsigned char *prefix = NULL; -#endif -#endif - -#ifndef PK11_MD5_DISABLE - REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || - dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#endif - - isc_buffer_availableregion(sig, &r); - -#if USE_EVP - if (r.length < (unsigned int) EVP_PKEY_size(pkey)) - return (ISC_R_NOSPACE); - - if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { - return (dst__openssl_toresult3(dctx->category, - "EVP_SignFinal", - ISC_R_FAILURE)); - } -#else - if (r.length < (unsigned int) RSA_size(rsa)) - return (ISC_R_NOSPACE); - - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - - isc_md5_final(md5ctx, digest); - type = NID_md5; - digestlen = ISC_MD5_DIGESTLENGTH; - } - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - isc_sha1_final(sha1ctx, digest); - type = NID_sha1; - digestlen = ISC_SHA1_DIGESTLENGTH; - } - break; - case DST_ALG_RSASHA256: - { - isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; - - isc_sha256_final(digest, sha256ctx); - digestlen = ISC_SHA256_DIGESTLENGTH; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - prefix = sha256_prefix; - prefixlen = sizeof(sha256_prefix); -#else - type = NID_sha256; -#endif - } - break; - case DST_ALG_RSASHA512: - { - isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; - - isc_sha512_final(digest, sha512ctx); - digestlen = ISC_SHA512_DIGESTLENGTH; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - prefix = sha512_prefix; - prefixlen = sizeof(sha512_prefix); -#else - type = NID_sha512; -#endif - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - -#if OPENSSL_VERSION_NUMBER < 0x00908000L - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - INSIST(type != 0); - status = RSA_sign(type, digest, digestlen, r.base, - &siglen, rsa); - break; - - case DST_ALG_RSASHA256: - case DST_ALG_RSASHA512: - INSIST(prefix != NULL); - INSIST(prefixlen != 0); - INSIST(prefixlen + digestlen <= sizeof(digest)); - - memmove(digest + prefixlen, digest, digestlen); - memmove(digest, prefix, prefixlen); - status = RSA_private_encrypt(digestlen + prefixlen, - digest, r.base, rsa, - RSA_PKCS1_PADDING); - if (status < 0) - status = 0; - else - siglen = status; - break; - - default: - INSIST(0); - ISC_UNREACHABLE(); - } -#else - INSIST(type != 0); - status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); -#endif - if (status == 0) - return (dst__openssl_toresult3(dctx->category, - "RSA_sign", - DST_R_OPENSSLFAILURE)); -#endif - - isc_buffer_add(sig, siglen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) { - dst_key_t *key = dctx->key; - int status = 0; - const BIGNUM *e = NULL; -#if USE_EVP - EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; - EVP_PKEY *pkey = key->keydata.pkey; - RSA *rsa; - int bits; -#else - /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ - unsigned char digest[ISC_SHA512_DIGESTLENGTH]; - int type = 0; - unsigned int digestlen = 0; - RSA *rsa = key->keydata.rsa; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - unsigned int prefixlen = 0; - const unsigned char *prefix = NULL; -#endif -#endif - -#ifndef PK11_MD5_DISABLE - REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || - dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 || - dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || - dctx->key->key_alg == DST_ALG_RSASHA256 || - dctx->key->key_alg == DST_ALG_RSASHA512); -#endif - -#if USE_EVP - rsa = EVP_PKEY_get1_RSA(pkey); - if (rsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - RSA_get0_key(rsa, NULL, &e, NULL); - bits = BN_num_bits(e); - RSA_free(rsa); - if (bits > maxbits && maxbits != 0) - return (DST_R_VERIFYFAILURE); - - status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); - switch (status) { - case 1: - return (ISC_R_SUCCESS); - case 0: - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - default: - return (dst__openssl_toresult3(dctx->category, - "EVP_VerifyFinal", - DST_R_VERIFYFAILURE)); - } -#else - RSA_get0_key(rsa, NULL, &e, NULL); - if (BN_num_bits(e) > maxbits && maxbits != 0) - return (DST_R_VERIFYFAILURE); - - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - { - isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; - - isc_md5_final(md5ctx, digest); - type = NID_md5; - digestlen = ISC_MD5_DIGESTLENGTH; - } - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - { - isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; - - isc_sha1_final(sha1ctx, digest); - type = NID_sha1; - digestlen = ISC_SHA1_DIGESTLENGTH; - } - break; - case DST_ALG_RSASHA256: - { - isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; - - isc_sha256_final(digest, sha256ctx); - digestlen = ISC_SHA256_DIGESTLENGTH; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - prefix = sha256_prefix; - prefixlen = sizeof(sha256_prefix); -#else - type = NID_sha256; -#endif - } - break; - case DST_ALG_RSASHA512: - { - isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; - - isc_sha512_final(digest, sha512ctx); - digestlen = ISC_SHA512_DIGESTLENGTH; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - prefix = sha512_prefix; - prefixlen = sizeof(sha512_prefix); -#else - type = NID_sha512; -#endif - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (sig->length != (unsigned int) RSA_size(rsa)) - return (DST_R_VERIFYFAILURE); - -#if OPENSSL_VERSION_NUMBER < 0x00908000L - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - INSIST(type != 0); - status = RSA_verify(type, digest, digestlen, sig->base, - RSA_size(rsa), rsa); - break; - - case DST_ALG_RSASHA256: - case DST_ALG_RSASHA512: - { - /* - * 1024 is big enough for all valid RSA bit sizes - * for use with DNSSEC. - */ - unsigned char original[PREFIXLEN + 1024]; - - INSIST(prefix != NULL); - INSIST(prefixlen != 0U); - - if (RSA_size(rsa) > (int)sizeof(original)) - return (DST_R_VERIFYFAILURE); - - status = RSA_public_decrypt(sig->length, sig->base, - original, rsa, - RSA_PKCS1_PADDING); - if (status <= 0) - return (dst__openssl_toresult3( - dctx->category, - "RSA_public_decrypt", - DST_R_VERIFYFAILURE)); - if (status != (int)(prefixlen + digestlen)) - return (DST_R_VERIFYFAILURE); - if (!isc_safe_memequal(original, prefix, prefixlen)) - return (DST_R_VERIFYFAILURE); - if (!isc_safe_memequal(original + prefixlen, - digest, digestlen)) - return (DST_R_VERIFYFAILURE); - status = 1; - } - break; - - default: - INSIST(0); - ISC_UNREACHABLE(); - } -#else - INSIST(type != 0); - status = RSA_verify(type, digest, digestlen, sig->base, - RSA_size(rsa), rsa); -#endif - if (status != 1) - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - return (ISC_R_SUCCESS); -#endif -} - -static isc_result_t -opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - return (opensslrsa_verify2(dctx, 0, sig)); -} - -static bool -opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - int status; - RSA *rsa1 = NULL, *rsa2 = NULL; - const BIGNUM *n1 = NULL, *n2 = NULL; - const BIGNUM *e1 = NULL, *e2 = NULL; - const BIGNUM *d1 = NULL, *d2 = NULL; - const BIGNUM *p1 = NULL, *p2 = NULL; - const BIGNUM *q1 = NULL, *q2 = NULL; -#if USE_EVP - EVP_PKEY *pkey1, *pkey2; -#endif - -#if USE_EVP - pkey1 = key1->keydata.pkey; - pkey2 = key2->keydata.pkey; - /* - * The pkey reference will keep these around after - * the RSA_free() call. - */ - if (pkey1 != NULL) { - rsa1 = EVP_PKEY_get1_RSA(pkey1); - RSA_free(rsa1); - } - if (pkey2 != NULL) { - rsa2 = EVP_PKEY_get1_RSA(pkey2); - RSA_free(rsa2); - } -#else - rsa1 = key1->keydata.rsa; - rsa2 = key2->keydata.rsa; -#endif - - if (rsa1 == NULL && rsa2 == NULL) - return (true); - else if (rsa1 == NULL || rsa2 == NULL) - return (false); - - RSA_get0_key(rsa1, &n1, &e1, &d1); - RSA_get0_key(rsa2, &n2, &e2, &d2); - status = BN_cmp(n1, n2) || BN_cmp(e1, e2); - - if (status != 0) - return (false); - -#if USE_EVP - if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) != 0 || - RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) != 0) { - if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) == 0 || - RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) == 0) - return (false); - /* - * Can't compare private parameters, BTW does it make sense? - */ - return (true); - } -#endif - - if (d1 != NULL || d2 != NULL) { - if (d1 == NULL || d2 == NULL) - return (false); - RSA_get0_factors(rsa1, &p1, &q1); - RSA_get0_factors(rsa2, &p2, &q2); - status = BN_cmp(d1, d2) || BN_cmp(p1, p1) || BN_cmp(q1, q2); - - if (status != 0) - return (false); - } - return (true); -} - -#if OPENSSL_VERSION_NUMBER > 0x00908000L -static int -progress_cb(int p, int n, BN_GENCB *cb) { - union { - void *dptr; - void (*fptr)(int); - } u; - - UNUSED(n); - - u.dptr = BN_GENCB_get_arg(cb); - if (u.fptr != NULL) - u.fptr(p); - return (1); -} -#endif - -static isc_result_t -opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { -#if OPENSSL_VERSION_NUMBER > 0x00908000L - isc_result_t ret = DST_R_OPENSSLFAILURE; - union { - void *dptr; - void (*fptr)(int); - } u; - RSA *rsa = RSA_new(); - BIGNUM *e = BN_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - BN_GENCB _cb; -#endif - BN_GENCB *cb = BN_GENCB_new(); -#if USE_EVP - EVP_PKEY *pkey = EVP_PKEY_new(); -#endif - - /* - * Reject incorrect RSA key lengths. - */ - switch (key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (key->key_size > 4096) - goto err; - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((key->key_size < 512) || - (key->key_size > 4096)) - goto err; - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((key->key_size < 1024) || - (key->key_size > 4096)) - goto err; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (rsa == NULL || e == NULL || cb == NULL) - goto err; -#if USE_EVP - if (pkey == NULL) - goto err; - if (!EVP_PKEY_set1_RSA(pkey, rsa)) - goto err; -#endif - - if (exp == 0) { - /* RSA_F4 0x10001 */ - BN_set_bit(e, 0); - BN_set_bit(e, 16); - } else { - /* (phased-out) F5 0x100000001 */ - BN_set_bit(e, 0); - BN_set_bit(e, 32); - } - - if (callback == NULL) { - BN_GENCB_set_old(cb, NULL, NULL); - } else { - u.fptr = callback; - BN_GENCB_set(cb, &progress_cb, u.dptr); - } - - if (RSA_generate_key_ex(rsa, key->key_size, e, cb)) { - BN_free(e); - BN_GENCB_free(cb); - cb = NULL; - SET_FLAGS(rsa); -#if USE_EVP - key->keydata.pkey = pkey; - - RSA_free(rsa); -#else - key->keydata.rsa = rsa; -#endif - return (ISC_R_SUCCESS); - } - ret = dst__openssl_toresult2("RSA_generate_key_ex", - DST_R_OPENSSLFAILURE); - - err: -#if USE_EVP - if (pkey != NULL) { - EVP_PKEY_free(pkey); - pkey = NULL; - } -#endif - if (e != NULL) { - BN_free(e); - e = NULL; - } - if (rsa != NULL) { - RSA_free(rsa); - rsa = NULL; - } - if (cb != NULL) { - BN_GENCB_free(cb); - cb = NULL; - } - return (dst__openssl_toresult(ret)); -#else - RSA *rsa; - unsigned long e; -#if USE_EVP - EVP_PKEY *pkey = EVP_PKEY_new(); - - UNUSED(callback); - - if (pkey == NULL) - return (ISC_R_NOMEMORY); -#else - UNUSED(callback); -#endif - - if (exp == 0) - e = RSA_F4; - else - e = 0x40000003; - rsa = RSA_generate_key(key->key_size, e, NULL, NULL); - if (rsa == NULL) { -#if USE_EVP - EVP_PKEY_free(pkey); -#endif - return (dst__openssl_toresult2("RSA_generate_key", - DST_R_OPENSSLFAILURE)); - } - SET_FLAGS(rsa); -#if USE_EVP - if (!EVP_PKEY_set1_RSA(pkey, rsa)) { - EVP_PKEY_free(pkey); - RSA_free(rsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } - key->keydata.pkey = pkey; - RSA_free(rsa); -#else - key->keydata.rsa = rsa; -#endif - - return (ISC_R_SUCCESS); -#endif -} - -static bool -opensslrsa_isprivate(const dst_key_t *key) { - const BIGNUM *d = NULL; -#if USE_EVP - RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); - INSIST(rsa != NULL); - RSA_free(rsa); - /* key->keydata.pkey still has a reference so rsa is still valid. */ -#else - RSA *rsa = key->keydata.rsa; -#endif - if (rsa != NULL && RSA_test_flags(rsa, RSA_FLAG_EXT_PKEY) != 0) - return (true); - RSA_get0_key(rsa, NULL, NULL, &d); - return (rsa != NULL && d != NULL); -} - -static void -opensslrsa_destroy(dst_key_t *key) { -#if USE_EVP - EVP_PKEY *pkey = key->keydata.pkey; - EVP_PKEY_free(pkey); - key->keydata.pkey = NULL; -#else - RSA *rsa = key->keydata.rsa; - RSA_free(rsa); - key->keydata.rsa = NULL; -#endif -} - -static isc_result_t -opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) { - isc_region_t r; - unsigned int e_bytes; - unsigned int mod_bytes; - isc_result_t ret; - RSA *rsa; -#if USE_EVP - EVP_PKEY *pkey; -#endif - const BIGNUM *e = NULL, *n = NULL; - -#if USE_EVP - REQUIRE(key->keydata.pkey != NULL); -#else - REQUIRE(key->keydata.rsa != NULL); -#endif - -#if USE_EVP - pkey = key->keydata.pkey; - rsa = EVP_PKEY_get1_RSA(pkey); - if (rsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); -#else - rsa = key->keydata.rsa; -#endif - - isc_buffer_availableregion(data, &r); - - RSA_get0_key(rsa, &n, &e, NULL); - mod_bytes = BN_num_bytes(n); - e_bytes = BN_num_bytes(e); - - if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ - if (r.length < 1) - DST_RET(ISC_R_NOSPACE); - isc_buffer_putuint8(data, (uint8_t) e_bytes); - isc_region_consume(&r, 1); - } else { - if (r.length < 3) - DST_RET(ISC_R_NOSPACE); - isc_buffer_putuint8(data, 0); - isc_buffer_putuint16(data, (uint16_t) e_bytes); - isc_region_consume(&r, 3); - } - - if (r.length < e_bytes + mod_bytes) - DST_RET(ISC_R_NOSPACE); - - RSA_get0_key(rsa, &n, &e, NULL); - BN_bn2bin(e, r.base); - isc_region_consume(&r, e_bytes); - BN_bn2bin(n, r.base); - - isc_buffer_add(data, e_bytes + mod_bytes); - - ret = ISC_R_SUCCESS; - err: -#if USE_EVP - if (rsa != NULL) - RSA_free(rsa); -#endif - return (ret); -} - -static isc_result_t -opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - RSA *rsa; - isc_region_t r; - unsigned int e_bytes; - unsigned int length; -#if USE_EVP - EVP_PKEY *pkey; -#endif - BIGNUM *e = NULL, *n = NULL; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - length = r.length; - - rsa = RSA_new(); - if (rsa == NULL) - return (dst__openssl_toresult(ISC_R_NOMEMORY)); - SET_FLAGS(rsa); - - if (r.length < 1) { - RSA_free(rsa); - return (DST_R_INVALIDPUBLICKEY); - } - e_bytes = *r.base; - isc_region_consume(&r, 1); - - if (e_bytes == 0) { - if (r.length < 2) { - RSA_free(rsa); - return (DST_R_INVALIDPUBLICKEY); - } - e_bytes = (*r.base) << 8; - isc_region_consume(&r, 1); - e_bytes += *r.base; - isc_region_consume(&r, 1); - } - - if (r.length < e_bytes) { - RSA_free(rsa); - return (DST_R_INVALIDPUBLICKEY); - } - e = BN_bin2bn(r.base, e_bytes, NULL); - isc_region_consume(&r, e_bytes); - n = BN_bin2bn(r.base, r.length, NULL); - if (RSA_set0_key(rsa, n, e, NULL) == 0) { - if (n != NULL) BN_free(n); - if (e != NULL) BN_free(e); - RSA_free(rsa); - return (ISC_R_NOMEMORY); - } - key->key_size = BN_num_bits(n); - - isc_buffer_forward(data, length); - -#if USE_EVP - pkey = EVP_PKEY_new(); - if (pkey == NULL) { - RSA_free(rsa); - return (ISC_R_NOMEMORY); - } - if (!EVP_PKEY_set1_RSA(pkey, rsa)) { - EVP_PKEY_free(pkey); - RSA_free(rsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } - key->keydata.pkey = pkey; - RSA_free(rsa); -#else - key->keydata.rsa = rsa; -#endif - - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslrsa_tofile(const dst_key_t *key, const char *directory) { - int i; - RSA *rsa; - dst_private_t priv; - unsigned char *bufs[8]; - isc_result_t result; - const BIGNUM *n = NULL, *e = NULL, *d = NULL; - const BIGNUM *p = NULL, *q = NULL; - const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; - -#if USE_EVP - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); - if (rsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); -#else - if (key->keydata.rsa == NULL) - return (DST_R_NULLKEY); - rsa = key->keydata.rsa; -#endif - memset(bufs, 0, sizeof(bufs)); - - RSA_get0_key(rsa, &n, &e, &d); - RSA_get0_factors(rsa, &p, &q); - RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - - if (key->external) { - priv.nelements = 0; - result = dst__privstruct_writefile(key, &priv, directory); - goto fail; - } - - for (i = 0; i < 8; i++) { - bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(n)); - if (bufs[i] == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - } - - i = 0; - - priv.elements[i].tag = TAG_RSA_MODULUS; - priv.elements[i].length = BN_num_bytes(n); - BN_bn2bin(n, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; - priv.elements[i].length = BN_num_bytes(e); - BN_bn2bin(e, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - - if (d != NULL) { - priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; - priv.elements[i].length = BN_num_bytes(d); - BN_bn2bin(d, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (p != NULL) { - priv.elements[i].tag = TAG_RSA_PRIME1; - priv.elements[i].length = BN_num_bytes(p); - BN_bn2bin(p, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (q != NULL) { - priv.elements[i].tag = TAG_RSA_PRIME2; - priv.elements[i].length = BN_num_bytes(q); - BN_bn2bin(q, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (dmp1 != NULL) { - priv.elements[i].tag = TAG_RSA_EXPONENT1; - priv.elements[i].length = BN_num_bytes(dmp1); - BN_bn2bin(dmp1, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (dmq1 != NULL) { - priv.elements[i].tag = TAG_RSA_EXPONENT2; - priv.elements[i].length = BN_num_bytes(dmq1); - BN_bn2bin(dmq1, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (iqmp != NULL) { - priv.elements[i].tag = TAG_RSA_COEFFICIENT; - priv.elements[i].length = BN_num_bytes(iqmp); - BN_bn2bin(iqmp, bufs[i]); - priv.elements[i].data = bufs[i]; - i++; - } - - if (key->engine != NULL) { - priv.elements[i].tag = TAG_RSA_ENGINE; - priv.elements[i].length = - (unsigned short)strlen(key->engine) + 1; - priv.elements[i].data = (unsigned char *)key->engine; - i++; - } - - if (key->label != NULL) { - priv.elements[i].tag = TAG_RSA_LABEL; - priv.elements[i].length = - (unsigned short)strlen(key->label) + 1; - priv.elements[i].data = (unsigned char *)key->label; - i++; - } - - - priv.nelements = i; - result = dst__privstruct_writefile(key, &priv, directory); - fail: -#if USE_EVP - RSA_free(rsa); -#endif - for (i = 0; i < 8; i++) { - if (bufs[i] == NULL) - break; - isc_mem_put(key->mctx, bufs[i], BN_num_bytes(n)); - } - return (result); -} - -static isc_result_t -rsa_check(RSA *rsa, RSA *pub) { - const BIGNUM *n1 = NULL, *n2 = NULL; - const BIGNUM *e1 = NULL, *e2 = NULL; - BIGNUM *n = NULL, *e = NULL; - - /* - * Public parameters should be the same but if they are not set - * copy them from the public key. - */ - RSA_get0_key(rsa, &n1, &e1, NULL); - if (pub != NULL) { - RSA_get0_key(pub, &n2, &e2, NULL); - if (n1 != NULL) { - if (BN_cmp(n1, n2) != 0) - return (DST_R_INVALIDPRIVATEKEY); - } else { - n = BN_dup(n2); - } - if (e1 != NULL) { - if (BN_cmp(e1, e2) != 0) - return (DST_R_INVALIDPRIVATEKEY); - } else { - e = BN_dup(e2); - } - if (RSA_set0_key(rsa, n, e, NULL) == 0) { - if (n != NULL) - BN_free(n); - if (e != NULL) - BN_free(e); - } - } - RSA_get0_key(rsa, &n1, &e1, NULL); - if (n1 == NULL || e1 == NULL) - return (DST_R_INVALIDPRIVATEKEY); - return (ISC_R_SUCCESS); -} - -static isc_result_t -opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - RSA *rsa = NULL, *pubrsa = NULL; -#if !defined(OPENSSL_NO_ENGINE) - ENGINE *ep = NULL; - const BIGNUM *ex = NULL; -#endif - isc_mem_t *mctx = key->mctx; - const char *engine = NULL, *label = NULL; -#if !defined(OPENSSL_NO_ENGINE) || USE_EVP - EVP_PKEY *pkey = NULL; -#endif - BIGNUM *n = NULL, *e = NULL, *d = NULL; - BIGNUM *p = NULL, *q = NULL; - BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - goto err; - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); - } - -#if USE_EVP - if (pub != NULL && pub->keydata.pkey != NULL) - pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); -#else - if (pub != NULL && pub->keydata.rsa != NULL) { - pubrsa = pub->keydata.rsa; - pub->keydata.rsa = NULL; - } -#endif - - for (i = 0; i < priv.nelements; i++) { - switch (priv.elements[i].tag) { - case TAG_RSA_ENGINE: - engine = (char *)priv.elements[i].data; - break; - case TAG_RSA_LABEL: - label = (char *)priv.elements[i].data; - break; - default: - break; - } - } - - /* - * Is this key is stored in a HSM? - * See if we can fetch it. - */ - if (label != NULL) { -#if !defined(OPENSSL_NO_ENGINE) - if (engine == NULL) - DST_RET(DST_R_NOENGINE); - ep = dst__openssl_getengine(engine); - if (ep == NULL) - DST_RET(DST_R_NOENGINE); - pkey = ENGINE_load_private_key(ep, label, NULL, NULL); - if (pkey == NULL) - DST_RET(dst__openssl_toresult2( - "ENGINE_load_private_key", - ISC_R_NOTFOUND)); - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - rsa = EVP_PKEY_get1_RSA(pkey); - if (rsa == NULL) - DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) - DST_RET(DST_R_INVALIDPRIVATEKEY); - RSA_get0_key(rsa, NULL, &ex, NULL); - if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) - DST_RET(ISC_R_RANGE); - if (pubrsa != NULL) - RSA_free(pubrsa); - key->key_size = EVP_PKEY_bits(pkey); -#if USE_EVP - key->keydata.pkey = pkey; - RSA_free(rsa); -#else - key->keydata.rsa = rsa; - EVP_PKEY_free(pkey); -#endif - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ISC_R_SUCCESS); -#else - DST_RET(DST_R_NOENGINE); -#endif - } - - rsa = RSA_new(); - if (rsa == NULL) - DST_RET(ISC_R_NOMEMORY); - SET_FLAGS(rsa); - -#if USE_EVP - pkey = EVP_PKEY_new(); - if (pkey == NULL) - DST_RET(ISC_R_NOMEMORY); - if (!EVP_PKEY_set1_RSA(pkey, rsa)) - DST_RET(ISC_R_FAILURE); - key->keydata.pkey = pkey; -#else - key->keydata.rsa = rsa; -#endif - - for (i = 0; i < priv.nelements; i++) { - BIGNUM *bn; - switch (priv.elements[i].tag) { - case TAG_RSA_ENGINE: - continue; - case TAG_RSA_LABEL: - continue; - default: - bn = BN_bin2bn(priv.elements[i].data, - priv.elements[i].length, NULL); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - switch (priv.elements[i].tag) { - case TAG_RSA_MODULUS: - n = bn; - break; - case TAG_RSA_PUBLICEXPONENT: - e = bn; - break; - case TAG_RSA_PRIVATEEXPONENT: - d = bn; - break; - case TAG_RSA_PRIME1: - p = bn; - break; - case TAG_RSA_PRIME2: - q = bn; - break; - case TAG_RSA_EXPONENT1: - dmp1 = bn; - break; - case TAG_RSA_EXPONENT2: - dmq1 = bn; - break; - case TAG_RSA_COEFFICIENT: - iqmp = bn; - break; - } - } - } - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - if (RSA_set0_key(rsa, n, e, d) == 0) { - if (n != NULL) BN_free(n); - if (e != NULL) BN_free(e); - if (d != NULL) BN_free(d); - } - if (RSA_set0_factors(rsa, p, q) == 0) { - if (p != NULL) BN_free(p); - if (q != NULL) BN_free(q); - } - if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0) { - if (dmp1 != NULL) BN_free(dmp1); - if (dmq1 != NULL) BN_free(dmq1); - if (iqmp != NULL) BN_free(iqmp); - } - - if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS) - DST_RET(ISC_R_RANGE); - key->key_size = BN_num_bits(n); - if (pubrsa != NULL) - RSA_free(pubrsa); -#if USE_EVP - RSA_free(rsa); -#endif - - return (ISC_R_SUCCESS); - - err: -#if USE_EVP - if (pkey != NULL) - EVP_PKEY_free(pkey); -#endif - if (rsa != NULL) - RSA_free(rsa); - if (pubrsa != NULL) - RSA_free(pubrsa); - key->keydata.generic = NULL; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static isc_result_t -opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, - const char *pin) -{ -#if !defined(OPENSSL_NO_ENGINE) - ENGINE *e = NULL; - isc_result_t ret; - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL, *pubrsa = NULL; - const BIGNUM *ex = NULL; - - UNUSED(pin); - - if (engine == NULL) { - DST_RET(DST_R_NOENGINE); - } - e = dst__openssl_getengine(engine); - if (e == NULL) { - DST_RET(DST_R_NOENGINE); - } - pkey = ENGINE_load_public_key(e, label, NULL, NULL); - if (pkey != NULL) { - pubrsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - if (pubrsa == NULL) { - DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } - } - pkey = ENGINE_load_private_key(e, label, NULL, NULL); - if (pkey == NULL) { - DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", - ISC_R_NOTFOUND)); - } - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) { - DST_RET(ISC_R_NOMEMORY); - } - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) { - DST_RET(ISC_R_NOMEMORY); - } - rsa = EVP_PKEY_get1_RSA(pkey); - if (rsa == NULL) { - DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } - if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) { - DST_RET(DST_R_INVALIDPRIVATEKEY); - } - RSA_get0_key(rsa, NULL, &ex, NULL); - if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) { - DST_RET(ISC_R_RANGE); - } - if (pubrsa != NULL) { - RSA_free(pubrsa); - } - key->key_size = EVP_PKEY_bits(pkey); -#if USE_EVP - key->keydata.pkey = pkey; - RSA_free(rsa); -#else - key->keydata.rsa = rsa; - EVP_PKEY_free(pkey); -#endif - return (ISC_R_SUCCESS); - - err: - if (rsa != NULL) - RSA_free(rsa); - if (pubrsa != NULL) - RSA_free(pubrsa); - if (pkey != NULL) - EVP_PKEY_free(pkey); - return (ret); -#else - UNUSED(key); - UNUSED(engine); - UNUSED(label); - UNUSED(pin); - return(DST_R_NOENGINE); -#endif -} - -static dst_func_t opensslrsa_functions = { - opensslrsa_createctx, - NULL, /*%< createctx2 */ - opensslrsa_destroyctx, - opensslrsa_adddata, - opensslrsa_sign, - opensslrsa_verify, - opensslrsa_verify2, - NULL, /*%< computesecret */ - opensslrsa_compare, - NULL, /*%< paramcompare */ - opensslrsa_generate, - opensslrsa_isprivate, - opensslrsa_destroy, - opensslrsa_todns, - opensslrsa_fromdns, - opensslrsa_tofile, - opensslrsa_parse, - NULL, /*%< cleanup */ - opensslrsa_fromlabel, - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) { - REQUIRE(funcp != NULL); - - if (*funcp == NULL) { - switch (algorithm) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (isc_md5_available()) - *funcp = &opensslrsa_functions; - break; -#endif - case DST_ALG_RSASHA256: -#if defined(HAVE_EVP_SHA256) || !USE_EVP - *funcp = &opensslrsa_functions; -#endif - break; - case DST_ALG_RSASHA512: -#if defined(HAVE_EVP_SHA512) || !USE_EVP - *funcp = &opensslrsa_functions; -#endif - break; - default: - *funcp = &opensslrsa_functions; - break; - } - } - return (ISC_R_SUCCESS); -} - -#else /* OPENSSL */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* OPENSSL */ -/*! \file */ diff --git a/lib/dns-pkcs11/order.c b/lib/dns-pkcs11/order.c deleted file mode 100644 index 1d7a37e..0000000 --- a/lib/dns-pkcs11/order.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -typedef struct dns_order_ent dns_order_ent_t; -struct dns_order_ent { - dns_fixedname_t name; - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - unsigned int mode; - ISC_LINK(dns_order_ent_t) link; -}; - -struct dns_order { - unsigned int magic; - isc_refcount_t references; - ISC_LIST(dns_order_ent_t) ents; - isc_mem_t *mctx; -}; - -#define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r') -#define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC) - -isc_result_t -dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { - dns_order_t *order; - isc_result_t result; - - REQUIRE(orderp != NULL && *orderp == NULL); - - order = isc_mem_get(mctx, sizeof(*order)); - if (order == NULL) - return (ISC_R_NOMEMORY); - - ISC_LIST_INIT(order->ents); - - /* Implicit attach. */ - result = isc_refcount_init(&order->references, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, order, sizeof(*order)); - return (result); - } - - order->mctx = NULL; - isc_mem_attach(mctx, &order->mctx); - order->magic = DNS_ORDER_MAGIC; - *orderp = order; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_order_add(dns_order_t *order, dns_name_t *name, - dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, - unsigned int mode) -{ - dns_order_ent_t *ent; - - REQUIRE(DNS_ORDER_VALID(order)); - REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE || - mode == DNS_RDATASETATTR_FIXEDORDER || - mode == 0 /* DNS_RDATASETATTR_CYCLIC */ ); - - ent = isc_mem_get(order->mctx, sizeof(*ent)); - if (ent == NULL) - return (ISC_R_NOMEMORY); - - dns_fixedname_init(&ent->name); - RUNTIME_CHECK(dns_name_copy(name, dns_fixedname_name(&ent->name), NULL) - == ISC_R_SUCCESS); - ent->rdtype = rdtype; - ent->rdclass = rdclass; - ent->mode = mode; - ISC_LINK_INIT(ent, link); - ISC_LIST_INITANDAPPEND(order->ents, ent, link); - return (ISC_R_SUCCESS); -} - -static inline bool -match(dns_name_t *name1, dns_name_t *name2) { - - if (dns_name_iswildcard(name2)) - return(dns_name_matcheswildcard(name1, name2)); - return (dns_name_equal(name1, name2)); -} - -unsigned int -dns_order_find(dns_order_t *order, dns_name_t *name, - dns_rdatatype_t rdtype, dns_rdataclass_t rdclass) -{ - dns_order_ent_t *ent; - REQUIRE(DNS_ORDER_VALID(order)); - - for (ent = ISC_LIST_HEAD(order->ents); - ent != NULL; - ent = ISC_LIST_NEXT(ent, link)) { - if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any) - continue; - if (ent->rdclass != rdclass && - ent->rdclass != dns_rdataclass_any) - continue; - if (match(name, dns_fixedname_name(&ent->name))) - return (ent->mode); - } - return (DNS_RDATASETATTR_RANDOMIZE); -} - -void -dns_order_attach(dns_order_t *source, dns_order_t **target) { - REQUIRE(DNS_ORDER_VALID(source)); - REQUIRE(target != NULL && *target == NULL); - isc_refcount_increment(&source->references, NULL); - *target = source; -} - -void -dns_order_detach(dns_order_t **orderp) { - dns_order_t *order; - dns_order_ent_t *ent; - unsigned int references; - - REQUIRE(orderp != NULL); - order = *orderp; - REQUIRE(DNS_ORDER_VALID(order)); - isc_refcount_decrement(&order->references, &references); - *orderp = NULL; - if (references != 0) - return; - - order->magic = 0; - while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) { - ISC_LIST_UNLINK(order->ents, ent, link); - isc_mem_put(order->mctx, ent, sizeof(*ent)); - } - isc_refcount_destroy(&order->references); - isc_mem_putanddetach(&order->mctx, order, sizeof(*order)); -} diff --git a/lib/dns-pkcs11/peer.c b/lib/dns-pkcs11/peer.c deleted file mode 100644 index 0867feb..0000000 --- a/lib/dns-pkcs11/peer.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -/*% - * Bit positions in the dns_peer_t structure flags field - */ -#define BOGUS_BIT 0 -#define SERVER_TRANSFER_FORMAT_BIT 1 -#define TRANSFERS_BIT 2 -#define PROVIDE_IXFR_BIT 3 -#define REQUEST_IXFR_BIT 4 -#define SUPPORT_EDNS_BIT 5 -#define SERVER_UDPSIZE_BIT 6 -#define SERVER_MAXUDP_BIT 7 -#define REQUEST_NSID_BIT 8 -#define SEND_COOKIE_BIT 9 -#define NOTIFY_DSCP_BIT 10 -#define TRANSFER_DSCP_BIT 11 -#define QUERY_DSCP_BIT 12 -#define REQUEST_EXPIRE_BIT 13 -#define EDNS_VERSION_BIT 14 -#define FORCE_TCP_BIT 15 - -static void -peerlist_delete(dns_peerlist_t **list); - -static void -peer_delete(dns_peer_t **peer); - -isc_result_t -dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { - dns_peerlist_t *l; - - REQUIRE(list != NULL); - - l = isc_mem_get(mem, sizeof(*l)); - if (l == NULL) - return (ISC_R_NOMEMORY); - - ISC_LIST_INIT(l->elements); - l->mem = mem; - l->refs = 1; - l->magic = DNS_PEERLIST_MAGIC; - - *list = l; - - return (ISC_R_SUCCESS); -} - -void -dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { - REQUIRE(DNS_PEERLIST_VALID(source)); - REQUIRE(target != NULL); - REQUIRE(*target == NULL); - - source->refs++; - - ENSURE(source->refs != 0xffffffffU); - - *target = source; -} - -void -dns_peerlist_detach(dns_peerlist_t **list) { - dns_peerlist_t *plist; - - REQUIRE(list != NULL); - REQUIRE(*list != NULL); - REQUIRE(DNS_PEERLIST_VALID(*list)); - - plist = *list; - *list = NULL; - - REQUIRE(plist->refs > 0); - - plist->refs--; - - if (plist->refs == 0) - peerlist_delete(&plist); -} - -static void -peerlist_delete(dns_peerlist_t **list) { - dns_peerlist_t *l; - dns_peer_t *server, *stmp; - - REQUIRE(list != NULL); - REQUIRE(DNS_PEERLIST_VALID(*list)); - - l = *list; - - REQUIRE(l->refs == 0); - - server = ISC_LIST_HEAD(l->elements); - while (server != NULL) { - stmp = ISC_LIST_NEXT(server, next); - ISC_LIST_UNLINK(l->elements, server, next); - dns_peer_detach(&server); - server = stmp; - } - - l->magic = 0; - isc_mem_put(l->mem, l, sizeof(*l)); - - *list = NULL; -} - -void -dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { - dns_peer_t *p = NULL; - - dns_peer_attach(peer, &p); - - /* - * More specifics to front of list. - */ - for (p = ISC_LIST_HEAD(peers->elements); - p != NULL; - p = ISC_LIST_NEXT(p, next)) - if (p->prefixlen < peer->prefixlen) - break; - - if (p != NULL) - ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); - else - ISC_LIST_APPEND(peers->elements, peer, next); - -} - -isc_result_t -dns_peerlist_peerbyaddr(dns_peerlist_t *servers, - isc_netaddr_t *addr, dns_peer_t **retval) -{ - dns_peer_t *server; - isc_result_t res; - - REQUIRE(retval != NULL); - REQUIRE(DNS_PEERLIST_VALID(servers)); - - server = ISC_LIST_HEAD(servers->elements); - while (server != NULL) { - if (isc_netaddr_eqprefix(addr, &server->address, - server->prefixlen)) - break; - - server = ISC_LIST_NEXT(server, next); - } - - if (server != NULL) { - *retval = server; - res = ISC_R_SUCCESS; - } else { - res = ISC_R_NOTFOUND; - } - - return (res); -} - - - -isc_result_t -dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { - dns_peer_t *p = NULL; - - p = ISC_LIST_TAIL(peers->elements); - - dns_peer_attach(p, retval); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { - unsigned int prefixlen = 0; - - REQUIRE(peerptr != NULL); - switch(addr->family) { - case AF_INET: - prefixlen = 32; - break; - case AF_INET6: - prefixlen = 128; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); -} - -isc_result_t -dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen, - dns_peer_t **peerptr) -{ - dns_peer_t *peer; - - REQUIRE(peerptr != NULL); - - peer = isc_mem_get(mem, sizeof(*peer)); - if (peer == NULL) - return (ISC_R_NOMEMORY); - - peer->magic = DNS_PEER_MAGIC; - peer->address = *addr; - peer->prefixlen = prefixlen; - peer->mem = mem; - peer->bogus = false; - peer->transfer_format = dns_one_answer; - peer->transfers = 0; - peer->request_ixfr = false; - peer->provide_ixfr = false; - peer->key = NULL; - peer->refs = 1; - peer->transfer_source = NULL; - peer->notify_source = NULL; - peer->query_source = NULL; - - memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); - - ISC_LINK_INIT(peer, next); - - *peerptr = peer; - - return (ISC_R_SUCCESS); -} - -void -dns_peer_attach(dns_peer_t *source, dns_peer_t **target) { - REQUIRE(DNS_PEER_VALID(source)); - REQUIRE(target != NULL); - REQUIRE(*target == NULL); - - source->refs++; - - ENSURE(source->refs != 0xffffffffU); - - *target = source; -} - -void -dns_peer_detach(dns_peer_t **peer) { - dns_peer_t *p; - - REQUIRE(peer != NULL); - REQUIRE(*peer != NULL); - REQUIRE(DNS_PEER_VALID(*peer)); - - p = *peer; - - REQUIRE(p->refs > 0); - - *peer = NULL; - p->refs--; - - if (p->refs == 0) - peer_delete(&p); -} - -static void -peer_delete(dns_peer_t **peer) { - dns_peer_t *p; - isc_mem_t *mem; - - REQUIRE(peer != NULL); - REQUIRE(DNS_PEER_VALID(*peer)); - - p = *peer; - - REQUIRE(p->refs == 0); - - mem = p->mem; - p->mem = NULL; - p->magic = 0; - - if (p->key != NULL) { - dns_name_free(p->key, mem); - isc_mem_put(mem, p->key, sizeof(dns_name_t)); - } - - if (p->query_source != NULL) - isc_mem_put(mem, p->query_source, sizeof(*p->query_source)); - - if (p->notify_source != NULL) - isc_mem_put(mem, p->notify_source, sizeof(*p->notify_source)); - - if (p->transfer_source != NULL) - isc_mem_put(mem, p->transfer_source, - sizeof(*p->transfer_source)); - - isc_mem_put(mem, p, sizeof(*p)); - - *peer = NULL; -} - -isc_result_t -dns_peer_setbogus(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags); - - peer->bogus = newval; - DNS_BIT_SET(BOGUS_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getbogus(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) { - *retval = peer->bogus; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - - -isc_result_t -dns_peer_setprovideixfr(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags); - - peer->provide_ixfr = newval; - DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getprovideixfr(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) { - *retval = peer->provide_ixfr; - return (ISC_R_SUCCESS); - } else { - return (ISC_R_NOTFOUND); - } -} - -isc_result_t -dns_peer_setrequestixfr(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags); - - peer->request_ixfr = newval; - DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getrequestixfr(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) { - *retval = peer->request_ixfr; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setsupportedns(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags); - - peer->support_edns = newval; - DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getsupportedns(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) { - *retval = peer->support_edns; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setrequestnsid(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags); - - peer->request_nsid = newval; - DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) { - *retval = peer->request_nsid; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setsendcookie(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags); - - peer->send_cookie = newval; - DNS_BIT_SET(SEND_COOKIE_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getsendcookie(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(SEND_COOKIE_BIT, &peer->bitflags)) { - *retval = peer->send_cookie; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setrequestexpire(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags); - - peer->request_expire = newval; - DNS_BIT_SET(REQUEST_EXPIRE_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getrequestexpire(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(REQUEST_EXPIRE_BIT, &peer->bitflags)) { - *retval = peer->request_expire; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setforcetcp(dns_peer_t *peer, bool newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags); - - peer->force_tcp = newval; - DNS_BIT_SET(FORCE_TCP_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getforcetcp(dns_peer_t *peer, bool *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(FORCE_TCP_BIT, &peer->bitflags)) { - *retval = peer->force_tcp; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_settransfers(dns_peer_t *peer, uint32_t newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags); - - peer->transfers = newval; - DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_gettransfers(dns_peer_t *peer, uint32_t *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) { - *retval = peer->transfers; - return (ISC_R_SUCCESS); - } else { - return (ISC_R_NOTFOUND); - } -} - -isc_result_t -dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, - &peer->bitflags); - - peer->transfer_format = newval; - DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) { - *retval = peer->transfer_format; - return (ISC_R_SUCCESS); - } else { - return (ISC_R_NOTFOUND); - } -} - -isc_result_t -dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(retval != NULL); - - if (peer->key != NULL) { - *retval = peer->key; - } - - return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) { - bool exists = false; - - if (peer->key != NULL) { - dns_name_free(peer->key, peer->mem); - isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t)); - exists = true; - } - - peer->key = *keyval; - *keyval = NULL; - - return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { - isc_buffer_t b; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - dns_fixedname_init(&fname); - isc_buffer_constinit(&b, keyval, strlen(keyval)); - isc_buffer_add(&b, strlen(keyval)); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - name = isc_mem_get(peer->mem, sizeof(dns_name_t)); - if (name == NULL) - return (ISC_R_NOMEMORY); - - dns_name_init(name, NULL); - result = dns_name_dup(dns_fixedname_name(&fname), peer->mem, name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(peer->mem, name, sizeof(dns_name_t)); - return (result); - } - - result = dns_peer_setkey(peer, &name); - if (result != ISC_R_SUCCESS) - isc_mem_put(peer->mem, name, sizeof(dns_name_t)); - - return (result); -} - -isc_result_t -dns_peer_settransfersource(dns_peer_t *peer, - const isc_sockaddr_t *transfer_source) -{ - REQUIRE(DNS_PEER_VALID(peer)); - - if (peer->transfer_source != NULL) { - isc_mem_put(peer->mem, peer->transfer_source, - sizeof(*peer->transfer_source)); - peer->transfer_source = NULL; - } - if (transfer_source != NULL) { - peer->transfer_source = isc_mem_get(peer->mem, - sizeof(*peer->transfer_source)); - if (peer->transfer_source == NULL) - return (ISC_R_NOMEMORY); - - *peer->transfer_source = *transfer_source; - } - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(transfer_source != NULL); - - if (peer->transfer_source == NULL) - return (ISC_R_NOTFOUND); - *transfer_source = *peer->transfer_source; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_setnotifysource(dns_peer_t *peer, - const isc_sockaddr_t *notify_source) -{ - REQUIRE(DNS_PEER_VALID(peer)); - - if (peer->notify_source != NULL) { - isc_mem_put(peer->mem, peer->notify_source, - sizeof(*peer->notify_source)); - peer->notify_source = NULL; - } - if (notify_source != NULL) { - peer->notify_source = isc_mem_get(peer->mem, - sizeof(*peer->notify_source)); - if (peer->notify_source == NULL) - return (ISC_R_NOMEMORY); - - *peer->notify_source = *notify_source; - } - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(notify_source != NULL); - - if (peer->notify_source == NULL) - return (ISC_R_NOTFOUND); - *notify_source = *peer->notify_source; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { - REQUIRE(DNS_PEER_VALID(peer)); - - if (peer->query_source != NULL) { - isc_mem_put(peer->mem, peer->query_source, - sizeof(*peer->query_source)); - peer->query_source = NULL; - } - if (query_source != NULL) { - peer->query_source = isc_mem_get(peer->mem, - sizeof(*peer->query_source)); - if (peer->query_source == NULL) - return (ISC_R_NOMEMORY); - - *peer->query_source = *query_source; - } - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(query_source != NULL); - - if (peer->query_source == NULL) - return (ISC_R_NOTFOUND); - *query_source = *peer->query_source; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_setudpsize(dns_peer_t *peer, uint16_t udpsize) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); - - peer->udpsize = udpsize; - DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getudpsize(dns_peer_t *peer, uint16_t *udpsize) { - - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(udpsize != NULL); - - if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { - *udpsize = peer->udpsize; - return (ISC_R_SUCCESS); - } else { - return (ISC_R_NOTFOUND); - } -} - -isc_result_t -dns_peer_setmaxudp(dns_peer_t *peer, uint16_t maxudp) { - bool existed; - - REQUIRE(DNS_PEER_VALID(peer)); - - existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); - - peer->maxudp = maxudp; - DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); - - return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getmaxudp(dns_peer_t *peer, uint16_t *maxudp) { - - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(maxudp != NULL); - - if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { - *maxudp = peer->maxudp; - return (ISC_R_SUCCESS); - } else { - return (ISC_R_NOTFOUND); - } -} - -isc_result_t -dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscp < 64); - - peer->notify_dscp = dscp; - DNS_BIT_SET(NOTIFY_DSCP_BIT, &peer->bitflags); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscpp != NULL); - - if (DNS_BIT_CHECK(NOTIFY_DSCP_BIT, &peer->bitflags)) { - *dscpp = peer->notify_dscp; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscp < 64); - - peer->transfer_dscp = dscp; - DNS_BIT_SET(TRANSFER_DSCP_BIT, &peer->bitflags); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscpp != NULL); - - if (DNS_BIT_CHECK(TRANSFER_DSCP_BIT, &peer->bitflags)) { - *dscpp = peer->transfer_dscp; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscp < 64); - - peer->query_dscp = dscp; - DNS_BIT_SET(QUERY_DSCP_BIT, &peer->bitflags); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(dscpp != NULL); - - if (DNS_BIT_CHECK(QUERY_DSCP_BIT, &peer->bitflags)) { - *dscpp = peer->query_dscp; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -dns_peer_setednsversion(dns_peer_t *peer, uint8_t ednsversion) { - REQUIRE(DNS_PEER_VALID(peer)); - - peer->ednsversion = ednsversion; - DNS_BIT_SET(EDNS_VERSION_BIT, &peer->bitflags); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_peer_getednsversion(dns_peer_t *peer, uint8_t *ednsversion) { - REQUIRE(DNS_PEER_VALID(peer)); - REQUIRE(ednsversion != NULL); - - if (DNS_BIT_CHECK(EDNS_VERSION_BIT, &peer->bitflags)) { - *ednsversion = peer->ednsversion; - return (ISC_R_SUCCESS); - } else - return (ISC_R_NOTFOUND); -} diff --git a/lib/dns-pkcs11/pkcs11.c b/lib/dns-pkcs11/pkcs11.c deleted file mode 100644 index 20552fa..0000000 --- a/lib/dns-pkcs11/pkcs11.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifdef PKCS11CRYPTO - -#include - -#include - -#include -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_pkcs11.h" - -isc_result_t -dst__pkcs11_toresult(const char *funcname, const char *file, int line, - isc_result_t fallback, CK_RV rv) -{ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, - "%s:%d: %s: Error = 0x%.8lX\n", - file, line, funcname, rv); - if (rv == CKR_HOST_MEMORY) - return (ISC_R_NOMEMORY); - return (fallback); -} - -isc_result_t -dst_random_getdata(void *data, unsigned int length, - unsigned int *returned, unsigned int flags) { -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_result_t ret; - -#ifndef DONT_REQUIRE_DST_LIB_INIT - INSIST(dst__memory_pool != NULL); -#endif - REQUIRE(data != NULL); - REQUIRE(length > 0); - UNUSED(flags); - - ret = pk11_rand_bytes(data, (int) length); - if ((ret == ISC_R_SUCCESS) && (returned != NULL)) - *returned = length; - return (ret); -#else - UNUSED(data); - UNUSED(length); - UNUSED(returned); - UNUSED(flags); - - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -#endif /* PKCS11CRYPTO */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11dh_link.c b/lib/dns-pkcs11/pkcs11dh_link.c deleted file mode 100644 index fb0a12f..0000000 --- a/lib/dns-pkcs11/pkcs11dh_link.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifdef PKCS11CRYPTO - -#include - -#include - -#ifndef PK11_DH_DISABLE - -#include -#include - -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" - -#include -#include -#define WANT_DH_PRIMES -#include - -#include - -/* - * PKCS#3 DH keys: - * mechanisms: - * CKM_DH_PKCS_PARAMETER_GEN, - * CKM_DH_PKCS_KEY_PAIR_GEN, - * CKM_DH_PKCS_DERIVE - * domain parameters: - * object class CKO_DOMAIN_PARAMETERS - * key type CKK_DH - * attribute CKA_PRIME (prime p) - * attribute CKA_BASE (base g) - * optional attribute CKA_PRIME_BITS (p length in bits) - * public key: - * object class CKO_PUBLIC_KEY - * key type CKK_DH - * attribute CKA_PRIME (prime p) - * attribute CKA_BASE (base g) - * attribute CKA_VALUE (public value y) - * private key: - * object class CKO_PRIVATE_KEY - * key type CKK_DH - * attribute CKA_PRIME (prime p) - * attribute CKA_BASE (base g) - * attribute CKA_VALUE (private value x) - * optional attribute CKA_VALUE_BITS (x length in bits) - * reuse CKA_PRIVATE_EXPONENT for key pair private value - */ - -#define CKA_VALUE2 CKA_PRIVATE_EXPONENT - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -#define DST_RET(a) {ret = a; goto err;} - -static void pkcs11dh_destroy(dst_key_t *key); -static isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data); - -static isc_result_t -pkcs11dh_loadpriv(const dst_key_t *key, - CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE *hKey) -{ - CK_RV rv; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_DH; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_PRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - const pk11_object_t *priv; - isc_result_t ret; - unsigned int i; - - priv = key->keydata.pkey; - if ((priv->object != CK_INVALID_HANDLE) && priv->ontoken) { - *hKey = priv->object; - return (ISC_R_SUCCESS); - } - - attr = pk11_attribute_bytype(priv, CKA_PRIME); - if (attr == NULL) - return (DST_R_INVALIDPRIVATEKEY); - keyTemplate[6].pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - - attr = pk11_attribute_bytype(priv, CKA_BASE); - if (attr == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - keyTemplate[7].pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (keyTemplate[7].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); - keyTemplate[7].ulValueLen = attr->ulValueLen; - - attr = pk11_attribute_bytype(priv, CKA_VALUE2); - if (attr == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - keyTemplate[8].pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (keyTemplate[8].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); - keyTemplate[8].ulValueLen = attr->ulValueLen; - - PK11_CALL(pkcs_C_CreateObject, - (session, keyTemplate, (CK_ULONG) 9, hKey), - DST_R_COMPUTESECRETFAILURE); - if (rv == CKR_OK) - ret = ISC_R_SUCCESS; - - err: - for (i = 6; i <= 8; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(key->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - return (ret); -} - -static isc_result_t -pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, - isc_buffer_t *secret) -{ - CK_RV rv; - CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_ATTRIBUTE *attr; - CK_ULONG secLen; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) } - }; - CK_ATTRIBUTE valTemplate[] = - { - { CKA_VALUE, NULL, 0 } - }; - CK_BYTE *secValue; - pk11_context_t ctx; - isc_result_t ret; - unsigned int i; - isc_region_t r; - - REQUIRE(pub->keydata.pkey != NULL); - REQUIRE(priv->keydata.pkey != NULL); - REQUIRE(priv->keydata.pkey->repr != NULL); - attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME); - if (attr == NULL) - return (DST_R_INVALIDPUBLICKEY); - REQUIRE(attr != NULL); - secLen = attr->ulValueLen; - attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); - if (attr == NULL) - return (DST_R_INVALIDPUBLICKEY); - - ret = pk11_get_session(&ctx, OP_DH, true, false, - priv->keydata.pkey->reqlogon, NULL, - pk11_get_best_token(OP_DH)); - if (ret != ISC_R_SUCCESS) - return (ret); - - mech.ulParameterLen = attr->ulValueLen; - mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen); - if (mech.pParameter == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(mech.pParameter, attr->pValue, mech.ulParameterLen); - - ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey); - if (ret != ISC_R_SUCCESS) - goto err; - - PK11_RET(pkcs_C_DeriveKey, - (ctx.session, &mech, hKey, - keyTemplate, (CK_ULONG) 6, &hDerived), - DST_R_COMPUTESECRETFAILURE); - - attr = valTemplate; - PK11_RET(pkcs_C_GetAttributeValue, - (ctx.session, hDerived, attr, (CK_ULONG) 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (ctx.session, hDerived, attr, (CK_ULONG) 1), - DST_R_CRYPTOFAILURE); - - /* strip leading zeros */ - secValue = (CK_BYTE_PTR) attr->pValue; - for (i = 0; i < attr->ulValueLen; i++) - if (secValue[i] != 0) - break; - isc_buffer_availableregion(secret, &r); - if (r.length < attr->ulValueLen - i) - DST_RET(ISC_R_NOSPACE); - memmove(r.base, secValue + i, attr->ulValueLen - i); - isc_buffer_add(secret, attr->ulValueLen - i); - ret = ISC_R_SUCCESS; - - err: - if (hDerived != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(ctx.session, hDerived); - if (valTemplate[0].pValue != NULL) { - isc_safe_memwipe(valTemplate[0].pValue, - valTemplate[0].ulValueLen); - isc_mem_put(pub->mctx, - valTemplate[0].pValue, - valTemplate[0].ulValueLen); - } - if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) - (void) pkcs_C_DestroyObject(ctx.session, hKey); - if (mech.pParameter != NULL) { - isc_safe_memwipe(mech.pParameter, mech.ulParameterLen); - isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); - } - pk11_return_session(&ctx); - return (ret); -} - -static bool -pkcs11dh_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *dh1, *dh2; - CK_ATTRIBUTE *attr1, *attr2; - - dh1 = key1->keydata.pkey; - dh2 = key2->keydata.pkey; - - if ((dh1 == NULL) && (dh2 == NULL)) - return (true); - else if ((dh1 == NULL) || (dh2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); - attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_BASE); - attr2 = pk11_attribute_bytype(dh2, CKA_BASE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_VALUE); - attr2 = pk11_attribute_bytype(dh2, CKA_VALUE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_VALUE2); - attr2 = pk11_attribute_bytype(dh2, CKA_VALUE2); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!dh1->ontoken && !dh2->ontoken) - return (true); - else if (dh1->ontoken || dh2->ontoken || - (dh1->object != dh2->object)) - return (false); - - return (true); -} - -static bool -pkcs11dh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *dh1, *dh2; - CK_ATTRIBUTE *attr1, *attr2; - - dh1 = key1->keydata.pkey; - dh2 = key2->keydata.pkey; - - if ((dh1 == NULL) && (dh2 == NULL)) - return (true); - else if ((dh1 == NULL) || (dh2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); - attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dh1, CKA_BASE); - attr2 = pk11_attribute_bytype(dh2, CKA_BASE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - return (true); -} - -static isc_result_t -pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 }; - CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE; - CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS; - CK_KEY_TYPE keyType = CKK_DH; - CK_ULONG bits = 0; - CK_ATTRIBUTE dTemplate[] = - { - { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) } - }; - CK_ATTRIBUTE pTemplate[] = - { - { CKA_PRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 } - }; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - }; - CK_ATTRIBUTE *attr; - pk11_object_t *dh = NULL; - pk11_context_t *pk11_ctx; - isc_result_t ret; - - UNUSED(callback); - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_DH, true, false, - false, NULL, pk11_get_best_token(OP_DH)); - if (ret != ISC_R_SUCCESS) - goto err; - - bits = key->key_size; - if ((generator == 0) && - ((bits == 768) || (bits == 1024) || (bits == 1536))) { - if (bits == 768) { - pubTemplate[4].pValue = - isc_mem_get(key->mctx, sizeof(pk11_dh_bn768)); - if (pubTemplate[4].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(pubTemplate[4].pValue, - pk11_dh_bn768, sizeof(pk11_dh_bn768)); - pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768); - } else if (bits == 1024) { - pubTemplate[4].pValue = - isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024)); - if (pubTemplate[4].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(pubTemplate[4].pValue, - pk11_dh_bn1024, sizeof(pk11_dh_bn1024)); - pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024); - } else { - pubTemplate[4].pValue = - isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536)); - if (pubTemplate[4].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(pubTemplate[4].pValue, - pk11_dh_bn1536, sizeof(pk11_dh_bn1536)); - pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536); - } - pubTemplate[5].pValue = isc_mem_get(key->mctx, - sizeof(pk11_dh_bn2)); - if (pubTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(pubTemplate[5].pValue, pk11_dh_bn2, - sizeof(pk11_dh_bn2)); - pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2); - } else { - PK11_RET(pkcs_C_GenerateKey, - (pk11_ctx->session, &mech, - dTemplate, (CK_ULONG) 5, &domainparams), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, domainparams, - pTemplate, (CK_ULONG) 2), - DST_R_CRYPTOFAILURE); - pTemplate[0].pValue = isc_mem_get(key->mctx, - pTemplate[0].ulValueLen); - if (pTemplate[0].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); - pTemplate[1].pValue = isc_mem_get(key->mctx, - pTemplate[1].ulValueLen); - if (pTemplate[1].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, domainparams, - pTemplate, (CK_ULONG) 2), - DST_R_CRYPTOFAILURE); - - pubTemplate[4].pValue = pTemplate[0].pValue; - pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen; - pTemplate[0].pValue = NULL; - pubTemplate[5].pValue = pTemplate[1].pValue; - pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen; - pTemplate[1].pValue = NULL; - } - - mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 6, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); - if (dh == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dh, 0, sizeof(*dh)); - key->keydata.pkey = dh; - dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); - if (dh->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dh->repr, 0, sizeof(*attr) * 4); - dh->attrcnt = 4; - - attr = dh->repr; - attr[0].type = CKA_PRIME; - attr[0].pValue = pubTemplate[4].pValue; - attr[0].ulValueLen = pubTemplate[4].ulValueLen; - pubTemplate[4].pValue = NULL; - - attr[1].type = CKA_BASE; - attr[1].pValue = pubTemplate[5].pValue; - attr[1].ulValueLen = pubTemplate[5].ulValueLen; - pubTemplate[5].pValue =NULL; - - attr += 2; - attr->type = CKA_VALUE; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - - attr++; - attr->type = CKA_VALUE; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->type = CKA_VALUE2; - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ISC_R_SUCCESS); - - err: - pkcs11dh_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - if (domainparams != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); - - if (pubTemplate[4].pValue != NULL) { - isc_safe_memwipe(pubTemplate[4].pValue, - pubTemplate[4].ulValueLen); - isc_mem_put(key->mctx, - pubTemplate[4].pValue, - pubTemplate[4].ulValueLen); - } - if (pubTemplate[5].pValue != NULL) { - isc_safe_memwipe(pubTemplate[5].pValue, - pubTemplate[5].ulValueLen); - isc_mem_put(key->mctx, - pubTemplate[5].pValue, - pubTemplate[5].ulValueLen); - } - if (pTemplate[0].pValue != NULL) { - isc_safe_memwipe(pTemplate[0].pValue, - pTemplate[0].ulValueLen); - isc_mem_put(key->mctx, - pTemplate[0].pValue, - pTemplate[0].ulValueLen); - } - if (pTemplate[1].pValue != NULL) { - isc_safe_memwipe(pTemplate[1].pValue, - pTemplate[1].ulValueLen); - isc_mem_put(key->mctx, - pTemplate[1].pValue, - pTemplate[1].ulValueLen); - } - - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11dh_isprivate(const dst_key_t *key) { - pk11_object_t *dh = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (dh == NULL) - return (false); - attr = pk11_attribute_bytype(dh, CKA_VALUE2); - return (attr != NULL || dh->ontoken); -} - -static void -pkcs11dh_destroy(dst_key_t *key) { - pk11_object_t *dh = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (dh == NULL) - return; - - INSIST((dh->object == CK_INVALID_HANDLE) || dh->ontoken); - - for (attr = pk11_attribute_first(dh); - attr != NULL; - attr = pk11_attribute_next(dh, attr)) - switch (attr->type) { - case CKA_VALUE: - case CKA_VALUE2: - case CKA_PRIME: - case CKA_BASE: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (dh->repr != NULL) { - isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(dh, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - key->keydata.pkey = NULL; -} - -static void -uint16_toregion(uint16_t val, isc_region_t *region) { - *region->base = (val & 0xff00) >> 8; - isc_region_consume(region, 1); - *region->base = (val & 0x00ff); - isc_region_consume(region, 1); -} - -static uint16_t -uint16_fromregion(isc_region_t *region) { - uint16_t val; - unsigned char *cp = region->base; - - val = ((unsigned int)(cp[0])) << 8; - val |= ((unsigned int)(cp[1])); - - isc_region_consume(region, 2); - - return (val); -} - -static isc_result_t -pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *dh; - CK_ATTRIBUTE *attr; - isc_region_t r; - uint16_t dnslen, plen = 0, glen = 0, publen = 0; - CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; - - REQUIRE(key->keydata.pkey != NULL); - - dh = key->keydata.pkey; - - for (attr = pk11_attribute_first(dh); - attr != NULL; - attr = pk11_attribute_next(dh, attr)) - switch (attr->type) { - case CKA_VALUE: - pub = (CK_BYTE *) attr->pValue; - publen = (uint16_t) attr->ulValueLen; - break; - case CKA_PRIME: - prime = (CK_BYTE *) attr->pValue; - plen = (uint16_t) attr->ulValueLen; - break; - case CKA_BASE: - base = (CK_BYTE *) attr->pValue; - glen = (uint16_t) attr->ulValueLen; - break; - } - REQUIRE((prime != NULL) && (base != NULL) && (pub != NULL)); - - isc_buffer_availableregion(data, &r); - - if ((glen == 1) && isc_safe_memequal(pk11_dh_bn2, base, glen) && - (((plen == sizeof(pk11_dh_bn768)) && - isc_safe_memequal(pk11_dh_bn768, prime, plen)) || - ((plen == sizeof(pk11_dh_bn1024)) && - isc_safe_memequal(pk11_dh_bn1024, prime, plen)) || - ((plen == sizeof(pk11_dh_bn1536)) && - isc_safe_memequal(pk11_dh_bn1536, prime, plen)))) { - plen = 1; - glen = 0; - } - - dnslen = plen + glen + publen + 6; - if (r.length < (unsigned int) dnslen) - return (ISC_R_NOSPACE); - - uint16_toregion(plen, &r); - if (plen == 1) { - if (isc_safe_memequal(pk11_dh_bn768, prime, - sizeof(pk11_dh_bn768))) - *r.base = 1; - else if (isc_safe_memequal(pk11_dh_bn1024, prime, - sizeof(pk11_dh_bn1024))) - *r.base = 2; - else - *r.base = 3; - } - else - memmove(r.base, prime, plen); - isc_region_consume(&r, plen); - - uint16_toregion(glen, &r); - if (glen > 0) - memmove(r.base, base, glen); - isc_region_consume(&r, glen); - - uint16_toregion(publen, &r); - memmove(r.base, pub, publen); - isc_region_consume(&r, publen); - - isc_buffer_add(data, dnslen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *dh = NULL; - isc_region_t r; - uint16_t plen, glen, plen_, glen_, publen; - CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; - CK_ATTRIBUTE *attr; - int special = 0; - unsigned int bits; - isc_result_t result; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) { - result = ISC_R_SUCCESS; - goto cleanup; - } - - dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); - if (dh == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - memset(dh, 0, sizeof(*dh)); - result = DST_R_INVALIDPUBLICKEY; - - /* - * Read the prime length. 1 & 2 are table entries, > 16 means a - * prime follows, otherwise an error. - */ - if (r.length < 2) - goto cleanup; - - plen = uint16_fromregion(&r); - if (plen < 16 && plen != 1 && plen != 2) - goto cleanup; - - if (r.length < plen) - goto cleanup; - - plen_ = plen; - if (plen == 1 || plen == 2) { - if (plen == 1) { - special = *r.base; - isc_region_consume(&r, 1); - } else { - special = uint16_fromregion(&r); - } - switch (special) { - case 1: - prime = pk11_dh_bn768; - plen_ = sizeof(pk11_dh_bn768); - break; - case 2: - prime = pk11_dh_bn1024; - plen_ = sizeof(pk11_dh_bn1024); - break; - case 3: - prime = pk11_dh_bn1536; - plen_ = sizeof(pk11_dh_bn1536); - break; - default: - goto cleanup; - } - } - else { - prime = r.base; - isc_region_consume(&r, plen); - } - - /* - * Read the generator length. This should be 0 if the prime was - * special, but it might not be. If it's 0 and the prime is not - * special, we have a problem. - */ - if (r.length < 2) - goto cleanup; - - glen = uint16_fromregion(&r); - if (r.length < glen) - goto cleanup; - - glen_ = glen; - if (special != 0) { - if (glen == 0) { - base = pk11_dh_bn2; - glen_ = sizeof(pk11_dh_bn2); - } - else { - base = r.base; - if (!isc_safe_memequal(base, pk11_dh_bn2, glen)) - goto cleanup; - base = pk11_dh_bn2; - glen_ = sizeof(pk11_dh_bn2); - } - } - else { - if (glen == 0) - goto cleanup; - base = r.base; - } - isc_region_consume(&r, glen); - - if (r.length < 2) - goto cleanup; - - publen = uint16_fromregion(&r); - if (r.length < publen) - goto cleanup; - - pub = r.base; - isc_region_consume(&r, publen); - - result = pk11_numbits(prime, plen_, &bits); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - key->key_size = bits; - - dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); - if (dh->repr == NULL) - goto nomemory; - memset(dh->repr, 0, sizeof(*attr) * 3); - dh->attrcnt = 3; - - attr = dh->repr; - attr[0].type = CKA_PRIME; - attr[0].pValue = isc_mem_get(key->mctx, plen_); - if (attr[0].pValue == NULL) - goto nomemory; - memmove(attr[0].pValue, prime, plen_); - attr[0].ulValueLen = (CK_ULONG) plen_; - - attr[1].type = CKA_BASE; - attr[1].pValue = isc_mem_get(key->mctx, glen_); - if (attr[1].pValue == NULL) - goto nomemory; - memmove(attr[1].pValue, base, glen_); - attr[1].ulValueLen = (CK_ULONG) glen_; - - attr[2].type = CKA_VALUE; - attr[2].pValue = isc_mem_get(key->mctx, publen); - if (attr[2].pValue == NULL) - goto nomemory; - memmove(attr[2].pValue, pub, publen); - attr[2].ulValueLen = (CK_ULONG) publen; - - isc_buffer_forward(data, plen + glen + publen + 6); - - key->keydata.pkey = dh; - - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(dh); - attr != NULL; - attr = pk11_attribute_next(dh, attr)) - switch (attr->type) { - case CKA_VALUE: - case CKA_PRIME: - case CKA_BASE: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (dh->repr != NULL) { - isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); - } - - result = ISC_R_NOMEMORY; - - cleanup: - if (dh != NULL) { - isc_safe_memwipe(dh, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - } - return (result); -} - -static isc_result_t -pkcs11dh_tofile(const dst_key_t *key, const char *directory) { - int i; - pk11_object_t *dh; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *prime = NULL, *base = NULL, *pub = NULL, *prv = NULL; - dst_private_t priv; - unsigned char *bufs[4]; - isc_result_t result; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) - return (DST_R_EXTERNALKEY); - - dh = key->keydata.pkey; - - for (attr = pk11_attribute_first(dh); - attr != NULL; - attr = pk11_attribute_next(dh, attr)) - switch (attr->type) { - case CKA_VALUE: - pub = attr; - break; - case CKA_VALUE2: - prv = attr; - break; - case CKA_PRIME: - prime = attr; - break; - case CKA_BASE: - base = attr; - break; - } - if ((prime == NULL) || (base == NULL) || - (pub == NULL) || (prv == NULL)) - return (DST_R_NULLKEY); - - memset(bufs, 0, sizeof(bufs)); - for (i = 0; i < 4; i++) { - bufs[i] = isc_mem_get(key->mctx, prime->ulValueLen); - if (bufs[i] == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - memset(bufs[i], 0, prime->ulValueLen); - } - - i = 0; - - priv.elements[i].tag = TAG_DH_PRIME; - priv.elements[i].length = (unsigned short) prime->ulValueLen; - memmove(bufs[i], prime->pValue, prime->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_GENERATOR; - priv.elements[i].length = (unsigned short) base->ulValueLen; - memmove(bufs[i], base->pValue, base->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_PRIVATE; - priv.elements[i].length = (unsigned short) prv->ulValueLen; - memmove(bufs[i], prv->pValue, prv->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_DH_PUBLIC; - priv.elements[i].length = (unsigned short) pub->ulValueLen; - memmove(bufs[i], pub->pValue, pub->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - priv.nelements = i; - result = dst__privstruct_writefile(key, &priv, directory); - fail: - for (i = 0; i < 4; i++) { - if (bufs[i] == NULL) - break; - isc_safe_memwipe(bufs[i], prime->ulValueLen); - isc_mem_put(key->mctx, bufs[i], prime->ulValueLen); - } - return (result); -} - -static isc_result_t -pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - unsigned int bits; - pk11_object_t *dh = NULL; - CK_ATTRIBUTE *attr; - isc_mem_t *mctx; - - UNUSED(pub); - mctx = key->mctx; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) - DST_RET(DST_R_EXTERNALKEY); - - dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); - if (dh == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dh, 0, sizeof(*dh)); - key->keydata.pkey = dh; - dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); - if (dh->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dh->repr, 0, sizeof(*attr) * 4); - dh->attrcnt = 4; - attr = dh->repr; - attr[0].type = CKA_PRIME; - attr[1].type = CKA_BASE; - attr[2].type = CKA_VALUE; - attr[3].type = CKA_VALUE2; - - for (i = 0; i < priv.nelements; i++) { - CK_BYTE *bn; - - bn = isc_mem_get(key->mctx, priv.elements[i].length); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(bn, priv.elements[i].data, priv.elements[i].length); - - switch (priv.elements[i].tag) { - case TAG_DH_PRIME: - attr = pk11_attribute_bytype(dh, CKA_PRIME); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DH_GENERATOR: - attr = pk11_attribute_bytype(dh, CKA_BASE); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DH_PRIVATE: - attr = pk11_attribute_bytype(dh, CKA_VALUE2); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DH_PUBLIC: - attr = pk11_attribute_bytype(dh, CKA_VALUE); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - } - } - dst__privstruct_free(&priv, mctx); - - attr = pk11_attribute_bytype(dh, CKA_PRIME); - INSIST(attr != NULL); - - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - return (ISC_R_SUCCESS); - - err: - pkcs11dh_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t pkcs11dh_functions = { - NULL, /*%< createctx */ - NULL, /*%< createctx2 */ - NULL, /*%< destroyctx */ - NULL, /*%< adddata */ - NULL, /*%< sign */ - NULL, /*%< verify */ - NULL, /*%< verify2 */ - pkcs11dh_computesecret, - pkcs11dh_compare, - pkcs11dh_paramcompare, - pkcs11dh_generate, - pkcs11dh_isprivate, - pkcs11dh_destroy, - pkcs11dh_todns, - pkcs11dh_fromdns, - pkcs11dh_tofile, - pkcs11dh_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11dh_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &pkcs11dh_functions; - return (ISC_R_SUCCESS); -} -#endif /* !PK11_DH_DISABLE */ - -#else /* PKCS11CRYPTO */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11dsa_link.c b/lib/dns-pkcs11/pkcs11dsa_link.c deleted file mode 100644 index 6d60e55..0000000 --- a/lib/dns-pkcs11/pkcs11dsa_link.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifdef PKCS11CRYPTO - -#include - -#include - -#ifndef PK11_DSA_DISABLE - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" - -#include - -/* - * FIPS 186-2 DSA keys: - * mechanisms: - * CKM_DSA_SHA1, - * CKM_DSA_KEY_PAIR_GEN, - * CKM_DSA_PARAMETER_GEN - * domain parameters: - * object class CKO_DOMAIN_PARAMETERS - * key type CKK_DSA - * attribute CKA_PRIME (prime p) - * attribute CKA_SUBPRIME (subprime q) - * attribute CKA_BASE (base g) - * optional attribute CKA_PRIME_BITS (p length in bits) - * public keys: - * object class CKO_PUBLIC_KEY - * key type CKK_DSA - * attribute CKA_PRIME (prime p) - * attribute CKA_SUBPRIME (subprime q) - * attribute CKA_BASE (base g) - * attribute CKA_VALUE (public value y) - * private keys: - * object class CKO_PRIVATE_KEY - * key type CKK_DSA - * attribute CKA_PRIME (prime p) - * attribute CKA_SUBPRIME (subprime q) - * attribute CKA_BASE (base g) - * attribute CKA_VALUE (private value x) - * reuse CKA_PRIVATE_EXPONENT for key pair private value - */ - -#define CKA_VALUE2 CKA_PRIVATE_EXPONENT - -#define DST_RET(a) {ret = a; goto err;} - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data); -static void pkcs11dsa_destroy(dst_key_t *key); - -static isc_result_t -pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_DSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *dsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - REQUIRE(key != NULL); - dsa = key->keydata.pkey; - REQUIRE(dsa != NULL); - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_DSA, true, false, - dsa->reqlogon, NULL, - pk11_get_best_token(OP_DSA)); - if (ret != ISC_R_SUCCESS) - goto err; - - if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = dsa->ontoken; - pk11_ctx->object = dsa->object; - goto token_key; - } - - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - case CKA_SUBPRIME: - INSIST(keyTemplate[7].type == attr->type); - keyTemplate[7].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[7].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[7].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[7].ulValueLen = attr->ulValueLen; - break; - case CKA_BASE: - INSIST(keyTemplate[8].type == attr->type); - keyTemplate[8].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[8].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[8].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[8].ulValueLen = attr->ulValueLen; - break; - case CKA_VALUE2: - INSIST(keyTemplate[9].type == CKA_VALUE); - keyTemplate[9].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[9].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[9].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[9].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 10, - &pk11_ctx->object), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 6; i <= 9; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); - for (i = 6; i <= 9; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_DSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *dsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - dsa = key->keydata.pkey; - REQUIRE(dsa != NULL); - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_DSA, true, false, - dsa->reqlogon, NULL, - pk11_get_best_token(OP_DSA)); - if (ret != ISC_R_SUCCESS) - goto err; - - if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = dsa->ontoken; - pk11_ctx->object = dsa->object; - goto token_key; - } - - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_SUBPRIME: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - case CKA_BASE: - INSIST(keyTemplate[7].type == attr->type); - keyTemplate[7].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[7].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[7].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[7].ulValueLen = attr->ulValueLen; - break; - case CKA_VALUE: - INSIST(keyTemplate[8].type == attr->type); - keyTemplate[8].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[8].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[8].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[8].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 9, - &pk11_ctx->object), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 5; i <= 8; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); - for (i = 5; i <= 8; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11dsa_createctx(dst_key_t *key, dst_context_t *dctx) { - if (dctx->use == DO_SIGN) - return (pkcs11dsa_createctx_sign(key, dctx)); - else - return (pkcs11dsa_createctx_verify(key, dctx)); -} - -static void -pkcs11dsa_destroyctx(dst_context_t *dctx) { - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - - if (pk11_ctx != NULL) { - if (!pk11_ctx->ontoken && - (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, - pk11_ctx->object); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - } -} - -static isc_result_t -pkcs11dsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - if (dctx->use == DO_SIGN) - PK11_CALL(pkcs_C_SignUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - else - PK11_CALL(pkcs_C_VerifyUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - return (ret); -} - -static isc_result_t -pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - CK_RV rv; - CK_ULONG siglen = ISC_SHA1_DIGESTLENGTH * 2; - isc_region_t r; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int klen; - - isc_buffer_availableregion(sig, &r); - if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) - return (ISC_R_NOSPACE); - - PK11_RET(pkcs_C_SignFinal, - (pk11_ctx->session, (CK_BYTE_PTR) r.base + 1, &siglen), - DST_R_SIGNFAILURE); - if (siglen != ISC_SHA1_DIGESTLENGTH * 2) - return (DST_R_SIGNFAILURE); - - klen = (dctx->key->key_size - 512)/64; - if (klen > 255) - return (ISC_R_FAILURE); - *r.base = klen; - isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); - - err: - return (ret); -} - -static isc_result_t -pkcs11dsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - PK11_CALL(pkcs_C_VerifyFinal, - (pk11_ctx->session, - (CK_BYTE_PTR) sig->base + 1, - (CK_ULONG) sig->length - 1), - DST_R_VERIFYFAILURE); - return (ret); -} - -static bool -pkcs11dsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *dsa1, *dsa2; - CK_ATTRIBUTE *attr1, *attr2; - - dsa1 = key1->keydata.pkey; - dsa2 = key2->keydata.pkey; - - if ((dsa1 == NULL) && (dsa2 == NULL)) - return (true); - else if ((dsa1 == NULL) || (dsa2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(dsa1, CKA_PRIME); - attr2 = pk11_attribute_bytype(dsa2, CKA_PRIME); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dsa1, CKA_SUBPRIME); - attr2 = pk11_attribute_bytype(dsa2, CKA_SUBPRIME); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dsa1, CKA_BASE); - attr2 = pk11_attribute_bytype(dsa2, CKA_BASE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE); - attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE2); - attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE2); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!dsa1->ontoken && !dsa2->ontoken) - return (true); - else if (dsa1->ontoken || dsa2->ontoken || - (dsa1->object != dsa2->object)) - return (false); - - return (true); -} - -static isc_result_t -pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 }; - CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE; - CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS; - CK_KEY_TYPE keyType = CKK_DSA; - CK_ULONG bits = 0; - CK_ATTRIBUTE dpTemplate[] = - { - { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }, - }; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 } - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - }; - CK_ATTRIBUTE *attr; - pk11_object_t *dsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - UNUSED(unused); - UNUSED(callback); - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_DSA, true, false, - false, NULL, pk11_get_best_token(OP_DSA)); - if (ret != ISC_R_SUCCESS) - goto err; - - bits = key->key_size; - PK11_RET(pkcs_C_GenerateKey, - (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp), - DST_R_CRYPTOFAILURE); - - dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); - if (dsa == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dsa, 0, sizeof(*dsa)); - key->keydata.pkey = dsa; - dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); - if (dsa->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dsa->repr, 0, sizeof(*attr) * 5); - dsa->attrcnt = 5; - - attr = dsa->repr; - attr[0].type = CKA_PRIME; - attr[1].type = CKA_SUBPRIME; - attr[2].type = CKA_BASE; - attr[3].type = CKA_VALUE; - attr[4].type = CKA_VALUE2; - - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, dp, attr, 3), - DST_R_CRYPTOFAILURE); - - for (i = 0; i <= 2; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, dp, attr, 3), - DST_R_CRYPTOFAILURE); - pubTemplate[5].pValue = attr[0].pValue; - pubTemplate[5].ulValueLen = attr[0].ulValueLen; - pubTemplate[6].pValue = attr[1].pValue; - pubTemplate[6].ulValueLen = attr[1].ulValueLen; - pubTemplate[7].pValue = attr[2].pValue; - pubTemplate[7].ulValueLen = attr[2].ulValueLen; - - mech.mechanism = CKM_DSA_KEY_PAIR_GEN; - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 8, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - attr = dsa->repr; - attr += 3; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - - attr++; - attr->type = CKA_VALUE; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->type = CKA_VALUE2; - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ISC_R_SUCCESS); - - err: - pkcs11dsa_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - if (dp != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11dsa_isprivate(const dst_key_t *key) { - pk11_object_t *dsa = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (dsa == NULL) - return (false); - attr = pk11_attribute_bytype(dsa, CKA_VALUE2); - return (attr != NULL || dsa->ontoken); -} - -static void -pkcs11dsa_destroy(dst_key_t *key) { - pk11_object_t *dsa = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (dsa == NULL) - return; - - INSIST((dsa->object == CK_INVALID_HANDLE) || dsa->ontoken); - - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - case CKA_SUBPRIME: - case CKA_BASE: - case CKA_VALUE: - case CKA_VALUE2: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (dsa->repr != NULL) { - isc_safe_memwipe(dsa->repr, dsa->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - dsa->repr, - dsa->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(dsa, sizeof(*dsa)); - isc_mem_put(key->mctx, dsa, sizeof(*dsa)); - key->keydata.pkey = NULL; -} - - -static isc_result_t -pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *dsa; - CK_ATTRIBUTE *attr; - isc_region_t r; - int dnslen; - unsigned int t, p_bytes; - CK_ATTRIBUTE *prime = NULL, *subprime = NULL; - CK_ATTRIBUTE *base = NULL, *pub_key = NULL; - CK_BYTE *cp; - - REQUIRE(key->keydata.pkey != NULL); - - dsa = key->keydata.pkey; - - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - prime = attr; - break; - case CKA_SUBPRIME: - subprime = attr; - break; - case CKA_BASE: - base = attr; - break; - case CKA_VALUE: - pub_key = attr; - break; - } - REQUIRE((prime != NULL) && (subprime != NULL) && - (base != NULL) && (pub_key != NULL)); - - isc_buffer_availableregion(data, &r); - - t = (prime->ulValueLen - 64) / 8; - if (t > 8) - return (DST_R_INVALIDPUBLICKEY); - p_bytes = 64 + 8 * t; - - dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; - if (r.length < (unsigned int) dnslen) - return (ISC_R_NOSPACE); - - memset(r.base, 0, dnslen); - *r.base = t; - isc_region_consume(&r, 1); - - cp = (CK_BYTE *) subprime->pValue; - memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen, - cp, subprime->ulValueLen); - isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); - cp = (CK_BYTE *) prime->pValue; - memmove(r.base + key->key_size/8 - prime->ulValueLen, - cp, prime->ulValueLen); - isc_region_consume(&r, p_bytes); - cp = (CK_BYTE *) base->pValue; - memmove(r.base + key->key_size/8 - base->ulValueLen, - cp, base->ulValueLen); - isc_region_consume(&r, p_bytes); - cp = (CK_BYTE *) pub_key->pValue; - memmove(r.base + key->key_size/8 - pub_key->ulValueLen, - cp, pub_key->ulValueLen); - isc_region_consume(&r, p_bytes); - - isc_buffer_add(data, dnslen); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *dsa; - isc_region_t r; - unsigned int t, p_bytes; - CK_BYTE *prime, *subprime, *base, *pub_key; - CK_ATTRIBUTE *attr; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - - dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); - if (dsa == NULL) - return (ISC_R_NOMEMORY); - memset(dsa, 0, sizeof(*dsa)); - - t = (unsigned int) *r.base; - isc_region_consume(&r, 1); - if (t > 8) { - isc_safe_memwipe(dsa, sizeof(*dsa)); - isc_mem_put(key->mctx, dsa, sizeof(*dsa)); - return (DST_R_INVALIDPUBLICKEY); - } - p_bytes = 64 + 8 * t; - - if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { - isc_safe_memwipe(dsa, sizeof(*dsa)); - isc_mem_put(key->mctx, dsa, sizeof(*dsa)); - return (DST_R_INVALIDPUBLICKEY); - } - - subprime = r.base; - isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); - - prime = r.base; - isc_region_consume(&r, p_bytes); - - base = r.base; - isc_region_consume(&r, p_bytes); - - pub_key = r.base; - isc_region_consume(&r, p_bytes); - - key->key_size = p_bytes * 8; - - isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); - - dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); - if (dsa->repr == NULL) - goto nomemory; - memset(dsa->repr, 0, sizeof(*attr) * 4); - dsa->attrcnt = 4; - - attr = dsa->repr; - attr[0].type = CKA_PRIME; - attr[0].pValue = isc_mem_get(key->mctx, p_bytes); - if (attr[0].pValue == NULL) - goto nomemory; - memmove(attr[0].pValue, prime, p_bytes); - attr[0].ulValueLen = p_bytes; - - attr[1].type = CKA_SUBPRIME; - attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH); - if (attr[1].pValue == NULL) - goto nomemory; - memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH); - attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH; - - attr[2].type = CKA_BASE; - attr[2].pValue = isc_mem_get(key->mctx, p_bytes); - if (attr[2].pValue == NULL) - goto nomemory; - memmove(attr[2].pValue, base, p_bytes); - attr[2].ulValueLen = p_bytes; - - attr[3].type = CKA_VALUE; - attr[3].pValue = isc_mem_get(key->mctx, p_bytes); - if (attr[3].pValue == NULL) - goto nomemory; - memmove(attr[3].pValue, pub_key, p_bytes); - attr[3].ulValueLen = p_bytes; - - key->keydata.pkey = dsa; - - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - case CKA_SUBPRIME: - case CKA_BASE: - case CKA_VALUE: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (dsa->repr != NULL) { - isc_safe_memwipe(dsa->repr, dsa->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - dsa->repr, - dsa->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(dsa, sizeof(*dsa)); - isc_mem_put(key->mctx, dsa, sizeof(*dsa)); - return (ISC_R_NOMEMORY); -} - -static isc_result_t -pkcs11dsa_tofile(const dst_key_t *key, const char *directory) { - int cnt = 0; - pk11_object_t *dsa; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL; - CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL; - dst_private_t priv; - unsigned char bufs[5][128]; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - dsa = key->keydata.pkey; - - for (attr = pk11_attribute_first(dsa); - attr != NULL; - attr = pk11_attribute_next(dsa, attr)) - switch (attr->type) { - case CKA_PRIME: - prime = attr; - break; - case CKA_SUBPRIME: - subprime = attr; - break; - case CKA_BASE: - base = attr; - break; - case CKA_VALUE: - pub_key = attr; - break; - case CKA_VALUE2: - priv_key = attr; - break; - } - if ((prime == NULL) || (subprime == NULL) || (base == NULL) || - (pub_key == NULL) || (priv_key ==NULL)) - return (DST_R_NULLKEY); - - priv.elements[cnt].tag = TAG_DSA_PRIME; - priv.elements[cnt].length = (unsigned short) prime->ulValueLen; - memmove(bufs[cnt], prime->pValue, prime->ulValueLen); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_SUBPRIME; - priv.elements[cnt].length = (unsigned short) subprime->ulValueLen; - memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_BASE; - priv.elements[cnt].length = (unsigned short) base->ulValueLen; - memmove(bufs[cnt], base->pValue, base->ulValueLen); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_PRIVATE; - priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen; - memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.elements[cnt].tag = TAG_DSA_PUBLIC; - priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen; - memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen); - priv.elements[cnt].data = bufs[cnt]; - cnt++; - - priv.nelements = cnt; - return (dst__privstruct_writefile(key, &priv, directory)); -} - -static isc_result_t -pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - unsigned int bits; - pk11_object_t *dsa = NULL; - CK_ATTRIBUTE *attr; - isc_mem_t *mctx = key->mctx; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - return (ISC_R_SUCCESS); - } - - dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); - if (dsa == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dsa, 0, sizeof(*dsa)); - key->keydata.pkey = dsa; - - dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); - if (dsa->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(dsa->repr, 0, sizeof(*attr) * 5); - dsa->attrcnt = 5; - attr = dsa->repr; - attr[0].type = CKA_PRIME; - attr[1].type = CKA_SUBPRIME; - attr[2].type = CKA_BASE; - attr[3].type = CKA_VALUE; - attr[4].type = CKA_VALUE2; - - for (i = 0; i < priv.nelements; i++) { - CK_BYTE *bn; - - bn = isc_mem_get(key->mctx, priv.elements[i].length); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(bn, priv.elements[i].data, priv.elements[i].length); - - switch (priv.elements[i].tag) { - case TAG_DSA_PRIME: - attr = pk11_attribute_bytype(dsa, CKA_PRIME); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DSA_SUBPRIME: - attr = pk11_attribute_bytype(dsa, - CKA_SUBPRIME); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DSA_BASE: - attr = pk11_attribute_bytype(dsa, CKA_BASE); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DSA_PRIVATE: - attr = pk11_attribute_bytype(dsa, CKA_VALUE2); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_DSA_PUBLIC: - attr = pk11_attribute_bytype(dsa, CKA_VALUE); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - } - } - dst__privstruct_free(&priv, mctx); - - attr = pk11_attribute_bytype(dsa, CKA_PRIME); - INSIST(attr != NULL); - - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - return (ISC_R_SUCCESS); - - err: - pkcs11dsa_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t pkcs11dsa_functions = { - pkcs11dsa_createctx, - NULL, /*%< createctx2 */ - pkcs11dsa_destroyctx, - pkcs11dsa_adddata, - pkcs11dsa_sign, - pkcs11dsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - pkcs11dsa_compare, - NULL, /*%< paramcompare */ - pkcs11dsa_generate, - pkcs11dsa_isprivate, - pkcs11dsa_destroy, - pkcs11dsa_todns, - pkcs11dsa_fromdns, - pkcs11dsa_tofile, - pkcs11dsa_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11dsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &pkcs11dsa_functions; - return (ISC_R_SUCCESS); -} -#endif /* !PK11_DSA_DISABLE */ - -#else /* PKCS11CRYPTO */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11ecdsa_link.c b/lib/dns-pkcs11/pkcs11ecdsa_link.c deleted file mode 100644 index 28f3761..0000000 --- a/lib/dns-pkcs11/pkcs11ecdsa_link.c +++ /dev/null @@ -1,1200 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_ECDSA) - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" - -#include -#include -#define WANT_ECC_CURVES -#include - -#include - -/* - * FIPS 186-3 ECDSA keys: - * mechanisms: - * CKM_ECDSA, - * CKM_EC_KEY_PAIR_GEN - * domain parameters: - * CKA_EC_PARAMS (choice with OID namedCurve) - * public keys: - * object class CKO_PUBLIC_KEY - * key type CKK_EC - * attribute CKA_EC_PARAMS (choice with OID namedCurve) - * attribute CKA_EC_POINT (point Q) - * private keys: - * object class CKO_PRIVATE_KEY - * key type CKK_EC - * attribute CKA_EC_PARAMS (choice with OID namedCurve) - * attribute CKA_VALUE (big int d) - * point format: 0x04 (octet-string) <2*size+1> 0x4 (uncompressed) - */ - -#define TAG_OCTECT_STRING 0x04 -#define UNCOMPRESSED 0x04 - -#define DST_RET(a) {ret = a; goto err;} - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -static isc_result_t pkcs11ecdsa_todns(const dst_key_t *key, - isc_buffer_t *data); -static void pkcs11ecdsa_destroy(dst_key_t *key); -static isc_result_t pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, - const char *label, dst_key_t *pub); - -static isc_result_t -pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = {0, NULL, 0 }; - CK_SLOT_ID slotid; - pk11_context_t *pk11_ctx; - pk11_object_t *ec = key->keydata.pkey; - isc_result_t ret; - - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - REQUIRE(ec != NULL); - - if (dctx->key->key_alg == DST_ALG_ECDSA256) - mech.mechanism = CKM_SHA256; - else - mech.mechanism = CKM_SHA384; - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - if (ec->ontoken && (dctx->use == DO_SIGN)) - slotid = ec->slot; - else - slotid = pk11_get_best_token(OP_EC); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, slotid); - if (ret != ISC_R_SUCCESS) - goto err; - - PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); - dctx->ctxdata.pk11_ctx = pk11_ctx; - return (ISC_R_SUCCESS); - - err: - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static void -pkcs11ecdsa_destroyctx(dst_context_t *dctx) { - CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; - CK_ULONG len = ISC_SHA384_DIGESTLENGTH; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - - if (pk11_ctx != NULL) { - (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - } -} - -static isc_result_t -pkcs11ecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || - dctx->key->key_alg == DST_ALG_ECDSA384); - - PK11_CALL(pkcs_C_DigestUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - - return (ret); -} - -static isc_result_t -pkcs11ecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - CK_RV rv; - CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_EC; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; - CK_ULONG dgstlen; - CK_ULONG siglen; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *ec = key->keydata.pkey; - isc_region_t r; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - REQUIRE(ec != NULL); - - if (key->key_alg == DST_ALG_ECDSA256) { - dgstlen = ISC_SHA256_DIGESTLENGTH; - siglen = DNS_SIG_ECDSA256SIZE; - } else { - siglen = DNS_SIG_ECDSA384SIZE; - dgstlen = ISC_SHA384_DIGESTLENGTH; - } - - PK11_RET(pkcs_C_DigestFinal, - (pk11_ctx->session, digest, &dgstlen), - ISC_R_FAILURE); - - isc_buffer_availableregion(sig, &r); - if (r.length < siglen) - DST_RET(ISC_R_NOSPACE); - - if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = ec->ontoken; - pk11_ctx->object = ec->object; - goto token_key; - } - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_VALUE: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &hKey), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, - pk11_ctx->ontoken ? pk11_ctx->object : hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_Sign, - (pk11_ctx->session, - digest, dgstlen, - (CK_BYTE_PTR) r.base, &siglen), - DST_R_SIGNFAILURE); - - isc_buffer_add(sig, (unsigned int) siglen); - - err: - - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - - return (ret); -} - -static isc_result_t -pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - CK_RV rv; - CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EC; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 }, - { CKA_EC_POINT, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; - CK_ULONG dgstlen; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *ec = key->keydata.pkey; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - REQUIRE(ec != NULL); - - if (key->key_alg == DST_ALG_ECDSA256) - dgstlen = ISC_SHA256_DIGESTLENGTH; - else - dgstlen = ISC_SHA384_DIGESTLENGTH; - - PK11_RET(pkcs_C_DigestFinal, - (pk11_ctx->session, digest, &dgstlen), - ISC_R_FAILURE); - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_EC_POINT: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_Verify, - (pk11_ctx->session, - digest, dgstlen, - (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), - DST_R_VERIFYFAILURE); - - err: - - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - - return (ret); -} - -static bool -pkcs11ecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *ec1, *ec2; - CK_ATTRIBUTE *attr1, *attr2; - - ec1 = key1->keydata.pkey; - ec2 = key2->keydata.pkey; - - if ((ec1 == NULL) && (ec2 == NULL)) - return (true); - else if ((ec1 == NULL) || (ec2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_EC_PARAMS); - attr2 = pk11_attribute_bytype(ec2, CKA_EC_PARAMS); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_EC_POINT); - attr2 = pk11_attribute_bytype(ec2, CKA_EC_POINT); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_VALUE); - attr2 = pk11_attribute_bytype(ec2, CKA_VALUE); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!ec1->ontoken && !ec2->ontoken) - return (true); - else if (ec1->ontoken || ec2->ontoken || - (ec1->object != ec2->object)) - return (false); - - return (true); -} - -#define SETCURVE() \ - if (key->key_alg == DST_ALG_ECDSA256) { \ - attr->pValue = isc_mem_get(key->mctx, \ - sizeof(pk11_ecc_prime256v1)); \ - if (attr->pValue == NULL) \ - DST_RET(ISC_R_NOMEMORY); \ - memmove(attr->pValue, \ - pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); \ - attr->ulValueLen = sizeof(pk11_ecc_prime256v1); \ - } else { \ - attr->pValue = isc_mem_get(key->mctx, \ - sizeof(pk11_ecc_secp384r1)); \ - if (attr->pValue == NULL) \ - DST_RET(ISC_R_NOMEMORY); \ - memmove(attr->pValue, \ - pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); \ - attr->ulValueLen = sizeof(pk11_ecc_secp384r1); \ - } - -#define FREECURVE() \ - if (attr->pValue != NULL) { \ - memset(attr->pValue, 0, attr->ulValueLen); \ - isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); \ - attr->pValue = NULL; \ - } - -static isc_result_t -pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 }; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EC; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 } - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *ec; - pk11_context_t *pk11_ctx; - isc_result_t ret; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - UNUSED(unused); - UNUSED(callback); - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - false, NULL, pk11_get_best_token(OP_EC)); - if (ret != ISC_R_SUCCESS) - goto err; - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - key->keydata.pkey = ec; - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 3); - ec->attrcnt = 3; - - attr = ec->repr; - attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_EC_POINT; - attr[2].type = CKA_VALUE; - - attr = &pubTemplate[5]; - SETCURVE(); - - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 6, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - attr = &pubTemplate[5]; - FREECURVE(); - - attr = ec->repr; - SETCURVE(); - - attr++; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - - attr++; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - if (key->key_alg == DST_ALG_ECDSA256) - key->key_size = DNS_KEY_ECDSA256SIZE * 4; - else - key->key_size = DNS_KEY_ECDSA384SIZE * 4; - - return (ISC_R_SUCCESS); - - err: - pkcs11ecdsa_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11ecdsa_isprivate(const dst_key_t *key) { - pk11_object_t *ec = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (ec == NULL) - return (false); - attr = pk11_attribute_bytype(ec, CKA_VALUE); - return (attr != NULL || ec->ontoken); -} - -static void -pkcs11ecdsa_destroy(dst_key_t *key) { - pk11_object_t *ec = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (ec == NULL) - return; - - INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken); - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_LABEL: - case CKA_ID: - case CKA_EC_PARAMS: - case CKA_EC_POINT: - case CKA_VALUE: - FREECURVE(); - break; - } - if (ec->repr != NULL) { - memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - ec->repr, - ec->attrcnt * sizeof(*attr)); - } - memset(ec, 0, sizeof(*ec)); - isc_mem_put(key->mctx, ec, sizeof(*ec)); - key->keydata.pkey = NULL; -} - -static isc_result_t -pkcs11ecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *ec; - isc_region_t r; - unsigned int len; - CK_ATTRIBUTE *attr; - - REQUIRE(key->keydata.pkey != NULL); - - if (key->key_alg == DST_ALG_ECDSA256) - len = DNS_KEY_ECDSA256SIZE; - else - len = DNS_KEY_ECDSA384SIZE; - - ec = key->keydata.pkey; - attr = pk11_attribute_bytype(ec, CKA_EC_POINT); - if ((attr == NULL) || - (attr->ulValueLen != len + 3) || - (((CK_BYTE_PTR) attr->pValue)[0] != TAG_OCTECT_STRING) || - (((CK_BYTE_PTR) attr->pValue)[1] != len + 1) || - (((CK_BYTE_PTR) attr->pValue)[2] != UNCOMPRESSED)) - return (ISC_R_FAILURE); - - isc_buffer_availableregion(data, &r); - if (r.length < len) - return (ISC_R_NOSPACE); - memmove(r.base, (CK_BYTE_PTR) attr->pValue + 3, len); - isc_buffer_add(data, len); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *ec; - isc_region_t r; - unsigned int len; - CK_ATTRIBUTE *attr; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - if (key->key_alg == DST_ALG_ECDSA256) - len = DNS_KEY_ECDSA256SIZE; - else - len = DNS_KEY_ECDSA384SIZE; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - if (r.length != len) - return (DST_R_INVALIDPUBLICKEY); - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - return (ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - goto nomemory; - ec->attrcnt = 2; - - attr = ec->repr; - attr->type = CKA_EC_PARAMS; - if (key->key_alg == DST_ALG_ECDSA256) { - attr->pValue = - isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1)); - if (attr->pValue == NULL) - goto nomemory; - memmove(attr->pValue, - pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); - attr->ulValueLen = sizeof(pk11_ecc_prime256v1); - } else { - attr->pValue = - isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1)); - if (attr->pValue == NULL) - goto nomemory; - memmove(attr->pValue, - pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); - attr->ulValueLen = sizeof(pk11_ecc_secp384r1); - } - - attr++; - attr->type = CKA_EC_POINT; - attr->pValue = isc_mem_get(key->mctx, len + 3); - if (attr->pValue == NULL) - goto nomemory; - ((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING; - ((CK_BYTE_PTR) attr->pValue)[1] = len + 1; - ((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED; - memmove((CK_BYTE_PTR) attr->pValue + 3, r.base, len); - attr->ulValueLen = len + 3; - - isc_buffer_forward(data, len); - key->keydata.pkey = ec; - key->key_size = len * 4; - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - case CKA_EC_POINT: - FREECURVE(); - break; - } - if (ec->repr != NULL) { - memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - ec->repr, - ec->attrcnt * sizeof(*attr)); - } - memset(ec, 0, sizeof(*ec)); - isc_mem_put(key->mctx, ec, sizeof(*ec)); - return (ISC_R_NOMEMORY); -} - -static isc_result_t -pkcs11ecdsa_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - pk11_object_t *ec; - dst_private_t priv; - unsigned char *buf = NULL; - unsigned int i = 0; - CK_ATTRIBUTE *attr; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - ec = key->keydata.pkey; - attr = pk11_attribute_bytype(ec, CKA_VALUE); - if (attr != NULL) { - buf = isc_mem_get(key->mctx, attr->ulValueLen); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[i].tag = TAG_ECDSA_PRIVATEKEY; - priv.elements[i].length = (unsigned short) attr->ulValueLen; - memmove(buf, attr->pValue, attr->ulValueLen); - priv.elements[i].data = buf; - i++; - } - - if (key->engine != NULL) { - priv.elements[i].tag = TAG_ECDSA_ENGINE; - priv.elements[i].length = strlen(key->engine) + 1; - priv.elements[i].data = (unsigned char *)key->engine; - i++; - } - - if (key->label != NULL) { - priv.elements[i].tag = TAG_ECDSA_LABEL; - priv.elements[i].length = strlen(key->label) + 1; - priv.elements[i].data = (unsigned char *)key->label; - i++; - } - - priv.nelements = i; - ret = dst__privstruct_writefile(key, &priv, directory); - - if (buf != NULL) { - memset(buf, 0, attr->ulValueLen); - isc_mem_put(key->mctx, buf, attr->ulValueLen); - } - return (ret); -} - -static isc_result_t -pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label, - dst_key_t *pub) -{ - CK_RV rv; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_EC; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *pubattr; - pk11_object_t *ec; - pk11_object_t *pubec; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - - if (label == NULL) - return (DST_R_NOENGINE); - - ec = key->keydata.pkey; - pubec = pub->keydata.pkey; - - ec->object = CK_INVALID_HANDLE; - ec->ontoken = true; - ec->reqlogon = true; - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - return (ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 2); - ec->attrcnt = 2; - attr = ec->repr; - - attr->type = CKA_EC_PARAMS; - pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS); - INSIST(pubattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - attr++; - - attr->type = CKA_EC_POINT; - pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT); - INSIST(pubattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - - ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, ec->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(ec, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(ec, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - return (ISC_R_SUCCESS); - - err: - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - return (ret); -} - -static isc_result_t -pkcs11ecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - pk11_object_t *ec = NULL; - CK_ATTRIBUTE *attr, *pattr; - isc_mem_t *mctx = key->mctx; - unsigned int i; - const char *engine = NULL, *label = NULL; - - REQUIRE(key->key_alg == DST_ALG_ECDSA256 || - key->key_alg == DST_ALG_ECDSA384); - - if ((pub == NULL) || (pub->keydata.pkey == NULL)) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - - return (ISC_R_SUCCESS); - } - - for (i = 0; i < priv.nelements; i++) { - switch (priv.elements[i].tag) { - case TAG_ECDSA_ENGINE: - engine = (char *)priv.elements[i].data; - break; - case TAG_ECDSA_LABEL: - label = (char *)priv.elements[i].data; - break; - default: - break; - } - } - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - key->keydata.pkey = ec; - - /* Is this key is stored in a HSM? See if we can fetch it. */ - if ((label != NULL) || (engine != NULL)) { - ret = pkcs11ecdsa_fetch(key, engine, label, pub); - if (ret != ISC_R_SUCCESS) - goto err; - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - return (ret); - } - - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 3); - ec->attrcnt = 3; - - attr = ec->repr; - attr->type = CKA_EC_PARAMS; - pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_PARAMS); - INSIST(pattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); - attr->ulValueLen = pattr->ulValueLen; - - attr++; - attr->type = CKA_EC_POINT; - pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_POINT); - INSIST(pattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); - attr->ulValueLen = pattr->ulValueLen; - - attr++; - attr->type = CKA_VALUE; - attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length); - attr->ulValueLen = priv.elements[0].length; - - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - if (key->key_alg == DST_ALG_ECDSA256) - key->key_size = DNS_KEY_ECDSA256SIZE * 4; - else - key->key_size = DNS_KEY_ECDSA384SIZE * 4; - - return (ISC_R_SUCCESS); - - err: - pkcs11ecdsa_destroy(key); - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - return (ret); -} - -static isc_result_t -pkcs11ecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label, - const char *pin) -{ - CK_RV rv; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EC; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - pk11_object_t *ec; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - unsigned int i; - - UNUSED(pin); - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - return (ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - ec->object = CK_INVALID_HANDLE; - ec->ontoken = true; - ec->reqlogon = true; - key->keydata.pkey = ec; - - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 2); - ec->attrcnt = 2; - attr = ec->repr; - attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_EC_POINT; - - ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, ec->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(ec, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(ec, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - attr = ec->repr; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - for (i = 0; i <= 1; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - - keyClass = CKO_PRIVATE_KEY; - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - if (key->key_alg == DST_ALG_ECDSA256) - key->key_size = DNS_KEY_ECDSA256SIZE * 4; - else - key->key_size = DNS_KEY_ECDSA384SIZE * 4; - - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - return (ISC_R_SUCCESS); - - err: - pkcs11ecdsa_destroy(key); - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - return (ret); -} - -static dst_func_t pkcs11ecdsa_functions = { - pkcs11ecdsa_createctx, - NULL, /*%< createctx2 */ - pkcs11ecdsa_destroyctx, - pkcs11ecdsa_adddata, - pkcs11ecdsa_sign, - pkcs11ecdsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - pkcs11ecdsa_compare, - NULL, /*%< paramcompare */ - pkcs11ecdsa_generate, - pkcs11ecdsa_isprivate, - pkcs11ecdsa_destroy, - pkcs11ecdsa_todns, - pkcs11ecdsa_fromdns, - pkcs11ecdsa_tofile, - pkcs11ecdsa_parse, - NULL, /*%< cleanup */ - pkcs11ecdsa_fromlabel, - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11ecdsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &pkcs11ecdsa_functions; - return (ISC_R_SUCCESS); -} - -#else /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11eddsa_link.c b/lib/dns-pkcs11/pkcs11eddsa_link.c deleted file mode 100644 index 8189980..0000000 --- a/lib/dns-pkcs11/pkcs11eddsa_link.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(PKCS11CRYPTO) && \ - defined(HAVE_PKCS11_ED25519) || defined(HAVE_PKCS11_ED448) - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" - -#include -#include -#define WANT_ECC_CURVES -#include - -#include -#include - -/* - * FIPS 186-3 EDDSA keys: - * mechanisms: - * CKM_EDDSA, - * CKM_EDDSA_KEY_PAIR_GEN - * domain parameters: - * CKA_EC_PARAMS (choice with OID namedCurve) - * public keys: - * object class CKO_PUBLIC_KEY - * key type CKK_EDDSA - * attribute CKA_EC_PARAMS (choice with OID namedCurve) - * attribute CKA_EC_POINT (big int A, CKA_VALUE on the token) - * private keys: - * object class CKO_PRIVATE_KEY - * key type CKK_EDDSA - * attribute CKA_EC_PARAMS (choice with OID namedCurve) - * attribute CKA_VALUE (big int k) - */ - -#define DST_RET(a) {ret = a; goto err;} - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -static isc_result_t pkcs11eddsa_todns(const dst_key_t *key, - isc_buffer_t *data); -static void pkcs11eddsa_destroy(dst_key_t *key); -static isc_result_t pkcs11eddsa_fetch(dst_key_t *key, const char *engine, - const char *label, dst_key_t *pub); - -static isc_result_t -pkcs11eddsa_createctx(dst_key_t *key, dst_context_t *dctx) { - isc_buffer_t *buf = NULL; - isc_result_t result; - - UNUSED(key); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - - result = isc_buffer_allocate(dctx->mctx, &buf, 16); - isc_buffer_setautorealloc(buf, true); - dctx->ctxdata.generic = buf; - - return (result); -} - -static void -pkcs11eddsa_destroyctx(dst_context_t *dctx) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - if (buf != NULL) - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; -} - -static isc_result_t -pkcs11eddsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - isc_buffer_t *nbuf = NULL; - isc_region_t r; - unsigned int length; - isc_result_t result; - - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); - - result = isc_buffer_copyregion(buf, data); - if (result == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - length = isc_buffer_length(buf) + data->length + 64; - result = isc_buffer_allocate(dctx->mctx, &nbuf, length); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_usedregion(buf, &r); - (void) isc_buffer_copyregion(nbuf, &r); - (void) isc_buffer_copyregion(nbuf, data); - isc_buffer_free(&buf); - dctx->ctxdata.generic = nbuf; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11eddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - CK_RV rv; - CK_MECHANISM mech = { CKM_EDDSA, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_EDDSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_ULONG siglen; - CK_SLOT_ID slotid; - pk11_context_t *pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *ec = key->keydata.pkey; - isc_region_t t; - isc_region_t r; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - REQUIRE(ec != NULL); - - if (key->key_alg == DST_ALG_ED25519) - siglen = DNS_SIG_ED25519SIZE; - else - siglen = DNS_SIG_ED448SIZE; - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - if (ec->ontoken && (dctx->use == DO_SIGN)) - slotid = ec->slot; - else - slotid = pk11_get_best_token(OP_EC); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, slotid); - if (ret != ISC_R_SUCCESS) - goto err; - - isc_buffer_availableregion(sig, &r); - if (r.length < siglen) - DST_RET(ISC_R_NOSPACE); - - if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = ec->ontoken; - pk11_ctx->object = ec->object; - goto token_key; - } - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_VALUE: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &hKey), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, - pk11_ctx->ontoken ? pk11_ctx->object : hKey), - ISC_R_FAILURE); - - isc_buffer_usedregion(buf, &t); - - PK11_RET(pkcs_C_Sign, - (pk11_ctx->session, - (CK_BYTE_PTR) t.base, (CK_ULONG) t.length, - (CK_BYTE_PTR) r.base, &siglen), - DST_R_SIGNFAILURE); - - isc_buffer_add(sig, (unsigned int) siglen); - - err: - - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; - - return (ret); -} - -static isc_result_t -pkcs11eddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic; - CK_RV rv; - CK_MECHANISM mech = { CKM_EDDSA, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EDDSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_SLOT_ID slotid; - pk11_context_t *pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *ec = key->keydata.pkey; - isc_region_t t; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - REQUIRE(ec != NULL); - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - if (ec->ontoken && (dctx->use == DO_SIGN)) - slotid = ec->slot; - else - slotid = pk11_get_best_token(OP_EC); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, slotid); - if (ret != ISC_R_SUCCESS) - goto err; - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_EC_POINT: - /* keyTemplate[6].type is CKA_VALUE */ - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, hKey), - ISC_R_FAILURE); - - isc_buffer_usedregion(buf, &t); - - PK11_RET(pkcs_C_Verify, - (pk11_ctx->session, - (CK_BYTE_PTR) t.base, (CK_ULONG) t.length, - (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), - DST_R_VERIFYFAILURE); - - err: - - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - isc_buffer_free(&buf); - dctx->ctxdata.generic = NULL; - - return (ret); -} - -static bool -pkcs11eddsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *ec1, *ec2; - CK_ATTRIBUTE *attr1, *attr2; - - ec1 = key1->keydata.pkey; - ec2 = key2->keydata.pkey; - - if ((ec1 == NULL) && (ec2 == NULL)) - return (true); - else if ((ec1 == NULL) || (ec2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_EC_PARAMS); - attr2 = pk11_attribute_bytype(ec2, CKA_EC_PARAMS); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_EC_POINT); - attr2 = pk11_attribute_bytype(ec2, CKA_EC_POINT); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(ec1, CKA_VALUE); - attr2 = pk11_attribute_bytype(ec2, CKA_VALUE); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!ec1->ontoken && !ec2->ontoken) - return (true); - else if (ec1->ontoken || ec2->ontoken || - (ec1->object != ec2->object)) - return (false); - - return (true); -} - -#define SETCURVE() \ - if (key->key_alg == DST_ALG_ED25519) { \ - attr->pValue = isc_mem_get(key->mctx, \ - sizeof(pk11_ecc_ed25519)); \ - if (attr->pValue == NULL) \ - DST_RET(ISC_R_NOMEMORY); \ - memmove(attr->pValue, \ - pk11_ecc_ed25519, sizeof(pk11_ecc_ed25519)); \ - attr->ulValueLen = sizeof(pk11_ecc_ed25519); \ - } else { \ - attr->pValue = isc_mem_get(key->mctx, \ - sizeof(pk11_ecc_ed448)); \ - if (attr->pValue == NULL) \ - DST_RET(ISC_R_NOMEMORY); \ - memmove(attr->pValue, \ - pk11_ecc_ed448, sizeof(pk11_ecc_ed448)); \ - attr->ulValueLen = sizeof(pk11_ecc_ed448); \ - } - -#define FREECURVE() \ - if (attr->pValue != NULL) { \ - memset(attr->pValue, 0, attr->ulValueLen); \ - isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); \ - attr->pValue = NULL; \ - } - -static isc_result_t -pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_EDDSA_KEY_PAIR_GEN, NULL, 0 }; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EDDSA; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_EC_PARAMS, NULL, 0 } - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *ec; - pk11_context_t *pk11_ctx; - isc_result_t ret; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - UNUSED(unused); - UNUSED(callback); - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - false, NULL, pk11_get_best_token(OP_EC)); - if (ret != ISC_R_SUCCESS) - goto err; - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - key->keydata.pkey = ec; - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 3); - ec->attrcnt = 3; - - attr = ec->repr; - attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_VALUE; - attr[2].type = CKA_VALUE; - - attr = &pubTemplate[5]; - SETCURVE(); - - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 6, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - attr = &pubTemplate[5]; - FREECURVE(); - - attr = ec->repr; - SETCURVE(); - - attr++; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->type = CKA_EC_POINT; - - attr++; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - if (key->key_alg == DST_ALG_ED25519) - key->key_size = DNS_KEY_ED25519SIZE; - else - key->key_size = DNS_KEY_ED448SIZE; - - return (ISC_R_SUCCESS); - - err: - pkcs11eddsa_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11eddsa_isprivate(const dst_key_t *key) { - pk11_object_t *ec = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (ec == NULL) - return (false); - attr = pk11_attribute_bytype(ec, CKA_VALUE); - return (attr != NULL || ec->ontoken); -} - -static void -pkcs11eddsa_destroy(dst_key_t *key) { - pk11_object_t *ec = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (ec == NULL) - return; - - INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken); - - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_LABEL: - case CKA_ID: - case CKA_EC_PARAMS: - case CKA_EC_POINT: - case CKA_VALUE: - FREECURVE(); - break; - } - if (ec->repr != NULL) { - memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - ec->repr, - ec->attrcnt * sizeof(*attr)); - } - memset(ec, 0, sizeof(*ec)); - isc_mem_put(key->mctx, ec, sizeof(*ec)); - key->keydata.pkey = NULL; -} - -static isc_result_t -pkcs11eddsa_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *ec; - isc_region_t r; - unsigned int len; - CK_ATTRIBUTE *attr; - - REQUIRE(key->keydata.pkey != NULL); - - if (key->key_alg == DST_ALG_ED25519) - len = DNS_KEY_ED25519SIZE; - else - len = DNS_KEY_ED448SIZE; - - ec = key->keydata.pkey; - attr = pk11_attribute_bytype(ec, CKA_EC_POINT); - if ((attr == NULL) || (attr->ulValueLen != len)) - return (ISC_R_FAILURE); - - isc_buffer_availableregion(data, &r); - if (r.length < len) - return (ISC_R_NOSPACE); - memmove(r.base, (CK_BYTE_PTR) attr->pValue, len); - isc_buffer_add(data, len); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11eddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *ec; - isc_region_t r; - unsigned int len; - CK_ATTRIBUTE *attr; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (key->key_alg == DST_ALG_ED25519) - len = DNS_KEY_ED25519SIZE; - else - len = DNS_KEY_ED448SIZE; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - if (r.length != len) - return (DST_R_INVALIDPUBLICKEY); - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - return (ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - goto nomemory; - ec->attrcnt = 2; - - attr = ec->repr; - attr->type = CKA_EC_PARAMS; - if (key->key_alg == DST_ALG_ED25519) { - attr->pValue = - isc_mem_get(key->mctx, sizeof(pk11_ecc_ed25519)); - if (attr->pValue == NULL) - goto nomemory; - memmove(attr->pValue, - pk11_ecc_ed25519, sizeof(pk11_ecc_ed25519)); - attr->ulValueLen = sizeof(pk11_ecc_ed25519); - } else { - attr->pValue = - isc_mem_get(key->mctx, sizeof(pk11_ecc_ed448)); - if (attr->pValue == NULL) - goto nomemory; - memmove(attr->pValue, - pk11_ecc_ed448, sizeof(pk11_ecc_ed448)); - attr->ulValueLen = sizeof(pk11_ecc_ed448); - } - - attr++; - attr->type = CKA_EC_POINT; - attr->pValue = isc_mem_get(key->mctx, len); - if (attr->pValue == NULL) - goto nomemory; - memmove((CK_BYTE_PTR) attr->pValue, r.base, len); - attr->ulValueLen = len; - - isc_buffer_forward(data, len); - key->keydata.pkey = ec; - key->key_size = len; - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(ec); - attr != NULL; - attr = pk11_attribute_next(ec, attr)) - switch (attr->type) { - case CKA_EC_PARAMS: - case CKA_EC_POINT: - FREECURVE(); - break; - } - if (ec->repr != NULL) { - memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - ec->repr, - ec->attrcnt * sizeof(*attr)); - } - memset(ec, 0, sizeof(*ec)); - isc_mem_put(key->mctx, ec, sizeof(*ec)); - return (ISC_R_NOMEMORY); -} - -static isc_result_t -pkcs11eddsa_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - pk11_object_t *ec; - dst_private_t priv; - unsigned char *buf = NULL; - unsigned int i = 0; - CK_ATTRIBUTE *attr; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - ec = key->keydata.pkey; - attr = pk11_attribute_bytype(ec, CKA_VALUE); - if (attr != NULL) { - buf = isc_mem_get(key->mctx, attr->ulValueLen); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[i].tag = TAG_EDDSA_PRIVATEKEY; - priv.elements[i].length = (unsigned short) attr->ulValueLen; - memmove(buf, attr->pValue, attr->ulValueLen); - priv.elements[i].data = buf; - i++; - } - - if (key->engine != NULL) { - priv.elements[i].tag = TAG_EDDSA_ENGINE; - priv.elements[i].length = strlen(key->engine) + 1; - priv.elements[i].data = (unsigned char *)key->engine; - i++; - } - - if (key->label != NULL) { - priv.elements[i].tag = TAG_EDDSA_LABEL; - priv.elements[i].length = strlen(key->label) + 1; - priv.elements[i].data = (unsigned char *)key->label; - i++; - } - - priv.nelements = i; - ret = dst__privstruct_writefile(key, &priv, directory); - - if (buf != NULL) { - memset(buf, 0, attr->ulValueLen); - isc_mem_put(key->mctx, buf, attr->ulValueLen); - } - return (ret); -} - -static isc_result_t -pkcs11eddsa_fetch(dst_key_t *key, const char *engine, const char *label, - dst_key_t *pub) -{ - CK_RV rv; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_EDDSA; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *pubattr; - pk11_object_t *ec; - pk11_object_t *pubec; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - - if (label == NULL) - return (DST_R_NOENGINE); - - ec = key->keydata.pkey; - pubec = pub->keydata.pkey; - - ec->object = CK_INVALID_HANDLE; - ec->ontoken = true; - ec->reqlogon = true; - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - return (ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 2); - ec->attrcnt = 2; - attr = ec->repr; - - attr->type = CKA_EC_PARAMS; - pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - attr++; - - attr->type = CKA_EC_POINT; - pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - - ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, ec->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(ec, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(ec, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - return (ISC_R_SUCCESS); - - err: - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - return (ret); -} - -static isc_result_t -pkcs11eddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - pk11_object_t *ec = NULL; - CK_ATTRIBUTE *attr, *pattr; - isc_mem_t *mctx = key->mctx; - unsigned int i; - const char *engine = NULL, *label = NULL; - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if ((pub == NULL) || (pub->keydata.pkey == NULL)) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - - return (ISC_R_SUCCESS); - } - - for (i = 0; i < priv.nelements; i++) { - switch (priv.elements[i].tag) { - case TAG_EDDSA_ENGINE: - engine = (char *)priv.elements[i].data; - break; - case TAG_EDDSA_LABEL: - label = (char *)priv.elements[i].data; - break; - default: - break; - } - } - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - key->keydata.pkey = ec; - - /* Is this key is stored in a HSM? See if we can fetch it. */ - if ((label != NULL) || (engine != NULL)) { - ret = pkcs11eddsa_fetch(key, engine, label, pub); - if (ret != ISC_R_SUCCESS) - goto err; - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - return (ret); - } - - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 3); - ec->attrcnt = 3; - - attr = ec->repr; - attr->type = CKA_EC_PARAMS; - pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_PARAMS); - INSIST(pattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); - attr->ulValueLen = pattr->ulValueLen; - - attr++; - attr->type = CKA_EC_POINT; - pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_POINT); - INSIST(pattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); - attr->ulValueLen = pattr->ulValueLen; - - attr++; - attr->type = CKA_VALUE; - attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length); - attr->ulValueLen = priv.elements[0].length; - - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - if (key->key_alg == DST_ALG_ED25519) - key->key_size = DNS_KEY_ED25519SIZE; - else - key->key_size = DNS_KEY_ED448SIZE; - - return (ISC_R_SUCCESS); - - err: - pkcs11eddsa_destroy(key); - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); - return (ret); -} - -static isc_result_t -pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, - const char *pin) -{ - CK_RV rv; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_EDDSA; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - pk11_object_t *ec; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - unsigned int i; - - UNUSED(pin); - - ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); - if (ec == NULL) - return (ISC_R_NOMEMORY); - memset(ec, 0, sizeof(*ec)); - ec->object = CK_INVALID_HANDLE; - ec->ontoken = true; - ec->reqlogon = true; - key->keydata.pkey = ec; - - ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (ec->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(ec->repr, 0, sizeof(*attr) * 2); - ec->attrcnt = 2; - attr = ec->repr; - attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_VALUE; - - ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_EC, true, false, - ec->reqlogon, NULL, ec->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(ec, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(ec, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - attr = ec->repr; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - for (i = 0; i <= 1; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - attr[1].type = CKA_EC_POINT; - - keyClass = CKO_PRIVATE_KEY; - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - if (key->key_alg == DST_ALG_ED25519) - key->key_size = DNS_KEY_ED25519SIZE; - else - key->key_size = DNS_KEY_ED448SIZE; - - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - return (ISC_R_SUCCESS); - - err: - pkcs11eddsa_destroy(key); - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - return (ret); -} - -static dst_func_t pkcs11eddsa_functions = { - pkcs11eddsa_createctx, - NULL, /*%< createctx2 */ - pkcs11eddsa_destroyctx, - pkcs11eddsa_adddata, - pkcs11eddsa_sign, - pkcs11eddsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - pkcs11eddsa_compare, - NULL, /*%< paramcompare */ - pkcs11eddsa_generate, - pkcs11eddsa_isprivate, - pkcs11eddsa_destroy, - pkcs11eddsa_todns, - pkcs11eddsa_fromdns, - pkcs11eddsa_tofile, - pkcs11eddsa_parse, - NULL, /*%< cleanup */ - pkcs11eddsa_fromlabel, - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11eddsa_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &pkcs11eddsa_functions; - return (ISC_R_SUCCESS); -} - -#else /* PKCS11CRYPTO && HAVE_PKCS11_EDxxx */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO && HAVE_PKCS11_EDxxx */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11gost_link.c b/lib/dns-pkcs11/pkcs11gost_link.c deleted file mode 100644 index eb7c83f..0000000 --- a/lib/dns-pkcs11/pkcs11gost_link.c +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_GOST) - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" -#include "dst_gost.h" - -#include -#include -#define WANT_GOST_PARAMS -#include - -#include - -/* - * RU CryptoPro GOST keys: - * mechanisms: - * CKM_GOSTR3411 - * CKM_GOSTR3410_WITH_GOSTR3411 - * CKM_GOSTR3410_KEY_PAIR_GEN - * domain parameters: - * CKA_GOSTR3410_PARAMS (fixed BER OID 1.2.643.2.2.35.1) - * CKA_GOSTR3411_PARAMS (fixed BER OID 1.2.643.2.2.30.1) - * CKA_GOST28147_PARAMS (optional, don't use) - * public keys: - * object class CKO_PUBLIC_KEY - * key type CKK_GOSTR3410 - * attribute CKA_VALUE (point Q) - * attribute CKA_GOSTR3410_PARAMS - * attribute CKA_GOSTR3411_PARAMS - * attribute CKA_GOST28147_PARAMS - * private keys: - * object class CKO_PRIVATE_KEY - * key type CKK_GOSTR3410 - * attribute CKA_VALUE (big int d) - * attribute CKA_GOSTR3410_PARAMS - * attribute CKA_GOSTR3411_PARAMS - * attribute CKA_GOST28147_PARAMS - * point format: (little endian) - */ - -#define CKA_VALUE2 CKA_PRIVATE_EXPONENT - -#define ISC_GOST_SIGNATURELENGTH 64 -#define ISC_GOST_PUBKEYLENGTH 64 -#define ISC_GOST_KEYSIZE 256 - -/* HASH methods */ - -isc_result_t -isc_gost_init(isc_gost_t *ctx) { - CK_RV rv; - CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 }; - int ret = ISC_R_SUCCESS; - - ret = pk11_get_session(ctx, OP_GOST, true, false, - false, NULL, 0); - if (ret != ISC_R_SUCCESS) - return (ret); - PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE); - return (ret); -} - -void -isc_gost_invalidate(isc_gost_t *ctx) { - CK_BYTE garbage[ISC_GOST_DIGESTLENGTH]; - CK_ULONG len = ISC_GOST_DIGESTLENGTH; - - if (ctx->handle == NULL) - return; - (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); - isc_safe_memwipe(garbage, sizeof(garbage)); - pk11_return_session(ctx); -} - -isc_result_t -isc_gost_update(isc_gost_t *ctx, const unsigned char *buf, unsigned int len) { - CK_RV rv; - CK_BYTE_PTR pPart; - int ret = ISC_R_SUCCESS; - - DE_CONST(buf, pPart); - PK11_CALL(pkcs_C_DigestUpdate, - (ctx->session, pPart, (CK_ULONG) len), - ISC_R_FAILURE); - return (ret); -} - -isc_result_t -isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { - CK_RV rv; - CK_ULONG len = ISC_GOST_DIGESTLENGTH; - int ret = ISC_R_SUCCESS; - - PK11_CALL(pkcs_C_DigestFinal, - (ctx->session, (CK_BYTE_PTR) digest, &len), - ISC_R_FAILURE); - pk11_return_session(ctx); - return (ret); -} - -/* DST methods */ - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -#define DST_RET(a) {ret = a; goto err;} - -static isc_result_t pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data); -static void pkcs11gost_destroy(dst_key_t *key); - -static isc_result_t -pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_GOSTR3410; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_VALUE, NULL, 0 }, - { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, - (CK_ULONG) sizeof(pk11_gost_a_paramset) }, - { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, - (CK_ULONG) sizeof(pk11_gost_paramset) } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *gost; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - REQUIRE(key != NULL); - gost = key->keydata.pkey; - REQUIRE(gost != NULL); - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_GOST, true, false, - gost->reqlogon, NULL, - pk11_get_best_token(OP_GOST)); - if (ret != ISC_R_SUCCESS) - goto err; - - if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = gost->ontoken; - pk11_ctx->object = gost->object; - goto token_key; - } - - for (attr = pk11_attribute_first(gost); - attr != NULL; - attr = pk11_attribute_next(gost, attr)) - switch (attr->type) { - case CKA_VALUE2: - INSIST(keyTemplate[6].type == CKA_VALUE); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 9, - &pk11_ctx->object), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 6; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); - for (i = 6; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_GOSTR3410; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_VALUE, NULL, 0 }, - { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, - (CK_ULONG) sizeof(pk11_gost_a_paramset) }, - { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, - (CK_ULONG) sizeof(pk11_gost_paramset) } - }; - CK_ATTRIBUTE *attr; - pk11_object_t *gost; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - REQUIRE(key != NULL); - gost = key->keydata.pkey; - REQUIRE(gost != NULL); - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_GOST, true, false, - gost->reqlogon, NULL, - pk11_get_best_token(OP_GOST)); - if (ret != ISC_R_SUCCESS) - goto err; - - if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = gost->ontoken; - pk11_ctx->object = gost->object; - goto token_key; - } - - for (attr = pk11_attribute_first(gost); - attr != NULL; - attr = pk11_attribute_next(gost, attr)) - switch (attr->type) { - case CKA_VALUE: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 8, - &pk11_ctx->object), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 5; i <= 5; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); - for (i = 5; i <= 5; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11gost_createctx(dst_key_t *key, dst_context_t *dctx) { - if (dctx->use == DO_SIGN) - return (pkcs11gost_createctx_sign(key, dctx)); - else - return (pkcs11gost_createctx_verify(key, dctx)); -} - -static void -pkcs11gost_destroyctx(dst_context_t *dctx) { - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - - if (pk11_ctx != NULL) { - if (!pk11_ctx->ontoken && - (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, - pk11_ctx->object); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - } -} - -static isc_result_t -pkcs11gost_adddata(dst_context_t *dctx, const isc_region_t *data) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - if (dctx->use == DO_SIGN) - PK11_CALL(pkcs_C_SignUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - else - PK11_CALL(pkcs_C_VerifyUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - return (ret); -} - -static isc_result_t -pkcs11gost_sign(dst_context_t *dctx, isc_buffer_t *sig) { - CK_RV rv; - CK_ULONG siglen = ISC_GOST_SIGNATURELENGTH; - isc_region_t r; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - isc_buffer_availableregion(sig, &r); - if (r.length < ISC_GOST_SIGNATURELENGTH) - return (ISC_R_NOSPACE); - - PK11_RET(pkcs_C_SignFinal, - (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), - DST_R_SIGNFAILURE); - if (siglen != ISC_GOST_SIGNATURELENGTH) - return (DST_R_SIGNFAILURE); - - isc_buffer_add(sig, ISC_GOST_SIGNATURELENGTH); - - err: - return (ret); -} - -static isc_result_t -pkcs11gost_verify(dst_context_t *dctx, const isc_region_t *sig) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - PK11_CALL(pkcs_C_VerifyFinal, - (pk11_ctx->session, - (CK_BYTE_PTR) sig->base, - (CK_ULONG) sig->length), - DST_R_VERIFYFAILURE); - return (ret); -} - -static bool -pkcs11gost_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *gost1, *gost2; - CK_ATTRIBUTE *attr1, *attr2; - - gost1 = key1->keydata.pkey; - gost2 = key2->keydata.pkey; - - if ((gost1 == NULL) && (gost2 == NULL)) - return (true); - else if ((gost1 == NULL) || (gost2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(gost1, CKA_VALUE); - attr2 = pk11_attribute_bytype(gost2, CKA_VALUE); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(gost1, CKA_VALUE2); - attr2 = pk11_attribute_bytype(gost2, CKA_VALUE2); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!gost1->ontoken && !gost2->ontoken) - return (true); - else if (gost1->ontoken || gost2->ontoken || - (gost1->object != gost2->object)) - return (false); - - return (true); -} - -static isc_result_t -pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 }; - CK_KEY_TYPE keyType = CKK_GOSTR3410; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, - (CK_ULONG) sizeof(pk11_gost_a_paramset) }, - { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, - (CK_ULONG) sizeof(pk11_gost_paramset) } - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - }; - CK_ATTRIBUTE *attr; - pk11_object_t *gost; - pk11_context_t *pk11_ctx; - isc_result_t ret; - - UNUSED(unused); - UNUSED(callback); - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_GOST, true, false, - false, NULL, pk11_get_best_token(OP_GOST)); - if (ret != ISC_R_SUCCESS) - goto err; - - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 7, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); - if (gost == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(gost, 0, sizeof(*gost)); - key->keydata.pkey = gost; - key->key_size = ISC_GOST_KEYSIZE; - gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, - sizeof(*attr) * 2); - if (gost->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(gost->repr, 0, sizeof(*attr) * 2); - gost->attrcnt = 2; - - attr = gost->repr; - attr[0].type = CKA_VALUE; - attr[1].type = CKA_VALUE2; - - attr = gost->repr; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 1), - DST_R_CRYPTOFAILURE); - - attr++; - attr->type = CKA_VALUE; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr->pValue, 0, attr->ulValueLen); - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 1), - DST_R_CRYPTOFAILURE); - attr->type = CKA_VALUE2; - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ISC_R_SUCCESS); - - err: - pkcs11gost_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11gost_isprivate(const dst_key_t *key) { - pk11_object_t *gost = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (gost == NULL) - return (false); - attr = pk11_attribute_bytype(gost, CKA_VALUE2); - return (attr != NULL || gost->ontoken); -} - -static void -pkcs11gost_destroy(dst_key_t *key) { - pk11_object_t *gost = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (gost == NULL) - return; - - INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken); - - for (attr = pk11_attribute_first(gost); - attr != NULL; - attr = pk11_attribute_next(gost, attr)) - switch (attr->type) { - case CKA_VALUE: - case CKA_VALUE2: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (gost->repr != NULL) { - isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - gost->repr, gost->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(gost, sizeof(*gost)); - isc_mem_put(key->mctx, gost, sizeof(*gost)); - key->keydata.pkey = NULL; -} - -static isc_result_t -pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *gost; - isc_region_t r; - CK_ATTRIBUTE *attr; - - REQUIRE(key->keydata.pkey != NULL); - - gost = key->keydata.pkey; - attr = pk11_attribute_bytype(gost, CKA_VALUE); - if ((attr == NULL) || (attr->ulValueLen != ISC_GOST_PUBKEYLENGTH)) - return (ISC_R_FAILURE); - - isc_buffer_availableregion(data, &r); - if (r.length < ISC_GOST_PUBKEYLENGTH) - return (ISC_R_NOSPACE); - memmove(r.base, (CK_BYTE_PTR) attr->pValue, ISC_GOST_PUBKEYLENGTH); - isc_buffer_add(data, ISC_GOST_PUBKEYLENGTH); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *gost; - isc_region_t r; - CK_ATTRIBUTE *attr; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - if (r.length != ISC_GOST_PUBKEYLENGTH) - return (DST_R_INVALIDPUBLICKEY); - - gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); - if (gost == NULL) - return (ISC_R_NOMEMORY); - memset(gost, 0, sizeof(*gost)); - gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr)); - if (gost->repr == NULL) - goto nomemory; - gost->attrcnt = 1; - - attr = gost->repr; - attr->type = CKA_VALUE; - attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH); - if (attr->pValue == NULL) - goto nomemory; - memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH); - attr->ulValueLen = ISC_GOST_PUBKEYLENGTH; - - isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH); - key->keydata.pkey = gost; - key->key_size = ISC_GOST_KEYSIZE; - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(gost); - attr != NULL; - attr = pk11_attribute_next(gost, attr)) - switch (attr->type) { - case CKA_VALUE: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (gost->repr != NULL) { - isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - gost->repr, gost->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(gost, sizeof(*gost)); - isc_mem_put(key->mctx, gost, sizeof(*gost)); - return (ISC_R_NOMEMORY); -} - -static unsigned char gost_private_der[39] = { - 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, - 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, - 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, - 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, - 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20 -}; - -#ifdef PREFER_GOSTASN1 - -static isc_result_t -pkcs11gost_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - pk11_object_t *gost; - dst_private_t priv; - unsigned char *buf = NULL; - unsigned int i = 0; - CK_ATTRIBUTE *attr; - int adj; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - gost = key->keydata.pkey; - attr = pk11_attribute_bytype(gost, CKA_VALUE2); - if (attr != NULL) { - buf = isc_mem_get(key->mctx, attr->ulValueLen + 39); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[i].tag = TAG_GOST_PRIVASN1; - priv.elements[i].length = - (unsigned short) attr->ulValueLen + 39; - memmove(buf, gost_private_der, 39); - memmove(buf + 39, attr->pValue, attr->ulValueLen); - adj = (int) attr->ulValueLen - 32; - if (adj != 0) { - buf[1] += adj; - buf[36] += adj; - buf[38] += adj; - } - priv.elements[i].data = buf; - i++; - } else - return (DST_R_CRYPTOFAILURE); - - priv.nelements = i; - ret = dst__privstruct_writefile(key, &priv, directory); - - if (buf != NULL) { - isc_safe_memwipe(buf, attr->ulValueLen); - isc_mem_put(key->mctx, buf, attr->ulValueLen); - } - return (ret); -} - -#else - -static isc_result_t -pkcs11gost_tofile(const dst_key_t *key, const char *directory) { - isc_result_t ret; - pk11_object_t *gost; - dst_private_t priv; - unsigned char *buf = NULL; - unsigned int i = 0; - CK_ATTRIBUTE *attr; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - gost = key->keydata.pkey; - attr = pk11_attribute_bytype(gost, CKA_VALUE2); - if (attr != NULL) { - buf = isc_mem_get(key->mctx, attr->ulValueLen); - if (buf == NULL) - return (ISC_R_NOMEMORY); - priv.elements[i].tag = TAG_GOST_PRIVRAW; - priv.elements[i].length = (unsigned short) attr->ulValueLen; - memmove(buf, attr->pValue, attr->ulValueLen); - priv.elements[i].data = buf; - i++; - } else - return (DST_R_CRYPTOFAILURE); - - priv.nelements = i; - ret = dst__privstruct_writefile(key, &priv, directory); - - if (buf != NULL) { - isc_safe_memwipe(buf, attr->ulValueLen); - isc_mem_put(key->mctx, buf, attr->ulValueLen); - } - return (ret); -} -#endif - -static isc_result_t -pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - pk11_object_t *gost = NULL; - CK_ATTRIBUTE *attr, *pattr; - isc_mem_t *mctx = key->mctx; - - if ((pub == NULL) || (pub->keydata.pkey == NULL)) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - return (ISC_R_SUCCESS); - } - - if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { - int adj = (int) priv.elements[0].length - (39 + 32); - unsigned char buf[39]; - - if ((adj > 0) || (adj < -31)) - DST_RET(DST_R_INVALIDPRIVATEKEY); - memmove(buf, gost_private_der, 39); - if (adj != 0) { - buf[1] += adj; - buf[36] += adj; - buf[38] += adj; - } - if (!isc_safe_memequal(priv.elements[0].data, buf, 39)) - DST_RET(DST_R_INVALIDPRIVATEKEY); - priv.elements[0].tag = TAG_GOST_PRIVRAW; - priv.elements[0].length -= 39; - memmove(priv.elements[0].data, - priv.elements[0].data + 39, - 32 + adj); - } - - gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); - if (gost == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(gost, 0, sizeof(*gost)); - key->keydata.pkey = gost; - key->key_size = ISC_GOST_KEYSIZE; - - gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, - sizeof(*attr) * 2); - if (gost->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(gost->repr, 0, sizeof(*attr) * 2); - gost->attrcnt = 2; - - attr = gost->repr; - attr->type = CKA_VALUE; - pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); - INSIST(pattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); - attr->ulValueLen = pattr->ulValueLen; - - attr++; - attr->type = CKA_VALUE2; - attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length); - attr->ulValueLen = priv.elements[0].length; - - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - return (ISC_R_SUCCESS); - - err: - pkcs11gost_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static dst_func_t pkcs11gost_functions = { - pkcs11gost_createctx, - NULL, /*%< createctx2 */ - pkcs11gost_destroyctx, - pkcs11gost_adddata, - pkcs11gost_sign, - pkcs11gost_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - pkcs11gost_compare, - NULL, /*%< paramcompare */ - pkcs11gost_generate, - pkcs11gost_isprivate, - pkcs11gost_destroy, - pkcs11gost_todns, - pkcs11gost_fromdns, - pkcs11gost_tofile, - pkcs11gost_parse, - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11gost_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &pkcs11gost_functions; - return (ISC_R_SUCCESS); -} - -#else /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ -/*! \file */ diff --git a/lib/dns-pkcs11/pkcs11rsa_link.c b/lib/dns-pkcs11/pkcs11rsa_link.c deleted file mode 100644 index f769f42..0000000 --- a/lib/dns-pkcs11/pkcs11rsa_link.c +++ /dev/null @@ -1,2319 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifdef PKCS11CRYPTO - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dst_internal.h" -#include "dst_parse.h" -#include "dst_pkcs11.h" - -#include -#include - -/* - * Limit the size of public exponents. - */ -#ifndef RSA_MAX_PUBEXP_BITS -#define RSA_MAX_PUBEXP_BITS 35 -#endif - -#define DST_RET(a) {ret = a; goto err;} - -static CK_BBOOL truevalue = TRUE; -static CK_BBOOL falsevalue = FALSE; - -static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data); -static void pkcs11rsa_destroy(dst_key_t *key); -static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, - const char *label, dst_key_t *pub); - -#ifndef PK11_RSA_PKCS_REPLACE - -static isc_result_t -pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { 0, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 }, - { CKA_PRIVATE_EXPONENT, NULL, 0 }, - { CKA_PRIME_1, NULL, 0 }, - { CKA_PRIME_2, NULL, 0 }, - { CKA_EXPONENT_1, NULL, 0 }, - { CKA_EXPONENT_2, NULL, 0 }, - { CKA_COEFFICIENT, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_SLOT_ID slotid; - pk11_object_t *rsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - -#ifndef PK11_MD5_DISABLE - REQUIRE(key->key_alg == DST_ALG_RSAMD5 || - key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#endif - - /* - * Reject incorrect RSA key lengths or disabled algorithms. - */ - switch (dctx->key->key_alg) { - case DST_ALG_RSAMD5: -#ifndef PK11_MD5_DISABLE - if (!isc_md5_available()) - return (ISC_R_FAILURE); -#endif - /* FALLTHROUGH */ - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (dctx->key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((dctx->key->key_size < 512) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((dctx->key->key_size < 1024) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - rsa = key->keydata.pkey; - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - if (rsa->ontoken) - slotid = rsa->slot; - else - slotid = pk11_get_best_token(OP_RSA); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - rsa->reqlogon, NULL, slotid); - if (ret != ISC_R_SUCCESS) - goto err; - - if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = rsa->ontoken; - pk11_ctx->object = rsa->object; - goto token_key; - } - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_MODULUS: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - case CKA_PUBLIC_EXPONENT: - INSIST(keyTemplate[7].type == attr->type); - keyTemplate[7].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[7].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[7].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[7].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIVATE_EXPONENT: - INSIST(keyTemplate[8].type == attr->type); - keyTemplate[8].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[8].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[8].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[8].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIME_1: - INSIST(keyTemplate[9].type == attr->type); - keyTemplate[9].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[9].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[9].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[9].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIME_2: - INSIST(keyTemplate[10].type == attr->type); - keyTemplate[10].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[10].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[10].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[10].ulValueLen = attr->ulValueLen; - break; - case CKA_EXPONENT_1: - INSIST(keyTemplate[11].type == attr->type); - keyTemplate[11].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[11].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[11].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[11].ulValueLen = attr->ulValueLen; - break; - case CKA_EXPONENT_2: - INSIST(keyTemplate[12].type == attr->type); - keyTemplate[12].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[12].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[12].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[12].ulValueLen = attr->ulValueLen; - break; - case CKA_COEFFICIENT: - INSIST(keyTemplate[13].type == attr->type); - keyTemplate[13].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[13].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[13].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[13].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 14, - &pk11_ctx->object), - ISC_R_FAILURE); - - token_key: - - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - mech.mechanism = CKM_MD5_RSA_PKCS; - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - mech.mechanism = CKM_SHA1_RSA_PKCS; - break; - case DST_ALG_RSASHA256: - mech.mechanism = CKM_SHA256_RSA_PKCS; - break; - case DST_ALG_RSASHA512: - mech.mechanism = CKM_SHA512_RSA_PKCS; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 6; i <= 13; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, - pk11_ctx->object); - for (i = 6; i <= 13; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, - dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { 0, NULL, 0 }; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 }, - }; - CK_ATTRIBUTE *attr; - pk11_object_t *rsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - -#ifndef PK11_MD5_DISABLE - REQUIRE(key->key_alg == DST_ALG_RSAMD5 || - key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#endif - REQUIRE(maxbits <= RSA_MAX_PUBEXP_BITS); - - /* - * Reject incorrect RSA key lengths. - */ - switch (dctx->key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (dctx->key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((dctx->key->key_size < 512) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((dctx->key->key_size < 1024) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - rsa = key->keydata.pkey; - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - rsa->reqlogon, NULL, - pk11_get_best_token(OP_RSA)); - if (ret != ISC_R_SUCCESS) - goto err; - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - { - unsigned int bits; - - switch (attr->type) { - case CKA_MODULUS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_PUBLIC_EXPONENT: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - ret = pk11_numbits(attr->pValue, attr->ulValueLen, - &bits); - if (ret != ISC_R_SUCCESS || - (bits > maxbits && maxbits != 0)) { - DST_RET(DST_R_VERIFYFAILURE); - } - break; - } - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &pk11_ctx->object), - ISC_R_FAILURE); - - switch (dctx->key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - mech.mechanism = CKM_MD5_RSA_PKCS; - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - mech.mechanism = CKM_SHA1_RSA_PKCS; - break; - case DST_ALG_RSASHA256: - mech.mechanism = CKM_SHA256_RSA_PKCS; - break; - case DST_ALG_RSASHA512: - mech.mechanism = CKM_SHA512_RSA_PKCS; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, pk11_ctx->object), - ISC_R_FAILURE); - - dctx->ctxdata.pk11_ctx = pk11_ctx; - - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - - return (ISC_R_SUCCESS); - - err: - if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, - pk11_ctx->object); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static isc_result_t -pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { - if (dctx->use == DO_SIGN) - return (pkcs11rsa_createctx_sign(key, dctx)); - else - return (pkcs11rsa_createctx_verify(key, 0U, dctx)); -} - -static isc_result_t -pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) { - if (dctx->use == DO_SIGN) - return (pkcs11rsa_createctx_sign(key, dctx)); - else - return (pkcs11rsa_createctx_verify(key, - (unsigned) maxbits, dctx)); -} - -static void -pkcs11rsa_destroyctx(dst_context_t *dctx) { - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - - if (pk11_ctx != NULL) { - if (!pk11_ctx->ontoken && - (pk11_ctx->object != CK_INVALID_HANDLE)) - (void) pkcs_C_DestroyObject(pk11_ctx->session, - pk11_ctx->object); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - } -} - -static isc_result_t -pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - if (dctx->use == DO_SIGN) - PK11_CALL(pkcs_C_SignUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - else - PK11_CALL(pkcs_C_VerifyUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - return (ret); -} - -static isc_result_t -pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - CK_RV rv; - CK_ULONG siglen = 0; - isc_region_t r; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - PK11_RET(pkcs_C_SignFinal, - (pk11_ctx->session, NULL, &siglen), - DST_R_SIGNFAILURE); - - isc_buffer_availableregion(sig, &r); - - if (r.length < (unsigned int) siglen) - return (ISC_R_NOSPACE); - - PK11_RET(pkcs_C_SignFinal, - (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), - DST_R_SIGNFAILURE); - - isc_buffer_add(sig, (unsigned int) siglen); - - err: - return (ret); -} - -static isc_result_t -pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - PK11_CALL(pkcs_C_VerifyFinal, - (pk11_ctx->session, - (CK_BYTE_PTR) sig->base, - (CK_ULONG) sig->length), - DST_R_VERIFYFAILURE); - return (ret); -} - -#else - -/* - * CKM__RSA_PKCS mechanisms are not available so fall back - * to CKM_RSA_PKCS and do the EMSA-PKCS#1-v1.5 encapsulation by hand. - */ - -CK_BYTE md5_der[] = - { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, - 0x04, 0x10 }; -CK_BYTE sha1_der[] = - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, - 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; -CK_BYTE sha256_der[] = - { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 }; -CK_BYTE sha512_der[] = - { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, - 0x00, 0x04, 0x40 }; -#define MAX_DER_SIZE 19 -#define MIN_PKCS1_PADLEN 11 - -static isc_result_t -pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { - CK_RV rv; - CK_MECHANISM mech = { 0, NULL, 0 }; - CK_SLOT_ID slotid; - pk11_object_t *rsa = key->keydata.pkey; - pk11_context_t *pk11_ctx; - isc_result_t ret; - -#ifndef PK11_MD5_DISABLE - REQUIRE(key->key_alg == DST_ALG_RSAMD5 || - key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#endif - REQUIRE(rsa != NULL); - - /* - * Reject incorrect RSA key lengths. - */ - switch (dctx->key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (dctx->key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((dctx->key->key_size < 512) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((dctx->key->key_size < 1024) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - switch (key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (!isc_md5_available()) - return (ISC_R_FAILURE); - - mech.mechanism = CKM_MD5; - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - mech.mechanism = CKM_SHA_1; - break; - case DST_ALG_RSASHA256: - mech.mechanism = CKM_SHA256; - break; - case DST_ALG_RSASHA512: - mech.mechanism = CKM_SHA512; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); - if (rsa->ontoken) - slotid = rsa->slot; - else - slotid = pk11_get_best_token(OP_RSA); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - rsa->reqlogon, NULL, slotid); - if (ret != ISC_R_SUCCESS) - goto err; - - PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); - dctx->ctxdata.pk11_ctx = pk11_ctx; - return (ISC_R_SUCCESS); - - err: - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static void -pkcs11rsa_destroyctx(dst_context_t *dctx) { - CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; - CK_ULONG len = ISC_SHA512_DIGESTLENGTH; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - - if (pk11_ctx != NULL) { - (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len); - isc_safe_memwipe(garbage, sizeof(garbage)); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - } -} - -static isc_result_t -pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) { - CK_RV rv; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - isc_result_t ret = ISC_R_SUCCESS; - - PK11_CALL(pkcs_C_DigestUpdate, - (pk11_ctx->session, - (CK_BYTE_PTR) data->base, - (CK_ULONG) data->length), - ISC_R_FAILURE); - - return (ret); -} - -static isc_result_t -pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { - CK_RV rv; - CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 }, - { CKA_PRIVATE_EXPONENT, NULL, 0 }, - { CKA_PRIME_1, NULL, 0 }, - { CKA_PRIME_2, NULL, 0 }, - { CKA_EXPONENT_1, NULL, 0 }, - { CKA_EXPONENT_2, NULL, 0 }, - { CKA_COEFFICIENT, NULL, 0 } - }; - CK_ATTRIBUTE *attr; - CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH]; - CK_BYTE *der; - CK_ULONG derlen; - CK_ULONG hashlen; - CK_ULONG dgstlen; - CK_ULONG siglen = 0; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *rsa = key->keydata.pkey; - isc_region_t r; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - -#ifndef PK11_MD5_DISABLE - REQUIRE(key->key_alg == DST_ALG_RSAMD5 || - key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#endif - REQUIRE(rsa != NULL); - - /* - * Reject incorrect RSA key lengths. - */ - switch (dctx->key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (dctx->key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((dctx->key->key_size < 512) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((dctx->key->key_size < 1024) || - (dctx->key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - switch (key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (!isc_md5_available()) - return (ISC_R_FAILURE); - - der = md5_der; - derlen = sizeof(md5_der); - hashlen = ISC_MD5_DIGESTLENGTH; - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - der = sha1_der; - derlen = sizeof(sha1_der); - hashlen = ISC_SHA1_DIGESTLENGTH; - break; - case DST_ALG_RSASHA256: - der = sha256_der; - derlen = sizeof(sha256_der); - hashlen = ISC_SHA256_DIGESTLENGTH; - break; - case DST_ALG_RSASHA512: - der = sha512_der; - derlen = sizeof(sha512_der); - hashlen = ISC_SHA512_DIGESTLENGTH; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - dgstlen = derlen + hashlen; - INSIST(dgstlen <= sizeof(digest)); - memmove(digest, der, derlen); - - PK11_RET(pkcs_C_DigestFinal, - (pk11_ctx->session, digest + derlen, &hashlen), - DST_R_SIGNFAILURE); - - isc_buffer_availableregion(sig, &r); - if (r.length < (unsigned int) dgstlen + MIN_PKCS1_PADLEN) - return (ISC_R_NOSPACE); - - if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { - pk11_ctx->ontoken = rsa->ontoken; - pk11_ctx->object = rsa->object; - goto token_key; - } - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_MODULUS: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - break; - case CKA_PUBLIC_EXPONENT: - INSIST(keyTemplate[7].type == attr->type); - keyTemplate[7].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[7].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[7].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[7].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIVATE_EXPONENT: - INSIST(keyTemplate[8].type == attr->type); - keyTemplate[8].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[8].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[8].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[8].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIME_1: - INSIST(keyTemplate[9].type == attr->type); - keyTemplate[9].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[9].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[9].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[9].ulValueLen = attr->ulValueLen; - break; - case CKA_PRIME_2: - INSIST(keyTemplate[10].type == attr->type); - keyTemplate[10].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[10].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[10].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[10].ulValueLen = attr->ulValueLen; - break; - case CKA_EXPONENT_1: - INSIST(keyTemplate[11].type == attr->type); - keyTemplate[11].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[11].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[11].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[11].ulValueLen = attr->ulValueLen; - break; - case CKA_EXPONENT_2: - INSIST(keyTemplate[12].type == attr->type); - keyTemplate[12].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[12].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[12].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[12].ulValueLen = attr->ulValueLen; - break; - case CKA_COEFFICIENT: - INSIST(keyTemplate[13].type == attr->type); - keyTemplate[13].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[13].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[13].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[13].ulValueLen = attr->ulValueLen; - break; - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 14, - &hKey), - ISC_R_FAILURE); - - token_key: - - PK11_RET(pkcs_C_SignInit, - (pk11_ctx->session, &mech, - pk11_ctx->ontoken ? pk11_ctx->object : hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_Sign, - (pk11_ctx->session, - digest, dgstlen, - NULL, &siglen), - DST_R_SIGNFAILURE); - - if (r.length < (unsigned int) siglen) - return (ISC_R_NOSPACE); - - PK11_RET(pkcs_C_Sign, - (pk11_ctx->session, - digest, dgstlen, - (CK_BYTE_PTR) r.base, &siglen), - DST_R_SIGNFAILURE); - - isc_buffer_add(sig, (unsigned int) siglen); - - err: - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 6; i <= 13; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - - return (ret); -} - -static isc_result_t -pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { - CK_RV rv; - CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 }; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_MODULUS, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 }, - }; - CK_ATTRIBUTE *attr; - CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH]; - CK_BYTE *der; - CK_ULONG derlen; - CK_ULONG hashlen; - CK_ULONG dgstlen; - pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; - dst_key_t *key = dctx->key; - pk11_object_t *rsa = key->keydata.pkey; - isc_result_t ret = ISC_R_SUCCESS; - unsigned int i; - -#ifndef PK11_MD5_DISABLE - REQUIRE(key->key_alg == DST_ALG_RSAMD5 || - key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#else - REQUIRE(key->key_alg == DST_ALG_RSASHA1 || - key->key_alg == DST_ALG_NSEC3RSASHA1 || - key->key_alg == DST_ALG_RSASHA256 || - key->key_alg == DST_ALG_RSASHA512); -#endif - REQUIRE(rsa != NULL); - - switch (key->key_alg) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (!isc_md5_available()) - return (ISC_R_FAILURE); - - der = md5_der; - derlen = sizeof(md5_der); - hashlen = ISC_MD5_DIGESTLENGTH; - break; -#endif - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - der = sha1_der; - derlen = sizeof(sha1_der); - hashlen = ISC_SHA1_DIGESTLENGTH; - break; - case DST_ALG_RSASHA256: - der = sha256_der; - derlen = sizeof(sha256_der); - hashlen = ISC_SHA256_DIGESTLENGTH; - break; - case DST_ALG_RSASHA512: - der = sha512_der; - derlen = sizeof(sha512_der); - hashlen = ISC_SHA512_DIGESTLENGTH; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - dgstlen = derlen + hashlen; - INSIST(dgstlen <= sizeof(digest)); - memmove(digest, der, derlen); - - PK11_RET(pkcs_C_DigestFinal, - (pk11_ctx->session, digest + derlen, &hashlen), - DST_R_SIGNFAILURE); - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - { - unsigned int bits; - - switch (attr->type) { - case CKA_MODULUS: - INSIST(keyTemplate[5].type == attr->type); - keyTemplate[5].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[5].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[5].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[5].ulValueLen = attr->ulValueLen; - break; - case CKA_PUBLIC_EXPONENT: - INSIST(keyTemplate[6].type == attr->type); - keyTemplate[6].pValue = isc_mem_get(dctx->mctx, - attr->ulValueLen); - if (keyTemplate[6].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(keyTemplate[6].pValue, attr->pValue, - attr->ulValueLen); - keyTemplate[6].ulValueLen = attr->ulValueLen; - ret = pk11_numbits(attr->pValue, attr->ulValueLen, - &bits); - if (ret != ISC_R_SUCCESS || bits > RSA_MAX_PUBEXP_BITS) - { - DST_RET(DST_R_VERIFYFAILURE); - } - break; - } - } - pk11_ctx->object = CK_INVALID_HANDLE; - pk11_ctx->ontoken = false; - PK11_RET(pkcs_C_CreateObject, - (pk11_ctx->session, - keyTemplate, (CK_ULONG) 7, - &hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_VerifyInit, - (pk11_ctx->session, &mech, hKey), - ISC_R_FAILURE); - - PK11_RET(pkcs_C_Verify, - (pk11_ctx->session, - digest, dgstlen, - (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), - DST_R_VERIFYFAILURE); - - err: - if (hKey != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); - for (i = 5; i <= 6; i++) - if (keyTemplate[i].pValue != NULL) { - isc_safe_memwipe(keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - isc_mem_put(dctx->mctx, - keyTemplate[i].pValue, - keyTemplate[i].ulValueLen); - } - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); - dctx->ctxdata.pk11_ctx = NULL; - - return (ret); -} -#endif - -static bool -pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) { - pk11_object_t *rsa1, *rsa2; - CK_ATTRIBUTE *attr1, *attr2; - - rsa1 = key1->keydata.pkey; - rsa2 = key2->keydata.pkey; - - if ((rsa1 == NULL) && (rsa2 == NULL)) - return (true); - else if ((rsa1 == NULL) || (rsa2 == NULL)) - return (false); - - attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS); - attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT); - attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT); - if ((attr1 == NULL) && (attr2 == NULL)) - return (true); - else if ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen)) - return (false); - - attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT); - attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT); - if (((attr1 != NULL) || (attr2 != NULL)) && - ((attr1 == NULL) || (attr2 == NULL) || - (attr1->ulValueLen != attr2->ulValueLen) || - !isc_safe_memequal(attr1->pValue, attr2->pValue, - attr1->ulValueLen))) - return (false); - - if (!rsa1->ontoken && !rsa2->ontoken) - return (true); - else if (rsa1->ontoken || rsa2->ontoken || - (rsa1->object != rsa2->object)) - return (false); - - return (true); -} - -static isc_result_t -pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { - CK_RV rv; - CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - CK_ULONG bits = 0; - CK_BYTE pubexp[5]; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE pubTemplate[] = - { - { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, - { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } - }; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE privTemplate[] = - { - { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - }; - CK_ATTRIBUTE *attr; - pk11_object_t *rsa; - pk11_context_t *pk11_ctx; - isc_result_t ret; - unsigned int i; - - UNUSED(callback); - - /* - * Reject incorrect RSA key lengths. - */ - switch (key->key_alg) { - case DST_ALG_RSAMD5: - case DST_ALG_RSASHA1: - case DST_ALG_NSEC3RSASHA1: - /* From RFC 3110 */ - if (key->key_size > 4096) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA256: - /* From RFC 5702 */ - if ((key->key_size < 512) || - (key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - case DST_ALG_RSASHA512: - /* From RFC 5702 */ - if ((key->key_size < 1024) || - (key->key_size > 4096)) - return (ISC_R_FAILURE); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - return (ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - false, NULL, pk11_get_best_token(OP_RSA)); - if (ret != ISC_R_SUCCESS) - goto err; - - bits = key->key_size; - if (exp == 0) { - /* RSA_F4 0x10001 */ - pubexp[0] = 1; - pubexp[1] = 0; - pubexp[2] = 1; - pubTemplate[6].ulValueLen = 3; - } else { - /* F5 0x100000001 */ - pubexp[0] = 1; - pubexp[1] = 0; - pubexp[2] = 0; - pubexp[3] = 0; - pubexp[4] = 1; - pubTemplate[6].ulValueLen = 5; - } - - PK11_RET(pkcs_C_GenerateKeyPair, - (pk11_ctx->session, &mech, - pubTemplate, (CK_ULONG) 7, - privTemplate, (CK_ULONG) 7, - &pub, &priv), - DST_R_CRYPTOFAILURE); - - rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); - if (rsa == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(rsa, 0, sizeof(*rsa)); - key->keydata.pkey = rsa; - rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); - if (rsa->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(rsa->repr, 0, sizeof(*attr) * 8); - rsa->attrcnt = 8; - - attr = rsa->repr; - attr[0].type = CKA_MODULUS; - attr[1].type = CKA_PUBLIC_EXPONENT; - attr[2].type = CKA_PRIVATE_EXPONENT; - attr[3].type = CKA_PRIME_1; - attr[4].type = CKA_PRIME_2; - attr[5].type = CKA_EXPONENT_1; - attr[6].type = CKA_EXPONENT_2; - attr[7].type = CKA_COEFFICIENT; - - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 2), - DST_R_CRYPTOFAILURE); - for (i = 0; i <= 1; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, pub, attr, 2), - DST_R_CRYPTOFAILURE); - - attr += 2; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 6), - DST_R_CRYPTOFAILURE); - for (i = 0; i <= 5; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, priv, attr, 6), - DST_R_CRYPTOFAILURE); - - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ISC_R_SUCCESS); - - err: - pkcs11rsa_destroy(key); - if (priv != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); - if (pub != CK_INVALID_HANDLE) - (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ret); -} - -static bool -pkcs11rsa_isprivate(const dst_key_t *key) { - pk11_object_t *rsa = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (rsa == NULL) - return (false); - attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT); - return (attr != NULL || rsa->ontoken); -} - -static void -pkcs11rsa_destroy(dst_key_t *key) { - pk11_object_t *rsa = key->keydata.pkey; - CK_ATTRIBUTE *attr; - - if (rsa == NULL) - return; - - INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken); - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_LABEL: - case CKA_ID: - case CKA_MODULUS: - case CKA_PUBLIC_EXPONENT: - case CKA_PRIVATE_EXPONENT: - case CKA_PRIME_1: - case CKA_PRIME_2: - case CKA_EXPONENT_1: - case CKA_EXPONENT_2: - case CKA_COEFFICIENT: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (rsa->repr != NULL) { - isc_safe_memwipe(rsa->repr, rsa->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - rsa->repr, - rsa->attrcnt * sizeof(*attr)); - } - isc_safe_memwipe(rsa, sizeof(*rsa)); - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); - key->keydata.pkey = NULL; -} - -static isc_result_t -pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *rsa; - CK_ATTRIBUTE *attr; - isc_region_t r; - unsigned int e_bytes = 0, mod_bytes = 0; - CK_BYTE *exponent = NULL, *modulus = NULL; - - REQUIRE(key->keydata.pkey != NULL); - - rsa = key->keydata.pkey; - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_PUBLIC_EXPONENT: - exponent = (CK_BYTE *) attr->pValue; - e_bytes = (unsigned int) attr->ulValueLen; - break; - case CKA_MODULUS: - modulus = (CK_BYTE *) attr->pValue; - mod_bytes = (unsigned int) attr->ulValueLen; - break; - } - REQUIRE((exponent != NULL) && (modulus != NULL)); - - isc_buffer_availableregion(data, &r); - - if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ - if (r.length < 1) - return (ISC_R_NOSPACE); - isc_buffer_putuint8(data, (uint8_t) e_bytes); - isc_region_consume(&r, 1); - } else { - if (r.length < 3) - return (ISC_R_NOSPACE); - isc_buffer_putuint8(data, 0); - isc_buffer_putuint16(data, (uint16_t) e_bytes); - isc_region_consume(&r, 3); - } - - if (r.length < e_bytes + mod_bytes) - return (ISC_R_NOSPACE); - - memmove(r.base, exponent, e_bytes); - isc_region_consume(&r, e_bytes); - memmove(r.base, modulus, mod_bytes); - - isc_buffer_add(data, e_bytes + mod_bytes); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *rsa; - isc_region_t r; - unsigned int e_bytes, mod_bytes; - CK_BYTE *exponent = NULL, *modulus = NULL; - CK_ATTRIBUTE *attr; - unsigned int length; - unsigned int bits; - isc_result_t ret = ISC_R_SUCCESS; - - isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); - length = r.length; - - rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); - if (rsa == NULL) - return (ISC_R_NOMEMORY); - - memset(rsa, 0, sizeof(*rsa)); - - e_bytes = *r.base; - isc_region_consume(&r, 1); - - if (e_bytes == 0) { - if (r.length < 2) { - DST_RET(DST_R_INVALIDPUBLICKEY); - } - e_bytes = (*r.base) << 8; - isc_region_consume(&r, 1); - e_bytes += *r.base; - isc_region_consume(&r, 1); - } - - if (r.length < e_bytes) { - DST_RET(DST_R_INVALIDPUBLICKEY); - } - exponent = r.base; - isc_region_consume(&r, e_bytes); - modulus = r.base; - mod_bytes = r.length; - - ret = pk11_numbits(modulus, mod_bytes, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - isc_buffer_forward(data, length); - - rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (rsa->repr == NULL) - goto nomemory; - memset(rsa->repr, 0, sizeof(*attr) * 2); - rsa->attrcnt = 2; - attr = rsa->repr; - attr[0].type = CKA_MODULUS; - attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); - if (attr[0].pValue == NULL) - goto nomemory; - memmove(attr[0].pValue, modulus, mod_bytes); - attr[0].ulValueLen = (CK_ULONG) mod_bytes; - attr[1].type = CKA_PUBLIC_EXPONENT; - attr[1].pValue = isc_mem_get(key->mctx, e_bytes); - if (attr[1].pValue == NULL) - goto nomemory; - memmove(attr[1].pValue, exponent, e_bytes); - attr[1].ulValueLen = (CK_ULONG) e_bytes; - - key->keydata.pkey = rsa; - - return (ISC_R_SUCCESS); - - nomemory: - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_MODULUS: - case CKA_PUBLIC_EXPONENT: - if (attr->pValue != NULL) { - isc_safe_memwipe(attr->pValue, - attr->ulValueLen); - isc_mem_put(key->mctx, - attr->pValue, - attr->ulValueLen); - } - break; - } - if (rsa->repr != NULL) { - isc_safe_memwipe(rsa->repr, - rsa->attrcnt * sizeof(*attr)); - isc_mem_put(key->mctx, - rsa->repr, - rsa->attrcnt * sizeof(*attr)); - } - ret = ISC_R_NOMEMORY; - - err: - isc_safe_memwipe(rsa, sizeof(*rsa)); - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); - return (ret); -} - -static isc_result_t -pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { - int i; - pk11_object_t *rsa; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; - CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; - CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; - dst_private_t priv; - unsigned char *bufs[10]; - isc_result_t result; - - if (key->keydata.pkey == NULL) - return (DST_R_NULLKEY); - - if (key->external) { - priv.nelements = 0; - return (dst__privstruct_writefile(key, &priv, directory)); - } - - rsa = key->keydata.pkey; - - for (attr = pk11_attribute_first(rsa); - attr != NULL; - attr = pk11_attribute_next(rsa, attr)) - switch (attr->type) { - case CKA_MODULUS: - modulus = attr; - break; - case CKA_PUBLIC_EXPONENT: - exponent = attr; - break; - case CKA_PRIVATE_EXPONENT: - d = attr; - break; - case CKA_PRIME_1: - p = attr; - break; - case CKA_PRIME_2: - q = attr; - break; - case CKA_EXPONENT_1: - dmp1 = attr; - break; - case CKA_EXPONENT_2: - dmq1 = attr; - break; - case CKA_COEFFICIENT: - iqmp = attr; - break; - } - if ((modulus == NULL) || (exponent == NULL)) - return (DST_R_NULLKEY); - - memset(bufs, 0, sizeof(bufs)); - - for (i = 0; i < 10; i++) { - bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); - if (bufs[i] == NULL) { - result = ISC_R_NOMEMORY; - goto fail; - } - memset(bufs[i], 0, modulus->ulValueLen); - } - - i = 0; - - priv.elements[i].tag = TAG_RSA_MODULUS; - priv.elements[i].length = (unsigned short) modulus->ulValueLen; - memmove(bufs[i], modulus->pValue, modulus->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; - priv.elements[i].length = (unsigned short) exponent->ulValueLen; - memmove(bufs[i], exponent->pValue, exponent->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - - if (d != NULL) { - priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; - priv.elements[i].length = (unsigned short) d->ulValueLen; - memmove(bufs[i], d->pValue, d->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (p != NULL) { - priv.elements[i].tag = TAG_RSA_PRIME1; - priv.elements[i].length = (unsigned short) p->ulValueLen; - memmove(bufs[i], p->pValue, p->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (q != NULL) { - priv.elements[i].tag = TAG_RSA_PRIME2; - priv.elements[i].length = (unsigned short) q->ulValueLen; - memmove(bufs[i], q->pValue, q->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (dmp1 != NULL) { - priv.elements[i].tag = TAG_RSA_EXPONENT1; - priv.elements[i].length = (unsigned short) dmp1->ulValueLen; - memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (dmq1 != NULL) { - priv.elements[i].tag = TAG_RSA_EXPONENT2; - priv.elements[i].length = (unsigned short) dmq1->ulValueLen; - memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (iqmp != NULL) { - priv.elements[i].tag = TAG_RSA_COEFFICIENT; - priv.elements[i].length = (unsigned short) iqmp->ulValueLen; - memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen); - priv.elements[i].data = bufs[i]; - i++; - } - - if (key->engine != NULL) { - priv.elements[i].tag = TAG_RSA_ENGINE; - priv.elements[i].length = - (unsigned short)strlen(key->engine) + 1; - priv.elements[i].data = (unsigned char *)key->engine; - i++; - } - - if (key->label != NULL) { - priv.elements[i].tag = TAG_RSA_LABEL; - priv.elements[i].length = - (unsigned short)strlen(key->label) + 1; - priv.elements[i].data = (unsigned char *)key->label; - i++; - } - - priv.nelements = i; - result = dst__privstruct_writefile(key, &priv, directory); - fail: - for (i = 0; i < 10; i++) { - if (bufs[i] == NULL) - break; - isc_safe_memwipe(bufs[i], modulus->ulValueLen); - isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); - } - return (result); -} - -static isc_result_t -pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, - dst_key_t *pub) -{ - CK_RV rv; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - CK_ATTRIBUTE *pubattr; - pk11_object_t *rsa; - pk11_object_t *pubrsa; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - unsigned int bits; - - if (label == NULL) - return (DST_R_NOENGINE); - - rsa = key->keydata.pkey; - pubrsa = pub->keydata.pkey; - - rsa->object = CK_INVALID_HANDLE; - rsa->ontoken = true; - rsa->reqlogon = true; - rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (rsa->repr == NULL) - return (ISC_R_NOMEMORY); - memset(rsa->repr, 0, sizeof(*attr) * 2); - rsa->attrcnt = 2; - attr = rsa->repr; - - attr->type = CKA_MODULUS; - pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); - INSIST(pubattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - attr++; - - attr->type = CKA_PUBLIC_EXPONENT; - pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); - INSIST(pubattr != NULL); - attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); - if (attr->pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); - attr->ulValueLen = pubattr->ulValueLen; - - ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - rsa->reqlogon, NULL, rsa->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(rsa, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(rsa, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - attr = pk11_attribute_bytype(rsa, CKA_MODULUS); - INSIST(attr != NULL); - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - return (ISC_R_SUCCESS); - - err: - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - - return (ret); -} - -static isc_result_t -rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) { - CK_ATTRIBUTE *pubattr, *privattr; - CK_BYTE *priv_exp = NULL, *priv_mod = NULL; - CK_BYTE *pub_exp = NULL, *pub_mod = NULL; - unsigned int priv_explen = 0, priv_modlen = 0; - unsigned int pub_explen = 0, pub_modlen = 0; - - REQUIRE(rsa != NULL && pubrsa != NULL); - - privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); - INSIST(privattr != NULL); - priv_exp = privattr->pValue; - priv_explen = privattr->ulValueLen; - - pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); - INSIST(pubattr != NULL); - pub_exp = pubattr->pValue; - pub_explen = pubattr->ulValueLen; - - if (priv_exp != NULL) { - if (priv_explen != pub_explen) - return (DST_R_INVALIDPRIVATEKEY); - if (!isc_safe_memequal(priv_exp, pub_exp, pub_explen)) - return (DST_R_INVALIDPRIVATEKEY); - } else { - privattr->pValue = pub_exp; - privattr->ulValueLen = pub_explen; - pubattr->pValue = NULL; - pubattr->ulValueLen = 0; - } - - if (privattr->pValue == NULL) - return (DST_R_INVALIDPRIVATEKEY); - - privattr = pk11_attribute_bytype(rsa, CKA_MODULUS); - INSIST(privattr != NULL); - priv_mod = privattr->pValue; - priv_modlen = privattr->ulValueLen; - - pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); - INSIST(pubattr != NULL); - pub_mod = pubattr->pValue; - pub_modlen = pubattr->ulValueLen; - - if (priv_mod != NULL) { - if (priv_modlen != pub_modlen) - return (DST_R_INVALIDPRIVATEKEY); - if (!isc_safe_memequal(priv_mod, pub_mod, pub_modlen)) - return (DST_R_INVALIDPRIVATEKEY); - } else { - privattr->pValue = pub_mod; - privattr->ulValueLen = pub_modlen; - pubattr->pValue = NULL; - pubattr->ulValueLen = 0; - } - - if (privattr->pValue == NULL) - return (DST_R_INVALIDPRIVATEKEY); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { - dst_private_t priv; - isc_result_t ret; - int i; - pk11_object_t *rsa; - CK_ATTRIBUTE *attr; - isc_mem_t *mctx = key->mctx; - const char *engine = NULL, *label = NULL; - unsigned int bits; - - /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); - - if (key->external) { - if (priv.nelements != 0) - DST_RET(DST_R_INVALIDPRIVATEKEY); - if (pub == NULL) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - key->keydata.pkey = pub->keydata.pkey; - pub->keydata.pkey = NULL; - key->key_size = pub->key_size; - - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - return (ISC_R_SUCCESS); - } - - for (i = 0; i < priv.nelements; i++) { - switch (priv.elements[i].tag) { - case TAG_RSA_ENGINE: - engine = (char *)priv.elements[i].data; - break; - case TAG_RSA_LABEL: - label = (char *)priv.elements[i].data; - break; - default: - break; - } - } - rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); - if (rsa == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(rsa, 0, sizeof(*rsa)); - key->keydata.pkey = rsa; - - /* Is this key is stored in a HSM? See if we can fetch it. */ - if ((label != NULL) || (engine != NULL)) { - ret = pkcs11rsa_fetch(key, engine, label, pub); - if (ret != ISC_R_SUCCESS) - goto err; - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); - } - - rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); - if (rsa->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(rsa->repr, 0, sizeof(*attr) * 8); - rsa->attrcnt = 8; - attr = rsa->repr; - attr[0].type = CKA_MODULUS; - attr[1].type = CKA_PUBLIC_EXPONENT; - attr[2].type = CKA_PRIVATE_EXPONENT; - attr[3].type = CKA_PRIME_1; - attr[4].type = CKA_PRIME_2; - attr[5].type = CKA_EXPONENT_1; - attr[6].type = CKA_EXPONENT_2; - attr[7].type = CKA_COEFFICIENT; - - for (i = 0; i < priv.nelements; i++) { - CK_BYTE *bn; - - switch (priv.elements[i].tag) { - case TAG_RSA_ENGINE: - continue; - case TAG_RSA_LABEL: - continue; - default: - bn = isc_mem_get(key->mctx, priv.elements[i].length); - if (bn == NULL) - DST_RET(ISC_R_NOMEMORY); - memmove(bn, priv.elements[i].data, - priv.elements[i].length); - } - - switch (priv.elements[i].tag) { - case TAG_RSA_MODULUS: - attr = pk11_attribute_bytype(rsa, CKA_MODULUS); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_PUBLICEXPONENT: - attr = pk11_attribute_bytype(rsa, - CKA_PUBLIC_EXPONENT); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_PRIVATEEXPONENT: - attr = pk11_attribute_bytype(rsa, - CKA_PRIVATE_EXPONENT); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_PRIME1: - attr = pk11_attribute_bytype(rsa, CKA_PRIME_1); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_PRIME2: - attr = pk11_attribute_bytype(rsa, CKA_PRIME_2); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_EXPONENT1: - attr = pk11_attribute_bytype(rsa, - CKA_EXPONENT_1); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_EXPONENT2: - attr = pk11_attribute_bytype(rsa, - CKA_EXPONENT_2); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - case TAG_RSA_COEFFICIENT: - attr = pk11_attribute_bytype(rsa, - CKA_COEFFICIENT); - INSIST(attr != NULL); - attr->pValue = bn; - attr->ulValueLen = priv.elements[i].length; - break; - } - } - - if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS) - DST_RET(DST_R_INVALIDPRIVATEKEY); - - attr = pk11_attribute_bytype(rsa, CKA_MODULUS); - INSIST(attr != NULL); - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); - INSIST(attr != NULL); - - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - if (bits > RSA_MAX_PUBEXP_BITS) { - DST_RET(ISC_R_RANGE); - } - - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - - return (ISC_R_SUCCESS); - - err: - pkcs11rsa_destroy(key); - dst__privstruct_free(&priv, mctx); - isc_safe_memwipe(&priv, sizeof(priv)); - return (ret); -} - -static isc_result_t -pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, - const char *pin) -{ - CK_RV rv; - CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_ATTRIBUTE searchTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG cnt; - CK_ATTRIBUTE *attr; - pk11_object_t *rsa; - pk11_context_t *pk11_ctx = NULL; - isc_result_t ret; - unsigned int i; - unsigned int bits; - - UNUSED(pin); - - rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); - if (rsa == NULL) - return (ISC_R_NOMEMORY); - memset(rsa, 0, sizeof(*rsa)); - rsa->object = CK_INVALID_HANDLE; - rsa->ontoken = true; - rsa->reqlogon = true; - key->keydata.pkey = rsa; - - rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); - if (rsa->repr == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(rsa->repr, 0, sizeof(*attr) * 2); - rsa->attrcnt = 2; - attr = rsa->repr; - attr[0].type = CKA_MODULUS; - attr[1].type = CKA_PUBLIC_EXPONENT; - - ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); - if (ret != ISC_R_SUCCESS) - goto err; - - pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, - sizeof(*pk11_ctx)); - if (pk11_ctx == NULL) - DST_RET(ISC_R_NOMEMORY); - ret = pk11_get_session(pk11_ctx, OP_RSA, true, false, - rsa->reqlogon, NULL, rsa->slot); - if (ret != ISC_R_SUCCESS) - goto err; - - attr = pk11_attribute_bytype(rsa, CKA_LABEL); - if (attr == NULL) { - attr = pk11_attribute_bytype(rsa, CKA_ID); - INSIST(attr != NULL); - searchTemplate[3].type = CKA_ID; - } - searchTemplate[3].pValue = attr->pValue; - searchTemplate[3].ulValueLen = attr->ulValueLen; - - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - attr = rsa->repr; - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - for (i = 0; i <= 1; i++) { - attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); - if (attr[i].pValue == NULL) - DST_RET(ISC_R_NOMEMORY); - memset(attr[i].pValue, 0, attr[i].ulValueLen); - } - PK11_RET(pkcs_C_GetAttributeValue, - (pk11_ctx->session, hKey, attr, 2), - DST_R_CRYPTOFAILURE); - - keyClass = CKO_PRIVATE_KEY; - PK11_RET(pkcs_C_FindObjectsInit, - (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), - DST_R_CRYPTOFAILURE); - PK11_RET(pkcs_C_FindObjects, - (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), - DST_R_CRYPTOFAILURE); - (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); - if (cnt == 0) - DST_RET(ISC_R_NOTFOUND); - if (cnt > 1) - DST_RET(ISC_R_EXISTS); - - if (engine != NULL) { - key->engine = isc_mem_strdup(key->mctx, engine); - if (key->engine == NULL) - DST_RET(ISC_R_NOMEMORY); - } - - key->label = isc_mem_strdup(key->mctx, label); - if (key->label == NULL) - DST_RET(ISC_R_NOMEMORY); - - attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); - INSIST(attr != NULL); - - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - if (bits > RSA_MAX_PUBEXP_BITS) { - DST_RET(ISC_R_RANGE); - } - - attr = pk11_attribute_bytype(rsa, CKA_MODULUS); - INSIST(attr != NULL); - ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); - if (ret != ISC_R_SUCCESS) { - goto err; - } - key->key_size = bits; - - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - - return (ISC_R_SUCCESS); - - err: - pkcs11rsa_destroy(key); - if (pk11_ctx != NULL) { - pk11_return_session(pk11_ctx); - isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); - isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); - } - - return (ret); -} - -static dst_func_t pkcs11rsa_functions = { - pkcs11rsa_createctx, -#ifndef PK11_RSA_PKCS_REPLACE - pkcs11rsa_createctx2, -#else - NULL, /*%< createctx2 */ -#endif - pkcs11rsa_destroyctx, - pkcs11rsa_adddata, - pkcs11rsa_sign, - pkcs11rsa_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - pkcs11rsa_compare, - NULL, /*%< paramcompare */ - pkcs11rsa_generate, - pkcs11rsa_isprivate, - pkcs11rsa_destroy, - pkcs11rsa_todns, - pkcs11rsa_fromdns, - pkcs11rsa_tofile, - pkcs11rsa_parse, - NULL, /*%< cleanup */ - pkcs11rsa_fromlabel, - NULL, /*%< dump */ - NULL, /*%< restore */ -}; - -isc_result_t -dst__pkcs11rsa_init(dst_func_t **funcp, unsigned char algorithm) { - REQUIRE(funcp != NULL); - - if (*funcp == NULL) { - switch (algorithm) { -#ifndef PK11_MD5_DISABLE - case DST_ALG_RSAMD5: - if (isc_md5_available()) - *funcp = &pkcs11rsa_functions; - break; -#endif - default: - *funcp = &pkcs11rsa_functions; - break; - } - } - return (ISC_R_SUCCESS); -} - -#else /* PKCS11CRYPTO */ - -#include - -EMPTY_TRANSLATION_UNIT - -#endif /* PKCS11CRYPTO */ -/*! \file */ diff --git a/lib/dns-pkcs11/portlist.c b/lib/dns-pkcs11/portlist.c deleted file mode 100644 index e34a6a9..0000000 --- a/lib/dns-pkcs11/portlist.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T') -#define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC) - -typedef struct dns_element { - in_port_t port; - uint16_t flags; -} dns_element_t; - -struct dns_portlist { - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t refcount; - isc_mutex_t lock; - dns_element_t *list; - unsigned int allocated; - unsigned int active; -}; - -#define DNS_PL_INET 0x0001 -#define DNS_PL_INET6 0x0002 -#define DNS_PL_ALLOCATE 16 - -static int -compare(const void *arg1, const void *arg2) { - const dns_element_t *e1 = (const dns_element_t *)arg1; - const dns_element_t *e2 = (const dns_element_t *)arg2; - - if (e1->port < e2->port) - return (-1); - if (e1->port > e2->port) - return (1); - return (0); -} - -isc_result_t -dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) { - dns_portlist_t *portlist; - isc_result_t result; - - REQUIRE(portlistp != NULL && *portlistp == NULL); - - portlist = isc_mem_get(mctx, sizeof(*portlist)); - if (portlist == NULL) - return (ISC_R_NOMEMORY); - result = isc_mutex_init(&portlist->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, portlist, sizeof(*portlist)); - return (result); - } - result = isc_refcount_init(&portlist->refcount, 1); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&portlist->lock); - isc_mem_put(mctx, portlist, sizeof(*portlist)); - return (result); - } - portlist->list = NULL; - portlist->allocated = 0; - portlist->active = 0; - portlist->mctx = NULL; - isc_mem_attach(mctx, &portlist->mctx); - portlist->magic = DNS_PORTLIST_MAGIC; - *portlistp = portlist; - return (ISC_R_SUCCESS); -} - -static dns_element_t * -find_port(dns_element_t *list, unsigned int len, in_port_t port) { - unsigned int xtry = len / 2; - unsigned int min = 0; - unsigned int max = len - 1; - unsigned int last = len; - - for (;;) { - if (list[xtry].port == port) - return (&list[xtry]); - if (port > list[xtry].port) { - if (xtry == max) - break; - min = xtry; - xtry = xtry + (max - xtry + 1) / 2; - INSIST(xtry <= max); - if (xtry == last) - break; - last = min; - } else { - if (xtry == min) - break; - max = xtry; - xtry = xtry - (xtry - min + 1) / 2; - INSIST(xtry >= min); - if (xtry == last) - break; - last = max; - } - } - return (NULL); -} - -isc_result_t -dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) { - dns_element_t *el; - isc_result_t result; - - REQUIRE(DNS_VALID_PORTLIST(portlist)); - REQUIRE(af == AF_INET || af == AF_INET6); - - LOCK(&portlist->lock); - if (portlist->active != 0) { - el = find_port(portlist->list, portlist->active, port); - if (el != NULL) { - if (af == AF_INET) - el->flags |= DNS_PL_INET; - else - el->flags |= DNS_PL_INET6; - result = ISC_R_SUCCESS; - goto unlock; - } - } - - if (portlist->allocated <= portlist->active) { - unsigned int allocated; - allocated = portlist->allocated + DNS_PL_ALLOCATE; - el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated); - if (el == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - if (portlist->list != NULL) { - memmove(el, portlist->list, - portlist->allocated * sizeof(*el)); - isc_mem_put(portlist->mctx, portlist->list, - portlist->allocated * sizeof(*el)); - } - portlist->list = el; - portlist->allocated = allocated; - } - portlist->list[portlist->active].port = port; - if (af == AF_INET) - portlist->list[portlist->active].flags = DNS_PL_INET; - else - portlist->list[portlist->active].flags = DNS_PL_INET6; - portlist->active++; - qsort(portlist->list, portlist->active, sizeof(*el), compare); - result = ISC_R_SUCCESS; - unlock: - UNLOCK(&portlist->lock); - return (result); -} - -void -dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) { - dns_element_t *el; - - REQUIRE(DNS_VALID_PORTLIST(portlist)); - REQUIRE(af == AF_INET || af == AF_INET6); - - LOCK(&portlist->lock); - if (portlist->active != 0) { - el = find_port(portlist->list, portlist->active, port); - if (el != NULL) { - if (af == AF_INET) - el->flags &= ~DNS_PL_INET; - else - el->flags &= ~DNS_PL_INET6; - if (el->flags == 0) { - *el = portlist->list[portlist->active]; - portlist->active--; - qsort(portlist->list, portlist->active, - sizeof(*el), compare); - } - } - } - UNLOCK(&portlist->lock); -} - -bool -dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) { - dns_element_t *el; - bool result = false; - - REQUIRE(DNS_VALID_PORTLIST(portlist)); - REQUIRE(af == AF_INET || af == AF_INET6); - LOCK(&portlist->lock); - if (portlist->active != 0) { - el = find_port(portlist->list, portlist->active, port); - if (el != NULL) { - if (af == AF_INET && (el->flags & DNS_PL_INET) != 0) - result = true; - if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0) - result = true; - } - } - UNLOCK(&portlist->lock); - return (result); -} - -void -dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) { - - REQUIRE(DNS_VALID_PORTLIST(portlist)); - REQUIRE(portlistp != NULL && *portlistp == NULL); - - isc_refcount_increment(&portlist->refcount, NULL); - *portlistp = portlist; -} - -void -dns_portlist_detach(dns_portlist_t **portlistp) { - dns_portlist_t *portlist; - unsigned int count; - - REQUIRE(portlistp != NULL); - portlist = *portlistp; - REQUIRE(DNS_VALID_PORTLIST(portlist)); - *portlistp = NULL; - isc_refcount_decrement(&portlist->refcount, &count); - if (count == 0) { - portlist->magic = 0; - isc_refcount_destroy(&portlist->refcount); - if (portlist->list != NULL) - isc_mem_put(portlist->mctx, portlist->list, - portlist->allocated * - sizeof(*portlist->list)); - DESTROYLOCK(&portlist->lock); - isc_mem_putanddetach(&portlist->mctx, portlist, - sizeof(*portlist)); - } -} diff --git a/lib/dns-pkcs11/private.c b/lib/dns-pkcs11/private.c deleted file mode 100644 index 7b40a4f..0000000 --- a/lib/dns-pkcs11/private.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * We need to build the relevant chain if there exists a NSEC/NSEC3PARAM - * at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist. - * - * If a NSEC3PARAM RRset exists then we will need to build a NSEC chain - * if all the NSEC3PARAM records (and associated chains) are slated for - * destruction and we have not been told to NOT build the NSEC chain. - * - * If the NSEC set exist then check to see if there is a request to create - * a NSEC3 chain. - * - * If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private - * type exists then we need to examine it to determine if NSEC3 chain has - * been requested to be built otherwise a NSEC chain needs to be built. - */ - -#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) -#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) -#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) -#define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0) - -#define CHECK(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - -/* - * Work out if 'param' should be ignored or not (i.e. it is in the process - * of being removed). - * - * Note: we 'belt-and-braces' here by also checking for a CREATE private - * record and keep the param record in this case. - */ - -static bool -ignore(dns_rdata_t *param, dns_rdataset_t *privateset) { - isc_result_t result; - - for (result = dns_rdataset_first(privateset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(privateset)) { - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t private = DNS_RDATA_INIT; - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(privateset, &private); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) - continue; - /* - * We are going to create a new NSEC3 chain so it - * doesn't matter if we are removing this one. - */ - if (CREATE(rdata.data[1])) - return (false); - if (rdata.data[0] != param->data[0] || - rdata.data[2] != param->data[2] || - rdata.data[3] != param->data[3] || - rdata.data[4] != param->data[4] || - memcmp(&rdata.data[5], ¶m->data[5], param->data[4])) - continue; - /* - * The removal of this NSEC3 chain does NOT cause a - * NSEC chain to be created so we don't need to tell - * the caller that it will be removed. - */ - if (NONSEC(rdata.data[1])) - return (false); - return (true); - } - return (false); -} - -isc_result_t -dns_private_chains(dns_db_t *db, dns_dbversion_t *ver, - dns_rdatatype_t privatetype, - bool *build_nsec, bool *build_nsec3) -{ - dns_dbnode_t *node; - dns_rdataset_t nsecset, nsec3paramset, privateset; - bool nsec3chain; - bool signing; - isc_result_t result; - unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; - unsigned int count; - - node = NULL; - dns_rdataset_init(&nsecset); - dns_rdataset_init(&nsec3paramset); - dns_rdataset_init(&privateset); - - CHECK(dns_db_getoriginnode(db, &node)); - - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, - 0, (isc_stdtime_t) 0, &nsecset, NULL); - - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto failure; - - result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, - 0, (isc_stdtime_t) 0, &nsec3paramset, - NULL); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto failure; - - if (dns_rdataset_isassociated(&nsecset) && - dns_rdataset_isassociated(&nsec3paramset)) { - if (build_nsec != NULL) - *build_nsec = true; - if (build_nsec3 != NULL) - *build_nsec3 = true; - goto success; - } - - if (privatetype != (dns_rdatatype_t)0) { - result = dns_db_findrdataset(db, node, ver, privatetype, - 0, (isc_stdtime_t) 0, - &privateset, NULL); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto failure; - } - - /* - * Look to see if we also need to be creating a NSEC3 chain. - */ - if (dns_rdataset_isassociated(&nsecset)) { - if (build_nsec != NULL) - *build_nsec = true; - if (build_nsec3 != NULL) - *build_nsec3 = false; - if (!dns_rdataset_isassociated(&privateset)) - goto success; - for (result = dns_rdataset_first(&privateset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&privateset)) { - dns_rdata_t private = DNS_RDATA_INIT; - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&privateset, &private); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) - continue; - if (REMOVE(rdata.data[1])) - continue; - if (build_nsec3 != NULL) - *build_nsec3 = true; - break; - } - goto success; - } - - if (dns_rdataset_isassociated(&nsec3paramset)) { - if (build_nsec3 != NULL) - *build_nsec3 = true; - if (build_nsec != NULL) - *build_nsec = false; - if (!dns_rdataset_isassociated(&privateset)) - goto success; - /* - * If we are in the process of building a new NSEC3 chain - * then we don't need to build a NSEC chain. - */ - for (result = dns_rdataset_first(&privateset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&privateset)) { - dns_rdata_t private = DNS_RDATA_INIT; - dns_rdata_t rdata = DNS_RDATA_INIT; - - dns_rdataset_current(&privateset, &private); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) - continue; - if (CREATE(rdata.data[1])) - goto success; - } - - /* - * Check to see if there will be a active NSEC3CHAIN once - * the changes queued complete. - */ - count = 0; - for (result = dns_rdataset_first(&nsec3paramset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&nsec3paramset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - /* - * If there is more that one NSEC3 chain present then - * we don't need to construct a NSEC chain. - */ - if (++count > 1) - goto success; - dns_rdataset_current(&nsec3paramset, &rdata); - if (ignore(&rdata, &privateset)) - continue; - /* - * We still have a good NSEC3 chain or we are - * not creating a NSEC chain as NONSEC is set. - */ - goto success; - } - - /* - * The last NSEC3 chain is being removed and does not have - * have NONSEC set. - */ - if (build_nsec != NULL) - *build_nsec = true; - goto success; - } - - if (build_nsec != NULL) - *build_nsec = false; - if (build_nsec3 != NULL) - *build_nsec3 = false; - if (!dns_rdataset_isassociated(&privateset)) - goto success; - - signing = false; - nsec3chain = false; - - for (result = dns_rdataset_first(&privateset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&privateset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_t private = DNS_RDATA_INIT; - - dns_rdataset_current(&privateset, &private); - if (!dns_nsec3param_fromprivate(&private, &rdata, - buf, sizeof(buf))) { - /* - * Look for record that says we are signing the - * zone with a key. - */ - if (private.length == 5 && private.data[0] != 0 && - private.data[3] == 0 && private.data[4] == 0) - signing = true; - } else { - if (CREATE(rdata.data[1])) - nsec3chain = true; - } - } - - if (signing) { - if (nsec3chain) { - if (build_nsec3 != NULL) - *build_nsec3 = true; - } else { - if (build_nsec != NULL) - *build_nsec = true; - } - } - - success: - result = ISC_R_SUCCESS; - failure: - if (dns_rdataset_isassociated(&nsecset)) - dns_rdataset_disassociate(&nsecset); - if (dns_rdataset_isassociated(&nsec3paramset)) - dns_rdataset_disassociate(&nsec3paramset); - if (dns_rdataset_isassociated(&privateset)) - dns_rdataset_disassociate(&privateset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -isc_result_t -dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) { - isc_result_t result; - - if (private->length < 5) - return (ISC_R_NOTFOUND); - - if (private->data[0] == 0) { - unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE]; - unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE]; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3param_t nsec3param; - bool del, init, nonsec; - isc_buffer_t b; - - if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf, - sizeof(nsec3buf))) - CHECK(ISC_R_FAILURE); - - CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - - del = ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0); - init = ((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0); - nonsec = ((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0); - - nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE| - DNS_NSEC3FLAG_REMOVE| - DNS_NSEC3FLAG_INITIAL| - DNS_NSEC3FLAG_NONSEC); - - if (init) - isc_buffer_putstr(buf, "Pending NSEC3 chain "); - else if (del) - isc_buffer_putstr(buf, "Removing NSEC3 chain "); - else - isc_buffer_putstr(buf, "Creating NSEC3 chain "); - - dns_rdata_reset(&rdata); - isc_buffer_init(&b, newbuf, sizeof(newbuf)); - CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in, - dns_rdatatype_nsec3param, - &nsec3param, &b)); - - CHECK(dns_rdata_totext(&rdata, NULL, buf)); - - if (del && !nonsec) - isc_buffer_putstr(buf, " / creating NSEC chain"); - } else if (private->length == 5) { - unsigned char alg = private->data[0]; - dns_keytag_t keyid = (private->data[2] | private->data[1] << 8); - char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE]; - bool del = (private->data[3] != 0); - bool complete = (private->data[4] != 0); - - if (del && complete) - isc_buffer_putstr(buf, "Done removing signatures for "); - else if (del) - isc_buffer_putstr(buf, "Removing signatures for "); - else if (complete) - isc_buffer_putstr(buf, "Done signing with "); - else - isc_buffer_putstr(buf, "Signing with "); - - dns_secalg_format(alg, algbuf, sizeof(algbuf)); - snprintf(keybuf, sizeof(keybuf), "key %d/%s", keyid, algbuf); - isc_buffer_putstr(buf, keybuf); - } else - return (ISC_R_NOTFOUND); - - isc_buffer_putuint8(buf, 0); - result = ISC_R_SUCCESS; - failure: - return (result); -} diff --git a/lib/dns-pkcs11/rbt.c b/lib/dns-pkcs11/rbt.c deleted file mode 100644 index b9a3541..0000000 --- a/lib/dns-pkcs11/rbt.c +++ /dev/null @@ -1,3701 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include /* uintptr_t */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*% - * This define is so dns/name.h (included by dns/fixedname.h) uses more - * efficient macro calls instead of functions for a few operations. - */ -#define DNS_NAME_USEINLINE 1 - -#include -#include -#include -#include -#include - -#include - -#define CHECK(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -#define RBT_MAGIC ISC_MAGIC('R', 'B', 'T', '+') -#define VALID_RBT(rbt) ISC_MAGIC_VALID(rbt, RBT_MAGIC) - -/* - * XXXDCL Since parent pointers were added in again, I could remove all of the - * chain junk, and replace with dns_rbt_firstnode, _previousnode, _nextnode, - * _lastnode. This would involve pretty major change to the API. - */ -#define CHAIN_MAGIC ISC_MAGIC('0', '-', '0', '-') -#define VALID_CHAIN(chain) ISC_MAGIC_VALID(chain, CHAIN_MAGIC) - -#define RBT_HASH_SIZE 64 - -#ifdef RBT_MEM_TEST -#undef RBT_HASH_SIZE -#define RBT_HASH_SIZE 2 /*%< To give the reallocation code a workout. */ -#endif - -struct dns_rbt { - unsigned int magic; - isc_mem_t * mctx; - dns_rbtnode_t * root; - void (*data_deleter)(void *, void *); - void * deleter_arg; - unsigned int nodecount; - size_t hashsize; - dns_rbtnode_t ** hashtable; - void * mmap_location; -}; - -#define RED 0 -#define BLACK 1 - -/* - * This is the header for map-format RBT images. It is populated, - * and then written, as the LAST thing done to the file before returning. - * Writing this last (with zeros in the header area initially) will ensure - * that the header is only valid when the RBT image is also valid. - */ -typedef struct file_header file_header_t; - -/* Pad to 32 bytes */ -static char FILE_VERSION[32] = "\0"; - -/* Header length, always the same size regardless of structure size */ -#define HEADER_LENGTH 1024 - -struct file_header { - char version1[32]; - uint64_t first_node_offset; /* usually 1024 */ - /* - * information about the system on which the map file was generated - * will be used to tell if we can load the map file or not - */ - uint32_t ptrsize; - unsigned int bigendian:1; /* big or little endian system */ - unsigned int rdataset_fixed:1; /* compiled with --enable-rrset-fixed */ - unsigned int nodecount; /* shadow from rbt structure */ - uint64_t crc; - char version2[32]; /* repeated; must match version1 */ -}; - -/* - * The following declarations are for the serialization of an RBT: - * - * step one: write out a zeroed header of 1024 bytes - * step two: walk the tree in a depth-first, left-right-down order, writing - * out the nodes, reserving space as we go, correcting addresses to point - * at the proper offset in the file, and setting a flag for each pointer to - * indicate that it is a reference to a location in the file, rather than in - * memory. - * step three: write out the header, adding the information that will be - * needed to re-create the tree object itself. - * - * The RBTDB object will do this three times, once for each of the three - * RBT objects it contains. - * - * Note: 'file' must point an actual open file that can be mmapped - * and fseeked, not to a pipe or stream - */ - -static isc_result_t -dns_rbt_zero_header(FILE *file); - -static isc_result_t -write_header(FILE *file, dns_rbt_t *rbt, uint64_t first_node_offset, - uint64_t crc); - -static bool -match_header_version(file_header_t *header); - -static isc_result_t -serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left, - uintptr_t right, uintptr_t down, uintptr_t parent, - uintptr_t data, uint64_t *crc); - -static isc_result_t -serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent, - dns_rbtdatawriter_t datawriter, void *writer_arg, - uintptr_t *where, uint64_t *crc); -/* - * The following functions allow you to get the actual address of a pointer - * without having to use an if statement to check to see if that address is - * relative or not - */ -static inline dns_rbtnode_t * -getparent(dns_rbtnode_t *node, file_header_t *header) { - char *adjusted_address = (char *)(node->parent); - adjusted_address += node->parent_is_relative * (uintptr_t)header; - - return ((dns_rbtnode_t *)adjusted_address); -} - -static inline dns_rbtnode_t * -getleft(dns_rbtnode_t *node, file_header_t *header) { - char *adjusted_address = (char *)(node->left); - adjusted_address += node->left_is_relative * (uintptr_t)header; - - return ((dns_rbtnode_t *)adjusted_address); -} - -static inline dns_rbtnode_t * -getright(dns_rbtnode_t *node, file_header_t *header) { - char *adjusted_address = (char *)(node->right); - adjusted_address += node->right_is_relative * (uintptr_t)header; - - return ((dns_rbtnode_t *)adjusted_address); -} - -static inline dns_rbtnode_t * -getdown(dns_rbtnode_t *node, file_header_t *header) { - char *adjusted_address = (char *)(node->down); - adjusted_address += node->down_is_relative * (uintptr_t)header; - - return ((dns_rbtnode_t *)adjusted_address); -} - -static inline dns_rbtnode_t * -getdata(dns_rbtnode_t *node, file_header_t *header) { - char *adjusted_address = (char *)(node->data); - adjusted_address += node->data_is_relative * (uintptr_t)header; - - return ((dns_rbtnode_t *)adjusted_address); -} - -/*% - * Elements of the rbtnode structure. - */ -#define PARENT(node) ((node)->parent) -#define LEFT(node) ((node)->left) -#define RIGHT(node) ((node)->right) -#define DOWN(node) ((node)->down) -#ifdef DNS_RBT_USEHASH -#define UPPERNODE(node) ((node)->uppernode) -#endif /* DNS_RBT_USEHASH */ -#define DATA(node) ((node)->data) -#define IS_EMPTY(node) ((node)->data == NULL) -#define HASHNEXT(node) ((node)->hashnext) -#define HASHVAL(node) ((node)->hashval) -#define COLOR(node) ((node)->color) -#define NAMELEN(node) ((node)->namelen) -#define OLDNAMELEN(node) ((node)->oldnamelen) -#define OFFSETLEN(node) ((node)->offsetlen) -#define ATTRS(node) ((node)->attributes) -#define IS_ROOT(node) ((node)->is_root == 1) -#define FINDCALLBACK(node) ((node)->find_callback == 1) - -#define WANTEMPTYDATA_OR_DATA(options, node) \ - ((options & DNS_RBTFIND_EMPTYDATA) != 0 || DATA(node) != NULL) - -/*% - * Structure elements from the rbtdb.c, not - * used as part of the rbt.c algorithms. - */ -#define DIRTY(node) ((node)->dirty) -#define WILD(node) ((node)->wild) -#define LOCKNUM(node) ((node)->locknum) - -/*% - * The variable length stuff stored after the node has the following - * structure. - * - * <name_data>{1..255}<oldoffsetlen>{1}<offsets>{1..128} - * - * <name_data> contains the name of the node when it was created. - * <oldoffsetlen> contains the length of <offsets> when the node was created. - * <offsets> contains the offsets into name for each label when the node was - * created. - */ - -#define NAME(node) ((unsigned char *)((node) + 1)) -#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1) -#define OLDOFFSETLEN(node) (OFFSETS(node)[-1]) - -#define NODE_SIZE(node) (sizeof(*node) + \ - OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1) - -/*% - * Color management. - */ -#define IS_RED(node) ((node) != NULL && (node)->color == RED) -#define IS_BLACK(node) ((node) == NULL || (node)->color == BLACK) -#define MAKE_RED(node) ((node)->color = RED) -#define MAKE_BLACK(node) ((node)->color = BLACK) - -/*% - * Chain management. - * - * The "ancestors" member of chains were removed, with their job now - * being wholly handled by parent pointers (which didn't exist, because - * of memory concerns, when chains were first implemented). - */ -#define ADD_LEVEL(chain, node) \ - do { \ - INSIST((chain)->level_count < DNS_RBT_LEVELBLOCK); \ - (chain)->levels[(chain)->level_count++] = (node); \ - } while (0) - -/*% - * The following macros directly access normally private name variables. - * These macros are used to avoid a lot of function calls in the critical - * path of the tree traversal code. - */ - -static inline void -NODENAME(dns_rbtnode_t *node, dns_name_t *name) { - name->length = NAMELEN(node); - name->labels = OFFSETLEN(node); - name->ndata = NAME(node); - name->offsets = OFFSETS(node); - name->attributes = ATTRS(node); - name->attributes |= DNS_NAMEATTR_READONLY; -} - -void -dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name) { - name->length = NAMELEN(node); - name->labels = OFFSETLEN(node); - name->ndata = NAME(node); - name->offsets = OFFSETS(node); - name->attributes = ATTRS(node); - name->attributes |= DNS_NAMEATTR_READONLY; -} - -dns_rbtnode_t * -dns_rbt_root(dns_rbt_t *rbt) { - return rbt->root; -} - -#ifdef DNS_RBT_USEHASH -static isc_result_t -inithash(dns_rbt_t *rbt); -#endif - -#ifdef DEBUG -#define inline -/* - * A little something to help out in GDB. - */ -dns_name_t Name(dns_rbtnode_t *node); -dns_name_t -Name(dns_rbtnode_t *node) { - dns_name_t name; - - dns_name_init(&name, NULL); - if (node != NULL) - NODENAME(node, &name); - - return (name); -} - -static void -hexdump(const char *desc, unsigned char *data, size_t size) { - char hexdump[BUFSIZ * 2 + 1]; - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - size_t bytes; - - fprintf(stderr, "%s: ", desc); - do { - isc_buffer_init(&b, hexdump, sizeof(hexdump)); - r.base = data; - r.length = bytes = (size > BUFSIZ) ? BUFSIZ : size; - result = isc_hex_totext(&r, 0, "", &b); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_putuint8(&b, 0); - fprintf(stderr, "%s", hexdump); - data += bytes; - size -= bytes; - } while (size > 0); - fprintf(stderr, "\n"); -} -#endif /* DEBUG */ - -#ifdef DNS_RBT_USEHASH - -/* - * Upper node is the parent of the root of the passed node's - * subtree. The passed node must not be NULL. - */ -static inline dns_rbtnode_t * -get_upper_node(dns_rbtnode_t *node) { - return (UPPERNODE(node)); -} - -static void -fixup_uppernodes_helper(dns_rbtnode_t *node, dns_rbtnode_t *uppernode) { - if (node == NULL) - return; - - UPPERNODE(node) = uppernode; - - fixup_uppernodes_helper(LEFT(node), uppernode); - fixup_uppernodes_helper(RIGHT(node), uppernode); - fixup_uppernodes_helper(DOWN(node), node); -} - -/* - * This function is used to fixup uppernode members of all dns_rbtnodes - * after deserialization. - */ -static void -fixup_uppernodes(dns_rbt_t *rbt) { - fixup_uppernodes_helper(rbt->root, NULL); -} - -#else - -/* The passed node must not be NULL. */ -static inline dns_rbtnode_t * -get_subtree_root(dns_rbtnode_t *node) { - while (!IS_ROOT(node)) { - node = PARENT(node); - } - - return (node); -} - -/* Upper node is the parent of the root of the passed node's - * subtree. The passed node must not be NULL. - */ -static inline dns_rbtnode_t * -get_upper_node(dns_rbtnode_t *node) { - dns_rbtnode_t *root = get_subtree_root(node); - - /* - * Return the node in the level above the argument node that points - * to the level the argument node is in. If the argument node is in - * the top level, the return value is NULL. - */ - return (PARENT(root)); -} - -#endif /* DNS_RBT_USEHASH */ - -size_t -dns__rbtnode_getdistance(dns_rbtnode_t *node) { - size_t nodes = 1; - - while (node != NULL) { - if (IS_ROOT(node)) - break; - nodes++; - node = PARENT(node); - } - - return (nodes); -} - -/* - * Forward declarations. - */ -static isc_result_t -create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep); - -#ifdef DNS_RBT_USEHASH -static inline void -hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name); -static inline void -unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node); -static void -rehash(dns_rbt_t *rbt, unsigned int newcount); -#else -#define hash_node(rbt, node, name) -#define unhash_node(rbt, node) -#define rehash(rbt, newcount) -#endif - -static inline void -rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp); -static inline void -rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp); - -static void -addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order, - dns_rbtnode_t **rootp); - -static void -deletefromlevel(dns_rbtnode_t *item, dns_rbtnode_t **rootp); - -static isc_result_t -treefix(dns_rbt_t *rbt, void *base, size_t size, - dns_rbtnode_t *n, dns_name_t *name, - dns_rbtdatafixer_t datafixer, void *fixer_arg, - uint64_t *crc); - -static void -deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, bool unhash, - dns_rbtnode_t **nodep); - -static void -printnodename(dns_rbtnode_t *node, bool quoted, FILE *f); - -static void -freenode(dns_rbt_t *rbt, dns_rbtnode_t **nodep); - -static isc_result_t -dns_rbt_zero_header(FILE *file) { - /* - * Write out a zeroed header as a placeholder. Doing this ensures - * that the file will not read while it is partially written, should - * writing fail or be interrupted. - */ - char buffer[HEADER_LENGTH]; - isc_result_t result; - - memset(buffer, 0, HEADER_LENGTH); - result = isc_stdio_write(buffer, 1, HEADER_LENGTH, file, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - result = fflush(file); - if (result != ISC_R_SUCCESS) - return (result); - - return (ISC_R_SUCCESS); -} - -static isc_once_t once = ISC_ONCE_INIT; - -static void -init_file_version(void) { - int n; - - memset(FILE_VERSION, 0, sizeof(FILE_VERSION)); - n = snprintf(FILE_VERSION, sizeof(FILE_VERSION), - "RBT Image %s %s", dns_major, dns_mapapi); - INSIST(n > 0 && (unsigned int)n < sizeof(FILE_VERSION)); -} - -/* - * Write out the real header, including NodeDump version information - * and the offset of the first node. - * - * Any information stored in the rbt object itself should be stored - * here. - */ -static isc_result_t -write_header(FILE *file, dns_rbt_t *rbt, uint64_t first_node_offset, - uint64_t crc) -{ - file_header_t header; - isc_result_t result; - off_t location; - - RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS); - - memset(&header, 0, sizeof(file_header_t)); - memmove(header.version1, FILE_VERSION, sizeof(header.version1)); - memmove(header.version2, FILE_VERSION, sizeof(header.version2)); - header.first_node_offset = first_node_offset; - header.ptrsize = (uint32_t) sizeof(void *); - header.bigendian = (1 == htonl(1)) ? 1 : 0; - -#ifdef DNS_RDATASET_FIXED - header.rdataset_fixed = 1; -#else - header.rdataset_fixed = 0; -#endif - - header.nodecount = rbt->nodecount; - - header.crc = crc; - - CHECK(isc_stdio_tell(file, &location)); - location = dns_rbt_serialize_align(location); - CHECK(isc_stdio_seek(file, location, SEEK_SET)); - CHECK(isc_stdio_write(&header, 1, sizeof(file_header_t), file, NULL)); - CHECK(fflush(file)); - - /* Ensure we are always at the end of the file. */ - CHECK(isc_stdio_seek(file, 0, SEEK_END)); - - cleanup: - return (result); -} - -static bool -match_header_version(file_header_t *header) { - RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS); - - if (memcmp(header->version1, FILE_VERSION, - sizeof(header->version1)) != 0 || - memcmp(header->version2, FILE_VERSION, - sizeof(header->version1)) != 0) - { - return (false); - } - - return (true); -} - -static isc_result_t -serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left, - uintptr_t right, uintptr_t down, uintptr_t parent, - uintptr_t data, uint64_t *crc) -{ - dns_rbtnode_t temp_node; - off_t file_position; - unsigned char *node_data; - size_t datasize; - isc_result_t result; -#ifdef DEBUG - dns_name_t nodename; -#endif - - INSIST(node != NULL); - - CHECK(isc_stdio_tell(file, &file_position)); - file_position = dns_rbt_serialize_align(file_position); - CHECK(isc_stdio_seek(file, file_position, SEEK_SET)); - - temp_node = *node; - temp_node.down_is_relative = 0; - temp_node.left_is_relative = 0; - temp_node.right_is_relative = 0; - temp_node.parent_is_relative = 0; - temp_node.data_is_relative = 0; - temp_node.is_mmapped = 1; - - /* - * If the next node is not NULL, calculate the next node's location - * in the file. Note that this will have to change when the data - * structure changes, and it also assumes that we always write the - * nodes out in list order (which we currently do.) - */ - if (temp_node.parent != NULL) { - temp_node.parent = (dns_rbtnode_t *)(parent); - temp_node.parent_is_relative = 1; - } - if (temp_node.left != NULL) { - temp_node.left = (dns_rbtnode_t *)(left); - temp_node.left_is_relative = 1; - } - if (temp_node.right != NULL) { - temp_node.right = (dns_rbtnode_t *)(right); - temp_node.right_is_relative = 1; - } - if (temp_node.down != NULL) { - temp_node.down = (dns_rbtnode_t *)(down); - temp_node.down_is_relative = 1; - } - if (temp_node.data != NULL) { - temp_node.data = (dns_rbtnode_t *)(data); - temp_node.data_is_relative = 1; - } - - node_data = (unsigned char *) node + sizeof(dns_rbtnode_t); - datasize = NODE_SIZE(node) - sizeof(dns_rbtnode_t); - - CHECK(isc_stdio_write(&temp_node, 1, sizeof(dns_rbtnode_t), - file, NULL)); - CHECK(isc_stdio_write(node_data, 1, datasize, file, NULL)); - -#ifdef DEBUG - dns_name_init(&nodename, NULL); - NODENAME(node, &nodename); - fprintf(stderr, "serialize "); - dns_name_print(&nodename, stderr); - fprintf(stderr, "\n"); - hexdump("node header", (unsigned char*) &temp_node, - sizeof(dns_rbtnode_t)); - hexdump("node data", node_data, datasize); -#endif - - isc_crc64_update(crc, (const uint8_t *) &temp_node, - sizeof(dns_rbtnode_t)); - isc_crc64_update(crc, (const uint8_t *) node_data, datasize); - - cleanup: - return (result); -} - -static isc_result_t -serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent, - dns_rbtdatawriter_t datawriter, void *writer_arg, - uintptr_t *where, uint64_t *crc) -{ - uintptr_t left = 0, right = 0, down = 0, data = 0; - off_t location = 0, offset_adjust; - isc_result_t result; - - if (node == NULL) { - if (where != NULL) - *where = 0; - return (ISC_R_SUCCESS); - } - - /* Reserve space for current node. */ - CHECK(isc_stdio_tell(file, &location)); - location = dns_rbt_serialize_align(location); - CHECK(isc_stdio_seek(file, location, SEEK_SET)); - - offset_adjust = dns_rbt_serialize_align(location + NODE_SIZE(node)); - CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET)); - - /* - * Serialize the rest of the tree. - * - * WARNING: A change in the order (from left, right, down) - * will break the way the crc hash is computed. - */ - CHECK(serialize_nodes(file, getleft(node, NULL), location, - datawriter, writer_arg, &left, crc)); - CHECK(serialize_nodes(file, getright(node, NULL), location, - datawriter, writer_arg, &right, crc)); - CHECK(serialize_nodes(file, getdown(node, NULL), location, - datawriter, writer_arg, &down, crc)); - - if (node->data != NULL) { - off_t ret; - - CHECK(isc_stdio_tell(file, &ret)); - ret = dns_rbt_serialize_align(ret); - CHECK(isc_stdio_seek(file, ret, SEEK_SET)); - data = ret; - - datawriter(file, node->data, writer_arg, crc); - } - - /* Seek back to reserved space. */ - CHECK(isc_stdio_seek(file, location, SEEK_SET)); - - /* Serialize the current node. */ - CHECK(serialize_node(file, node, left, right, down, parent, data, crc)); - - /* Ensure we are always at the end of the file. */ - CHECK(isc_stdio_seek(file, 0, SEEK_END)); - - if (where != NULL) - *where = (uintptr_t) location; - - cleanup: - return (result); -} - -off_t -dns_rbt_serialize_align(off_t target) { - off_t offset = target % 8; - - if (offset == 0) - return (target); - else - return (target + 8 - offset); -} - -isc_result_t -dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt, - dns_rbtdatawriter_t datawriter, - void *writer_arg, off_t *offset) -{ - isc_result_t result; - off_t header_position, node_position, end_position; - uint64_t crc; - - REQUIRE(file != NULL); - - CHECK(isc_file_isplainfilefd(fileno(file))); - - isc_crc64_init(&crc); - - CHECK(isc_stdio_tell(file, &header_position)); - - /* Write dummy header */ - CHECK(dns_rbt_zero_header(file)); - - /* Serialize nodes */ - CHECK(isc_stdio_tell(file, &node_position)); - CHECK(serialize_nodes(file, rbt->root, 0, datawriter, - writer_arg, NULL, &crc)); - - CHECK(isc_stdio_tell(file, &end_position)); - if (node_position == end_position) { - CHECK(isc_stdio_seek(file, header_position, SEEK_SET)); - *offset = 0; - return (ISC_R_SUCCESS); - } - - isc_crc64_final(&crc); -#ifdef DEBUG - hexdump("serializing CRC", (unsigned char *)&crc, sizeof(crc)); -#endif - - /* Serialize header */ - CHECK(isc_stdio_seek(file, header_position, SEEK_SET)); - CHECK(write_header(file, rbt, HEADER_LENGTH, crc)); - - /* Ensure we are always at the end of the file. */ - CHECK(isc_stdio_seek(file, 0, SEEK_END)); - *offset = dns_rbt_serialize_align(header_position); - - cleanup: - return (result); -} - -#define CONFIRM(a) do { \ - if (! (a)) { \ - result = ISC_R_INVALIDFILE; \ - goto cleanup; \ - } \ -} while(0); - -static isc_result_t -treefix(dns_rbt_t *rbt, void *base, size_t filesize, dns_rbtnode_t *n, - dns_name_t *name, dns_rbtdatafixer_t datafixer, - void *fixer_arg, uint64_t *crc) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_fixedname_t fixed; - dns_name_t nodename, *fullname; - unsigned char *node_data; - dns_rbtnode_t header; - size_t datasize, nodemax = filesize - sizeof(dns_rbtnode_t); - - if (n == NULL) - return (ISC_R_SUCCESS); - - CONFIRM((void *) n >= base); - CONFIRM((char *) n - (char *) base <= (int) nodemax); - CONFIRM(DNS_RBTNODE_VALID(n)); - - dns_name_init(&nodename, NULL); - NODENAME(n, &nodename); - - fullname = &nodename; - CONFIRM(dns_name_isvalid(fullname)); - - if (!dns_name_isabsolute(&nodename)) { - fullname = dns_fixedname_initname(&fixed); - CHECK(dns_name_concatenate(&nodename, name, fullname, NULL)); - } - - /* memorize header contents prior to fixup */ - memmove(&header, n, sizeof(header)); - - if (n->left_is_relative) { - CONFIRM(n->left <= (dns_rbtnode_t *) nodemax); - n->left = getleft(n, rbt->mmap_location); - n->left_is_relative = 0; - CONFIRM(DNS_RBTNODE_VALID(n->left)); - } else - CONFIRM(n->left == NULL); - - if (n->right_is_relative) { - CONFIRM(n->right <= (dns_rbtnode_t *) nodemax); - n->right = getright(n, rbt->mmap_location); - n->right_is_relative = 0; - CONFIRM(DNS_RBTNODE_VALID(n->right)); - } else - CONFIRM(n->right == NULL); - - if (n->down_is_relative) { - CONFIRM(n->down <= (dns_rbtnode_t *) nodemax); - n->down = getdown(n, rbt->mmap_location); - n->down_is_relative = 0; - CONFIRM(n->down > (dns_rbtnode_t *) n); - CONFIRM(DNS_RBTNODE_VALID(n->down)); - } else - CONFIRM(n->down == NULL); - - if (n->parent_is_relative) { - CONFIRM(n->parent <= (dns_rbtnode_t *) nodemax); - n->parent = getparent(n, rbt->mmap_location); - n->parent_is_relative = 0; - CONFIRM(n->parent < (dns_rbtnode_t *) n); - CONFIRM(DNS_RBTNODE_VALID(n->parent)); - } else - CONFIRM(n->parent == NULL); - - if (n->data_is_relative) { - CONFIRM(n->data <= (void *) filesize); - n->data = getdata(n, rbt->mmap_location); - n->data_is_relative = 0; - CONFIRM(n->data > (void *) n); - } else - CONFIRM(n->data == NULL); - - hash_node(rbt, n, fullname); - - /* a change in the order (from left, right, down) will break hashing*/ - if (n->left != NULL) - CHECK(treefix(rbt, base, filesize, n->left, name, - datafixer, fixer_arg, crc)); - if (n->right != NULL) - CHECK(treefix(rbt, base, filesize, n->right, name, - datafixer, fixer_arg, crc)); - if (n->down != NULL) - CHECK(treefix(rbt, base, filesize, n->down, fullname, - datafixer, fixer_arg, crc)); - - if (datafixer != NULL && n->data != NULL) - CHECK(datafixer(n, base, filesize, fixer_arg, crc)); - - rbt->nodecount++; - node_data = (unsigned char *) n + sizeof(dns_rbtnode_t); - datasize = NODE_SIZE(n) - sizeof(dns_rbtnode_t); - -#ifdef DEBUG - fprintf(stderr, "deserialize "); - dns_name_print(&nodename, stderr); - fprintf(stderr, "\n"); - hexdump("node header", (unsigned char *) &header, - sizeof(dns_rbtnode_t)); - hexdump("node data", node_data, datasize); -#endif - isc_crc64_update(crc, (const uint8_t *) &header, - sizeof(dns_rbtnode_t)); - isc_crc64_update(crc, (const uint8_t *) node_data, - datasize); - - cleanup: - return (result); -} - -isc_result_t -dns_rbt_deserialize_tree(void *base_address, size_t filesize, - off_t header_offset, isc_mem_t *mctx, - dns_rbtdeleter_t deleter, void *deleter_arg, - dns_rbtdatafixer_t datafixer, void *fixer_arg, - dns_rbtnode_t **originp, dns_rbt_t **rbtp) -{ - isc_result_t result = ISC_R_SUCCESS; - file_header_t *header; - dns_rbt_t *rbt = NULL; - uint64_t crc; - unsigned int host_big_endian; - - REQUIRE(originp == NULL || *originp == NULL); - REQUIRE(rbtp != NULL && *rbtp == NULL); - - isc_crc64_init(&crc); - - CHECK(dns_rbt_create(mctx, deleter, deleter_arg, &rbt)); - - rbt->mmap_location = base_address; - - header = (file_header_t *)((char *)base_address + header_offset); - if (!match_header_version(header)) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - -#ifdef DNS_RDATASET_FIXED - if (header->rdataset_fixed != 1) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - -#else - if (header->rdataset_fixed != 0) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } -#endif - - if (header->ptrsize != (uint32_t) sizeof(void *)) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - - host_big_endian = (1 == htonl(1)); - if (header->bigendian != host_big_endian) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - - /* Copy other data items from the header into our rbt. */ - rbt->root = (dns_rbtnode_t *)((char *)base_address + - header_offset + header->first_node_offset); - - if ((header->nodecount * sizeof(dns_rbtnode_t)) > filesize) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - rehash(rbt, header->nodecount); - - CHECK(treefix(rbt, base_address, filesize, rbt->root, - dns_rootname, datafixer, fixer_arg, &crc)); - - isc_crc64_final(&crc); -#ifdef DEBUG - hexdump("deserializing CRC", (unsigned char *)&crc, sizeof(crc)); -#endif - - /* Check file hash */ - if (header->crc != crc) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - - if (header->nodecount != rbt->nodecount) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - -#ifdef DNS_RBT_USEHASH - fixup_uppernodes(rbt); -#endif /* DNS_RBT_USEHASH */ - - *rbtp = rbt; - if (originp != NULL) - *originp = rbt->root; - - cleanup: - if (result != ISC_R_SUCCESS && rbt != NULL) { - rbt->root = NULL; - rbt->nodecount = 0; - dns_rbt_destroy(&rbt); - } - - return (result); -} - -/* - * Initialize a red/black tree of trees. - */ -isc_result_t -dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, - void *deleter_arg, dns_rbt_t **rbtp) -{ -#ifdef DNS_RBT_USEHASH - isc_result_t result; -#endif - dns_rbt_t *rbt; - - REQUIRE(mctx != NULL); - REQUIRE(rbtp != NULL && *rbtp == NULL); - REQUIRE(deleter == NULL ? deleter_arg == NULL : 1); - - rbt = (dns_rbt_t *)isc_mem_get(mctx, sizeof(*rbt)); - if (rbt == NULL) - return (ISC_R_NOMEMORY); - - rbt->mctx = NULL; - isc_mem_attach(mctx, &rbt->mctx); - rbt->data_deleter = deleter; - rbt->deleter_arg = deleter_arg; - rbt->root = NULL; - rbt->nodecount = 0; - rbt->hashtable = NULL; - rbt->hashsize = 0; - rbt->mmap_location = NULL; - -#ifdef DNS_RBT_USEHASH - result = inithash(rbt); - if (result != ISC_R_SUCCESS) { - isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); - return (result); - } -#endif - - rbt->magic = RBT_MAGIC; - - *rbtp = rbt; - - return (ISC_R_SUCCESS); -} - -/* - * Deallocate a red/black tree of trees. - */ -void -dns_rbt_destroy(dns_rbt_t **rbtp) { - RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS); -} - -isc_result_t -dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) { - dns_rbt_t *rbt; - - REQUIRE(rbtp != NULL && VALID_RBT(*rbtp)); - - rbt = *rbtp; - - deletetreeflat(rbt, quantum, false, &rbt->root); - if (rbt->root != NULL) - return (ISC_R_QUOTA); - - INSIST(rbt->nodecount == 0); - - rbt->mmap_location = NULL; - - if (rbt->hashtable != NULL) - isc_mem_put(rbt->mctx, rbt->hashtable, - rbt->hashsize * sizeof(dns_rbtnode_t *)); - - rbt->magic = 0; - - isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); - *rbtp = NULL; - return (ISC_R_SUCCESS); -} - -unsigned int -dns_rbt_nodecount(dns_rbt_t *rbt) { - - REQUIRE(VALID_RBT(rbt)); - - return (rbt->nodecount); -} - -size_t -dns_rbt_hashsize(dns_rbt_t *rbt) { - - REQUIRE(VALID_RBT(rbt)); - - return (rbt->hashsize); -} - -static inline isc_result_t -chain_name(dns_rbtnodechain_t *chain, dns_name_t *name, - bool include_chain_end) -{ - dns_name_t nodename; - isc_result_t result = ISC_R_SUCCESS; - int i; - - dns_name_init(&nodename, NULL); - - if (include_chain_end && chain->end != NULL) { - NODENAME(chain->end, &nodename); - result = dns_name_copy(&nodename, name, NULL); - if (result != ISC_R_SUCCESS) - return (result); - } else - dns_name_reset(name); - - for (i = (int)chain->level_count - 1; i >= 0; i--) { - NODENAME(chain->levels[i], &nodename); - result = dns_name_concatenate(name, &nodename, name, NULL); - - if (result != ISC_R_SUCCESS) - return (result); - } - return (result); -} - -static inline isc_result_t -move_chain_to_last(dns_rbtnodechain_t *chain, dns_rbtnode_t *node) { - do { - /* - * Go as far right and then down as much as possible, - * as long as the rightmost node has a down pointer. - */ - while (RIGHT(node) != NULL) - node = RIGHT(node); - - if (DOWN(node) == NULL) - break; - - ADD_LEVEL(chain, node); - node = DOWN(node); - } while (1); - - chain->end = node; - - return (ISC_R_SUCCESS); -} - -/* - * Add 'name' to tree, initializing its data pointer with 'data'. - */ - -isc_result_t -dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) { - /* - * Does this thing have too many variables or what? - */ - dns_rbtnode_t **root, *parent, *child, *current, *new_current; - dns_name_t *add_name, *new_name, current_name, *prefix, *suffix; - dns_fixedname_t fixedcopy, fixedprefix, fixedsuffix, fnewname; - dns_offsets_t current_offsets; - dns_namereln_t compared; - isc_result_t result = ISC_R_SUCCESS; - unsigned int level_count; - unsigned int common_labels; - unsigned int nlabels, hlabels; - int order; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(nodep != NULL && *nodep == NULL); - - /* - * Dear future BIND developer, - * - * After you have tried attempting to optimize this routine by - * using the hashtable and have realized your folly, please - * append another cross ("X") below as a warning to the next - * future BIND developer: - * - * Number of victim developers: X - * - * I wish the past developer had included such a notice. - * - * Long form: Unlike dns_rbt_findnode(), this function does not - * lend itself to be optimized using the hashtable: - * - * 1. In the subtree where the insertion occurs, this function - * needs to have the insertion point and the order where the - * lookup terminated (i.e., at the insertion point where left or - * right child is NULL). This cannot be determined from the - * hashtable, so at least in that subtree, a BST O(log N) lookup - * is necessary. - * - * 2. Our RBT nodes contain not only single labels but label - * sequences to optimize space usage. So at every level, we have - * to look for a match in the hashtable for all superdomains in - * the rest of the name we're searching. This is an O(N) - * operation at least, here N being the label size of name, each - * of which is a hashtable lookup involving dns_name_equal() - * comparisons. - */ - - /* - * Create a copy of the name so the original name structure is - * not modified. - */ - add_name = dns_fixedname_initname(&fixedcopy); - dns_name_clone(name, add_name); - - if (ISC_UNLIKELY(rbt->root == NULL)) { - result = create_node(rbt->mctx, add_name, &new_current); - if (result == ISC_R_SUCCESS) { - rbt->nodecount++; - new_current->is_root = 1; -#ifdef DNS_RBT_USEHASH - UPPERNODE(new_current) = NULL; -#endif /* DNS_RBT_USEHASH */ - rbt->root = new_current; - *nodep = new_current; - hash_node(rbt, new_current, name); - } - return (result); - } - - level_count = 0; - - prefix = dns_fixedname_initname(&fixedprefix); - suffix = dns_fixedname_initname(&fixedsuffix); - - root = &rbt->root; - INSIST(IS_ROOT(*root)); - parent = NULL; - current = NULL; - child = *root; - dns_name_init(¤t_name, current_offsets); - new_name = dns_fixedname_initname(&fnewname); - nlabels = dns_name_countlabels(name); - hlabels = 0; - - do { - current = child; - - NODENAME(current, ¤t_name); - compared = dns_name_fullcompare(add_name, ¤t_name, - &order, &common_labels); - - if (compared == dns_namereln_equal) { - *nodep = current; - result = ISC_R_EXISTS; - break; - - } - - if (compared == dns_namereln_none) { - - if (order < 0) { - parent = current; - child = LEFT(current); - - } else if (order > 0) { - parent = current; - child = RIGHT(current); - - } - - } else { - /* - * This name has some suffix in common with the - * name at the current node. If the name at - * the current node is shorter, that means the - * new name should be in a subtree. If the - * name at the current node is longer, that means - * the down pointer to this tree should point - * to a new tree that has the common suffix, and - * the non-common parts of these two names should - * start a new tree. - */ - hlabels += common_labels; - if (compared == dns_namereln_subdomain) { - /* - * All of the existing labels are in common, - * so the new name is in a subtree. - * Whack off the common labels for the - * not-in-common part to be searched for - * in the next level. - */ - dns_name_split(add_name, common_labels, - add_name, NULL); - - /* - * Follow the down pointer (possibly NULL). - */ - root = &DOWN(current); - - INSIST(*root == NULL || - (IS_ROOT(*root) && - PARENT(*root) == current)); - - parent = NULL; - child = DOWN(current); - - INSIST(level_count < DNS_RBT_LEVELBLOCK); - level_count++; - } else { - /* - * The number of labels in common is fewer - * than the number of labels at the current - * node, so the current node must be adjusted - * to have just the common suffix, and a down - * pointer made to a new tree. - */ - - INSIST(compared == dns_namereln_commonancestor - || compared == dns_namereln_contains); - - /* - * Ensure the number of levels in the tree - * does not exceed the number of logical - * levels allowed by DNSSEC. - * - * XXXDCL need a better error result? - */ - if (level_count >= DNS_RBT_LEVELBLOCK) { - result = ISC_R_NOSPACE; - break; - } - - /* - * Split the name into two parts, a prefix - * which is the not-in-common parts of the - * two names and a suffix that is the common - * parts of them. - */ - dns_name_split(¤t_name, common_labels, - prefix, suffix); - result = create_node(rbt->mctx, suffix, - &new_current); - - if (result != ISC_R_SUCCESS) - break; - - /* - * Reproduce the tree attributes of the - * current node. - */ - new_current->is_root = current->is_root; - if (current->nsec == DNS_RBT_NSEC_HAS_NSEC) - new_current->nsec = DNS_RBT_NSEC_NORMAL; - else - new_current->nsec = current->nsec; - PARENT(new_current) = PARENT(current); - LEFT(new_current) = LEFT(current); - RIGHT(new_current) = RIGHT(current); - COLOR(new_current) = COLOR(current); - - /* - * Fix pointers that were to the current node. - */ - if (parent != NULL) { - if (LEFT(parent) == current) - LEFT(parent) = new_current; - else - RIGHT(parent) = new_current; - } - if (LEFT(new_current) != NULL) - PARENT(LEFT(new_current)) = - new_current; - if (RIGHT(new_current) != NULL) - PARENT(RIGHT(new_current)) = - new_current; - if (*root == current) - *root = new_current; - - NAMELEN(current) = prefix->length; - OFFSETLEN(current) = prefix->labels; - - /* - * Set up the new root of the next level. - * By definition it will not be the top - * level tree, so clear DNS_NAMEATTR_ABSOLUTE. - */ - current->is_root = 1; - PARENT(current) = new_current; - DOWN(new_current) = current; - root = &DOWN(new_current); -#ifdef DNS_RBT_USEHASH - UPPERNODE(new_current) = UPPERNODE(current); - UPPERNODE(current) = new_current; -#endif /* DNS_RBT_USEHASH */ - - INSIST(level_count < DNS_RBT_LEVELBLOCK); - level_count++; - - LEFT(current) = NULL; - RIGHT(current) = NULL; - - MAKE_BLACK(current); - ATTRS(current) &= ~DNS_NAMEATTR_ABSOLUTE; - - rbt->nodecount++; - dns_name_getlabelsequence(name, - nlabels - hlabels, - hlabels, new_name); - hash_node(rbt, new_current, new_name); - - if (common_labels == - dns_name_countlabels(add_name)) { - /* - * The name has been added by pushing - * the not-in-common parts down to - * a new level. - */ - *nodep = new_current; - return (ISC_R_SUCCESS); - - } else { - /* - * The current node has no data, - * because it is just a placeholder. - * Its data pointer is already NULL - * from create_node()), so there's - * nothing more to do to it. - */ - - /* - * The not-in-common parts of the new - * name will be inserted into the new - * level following this loop (unless - * result != ISC_R_SUCCESS, which - * is tested after the loop ends). - */ - dns_name_split(add_name, common_labels, - add_name, NULL); - - break; - } - - } - - } - - } while (ISC_LIKELY(child != NULL)); - - if (ISC_LIKELY(result == ISC_R_SUCCESS)) - result = create_node(rbt->mctx, add_name, &new_current); - - if (ISC_LIKELY(result == ISC_R_SUCCESS)) { -#ifdef DNS_RBT_USEHASH - if (*root == NULL) - UPPERNODE(new_current) = current; - else - UPPERNODE(new_current) = PARENT(*root); -#endif /* DNS_RBT_USEHASH */ - addonlevel(new_current, current, order, root); - rbt->nodecount++; - *nodep = new_current; - hash_node(rbt, new_current, name); - } - - return (result); -} - -/* - * Add a name to the tree of trees, associating it with some data. - */ -isc_result_t -dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) { - isc_result_t result; - dns_rbtnode_t *node; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(dns_name_isabsolute(name)); - - node = NULL; - - result = dns_rbt_addnode(rbt, name, &node); - - /* - * dns_rbt_addnode will report the node exists even when - * it does not have data associated with it, but the - * dns_rbt_*name functions all behave depending on whether - * there is data associated with a node. - */ - if (result == ISC_R_SUCCESS || - (result == ISC_R_EXISTS && DATA(node) == NULL)) { - DATA(node) = data; - result = ISC_R_SUCCESS; - } - - return (result); -} - -/* - * Find the node for "name" in the tree of trees. - */ -isc_result_t -dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname, - dns_rbtnode_t **node, dns_rbtnodechain_t *chain, - unsigned int options, dns_rbtfindcallback_t callback, - void *callback_arg) -{ - dns_rbtnode_t *current, *last_compared; - dns_rbtnodechain_t localchain; - dns_name_t *search_name, current_name, *callback_name; - dns_fixedname_t fixedcallbackname, fixedsearchname; - dns_namereln_t compared; - isc_result_t result, saved_result; - unsigned int common_labels; - unsigned int hlabels = 0; - int order; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(node != NULL && *node == NULL); - REQUIRE((options & (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR)) - != (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR)); - - /* - * If there is a chain it needs to appear to be in a sane state, - * otherwise a chain is still needed to generate foundname and - * callback_name. - */ - if (chain == NULL) { - options |= DNS_RBTFIND_NOPREDECESSOR; - chain = &localchain; - dns_rbtnodechain_init(chain, rbt->mctx); - } else - dns_rbtnodechain_reset(chain); - - if (ISC_UNLIKELY(rbt->root == NULL)) - return (ISC_R_NOTFOUND); - - /* - * Appease GCC about variables it incorrectly thinks are - * possibly used uninitialized. - */ - compared = dns_namereln_none; - last_compared = NULL; - order = 0; - - callback_name = dns_fixedname_initname(&fixedcallbackname); - - /* - * search_name is the name segment being sought in each tree level. - * By using a fixedname, the search_name will definitely have offsets - * for use by any splitting. - * By using dns_name_clone, no name data should be copied thanks to - * the lack of bitstring labels. - */ - search_name = dns_fixedname_initname(&fixedsearchname); - dns_name_clone(name, search_name); - - dns_name_init(¤t_name, NULL); - - saved_result = ISC_R_SUCCESS; - current = rbt->root; - - while (ISC_LIKELY(current != NULL)) { - NODENAME(current, ¤t_name); - compared = dns_name_fullcompare(search_name, ¤t_name, - &order, &common_labels); - /* - * last_compared is used as a shortcut to start (or - * continue rather) finding the stop-node of the search - * when hashing was used (see much below in this - * function). - */ - last_compared = current; - - if (compared == dns_namereln_equal) - break; - - if (compared == dns_namereln_none) { -#ifdef DNS_RBT_USEHASH - /* - * Here, current is pointing at a subtree root - * node. We try to find a matching node using - * the hashtable. We can get one of 3 results - * here: (a) we locate the matching node, (b) we - * find a node to which the current node has a - * subdomain relation, (c) we fail to find (a) - * or (b). - */ - - dns_name_t hash_name; - dns_rbtnode_t *hnode; - dns_rbtnode_t *up_current; - unsigned int nlabels; - unsigned int tlabels = 1; - unsigned int hash; - - /* - * The case of current not being a subtree root, - * that means a left or right pointer was - * followed, only happens when the algorithm - * fell through to the traditional binary search - * because of a bitstring label. Since we - * dropped the bitstring support, this should - * not happen. - */ - INSIST(IS_ROOT(current)); - - nlabels = dns_name_countlabels(search_name); - - /* - * current is the root of the current level, so - * its parent is the same as its "up" pointer. - */ - up_current = PARENT(current); - dns_name_init(&hash_name, NULL); - - hashagain: - /* - * Compute the hash over the full absolute - * name. Look for the smallest suffix match at - * this tree level (hlevel), and then at every - * iteration, look for the next smallest suffix - * match (add another subdomain label to the - * absolute name being hashed). - */ - dns_name_getlabelsequence(name, - nlabels - tlabels, - hlabels + tlabels, - &hash_name); - hash = dns_name_fullhash(&hash_name, false); - dns_name_getlabelsequence(search_name, - nlabels - tlabels, - tlabels, &hash_name); - - /* - * Walk all the nodes in the hash bucket pointed - * by the computed hash value. - */ - for (hnode = rbt->hashtable[hash % rbt->hashsize]; - hnode != NULL; - hnode = hnode->hashnext) - { - dns_name_t hnode_name; - - if (ISC_LIKELY(hash != HASHVAL(hnode))) - continue; - /* - * This checks that the hashed label - * sequence being looked up is at the - * same tree level, so that we don't - * match a labelsequence from some other - * subdomain. - */ - if (ISC_LIKELY(get_upper_node(hnode) != up_current)) - continue; - - dns_name_init(&hnode_name, NULL); - NODENAME(hnode, &hnode_name); - if (ISC_LIKELY(dns_name_equal(&hnode_name, &hash_name))) - break; - } - - if (hnode != NULL) { - current = hnode; - /* - * This is an optimization. If hashing found - * the right node, the next call to - * dns_name_fullcompare() would obviously - * return _equal or _subdomain. Determine - * which of those would be the case by - * checking if the full name was hashed. Then - * make it look like dns_name_fullcompare - * was called and jump to the right place. - */ - if (tlabels == nlabels) { - compared = dns_namereln_equal; - break; - } else { - common_labels = tlabels; - compared = dns_namereln_subdomain; - goto subdomain; - } - } - - if (tlabels++ < nlabels) - goto hashagain; - - /* - * All of the labels have been tried against the hash - * table. Since we dropped the support of bitstring - * labels, the name isn't in the table. - */ - current = NULL; - continue; - -#else /* DNS_RBT_USEHASH */ - - /* - * Standard binary search tree movement. - */ - if (order < 0) - current = LEFT(current); - else - current = RIGHT(current); - -#endif /* DNS_RBT_USEHASH */ - - } else { - /* - * The names have some common suffix labels. - * - * If the number in common are equal in length to - * the current node's name length, then follow the - * down pointer and search in the new tree. - */ - if (compared == dns_namereln_subdomain) { -#ifdef DNS_RBT_USEHASH - subdomain: -#endif - /* - * Whack off the current node's common parts - * for the name to search in the next level. - */ - dns_name_split(search_name, common_labels, - search_name, NULL); - hlabels += common_labels; - /* - * This might be the closest enclosing name. - */ - if (WANTEMPTYDATA_OR_DATA(options, current)) { - *node = current; - } - - /* - * Point the chain to the next level. This - * needs to be done before 'current' is pointed - * there because the callback in the next - * block of code needs the current 'current', - * but in the event the callback requests that - * the search be stopped then the - * DNS_R_PARTIALMATCH code at the end of this - * function needs the chain pointed to the - * next level. - */ - ADD_LEVEL(chain, current); - - /* - * The caller may want to interrupt the - * downward search when certain special nodes - * are traversed. If this is a special node, - * the callback is used to learn what the - * caller wants to do. - */ - if (callback != NULL && - FINDCALLBACK(current)) { - result = chain_name(chain, - callback_name, - false); - if (result != ISC_R_SUCCESS) { - dns_rbtnodechain_reset(chain); - return (result); - } - - result = (callback)(current, - callback_name, - callback_arg); - if (result != DNS_R_CONTINUE) { - saved_result = result; - /* - * Treat this node as if it - * had no down pointer. - */ - current = NULL; - break; - } - } - - /* - * Finally, head to the next tree level. - */ - current = DOWN(current); - } else { - /* - * Though there are labels in common, the - * entire name at this node is not common - * with the search name so the search - * name does not exist in the tree. - */ - INSIST(compared == dns_namereln_commonancestor - || compared == dns_namereln_contains); - - current = NULL; - } - } - } - - /* - * If current is not NULL, NOEXACT is not disallowing exact matches, - * and either the node has data or an empty node is ok, return - * ISC_R_SUCCESS to indicate an exact match. - */ - if (current != NULL && (options & DNS_RBTFIND_NOEXACT) == 0 && - (WANTEMPTYDATA_OR_DATA(options, current))) { - /* - * Found an exact match. - */ - chain->end = current; - chain->level_matches = chain->level_count; - - if (foundname != NULL) - result = chain_name(chain, foundname, true); - else - result = ISC_R_SUCCESS; - - if (result == ISC_R_SUCCESS) { - *node = current; - result = saved_result; - } else - *node = NULL; - } else { - /* - * Did not find an exact match (or did not want one). - */ - if (*node != NULL) { - /* - * ... but found a partially matching superdomain. - * Unwind the chain to the partial match node - * to set level_matches to the level above the node, - * and then to derive the name. - * - * chain->level_count is guaranteed to be at least 1 - * here because by definition of finding a superdomain, - * the chain is pointed to at least the first subtree. - */ - chain->level_matches = chain->level_count - 1; - - while (chain->levels[chain->level_matches] != *node) { - INSIST(chain->level_matches > 0); - chain->level_matches--; - } - - if (foundname != NULL) { - unsigned int saved_count = chain->level_count; - - chain->level_count = chain->level_matches + 1; - - result = chain_name(chain, foundname, - false); - - chain->level_count = saved_count; - } else - result = ISC_R_SUCCESS; - - if (result == ISC_R_SUCCESS) - result = DNS_R_PARTIALMATCH; - - } else - result = ISC_R_NOTFOUND; - - if (current != NULL) { - /* - * There was an exact match but either - * DNS_RBTFIND_NOEXACT was set, or - * DNS_RBTFIND_EMPTYDATA was set and the node had no - * data. A policy decision was made to set the - * chain to the exact match, but this is subject - * to change if it becomes apparent that something - * else would be more useful. It is important that - * this case is handled here, because the predecessor - * setting code below assumes the match was not exact. - */ - INSIST(((options & DNS_RBTFIND_NOEXACT) != 0) || - ((options & DNS_RBTFIND_EMPTYDATA) == 0 && - DATA(current) == NULL)); - chain->end = current; - - } else if ((options & DNS_RBTFIND_NOPREDECESSOR) != 0) { - /* - * Ensure the chain points nowhere. - */ - chain->end = NULL; - - } else { - /* - * Since there was no exact match, the chain argument - * needs to be pointed at the DNSSEC predecessor of - * the search name. - */ - if (compared == dns_namereln_subdomain) { - /* - * Attempted to follow a down pointer that was - * NULL, which means the searched for name was - * a subdomain of a terminal name in the tree. - * Since there are no existing subdomains to - * order against, the terminal name is the - * predecessor. - */ - INSIST(chain->level_count > 0); - INSIST(chain->level_matches < - chain->level_count); - chain->end = - chain->levels[--chain->level_count]; - - } else { - isc_result_t result2; - - /* - * Point current to the node that stopped - * the search. - * - * With the hashing modification that has been - * added to the algorithm, the stop node of a - * standard binary search is not known. So it - * has to be found. There is probably a more - * clever way of doing this. - * - * The assignment of current to NULL when - * the relationship is *not* dns_namereln_none, - * even though it later gets set to the same - * last_compared anyway, is simply to not push - * the while loop in one more level of - * indentation. - */ - if (compared == dns_namereln_none) - current = last_compared; - else - current = NULL; - - while (current != NULL) { - NODENAME(current, ¤t_name); - compared = dns_name_fullcompare( - search_name, - ¤t_name, - &order, - &common_labels); - POST(compared); - - last_compared = current; - - /* - * Standard binary search movement. - */ - if (order < 0) - current = LEFT(current); - else - current = RIGHT(current); - - } - - current = last_compared; - - /* - * Reached a point within a level tree that - * positively indicates the name is not - * present, but the stop node could be either - * less than the desired name (order > 0) or - * greater than the desired name (order < 0). - * - * If the stop node is less, it is not - * necessarily the predecessor. If the stop - * node has a down pointer, then the real - * predecessor is at the end of a level below - * (not necessarily the next level). - * Move down levels until the rightmost node - * does not have a down pointer. - * - * When the stop node is greater, it is - * the successor. All the logic for finding - * the predecessor is handily encapsulated - * in dns_rbtnodechain_prev. In the event - * that the search name is less than anything - * else in the tree, the chain is reset. - * XXX DCL What is the best way for the caller - * to know that the search name has - * no predecessor? - */ - - - if (order > 0) { - if (DOWN(current) != NULL) { - ADD_LEVEL(chain, current); - - result2 = - move_chain_to_last(chain, - DOWN(current)); - - if (result2 != ISC_R_SUCCESS) - result = result2; - } else - /* - * Ah, the pure and simple - * case. The stop node is the - * predecessor. - */ - chain->end = current; - - } else { - INSIST(order < 0); - - chain->end = current; - - result2 = dns_rbtnodechain_prev(chain, - NULL, - NULL); - if (result2 == ISC_R_SUCCESS || - result2 == DNS_R_NEWORIGIN) - ; /* Nothing. */ - else if (result2 == ISC_R_NOMORE) - /* - * There is no predecessor. - */ - dns_rbtnodechain_reset(chain); - else - result = result2; - } - - } - } - } - - ENSURE(*node == NULL || DNS_RBTNODE_VALID(*node)); - - return (result); -} - -/* - * Get the data pointer associated with 'name'. - */ -isc_result_t -dns_rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options, - dns_name_t *foundname, void **data) { - dns_rbtnode_t *node = NULL; - isc_result_t result; - - REQUIRE(data != NULL && *data == NULL); - - result = dns_rbt_findnode(rbt, name, foundname, &node, NULL, - options, NULL, NULL); - - if (node != NULL && WANTEMPTYDATA_OR_DATA(options, node)) { - *data = DATA(node); - } else { - result = ISC_R_NOTFOUND; - } - - return (result); -} - -/* - * Delete a name from the tree of trees. - */ -isc_result_t -dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, bool recurse) { - dns_rbtnode_t *node = NULL; - isc_result_t result; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(dns_name_isabsolute(name)); - - /* - * First, find the node. - * - * When searching, the name might not have an exact match: - * consider a.b.a.com, b.b.a.com and c.b.a.com as the only - * elements of a tree, which would make layer 1 a single - * node tree of "b.a.com" and layer 2 a three node tree of - * a, b, and c. Deleting a.com would find only a partial depth - * match in the first layer. Should it be a requirement that - * that the name to be deleted have data? For now, it is. - * - * ->dirty, ->locknum and ->references are ignored; they are - * solely the province of rbtdb.c. - */ - result = dns_rbt_findnode(rbt, name, NULL, &node, NULL, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); - - if (result == ISC_R_SUCCESS) { - if (DATA(node) != NULL) - result = dns_rbt_deletenode(rbt, node, recurse); - else - result = ISC_R_NOTFOUND; - - } else if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - - return (result); -} - -/* - * Remove a node from the tree of trees. - * - * NOTE WELL: deletion is *not* symmetric with addition; that is, reversing - * a sequence of additions to be deletions will not generally get the - * tree back to the state it started in. For example, if the addition - * of "b.c" caused the node "a.b.c" to be split, pushing "a" to its own level, - * then the subsequent deletion of "b.c" will not cause "a" to be pulled up, - * restoring "a.b.c". The RBT *used* to do this kind of rejoining, but it - * turned out to be a bad idea because it could corrupt an active nodechain - * that had "b.c" as one of its levels -- and the RBT has no idea what - * nodechains are in use by callers, so it can't even *try* to helpfully - * fix them up (which would probably be doomed to failure anyway). - * - * Similarly, it is possible to leave the tree in a state where a supposedly - * deleted node still exists. The first case of this is obvious; take - * the tree which has "b.c" on one level, pointing to "a". Now deleted "b.c". - * It was just established in the previous paragraph why we can't pull "a" - * back up to its parent level. But what happens when "a" then gets deleted? - * "b.c" is left hanging around without data or children. This condition - * is actually pretty easy to detect, but ... should it really be removed? - * Is a chain pointing to it? An iterator? Who knows! (Note that the - * references structure member cannot be looked at because it is private to - * rbtdb.) This is ugly and makes me unhappy, but after hours of trying to - * make it more aesthetically proper and getting nowhere, this is the way it - * is going to stay until such time as it proves to be a *real* problem. - * - * Finally, for reference, note that the original routine that did node - * joining was called join_nodes(). It has been excised, living now only - * in the CVS history, but comments have been left behind that point to it just - * in case someone wants to muck with this some more. - * - * The one positive aspect of all of this is that joining used to have a - * case where it might fail. Without trying to join, now this function always - * succeeds. It still returns isc_result_t, though, so the API wouldn't change. - */ -isc_result_t -dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse) -{ - dns_rbtnode_t *parent; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(DNS_RBTNODE_VALID(node)); - INSIST(rbt->nodecount != 0); - - if (DOWN(node) != NULL) { - if (recurse) { - PARENT(DOWN(node)) = NULL; - deletetreeflat(rbt, 0, true, &DOWN(node)); - } else { - if (DATA(node) != NULL && rbt->data_deleter != NULL) - rbt->data_deleter(DATA(node), rbt->deleter_arg); - DATA(node) = NULL; - - /* - * Since there is at least one node below this one and - * no recursion was requested, the deletion is - * complete. The down node from this node might be all - * by itself on a single level, so join_nodes() could - * be used to collapse the tree (with all the caveats - * of the comment at the start of this function). - * But join_nodes() function has now been removed. - */ - return (ISC_R_SUCCESS); - } - } - - /* - * Note the node that points to the level of the node - * that is being deleted. If the deleted node is the - * top level, parent will be set to NULL. - */ - parent = get_upper_node(node); - - /* - * This node now has no down pointer, so now it needs - * to be removed from this level. - */ - deletefromlevel(node, parent == NULL ? &rbt->root : &DOWN(parent)); - - if (DATA(node) != NULL && rbt->data_deleter != NULL) - rbt->data_deleter(DATA(node), rbt->deleter_arg); - - unhash_node(rbt, node); -#if DNS_RBT_USEMAGIC - node->magic = 0; -#endif - dns_rbtnode_refdestroy(node); - - freenode(rbt, &node); - - /* - * This function never fails. - */ - return (ISC_R_SUCCESS); -} - -void -dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) { - - REQUIRE(DNS_RBTNODE_VALID(node)); - REQUIRE(name != NULL); - REQUIRE(name->offsets == NULL); - - NODENAME(node, name); -} - -isc_result_t -dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name) { - dns_name_t current; - isc_result_t result; - - REQUIRE(DNS_RBTNODE_VALID(node)); - REQUIRE(name != NULL); - REQUIRE(name->buffer != NULL); - - dns_name_init(¤t, NULL); - dns_name_reset(name); - - do { - INSIST(node != NULL); - - NODENAME(node, ¤t); - - result = dns_name_concatenate(name, ¤t, name, NULL); - if (result != ISC_R_SUCCESS) - break; - - node = get_upper_node(node); - } while (! dns_name_isabsolute(name)); - - return (result); -} - -char * -dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, unsigned int size) -{ - dns_fixedname_t fixedname; - dns_name_t *name; - isc_result_t result; - - REQUIRE(DNS_RBTNODE_VALID(node)); - REQUIRE(printname != NULL); - - name = dns_fixedname_initname(&fixedname); - result = dns_rbt_fullnamefromnode(node, name); - if (result == ISC_R_SUCCESS) - dns_name_format(name, printname, size); - else - snprintf(printname, size, "", - dns_result_totext(result)); - - return (printname); -} - -static isc_result_t -create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { - dns_rbtnode_t *node; - isc_region_t region; - unsigned int labels; - size_t nodelen; - - REQUIRE(name->offsets != NULL); - - dns_name_toregion(name, ®ion); - labels = dns_name_countlabels(name); - ENSURE(labels > 0); - - /* - * Allocate space for the node structure, the name, and the offsets. - */ - nodelen = sizeof(dns_rbtnode_t) + region.length + labels + 1; - node = (dns_rbtnode_t *)isc_mem_get(mctx, nodelen); - if (node == NULL) - return (ISC_R_NOMEMORY); - memset(node, 0, nodelen); - - node->is_root = 0; - PARENT(node) = NULL; - RIGHT(node) = NULL; - LEFT(node) = NULL; - DOWN(node) = NULL; - DATA(node) = NULL; - node->is_mmapped = 0; - node->down_is_relative = 0; - node->left_is_relative = 0; - node->right_is_relative = 0; - node->parent_is_relative = 0; - node->data_is_relative = 0; - node->rpz = 0; - -#ifdef DNS_RBT_USEHASH - HASHNEXT(node) = NULL; - HASHVAL(node) = 0; -#endif - - ISC_LINK_INIT(node, deadlink); - - LOCKNUM(node) = 0; - WILD(node) = 0; - DIRTY(node) = 0; - dns_rbtnode_refinit(node, 0); - node->find_callback = 0; - node->nsec = DNS_RBT_NSEC_NORMAL; - - MAKE_BLACK(node); - - /* - * The following is stored to make reconstructing a name from the - * stored value in the node easy: the length of the name, the number - * of labels, whether the name is absolute or not, the name itself, - * and the name's offsets table. - * - * XXX RTH - * The offsets table could be made smaller by eliminating the - * first offset, which is always 0. This requires changes to - * lib/dns/name.c. - * - * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned - * as it uses OLDNAMELEN. - */ - OLDNAMELEN(node) = NAMELEN(node) = region.length; - OLDOFFSETLEN(node) = OFFSETLEN(node) = labels; - ATTRS(node) = name->attributes; - - memmove(NAME(node), region.base, region.length); - memmove(OFFSETS(node), name->offsets, labels); - -#if DNS_RBT_USEMAGIC - node->magic = DNS_RBTNODE_MAGIC; -#endif - *nodep = node; - - return (ISC_R_SUCCESS); -} - -#ifdef DNS_RBT_USEHASH -static inline void -hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) { - unsigned int hash; - - REQUIRE(name != NULL); - - HASHVAL(node) = dns_name_fullhash(name, false); - - hash = HASHVAL(node) % rbt->hashsize; - HASHNEXT(node) = rbt->hashtable[hash]; - - rbt->hashtable[hash] = node; -} - -static isc_result_t -inithash(dns_rbt_t *rbt) { - unsigned int bytes; - - rbt->hashsize = RBT_HASH_SIZE; - bytes = (unsigned int)rbt->hashsize * sizeof(dns_rbtnode_t *); - rbt->hashtable = isc_mem_get(rbt->mctx, bytes); - - if (rbt->hashtable == NULL) - return (ISC_R_NOMEMORY); - - memset(rbt->hashtable, 0, bytes); - - return (ISC_R_SUCCESS); -} - -static void -rehash(dns_rbt_t *rbt, unsigned int newcount) { - unsigned int oldsize; - dns_rbtnode_t **oldtable; - dns_rbtnode_t *node; - dns_rbtnode_t *nextnode; - unsigned int hash; - unsigned int i; - - oldsize = (unsigned int)rbt->hashsize; - oldtable = rbt->hashtable; - do { - INSIST((rbt->hashsize * 2 + 1) > rbt->hashsize); - rbt->hashsize = rbt->hashsize * 2 + 1; - } while (newcount >= (rbt->hashsize * 3)); - rbt->hashtable = isc_mem_get(rbt->mctx, - rbt->hashsize * sizeof(dns_rbtnode_t *)); - if (rbt->hashtable == NULL) { - rbt->hashtable = oldtable; - rbt->hashsize = oldsize; - return; - } - - for (i = 0; i < rbt->hashsize; i++) - rbt->hashtable[i] = NULL; - - for (i = 0; i < oldsize; i++) { - for (node = oldtable[i]; node != NULL; node = nextnode) { - hash = HASHVAL(node) % rbt->hashsize; - nextnode = HASHNEXT(node); - HASHNEXT(node) = rbt->hashtable[hash]; - rbt->hashtable[hash] = node; - } - } - - isc_mem_put(rbt->mctx, oldtable, oldsize * sizeof(dns_rbtnode_t *)); -} - -static inline void -hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) { - REQUIRE(DNS_RBTNODE_VALID(node)); - - if (rbt->nodecount >= (rbt->hashsize * 3)) - rehash(rbt, rbt->nodecount); - - hash_add_node(rbt, node, name); -} - -static inline void -unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) { - unsigned int bucket; - dns_rbtnode_t *bucket_node; - - REQUIRE(DNS_RBTNODE_VALID(node)); - - bucket = HASHVAL(node) % rbt->hashsize; - bucket_node = rbt->hashtable[bucket]; - - if (bucket_node == node) { - rbt->hashtable[bucket] = HASHNEXT(node); - } else { - while (HASHNEXT(bucket_node) != node) { - INSIST(HASHNEXT(bucket_node) != NULL); - bucket_node = HASHNEXT(bucket_node); - } - HASHNEXT(bucket_node) = HASHNEXT(node); - } -} -#endif /* DNS_RBT_USEHASH */ - -static inline void -rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp) { - dns_rbtnode_t *child; - - REQUIRE(DNS_RBTNODE_VALID(node)); - REQUIRE(rootp != NULL); - - child = RIGHT(node); - INSIST(child != NULL); - - RIGHT(node) = LEFT(child); - if (LEFT(child) != NULL) - PARENT(LEFT(child)) = node; - LEFT(child) = node; - - PARENT(child) = PARENT(node); - - if (IS_ROOT(node)) { - *rootp = child; - child->is_root = 1; - node->is_root = 0; - - } else { - if (LEFT(PARENT(node)) == node) - LEFT(PARENT(node)) = child; - else - RIGHT(PARENT(node)) = child; - } - - PARENT(node) = child; -} - -static inline void -rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp) { - dns_rbtnode_t *child; - - REQUIRE(DNS_RBTNODE_VALID(node)); - REQUIRE(rootp != NULL); - - child = LEFT(node); - INSIST(child != NULL); - - LEFT(node) = RIGHT(child); - if (RIGHT(child) != NULL) - PARENT(RIGHT(child)) = node; - RIGHT(child) = node; - - PARENT(child) = PARENT(node); - - if (IS_ROOT(node)) { - *rootp = child; - child->is_root = 1; - node->is_root = 0; - - } else { - if (LEFT(PARENT(node)) == node) - LEFT(PARENT(node)) = child; - else - RIGHT(PARENT(node)) = child; - } - - PARENT(node) = child; -} - -/* - * This is the real workhorse of the insertion code, because it does the - * true red/black tree on a single level. - */ -static void -addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order, - dns_rbtnode_t **rootp) -{ - dns_rbtnode_t *child, *root, *parent, *grandparent; - dns_name_t add_name, current_name; - dns_offsets_t add_offsets, current_offsets; - - REQUIRE(rootp != NULL); - REQUIRE(DNS_RBTNODE_VALID(node) && LEFT(node) == NULL && - RIGHT(node) == NULL); - REQUIRE(current != NULL); - - root = *rootp; - if (root == NULL) { - /* - * First node of a level. - */ - MAKE_BLACK(node); - node->is_root = 1; - PARENT(node) = current; - *rootp = node; - return; - } - - child = root; - POST(child); - - dns_name_init(&add_name, add_offsets); - NODENAME(node, &add_name); - - dns_name_init(¤t_name, current_offsets); - NODENAME(current, ¤t_name); - - if (order < 0) { - INSIST(LEFT(current) == NULL); - LEFT(current) = node; - } else { - INSIST(RIGHT(current) == NULL); - RIGHT(current) = node; - } - - INSIST(PARENT(node) == NULL); - PARENT(node) = current; - - MAKE_RED(node); - - while (node != root && IS_RED(PARENT(node))) { - /* - * XXXDCL could do away with separate parent and grandparent - * variables. They are vestiges of the days before parent - * pointers. However, they make the code a little clearer. - */ - - parent = PARENT(node); - grandparent = PARENT(parent); - - if (parent == LEFT(grandparent)) { - child = RIGHT(grandparent); - if (child != NULL && IS_RED(child)) { - MAKE_BLACK(parent); - MAKE_BLACK(child); - MAKE_RED(grandparent); - node = grandparent; - } else { - if (node == RIGHT(parent)) { - rotate_left(parent, &root); - node = parent; - parent = PARENT(node); - grandparent = PARENT(parent); - } - MAKE_BLACK(parent); - MAKE_RED(grandparent); - rotate_right(grandparent, &root); - } - } else { - child = LEFT(grandparent); - if (child != NULL && IS_RED(child)) { - MAKE_BLACK(parent); - MAKE_BLACK(child); - MAKE_RED(grandparent); - node = grandparent; - } else { - if (node == LEFT(parent)) { - rotate_right(parent, &root); - node = parent; - parent = PARENT(node); - grandparent = PARENT(parent); - } - MAKE_BLACK(parent); - MAKE_RED(grandparent); - rotate_left(grandparent, &root); - } - } - } - - MAKE_BLACK(root); - ENSURE(IS_ROOT(root)); - *rootp = root; - - return; -} - -/* - * This is the real workhorse of the deletion code, because it does the - * true red/black tree on a single level. - */ -static void -deletefromlevel(dns_rbtnode_t *item, dns_rbtnode_t **rootp) { - dns_rbtnode_t *child, *sibling, *parent; - dns_rbtnode_t *successor; - - REQUIRE(item != NULL); - - /* - * Verify that the parent history is (apparently) correct. - */ - INSIST((IS_ROOT(item) && *rootp == item) || - (! IS_ROOT(item) && - (LEFT(PARENT(item)) == item || - RIGHT(PARENT(item)) == item))); - - child = NULL; - - if (LEFT(item) == NULL) { - if (RIGHT(item) == NULL) { - if (IS_ROOT(item)) { - /* - * This is the only item in the tree. - */ - *rootp = NULL; - return; - } - } else - /* - * This node has one child, on the right. - */ - child = RIGHT(item); - - } else if (RIGHT(item) == NULL) - /* - * This node has one child, on the left. - */ - child = LEFT(item); - else { - dns_rbtnode_t holder, *tmp = &holder; - - /* - * This node has two children, so it cannot be directly - * deleted. Find its immediate in-order successor and - * move it to this location, then do the deletion at the - * old site of the successor. - */ - successor = RIGHT(item); - while (LEFT(successor) != NULL) - successor = LEFT(successor); - - /* - * The successor cannot possibly have a left child; - * if there is any child, it is on the right. - */ - if (RIGHT(successor) != NULL) - child = RIGHT(successor); - - /* - * Swap the two nodes; it would be simpler to just replace - * the value being deleted with that of the successor, - * but this rigamarole is done so the caller has complete - * control over the pointers (and memory allocation) of - * all of nodes. If just the key value were removed from - * the tree, the pointer to the node would be unchanged. - */ - - /* - * First, put the successor in the tree location of the - * node to be deleted. Save its existing tree pointer - * information, which will be needed when linking up - * delete to the successor's old location. - */ - memmove(tmp, successor, sizeof(dns_rbtnode_t)); - - if (IS_ROOT(item)) { - *rootp = successor; - successor->is_root = true; - item->is_root = false; - - } else - if (LEFT(PARENT(item)) == item) - LEFT(PARENT(item)) = successor; - else - RIGHT(PARENT(item)) = successor; - - PARENT(successor) = PARENT(item); - LEFT(successor) = LEFT(item); - RIGHT(successor) = RIGHT(item); - COLOR(successor) = COLOR(item); - - if (LEFT(successor) != NULL) - PARENT(LEFT(successor)) = successor; - if (RIGHT(successor) != successor) - PARENT(RIGHT(successor)) = successor; - - /* - * Now relink the node to be deleted into the - * successor's previous tree location. PARENT(tmp) - * is the successor's original parent. - */ - INSIST(! IS_ROOT(item)); - - if (PARENT(tmp) == item) { - /* - * Node being deleted was successor's parent. - */ - RIGHT(successor) = item; - PARENT(item) = successor; - - } else { - LEFT(PARENT(tmp)) = item; - PARENT(item) = PARENT(tmp); - } - - /* - * Original location of successor node has no left. - */ - LEFT(item) = NULL; - RIGHT(item) = RIGHT(tmp); - COLOR(item) = COLOR(tmp); - } - - /* - * Remove the node by removing the links from its parent. - */ - if (! IS_ROOT(item)) { - if (LEFT(PARENT(item)) == item) - LEFT(PARENT(item)) = child; - else - RIGHT(PARENT(item)) = child; - - if (child != NULL) - PARENT(child) = PARENT(item); - - } else { - /* - * This is the root being deleted, and at this point - * it is known to have just one child. - */ - *rootp = child; - child->is_root = 1; - PARENT(child) = PARENT(item); - } - - /* - * Fix color violations. - */ - if (IS_BLACK(item)) { - /* cppcheck-suppress nullPointerRedundantCheck symbolName=item */ - parent = PARENT(item); - - while (child != *rootp && IS_BLACK(child)) { - INSIST(child == NULL || ! IS_ROOT(child)); - - if (LEFT(parent) == child) { - sibling = RIGHT(parent); - - if (IS_RED(sibling)) { - MAKE_BLACK(sibling); - MAKE_RED(parent); - rotate_left(parent, rootp); - sibling = RIGHT(parent); - } - - INSIST(sibling != NULL); - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=sibling */ - if (IS_BLACK(LEFT(sibling)) && - IS_BLACK(RIGHT(sibling))) { - MAKE_RED(sibling); - child = parent; - - } else { - - if (IS_BLACK(RIGHT(sibling))) { - MAKE_BLACK(LEFT(sibling)); - MAKE_RED(sibling); - rotate_right(sibling, rootp); - sibling = RIGHT(parent); - } - - COLOR(sibling) = COLOR(parent); - MAKE_BLACK(parent); - INSIST(RIGHT(sibling) != NULL); - MAKE_BLACK(RIGHT(sibling)); - rotate_left(parent, rootp); - child = *rootp; - } - - } else { - /* - * Child is parent's right child. - * Everything is done the same as above, - * except mirrored. - */ - sibling = LEFT(parent); - - if (IS_RED(sibling)) { - MAKE_BLACK(sibling); - MAKE_RED(parent); - rotate_right(parent, rootp); - sibling = LEFT(parent); - } - - INSIST(sibling != NULL); - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=sibling */ - if (IS_BLACK(LEFT(sibling)) && - IS_BLACK(RIGHT(sibling))) { - MAKE_RED(sibling); - child = parent; - - } else { - if (IS_BLACK(LEFT(sibling))) { - MAKE_BLACK(RIGHT(sibling)); - MAKE_RED(sibling); - rotate_left(sibling, rootp); - sibling = LEFT(parent); - } - - COLOR(sibling) = COLOR(parent); - MAKE_BLACK(parent); - INSIST(LEFT(sibling) != NULL); - MAKE_BLACK(LEFT(sibling)); - rotate_right(parent, rootp); - child = *rootp; - } - } - - parent = PARENT(child); - } - - if (IS_RED(child)) - MAKE_BLACK(child); - } -} - -static void -freenode(dns_rbt_t *rbt, dns_rbtnode_t **nodep) { - dns_rbtnode_t *node = *nodep; - - if (node->is_mmapped == 0) { - isc_mem_put(rbt->mctx, node, NODE_SIZE(node)); - } - *nodep = NULL; - - rbt->nodecount--; -} - -static void -deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, bool unhash, - dns_rbtnode_t **nodep) -{ - dns_rbtnode_t *root = *nodep; - - while (root != NULL) { - /* - * If there is a left, right or down node, walk into it - * and iterate. - */ - if (LEFT(root) != NULL) { - dns_rbtnode_t *node = root; - root = LEFT(root); - LEFT(node) = NULL; - } else if (RIGHT(root) != NULL) { - dns_rbtnode_t *node = root; - root = RIGHT(root); - RIGHT(node) = NULL; - } else if (DOWN(root) != NULL) { - dns_rbtnode_t *node = root; - root = DOWN(root); - DOWN(node) = NULL; - } else { - /* - * There are no left, right or down nodes, so we - * can free this one and go back to its parent. - */ - dns_rbtnode_t *node = root; - root = PARENT(root); - - if (rbt->data_deleter != NULL && DATA(node) != NULL) { - rbt->data_deleter(DATA(node), - rbt->deleter_arg); - } - if (unhash) - unhash_node(rbt, node); - /* - * Note: we don't call unhash_node() here as we - * are destroying the complete RBT tree. - */ -#if DNS_RBT_USEMAGIC - node->magic = 0; -#endif - freenode(rbt, &node); - if (quantum != 0 && --quantum == 0) - break; - } - } - - *nodep = root; -} - -static size_t -getheight_helper(dns_rbtnode_t *node) { - size_t dl, dr; - size_t this_height, down_height; - - if (node == NULL) - return (0); - - dl = getheight_helper(LEFT(node)); - dr = getheight_helper(RIGHT(node)); - - this_height = ISC_MAX(dl + 1, dr + 1); - down_height = getheight_helper(DOWN(node)); - - return (ISC_MAX(this_height, down_height)); -} - -size_t -dns__rbt_getheight(dns_rbt_t *rbt) { - return (getheight_helper(rbt->root)); -} - -static bool -check_properties_helper(dns_rbtnode_t *node) { - if (node == NULL) - return (true); - - if (IS_RED(node)) { - /* Root nodes must be BLACK. */ - if (IS_ROOT(node)) - return (false); - - /* Both children of RED nodes must be BLACK. */ - if (IS_RED(LEFT(node)) || IS_RED(RIGHT(node))) - return (false); - } - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=node */ - if ((DOWN(node) != NULL) && (!IS_ROOT(DOWN(node)))) - return (false); - - if (IS_ROOT(node)) { - if ((PARENT(node) != NULL) && - (DOWN(PARENT(node)) != node)) - return (false); - - if (get_upper_node(node) != PARENT(node)) - return (false); - } - - /* If node is assigned to the down_ pointer of its parent, it is - * a subtree root and must have the flag set. - */ - if (((!PARENT(node)) || - (DOWN(PARENT(node)) == node)) && - (!IS_ROOT(node))) - { - return (false); - } - - /* Repeat tests with this node's children. */ - return (check_properties_helper(LEFT(node)) && - check_properties_helper(RIGHT(node)) && - check_properties_helper(DOWN(node))); -} - -static bool -check_black_distance_helper(dns_rbtnode_t *node, size_t *distance) { - size_t dl, dr, dd; - - if (node == NULL) { - *distance = 1; - return (true); - } - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=node */ - if (!check_black_distance_helper(LEFT(node), &dl)) - return (false); - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=node */ - if (!check_black_distance_helper(RIGHT(node), &dr)) - return (false); - - /* cppcheck-suppress nullPointerRedundantCheck symbolName=node */ - if (!check_black_distance_helper(DOWN(node), &dd)) - return (false); - - /* Left and right side black node counts must match. */ - if (dl != dr) - return (false); - - if (IS_BLACK(node)) - dl++; - - *distance = dl; - - return (true); -} - -bool -dns__rbt_checkproperties(dns_rbt_t *rbt) { - size_t dd; - - if (!check_properties_helper(rbt->root)) - return (false); - - /* Path from a given node to all its leaves must contain the - * same number of BLACK child nodes. This is done separately - * here instead of inside check_properties_helper() as - * it would take (n log n) complexity otherwise. - */ - return (check_black_distance_helper(rbt->root, &dd)); -} - -static void -dns_rbt_indent(FILE *f, int depth) { - int i; - - fprintf(f, "%4d ", depth); - - for (i = 0; i < depth; i++) - fprintf(f, "- "); -} - -void -dns_rbt_printnodeinfo(dns_rbtnode_t *n, FILE *f) { - - if (n == NULL) { - fprintf(f, "Null node\n"); - return; - } - - fprintf(f, "Node info for nodename: "); - printnodename(n, true, f); - fprintf(f, "\n"); - - fprintf(f, "n = %p\n", n); - - fprintf(f, "Relative pointers: %s%s%s%s%s\n", - (n->parent_is_relative == 1 ? " P" : ""), - (n->right_is_relative == 1 ? " R" : ""), - (n->left_is_relative == 1 ? " L" : ""), - (n->down_is_relative == 1 ? " D" : ""), - (n->data_is_relative == 1 ? " T" : "")); - - fprintf(f, "node lock address = %u\n", n->locknum); - - fprintf(f, "Parent: %p\n", n->parent); - fprintf(f, "Right: %p\n", n->right); - fprintf(f, "Left: %p\n", n->left); - fprintf(f, "Down: %p\n", n->down); - fprintf(f, "Data: %p\n", n->data); -} - -static void -printnodename(dns_rbtnode_t *node, bool quoted, FILE *f) { - isc_region_t r; - dns_name_t name; - char buffer[DNS_NAME_FORMATSIZE]; - dns_offsets_t offsets; - - r.length = NAMELEN(node); - r.base = NAME(node); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &r); - - dns_name_format(&name, buffer, sizeof(buffer)); - - if (quoted) - fprintf(f, "\"%s\"", buffer); - else - fprintf(f, "%s", buffer); -} - -static void -print_text_helper(dns_rbtnode_t *root, dns_rbtnode_t *parent, - int depth, const char *direction, - void (*data_printer)(FILE *, void *), FILE *f) -{ - dns_rbt_indent(f, depth); - - if (root != NULL) { - printnodename(root, true, f); - /* - * Don't use IS_RED(root) as it tests for 'root != NULL' - * and cppcheck produces false positives. - */ - fprintf(f, " (%s, %s", direction, - COLOR(root) == RED ? "RED" : "BLACK"); - - if ((! IS_ROOT(root) && PARENT(root) != parent) || - ( IS_ROOT(root) && depth > 0 && - DOWN(PARENT(root)) != root)) { - - fprintf(f, " (BAD parent pointer! -> "); - if (PARENT(root) != NULL) - printnodename(PARENT(root), true, f); - else - fprintf(f, "NULL"); - fprintf(f, ")"); - } - - fprintf(f, ")"); - - if (root->data != NULL && data_printer != NULL) { - fprintf(f, " data@%p: ", root->data); - data_printer(f, root->data); - } - fprintf(f, "\n"); - - depth++; - - /* - * Don't use IS_RED(root) as it tests for 'root != NULL' - * and cppcheck produces false positives. - */ - if (COLOR(root) == RED && IS_RED(LEFT(root))) { - fprintf(f, "** Red/Red color violation on left\n"); - } - print_text_helper(LEFT(root), root, depth, "left", - data_printer, f); - - /* - * Don't use IS_RED(root) as cppcheck produces false positives. - */ - if (COLOR(root) == RED && IS_RED(RIGHT(root))) { - fprintf(f, "** Red/Red color violation on right\n"); - } - print_text_helper(RIGHT(root), root, depth, "right", - data_printer, f); - - print_text_helper(DOWN(root), NULL, depth, "down", - data_printer, f); - } else { - fprintf(f, "NULL (%s)\n", direction); - } -} - -void -dns_rbt_printtext(dns_rbt_t *rbt, - void (*data_printer)(FILE *, void *), FILE *f) -{ - REQUIRE(VALID_RBT(rbt)); - - print_text_helper(rbt->root, NULL, 0, "root", data_printer, f); -} - -static int -print_dot_helper(dns_rbtnode_t *node, unsigned int *nodecount, - bool show_pointers, FILE *f) -{ - unsigned int l, r, d; - - if (node == NULL) - return (0); - - l = print_dot_helper(LEFT(node), nodecount, show_pointers, f); - r = print_dot_helper(RIGHT(node), nodecount, show_pointers, f); - d = print_dot_helper(DOWN(node), nodecount, show_pointers, f); - - *nodecount += 1; - - fprintf(f, "node%u[label = \" | ", *nodecount); - printnodename(node, false, f); - fprintf(f, "|"); - - if (show_pointers) - fprintf(f, "| n=%p| p=%p", node, PARENT(node)); - - fprintf(f, "\"] ["); - - if (IS_RED(node)) - fprintf(f, "color=red"); - else - fprintf(f, "color=black"); - - /* XXXMUKS: verify that IS_ROOT() indicates subtree root and not - * forest root. - */ - if (IS_ROOT(node)) - fprintf(f, ",penwidth=3"); - - if (IS_EMPTY(node)) - fprintf(f, ",style=filled,fillcolor=lightgrey"); - - fprintf(f, "];\n"); - - if (LEFT(node) != NULL) - fprintf(f, "\"node%u\":f0 -> \"node%u\":f1;\n", *nodecount, l); - - if (DOWN(node) != NULL) - fprintf(f, "\"node%u\":f1 -> \"node%u\":f1 [penwidth=5];\n", - *nodecount, d); - - if (RIGHT(node) != NULL) - fprintf(f, "\"node%u\":f2 -> \"node%u\":f1;\n", *nodecount, r); - - return (*nodecount); -} - -void -dns_rbt_printdot(dns_rbt_t *rbt, bool show_pointers, FILE *f) { - unsigned int nodecount = 0; - - REQUIRE(VALID_RBT(rbt)); - - fprintf(f, "digraph g {\n"); - fprintf(f, "node [shape = record,height=.1];\n"); - print_dot_helper(rbt->root, &nodecount, show_pointers, f); - fprintf(f, "}\n"); -} - -/* - * Chain Functions - */ - -void -dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) { - - REQUIRE(chain != NULL); - - /* - * Initialize 'chain'. - */ - chain->mctx = mctx; - chain->end = NULL; - chain->level_count = 0; - chain->level_matches = 0; - memset(chain->levels, 0, sizeof(chain->levels)); - - chain->magic = CHAIN_MAGIC; -} - -isc_result_t -dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin, dns_rbtnode_t **node) -{ - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(VALID_CHAIN(chain)); - - if (node != NULL) - *node = chain->end; - - if (chain->end == NULL) - return (ISC_R_NOTFOUND); - - if (name != NULL) { - NODENAME(chain->end, name); - - if (chain->level_count == 0) { - /* - * Names in the top level tree are all absolute. - * Always make 'name' relative. - */ - INSIST(dns_name_isabsolute(name)); - - /* - * This is cheaper than dns_name_getlabelsequence(). - */ - name->labels--; - name->length--; - name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; - } - } - - if (origin != NULL) { - if (chain->level_count > 0) - result = chain_name(chain, origin, false); - else - result = dns_name_copy(dns_rootname, origin, NULL); - } - - return (result); -} - -isc_result_t -dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin) -{ - dns_rbtnode_t *current, *previous, *predecessor; - isc_result_t result = ISC_R_SUCCESS; - bool new_origin = false; - - REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); - - predecessor = NULL; - - current = chain->end; - - if (LEFT(current) != NULL) { - /* - * Moving left one then right as far as possible is the - * previous node, at least for this level. - */ - current = LEFT(current); - - while (RIGHT(current) != NULL) - current = RIGHT(current); - - predecessor = current; - - } else { - /* - * No left links, so move toward the root. If at any point on - * the way there the link from parent to child is a right - * link, then the parent is the previous node, at least - * for this level. - */ - while (! IS_ROOT(current)) { - previous = current; - current = PARENT(current); - - if (RIGHT(current) == previous) { - predecessor = current; - break; - } - } - } - - if (predecessor != NULL) { - /* - * Found a predecessor node in this level. It might not - * really be the predecessor, however. - */ - if (DOWN(predecessor) != NULL) { - /* - * The predecessor is really down at least one level. - * Go down and as far right as possible, and repeat - * as long as the rightmost node has a down pointer. - */ - do { - /* - * XXX DCL Need to do something about origins - * here. See whether to go down, and if so - * whether it is truly what Bob calls a - * new origin. - */ - ADD_LEVEL(chain, predecessor); - predecessor = DOWN(predecessor); - - /* XXX DCL duplicated from above; clever - * way to unduplicate? */ - - while (RIGHT(predecessor) != NULL) - predecessor = RIGHT(predecessor); - } while (DOWN(predecessor) != NULL); - - /* XXX DCL probably needs work on the concept */ - if (origin != NULL) - new_origin = true; - } - - } else if (chain->level_count > 0) { - /* - * Dang, didn't find a predecessor in this level. - * Got to the root of this level without having traversed - * any right links. Ascend the tree one level; the - * node that points to this tree is the predecessor. - */ - INSIST(chain->level_count > 0 && IS_ROOT(current)); - predecessor = chain->levels[--chain->level_count]; - - /* XXX DCL probably needs work on the concept */ - /* - * Don't declare an origin change when the new origin is "." - * at the top level tree, because "." is declared as the origin - * for the second level tree. - */ - if (origin != NULL && - (chain->level_count > 0 || OFFSETLEN(predecessor) > 1)) - new_origin = true; - } - - if (predecessor != NULL) { - chain->end = predecessor; - - if (new_origin) { - result = dns_rbtnodechain_current(chain, name, origin, - NULL); - if (result == ISC_R_SUCCESS) - result = DNS_R_NEWORIGIN; - - } else - result = dns_rbtnodechain_current(chain, name, NULL, - NULL); - - } else - result = ISC_R_NOMORE; - - return (result); -} - -isc_result_t -dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin) -{ - dns_rbtnode_t *current, *successor; - isc_result_t result = ISC_R_SUCCESS; - bool new_origin = false; - - REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); - - successor = NULL; - - current = chain->end; - - if (DOWN(current) != NULL) { - /* - * Don't declare an origin change when the new origin is "." - * at the second level tree, because "." is already declared - * as the origin for the top level tree. - */ - if (chain->level_count > 0 || - OFFSETLEN(current) > 1) - new_origin = true; - - ADD_LEVEL(chain, current); - current = DOWN(current); - - while (LEFT(current) != NULL) - current = LEFT(current); - - successor = current; - } - - if (successor != NULL) { - chain->end = successor; - - /* - * It is not necessary to use dns_rbtnodechain_current like - * the other functions because this function will never - * find a node in the topmost level. This is because the - * root level will never be more than one name, and everything - * in the megatree is a successor to that node, down at - * the second level or below. - */ - - if (name != NULL) - NODENAME(chain->end, name); - - if (new_origin) { - if (origin != NULL) - result = chain_name(chain, origin, false); - - if (result == ISC_R_SUCCESS) - result = DNS_R_NEWORIGIN; - - } else - result = ISC_R_SUCCESS; - - } else - result = ISC_R_NOMORE; - - return (result); -} - -isc_result_t -dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name) { - dns_rbtnode_t *current, *previous, *successor; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); - - successor = NULL; - - current = chain->end; - - if (RIGHT(current) == NULL) { - while (! IS_ROOT(current)) { - previous = current; - current = PARENT(current); - - if (LEFT(current) == previous) { - successor = current; - break; - } - } - } else { - current = RIGHT(current); - - while (LEFT(current) != NULL) - current = LEFT(current); - - successor = current; - } - - if (successor != NULL) { - chain->end = successor; - - if (name != NULL) - NODENAME(chain->end, name); - - result = ISC_R_SUCCESS; - } else - result = ISC_R_NOMORE; - - return (result); -} - -isc_result_t -dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name, - dns_name_t *origin) -{ - dns_rbtnode_t *current, *previous, *successor; - isc_result_t result = ISC_R_SUCCESS; - bool new_origin = false; - - REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); - - successor = NULL; - - current = chain->end; - - /* - * If there is a level below this node, the next node is the leftmost - * node of the next level. - */ - if (DOWN(current) != NULL) { - /* - * Don't declare an origin change when the new origin is "." - * at the second level tree, because "." is already declared - * as the origin for the top level tree. - */ - if (chain->level_count > 0 || - OFFSETLEN(current) > 1) - new_origin = true; - - ADD_LEVEL(chain, current); - current = DOWN(current); - - while (LEFT(current) != NULL) - current = LEFT(current); - - successor = current; - - } else if (RIGHT(current) == NULL) { - /* - * The successor is up, either in this level or a previous one. - * Head back toward the root of the tree, looking for any path - * that was via a left link; the successor is the node that has - * that left link. In the event the root of the level is - * reached without having traversed any left links, ascend one - * level and look for either a right link off the point of - * ascent, or search for a left link upward again, repeating - * ascends until either case is true. - */ - do { - while (! IS_ROOT(current)) { - previous = current; - current = PARENT(current); - - if (LEFT(current) == previous) { - successor = current; - break; - } - } - - if (successor == NULL) { - /* - * Reached the root without having traversed - * any left pointers, so this level is done. - */ - if (chain->level_count == 0) { - /* - * If the tree we are iterating over - * was modified since this chain was - * initialized in a way that caused - * node splits to occur, "current" may - * now be pointing to a root node which - * appears to be at level 0, but still - * has a parent. If that happens, - * abort. Otherwise, we are done - * looking for a successor as we really - * reached the root node on level 0. - */ - INSIST(PARENT(current) == NULL); - break; - } - - current = chain->levels[--chain->level_count]; - new_origin = true; - - if (RIGHT(current) != NULL) - break; - } - } while (successor == NULL); - } - - if (successor == NULL && RIGHT(current) != NULL) { - current = RIGHT(current); - - while (LEFT(current) != NULL) - current = LEFT(current); - - successor = current; - } - - if (successor != NULL) { - /* - * If we determine that the current node is the successor to - * itself, we will run into an infinite loop, so abort instead. - */ - INSIST(chain->end != successor); - - chain->end = successor; - - /* - * It is not necessary to use dns_rbtnodechain_current like - * the other functions because this function will never - * find a node in the topmost level. This is because the - * root level will never be more than one name, and everything - * in the megatree is a successor to that node, down at - * the second level or below. - */ - - if (name != NULL) - NODENAME(chain->end, name); - - if (new_origin) { - if (origin != NULL) - result = chain_name(chain, origin, false); - - if (result == ISC_R_SUCCESS) - result = DNS_R_NEWORIGIN; - - } else - result = ISC_R_SUCCESS; - - } else - result = ISC_R_NOMORE; - - return (result); -} - -isc_result_t -dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, - dns_name_t *name, dns_name_t *origin) - -{ - isc_result_t result; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(VALID_CHAIN(chain)); - - dns_rbtnodechain_reset(chain); - - chain->end = rbt->root; - - result = dns_rbtnodechain_current(chain, name, origin, NULL); - - if (result == ISC_R_SUCCESS) - result = DNS_R_NEWORIGIN; - - return (result); -} - -isc_result_t -dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, - dns_name_t *name, dns_name_t *origin) - -{ - isc_result_t result; - - REQUIRE(VALID_RBT(rbt)); - REQUIRE(VALID_CHAIN(chain)); - - dns_rbtnodechain_reset(chain); - - result = move_chain_to_last(chain, rbt->root); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_rbtnodechain_current(chain, name, origin, NULL); - - if (result == ISC_R_SUCCESS) - result = DNS_R_NEWORIGIN; - - return (result); -} - - -void -dns_rbtnodechain_reset(dns_rbtnodechain_t *chain) { - - REQUIRE(VALID_CHAIN(chain)); - - /* - * Free any dynamic storage associated with 'chain', and then - * reinitialize 'chain'. - */ - chain->end = NULL; - chain->level_count = 0; - chain->level_matches = 0; -} - -void -dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain) { - /* - * Free any dynamic storage associated with 'chain', and then - * invalidate 'chain'. - */ - - dns_rbtnodechain_reset(chain); - - chain->magic = 0; -} - -/* XXXMUKS: - * - * - worth removing inline as static functions are inlined automatically - * where suitable by modern compilers. - * - bump the size of dns_rbt.nodecount to size_t. - * - the dumpfile header also contains a nodecount that is unsigned - * int. If large files (> 2^32 nodes) are to be supported, the - * allocation for this field should be increased. - */ diff --git a/lib/dns-pkcs11/rbtdb.c b/lib/dns-pkcs11/rbtdb.c deleted file mode 100644 index 8ea4d47..0000000 --- a/lib/dns-pkcs11/rbtdb.c +++ /dev/null @@ -1,10720 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -/* #define inline */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef WIN32 -#include -#else -#define PROT_READ 0x01 -#define PROT_WRITE 0x02 -#define MAP_PRIVATE 0x0002 -#define MAP_FAILED ((void *)-1) -#endif - -#ifdef DNS_RBTDB_VERSION64 -#include "rbtdb64.h" -#else -#include "rbtdb.h" -#endif - -#ifdef DNS_RBTDB_VERSION64 -#define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '8') -#else -#define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '4') -#endif - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/* - * This is the map file header for RBTDB images. It is populated, and then - * written, as the LAST thing done to the file. Writing this last (with - * zeros in the header area initially) will ensure that the header is only - * valid when the RBTDB image is also valid. - */ -typedef struct rbtdb_file_header rbtdb_file_header_t; - -/* Header length, always the same size regardless of structure size */ -#define RBTDB_HEADER_LENGTH 1024 - -struct rbtdb_file_header { - char version1[32]; - uint32_t ptrsize; - unsigned int bigendian:1; - uint64_t tree; - uint64_t nsec; - uint64_t nsec3; - - char version2[32]; /* repeated; must match version1 */ -}; - - -/*% - * Note that "impmagic" is not the first four bytes of the struct, so - * ISC_MAGIC_VALID cannot be used. - */ -#define VALID_RBTDB(rbtdb) ((rbtdb) != NULL && \ - (rbtdb)->common.impmagic == RBTDB_MAGIC) - -#ifdef DNS_RBTDB_VERSION64 -typedef uint64_t rbtdb_serial_t; -/*% - * Make casting easier in symbolic debuggers by using different names - * for the 64 bit version. - */ -#define dns_rbtdb_t dns_rbtdb64_t -#define rdatasetheader_t rdatasetheader64_t -#define rbtdb_version_t rbtdb_version64_t - -#define once once64 -#define FILE_VERSION FILE_VERSION64 -#define init_count init_count64 - -#define cache_methods cache_methods64 -#define dbiterator_methods dbiterator_methods64 -#define rdataset_methods rdataset_methods64 -#define rdatasetiter_methods rdatasetiter_methods64 -#define slab_methods slab_methods64 -#define zone_methods zone_methods64 - -#define acache_callback acache_callback64 -#define acache_cancelentry acache_cancelentry64 -#define activeempty activeempty64 -#define activeemptynode activeemptynode64 -#define add32 add64 -#define add_changed add_changed64 -#define add_empty_wildcards add_empty_wildcards64 -#define add_wildcard_magic add_wildcard_magic64 -#define addclosest addclosest64 -#define addnoqname addnoqname64 -#define addrdataset addrdataset64 -#define adjust_quantum adjust_quantum64 -#define allocate_version allocate_version64 -#define allrdatasets allrdatasets64 -#define attach attach64 -#define attachnode attachnode64 -#define attachversion attachversion64 -#define beginload beginload64 -#define bind_rdataset bind_rdataset64 -#define cache_find cache_find64 -#define cache_findrdataset cache_findrdataset64 -#define cache_findzonecut cache_findzonecut64 -#define cache_zonecut_callback cache_zonecut_callback64 -#define check_stale_header check_stale_header64 -#define clean_cache_node clean_cache_node64 -#define clean_stale_headers clean_stale_headers64 -#define clean_zone_node clean_zone_node64 -#define cleanup_dead_nodes cleanup_dead_nodes64 -#define cleanup_dead_nodes_callback cleanup_dead_nodes_callback64 -#define cleanup_nondirty cleanup_nondirty64 -#define closeversion closeversion64 -#define cname_and_other_data cname_and_other_data64 -#define createiterator createiterator64 -#define currentversion currentversion64 -#define dbiterator_current dbiterator_current64 -#define dbiterator_destroy dbiterator_destroy64 -#define dbiterator_first dbiterator_first64 -#define dbiterator_last dbiterator_last64 -#define dbiterator_next dbiterator_next64 -#define dbiterator_origin dbiterator_origin64 -#define dbiterator_pause dbiterator_pause64 -#define dbiterator_prev dbiterator_prev64 -#define dbiterator_seek dbiterator_seek64 -#define decrement_reference decrement_reference64 -#define delegating_type delegating_type64 -#define delete_callback delete_callback64 -#define delete_node delete_node64 -#define deleterdataset deleterdataset64 -#define dereference_iter_node dereference_iter_node64 -#define deserialize32 deserialize64 -#define detach detach64 -#define detachnode detachnode64 -#define dump dump64 -#define endload endload64 -#define expire_header expire_header64 -#define expirenode expirenode64 -#define find_closest_nsec find_closest_nsec64 -#define find_coveringnsec find_coveringnsec64 -#define find_deepest_zonecut find_deepest_zonecut64 -#define find_wildcard find_wildcard64 -#define findnode findnode64 -#define findnodeintree findnodeintree64 -#define findnsec3node findnsec3node64 -#define flush_deletions flush_deletions64 -#define free_acachearray free_acachearray64 -#define free_noqname free_noqname64 -#define free_rbtdb free_rbtdb64 -#define free_rbtdb_callback free_rbtdb_callback64 -#define free_rdataset free_rdataset64 -#define getnsec3parameters getnsec3parameters64 -#define getoriginnode getoriginnode64 -#define getrrsetstats getrrsetstats64 -#define getsigningtime getsigningtime64 -#define getsize getsize64 -#define hashsize hashsize64 -#define init_file_version init_file_version64 -#define init_rdataset init_rdataset64 -#define isdnssec isdnssec64 -#define ispersistent ispersistent64 -#define issecure issecure64 -#define iszonesecure iszonesecure64 -#define loading_addrdataset loading_addrdataset64 -#define loadnode loadnode64 -#define make_least_version make_least_version64 -#define mark_stale_header mark_stale_header64 -#define match_header_version match_header_version64 -#define matchparams matchparams64 -#define maybe_free_rbtdb maybe_free_rbtdb64 -#define need_headerupdate need_headerupdate64 -#define new_rdataset new_rdataset64 -#define new_reference new_reference64 -#define newversion newversion64 -#define nodecount nodecount64 -#define nodefullname nodefullname64 -#define overmem overmem64 -#define overmem_purge overmem_purge64 -#define previous_closest_nsec previous_closest_nsec64 -#define printnode printnode64 -#define prune_tree prune_tree64 -#define rbt_datafixer rbt_datafixer64 -#define rbt_datawriter rbt_datawriter64 -#define rbtdb_write_header rbtdb_write_header64 -#define rbtdb_zero_header rbtdb_zero_header64 -#define rdataset_clearprefetch rdataset_clearprefetch64 -#define rdataset_clone rdataset_clone64 -#define rdataset_count rdataset_count64 -#define rdataset_current rdataset_current64 -#define rdataset_disassociate rdataset_disassociate64 -#define rdataset_expire rdataset_expire64 -#define rdataset_first rdataset_first64 -#define rdataset_getadditional rdataset_getadditional64 -#define rdataset_getclosest rdataset_getclosest64 -#define rdataset_getnoqname rdataset_getnoqname64 -#define rdataset_getownercase rdataset_getownercase64 -#define rdataset_next rdataset_next64 -#define rdataset_putadditional rdataset_putadditional64 -#define rdataset_setadditional rdataset_setadditional64 -#define rdataset_setownercase rdataset_setownercase64 -#define rdataset_settrust rdataset_settrust64 -#define rdatasetiter_current rdatasetiter_current64 -#define rdatasetiter_destroy rdatasetiter_destroy64 -#define rdatasetiter_first rdatasetiter_first64 -#define rdatasetiter_next rdatasetiter_next64 -#define reactivate_node reactivate_node64 -#define reference_iter_node reference_iter_node64 -#define resign_delete resign_delete64 -#define resign_insert resign_insert64 -#define resign_sooner resign_sooner64 -#define resigned resigned64 -#define resume_iteration resume_iteration64 -#define rollback_node rollback_node64 -#define rpz_attach rpz_attach64 -#define rpz_ready rpz_ready64 -#define serialize serialize64 -#define set_index set_index64 -#define set_ttl set_ttl64 -#define setcachestats setcachestats64 -#define setnsec3parameters setnsec3parameters64 -#define setownercase setownercase64 -#define setsigningtime setsigningtime64 -#define settask settask64 -#define setup_delegation setup_delegation64 -#define subtractrdataset subtractrdataset64 -#define ttl_sooner ttl_sooner64 -#define update_cachestats update_cachestats64 -#define update_header update_header64 -#define update_newheader update_newheader64 -#define update_recordsandbytes update_recordsandbytes64 -#define update_rrsetstats update_rrsetstats64 -#define valid_glue valid_glue64 -#define zone_find zone_find64 -#define zone_findrdataset zone_findrdataset64 -#define zone_findzonecut zone_findzonecut64 -#define zone_zonecut_callback zone_zonecut_callback64 - -#else -typedef uint32_t rbtdb_serial_t; -#endif - -typedef uint32_t rbtdb_rdatatype_t; - -#define RBTDB_RDATATYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF)) -#define RBTDB_RDATATYPE_EXT(type) ((dns_rdatatype_t)((type) >> 16)) -#define RBTDB_RDATATYPE_VALUE(base, ext) ((rbtdb_rdatatype_t)(((uint32_t)ext) << 16) | (((uint32_t)base) & 0xffff)) - -#define RBTDB_RDATATYPE_SIGNSEC \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec) -#define RBTDB_RDATATYPE_SIGNSEC3 \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3) -#define RBTDB_RDATATYPE_SIGNS \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns) -#define RBTDB_RDATATYPE_SIGCNAME \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname) -#define RBTDB_RDATATYPE_SIGDNAME \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname) -#define RBTDB_RDATATYPE_SIGDS \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds) -#define RBTDB_RDATATYPE_SIGSOA \ - RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa) -#define RBTDB_RDATATYPE_NCACHEANY \ - RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) - -/* - * We use rwlock for DB lock only when ISC_RWLOCK_USEATOMIC is non 0. - * Using rwlock is effective with regard to lookup performance only when - * it is implemented in an efficient way. - * Otherwise, it is generally wise to stick to the simple locking since rwlock - * would require more memory or can even make lookups slower due to its own - * overhead (when it internally calls mutex locks). - */ -#ifdef ISC_RWLOCK_USEATOMIC -#define DNS_RBTDB_USERWLOCK 1 -#else -#define DNS_RBTDB_USERWLOCK 0 -#endif - -#if DNS_RBTDB_USERWLOCK -#define RBTDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) -#define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l) -#define RBTDB_LOCK(l, t) RWLOCK((l), (t)) -#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t)) -#else -#define RBTDB_INITLOCK(l) isc_mutex_init(l) -#define RBTDB_DESTROYLOCK(l) DESTROYLOCK(l) -#define RBTDB_LOCK(l, t) LOCK(l) -#define RBTDB_UNLOCK(l, t) UNLOCK(l) -#endif - -/* - * Since node locking is sensitive to both performance and memory footprint, - * we need some trick here. If we have both high-performance rwlock and - * high performance and small-memory reference counters, we use rwlock for - * node lock and isc_refcount for node references. In this case, we don't have - * to protect the access to the counters by locks. - * Otherwise, we simply use ordinary mutex lock for node locking, and use - * simple integers as reference counters which is protected by the lock. - * In most cases, we can simply use wrapper macros such as NODE_LOCK and - * NODE_UNLOCK. In some other cases, however, we need to protect reference - * counters first and then protect other parts of a node as read-only data. - * Special additional macros, NODE_STRONGLOCK(), NODE_WEAKLOCK(), etc, are also - * provided for these special cases. When we can use the efficient backend - * routines, we should only protect the "other members" by NODE_WEAKLOCK(read). - * Otherwise, we should use NODE_STRONGLOCK() to protect the entire critical - * section including the access to the reference counter. - * Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected - * section is also protected by NODE_STRONGLOCK(). - */ -#if defined(ISC_RWLOCK_USEATOMIC) && defined(DNS_RBT_USEISCREFCOUNT) -typedef isc_rwlock_t nodelock_t; - -#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0) -#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l) -#define NODE_LOCK(l, t) RWLOCK((l), (t)) -#define NODE_UNLOCK(l, t) RWUNLOCK((l), (t)) -#define NODE_TRYUPGRADE(l) isc_rwlock_tryupgrade(l) - -#define NODE_STRONGLOCK(l) ((void)0) -#define NODE_STRONGUNLOCK(l) ((void)0) -#define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t) -#define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t) -#define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l) -#else -typedef isc_mutex_t nodelock_t; - -#define NODE_INITLOCK(l) isc_mutex_init(l) -#define NODE_DESTROYLOCK(l) DESTROYLOCK(l) -#define NODE_LOCK(l, t) LOCK(l) -#define NODE_UNLOCK(l, t) UNLOCK(l) -#define NODE_TRYUPGRADE(l) ISC_R_SUCCESS - -#define NODE_STRONGLOCK(l) LOCK(l) -#define NODE_STRONGUNLOCK(l) UNLOCK(l) -#define NODE_WEAKLOCK(l, t) ((void)0) -#define NODE_WEAKUNLOCK(l, t) ((void)0) -#define NODE_WEAKDOWNGRADE(l) ((void)0) -#endif - -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#if defined(__cplusplus) -#include -#else -#include -#endif -#define DNS_RBTDB_STDATOMIC 1 -#define DNS_RBTDB_INC(x) atomic_fetch_add(&(x), (1)) -#define DNS_RBTDB_LOAD(x) atomic_load(&(x)) -#elif defined(ISC_PLATFORM_HAVEXADD) -#define DNS_RBTDB_INC(x) isc_atomic_xadd((int *)&(x), 1); -#define DNS_RBTDB_LOAD(x) isc_atomic_xadd((int *)&(x), 0); -#else -#define DNS_RBTDB_INC(x) ((x)++) -#define DNS_RBTDB_LOAD(x) (x) -#endif - -/*% - * Whether to rate-limit updating the LRU to avoid possible thread contention. - * Our performance measurement has shown the cost is marginal, so it's defined - * to be 0 by default either with or without threads. - */ -#ifndef DNS_RBTDB_LIMITLRUUPDATE -#define DNS_RBTDB_LIMITLRUUPDATE 0 -#endif - -/* - * Allow clients with a virtual time of up to 5 minutes in the past to see - * records that would have otherwise have expired. - */ -#define RBTDB_VIRTUAL 300 - -struct noqname { - dns_name_t name; - void * neg; - void * negsig; - dns_rdatatype_t type; -}; - -typedef struct acachectl acachectl_t; - -typedef struct rdatasetheader { - /*% - * Locked by the owning node's lock. - */ - rbtdb_serial_t serial; - dns_ttl_t rdh_ttl; - rbtdb_rdatatype_t type; - uint16_t attributes; - dns_trust_t trust; - struct noqname *noqname; - struct noqname *closest; - unsigned int is_mmapped : 1; - unsigned int next_is_relative : 1; - unsigned int node_is_relative : 1; - unsigned int resign_lsb : 1; - /*%< - * We don't use the LIST macros, because the LIST structure has - * both head and tail pointers, and is doubly linked. - */ - - struct rdatasetheader *next; - /*%< - * If this is the top header for an rdataset, 'next' points - * to the top header for the next rdataset (i.e., the next type). - * Otherwise, it points up to the header whose down pointer points - * at this header. - */ - - struct rdatasetheader *down; - /*%< - * Points to the header for the next older version of - * this rdataset. - */ - -#ifdef DNS_RBTDB_STDATOMIC - _Atomic(uint32_t) count; -#else - uint32_t count; -#endif - /*%< - * Monotonously increased every time this rdataset is bound so that - * it is used as the base of the starting point in DNS responses - * when the "cyclic" rrset-order is required. Since the ordering - * should not be so crucial, no lock is set for the counter for - * performance reasons. - */ - - acachectl_t *additional_auth; - acachectl_t *additional_glue; - - dns_rbtnode_t *node; - isc_stdtime_t last_used; - ISC_LINK(struct rdatasetheader) link; - - unsigned int heap_index; - /*%< - * Used for TTL-based cache cleaning. - */ - isc_stdtime_t resign; - /*%< - * Case vector. If the bit is set then the corresponding - * character in the owner name needs to be AND'd with 0x20, - * rendering that character upper case. - */ - unsigned char upper[32]; -} rdatasetheader_t; - -typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_t; -typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t; - -#define RDATASET_ATTR_NONEXISTENT 0x0001 -/*%< May be potentially served as stale data. */ -#define RDATASET_ATTR_STALE 0x0002 -#define RDATASET_ATTR_IGNORE 0x0004 -#define RDATASET_ATTR_RETAIN 0x0008 -#define RDATASET_ATTR_NXDOMAIN 0x0010 -#define RDATASET_ATTR_RESIGN 0x0020 -#define RDATASET_ATTR_STATCOUNT 0x0040 -#define RDATASET_ATTR_OPTOUT 0x0080 -#define RDATASET_ATTR_NEGATIVE 0x0100 -#define RDATASET_ATTR_PREFETCH 0x0200 -#define RDATASET_ATTR_CASESET 0x0400 -#define RDATASET_ATTR_ZEROTTL 0x0800 -#define RDATASET_ATTR_CASEFULLYLOWER 0x1000 -/*%< Ancient - awaiting cleanup. */ -#define RDATASET_ATTR_ANCIENT 0x2000 - -typedef struct acache_cbarg { - dns_rdatasetadditional_t type; - unsigned int count; - dns_db_t *db; - dns_dbnode_t *node; - rdatasetheader_t *header; -} acache_cbarg_t; - -struct acachectl { - dns_acacheentry_t *entry; - acache_cbarg_t *cbarg; -}; - -/* - * XXX - * When the cache will pre-expire data (due to memory low or other - * situations) before the rdataset's TTL has expired, it MUST - * respect the RETAIN bit and not expire the data until its TTL is - * expired. - */ - -#undef IGNORE /* WIN32 winbase.h defines this. */ - -#define EXISTS(header) \ - (((header)->attributes & RDATASET_ATTR_NONEXISTENT) == 0) -#define NONEXISTENT(header) \ - (((header)->attributes & RDATASET_ATTR_NONEXISTENT) != 0) -#define IGNORE(header) \ - (((header)->attributes & RDATASET_ATTR_IGNORE) != 0) -#define RETAIN(header) \ - (((header)->attributes & RDATASET_ATTR_RETAIN) != 0) -#define NXDOMAIN(header) \ - (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) -#define STALE(header) \ - (((header)->attributes & RDATASET_ATTR_STALE) != 0) -#define RESIGN(header) \ - (((header)->attributes & RDATASET_ATTR_RESIGN) != 0) -#define OPTOUT(header) \ - (((header)->attributes & RDATASET_ATTR_OPTOUT) != 0) -#define NEGATIVE(header) \ - (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0) -#define PREFETCH(header) \ - (((header)->attributes & RDATASET_ATTR_PREFETCH) != 0) -#define CASESET(header) \ - (((header)->attributes & RDATASET_ATTR_CASESET) != 0) -#define ZEROTTL(header) \ - (((header)->attributes & RDATASET_ATTR_ZEROTTL) != 0) -#define CASEFULLYLOWER(header) \ - (((header)->attributes & RDATASET_ATTR_CASEFULLYLOWER) != 0) -#define ANCIENT(header) \ - (((header)->attributes & RDATASET_ATTR_ANCIENT) != 0) - - -#define ACTIVE(header, now) \ - (((header)->rdh_ttl > (now)) || \ - ((header)->rdh_ttl == (now) && ZEROTTL(header))) - -#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */ - -/*% - * Number of buckets for cache DB entries (locks, LRU lists, TTL heaps). - * There is a tradeoff issue about configuring this value: if this is too - * small, it may cause heavier contention between threads; if this is too large, - * LRU purge algorithm won't work well (entries tend to be purged prematurely). - * The default value should work well for most environments, but this can - * also be configurable at compilation time via the - * DNS_RBTDB_CACHE_NODE_LOCK_COUNT variable. This value must be larger than - * 1 due to the assumption of overmem_purge(). - */ -#ifdef DNS_RBTDB_CACHE_NODE_LOCK_COUNT -#if DNS_RBTDB_CACHE_NODE_LOCK_COUNT <= 1 -#error "DNS_RBTDB_CACHE_NODE_LOCK_COUNT must be larger than 1" -#else -#define DEFAULT_CACHE_NODE_LOCK_COUNT DNS_RBTDB_CACHE_NODE_LOCK_COUNT -#endif -#else -#define DEFAULT_CACHE_NODE_LOCK_COUNT 16 -#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */ - -typedef struct { - nodelock_t lock; - /* Protected in the refcount routines. */ - isc_refcount_t references; - /* Locked by lock. */ - bool exiting; -} rbtdb_nodelock_t; - -typedef struct rbtdb_changed { - dns_rbtnode_t * node; - bool dirty; - ISC_LINK(struct rbtdb_changed) link; -} rbtdb_changed_t; - -typedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t; - -typedef enum { - dns_db_insecure, - dns_db_partial, - dns_db_secure -} dns_db_secure_t; - -typedef struct dns_rbtdb dns_rbtdb_t; - -/* Reason for expiring a record from cache */ -typedef enum { - expire_lru, - expire_ttl, - expire_flush -} expire_t; - -typedef enum { - rdataset_ttl_fresh, - rdataset_ttl_stale, - rdataset_ttl_ancient -} rdataset_ttl_t; - -typedef struct rbtdb_version { - /* Not locked */ - rbtdb_serial_t serial; - dns_rbtdb_t * rbtdb; - /* - * Protected in the refcount routines. - * XXXJT: should we change the lock policy based on the refcount - * performance? - */ - isc_refcount_t references; - /* Locked by database lock. */ - bool writer; - bool commit_ok; - rbtdb_changedlist_t changed_list; - rdatasetheaderlist_t resigned_list; - ISC_LINK(struct rbtdb_version) link; - dns_db_secure_t secure; - bool havensec3; - /* NSEC3 parameters */ - dns_hash_t hash; - uint8_t flags; - uint16_t iterations; - uint8_t salt_length; - unsigned char salt[DNS_NSEC3_SALTSIZE]; - - /* - * records and bytes are covered by rwlock. - */ - isc_rwlock_t rwlock; - uint64_t records; - uint64_t bytes; -} rbtdb_version_t; - -typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t; - -struct dns_rbtdb { - /* Unlocked. */ - dns_db_t common; - /* Locks the data in this struct */ -#if DNS_RBTDB_USERWLOCK - isc_rwlock_t lock; -#else - isc_mutex_t lock; -#endif - /* Locks the tree structure (prevents nodes appearing/disappearing) */ - isc_rwlock_t tree_lock; - /* Locks for individual tree nodes */ - unsigned int node_lock_count; - rbtdb_nodelock_t * node_locks; - dns_rbtnode_t * origin_node; - dns_rbtnode_t * nsec3_origin_node; - dns_stats_t * rrsetstats; /* cache DB only */ - isc_stats_t * cachestats; /* cache DB only */ - /* Locked by lock. */ - unsigned int active; - isc_refcount_t references; - unsigned int attributes; - rbtdb_serial_t current_serial; - rbtdb_serial_t least_serial; - rbtdb_serial_t next_serial; - rbtdb_version_t * current_version; - rbtdb_version_t * future_version; - rbtdb_versionlist_t open_versions; - isc_task_t * task; - dns_dbnode_t *soanode; - dns_dbnode_t *nsnode; - - /* - * Maximum length of time to keep using a stale answer past its - * normal TTL expiry. - */ - dns_ttl_t serve_stale_ttl; - - /* - * This is a linked list used to implement the LRU cache. There will - * be node_lock_count linked lists here. Nodes in bucket 1 will be - * placed on the linked list rdatasets[1]. - */ - rdatasetheaderlist_t *rdatasets; - - /*% - * Temporary storage for stale cache nodes and dynamically deleted - * nodes that await being cleaned up. - */ - rbtnodelist_t *deadnodes; - - /* - * Heaps. These are used for TTL based expiry in a cache, - * or for zone resigning in a zone DB. hmctx is the memory - * context to use for the heap (which differs from the main - * database memory context in the case of a cache). - */ - isc_mem_t *hmctx; - isc_heap_t **heaps; - - /* - * Base values for the mmap() code. - */ - void * mmap_location; - size_t mmap_size; - - /* Locked by tree_lock. */ - dns_rbt_t * tree; - dns_rbt_t * nsec; - dns_rbt_t * nsec3; - dns_rpz_zones_t *rpzs; - dns_rpz_num_t rpz_num; - dns_rpz_zones_t *load_rpzs; - - /* Unlocked */ - unsigned int quantum; -}; - -#define RBTDB_ATTR_LOADED 0x01 -#define RBTDB_ATTR_LOADING 0x02 - -#define KEEPSTALE(rbtdb) ((rbtdb)->serve_stale_ttl > 0) - -/*% - * Search Context - */ -typedef struct { - dns_rbtdb_t * rbtdb; - rbtdb_version_t * rbtversion; - rbtdb_serial_t serial; - unsigned int options; - dns_rbtnodechain_t chain; - bool copy_name; - bool need_cleanup; - bool wild; - dns_rbtnode_t * zonecut; - rdatasetheader_t * zonecut_rdataset; - rdatasetheader_t * zonecut_sigrdataset; - dns_fixedname_t zonecut_name; - isc_stdtime_t now; -} rbtdb_search_t; - -/*% - * Load Context - */ -typedef struct { - dns_rbtdb_t * rbtdb; - isc_stdtime_t now; -} rbtdb_load_t; - -static void delete_callback(void *data, void *arg); -static void rdataset_disassociate(dns_rdataset_t *rdataset); -static isc_result_t rdataset_first(dns_rdataset_t *rdataset); -static isc_result_t rdataset_next(dns_rdataset_t *rdataset); -static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); -static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); -static unsigned int rdataset_count(dns_rdataset_t *rdataset); -static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset, - dns_name_t *name, - dns_rdataset_t *neg, - dns_rdataset_t *negsig); -static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset, - dns_name_t *name, - dns_rdataset_t *neg, - dns_rdataset_t *negsig); -static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t **zonep, - dns_db_t **dbp, - dns_dbversion_t **versionp, - dns_dbnode_t **nodep, - dns_name_t *fname, - dns_message_t *msg, - isc_stdtime_t now); -static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t *zone, - dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, - dns_name_t *fname); -static isc_result_t rdataset_putadditional(dns_acache_t *acache, - dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype); -static inline bool need_headerupdate(rdatasetheader_t *header, - isc_stdtime_t now); -static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - isc_stdtime_t now); -static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - bool tree_locked, expire_t reason); -static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, - isc_stdtime_t now, bool tree_locked); -static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx, - rdatasetheader_t *newheader); -static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, - rdatasetheader_t *header); -static void prune_tree(isc_task_t *task, isc_event_t *event); -static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); -static void rdataset_expire(dns_rdataset_t *rdataset); -static void rdataset_clearprefetch(dns_rdataset_t *rdataset); -static void rdataset_setownercase(dns_rdataset_t *rdataset, - const dns_name_t *name); -static void rdataset_getownercase(const dns_rdataset_t *rdataset, - dns_name_t *name); - -static dns_rdatasetmethods_t rdataset_methods = { - rdataset_disassociate, - rdataset_first, - rdataset_next, - rdataset_current, - rdataset_clone, - rdataset_count, - NULL, - rdataset_getnoqname, - NULL, - rdataset_getclosest, - rdataset_getadditional, - rdataset_setadditional, - rdataset_putadditional, - rdataset_settrust, - rdataset_expire, - rdataset_clearprefetch, - rdataset_setownercase, - rdataset_getownercase -}; - -static dns_rdatasetmethods_t slab_methods = { - rdataset_disassociate, - rdataset_first, - rdataset_next, - rdataset_current, - rdataset_clone, - rdataset_count, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); -static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); -static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); -static void rdatasetiter_current(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset); - -static dns_rdatasetitermethods_t rdatasetiter_methods = { - rdatasetiter_destroy, - rdatasetiter_first, - rdatasetiter_next, - rdatasetiter_current -}; - -typedef struct rbtdb_rdatasetiter { - dns_rdatasetiter_t common; - rdatasetheader_t * current; -} rbtdb_rdatasetiter_t; - -/* - * Note that these iterators, unless created with either DNS_DB_NSEC3ONLY or - * DNS_DB_NONSEC3, will transparently move between the last node of the - * "regular" RBT ("chain" field) and the root node of the NSEC3 RBT - * ("nsec3chain" field) of the database in question, as if the latter was a - * successor to the former in lexical order. The "current" field always holds - * the address of either "chain" or "nsec3chain", depending on which RBT is - * being traversed at given time. - */ -static void dbiterator_destroy(dns_dbiterator_t **iteratorp); -static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, - dns_name_t *name); -static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, - dns_dbnode_t **nodep, - dns_name_t *name); -static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, - dns_name_t *name); - -static dns_dbiteratormethods_t dbiterator_methods = { - dbiterator_destroy, - dbiterator_first, - dbiterator_last, - dbiterator_seek, - dbiterator_prev, - dbiterator_next, - dbiterator_current, - dbiterator_pause, - dbiterator_origin -}; - -#define DELETION_BATCH_MAX 64 - -/* - * If 'paused' is true, then the tree lock is not being held. - */ -typedef struct rbtdb_dbiterator { - dns_dbiterator_t common; - bool paused; - bool new_origin; - isc_rwlocktype_t tree_locked; - isc_result_t result; - dns_fixedname_t name; - dns_fixedname_t origin; - dns_rbtnodechain_t chain; - dns_rbtnodechain_t nsec3chain; - dns_rbtnodechain_t *current; - dns_rbtnode_t *node; - dns_rbtnode_t *deletions[DELETION_BATCH_MAX]; - int delcnt; - bool nsec3only; - bool nonsec3; -} rbtdb_dbiterator_t; - - -#define IS_STUB(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_STUB) != 0) -#define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0) - -static void free_rbtdb(dns_rbtdb_t *rbtdb, bool log, - isc_event_t *event); -static void overmem(dns_db_t *db, bool over); -static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version); -static void setownercase(rdatasetheader_t *header, const dns_name_t *name); - -static bool match_header_version(rbtdb_file_header_t *header); - -/* Pad to 32 bytes */ -static char FILE_VERSION[32] = "\0"; - -/*% - * 'init_count' is used to initialize 'newheader->count' which inturn - * is used to determine where in the cycle rrset-order cyclic starts. - * We don't lock this as we don't care about simultaneous updates. - * - * Note: - * Both init_count and header->count can be UINT32_MAX. - * The count on the returned rdataset however can't be as - * that indicates that the database does not implement cyclic - * processing. - */ -#ifdef DNS_RBTDB_STDATOMIC -static _Atomic(unsigned int) init_count; -#else -static unsigned int init_count; -#endif - -/* - * Locking - * - * If a routine is going to lock more than one lock in this module, then - * the locking must be done in the following order: - * - * Tree Lock - * - * Node Lock (Only one from the set may be locked at one time by - * any caller) - * - * Database Lock - * - * Failure to follow this hierarchy can result in deadlock. - */ - -/* - * Deleting Nodes - * - * For zone databases the node for the origin of the zone MUST NOT be deleted. - */ - -/* - * Debugging routines - */ -#ifdef DEBUG -static void -hexdump(const char *desc, unsigned char *data, size_t size) { - char hexdump[BUFSIZ * 2 + 1]; - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - size_t bytes; - - fprintf(stderr, "%s: ", desc); - do { - isc_buffer_init(&b, hexdump, sizeof(hexdump)); - r.base = data; - r.length = bytes = (size > BUFSIZ) ? BUFSIZ : size; - result = isc_hex_totext(&r, 0, "", &b); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_putuint8(&b, 0); - fprintf(stderr, "%s", hexdump); - data += bytes; - size -= bytes; - } while (size > 0); - fprintf(stderr, "\n"); -} -#endif - -/* Fixed RRSet helper macros */ - -#define DNS_RDATASET_LENGTH 2; - -#if DNS_RDATASET_FIXED -#define DNS_RDATASET_ORDER 2 -#define DNS_RDATASET_COUNT (count * 4) -#else /* !DNS_RDATASET_FIXED */ -#define DNS_RDATASET_ORDER 0 -#define DNS_RDATASET_COUNT 0 -#endif /* DNS_RDATASET_FIXED */ - -/* - * DB Routines - */ - -static void -attach(dns_db_t *source, dns_db_t **targetp) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)source; - - REQUIRE(VALID_RBTDB(rbtdb)); - - isc_refcount_increment(&rbtdb->references, NULL); - - *targetp = source; -} - -static void -free_rbtdb_callback(isc_task_t *task, isc_event_t *event) { - dns_rbtdb_t *rbtdb = event->ev_arg; - - UNUSED(task); - - free_rbtdb(rbtdb, true, event); -} - -static void -update_cachestats(dns_rbtdb_t *rbtdb, isc_result_t result) { - INSIST(IS_CACHE(rbtdb)); - - if (rbtdb->cachestats == NULL) - return; - - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_CNAME: - case DNS_R_DNAME: - case DNS_R_DELEGATION: - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - isc_stats_increment(rbtdb->cachestats, - dns_cachestatscounter_hits); - break; - default: - isc_stats_increment(rbtdb->cachestats, - dns_cachestatscounter_misses); - } -} - -static void -update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - bool increment) -{ - dns_rdatastatstype_t statattributes = 0; - dns_rdatastatstype_t base = 0; - dns_rdatastatstype_t type; - - /* At the moment we count statistics only for cache DB */ - INSIST(IS_CACHE(rbtdb)); - - if (NEGATIVE(header)) { - if (NXDOMAIN(header)) - statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN; - else { - statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; - base = RBTDB_RDATATYPE_EXT(header->type); - } - } else - base = RBTDB_RDATATYPE_BASE(header->type); - - if (STALE(header)) - statattributes |= DNS_RDATASTATSTYPE_ATTR_STALE; - - type = DNS_RDATASTATSTYPE_VALUE(base, statattributes); - if (increment) - dns_rdatasetstats_increment(rbtdb->rrsetstats, type); - else - dns_rdatasetstats_decrement(rbtdb->rrsetstats, type); -} - -static void -set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) { - int idx; - isc_heap_t *heap; - dns_ttl_t oldttl; - - - if (!IS_CACHE(rbtdb)) { - header->rdh_ttl = newttl; - return; - } - - oldttl = header->rdh_ttl; - header->rdh_ttl = newttl; - - /* - * It's possible the rbtdb is not a cache. If this is the case, - * we will not have a heap, and we move on. If we do, though, - * we might need to adjust things. - */ - if (header->heap_index == 0 || newttl == oldttl) - return; - idx = header->node->locknum; - if (rbtdb->heaps == NULL || rbtdb->heaps[idx] == NULL) - return; - heap = rbtdb->heaps[idx]; - - if (newttl < oldttl) - isc_heap_increased(heap, header->heap_index); - else - isc_heap_decreased(heap, header->heap_index); -} - -/*% - * These functions allow the heap code to rank the priority of each - * element. It returns true if v1 happens "sooner" than v2. - */ -static bool -ttl_sooner(void *v1, void *v2) { - rdatasetheader_t *h1 = v1; - rdatasetheader_t *h2 = v2; - - return (h1->rdh_ttl < h2->rdh_ttl); -} - -/*% - * Return which RRset should be resigned sooner. If the RRsets have the - * same signing time, prefer the other RRset over the SOA RRset. - */ -static bool -resign_sooner(void *v1, void *v2) { - rdatasetheader_t *h1 = v1; - rdatasetheader_t *h2 = v2; - - return (h1->resign < h2->resign || - (h1->resign == h2->resign && h1->resign_lsb < h2->resign_lsb) || - (h1->resign == h2->resign && h1->resign_lsb == h2->resign_lsb && - h2->type == RBTDB_RDATATYPE_SIGSOA)); -} - -/*% - * This function sets the heap index into the header. - */ -static void -set_index(void *what, unsigned int idx) { - rdatasetheader_t *h = what; - - h->heap_index = idx; -} - -/*% - * Work out how many nodes can be deleted in the time between two - * requests to the nameserver. Smooth the resulting number and use it - * as a estimate for the number of nodes to be deleted in the next - * iteration. - */ -static unsigned int -adjust_quantum(unsigned int old, isc_time_t *start) { - unsigned int pps = dns_pps; /* packets per second */ - unsigned int interval; - uint64_t usecs; - isc_time_t end; - unsigned int nodes; - - if (pps < 100) - pps = 100; - isc_time_now(&end); - - interval = 1000000 / pps; /* interval in usec */ - if (interval == 0) - interval = 1; - usecs = isc_time_microdiff(&end, start); - if (usecs == 0) { - /* - * We were unable to measure the amount of time taken. - * Double the nodes deleted next time. - */ - old *= 2; - if (old > 1000) - old = 1000; - return (old); - } - nodes = old * interval; - nodes /= (unsigned int)usecs; - if (nodes == 0) - nodes = 1; - else if (nodes > 1000) - nodes = 1000; - - /* Smooth */ - nodes = (nodes + old * 3) / 4; - - if (nodes != old) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "adjust_quantum: old=%d, new=%d", old, nodes); - - return (nodes); -} - -static void -free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) { - unsigned int i; - isc_ondestroy_t ondest; - isc_result_t result; - char buf[DNS_NAME_FORMATSIZE]; - dns_rbt_t **treep; - isc_time_t start; - dns_dbonupdatelistener_t *listener, *listener_next; - - if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) - overmem((dns_db_t *)rbtdb, (bool)-1); - - REQUIRE(rbtdb->current_version != NULL || EMPTY(rbtdb->open_versions)); - REQUIRE(rbtdb->future_version == NULL); - - if (rbtdb->current_version != NULL) { - unsigned int refs; - - isc_refcount_decrement(&rbtdb->current_version->references, - &refs); - INSIST(refs == 0); - UNLINK(rbtdb->open_versions, rbtdb->current_version, link); - isc_refcount_destroy(&rbtdb->current_version->references); - isc_rwlock_destroy(&rbtdb->current_version->rwlock); - isc_mem_put(rbtdb->common.mctx, rbtdb->current_version, - sizeof(rbtdb_version_t)); - } - - /* - * We assume the number of remaining dead nodes is reasonably small; - * the overhead of unlinking all nodes here should be negligible. - */ - for (i = 0; i < rbtdb->node_lock_count; i++) { - dns_rbtnode_t *node; - - node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); - while (node != NULL) { - ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, deadlink); - node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); - } - } - - if (event == NULL) - rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0; - - for (;;) { - /* - * pick the next tree to (start to) destroy - */ - treep = &rbtdb->tree; - if (*treep == NULL) { - treep = &rbtdb->nsec; - if (*treep == NULL) { - treep = &rbtdb->nsec3; - /* - * we're finished after clear cutting - */ - if (*treep == NULL) - break; - } - } - - isc_time_now(&start); - result = dns_rbt_destroy2(treep, rbtdb->quantum); - if (result == ISC_R_QUOTA) { - INSIST(rbtdb->task != NULL); - if (rbtdb->quantum != 0) - rbtdb->quantum = adjust_quantum(rbtdb->quantum, - &start); - if (event == NULL) - event = isc_event_allocate(rbtdb->common.mctx, - NULL, - DNS_EVENT_FREESTORAGE, - free_rbtdb_callback, - rbtdb, - sizeof(isc_event_t)); - if (event == NULL) - continue; - isc_task_send(rbtdb->task, &event); - return; - } - INSIST(result == ISC_R_SUCCESS && *treep == NULL); - } - - if (event != NULL) - isc_event_free(&event); - if (log) { - if (dns_name_dynamic(&rbtdb->common.origin)) - dns_name_format(&rbtdb->common.origin, buf, - sizeof(buf)); - else - strlcpy(buf, "", sizeof(buf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "done free_rbtdb(%s)", buf); - } - if (dns_name_dynamic(&rbtdb->common.origin)) - dns_name_free(&rbtdb->common.origin, rbtdb->common.mctx); - for (i = 0; i < rbtdb->node_lock_count; i++) { - isc_refcount_destroy(&rbtdb->node_locks[i].references); - NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); - } - - /* - * Clean up LRU / re-signing order lists. - */ - if (rbtdb->rdatasets != NULL) { - for (i = 0; i < rbtdb->node_lock_count; i++) - INSIST(ISC_LIST_EMPTY(rbtdb->rdatasets[i])); - isc_mem_put(rbtdb->common.mctx, rbtdb->rdatasets, - rbtdb->node_lock_count * - sizeof(rdatasetheaderlist_t)); - } - /* - * Clean up dead node buckets. - */ - if (rbtdb->deadnodes != NULL) { - for (i = 0; i < rbtdb->node_lock_count; i++) - INSIST(ISC_LIST_EMPTY(rbtdb->deadnodes[i])); - isc_mem_put(rbtdb->common.mctx, rbtdb->deadnodes, - rbtdb->node_lock_count * sizeof(rbtnodelist_t)); - } - /* - * Clean up heap objects. - */ - if (rbtdb->heaps != NULL) { - for (i = 0; i < rbtdb->node_lock_count; i++) - isc_heap_destroy(&rbtdb->heaps[i]); - isc_mem_put(rbtdb->hmctx, rbtdb->heaps, - rbtdb->node_lock_count * sizeof(isc_heap_t *)); - } - - if (rbtdb->rrsetstats != NULL) - dns_stats_detach(&rbtdb->rrsetstats); - if (rbtdb->cachestats != NULL) - isc_stats_detach(&rbtdb->cachestats); - - if (rbtdb->load_rpzs != NULL) { - /* - * We must be cleaning up after a failed zone loading. - */ - REQUIRE(rbtdb->rpzs != NULL && - rbtdb->rpz_num < rbtdb->rpzs->p.num_zones); - dns_rpz_detach_rpzs(&rbtdb->load_rpzs); - } - if (rbtdb->rpzs != NULL) { - REQUIRE(rbtdb->rpz_num < rbtdb->rpzs->p.num_zones); - dns_rpz_detach_rpzs(&rbtdb->rpzs); - } - - isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks, - rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); - isc_rwlock_destroy(&rbtdb->tree_lock); - isc_refcount_destroy(&rbtdb->references); - if (rbtdb->task != NULL) - isc_task_detach(&rbtdb->task); - - RBTDB_DESTROYLOCK(&rbtdb->lock); - rbtdb->common.magic = 0; - rbtdb->common.impmagic = 0; - ondest = rbtdb->common.ondest; - isc_mem_detach(&rbtdb->hmctx); - - if (rbtdb->mmap_location != NULL) - isc_file_munmap(rbtdb->mmap_location, - (size_t) rbtdb->mmap_size); - - for (listener = ISC_LIST_HEAD(rbtdb->common.update_listeners); - listener != NULL; - listener = listener_next) - { - listener_next = ISC_LIST_NEXT(listener, link); - ISC_LIST_UNLINK(rbtdb->common.update_listeners, listener, link); - isc_mem_put(rbtdb->common.mctx, listener, - sizeof(dns_dbonupdatelistener_t)); - } - - isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb)); - isc_ondestroy_notify(&ondest, rbtdb); -} - -static inline void -maybe_free_rbtdb(dns_rbtdb_t *rbtdb) { - bool want_free = false; - unsigned int i; - unsigned int inactive = 0; - - /* XXX check for open versions here */ - - if (rbtdb->soanode != NULL) - dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->soanode); - if (rbtdb->nsnode != NULL) - dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode); - - /* - * Even though there are no external direct references, there still - * may be nodes in use. - */ - for (i = 0; i < rbtdb->node_lock_count; i++) { - NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); - rbtdb->node_locks[i].exiting = true; - NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); - if (isc_refcount_current(&rbtdb->node_locks[i].references) - == 0) { - inactive++; - } - } - - if (inactive != 0) { - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - rbtdb->active -= inactive; - if (rbtdb->active == 0) - want_free = true; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - if (want_free) { - char buf[DNS_NAME_FORMATSIZE]; - if (dns_name_dynamic(&rbtdb->common.origin)) { - dns_name_format(&rbtdb->common.origin, buf, - sizeof(buf)); - } else { - strlcpy(buf, "", sizeof(buf)); - } - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "calling free_rbtdb(%s)", buf); - free_rbtdb(rbtdb, true, NULL); - } - } -} - -static void -detach(dns_db_t **dbp) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp); - unsigned int refs; - - REQUIRE(VALID_RBTDB(rbtdb)); - - isc_refcount_decrement(&rbtdb->references, &refs); - - if (refs == 0) - maybe_free_rbtdb(rbtdb); - - *dbp = NULL; -} - -static void -currentversion(dns_db_t *db, dns_dbversion_t **versionp) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rbtdb_version_t *version; - unsigned int refs; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - version = rbtdb->current_version; - isc_refcount_increment(&version->references, &refs); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - - *versionp = (dns_dbversion_t *)version; -} - -static inline rbtdb_version_t * -allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial, - unsigned int references, bool writer) -{ - isc_result_t result; - rbtdb_version_t *version; - - version = isc_mem_get(mctx, sizeof(*version)); - if (version == NULL) - return (NULL); - version->serial = serial; - result = isc_refcount_init(&version->references, references); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, version, sizeof(*version)); - return (NULL); - } - version->writer = writer; - version->commit_ok = false; - ISC_LIST_INIT(version->changed_list); - ISC_LIST_INIT(version->resigned_list); - ISC_LINK_INIT(version, link); - - return (version); -} - -static isc_result_t -newversion(dns_db_t *db, dns_dbversion_t **versionp) { - isc_result_t result; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rbtdb_version_t *version; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(versionp != NULL && *versionp == NULL); - REQUIRE(rbtdb->future_version == NULL); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */ - version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1, - true); - if (version != NULL) { - version->rbtdb = rbtdb; - version->commit_ok = true; - version->secure = rbtdb->current_version->secure; - version->havensec3 = rbtdb->current_version->havensec3; - if (version->havensec3) { - version->flags = rbtdb->current_version->flags; - version->iterations = - rbtdb->current_version->iterations; - version->hash = rbtdb->current_version->hash; - version->salt_length = - rbtdb->current_version->salt_length; - memmove(version->salt, rbtdb->current_version->salt, - version->salt_length); - } else { - version->flags = 0; - version->iterations = 0; - version->hash = 0; - version->salt_length = 0; - memset(version->salt, 0, sizeof(version->salt)); - } - result = isc_rwlock_init(&version->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - isc_refcount_destroy(&version->references); - isc_mem_put(rbtdb->common.mctx, version, - sizeof(*version)); - version = NULL; - } else { - RWLOCK(&rbtdb->current_version->rwlock, - isc_rwlocktype_read); - version->records = rbtdb->current_version->records; - version->bytes = rbtdb->current_version->bytes; - RWUNLOCK(&rbtdb->current_version->rwlock, - isc_rwlocktype_read); - rbtdb->next_serial++; - rbtdb->future_version = version; - } - } else - result = ISC_R_NOMEMORY; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - - if (version == NULL) - return (result); - - *versionp = version; - - return (ISC_R_SUCCESS); -} - -static void -attachversion(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rbtdb_version_t *rbtversion = source; - unsigned int refs; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb); - - isc_refcount_increment(&rbtversion->references, &refs); - INSIST(refs > 1); - - *targetp = rbtversion; -} - -static rbtdb_changed_t * -add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, - dns_rbtnode_t *node) -{ - rbtdb_changed_t *changed; - unsigned int refs; - - /* - * Caller must be holding the node lock if its reference must be - * protected by the lock. - */ - - changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed)); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - - REQUIRE(version->writer); - - if (changed != NULL) { - dns_rbtnode_refincrement(node, &refs); - INSIST(refs != 0); - changed->node = node; - changed->dirty = false; - ISC_LIST_INITANDAPPEND(version->changed_list, changed, link); - } else - version->commit_ok = false; - - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - - return (changed); -} - -static void -free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header, - acachectl_t *array) -{ - unsigned int count; - unsigned int i; - unsigned char *raw; /* RDATASLAB */ - - /* - * The caller must be holding the corresponding node lock. - */ - - if (array == NULL) - return; - - raw = (unsigned char *)header + sizeof(*header); - count = raw[0] * 256 + raw[1]; - - /* - * Sanity check: since an additional cache entry has a reference to - * the original DB node (in the callback arg), there should be no - * acache entries when the node can be freed. - */ - for (i = 0; i < count; i++) - INSIST(array[i].entry == NULL && array[i].cbarg == NULL); - - isc_mem_put(mctx, array, count * sizeof(acachectl_t)); -} - -static inline void -free_noqname(isc_mem_t *mctx, struct noqname **noqname) { - - if (dns_name_dynamic(&(*noqname)->name)) - dns_name_free(&(*noqname)->name, mctx); - if ((*noqname)->neg != NULL) - isc_mem_put(mctx, (*noqname)->neg, - dns_rdataslab_size((*noqname)->neg, 0)); - if ((*noqname)->negsig != NULL) - isc_mem_put(mctx, (*noqname)->negsig, - dns_rdataslab_size((*noqname)->negsig, 0)); - isc_mem_put(mctx, *noqname, sizeof(**noqname)); - *noqname = NULL; -} - -static inline void -init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) { - ISC_LINK_INIT(h, link); - h->heap_index = 0; - h->is_mmapped = 0; - h->next_is_relative = 0; - h->node_is_relative = 0; - -#if TRACE_HEADER - if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) - fprintf(stderr, "initialized header: %p\n", h); -#else - UNUSED(rbtdb); -#endif -} - -/* - * Update the copied values of 'next' and 'node' if they are relative. - */ -static void -update_newheader(rdatasetheader_t *newh, rdatasetheader_t *old) { - char *p; - - if (old->next_is_relative) { - p = (char *) old; - p += (uintptr_t)old->next; - newh->next = (rdatasetheader_t *)p; - } - if (old->node_is_relative) { - p = (char *) old; - p += (uintptr_t)old->node; - newh->node = (dns_rbtnode_t *)p; - } - if (CASESET(old)) { - uint16_t attr; - - memmove(newh->upper, old->upper, sizeof(old->upper)); - attr = old->attributes & (RDATASET_ATTR_CASESET | - RDATASET_ATTR_CASEFULLYLOWER); - newh->attributes |= attr; - } -} - -static inline rdatasetheader_t * -new_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx) { - rdatasetheader_t *h; - - h = isc_mem_get(mctx, sizeof(*h)); - if (h == NULL) - return (NULL); - -#if TRACE_HEADER - if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) - fprintf(stderr, "allocated header: %p\n", h); -#endif - memset(h->upper, 0xeb, sizeof(h->upper)); - init_rdataset(rbtdb, h); - h->rdh_ttl = 0; - return (h); -} - -static inline void -free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) { - unsigned int size; - int idx; - - if (EXISTS(rdataset) && - (rdataset->attributes & RDATASET_ATTR_STATCOUNT) != 0) { - update_rrsetstats(rbtdb, rdataset, false); - } - - idx = rdataset->node->locknum; - if (ISC_LINK_LINKED(rdataset, link)) { - INSIST(IS_CACHE(rbtdb)); - ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link); - } - - if (rdataset->heap_index != 0) - isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index); - rdataset->heap_index = 0; - - if (rdataset->noqname != NULL) - free_noqname(mctx, &rdataset->noqname); - if (rdataset->closest != NULL) - free_noqname(mctx, &rdataset->closest); - - free_acachearray(mctx, rdataset, rdataset->additional_auth); - free_acachearray(mctx, rdataset, rdataset->additional_glue); - - if (NONEXISTENT(rdataset)) - size = sizeof(*rdataset); - else - size = dns_rdataslab_size((unsigned char *)rdataset, - sizeof(*rdataset)); - - if (rdataset->is_mmapped == 1) - return; - - isc_mem_put(mctx, rdataset, size); -} - -static inline void -rollback_node(dns_rbtnode_t *node, rbtdb_serial_t serial) { - rdatasetheader_t *header, *dcurrent; - bool make_dirty = false; - - /* - * Caller must hold the node lock. - */ - - /* - * We set the IGNORE attribute on rdatasets with serial number - * 'serial'. When the reference count goes to zero, these rdatasets - * will be cleaned up; until that time, they will be ignored. - */ - for (header = node->data; header != NULL; header = header->next) { - if (header->serial == serial) { - header->attributes |= RDATASET_ATTR_IGNORE; - make_dirty = true; - } - for (dcurrent = header->down; - dcurrent != NULL; - dcurrent = dcurrent->down) { - if (dcurrent->serial == serial) { - dcurrent->attributes |= RDATASET_ATTR_IGNORE; - make_dirty = true; - } - } - } - if (make_dirty) - node->dirty = 1; -} - -static inline void -mark_header_ancient(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) { - - /* - * If we are already ancient there is nothing to do. - */ - if (ANCIENT(header)) - return; - - header->attributes |= RDATASET_ATTR_ANCIENT; - header->node->dirty = 1; - - /* - * If we have not been counted then there is nothing to do. - */ - if ((header->attributes & RDATASET_ATTR_STATCOUNT) == 0) - return; - - if (EXISTS(header)) - update_rrsetstats(rbtdb, header, true); -} - -static inline void -clean_stale_headers(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *top) -{ - rdatasetheader_t *d, *down_next; - - for (d = top->down; d != NULL; d = down_next) { - down_next = d->down; - free_rdataset(rbtdb, mctx, d); - } - top->down = NULL; -} - -static inline void -clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { - rdatasetheader_t *current, *top_prev, *top_next; - isc_mem_t *mctx = rbtdb->common.mctx; - - /* - * Caller must be holding the node lock. - */ - - top_prev = NULL; - for (current = node->data; current != NULL; current = top_next) { - top_next = current->next; - clean_stale_headers(rbtdb, mctx, current); - /* - * If current is nonexistent or stale, we can clean it up. - */ - if (NONEXISTENT(current) || ANCIENT(current) || - (STALE(current) && ! KEEPSTALE(rbtdb))) { - if (top_prev != NULL) - top_prev->next = current->next; - else - node->data = current->next; - free_rdataset(rbtdb, mctx, current); - } else - top_prev = current; - } - node->dirty = 0; -} - -static inline void -clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - rbtdb_serial_t least_serial) -{ - rdatasetheader_t *current, *dcurrent, *down_next, *dparent; - rdatasetheader_t *top_prev, *top_next; - isc_mem_t *mctx = rbtdb->common.mctx; - bool still_dirty = false; - - /* - * Caller must be holding the node lock. - */ - REQUIRE(least_serial != 0); - - top_prev = NULL; - for (current = node->data; current != NULL; current = top_next) { - top_next = current->next; - - /* - * First, we clean up any instances of multiple rdatasets - * with the same serial number, or that have the IGNORE - * attribute. - */ - dparent = current; - for (dcurrent = current->down; - dcurrent != NULL; - dcurrent = down_next) { - down_next = dcurrent->down; - INSIST(dcurrent->serial <= dparent->serial); - if (dcurrent->serial == dparent->serial || - IGNORE(dcurrent)) { - if (down_next != NULL) - down_next->next = dparent; - dparent->down = down_next; - free_rdataset(rbtdb, mctx, dcurrent); - } else - dparent = dcurrent; - } - - /* - * We've now eliminated all IGNORE datasets with the possible - * exception of current, which we now check. - */ - if (IGNORE(current)) { - down_next = current->down; - if (down_next == NULL) { - if (top_prev != NULL) - top_prev->next = current->next; - else - node->data = current->next; - free_rdataset(rbtdb, mctx, current); - /* - * current no longer exists, so we can - * just continue with the loop. - */ - continue; - } else { - /* - * Pull up current->down, making it the new - * current. - */ - if (top_prev != NULL) - top_prev->next = down_next; - else - node->data = down_next; - down_next->next = top_next; - free_rdataset(rbtdb, mctx, current); - current = down_next; - } - } - - /* - * We now try to find the first down node less than the - * least serial. - */ - dparent = current; - for (dcurrent = current->down; - dcurrent != NULL; - dcurrent = down_next) { - down_next = dcurrent->down; - if (dcurrent->serial < least_serial) - break; - dparent = dcurrent; - } - - /* - * If there is a such an rdataset, delete it and any older - * versions. - */ - if (dcurrent != NULL) { - do { - down_next = dcurrent->down; - INSIST(dcurrent->serial <= least_serial); - free_rdataset(rbtdb, mctx, dcurrent); - dcurrent = down_next; - } while (dcurrent != NULL); - dparent->down = NULL; - } - - /* - * Note. The serial number of 'current' might be less than - * least_serial too, but we cannot delete it because it is - * the most recent version, unless it is a NONEXISTENT - * rdataset. - */ - if (current->down != NULL) { - still_dirty = true; - top_prev = current; - } else { - /* - * If this is a NONEXISTENT rdataset, we can delete it. - */ - if (NONEXISTENT(current)) { - if (top_prev != NULL) - top_prev->next = current->next; - else - node->data = current->next; - free_rdataset(rbtdb, mctx, current); - } else - top_prev = current; - } - } - if (!still_dirty) - node->dirty = 0; -} - -/* - * tree_lock(write) must be held. - */ -static void -delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { - dns_rbtnode_t *nsecnode; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result = ISC_R_UNEXPECTED; - unsigned int node_has_rpz; - - INSIST(!ISC_LINK_LINKED(node, deadlink)); - - if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { - char printname[DNS_NAME_FORMATSIZE]; - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), - "delete_node(): %p %s (bucket %d)", - node, - dns_rbt_formatnodename(node, - printname, sizeof(printname)), - node->locknum); - } - - switch (node->nsec) { - case DNS_RBT_NSEC_NORMAL: - /* - * Though this may be wasteful, it has to be done before - * node is deleted. - */ - name = dns_fixedname_initname(&fname); - dns_rbt_fullnamefromnode(node, name); - - /* - * dns_rbt_deletenode() may keep the node if it has a - * down pointer, but we mustn't call dns_rpz_delete() on - * it again. - */ - node_has_rpz = node->rpz; - node->rpz = 0; - result = dns_rbt_deletenode(rbtdb->tree, node, false); - if (result == ISC_R_SUCCESS && - rbtdb->rpzs != NULL && node_has_rpz) - dns_rpz_delete(rbtdb->rpzs, rbtdb->rpz_num, name); - break; - case DNS_RBT_NSEC_HAS_NSEC: - name = dns_fixedname_initname(&fname); - dns_rbt_fullnamefromnode(node, name); - /* - * Delete the corresponding node from the auxiliary NSEC - * tree before deleting from the main tree. - */ - nsecnode = NULL; - result = dns_rbt_findnode(rbtdb->nsec, name, NULL, &nsecnode, - NULL, DNS_RBTFIND_EMPTYDATA, - NULL, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_node: " - "dns_rbt_findnode(nsec): %s", - isc_result_totext(result)); - } else { - result = dns_rbt_deletenode(rbtdb->nsec, nsecnode, - false); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_WARNING, - "delete_node(): " - "dns_rbt_deletenode(nsecnode): %s", - isc_result_totext(result)); - } - } - /* - * dns_rbt_deletenode() may keep the node if it has a - * down pointer, but we mustn't call dns_rpz_delete() on - * it again. - */ - node_has_rpz = node->rpz; - node->rpz = 0; - result = dns_rbt_deletenode(rbtdb->tree, node, false); - if (result == ISC_R_SUCCESS && - rbtdb->rpzs != NULL && node_has_rpz) - dns_rpz_delete(rbtdb->rpzs, rbtdb->rpz_num, name); - break; - case DNS_RBT_NSEC_NSEC: - result = dns_rbt_deletenode(rbtdb->nsec, node, false); - break; - case DNS_RBT_NSEC_NSEC3: - result = dns_rbt_deletenode(rbtdb->nsec3, node, false); - break; - } - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_WARNING, - "delete_node(): " - "dns_rbt_deletenode: %s", - isc_result_totext(result)); - } -} - -#if 0 -static void -clean_now_or_later(dns_rbtnode_t *node, dns_rbtdb_t *rbtdb, - rdatasetheader_t *header, rdatasetheader_t **header_prevp) -{ - if (dns_rbtnode_refcurrent(node) == 0) { - isc_mem_t *mctx; - - /* - * header->down can be non-NULL if the refcount has just - * decremented to 0 but decrement_reference() has not performed - * clean_cache_node(), in which case we need to purge the stale - * headers first. - */ - mctx = rbtdb->common.mctx; - clean_stale_headers(rbtdb, mctx, header); - if (*header_prevp != NULL) - (*header_prevp)->next = header->next; - else - node->data = header->next; - free_rdataset(rbtdb, mctx, header); - } else { - header->attributes |= RDATASET_ATTR_STALE | - RDATASET_ATTR_ANCIENT; - node->dirty = 1; - *header_prevp = header; - } -} - -static rdataset_ttl_t -check_ttl(dns_rbtnode_t *node, rbtdb_search_t *search, - rdatasetheader_t *header, rdatasetheader_t **header_prevp, - nodelock_t *lock, isc_rwlocktype_t *locktype) -{ - dns_rbtdb_t *rbtdb = search->rbtdb; - - if (header->rdh_ttl > search->now) - return rdataset_ttl_fresh; - - /* - * This rdataset is stale, but perhaps still usable. - */ - if (KEEPSTALE(rbtdb) && - header->rdh_ttl + rbtdb->serve_stale_ttl > search->now) { - header->attributes |= RDATASET_ATTR_STALE; - /* Doesn't set dirty because it doesn't need removal. */ - return rdataset_ttl_stale; - } - - /* - * This rdataset is so stale it is no longer usable, even with - * KEEPSTALE. If no one else is using the node, we can clean it up - * right now, otherwise we mark it as ancient, and the node as dirty, - * so it will get cleaned up later. - */ - if ((header->rdh_ttl <= search->now - RBTDB_VIRTUAL) && - (*locktype == isc_rwlocktype_write || - NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { - /* - * We update the node's status only when we can get write - * access; otherwise, we leave others to this work. Periodical - * cleaning will eventually take the job as the last resort. - * We won't downgrade the lock, since other rdatasets are - * probably stale, too. - */ - *locktype = isc_rwlocktype_write; - clean_now_or_later(node, rbtdb, header, header_prevp); - } else - *header_prevp = header; - - return rdataset_ttl_ancient; -} -#endif - -/* - * Caller must be holding the node lock. - */ -static inline void -new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - isc_rwlocktype_t locktype) { - unsigned int lockrefs, noderefs; - isc_refcount_t *lockref; - - if (locktype == isc_rwlocktype_write && ISC_LINK_LINKED(node, deadlink)) - { - ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node, - deadlink); - } - dns_rbtnode_refincrement0(node, &noderefs); - if (noderefs == 1) { /* this is the first reference to the node */ - lockref = &rbtdb->node_locks[node->locknum].references; - isc_refcount_increment0(lockref, &lockrefs); - INSIST(lockrefs != 0); - } - INSIST(noderefs != 0); -} - -/*% - * The tree lock must be held for the result to be valid. - */ -static inline bool -is_leaf(dns_rbtnode_t *node) { - return (node->parent != NULL && node->parent->down == node && - node->left == NULL && node->right == NULL); -} - -static inline void -send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - isc_rwlocktype_t locktype) { - isc_event_t *ev; - dns_db_t *db; - - ev = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTPRUNE, - prune_tree, node, sizeof(isc_event_t)); - new_reference(rbtdb, node, locktype); - db = NULL; - attach((dns_db_t *)rbtdb, &db); - ev->ev_sender = db; - isc_task_send(rbtdb->task, &ev); -} - -/*% - * Clean up dead nodes. These are nodes which have no references, and - * have no data. They are dead but we could not or chose not to delete - * them when we deleted all the data at that node because we did not want - * to wait for the tree write lock. - * - * The caller must hold a tree write lock and bucketnum'th node (write) lock. - */ -static void -cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) { - dns_rbtnode_t *node; - int count = 10; /* XXXJT: should be adjustable */ - - node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]); - while (node != NULL && count > 0) { - ISC_LIST_UNLINK(rbtdb->deadnodes[bucketnum], node, deadlink); - - /* - * We might have reactivated this node without a tree write - * lock, so we couldn't remove this node from deadnodes then - * and we have to do it now. - */ - if (dns_rbtnode_refcurrent(node) != 0 || - node->data != NULL) { - node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]); - count--; - continue; - } - - if (is_leaf(node) && rbtdb->task != NULL) { - send_to_prune_tree(rbtdb, node, isc_rwlocktype_write); - } else if (node->down == NULL && node->data == NULL) { - /* - * Not a interior node and not needing to be - * reactivated. - */ - delete_node(rbtdb, node); - } else if (node->data == NULL) { - /* - * A interior node without data. Leave linked to - * to be cleaned up when node->down becomes NULL. - */ - ISC_LIST_APPEND(rbtdb->deadnodes[bucketnum], - node, deadlink); - } - node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]); - count--; - } -} - -/* - * This function is assumed to be called when a node is newly referenced - * and can be in the deadnode list. In that case the node must be retrieved - * from the list because it is going to be used. In addition, if the caller - * happens to hold a write lock on the tree, it's a good chance to purge dead - * nodes. - * Note: while a new reference is gained in multiple places, there are only very - * few cases where the node can be in the deadnode list (only empty nodes can - * have been added to the list). - */ -static inline void -reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - isc_rwlocktype_t treelocktype) -{ - isc_rwlocktype_t locktype = isc_rwlocktype_read; - nodelock_t *nodelock = &rbtdb->node_locks[node->locknum].lock; - bool maybe_cleanup = false; - - POST(locktype); - - NODE_STRONGLOCK(nodelock); - NODE_WEAKLOCK(nodelock, locktype); - - /* - * Check if we can possibly cleanup the dead node. If so, upgrade - * the node lock below to perform the cleanup. - */ - if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) && - treelocktype == isc_rwlocktype_write) { - maybe_cleanup = true; - } - - if (ISC_LINK_LINKED(node, deadlink) || maybe_cleanup) { - /* - * Upgrade the lock and test if we still need to unlink. - */ - NODE_WEAKUNLOCK(nodelock, locktype); - locktype = isc_rwlocktype_write; - POST(locktype); - NODE_WEAKLOCK(nodelock, locktype); - if (ISC_LINK_LINKED(node, deadlink)) - ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], - node, deadlink); - if (maybe_cleanup) - cleanup_dead_nodes(rbtdb, node->locknum); - } - - new_reference(rbtdb, node, locktype); - - NODE_WEAKUNLOCK(nodelock, locktype); - NODE_STRONGUNLOCK(nodelock); -} - -/* - * Caller must be holding the node lock; either the "strong", read or write - * lock. Note that the lock must be held even when node references are - * atomically modified; in that case the decrement operation itself does not - * have to be protected, but we must avoid a race condition where multiple - * threads are decreasing the reference to zero simultaneously and at least - * one of them is going to free the node. - * - * This function returns true if and only if the node reference decreases - * to zero. - * - * NOTE: Decrementing the reference count of a node to zero does not mean it - * will be immediately freed. - */ -static bool -decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - rbtdb_serial_t least_serial, - isc_rwlocktype_t nlock, isc_rwlocktype_t tlock, - bool pruning) -{ - isc_result_t result; - bool write_locked; - bool locked = tlock != isc_rwlocktype_none; - rbtdb_nodelock_t *nodelock; - unsigned int refs, nrefs; - int bucket = node->locknum; - bool no_reference = true; - - nodelock = &rbtdb->node_locks[bucket]; - -#define KEEP_NODE(n, r, l) \ - ((n)->data != NULL || ((l) && (n)->down != NULL) || \ - (n) == (r)->origin_node || (n) == (r)->nsec3_origin_node) - - /* Handle easy and typical case first. */ - if (!node->dirty && KEEP_NODE(node, rbtdb, locked)) { - dns_rbtnode_refdecrement(node, &nrefs); - INSIST((int)nrefs >= 0); - if (nrefs == 0) { - isc_refcount_decrement(&nodelock->references, &refs); - INSIST((int)refs >= 0); - return (true); - } else { - return (false); - } - } - - /* Upgrade the lock? */ - if (nlock == isc_rwlocktype_read) { - NODE_WEAKUNLOCK(&nodelock->lock, isc_rwlocktype_read); - NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write); - } - - dns_rbtnode_refdecrement(node, &nrefs); - INSIST((int)nrefs >= 0); - if (nrefs > 0) { - /* Restore the lock? */ - if (nlock == isc_rwlocktype_read) - NODE_WEAKDOWNGRADE(&nodelock->lock); - return (false); - } - - if (node->dirty) { - if (IS_CACHE(rbtdb)) - clean_cache_node(rbtdb, node); - else { - if (least_serial == 0) { - /* - * Caller doesn't know the least serial. - * Get it. - */ - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - least_serial = rbtdb->least_serial; - RBTDB_UNLOCK(&rbtdb->lock, - isc_rwlocktype_read); - } - clean_zone_node(rbtdb, node, least_serial); - } - } - - /* - * Attempt to switch to a write lock on the tree. If this fails, - * we will add this node to a linked list of nodes in this locking - * bucket which we will free later. - */ - if (tlock != isc_rwlocktype_write) { - /* - * Locking hierarchy notwithstanding, we don't need to free - * the node lock before acquiring the tree write lock because - * we only do a trylock. - */ - if (tlock == isc_rwlocktype_read) - result = isc_rwlock_tryupgrade(&rbtdb->tree_lock); - else - result = isc_rwlock_trylock(&rbtdb->tree_lock, - isc_rwlocktype_write); - RUNTIME_CHECK(result == ISC_R_SUCCESS || - result == ISC_R_LOCKBUSY); - - write_locked = (result == ISC_R_SUCCESS); - } else - write_locked = true; - - isc_refcount_decrement(&nodelock->references, &refs); - INSIST((int)refs >= 0); - - if (KEEP_NODE(node, rbtdb, locked || write_locked)) { - goto restore_locks; - } - -#undef KEEP_NODE - - if (write_locked) { - /* - * We can now delete the node. - */ - - /* - * If this node is the only one in the level it's in, deleting - * this node may recursively make its parent the only node in - * the parent level; if so, and if no one is currently using - * the parent node, this is almost the only opportunity to - * clean it up. But the recursive cleanup is not that trivial - * since the child and parent may be in different lock buckets, - * which would cause a lock order reversal problem. To avoid - * the trouble, we'll dispatch a separate event for batch - * cleaning. We need to check whether we're deleting the node - * as a result of pruning to avoid infinite dispatching. - * Note: pruning happens only when a task has been set for the - * rbtdb. If the user of the rbtdb chooses not to set a task, - * it's their responsibility to purge stale leaves (e.g. by - * periodic walk-through). - */ - if (!pruning && is_leaf(node) && rbtdb->task != NULL) { - send_to_prune_tree(rbtdb, node, isc_rwlocktype_write); - no_reference = false; - } else { - delete_node(rbtdb, node); - } - } else { - INSIST(node->data == NULL); - if (!ISC_LINK_LINKED(node, deadlink)) { - ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, - deadlink); - } - } - - restore_locks: - /* Restore the lock? */ - if (nlock == isc_rwlocktype_read) - NODE_WEAKDOWNGRADE(&nodelock->lock); - - /* - * Relock a read lock, or unlock the write lock if no lock was held. - */ - if (tlock == isc_rwlocktype_none) - if (write_locked) - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - - if (tlock == isc_rwlocktype_read) - if (write_locked) - isc_rwlock_downgrade(&rbtdb->tree_lock); - - return (no_reference); -} - -/* - * Prune the tree by recursively cleaning-up single leaves. In the worst - * case, the number of iteration is the number of tree levels, which is at - * most the maximum number of domain name labels, i.e, 127. In practice, this - * should be much smaller (only a few times), and even the worst case would be - * acceptable for a single event. - */ -static void -prune_tree(isc_task_t *task, isc_event_t *event) { - dns_rbtdb_t *rbtdb = event->ev_sender; - dns_rbtnode_t *node = event->ev_arg; - dns_rbtnode_t *parent; - unsigned int locknum; - - UNUSED(task); - - isc_event_free(&event); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - locknum = node->locknum; - NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); - do { - parent = node->parent; - decrement_reference(rbtdb, node, 0, isc_rwlocktype_write, - isc_rwlocktype_write, true); - - if (parent != NULL && parent->down == NULL) { - /* - * node was the only down child of the parent and has - * just been removed. We'll then need to examine the - * parent. Keep the lock if possible; otherwise, - * release the old lock and acquire one for the parent. - */ - if (parent->locknum != locknum) { - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - locknum = parent->locknum; - NODE_LOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - } - - /* - * We need to gain a reference to the node before - * decrementing it in the next iteration. - */ - if (ISC_LINK_LINKED(parent, deadlink)) { - ISC_LIST_UNLINK(rbtdb->deadnodes[locknum], - parent, deadlink); - } - new_reference(rbtdb, parent, isc_rwlocktype_write); - } else { - parent = NULL; - } - - node = parent; - } while (node != NULL); - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - - detach((dns_db_t **)&rbtdb); -} - -static inline void -make_least_version(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, - rbtdb_changedlist_t *cleanup_list) -{ - /* - * Caller must be holding the database lock. - */ - - rbtdb->least_serial = version->serial; - *cleanup_list = version->changed_list; - ISC_LIST_INIT(version->changed_list); -} - -static inline void -cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) { - rbtdb_changed_t *changed, *next_changed; - - /* - * If the changed record is dirty, then - * an update created multiple versions of - * a given rdataset. We keep this list - * until we're the least open version, at - * which point it's safe to get rid of any - * older versions. - * - * If the changed record isn't dirty, then - * we don't need it anymore since we're - * committing and not rolling back. - * - * The caller must be holding the database lock. - */ - for (changed = HEAD(version->changed_list); - changed != NULL; - changed = next_changed) { - next_changed = NEXT(changed, link); - if (!changed->dirty) { - UNLINK(version->changed_list, - changed, link); - APPEND(*cleanup_list, - changed, link); - } - } -} - -static void -iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) { - dns_rdataset_t keyset; - dns_rdataset_t nsecset, signsecset; - bool haszonekey = false; - bool hasnsec = false; - isc_result_t result; - - dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, origin, version, dns_rdatatype_dnskey, - 0, 0, &keyset, NULL); - if (result == ISC_R_SUCCESS) { - result = dns_rdataset_first(&keyset); - while (result == ISC_R_SUCCESS) { - dns_rdata_t keyrdata = DNS_RDATA_INIT; - dns_rdataset_current(&keyset, &keyrdata); - if (dns_zonekey_iszonekey(&keyrdata)) { - haszonekey = true; - break; - } - result = dns_rdataset_next(&keyset); - } - dns_rdataset_disassociate(&keyset); - } - if (!haszonekey) { - version->secure = dns_db_insecure; - version->havensec3 = false; - return; - } - - dns_rdataset_init(&nsecset); - dns_rdataset_init(&signsecset); - result = dns_db_findrdataset(db, origin, version, dns_rdatatype_nsec, - 0, 0, &nsecset, &signsecset); - if (result == ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&signsecset)) { - hasnsec = true; - dns_rdataset_disassociate(&signsecset); - } - dns_rdataset_disassociate(&nsecset); - } - - setnsec3parameters(db, version); - - /* - * Do we have a valid NSEC/NSEC3 chain? - */ - if (version->havensec3 || hasnsec) - version->secure = dns_db_secure; - else - version->secure = dns_db_insecure; -} - -/*%< - * Walk the origin node looking for NSEC3PARAM records. - * Cache the nsec3 parameters. - */ -static void -setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) { - dns_rbtnode_t *node; - dns_rdata_nsec3param_t nsec3param; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_region_t region; - isc_result_t result; - rdatasetheader_t *header, *header_next; - unsigned char *raw; /* RDATASLAB */ - unsigned int count, length; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - version->havensec3 = false; - node = rbtdb->origin_node; - NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - for (header = node->data; - header != NULL; - header = header_next) { - header_next = header->next; - do { - if (header->serial <= version->serial && - !IGNORE(header)) { - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - - if (header != NULL && - (header->type == dns_rdatatype_nsec3param)) { - /* - * Find A NSEC3PARAM with a supported algorithm. - */ - raw = (unsigned char *)header + sizeof(*header); - count = raw[0] * 256 + raw[1]; /* count */ - raw += DNS_RDATASET_COUNT + DNS_RDATASET_LENGTH; - while (count-- > 0U) { - length = raw[0] * 256 + raw[1]; - raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH; - region.base = raw; - region.length = length; - raw += length; - dns_rdata_fromregion(&rdata, - rbtdb->common.rdclass, - dns_rdatatype_nsec3param, - ®ion); - result = dns_rdata_tostruct(&rdata, - &nsec3param, - NULL); - INSIST(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - - if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG && - !dns_nsec3_supportedhash(nsec3param.hash)) - continue; - - if (nsec3param.flags != 0) - continue; - - memmove(version->salt, nsec3param.salt, - nsec3param.salt_length); - version->hash = nsec3param.hash; - version->salt_length = nsec3param.salt_length; - version->iterations = nsec3param.iterations; - version->flags = nsec3param.flags; - version->havensec3 = true; - /* - * Look for a better algorithm than the - * unknown test algorithm. - */ - if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG) - goto unlock; - } - } - } - unlock: - NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); -} - -static void -cleanup_dead_nodes_callback(isc_task_t *task, isc_event_t *event) { - dns_rbtdb_t *rbtdb = event->ev_arg; - bool again = false; - unsigned int locknum; - unsigned int refs; - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) { - NODE_LOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - cleanup_dead_nodes(rbtdb, locknum); - if (ISC_LIST_HEAD(rbtdb->deadnodes[locknum]) != NULL) - again = true; - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - } - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - if (again) - isc_task_send(task, &event); - else { - isc_event_free(&event); - isc_refcount_decrement(&rbtdb->references, &refs); - if (refs == 0) - maybe_free_rbtdb(rbtdb); - } -} - -static void -closeversion(dns_db_t *db, dns_dbversion_t **versionp, bool commit) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rbtdb_version_t *version, *cleanup_version, *least_greater; - bool rollback = false; - rbtdb_changedlist_t cleanup_list; - rdatasetheaderlist_t resigned_list; - rbtdb_changed_t *changed, *next_changed; - rbtdb_serial_t serial, least_serial; - dns_rbtnode_t *rbtnode; - unsigned int refs; - rdatasetheader_t *header; - - REQUIRE(VALID_RBTDB(rbtdb)); - version = (rbtdb_version_t *)*versionp; - INSIST(version->rbtdb == rbtdb); - - cleanup_version = NULL; - ISC_LIST_INIT(cleanup_list); - ISC_LIST_INIT(resigned_list); - - isc_refcount_decrement(&version->references, &refs); - if (refs > 0) { /* typical and easy case first */ - if (commit) { - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - INSIST(!version->writer); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - } - goto end; - } - - /* - * Update the zone's secure status in version before making - * it the current version. - */ - if (version->writer && commit && !IS_CACHE(rbtdb)) - iszonesecure(db, version, rbtdb->origin_node); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - serial = version->serial; - if (version->writer) { - if (commit) { - unsigned cur_ref; - rbtdb_version_t *cur_version; - - INSIST(version->commit_ok); - INSIST(version == rbtdb->future_version); - /* - * The current version is going to be replaced. - * Release the (likely last) reference to it from the - * DB itself and unlink it from the open list. - */ - cur_version = rbtdb->current_version; - isc_refcount_decrement(&cur_version->references, - &cur_ref); - if (cur_ref == 0) { - if (cur_version->serial == rbtdb->least_serial) - INSIST(EMPTY(cur_version->changed_list)); - UNLINK(rbtdb->open_versions, - cur_version, link); - } - if (EMPTY(rbtdb->open_versions)) { - /* - * We're going to become the least open - * version. - */ - make_least_version(rbtdb, version, - &cleanup_list); - } else { - /* - * Some other open version is the - * least version. We can't cleanup - * records that were changed in this - * version because the older versions - * may still be in use by an open - * version. - * - * We can, however, discard the - * changed records for things that - * we've added that didn't exist in - * prior versions. - */ - cleanup_nondirty(version, &cleanup_list); - } - /* - * If the (soon to be former) current version - * isn't being used by anyone, we can clean - * it up. - */ - if (cur_ref == 0) { - cleanup_version = cur_version; - APPENDLIST(version->changed_list, - cleanup_version->changed_list, - link); - } - /* - * Become the current version. - */ - version->writer = false; - rbtdb->current_version = version; - rbtdb->current_serial = version->serial; - rbtdb->future_version = NULL; - - /* - * Keep the current version in the open list, and - * gain a reference for the DB itself (see the DB - * creation function below). This must be the only - * case where we need to increment the counter from - * zero and need to use isc_refcount_increment0(). - */ - isc_refcount_increment0(&version->references, - &cur_ref); - INSIST(cur_ref == 1); - PREPEND(rbtdb->open_versions, - rbtdb->current_version, link); - resigned_list = version->resigned_list; - ISC_LIST_INIT(version->resigned_list); - } else { - /* - * We're rolling back this transaction. - */ - cleanup_list = version->changed_list; - ISC_LIST_INIT(version->changed_list); - resigned_list = version->resigned_list; - ISC_LIST_INIT(version->resigned_list); - rollback = true; - cleanup_version = version; - rbtdb->future_version = NULL; - } - } else { - if (version != rbtdb->current_version) { - /* - * There are no external or internal references - * to this version and it can be cleaned up. - */ - cleanup_version = version; - - /* - * Find the version with the least serial - * number greater than ours. - */ - least_greater = PREV(version, link); - if (least_greater == NULL) - least_greater = rbtdb->current_version; - - INSIST(version->serial < least_greater->serial); - /* - * Is this the least open version? - */ - if (version->serial == rbtdb->least_serial) { - /* - * Yes. Install the new least open - * version. - */ - make_least_version(rbtdb, - least_greater, - &cleanup_list); - } else { - /* - * Add any unexecuted cleanups to - * those of the least greater version. - */ - APPENDLIST(least_greater->changed_list, - version->changed_list, - link); - } - } else if (version->serial == rbtdb->least_serial) - INSIST(EMPTY(version->changed_list)); - UNLINK(rbtdb->open_versions, version, link); - } - least_serial = rbtdb->least_serial; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - - if (cleanup_version != NULL) { - INSIST(EMPTY(cleanup_version->changed_list)); - isc_rwlock_destroy(&cleanup_version->rwlock); - isc_mem_put(rbtdb->common.mctx, cleanup_version, - sizeof(*cleanup_version)); - } - - /* - * Commit/rollback re-signed headers. - */ - for (header = HEAD(resigned_list); - header != NULL; - header = HEAD(resigned_list)) { - nodelock_t *lock; - - ISC_LIST_UNLINK(resigned_list, header, link); - - lock = &rbtdb->node_locks[header->node->locknum].lock; - NODE_LOCK(lock, isc_rwlocktype_write); - if (rollback && !IGNORE(header)) { - isc_result_t result; - result = resign_insert(rbtdb, header->node->locknum, - header); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_ZONE, ISC_LOG_ERROR, - "Unable to reinsert header to " - "re-signing heap: %s\n", - dns_result_totext(result)); - } - decrement_reference(rbtdb, header->node, least_serial, - isc_rwlocktype_write, isc_rwlocktype_none, - false); - NODE_UNLOCK(lock, isc_rwlocktype_write); - } - - if (!EMPTY(cleanup_list)) { - isc_event_t *event = NULL; - isc_rwlocktype_t tlock = isc_rwlocktype_none; - - if (rbtdb->task != NULL) - event = isc_event_allocate(rbtdb->common.mctx, NULL, - DNS_EVENT_RBTDEADNODES, - cleanup_dead_nodes_callback, - rbtdb, sizeof(isc_event_t)); - if (event == NULL) { - /* - * We acquire a tree write lock here in order to make - * sure that stale nodes will be removed in - * decrement_reference(). If we didn't have the lock, - * those nodes could miss the chance to be removed - * until the server stops. The write lock is - * expensive, but this event should be rare enough - * to justify the cost. - */ - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - tlock = isc_rwlocktype_write; - } - - for (changed = HEAD(cleanup_list); - changed != NULL; - changed = next_changed) { - nodelock_t *lock; - - next_changed = NEXT(changed, link); - rbtnode = changed->node; - lock = &rbtdb->node_locks[rbtnode->locknum].lock; - - NODE_LOCK(lock, isc_rwlocktype_write); - /* - * This is a good opportunity to purge any dead nodes, - * so use it. - */ - if (event == NULL) - cleanup_dead_nodes(rbtdb, rbtnode->locknum); - - if (rollback) - rollback_node(rbtnode, serial); - decrement_reference(rbtdb, rbtnode, least_serial, - isc_rwlocktype_write, tlock, - false); - - NODE_UNLOCK(lock, isc_rwlocktype_write); - - isc_mem_put(rbtdb->common.mctx, changed, - sizeof(*changed)); - } - if (event != NULL) { - isc_refcount_increment(&rbtdb->references, NULL); - isc_task_send(rbtdb->task, &event); - } else - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - } - - end: - *versionp = NULL; -} - -/* - * Add the necessary magic for the wildcard name 'name' - * to be found in 'rbtdb'. - * - * In order for wildcard matching to work correctly in - * zone_find(), we must ensure that a node for the wildcarding - * level exists in the database, and has its 'find_callback' - * and 'wild' bits set. - * - * E.g. if the wildcard name is "*.sub.example." then we - * must ensure that "sub.example." exists and is marked as - * a wildcard level. - * - * tree_lock(write) must be held. - */ -static isc_result_t -add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) { - isc_result_t result; - dns_name_t foundname; - dns_offsets_t offsets; - unsigned int n; - dns_rbtnode_t *node = NULL; - - dns_name_init(&foundname, offsets); - n = dns_name_countlabels(name); - INSIST(n >= 2); - n--; - dns_name_getlabelsequence(name, 1, n, &foundname); - result = dns_rbt_addnode(rbtdb->tree, &foundname, &node); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) - return (result); - if (result == ISC_R_SUCCESS) - node->nsec = DNS_RBT_NSEC_NORMAL; - node->find_callback = 1; - node->wild = 1; - return (ISC_R_SUCCESS); -} - -/* - * tree_lock(write) must be held. - */ -static isc_result_t -add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) { - isc_result_t result; - dns_name_t foundname; - dns_offsets_t offsets; - unsigned int n, l, i; - - dns_name_init(&foundname, offsets); - n = dns_name_countlabels(name); - l = dns_name_countlabels(&rbtdb->common.origin); - i = l + 1; - while (i < n) { - dns_rbtnode_t *node = NULL; /* dummy */ - dns_name_getlabelsequence(name, n - i, i, &foundname); - if (dns_name_iswildcard(&foundname)) { - result = add_wildcard_magic(rbtdb, &foundname); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_rbt_addnode(rbtdb->tree, &foundname, - &node); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) - return (result); - if (result == ISC_R_SUCCESS) - node->nsec = DNS_RBT_NSEC_NORMAL; - } - i++; - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name, - bool create, dns_dbnode_t **nodep) -{ - dns_rbtnode_t *node = NULL; - dns_name_t nodename; - isc_result_t result; - isc_rwlocktype_t locktype = isc_rwlocktype_read; - - INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3); - - dns_name_init(&nodename, NULL); - RWLOCK(&rbtdb->tree_lock, locktype); - result = dns_rbt_findnode(tree, name, NULL, &node, NULL, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result != ISC_R_SUCCESS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - if (!create) { - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - return (result); - } - /* - * It would be nice to try to upgrade the lock instead of - * unlocking then relocking. - */ - locktype = isc_rwlocktype_write; - RWLOCK(&rbtdb->tree_lock, locktype); - node = NULL; - result = dns_rbt_addnode(tree, name, &node); - if (result == ISC_R_SUCCESS) { - dns_rbt_namefromnode(node, &nodename); -#ifdef DNS_RBT_USEHASH - node->locknum = node->hashval % rbtdb->node_lock_count; -#else - node->locknum = dns_name_hash(&nodename, true) % - rbtdb->node_lock_count; -#endif - if (tree == rbtdb->tree) { - add_empty_wildcards(rbtdb, name); - - if (dns_name_iswildcard(name)) { - result = add_wildcard_magic(rbtdb, name); - if (result != ISC_R_SUCCESS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - return (result); - } - } - } - if (tree == rbtdb->nsec3) - node->nsec = DNS_RBT_NSEC_NSEC3; - } else if (result != ISC_R_EXISTS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - return (result); - } - } - - if (tree == rbtdb->nsec3) - INSIST(node->nsec == DNS_RBT_NSEC_NSEC3); - - reactivate_node(rbtdb, node, locktype); - - /* - * Always try to add the policy zone data, because this node might - * already have been implicitly created by the previous addition of - * a longer domain. A common example is adding *.example.com - * (implicitly creating example.com) followed by explicitly adding - * example.com. - */ - if (create && rbtdb->rpzs != NULL && tree == rbtdb->tree) { - dns_fixedname_t fnamef; - dns_name_t *fname; - - dns_fixedname_init(&fnamef); - fname = dns_fixedname_name(&fnamef); - dns_rbt_fullnamefromnode(node, fname); - result = dns_rpz_add(rbtdb->rpzs, rbtdb->rpz_num, fname); - if (result == ISC_R_SUCCESS) - node->rpz = 1; - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { - /* - * It is too late to give up, so merely complain. - */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "dns_rpz_add(): %s", - isc_result_totext(result)); - } - } - - RWUNLOCK(&rbtdb->tree_lock, locktype); - - *nodep = (dns_dbnode_t *)node; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, bool create, - dns_dbnode_t **nodep) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - return (findnodeintree(rbtdb, rbtdb->tree, name, create, nodep)); -} - -static isc_result_t -findnsec3node(dns_db_t *db, dns_name_t *name, bool create, - dns_dbnode_t **nodep) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - return (findnodeintree(rbtdb, rbtdb->nsec3, name, create, nodep)); -} - -static isc_result_t -zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { - rbtdb_search_t *search = arg; - rdatasetheader_t *header, *header_next; - rdatasetheader_t *dname_header, *sigdname_header, *ns_header; - rdatasetheader_t *found; - isc_result_t result; - dns_rbtnode_t *onode; - - /* - * We only want to remember the topmost zone cut, since it's the one - * that counts, so we'll just continue if we've already found a - * zonecut. - */ - if (search->zonecut != NULL) - return (DNS_R_CONTINUE); - - found = NULL; - result = DNS_R_CONTINUE; - onode = search->rbtdb->origin_node; - - NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - - /* - * Look for an NS or DNAME rdataset active in our version. - */ - ns_header = NULL; - dname_header = NULL; - sigdname_header = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (header->type == dns_rdatatype_ns || - header->type == dns_rdatatype_dname || - header->type == RBTDB_RDATATYPE_SIGDNAME) { - do { - if (header->serial <= search->serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) { - if (header->type == dns_rdatatype_dname) - dname_header = header; - else if (header->type == - RBTDB_RDATATYPE_SIGDNAME) - sigdname_header = header; - else if (node != onode || - IS_STUB(search->rbtdb)) { - /* - * We've found an NS rdataset that - * isn't at the origin node. We check - * that they're not at the origin node, - * because otherwise we'd erroneously - * treat the zone top as if it were - * a delegation. - */ - ns_header = header; - } - } - } - } - - /* - * Did we find anything? - */ - if (!IS_CACHE(search->rbtdb) && !IS_STUB(search->rbtdb) && - ns_header != NULL) { - /* - * Note that NS has precedence over DNAME if both exist - * in a zone. Otherwise DNAME take precedence over NS. - */ - found = ns_header; - search->zonecut_sigrdataset = NULL; - } else if (dname_header != NULL) { - found = dname_header; - search->zonecut_sigrdataset = sigdname_header; - } else if (ns_header != NULL) { - found = ns_header; - search->zonecut_sigrdataset = NULL; - } - - if (found != NULL) { - /* - * We increment the reference count on node to ensure that - * search->zonecut_rdataset will still be valid later. - */ - new_reference(search->rbtdb, node, isc_rwlocktype_read); - search->zonecut = node; - search->zonecut_rdataset = found; - search->need_cleanup = true; - /* - * Since we've found a zonecut, anything beneath it is - * glue and is not subject to wildcard matching, so we - * may clear search->wild. - */ - search->wild = false; - if ((search->options & DNS_DBFIND_GLUEOK) == 0) { - /* - * If the caller does not want to find glue, then - * this is the best answer and the search should - * stop now. - */ - result = DNS_R_PARTIALMATCH; - } else { - dns_name_t *zcname; - - /* - * The search will continue beneath the zone cut. - * This may or may not be the best match. In case it - * is, we need to remember the node name. - */ - zcname = dns_fixedname_name(&search->zonecut_name); - RUNTIME_CHECK(dns_name_copy(name, zcname, NULL) == - ISC_R_SUCCESS); - search->copy_name = true; - } - } else { - /* - * There is no zonecut at this node which is active in this - * version. - * - * If this is a "wild" node and the caller hasn't disabled - * wildcard matching, remember that we've seen a wild node - * in case we need to go searching for wildcard matches - * later on. - */ - if (node->wild && (search->options & DNS_DBFIND_NOWILD) == 0) - search->wild = true; - } - - NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - - return (result); -} - -static inline void -bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header, - isc_stdtime_t now, isc_rwlocktype_t locktype, - dns_rdataset_t *rdataset) { - unsigned char *raw; /* RDATASLAB */ - - /* - * Caller must be holding the node reader lock. - * XXXJT: technically, we need a writer lock, since we'll increment - * the header count below. However, since the actual counter value - * doesn't matter, we prioritize performance here. (We may want to - * use atomic increment when available). - */ - - if (rdataset == NULL) - return; - - new_reference(rbtdb, node, locktype); - - INSIST(rdataset->methods == NULL); /* We must be disassociated. */ - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = rbtdb->common.rdclass; - rdataset->type = RBTDB_RDATATYPE_BASE(header->type); - rdataset->covers = RBTDB_RDATATYPE_EXT(header->type); - rdataset->ttl = header->rdh_ttl - now; - rdataset->trust = header->trust; - if (NEGATIVE(header)) - rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; - if (NXDOMAIN(header)) - rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN; - if (OPTOUT(header)) - rdataset->attributes |= DNS_RDATASETATTR_OPTOUT; - if (PREFETCH(header)) - rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; - if (STALE(header)) { - rdataset->attributes |= DNS_RDATASETATTR_STALE; - rdataset->stale_ttl = - (rbtdb->serve_stale_ttl + header->rdh_ttl) - now; - rdataset->ttl = 0; - } - rdataset->private1 = rbtdb; - rdataset->private2 = node; - raw = (unsigned char *)header + sizeof(*header); - rdataset->private3 = raw; - rdataset->count = DNS_RBTDB_INC(header->count); - if (rdataset->count == UINT32_MAX) - rdataset->count = 0; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - - /* - * Add noqname proof. - */ - rdataset->private6 = header->noqname; - if (rdataset->private6 != NULL) - rdataset->attributes |= DNS_RDATASETATTR_NOQNAME; - rdataset->private7 = header->closest; - if (rdataset->private7 != NULL) - rdataset->attributes |= DNS_RDATASETATTR_CLOSEST; - - /* - * Copy out re-signing information. - */ - if (RESIGN(header)) { - rdataset->attributes |= DNS_RDATASETATTR_RESIGN; - rdataset->resign = (header->resign << 1) | header->resign_lsb; - } else - rdataset->resign = 0; -} - -static inline isc_result_t -setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep, - dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_name_t *zcname; - rbtdb_rdatatype_t type; - dns_rbtnode_t *node; - - /* - * The caller MUST NOT be holding any node locks. - */ - - node = search->zonecut; - type = search->zonecut_rdataset->type; - - /* - * If we have to set foundname, we do it before anything else. - * If we were to set foundname after we had set nodep or bound the - * rdataset, then we'd have to undo that work if dns_name_copy() - * failed. By setting foundname first, there's nothing to undo if - * we have trouble. - */ - if (foundname != NULL && search->copy_name) { - zcname = dns_fixedname_name(&search->zonecut_name); - result = dns_name_copy(zcname, foundname, NULL); - if (result != ISC_R_SUCCESS) - return (result); - } - if (nodep != NULL) { - /* - * Note that we don't have to increment the node's reference - * count here because we're going to use the reference we - * already have in the search block. - */ - *nodep = node; - search->need_cleanup = false; - } - if (rdataset != NULL) { - NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - bind_rdataset(search->rbtdb, node, search->zonecut_rdataset, - search->now, isc_rwlocktype_read, rdataset); - if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL) - { - bind_rdataset(search->rbtdb, node, - search->zonecut_sigrdataset, search->now, - isc_rwlocktype_read, sigrdataset); - } - NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - } - - if (type == dns_rdatatype_dname) - return (DNS_R_DNAME); - return (DNS_R_DELEGATION); -} - -static inline bool -valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type, - dns_rbtnode_t *node) -{ - unsigned char *raw; /* RDATASLAB */ - unsigned int count, size; - dns_name_t ns_name; - bool valid = false; - dns_offsets_t offsets; - isc_region_t region; - rdatasetheader_t *header; - - /* - * No additional locking is required. - */ - - /* - * Valid glue types are A, AAAA, A6. NS is also a valid glue type - * if it occurs at a zone cut, but is not valid below it. - */ - if (type == dns_rdatatype_ns) { - if (node != search->zonecut) { - return (false); - } - } else if (type != dns_rdatatype_a && - type != dns_rdatatype_aaaa && - type != dns_rdatatype_a6) { - return (false); - } - - header = search->zonecut_rdataset; - raw = (unsigned char *)header + sizeof(*header); - count = raw[0] * 256 + raw[1]; - raw += DNS_RDATASET_COUNT + DNS_RDATASET_LENGTH; - - while (count > 0) { - count--; - size = raw[0] * 256 + raw[1]; - raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH; - region.base = raw; - region.length = size; - raw += size; - /* - * XXX Until we have rdata structures, we have no choice but - * to directly access the rdata format. - */ - dns_name_init(&ns_name, offsets); - dns_name_fromregion(&ns_name, ®ion); - if (dns_name_compare(&ns_name, name) == 0) { - valid = true; - break; - } - } - - return (valid); -} - -static inline bool -activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain, - dns_name_t *name) -{ - dns_fixedname_t fnext; - dns_fixedname_t forigin; - dns_name_t *next; - dns_name_t *origin; - dns_name_t prefix; - dns_rbtdb_t *rbtdb; - dns_rbtnode_t *node; - isc_result_t result; - bool answer = false; - rdatasetheader_t *header; - - rbtdb = search->rbtdb; - - dns_name_init(&prefix, NULL); - next = dns_fixedname_initname(&fnext); - origin = dns_fixedname_initname(&forigin); - - result = dns_rbtnodechain_next(chain, NULL, NULL); - while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - node = NULL; - result = dns_rbtnodechain_current(chain, &prefix, - origin, &node); - if (result != ISC_R_SUCCESS) - break; - NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - for (header = node->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - if (header != NULL) - break; - result = dns_rbtnodechain_next(chain, NULL, NULL); - } - if (result == ISC_R_SUCCESS) - result = dns_name_concatenate(&prefix, origin, next, NULL); - if (result == ISC_R_SUCCESS && dns_name_issubdomain(next, name)) - answer = true; - return (answer); -} - -static inline bool -activeemptynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { - dns_fixedname_t fnext; - dns_fixedname_t forigin; - dns_fixedname_t fprev; - dns_name_t *next; - dns_name_t *origin; - dns_name_t *prev; - dns_name_t name; - dns_name_t rname; - dns_name_t tname; - dns_rbtdb_t *rbtdb; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - bool check_next = true; - bool check_prev = true; - bool answer = false; - isc_result_t result; - rdatasetheader_t *header; - unsigned int n; - - rbtdb = search->rbtdb; - - dns_name_init(&name, NULL); - dns_name_init(&tname, NULL); - dns_name_init(&rname, NULL); - next = dns_fixedname_initname(&fnext); - prev = dns_fixedname_initname(&fprev); - origin = dns_fixedname_initname(&forigin); - - /* - * Find if qname is at or below a empty node. - * Use our own copy of the chain. - */ - - chain = search->chain; - do { - node = NULL; - result = dns_rbtnodechain_current(&chain, &name, - origin, &node); - if (result != ISC_R_SUCCESS) - break; - NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - for (header = node->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - if (header != NULL) - break; - result = dns_rbtnodechain_prev(&chain, NULL, NULL); - } while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN); - if (result == ISC_R_SUCCESS) - result = dns_name_concatenate(&name, origin, prev, NULL); - if (result != ISC_R_SUCCESS) - check_prev = false; - - result = dns_rbtnodechain_next(&chain, NULL, NULL); - while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - node = NULL; - result = dns_rbtnodechain_current(&chain, &name, - origin, &node); - if (result != ISC_R_SUCCESS) - break; - NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - for (header = node->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - if (header != NULL) - break; - result = dns_rbtnodechain_next(&chain, NULL, NULL); - } - if (result == ISC_R_SUCCESS) - result = dns_name_concatenate(&name, origin, next, NULL); - if (result != ISC_R_SUCCESS) - check_next = false; - - dns_name_clone(qname, &rname); - - /* - * Remove the wildcard label to find the terminal name. - */ - n = dns_name_countlabels(wname); - dns_name_getlabelsequence(wname, 1, n - 1, &tname); - - do { - if ((check_prev && dns_name_issubdomain(prev, &rname)) || - (check_next && dns_name_issubdomain(next, &rname))) { - answer = true; - break; - } - /* - * Remove the left hand label. - */ - n = dns_name_countlabels(&rname); - dns_name_getlabelsequence(&rname, 1, n - 1, &rname); - } while (!dns_name_equal(&rname, &tname)); - return (answer); -} - -static inline isc_result_t -find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep, - dns_name_t *qname) -{ - unsigned int i, j; - dns_rbtnode_t *node, *level_node, *wnode; - rdatasetheader_t *header; - isc_result_t result = ISC_R_NOTFOUND; - dns_name_t name; - dns_name_t *wname; - dns_fixedname_t fwname; - dns_rbtdb_t *rbtdb; - bool done, wild, active; - dns_rbtnodechain_t wchain; - - /* - * Caller must be holding the tree lock and MUST NOT be holding - * any node locks. - */ - - /* - * Examine each ancestor level. If the level's wild bit - * is set, then construct the corresponding wildcard name and - * search for it. If the wildcard node exists, and is active in - * this version, we're done. If not, then we next check to see - * if the ancestor is active in this version. If so, then there - * can be no possible wildcard match and again we're done. If not, - * continue the search. - */ - - rbtdb = search->rbtdb; - i = search->chain.level_matches; - done = false; - node = *nodep; - do { - NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - - /* - * First we try to figure out if this node is active in - * the search's version. We do this now, even though we - * may not need the information, because it simplifies the - * locking and code flow. - */ - for (header = node->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - if (header != NULL) - active = true; - else - active = false; - - if (node->wild) - wild = true; - else - wild = false; - - NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - - if (wild) { - /* - * Construct the wildcard name for this level. - */ - dns_name_init(&name, NULL); - dns_rbt_namefromnode(node, &name); - wname = dns_fixedname_initname(&fwname); - result = dns_name_concatenate(dns_wildcardname, &name, - wname, NULL); - j = i; - while (result == ISC_R_SUCCESS && j != 0) { - j--; - level_node = search->chain.levels[j]; - dns_name_init(&name, NULL); - dns_rbt_namefromnode(level_node, &name); - result = dns_name_concatenate(wname, - &name, - wname, - NULL); - } - if (result != ISC_R_SUCCESS) - break; - - wnode = NULL; - dns_rbtnodechain_init(&wchain, NULL); - result = dns_rbt_findnode(rbtdb->tree, wname, - NULL, &wnode, &wchain, - DNS_RBTFIND_EMPTYDATA, - NULL, NULL); - if (result == ISC_R_SUCCESS) { - nodelock_t *lock; - - /* - * We have found the wildcard node. If it - * is active in the search's version, we're - * done. - */ - lock = &rbtdb->node_locks[wnode->locknum].lock; - NODE_LOCK(lock, isc_rwlocktype_read); - for (header = wnode->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - NODE_UNLOCK(lock, isc_rwlocktype_read); - if (header != NULL || - activeempty(search, &wchain, wname)) { - if (activeemptynode(search, qname, - wname)) { - return (ISC_R_NOTFOUND); - } - /* - * The wildcard node is active! - * - * Note: result is still ISC_R_SUCCESS - * so we don't have to set it. - */ - *nodep = wnode; - break; - } - } else if (result != ISC_R_NOTFOUND && - result != DNS_R_PARTIALMATCH) { - /* - * An error has occurred. Bail out. - */ - break; - } - } - - if (active) { - /* - * The level node is active. Any wildcarding - * present at higher levels has no - * effect and we're done. - */ - result = ISC_R_NOTFOUND; - break; - } - - if (i > 0) { - i--; - node = search->chain.levels[i]; - } else - done = true; - } while (!done); - - return (result); -} - -static bool -matchparams(rdatasetheader_t *header, rbtdb_search_t *search) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3_t nsec3; - unsigned char *raw; /* RDATASLAB */ - unsigned int rdlen, count; - isc_region_t region; - isc_result_t result; - - REQUIRE(header->type == dns_rdatatype_nsec3); - - raw = (unsigned char *)header + sizeof(*header); - count = raw[0] * 256 + raw[1]; /* count */ - raw += DNS_RDATASET_COUNT + DNS_RDATASET_LENGTH; - - while (count-- > 0) { - rdlen = raw[0] * 256 + raw[1]; - raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH; - region.base = raw; - region.length = rdlen; - dns_rdata_fromregion(&rdata, search->rbtdb->common.rdclass, - dns_rdatatype_nsec3, ®ion); - raw += rdlen; - result = dns_rdata_tostruct(&rdata, &nsec3, NULL); - INSIST(result == ISC_R_SUCCESS); - if (nsec3.hash == search->rbtversion->hash && - nsec3.iterations == search->rbtversion->iterations && - nsec3.salt_length == search->rbtversion->salt_length && - memcmp(nsec3.salt, search->rbtversion->salt, - nsec3.salt_length) == 0) - return (true); - dns_rdata_reset(&rdata); - } - return (false); -} - -/* - * Find node of the NSEC/NSEC3 record that is 'name'. - */ -static inline isc_result_t -previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, - dns_name_t *name, dns_name_t *origin, - dns_rbtnode_t **nodep, dns_rbtnodechain_t *nsecchain, - bool *firstp) -{ - dns_fixedname_t ftarget; - dns_name_t *target; - dns_rbtnode_t *nsecnode; - isc_result_t result; - - REQUIRE(nodep != NULL && *nodep == NULL); - - if (type == dns_rdatatype_nsec3) { - result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) - return (result); - result = dns_rbtnodechain_current(&search->chain, name, origin, - nodep); - return (result); - } - - target = dns_fixedname_initname(&ftarget); - - for (;;) { - if (*firstp) { - /* - * Construct the name of the second node to check. - * It is the first node sought in the NSEC tree. - */ - *firstp = false; - dns_rbtnodechain_init(nsecchain, NULL); - result = dns_name_concatenate(name, origin, - target, NULL); - if (result != ISC_R_SUCCESS) - return (result); - nsecnode = NULL; - result = dns_rbt_findnode( - search->rbtdb->nsec, target, NULL, &nsecnode, - nsecchain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result == ISC_R_SUCCESS) { - /* - * Since this was the first loop, finding the - * name in the NSEC tree implies that the first - * node checked in the main tree had an - * unacceptable NSEC record. - * Try the previous node in the NSEC tree. - */ - result = dns_rbtnodechain_prev(nsecchain, - name, origin); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - } else if (result == ISC_R_NOTFOUND || - result == DNS_R_PARTIALMATCH) { - result = dns_rbtnodechain_current(nsecchain, - name, origin, NULL); - if (result == ISC_R_NOTFOUND) - result = ISC_R_NOMORE; - } - } else { - /* - * This is a second or later trip through the auxiliary - * tree for the name of a third or earlier NSEC node in - * the main tree. Previous trips through the NSEC tree - * must have found nodes in the main tree with NSEC - * records. Perhaps they lacked signature records. - */ - result = dns_rbtnodechain_prev(nsecchain, name, origin); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Construct the name to seek in the main tree. - */ - result = dns_name_concatenate(name, origin, target, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - *nodep = NULL; - result = dns_rbt_findnode(search->rbtdb->tree, target, NULL, - nodep, &search->chain, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result == ISC_R_SUCCESS) { - return (result); - } - - /* - * There should always be a node in the main tree with the - * same name as the node in the auxiliary NSEC tree, except for - * nodes in the auxiliary tree that are awaiting deletion. - */ - if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_ERROR, - "previous_closest_nsec(): %s", - isc_result_totext(result)); - return (DNS_R_BADDB); - } - } -} - -/* - * Find the NSEC/NSEC3 which is or before the current point on the - * search chain. For NSEC3 records only NSEC3 records that match the - * current NSEC3PARAM record are considered. - */ -static inline isc_result_t -find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, - dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, dns_rbt_t *tree, - dns_db_secure_t secure) -{ - dns_rbtnode_t *node, *prevnode; - rdatasetheader_t *header, *header_next, *found, *foundsig; - dns_rbtnodechain_t nsecchain; - bool empty_node; - isc_result_t result; - dns_fixedname_t fname, forigin; - dns_name_t *name, *origin; - dns_rdatatype_t type; - rbtdb_rdatatype_t sigtype; - bool wraps; - bool first = true; - bool need_sig = (secure == dns_db_secure); - - if (tree == search->rbtdb->nsec3) { - type = dns_rdatatype_nsec3; - sigtype = RBTDB_RDATATYPE_SIGNSEC3; - wraps = true; - } else { - type = dns_rdatatype_nsec; - sigtype = RBTDB_RDATATYPE_SIGNSEC; - wraps = false; - } - - /* - * Use the auxiliary tree only starting with the second node in the - * hope that the original node will be right much of the time. - */ - name = dns_fixedname_initname(&fname); - origin = dns_fixedname_initname(&forigin); - again: - node = NULL; - prevnode = NULL; - result = dns_rbtnodechain_current(&search->chain, name, origin, &node); - if (result != ISC_R_SUCCESS) - return (result); - do { - NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - found = NULL; - foundsig = NULL; - empty_node = true; - for (header = node->data; - header != NULL; - header = header_next) { - header_next = header->next; - /* - * Look for an active, extant NSEC or RRSIG NSEC. - */ - do { - if (header->serial <= search->serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) { - /* - * We now know that there is at least one - * active rdataset at this node. - */ - empty_node = false; - if (header->type == type) { - found = header; - if (foundsig != NULL) - break; - } else if (header->type == sigtype) { - foundsig = header; - if (found != NULL) - break; - } - } - } - if (!empty_node) { - if (found != NULL && search->rbtversion->havensec3 && - found->type == dns_rdatatype_nsec3 && - !matchparams(found, search)) { - empty_node = true; - found = NULL; - foundsig = NULL; - result = previous_closest_nsec(type, search, - name, origin, - &prevnode, NULL, - NULL); - } else if (found != NULL && - (foundsig != NULL || !need_sig)) { - /* - * We've found the right NSEC/NSEC3 record. - * - * Note: for this to really be the right - * NSEC record, it's essential that the NSEC - * records of any nodes obscured by a zone - * cut have been removed; we assume this is - * the case. - */ - result = dns_name_concatenate(name, origin, - foundname, NULL); - if (result == ISC_R_SUCCESS) { - if (nodep != NULL) { - new_reference( - search->rbtdb, node, - isc_rwlocktype_read); - *nodep = node; - } - bind_rdataset(search->rbtdb, node, - found, search->now, - isc_rwlocktype_read, - rdataset); - if (foundsig != NULL) { - bind_rdataset( - search->rbtdb, node, - foundsig, search->now, - isc_rwlocktype_read, - sigrdataset); - } - } - } else if (found == NULL && foundsig == NULL) { - /* - * This node is active, but has no NSEC or - * RRSIG NSEC. That means it's glue or - * other obscured zone data that isn't - * relevant for our search. Treat the - * node as if it were empty and keep looking. - */ - empty_node = true; - result = previous_closest_nsec(type, search, - name, origin, - &prevnode, - &nsecchain, - &first); - } else { - /* - * We found an active node, but either the - * NSEC or the RRSIG NSEC is missing. This - * shouldn't happen. - */ - result = DNS_R_BADDB; - } - } else { - /* - * This node isn't active. We've got to keep - * looking. - */ - result = previous_closest_nsec(type, search, - name, origin, &prevnode, - &nsecchain, &first); - } - NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), - isc_rwlocktype_read); - node = prevnode; - prevnode = NULL; - } while (empty_node && result == ISC_R_SUCCESS); - - if (!first) - dns_rbtnodechain_invalidate(&nsecchain); - - if (result == ISC_R_NOMORE && wraps) { - result = dns_rbtnodechain_last(&search->chain, tree, - NULL, NULL); - if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - wraps = false; - goto again; - } - } - - /* - * If the result is ISC_R_NOMORE, then we got to the beginning of - * the database and didn't find a NSEC record. This shouldn't - * happen. - */ - if (result == ISC_R_NOMORE) - result = DNS_R_BADDB; - - return (result); -} - -static isc_result_t -zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_rbtnode_t *node = NULL; - isc_result_t result; - rbtdb_search_t search; - bool cname_ok = true; - bool close_version = false; - bool maybe_zonecut = false; - bool at_zonecut = false; - bool wild; - bool empty_node; - rdatasetheader_t *header, *header_next, *found, *nsecheader; - rdatasetheader_t *foundsig, *cnamesig, *nsecsig; - rbtdb_rdatatype_t sigtype; - bool active; - nodelock_t *lock; - dns_rbt_t *tree; - - search.rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(search.rbtdb)); - INSIST(version == NULL || - ((rbtdb_version_t *)version)->rbtdb == (dns_rbtdb_t *)db); - - /* - * We don't care about 'now'. - */ - UNUSED(now); - - /* - * If the caller didn't supply a version, attach to the current - * version. - */ - if (version == NULL) { - currentversion(db, &version); - close_version = true; - } - - search.rbtversion = version; - search.serial = search.rbtversion->serial; - search.options = options; - search.copy_name = false; - search.need_cleanup = false; - search.wild = false; - search.zonecut = NULL; - dns_fixedname_init(&search.zonecut_name); - dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); - search.now = 0; - - /* - * 'wild' will be true iff. we've matched a wildcard. - */ - wild = false; - - RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * Search down from the root of the tree. If, while going down, we - * encounter a callback node, zone_zonecut_callback() will search the - * rdatasets at the zone cut for active DNAME or NS rdatasets. - */ - tree = (options & DNS_DBFIND_FORCENSEC3) != 0 ? search.rbtdb->nsec3 : - search.rbtdb->tree; - result = dns_rbt_findnode(tree, name, foundname, &node, - &search.chain, DNS_RBTFIND_EMPTYDATA, - zone_zonecut_callback, &search); - - if (result == DNS_R_PARTIALMATCH) { - partial_match: - if (search.zonecut != NULL) { - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; - } - - if (search.wild) { - /* - * At least one of the levels in the search chain - * potentially has a wildcard. For each such level, - * we must see if there's a matching wildcard active - * in the current version. - */ - result = find_wildcard(&search, &node, name); - if (result == ISC_R_SUCCESS) { - result = dns_name_copy(name, foundname, NULL); - if (result != ISC_R_SUCCESS) - goto tree_exit; - wild = true; - goto found; - } - else if (result != ISC_R_NOTFOUND) - goto tree_exit; - } - - active = false; - if ((options & DNS_DBFIND_FORCENSEC3) == 0) { - /* - * The NSEC3 tree won't have empty nodes, - * so it isn't necessary to check for them. - */ - dns_rbtnodechain_t chain = search.chain; - active = activeempty(&search, &chain, name); - } - - /* - * If we're here, then the name does not exist, is not - * beneath a zonecut, and there's no matching wildcard. - */ - if ((search.rbtversion->secure == dns_db_secure && - !search.rbtversion->havensec3) || - (search.options & DNS_DBFIND_FORCENSEC) != 0 || - (search.options & DNS_DBFIND_FORCENSEC3) != 0) - { - result = find_closest_nsec(&search, nodep, foundname, - rdataset, sigrdataset, tree, - search.rbtversion->secure); - if (result == ISC_R_SUCCESS) - result = active ? DNS_R_EMPTYNAME : - DNS_R_NXDOMAIN; - } else - result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN; - goto tree_exit; - } else if (result != ISC_R_SUCCESS) - goto tree_exit; - - found: - /* - * We have found a node whose name is the desired name, or we - * have matched a wildcard. - */ - - if (search.zonecut != NULL) { - /* - * If we're beneath a zone cut, we don't want to look for - * CNAMEs because they're not legitimate zone glue. - */ - cname_ok = false; - } else { - /* - * The node may be a zone cut itself. If it might be one, - * make sure we check for it later. - * - * DS records live above the zone cut in ordinary zone so - * we want to ignore any referral. - * - * Stub zones don't have anything "above" the delegation so - * we always return a referral. - */ - if (node->find_callback && - ((node != search.rbtdb->origin_node && - !dns_rdatatype_atparent(type)) || - IS_STUB(search.rbtdb))) - maybe_zonecut = true; - } - - /* - * Certain DNSSEC types are not subject to CNAME matching - * (RFC4035, section 2.5 and RFC3007). - * - * We don't check for RRSIG, because we don't store RRSIG records - * directly. - */ - if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) - cname_ok = false; - - /* - * We now go looking for rdata... - */ - - lock = &search.rbtdb->node_locks[node->locknum].lock; - NODE_LOCK(lock, isc_rwlocktype_read); - - found = NULL; - foundsig = NULL; - sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); - nsecheader = NULL; - nsecsig = NULL; - cnamesig = NULL; - empty_node = true; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - /* - * Look for an active, extant rdataset. - */ - do { - if (header->serial <= search.serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) { - /* - * We now know that there is at least one active - * rdataset at this node. - */ - empty_node = false; - - /* - * Do special zone cut handling, if requested. - */ - if (maybe_zonecut && - header->type == dns_rdatatype_ns) { - /* - * We increment the reference count on node to - * ensure that search->zonecut_rdataset will - * still be valid later. - */ - new_reference(search.rbtdb, node, - isc_rwlocktype_read); - search.zonecut = node; - search.zonecut_rdataset = header; - search.zonecut_sigrdataset = NULL; - search.need_cleanup = true; - maybe_zonecut = false; - at_zonecut = true; - /* - * It is not clear if KEY should still be - * allowed at the parent side of the zone - * cut or not. It is needed for RFC3007 - * validated updates. - */ - if ((search.options & DNS_DBFIND_GLUEOK) == 0 - && type != dns_rdatatype_nsec - && type != dns_rdatatype_key) { - /* - * Glue is not OK, but any answer we - * could return would be glue. Return - * the delegation. - */ - found = NULL; - break; - } - if (found != NULL && foundsig != NULL) - break; - } - - - /* - * If the NSEC3 record doesn't match the chain - * we are using behave as if it isn't here. - */ - if (header->type == dns_rdatatype_nsec3 && - !matchparams(header, &search)) { - NODE_UNLOCK(lock, isc_rwlocktype_read); - goto partial_match; - } - /* - * If we found a type we were looking for, - * remember it. - */ - if (header->type == type || - type == dns_rdatatype_any || - (header->type == dns_rdatatype_cname && - cname_ok)) { - /* - * We've found the answer! - */ - found = header; - if (header->type == dns_rdatatype_cname && - cname_ok) { - /* - * We may be finding a CNAME instead - * of the desired type. - * - * If we've already got the CNAME RRSIG, - * use it, otherwise change sigtype - * so that we find it. - */ - if (cnamesig != NULL) - foundsig = cnamesig; - else - sigtype = - RBTDB_RDATATYPE_SIGCNAME; - } - /* - * If we've got all we need, end the search. - */ - if (!maybe_zonecut && foundsig != NULL) - break; - } else if (header->type == sigtype) { - /* - * We've found the RRSIG rdataset for our - * target type. Remember it. - */ - foundsig = header; - /* - * If we've got all we need, end the search. - */ - if (!maybe_zonecut && found != NULL) - break; - } else if (header->type == dns_rdatatype_nsec && - !search.rbtversion->havensec3) { - /* - * Remember a NSEC rdataset even if we're - * not specifically looking for it, because - * we might need it later. - */ - nsecheader = header; - } else if (header->type == RBTDB_RDATATYPE_SIGNSEC && - !search.rbtversion->havensec3) { - /* - * If we need the NSEC rdataset, we'll also - * need its signature. - */ - nsecsig = header; - } else if (cname_ok && - header->type == RBTDB_RDATATYPE_SIGCNAME) { - /* - * If we get a CNAME match, we'll also need - * its signature. - */ - cnamesig = header; - } - } - } - - if (empty_node) { - /* - * We have an exact match for the name, but there are no - * active rdatasets in the desired version. That means that - * this node doesn't exist in the desired version, and that - * we really have a partial match. - */ - if (!wild) { - NODE_UNLOCK(lock, isc_rwlocktype_read); - goto partial_match; - } - } - - /* - * If we didn't find what we were looking for... - */ - if (found == NULL) { - if (search.zonecut != NULL) { - /* - * We were trying to find glue at a node beneath a - * zone cut, but didn't. - * - * Return the delegation. - */ - NODE_UNLOCK(lock, isc_rwlocktype_read); - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; - } - /* - * The desired type doesn't exist. - */ - result = DNS_R_NXRRSET; - if (search.rbtversion->secure == dns_db_secure && - !search.rbtversion->havensec3 && - (nsecheader == NULL || nsecsig == NULL)) { - /* - * The zone is secure but there's no NSEC, - * or the NSEC has no signature! - */ - if (!wild) { - result = DNS_R_BADDB; - goto node_exit; - } - - NODE_UNLOCK(lock, isc_rwlocktype_read); - result = find_closest_nsec(&search, nodep, foundname, - rdataset, sigrdataset, - search.rbtdb->tree, - search.rbtversion->secure); - if (result == ISC_R_SUCCESS) - result = DNS_R_EMPTYWILD; - goto tree_exit; - } - if ((search.options & DNS_DBFIND_FORCENSEC) != 0 && - nsecheader == NULL) - { - /* - * There's no NSEC record, and we were told - * to find one. - */ - result = DNS_R_BADDB; - goto node_exit; - } - if (nodep != NULL) { - new_reference(search.rbtdb, node, isc_rwlocktype_read); - *nodep = node; - } - if ((search.rbtversion->secure == dns_db_secure && - !search.rbtversion->havensec3) || - (search.options & DNS_DBFIND_FORCENSEC) != 0) - { - bind_rdataset(search.rbtdb, node, nsecheader, 0, - isc_rwlocktype_read, rdataset); - if (nsecsig != NULL) { - bind_rdataset(search.rbtdb, node, nsecsig, 0, - isc_rwlocktype_read, sigrdataset); - } - } - if (wild) - foundname->attributes |= DNS_NAMEATTR_WILDCARD; - goto node_exit; - } - - /* - * We found what we were looking for, or we found a CNAME. - */ - - if (type != found->type && - type != dns_rdatatype_any && - found->type == dns_rdatatype_cname) { - /* - * We weren't doing an ANY query and we found a CNAME instead - * of the type we were looking for, so we need to indicate - * that result to the caller. - */ - result = DNS_R_CNAME; - } else if (search.zonecut != NULL) { - /* - * If we're beneath a zone cut, we must indicate that the - * result is glue, unless we're actually at the zone cut - * and the type is NSEC or KEY. - */ - if (search.zonecut == node) { - /* - * It is not clear if KEY should still be - * allowed at the parent side of the zone - * cut or not. It is needed for RFC3007 - * validated updates. - */ - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3 || - type == dns_rdatatype_key) - result = ISC_R_SUCCESS; - else if (type == dns_rdatatype_any) - result = DNS_R_ZONECUT; - else - result = DNS_R_GLUE; - } else - result = DNS_R_GLUE; - /* - * We might have found data that isn't glue, but was occluded - * by a dynamic update. If the caller cares about this, they - * will have told us to validate glue. - * - * XXX We should cache the glue validity state! - */ - if (result == DNS_R_GLUE && - (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 && - !valid_glue(&search, foundname, type, node)) { - NODE_UNLOCK(lock, isc_rwlocktype_read); - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; - } - } else { - /* - * An ordinary successful query! - */ - result = ISC_R_SUCCESS; - } - - if (nodep != NULL) { - if (!at_zonecut) { - new_reference(search.rbtdb, node, isc_rwlocktype_read); - } else { - search.need_cleanup = false; - } - *nodep = node; - } - - if (type != dns_rdatatype_any) { - bind_rdataset(search.rbtdb, node, found, 0, isc_rwlocktype_read, - rdataset); - if (foundsig != NULL) { - bind_rdataset(search.rbtdb, node, foundsig, 0, - isc_rwlocktype_read, sigrdataset); - } - } - - if (wild) - foundname->attributes |= DNS_NAMEATTR_WILDCARD; - - node_exit: - NODE_UNLOCK(lock, isc_rwlocktype_read); - - tree_exit: - RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * If we found a zonecut but aren't going to use it, we have to - * let go of it. - */ - if (search.need_cleanup) { - node = search.zonecut; - INSIST(node != NULL); - lock = &(search.rbtdb->node_locks[node->locknum].lock); - - NODE_LOCK(lock, isc_rwlocktype_read); - decrement_reference(search.rbtdb, node, 0, - isc_rwlocktype_read, isc_rwlocktype_none, - false); - NODE_UNLOCK(lock, isc_rwlocktype_read); - } - - if (close_version) - closeversion(db, &version, false); - - dns_rbtnodechain_reset(&search.chain); - - return (result); -} - -static isc_result_t -zone_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, - dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - UNUSED(db); - UNUSED(name); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - FATAL_ERROR(__FILE__, __LINE__, "zone_findzonecut() called!"); - - /* NOTREACHED */ - return (ISC_R_NOTIMPLEMENTED); -} - -static bool -check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header, - isc_rwlocktype_t *locktype, nodelock_t *lock, - rbtdb_search_t *search, rdatasetheader_t **header_prev) -{ - -#if !defined(ISC_RWLOCK_USEATOMIC) || !defined(DNS_RBT_USEISCREFCOUNT) - UNUSED(lock); -#endif - - if (!ACTIVE(header, search->now)) { - dns_ttl_t stale = header->rdh_ttl + - search->rbtdb->serve_stale_ttl; - /* - * If this data is in the stale window keep it and if - * DNS_DBFIND_STALEOK is not set we tell the caller to - * skip this record. - */ - if (KEEPSTALE(search->rbtdb) && stale > search->now) { - header->attributes |= RDATASET_ATTR_STALE; - *header_prev = header; - return ((search->options & DNS_DBFIND_STALEOK) == 0); - } - - /* - * This rdataset is stale. If no one else is using the - * node, we can clean it up right now, otherwise we mark - * it as stale, and the node as dirty, so it will get - * cleaned up later. - */ - if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) && - (*locktype == isc_rwlocktype_write || - NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) - { - /* - * We update the node's status only when we can - * get write access; otherwise, we leave others - * to this work. Periodical cleaning will - * eventually take the job as the last resort. - * We won't downgrade the lock, since other - * rdatasets are probably stale, too. - */ - *locktype = isc_rwlocktype_write; - - if (dns_rbtnode_refcurrent(node) == 0) { - isc_mem_t *mctx; - - /* - * header->down can be non-NULL if the - * refcount has just decremented to 0 - * but decrement_reference() has not - * performed clean_cache_node(), in - * which case we need to purge the stale - * headers first. - */ - mctx = search->rbtdb->common.mctx; - clean_stale_headers(search->rbtdb, mctx, header); - if (*header_prev != NULL) - (*header_prev)->next = header->next; - else - node->data = header->next; - free_rdataset(search->rbtdb, mctx, header); - } else { - mark_header_ancient(search->rbtdb, header); - *header_prev = header; - } - } else - *header_prev = header; - return (true); - } - return (false); -} - -static isc_result_t -cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { - rbtdb_search_t *search = arg; - rdatasetheader_t *header, *header_prev, *header_next; - rdatasetheader_t *dname_header, *sigdname_header; - isc_result_t result; - nodelock_t *lock; - isc_rwlocktype_t locktype; - - /* XXX comment */ - - REQUIRE(search->zonecut == NULL); - - /* - * Keep compiler silent. - */ - UNUSED(name); - - lock = &(search->rbtdb->node_locks[node->locknum].lock); - locktype = isc_rwlocktype_read; - NODE_LOCK(lock, locktype); - - /* - * Look for a DNAME or RRSIG DNAME rdataset. - */ - dname_header = NULL; - sigdname_header = NULL; - header_prev = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (check_stale_header(node, header, - &locktype, lock, search, - &header_prev)) { - /* Do nothing. */ - } else if (header->type == dns_rdatatype_dname && - EXISTS(header)) { - dname_header = header; - header_prev = header; - } else if (header->type == RBTDB_RDATATYPE_SIGDNAME && - EXISTS(header)) { - sigdname_header = header; - header_prev = header; - } else - header_prev = header; - } - - if (dname_header != NULL && - (!DNS_TRUST_PENDING(dname_header->trust) || - (search->options & DNS_DBFIND_PENDINGOK) != 0)) { - /* - * We increment the reference count on node to ensure that - * search->zonecut_rdataset will still be valid later. - */ - new_reference(search->rbtdb, node, locktype); - search->zonecut = node; - search->zonecut_rdataset = dname_header; - search->zonecut_sigrdataset = sigdname_header; - search->need_cleanup = true; - result = DNS_R_PARTIALMATCH; - } else - result = DNS_R_CONTINUE; - - NODE_UNLOCK(lock, locktype); - - return (result); -} - -static inline isc_result_t -find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - unsigned int i; - dns_rbtnode_t *level_node; - rdatasetheader_t *header, *header_prev, *header_next; - rdatasetheader_t *found, *foundsig; - isc_result_t result = ISC_R_NOTFOUND; - dns_name_t name; - dns_rbtdb_t *rbtdb; - bool done; - nodelock_t *lock; - isc_rwlocktype_t locktype; - - /* - * Caller must be holding the tree lock. - */ - - rbtdb = search->rbtdb; - i = search->chain.level_matches; - done = false; - do { - locktype = isc_rwlocktype_read; - lock = &rbtdb->node_locks[node->locknum].lock; - NODE_LOCK(lock, locktype); - - /* - * Look for NS and RRSIG NS rdatasets. - */ - found = NULL; - foundsig = NULL; - header_prev = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (check_stale_header(node, header, - &locktype, lock, search, - &header_prev)) { - /* Do nothing. */ - } else if (EXISTS(header)) { - /* - * We've found an extant rdataset. See if - * we're interested in it. - */ - if (header->type == dns_rdatatype_ns) { - found = header; - if (foundsig != NULL) - break; - } else if (header->type == - RBTDB_RDATATYPE_SIGNS) { - foundsig = header; - if (found != NULL) - break; - } - header_prev = header; - } else - header_prev = header; - } - - if (found != NULL) { - /* - * If we have to set foundname, we do it before - * anything else. If we were to set foundname after - * we had set nodep or bound the rdataset, then we'd - * have to undo that work if dns_name_concatenate() - * failed. By setting foundname first, there's - * nothing to undo if we have trouble. - */ - if (foundname != NULL) { - dns_name_init(&name, NULL); - dns_rbt_namefromnode(node, &name); - result = dns_name_copy(&name, foundname, NULL); - while (result == ISC_R_SUCCESS && i > 0) { - i--; - level_node = search->chain.levels[i]; - dns_name_init(&name, NULL); - dns_rbt_namefromnode(level_node, - &name); - result = - dns_name_concatenate(foundname, - &name, - foundname, - NULL); - } - if (result != ISC_R_SUCCESS) { - *nodep = NULL; - goto node_exit; - } - } - result = DNS_R_DELEGATION; - if (nodep != NULL) { - new_reference(search->rbtdb, node, locktype); - *nodep = node; - } - bind_rdataset(search->rbtdb, node, found, search->now, - locktype, rdataset); - if (foundsig != NULL) { - bind_rdataset(search->rbtdb, node, foundsig, - search->now, locktype, - sigrdataset); - } - if (need_headerupdate(found, search->now) || - (foundsig != NULL && - need_headerupdate(foundsig, search->now))) { - if (locktype != isc_rwlocktype_write) { - NODE_UNLOCK(lock, locktype); - NODE_LOCK(lock, isc_rwlocktype_write); - locktype = isc_rwlocktype_write; - POST(locktype); - } - if (need_headerupdate(found, search->now)) - update_header(search->rbtdb, found, - search->now); - if (foundsig != NULL && - need_headerupdate(foundsig, search->now)) { - update_header(search->rbtdb, foundsig, - search->now); - } - } - } - - node_exit: - NODE_UNLOCK(lock, locktype); - - if (found == NULL && i > 0) { - i--; - node = search->chain.levels[i]; - } else - done = true; - - } while (!done); - - return (result); -} - -static isc_result_t -find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, - isc_stdtime_t now, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_rbtnode_t *node; - rdatasetheader_t *header, *header_next, *header_prev; - rdatasetheader_t *found, *foundsig; - bool empty_node; - isc_result_t result; - dns_fixedname_t fname, forigin; - dns_name_t *name, *origin; - rbtdb_rdatatype_t matchtype, sigmatchtype; - nodelock_t *lock; - isc_rwlocktype_t locktype; - - matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0); - sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, - dns_rdatatype_nsec); - - do { - node = NULL; - name = dns_fixedname_initname(&fname); - origin = dns_fixedname_initname(&forigin); - result = dns_rbtnodechain_current(&search->chain, name, - origin, &node); - if (result != ISC_R_SUCCESS) - return (result); - locktype = isc_rwlocktype_read; - lock = &(search->rbtdb->node_locks[node->locknum].lock); - NODE_LOCK(lock, locktype); - found = NULL; - foundsig = NULL; - empty_node = true; - header_prev = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (check_stale_header(node, header, - &locktype, lock, search, - &header_prev)) { - continue; - } - if (NONEXISTENT(header) || - RBTDB_RDATATYPE_BASE(header->type) == 0) { - header_prev = header; - continue; - } - empty_node = false; - if (header->type == matchtype) - found = header; - else if (header->type == sigmatchtype) - foundsig = header; - header_prev = header; - } - if (found != NULL) { - result = dns_name_concatenate(name, origin, - foundname, NULL); - if (result != ISC_R_SUCCESS) { - goto unlock_node; - } - bind_rdataset(search->rbtdb, node, found, now, locktype, - rdataset); - if (foundsig != NULL) { - bind_rdataset(search->rbtdb, node, foundsig, - now, locktype, sigrdataset); - } - new_reference(search->rbtdb, node, locktype); - *nodep = node; - result = DNS_R_COVERINGNSEC; - } else if (!empty_node) { - result = ISC_R_NOTFOUND; - } else - result = dns_rbtnodechain_prev(&search->chain, NULL, - NULL); - unlock_node: - NODE_UNLOCK(lock, locktype); - } while (empty_node && result == ISC_R_SUCCESS); - return (result); -} - -/* - * Connect this RBTDB to the response policy zone summary data for the view. - */ -static void -rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { - dns_rbtdb_t * rbtdb; - - rbtdb = (dns_rbtdb_t *)db; - REQUIRE(VALID_RBTDB(rbtdb)); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - REQUIRE(rbtdb->rpzs == NULL && rbtdb->rpz_num == DNS_RPZ_INVALID_NUM); - dns_rpz_attach_rpzs(rpzs, &rbtdb->rpzs); - rbtdb->rpz_num = rpz_num; - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); -} - -/* - * Enable this RBTDB as a response policy zone. - */ -static isc_result_t -rpz_ready(dns_db_t *db) { - dns_rbtdb_t * rbtdb; - isc_result_t result; - - rbtdb = (dns_rbtdb_t *)db; - REQUIRE(VALID_RBTDB(rbtdb)); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - if (rbtdb->rpzs == NULL) { - INSIST(rbtdb->rpz_num == DNS_RPZ_INVALID_NUM); - result = ISC_R_SUCCESS; - } else { - result = dns_rpz_ready(rbtdb->rpzs, &rbtdb->load_rpzs, - rbtdb->rpz_num); - } - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - return (result); -} - -static isc_result_t -cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_rbtnode_t *node = NULL; - isc_result_t result; - rbtdb_search_t search; - bool cname_ok = true; - bool empty_node; - nodelock_t *lock; - isc_rwlocktype_t locktype; - rdatasetheader_t *header, *header_prev, *header_next; - rdatasetheader_t *found, *nsheader; - rdatasetheader_t *foundsig, *nssig, *cnamesig; - rdatasetheader_t *update, *updatesig; - rbtdb_rdatatype_t sigtype, negtype; - - UNUSED(version); - - search.rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(search.rbtdb)); - REQUIRE(version == NULL); - - if (now == 0) - isc_stdtime_get(&now); - - search.rbtversion = NULL; - search.serial = 1; - search.options = options; - search.copy_name = false; - search.need_cleanup = false; - search.wild = false; - search.zonecut = NULL; - dns_fixedname_init(&search.zonecut_name); - dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); - search.now = now; - update = NULL; - updatesig = NULL; - - RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * Search down from the root of the tree. If, while going down, we - * encounter a callback node, cache_zonecut_callback() will search the - * rdatasets at the zone cut for a DNAME rdataset. - */ - result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node, - &search.chain, DNS_RBTFIND_EMPTYDATA, - cache_zonecut_callback, &search); - - if (result == DNS_R_PARTIALMATCH) { - if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0) { - result = find_coveringnsec(&search, nodep, now, - foundname, rdataset, - sigrdataset); - if (result == DNS_R_COVERINGNSEC) - goto tree_exit; - } - if (search.zonecut != NULL) { - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; - } else { - find_ns: - result = find_deepest_zonecut(&search, node, nodep, - foundname, rdataset, - sigrdataset); - goto tree_exit; - } - } else if (result != ISC_R_SUCCESS) - goto tree_exit; - - /* - * Certain DNSSEC types are not subject to CNAME matching - * (RFC4035, section 2.5 and RFC3007). - * - * We don't check for RRSIG, because we don't store RRSIG records - * directly. - */ - if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) - cname_ok = false; - - /* - * We now go looking for rdata... - */ - - lock = &(search.rbtdb->node_locks[node->locknum].lock); - locktype = isc_rwlocktype_read; - NODE_LOCK(lock, locktype); - - found = NULL; - foundsig = NULL; - sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); - negtype = RBTDB_RDATATYPE_VALUE(0, type); - nsheader = NULL; - nssig = NULL; - cnamesig = NULL; - empty_node = true; - header_prev = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (check_stale_header(node, header, - &locktype, lock, &search, - &header_prev)) { - /* Do nothing. */ - } else if (EXISTS(header) && !ANCIENT(header)) { - /* - * We now know that there is at least one active - * non-stale rdataset at this node. - */ - empty_node = false; - - /* - * If we found a type we were looking for, remember - * it. - */ - if (header->type == type || - (type == dns_rdatatype_any && - RBTDB_RDATATYPE_BASE(header->type) != 0) || - (cname_ok && header->type == - dns_rdatatype_cname)) { - /* - * We've found the answer. - */ - found = header; - if (header->type == dns_rdatatype_cname && - cname_ok && - cnamesig != NULL) { - /* - * If we've already got the - * CNAME RRSIG, use it. - */ - foundsig = cnamesig; - } - } else if (header->type == sigtype) { - /* - * We've found the RRSIG rdataset for our - * target type. Remember it. - */ - foundsig = header; - } else if (header->type == RBTDB_RDATATYPE_NCACHEANY || - header->type == negtype) { - /* - * We've found a negative cache entry. - */ - found = header; - } else if (header->type == dns_rdatatype_ns) { - /* - * Remember a NS rdataset even if we're - * not specifically looking for it, because - * we might need it later. - */ - nsheader = header; - } else if (header->type == RBTDB_RDATATYPE_SIGNS) { - /* - * If we need the NS rdataset, we'll also - * need its signature. - */ - nssig = header; - } else if (cname_ok && - header->type == RBTDB_RDATATYPE_SIGCNAME) { - /* - * If we get a CNAME match, we'll also need - * its signature. - */ - cnamesig = header; - } - header_prev = header; - } else - header_prev = header; - } - - if (empty_node) { - /* - * We have an exact match for the name, but there are no - * extant rdatasets. That means that this node doesn't - * meaningfully exist, and that we really have a partial match. - */ - NODE_UNLOCK(lock, locktype); - goto find_ns; - } - - /* - * If we didn't find what we were looking for... - */ - if (found == NULL || - (DNS_TRUST_ADDITIONAL(found->trust) && - ((options & DNS_DBFIND_ADDITIONALOK) == 0)) || - (found->trust == dns_trust_glue && - ((options & DNS_DBFIND_GLUEOK) == 0)) || - (DNS_TRUST_PENDING(found->trust) && - ((options & DNS_DBFIND_PENDINGOK) == 0))) { - /* - * If there is an NS rdataset at this node, then this is the - * deepest zone cut. - */ - if (nsheader != NULL) { - if (nodep != NULL) { - new_reference(search.rbtdb, node, locktype); - *nodep = node; - } - bind_rdataset(search.rbtdb, node, nsheader, search.now, - locktype, rdataset); - if (need_headerupdate(nsheader, search.now)) { - update = nsheader; - } - if (nssig != NULL) { - bind_rdataset(search.rbtdb, node, nssig, - search.now, locktype, - sigrdataset); - if (need_headerupdate(nssig, search.now)) { - updatesig = nssig; - } - } - result = DNS_R_DELEGATION; - goto node_exit; - } - - /* - * Go find the deepest zone cut. - */ - NODE_UNLOCK(lock, locktype); - goto find_ns; - } - - /* - * We found what we were looking for, or we found a CNAME. - */ - - if (nodep != NULL) { - new_reference(search.rbtdb, node, locktype); - *nodep = node; - } - - if (NEGATIVE(found)) { - /* - * We found a negative cache entry. - */ - if (NXDOMAIN(found)) - result = DNS_R_NCACHENXDOMAIN; - else - result = DNS_R_NCACHENXRRSET; - } else if (type != found->type && - type != dns_rdatatype_any && - found->type == dns_rdatatype_cname) { - /* - * We weren't doing an ANY query and we found a CNAME instead - * of the type we were looking for, so we need to indicate - * that result to the caller. - */ - result = DNS_R_CNAME; - } else { - /* - * An ordinary successful query! - */ - result = ISC_R_SUCCESS; - } - - if (type != dns_rdatatype_any || result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET) - { - bind_rdataset(search.rbtdb, node, found, search.now, locktype, - rdataset); - if (need_headerupdate(found, search.now)) { - update = found; - } - if (!NEGATIVE(found) && foundsig != NULL) { - bind_rdataset(search.rbtdb, node, foundsig, search.now, - locktype, sigrdataset); - if (need_headerupdate(foundsig, search.now)) { - updatesig = foundsig; - } - } - } - - node_exit: - if ((update != NULL || updatesig != NULL) && - locktype != isc_rwlocktype_write) { - NODE_UNLOCK(lock, locktype); - NODE_LOCK(lock, isc_rwlocktype_write); - locktype = isc_rwlocktype_write; - POST(locktype); - } - if (update != NULL && need_headerupdate(update, search.now)) - update_header(search.rbtdb, update, search.now); - if (updatesig != NULL && need_headerupdate(updatesig, search.now)) - update_header(search.rbtdb, updatesig, search.now); - - NODE_UNLOCK(lock, locktype); - - tree_exit: - RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * If we found a zonecut but aren't going to use it, we have to - * let go of it. - */ - if (search.need_cleanup) { - node = search.zonecut; - INSIST(node != NULL); - lock = &(search.rbtdb->node_locks[node->locknum].lock); - - NODE_LOCK(lock, isc_rwlocktype_read); - decrement_reference(search.rbtdb, node, 0, - isc_rwlocktype_read, isc_rwlocktype_none, - false); - NODE_UNLOCK(lock, isc_rwlocktype_read); - } - - dns_rbtnodechain_reset(&search.chain); - - update_cachestats(search.rbtdb, result); - return (result); -} - -static isc_result_t -cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, - dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_rbtnode_t *node = NULL; - nodelock_t *lock; - isc_result_t result; - rbtdb_search_t search; - rdatasetheader_t *header, *header_prev, *header_next; - rdatasetheader_t *found, *foundsig; - unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA; - isc_rwlocktype_t locktype; - - search.rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(search.rbtdb)); - - if (now == 0) - isc_stdtime_get(&now); - - search.rbtversion = NULL; - search.serial = 1; - search.options = options; - search.copy_name = false; - search.need_cleanup = false; - search.wild = false; - search.zonecut = NULL; - dns_fixedname_init(&search.zonecut_name); - dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); - search.now = now; - - if ((options & DNS_DBFIND_NOEXACT) != 0) - rbtoptions |= DNS_RBTFIND_NOEXACT; - - RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * Search down from the root of the tree. - */ - result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node, - &search.chain, rbtoptions, NULL, &search); - - if (result == DNS_R_PARTIALMATCH) { - find_ns: - result = find_deepest_zonecut(&search, node, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; - } else if (result != ISC_R_SUCCESS) - goto tree_exit; - - /* - * We now go looking for an NS rdataset at the node. - */ - - lock = &(search.rbtdb->node_locks[node->locknum].lock); - locktype = isc_rwlocktype_read; - NODE_LOCK(lock, locktype); - - found = NULL; - foundsig = NULL; - header_prev = NULL; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (check_stale_header(node, header, - &locktype, lock, &search, - &header_prev)) { - /* Do nothing. */ - } else if (EXISTS(header)) { - /* - * If we found a type we were looking for, remember - * it. - */ - if (header->type == dns_rdatatype_ns) { - /* - * Remember a NS rdataset even if we're - * not specifically looking for it, because - * we might need it later. - */ - found = header; - } else if (header->type == RBTDB_RDATATYPE_SIGNS) { - /* - * If we need the NS rdataset, we'll also - * need its signature. - */ - foundsig = header; - } - header_prev = header; - } else - header_prev = header; - } - - if (found == NULL) { - /* - * No NS records here. - */ - NODE_UNLOCK(lock, locktype); - goto find_ns; - } - - if (nodep != NULL) { - new_reference(search.rbtdb, node, locktype); - *nodep = node; - } - - bind_rdataset(search.rbtdb, node, found, search.now, locktype, - rdataset); - if (foundsig != NULL) { - bind_rdataset(search.rbtdb, node, foundsig, search.now, - locktype, sigrdataset); - } - - if (need_headerupdate(found, search.now) || - (foundsig != NULL && need_headerupdate(foundsig, search.now))) { - if (locktype != isc_rwlocktype_write) { - NODE_UNLOCK(lock, locktype); - NODE_LOCK(lock, isc_rwlocktype_write); - locktype = isc_rwlocktype_write; - POST(locktype); - } - if (need_headerupdate(found, search.now)) - update_header(search.rbtdb, found, search.now); - if (foundsig != NULL && - need_headerupdate(foundsig, search.now)) { - update_header(search.rbtdb, foundsig, search.now); - } - } - - NODE_UNLOCK(lock, locktype); - - tree_exit: - RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); - - INSIST(!search.need_cleanup); - - dns_rbtnodechain_reset(&search.chain); - - if (result == DNS_R_DELEGATION) - result = ISC_R_SUCCESS; - - return (result); -} - -static void -attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *node = (dns_rbtnode_t *)source; - unsigned int refs; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(targetp != NULL && *targetp == NULL); - - NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); - dns_rbtnode_refincrement(node, &refs); - INSIST(refs != 0); - NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); - - *targetp = source; -} - -static void -detachnode(dns_db_t *db, dns_dbnode_t **targetp) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *node; - bool want_free = false; - bool inactive = false; - rbtdb_nodelock_t *nodelock; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(targetp != NULL && *targetp != NULL); - - node = (dns_rbtnode_t *)(*targetp); - nodelock = &rbtdb->node_locks[node->locknum]; - - NODE_LOCK(&nodelock->lock, isc_rwlocktype_read); - - if (decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, - isc_rwlocktype_none, false)) { - if (isc_refcount_current(&nodelock->references) == 0 && - nodelock->exiting) { - inactive = true; - } - } - - NODE_UNLOCK(&nodelock->lock, isc_rwlocktype_read); - - *targetp = NULL; - - if (inactive) { - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - rbtdb->active--; - if (rbtdb->active == 0) - want_free = true; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - if (want_free) { - char buf[DNS_NAME_FORMATSIZE]; - if (dns_name_dynamic(&rbtdb->common.origin)) - dns_name_format(&rbtdb->common.origin, buf, - sizeof(buf)); - else - strlcpy(buf, "", sizeof(buf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "calling free_rbtdb(%s)", buf); - free_rbtdb(rbtdb, true, NULL); - } - } -} - -static isc_result_t -expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = node; - rdatasetheader_t *header; - bool force_expire = false; - /* - * These are the category and module used by the cache cleaner. - */ - bool log = false; - isc_logcategory_t *category = DNS_LOGCATEGORY_DATABASE; - isc_logmodule_t *module = DNS_LOGMODULE_CACHE; - int level = ISC_LOG_DEBUG(2); - char printname[DNS_NAME_FORMATSIZE]; - - REQUIRE(VALID_RBTDB(rbtdb)); - - /* - * Caller must hold a tree lock. - */ - - if (now == 0) - isc_stdtime_get(&now); - - if (isc_mem_isovermem(rbtdb->common.mctx)) { - uint32_t val; - - isc_random_get(&val); - /* - * XXXDCL Could stand to have a better policy, like LRU. - */ - force_expire = (rbtnode->down == NULL && val % 4 == 0); - - /* - * Note that 'log' can be true IFF overmem is also true. - * overmem can currently only be true for cache - * databases -- hence all of the "overmem cache" log strings. - */ - log = isc_log_wouldlog(dns_lctx, level); - if (log) - isc_log_write(dns_lctx, category, module, level, - "overmem cache: %s %s", - force_expire ? "FORCE" : "check", - dns_rbt_formatnodename(rbtnode, - printname, - sizeof(printname))); - } - - /* - * We may not need write access, but this code path is not performance - * sensitive, so it should be okay to always lock as a writer. - */ - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - for (header = rbtnode->data; header != NULL; header = header->next) - if (header->rdh_ttl <= now - RBTDB_VIRTUAL) { - /* - * We don't check if refcurrent(rbtnode) == 0 and try - * to free like we do in cache_find(), because - * refcurrent(rbtnode) must be non-zero. This is so - * because 'node' is an argument to the function. - */ - mark_header_ancient(rbtdb, header); - if (log) - isc_log_write(dns_lctx, category, module, - level, "overmem cache: stale %s", - printname); - } else if (force_expire) { - if (! RETAIN(header)) { - set_ttl(rbtdb, header, 0); - mark_header_ancient(rbtdb, header); - } else if (log) { - isc_log_write(dns_lctx, category, module, - level, "overmem cache: " - "reprieve by RETAIN() %s", - printname); - } - } else if (isc_mem_isovermem(rbtdb->common.mctx) && log) - isc_log_write(dns_lctx, category, module, level, - "overmem cache: saved %s", printname); - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - return (ISC_R_SUCCESS); -} - -static void -overmem(dns_db_t *db, bool over) { - /* This is an empty callback. See adb.c:water() */ - - UNUSED(db); - UNUSED(over); - - return; -} - -static void -printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = node; - bool first; - - REQUIRE(VALID_RBTDB(rbtdb)); - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - fprintf(out, "node %p, %u references, locknum = %u\n", - rbtnode, dns_rbtnode_refcurrent(rbtnode), - rbtnode->locknum); - if (rbtnode->data != NULL) { - rdatasetheader_t *current, *top_next; - - for (current = rbtnode->data; current != NULL; - current = top_next) { - top_next = current->next; - first = true; - fprintf(out, "\ttype %u", current->type); - do { - if (!first) - fprintf(out, "\t"); - first = false; - fprintf(out, - "\tserial = %lu, ttl = %u, " - "trust = %u, attributes = %u, " - "resign = %u\n", - (unsigned long)current->serial, - current->rdh_ttl, - current->trust, - current->attributes, - (current->resign << 1) | - current->resign_lsb); - current = current->down; - } while (current != NULL); - } - } else - fprintf(out, "(empty)\n"); - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); -} - -static isc_result_t -createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rbtdb_dbiterator_t *rbtdbiter; - - REQUIRE(VALID_RBTDB(rbtdb)); - - rbtdbiter = isc_mem_get(rbtdb->common.mctx, sizeof(*rbtdbiter)); - if (rbtdbiter == NULL) - return (ISC_R_NOMEMORY); - - rbtdbiter->common.methods = &dbiterator_methods; - rbtdbiter->common.db = NULL; - dns_db_attach(db, &rbtdbiter->common.db); - rbtdbiter->common.relative_names = - ((options & DNS_DB_RELATIVENAMES) != 0); - rbtdbiter->common.magic = DNS_DBITERATOR_MAGIC; - rbtdbiter->common.cleaning = false; - rbtdbiter->paused = true; - rbtdbiter->tree_locked = isc_rwlocktype_none; - rbtdbiter->result = ISC_R_SUCCESS; - dns_fixedname_init(&rbtdbiter->name); - dns_fixedname_init(&rbtdbiter->origin); - rbtdbiter->node = NULL; - rbtdbiter->delcnt = 0; - rbtdbiter->nsec3only = ((options & DNS_DB_NSEC3ONLY) != 0); - rbtdbiter->nonsec3 = ((options & DNS_DB_NONSEC3) != 0); - memset(rbtdbiter->deletions, 0, sizeof(rbtdbiter->deletions)); - dns_rbtnodechain_init(&rbtdbiter->chain, db->mctx); - dns_rbtnodechain_init(&rbtdbiter->nsec3chain, db->mctx); - if (rbtdbiter->nsec3only) - rbtdbiter->current = &rbtdbiter->nsec3chain; - else - rbtdbiter->current = &rbtdbiter->chain; - - *iteratorp = (dns_dbiterator_t *)rbtdbiter; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rdatasetheader_t *header, *header_next, *found, *foundsig; - rbtdb_serial_t serial; - rbtdb_version_t *rbtversion = version; - bool close_version = false; - rbtdb_rdatatype_t matchtype, sigmatchtype; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(type != dns_rdatatype_any); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - if (rbtversion == NULL) { - currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion)); - close_version = true; - } - serial = rbtversion->serial; - now = 0; - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - found = NULL; - foundsig = NULL; - matchtype = RBTDB_RDATATYPE_VALUE(type, covers); - if (covers == 0) - sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); - else - sigmatchtype = 0; - - for (header = rbtnode->data; header != NULL; header = header_next) { - header_next = header->next; - do { - if (header->serial <= serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) { - /* - * We have an active, extant rdataset. If it's a - * type we're looking for, remember it. - */ - if (header->type == matchtype) { - found = header; - if (foundsig != NULL) - break; - } else if (header->type == sigmatchtype) { - foundsig = header; - if (found != NULL) - break; - } - } - } - if (found != NULL) { - bind_rdataset(rbtdb, rbtnode, found, now, isc_rwlocktype_read, - rdataset); - if (foundsig != NULL) { - bind_rdataset(rbtdb, rbtnode, foundsig, now, - isc_rwlocktype_read, sigrdataset); - } - } - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - if (close_version) - closeversion(db, (dns_dbversion_t **) (void *)(&rbtversion), - false); - - if (found == NULL) - return (ISC_R_NOTFOUND); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rdatasetheader_t *header, *header_next, *found, *foundsig; - rbtdb_rdatatype_t matchtype, sigmatchtype, negtype; - isc_result_t result; - nodelock_t *lock; - isc_rwlocktype_t locktype; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(type != dns_rdatatype_any); - - UNUSED(version); - - result = ISC_R_SUCCESS; - - if (now == 0) - isc_stdtime_get(&now); - - lock = &rbtdb->node_locks[rbtnode->locknum].lock; - locktype = isc_rwlocktype_read; - NODE_LOCK(lock, locktype); - - found = NULL; - foundsig = NULL; - matchtype = RBTDB_RDATATYPE_VALUE(type, covers); - negtype = RBTDB_RDATATYPE_VALUE(0, type); - if (covers == 0) - sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); - else - sigmatchtype = 0; - - for (header = rbtnode->data; header != NULL; header = header_next) { - header_next = header->next; - if (!ACTIVE(header, now)) { - if ((header->rdh_ttl < now - RBTDB_VIRTUAL) && - (locktype == isc_rwlocktype_write || - NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { - /* - * We update the node's status only when we - * can get write access. - */ - locktype = isc_rwlocktype_write; - - /* - * We don't check if refcurrent(rbtnode) == 0 - * and try to free like we do in cache_find(), - * because refcurrent(rbtnode) must be - * non-zero. This is so because 'node' is an - * argument to the function. - */ - mark_header_ancient(rbtdb, header); - } - } else if (EXISTS(header) && !ANCIENT(header)) { - if (header->type == matchtype) - found = header; - else if (header->type == RBTDB_RDATATYPE_NCACHEANY || - header->type == negtype) - found = header; - else if (header->type == sigmatchtype) - foundsig = header; - } - } - if (found != NULL) { - bind_rdataset(rbtdb, rbtnode, found, now, locktype, rdataset); - if (!NEGATIVE(found) && foundsig != NULL) { - bind_rdataset(rbtdb, rbtnode, foundsig, now, locktype, - sigrdataset); - } - } - - if (found == NULL) { - NODE_UNLOCK(lock, locktype); - return (ISC_R_NOTFOUND); - } - - if (NEGATIVE(found)) { - /* - * We found a negative cache entry. - */ - if (NXDOMAIN(found)) - result = DNS_R_NCACHENXDOMAIN; - else - result = DNS_R_NCACHENXRRSET; - } - - NODE_UNLOCK(lock, locktype); - - update_cachestats(rbtdb, result); - - return (result); -} - -static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rbtdb_version_t *rbtversion = version; - rbtdb_rdatasetiter_t *iterator; - unsigned int refs; - - REQUIRE(VALID_RBTDB(rbtdb)); - - iterator = isc_mem_get(rbtdb->common.mctx, sizeof(*iterator)); - if (iterator == NULL) - return (ISC_R_NOMEMORY); - - if ((db->attributes & DNS_DBATTR_CACHE) == 0) { - now = 0; - if (rbtversion == NULL) - currentversion(db, - (dns_dbversion_t **) (void *)(&rbtversion)); - else { - INSIST(rbtversion->rbtdb == rbtdb); - - isc_refcount_increment(&rbtversion->references, - &refs); - INSIST(refs > 1); - } - } else { - if (now == 0) - isc_stdtime_get(&now); - rbtversion = NULL; - } - - iterator->common.magic = DNS_RDATASETITER_MAGIC; - iterator->common.methods = &rdatasetiter_methods; - iterator->common.db = db; - iterator->common.node = node; - iterator->common.version = (dns_dbversion_t *)rbtversion; - iterator->common.now = now; - - NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); - - dns_rbtnode_refincrement(rbtnode, &refs); - INSIST(refs != 0); - - iterator->current = NULL; - - NODE_STRONGUNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); - - *iteratorp = (dns_rdatasetiter_t *)iterator; - - return (ISC_R_SUCCESS); -} - -static bool -cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { - rdatasetheader_t *header, *header_next; - bool cname, other_data; - dns_rdatatype_t rdtype; - - /* - * The caller must hold the node lock. - */ - - /* - * Look for CNAME and "other data" rdatasets active in our version. - */ - cname = false; - other_data = false; - for (header = node->data; header != NULL; header = header_next) { - header_next = header->next; - if (header->type == dns_rdatatype_cname) { - /* - * Look for an active extant CNAME. - */ - do { - if (header->serial <= serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) - cname = true; - } else { - /* - * Look for active extant "other data". - * - * "Other data" is any rdataset whose type is not - * KEY, NSEC, SIG or RRSIG. - */ - rdtype = RBTDB_RDATATYPE_BASE(header->type); - if (rdtype != dns_rdatatype_key && - rdtype != dns_rdatatype_sig && - rdtype != dns_rdatatype_nsec && - rdtype != dns_rdatatype_rrsig) { - /* - * Is it active and extant? - */ - do { - if (header->serial <= serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset - * doesn't exist" record? - */ - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) - other_data = true; - } - } - } - - if (cname && other_data) - return (true); - - return (false); -} - -static isc_result_t -resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) { - isc_result_t result; - - INSIST(!IS_CACHE(rbtdb)); - INSIST(newheader->heap_index == 0); - INSIST(!ISC_LINK_LINKED(newheader, link)); - - result = isc_heap_insert(rbtdb->heaps[idx], newheader); - return (result); -} - -/* - * node write lock must be held. - */ -static void -resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, - rdatasetheader_t *header) -{ - /* - * Remove the old header from the heap - */ - if (header != NULL && header->heap_index != 0) { - isc_heap_delete(rbtdb->heaps[header->node->locknum], - header->heap_index); - header->heap_index = 0; - if (version != NULL) { - new_reference(rbtdb, header->node, - isc_rwlocktype_write); - ISC_LIST_APPEND(version->resigned_list, header, link); - } - } -} - -static void -update_recordsandbytes(bool add, rbtdb_version_t *rbtversion, - rdatasetheader_t *header) -{ - unsigned char *hdr = (unsigned char *)header; - size_t hdrsize = sizeof (*header); - - RWLOCK(&rbtversion->rwlock, isc_rwlocktype_write); - if (add) { - rbtversion->records += dns_rdataslab_count(hdr, hdrsize); - rbtversion->bytes += dns_rdataslab_size(hdr, hdrsize); - } else { - rbtversion->records -= dns_rdataslab_count(hdr, hdrsize); - rbtversion->bytes -= dns_rdataslab_size(hdr, hdrsize); - } - RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write); -} - -/* - * write lock on rbtnode must be held. - */ -static isc_result_t -add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, - rdatasetheader_t *newheader, unsigned int options, bool loading, - dns_rdataset_t *addedrdataset, isc_stdtime_t now) -{ - rbtdb_changed_t *changed = NULL; - rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader; - unsigned char *merged; - isc_result_t result; - bool header_nx; - bool newheader_nx; - bool merge; - dns_rdatatype_t rdtype, covers; - rbtdb_rdatatype_t negtype, sigtype; - dns_trust_t trust; - int idx; - - /* - * Add an rdatasetheader_t to a node. - */ - - /* - * Caller must be holding the node lock. - */ - - if ((options & DNS_DBADD_MERGE) != 0) { - REQUIRE(rbtversion != NULL); - merge = true; - } else - merge = false; - - if ((options & DNS_DBADD_FORCE) != 0) - trust = dns_trust_ultimate; - else - trust = newheader->trust; - - if (rbtversion != NULL && !loading) { - /* - * We always add a changed record, even if no changes end up - * being made to this node, because it's harmless and - * simplifies the code. - */ - changed = add_changed(rbtdb, rbtversion, rbtnode); - if (changed == NULL) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - return (ISC_R_NOMEMORY); - } - } - - newheader_nx = NONEXISTENT(newheader) ? true : false; - topheader_prev = NULL; - sigheader = NULL; - negtype = 0; - if (rbtversion == NULL && !newheader_nx) { - rdtype = RBTDB_RDATATYPE_BASE(newheader->type); - covers = RBTDB_RDATATYPE_EXT(newheader->type); - sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers); - if (NEGATIVE(newheader)) { - /* - * We're adding a negative cache entry. - */ - if (covers == dns_rdatatype_any) { - /* - * If we're adding an negative cache entry - * which covers all types (NXDOMAIN, - * NODATA(QTYPE=ANY)), - * - * We make all other data stale so that the - * only rdataset that can be found at this - * node is the negative cache entry. - */ - for (topheader = rbtnode->data; - topheader != NULL; - topheader = topheader->next) - { - set_ttl(rbtdb, topheader, 0); - mark_header_ancient(rbtdb, topheader); - } - goto find_header; - } - /* - * Otherwise look for any RRSIGs of the given - * type so they can be marked stale later. - */ - for (topheader = rbtnode->data; - topheader != NULL; - topheader = topheader->next) - if (topheader->type == sigtype) - sigheader = topheader; - negtype = RBTDB_RDATATYPE_VALUE(covers, 0); - } else { - /* - * We're adding something that isn't a - * negative cache entry. Look for an extant - * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative - * cache entry. If we're adding an RRSIG, also - * check for an extant non-stale NODATA ncache - * entry which covers the same type as the RRSIG. - */ - for (topheader = rbtnode->data; - topheader != NULL; - topheader = topheader->next) { - if ((topheader->type == - RBTDB_RDATATYPE_NCACHEANY) || - (newheader->type == sigtype && - topheader->type == - RBTDB_RDATATYPE_VALUE(0, covers))) { - break; - } - } - if (topheader != NULL && EXISTS(topheader) && - ACTIVE(topheader, now)) { - /* - * Found one. - */ - if (trust < topheader->trust) { - /* - * The NXDOMAIN/NODATA(QTYPE=ANY) - * is more trusted. - */ - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - if (addedrdataset != NULL) { - bind_rdataset( - rbtdb, rbtnode, - topheader, now, - isc_rwlocktype_write, - addedrdataset); - } - return (DNS_R_UNCHANGED); - } - /* - * The new rdataset is better. Expire the - * ncache entry. - */ - set_ttl(rbtdb, topheader, 0); - mark_header_ancient(rbtdb, topheader); - topheader = NULL; - goto find_header; - } - negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); - } - } - - for (topheader = rbtnode->data; - topheader != NULL; - topheader = topheader->next) { - if (topheader->type == newheader->type || - topheader->type == negtype) - break; - topheader_prev = topheader; - } - - find_header: - /* - * If header isn't NULL, we've found the right type. There may be - * IGNORE rdatasets between the top of the chain and the first real - * data. We skip over them. - */ - header = topheader; - while (header != NULL && IGNORE(header)) - header = header->down; - if (header != NULL) { - header_nx = NONEXISTENT(header) ? true : false; - - /* - * Deleting an already non-existent rdataset has no effect. - */ - if (header_nx && newheader_nx) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - return (DNS_R_UNCHANGED); - } - - /* - * Trying to add an rdataset with lower trust to a cache - * DB has no effect, provided that the cache data isn't - * stale. If the cache data is stale, new lower trust - * data will supersede it below. Unclear what the best - * policy is here. - */ - if (rbtversion == NULL && trust < header->trust && - (ACTIVE(header, now) || header_nx)) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - if (addedrdataset != NULL) - bind_rdataset(rbtdb, rbtnode, header, now, - isc_rwlocktype_write, - addedrdataset); - return (DNS_R_UNCHANGED); - } - - /* - * Don't merge if a nonexistent rdataset is involved. - */ - if (merge && (header_nx || newheader_nx)) - merge = false; - - /* - * If 'merge' is true, we'll try to create a new rdataset - * that is the union of 'newheader' and 'header'. - */ - if (merge) { - unsigned int flags = 0; - INSIST(rbtversion->serial >= header->serial); - merged = NULL; - result = ISC_R_SUCCESS; - - if ((options & DNS_DBADD_EXACT) != 0) - flags |= DNS_RDATASLAB_EXACT; - /* - * TTL use here is irrelevant to the cache; - * merge is only done with zonedbs. - */ - if ((options & DNS_DBADD_EXACTTTL) != 0 && - newheader->rdh_ttl != header->rdh_ttl) - result = DNS_R_NOTEXACT; - else if (newheader->rdh_ttl != header->rdh_ttl) - flags |= DNS_RDATASLAB_FORCE; - if (result == ISC_R_SUCCESS) - result = dns_rdataslab_merge( - (unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)), - rbtdb->common.mctx, - rbtdb->common.rdclass, - (dns_rdatatype_t)header->type, - flags, &merged); - if (result == ISC_R_SUCCESS) { - /* - * If 'header' has the same serial number as - * we do, we could clean it up now if we knew - * that our caller had no references to it. - * We don't know this, however, so we leave it - * alone. It will get cleaned up when - * clean_zone_node() runs. - */ - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - newheader = (rdatasetheader_t *)merged; - init_rdataset(rbtdb, newheader); - update_newheader(newheader, header); - if (loading && RESIGN(newheader) && - RESIGN(header) && - resign_sooner(header, newheader)) - { - newheader->resign = header->resign; - newheader->resign_lsb = - header->resign_lsb; - } - } else { - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - return (result); - } - } - /* - * Don't replace existing NS, A and AAAA RRsets in the - * cache if they are already exist. This prevents named - * being locked to old servers. Don't lower trust of - * existing record if the update is forced. Nothing - * special to be done w.r.t stale data; it gets replaced - * normally further down. - */ - if (IS_CACHE(rbtdb) && ACTIVE(header, now) && - header->type == dns_rdatatype_ns && - !header_nx && !newheader_nx && - header->trust >= newheader->trust && - dns_rdataslab_equalx((unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)), - rbtdb->common.rdclass, - (dns_rdatatype_t)header->type)) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->rdh_ttl > newheader->rdh_ttl) - set_ttl(rbtdb, header, newheader->rdh_ttl); - if (header->noqname == NULL && - newheader->noqname != NULL) { - header->noqname = newheader->noqname; - newheader->noqname = NULL; - } - if (header->closest == NULL && - newheader->closest != NULL) { - header->closest = newheader->closest; - newheader->closest = NULL; - } - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - if (addedrdataset != NULL) - bind_rdataset(rbtdb, rbtnode, header, now, - isc_rwlocktype_write, - addedrdataset); - return (ISC_R_SUCCESS); - } - /* - * If we have will be replacing a NS RRset force its TTL - * to be no more than the current NS RRset's TTL. This - * ensures the delegations that are withdrawn are honoured. - */ - if (IS_CACHE(rbtdb) && ACTIVE(header, now) && - header->type == dns_rdatatype_ns && - !header_nx && !newheader_nx && - header->trust <= newheader->trust) { - if (newheader->rdh_ttl > header->rdh_ttl) { - newheader->rdh_ttl = header->rdh_ttl; - } - } - if (IS_CACHE(rbtdb) && ACTIVE(header, now) && - (options & DNS_DBADD_PREFETCH) == 0 && - (header->type == dns_rdatatype_a || - header->type == dns_rdatatype_aaaa || - header->type == dns_rdatatype_ds || - header->type == RBTDB_RDATATYPE_SIGDS) && - !header_nx && !newheader_nx && - header->trust >= newheader->trust && - dns_rdataslab_equal((unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)))) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->rdh_ttl > newheader->rdh_ttl) - set_ttl(rbtdb, header, newheader->rdh_ttl); - if (header->noqname == NULL && - newheader->noqname != NULL) { - header->noqname = newheader->noqname; - newheader->noqname = NULL; - } - if (header->closest == NULL && - newheader->closest != NULL) { - header->closest = newheader->closest; - newheader->closest = NULL; - } - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - if (addedrdataset != NULL) - bind_rdataset(rbtdb, rbtnode, header, now, - isc_rwlocktype_write, - addedrdataset); - return (ISC_R_SUCCESS); - } - INSIST(rbtversion == NULL || - rbtversion->serial >= topheader->serial); - if (loading) { - newheader->down = NULL; - idx = newheader->node->locknum; - if (IS_CACHE(rbtdb)) { - if (ZEROTTL(newheader)) - ISC_LIST_APPEND(rbtdb->rdatasets[idx], - newheader, link); - else - ISC_LIST_PREPEND(rbtdb->rdatasets[idx], - newheader, link); - INSIST(rbtdb->heaps != NULL); - result = isc_heap_insert(rbtdb->heaps[idx], - newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - return (result); - } - } else if (RESIGN(newheader)) { - result = resign_insert(rbtdb, idx, newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - return (result); - } - /* - * Don't call resign_delete as we don't need - * to reverse the delete. The free_rdataset - * call below will clean up the heap entry. - */ - } - - /* - * There are no other references to 'header' when - * loading, so we MAY clean up 'header' now. - * Since we don't generate changed records when - * loading, we MUST clean up 'header' now. - */ - if (topheader_prev != NULL) - topheader_prev->next = newheader; - else - rbtnode->data = newheader; - newheader->next = topheader->next; - if (rbtversion != NULL && !header_nx) { - update_recordsandbytes(false, rbtversion, - header); - } - free_rdataset(rbtdb, rbtdb->common.mctx, header); - } else { - idx = newheader->node->locknum; - if (IS_CACHE(rbtdb)) { - INSIST(rbtdb->heaps != NULL); - result = isc_heap_insert(rbtdb->heaps[idx], - newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - return (result); - } - if (ZEROTTL(newheader)) - ISC_LIST_APPEND(rbtdb->rdatasets[idx], - newheader, link); - else - ISC_LIST_PREPEND(rbtdb->rdatasets[idx], - newheader, link); - } else if (RESIGN(newheader)) { - result = resign_insert(rbtdb, idx, newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - return (result); - } - resign_delete(rbtdb, rbtversion, header); - } - if (topheader_prev != NULL) - topheader_prev->next = newheader; - else - rbtnode->data = newheader; - newheader->next = topheader->next; - newheader->down = topheader; - topheader->next = newheader; - rbtnode->dirty = 1; - if (changed != NULL) - changed->dirty = true; - if (rbtversion == NULL) { - set_ttl(rbtdb, header, 0); - mark_header_ancient(rbtdb, header); - if (sigheader != NULL) { - set_ttl(rbtdb, sigheader, 0); - mark_header_ancient(rbtdb, sigheader); - } - } - if (rbtversion != NULL && !header_nx) { - update_recordsandbytes(false, rbtversion, - header); - } - } - } else { - /* - * No non-IGNORED rdatasets of the given type exist at - * this node. - */ - - /* - * If we're trying to delete the type, don't bother. - */ - if (newheader_nx) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - return (DNS_R_UNCHANGED); - } - - idx = newheader->node->locknum; - if (IS_CACHE(rbtdb)) { - result = isc_heap_insert(rbtdb->heaps[idx], newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - return (result); - } - if (ZEROTTL(newheader)) - ISC_LIST_APPEND(rbtdb->rdatasets[idx], - newheader, link); - else - ISC_LIST_PREPEND(rbtdb->rdatasets[idx], - newheader, link); - } else if (RESIGN(newheader)) { - result = resign_insert(rbtdb, idx, newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - return (result); - } - resign_delete(rbtdb, rbtversion, header); - } - - if (topheader != NULL) { - /* - * We have an list of rdatasets of the given type, - * but they're all marked IGNORE. We simply insert - * the new rdataset at the head of the list. - * - * Ignored rdatasets cannot occur during loading, so - * we INSIST on it. - */ - INSIST(!loading); - INSIST(rbtversion == NULL || - rbtversion->serial >= topheader->serial); - if (topheader_prev != NULL) { - topheader_prev->next = newheader; - } else { - rbtnode->data = newheader; - } - newheader->next = topheader->next; - newheader->down = topheader; - topheader->next = newheader; - rbtnode->dirty = 1; - if (changed != NULL) { - changed->dirty = true; - } - } else { - /* - * No rdatasets of the given type exist at the node. - */ - newheader->next = rbtnode->data; - newheader->down = NULL; - rbtnode->data = newheader; - } - } - - if (rbtversion != NULL && !newheader_nx) { - update_recordsandbytes(true, rbtversion, newheader); - } - - /* - * Check if the node now contains CNAME and other data. - */ - if (rbtversion != NULL && - cname_and_other_data(rbtnode, rbtversion->serial)) - return (DNS_R_CNAMEANDOTHER); - - if (addedrdataset != NULL) { - bind_rdataset(rbtdb, rbtnode, newheader, now, - isc_rwlocktype_write, addedrdataset); - } - - return (ISC_R_SUCCESS); -} - -static inline bool -delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - rbtdb_rdatatype_t type) -{ - if (IS_CACHE(rbtdb)) { - if (type == dns_rdatatype_dname) - return (true); - else - return (false); - } else if (type == dns_rdatatype_dname || - (type == dns_rdatatype_ns && - (node != rbtdb->origin_node || IS_STUB(rbtdb)))) - return (true); - return (false); -} - -static inline isc_result_t -addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, - dns_rdataset_t *rdataset) -{ - struct noqname *noqname; - isc_mem_t *mctx = rbtdb->common.mctx; - dns_name_t name; - dns_rdataset_t neg, negsig; - isc_result_t result; - isc_region_t r; - - dns_name_init(&name, NULL); - dns_rdataset_init(&neg); - dns_rdataset_init(&negsig); - - result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - noqname = isc_mem_get(mctx, sizeof(*noqname)); - if (noqname == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - dns_name_init(&noqname->name, NULL); - noqname->neg = NULL; - noqname->negsig = NULL; - noqname->type = neg.type; - result = dns_name_dup(&name, mctx, &noqname->name); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - noqname->neg = r.base; - result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - noqname->negsig = r.base; - dns_rdataset_disassociate(&neg); - dns_rdataset_disassociate(&negsig); - newheader->noqname = noqname; - return (ISC_R_SUCCESS); - -cleanup: - dns_rdataset_disassociate(&neg); - dns_rdataset_disassociate(&negsig); - if (noqname != NULL) - free_noqname(mctx, &noqname); - return(result); -} - -static inline isc_result_t -addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, - dns_rdataset_t *rdataset) -{ - struct noqname *closest; - isc_mem_t *mctx = rbtdb->common.mctx; - dns_name_t name; - dns_rdataset_t neg, negsig; - isc_result_t result; - isc_region_t r; - - dns_name_init(&name, NULL); - dns_rdataset_init(&neg); - dns_rdataset_init(&negsig); - - result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - closest = isc_mem_get(mctx, sizeof(*closest)); - if (closest == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - dns_name_init(&closest->name, NULL); - closest->neg = NULL; - closest->negsig = NULL; - closest->type = neg.type; - result = dns_name_dup(&name, mctx, &closest->name); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - closest->neg = r.base; - result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - closest->negsig = r.base; - dns_rdataset_disassociate(&neg); - dns_rdataset_disassociate(&negsig); - newheader->closest = closest; - return (ISC_R_SUCCESS); - - cleanup: - dns_rdataset_disassociate(&neg); - dns_rdataset_disassociate(&negsig); - if (closest != NULL) - free_noqname(mctx, &closest); - return(result); -} - -static dns_dbmethods_t zone_methods; - -static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rbtdb_version_t *rbtversion = version; - isc_region_t region; - rdatasetheader_t *newheader; - rdatasetheader_t *header; - isc_result_t result; - bool delegating; - bool newnsec; - bool tree_locked = false; - bool cache_is_overmem = false; - dns_fixedname_t fixed; - dns_name_t *name; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - if (rbtdb->common.methods == &zone_methods) { - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && - (rdataset->type == dns_rdatatype_nsec3 || - rdataset->covers == dns_rdatatype_nsec3)) || - (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 && - rdataset->type != dns_rdatatype_nsec3 && - rdataset->covers != dns_rdatatype_nsec3))); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - } - - if (rbtversion == NULL) { - if (now == 0) - isc_stdtime_get(&now); - } else - now = 0; - - result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, - ®ion, sizeof(rdatasetheader_t)); - if (result != ISC_R_SUCCESS) - return (result); - - name = dns_fixedname_initname(&fixed); - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - dns_rbt_fullnamefromnode(node, name); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - dns_rdataset_getownercase(rdataset, name); - - newheader = (rdatasetheader_t *)region.base; - init_rdataset(rbtdb, newheader); - setownercase(newheader, name); - set_ttl(rbtdb, newheader, rdataset->ttl + now); - newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, - rdataset->covers); - newheader->attributes = 0; - if (rdataset->ttl == 0U) - newheader->attributes |= RDATASET_ATTR_ZEROTTL; - newheader->noqname = NULL; - newheader->closest = NULL; - newheader->count = DNS_RBTDB_INC(init_count); - newheader->trust = rdataset->trust; - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - newheader->last_used = now; - newheader->node = rbtnode; - if (rbtversion != NULL) { - newheader->serial = rbtversion->serial; - now = 0; - - if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { - newheader->attributes |= RDATASET_ATTR_RESIGN; - newheader->resign = (isc_stdtime_t) - (dns_time64_from32(rdataset->resign) >> 1); - newheader->resign_lsb = rdataset->resign & 0x1; - } else { - newheader->resign = 0; - newheader->resign_lsb = 0; - } - } else { - newheader->serial = 1; - newheader->resign = 0; - newheader->resign_lsb = 0; - if ((rdataset->attributes & DNS_RDATASETATTR_PREFETCH) != 0) - newheader->attributes |= RDATASET_ATTR_PREFETCH; - if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) - newheader->attributes |= RDATASET_ATTR_NEGATIVE; - if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) - newheader->attributes |= RDATASET_ATTR_NXDOMAIN; - if ((rdataset->attributes & DNS_RDATASETATTR_OPTOUT) != 0) - newheader->attributes |= RDATASET_ATTR_OPTOUT; - if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) { - result = addnoqname(rbtdb, newheader, rdataset); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - return (result); - } - } - if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) { - result = addclosest(rbtdb, newheader, rdataset); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, rbtdb->common.mctx, - newheader); - return (result); - } - } - } - - /* - * If we're adding a delegation type (e.g. NS or DNAME for a zone, - * just DNAME for the cache), then we need to set the callback bit - * on the node. - */ - if (delegating_type(rbtdb, rbtnode, rdataset->type)) - delegating = true; - else - delegating = false; - - /* - * Add to the auxiliary NSEC tree if we're adding an NSEC record. - */ - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - if (rbtnode->nsec != DNS_RBT_NSEC_HAS_NSEC && - rdataset->type == dns_rdatatype_nsec) - { - newnsec = true; - } else { - newnsec = false; - } - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - /* - * If we're adding a delegation type, adding to the auxiliary NSEC tree, - * or the DB is a cache in an overmem state, hold an exclusive lock on - * the tree. In the latter case the lock does not necessarily have to - * be acquired but it will help purge stale entries more effectively. - */ - if (IS_CACHE(rbtdb) && isc_mem_isovermem(rbtdb->common.mctx)) - cache_is_overmem = true; - if (delegating || newnsec || cache_is_overmem) { - tree_locked = true; - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - } - - if (cache_is_overmem) - overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked); - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - if (rbtdb->rrsetstats != NULL) { - newheader->attributes |= RDATASET_ATTR_STATCOUNT; - update_rrsetstats(rbtdb, newheader, true); - } - - if (IS_CACHE(rbtdb)) { - if (tree_locked) - cleanup_dead_nodes(rbtdb, rbtnode->locknum); - - header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1); - if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) - expire_header(rbtdb, header, tree_locked, - expire_ttl); - - /* - * If we've been holding a write lock on the tree just for - * cleaning, we can release it now. However, we still need the - * node lock. - */ - if (tree_locked && !delegating && !newnsec) { - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - tree_locked = false; - } - } - - result = ISC_R_SUCCESS; - if (newnsec) { - dns_rbtnode_t *nsecnode; - - dns_rbt_fullnamefromnode(rbtnode, name); - nsecnode = NULL; - result = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode); - if (result == ISC_R_SUCCESS) { - nsecnode->nsec = DNS_RBT_NSEC_NSEC; - rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC; - } else if (result == ISC_R_EXISTS) { - rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC; - result = ISC_R_SUCCESS; - } - } - - if (result == ISC_R_SUCCESS) - result = add32(rbtdb, rbtnode, rbtversion, newheader, options, - false, addedrdataset, now); - if (result == ISC_R_SUCCESS && delegating) - rbtnode->find_callback = 1; - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - if (tree_locked) - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - - /* - * Update the zone's secure status. If version is non-NULL - * this is deferred until closeversion() is called. - */ - if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) - iszonesecure(db, version, rbtdb->origin_node); - - return (result); -} - -static isc_result_t -subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *newrdataset) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rbtdb_version_t *rbtversion = version; - rdatasetheader_t *topheader, *topheader_prev, *header, *newheader; - unsigned char *subresult; - isc_region_t region; - isc_result_t result; - rbtdb_changed_t *changed; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb); - - if (rbtdb->common.methods == &zone_methods) { - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && - (rdataset->type == dns_rdatatype_nsec3 || - rdataset->covers == dns_rdatatype_nsec3)) || - (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 && - rdataset->type != dns_rdatatype_nsec3 && - rdataset->covers != dns_rdatatype_nsec3))); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - } - - result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, - ®ion, sizeof(rdatasetheader_t)); - if (result != ISC_R_SUCCESS) - return (result); - newheader = (rdatasetheader_t *)region.base; - init_rdataset(rbtdb, newheader); - set_ttl(rbtdb, newheader, rdataset->ttl); - newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, - rdataset->covers); - newheader->attributes = 0; - newheader->serial = rbtversion->serial; - newheader->trust = 0; - newheader->noqname = NULL; - newheader->closest = NULL; - newheader->count = DNS_RBTDB_INC(init_count); - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - newheader->last_used = 0; - newheader->node = rbtnode; - if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { - newheader->attributes |= RDATASET_ATTR_RESIGN; - newheader->resign = (isc_stdtime_t) - (dns_time64_from32(rdataset->resign) >> 1); - newheader->resign_lsb = rdataset->resign & 0x1; - } else { - newheader->resign = 0; - newheader->resign_lsb = 0; - } - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - changed = add_changed(rbtdb, rbtversion, rbtnode); - if (changed == NULL) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - return (ISC_R_NOMEMORY); - } - - topheader_prev = NULL; - for (topheader = rbtnode->data; - topheader != NULL; - topheader = topheader->next) { - if (topheader->type == newheader->type) - break; - topheader_prev = topheader; - } - /* - * If header isn't NULL, we've found the right type. There may be - * IGNORE rdatasets between the top of the chain and the first real - * data. We skip over them. - */ - header = topheader; - while (header != NULL && IGNORE(header)) - header = header->down; - if (header != NULL && EXISTS(header)) { - unsigned int flags = 0; - subresult = NULL; - result = ISC_R_SUCCESS; - if ((options & DNS_DBSUB_EXACT) != 0) { - flags |= DNS_RDATASLAB_EXACT; - if (newheader->rdh_ttl != header->rdh_ttl) - result = DNS_R_NOTEXACT; - } - if (result == ISC_R_SUCCESS) - result = dns_rdataslab_subtract( - (unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)), - rbtdb->common.mctx, - rbtdb->common.rdclass, - (dns_rdatatype_t)header->type, - flags, &subresult); - if (result == ISC_R_SUCCESS) { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - newheader = (rdatasetheader_t *)subresult; - init_rdataset(rbtdb, newheader); - update_newheader(newheader, header); - if (RESIGN(header)) { - newheader->attributes |= RDATASET_ATTR_RESIGN; - newheader->resign = header->resign; - newheader->resign_lsb = header->resign_lsb; - result = resign_insert(rbtdb, rbtnode->locknum, - newheader); - if (result != ISC_R_SUCCESS) { - free_rdataset(rbtdb, - rbtdb->common.mctx, - newheader); - goto unlock; - } - } - /* - * We have to set the serial since the rdataslab - * subtraction routine copies the reserved portion of - * header, not newheader. - */ - newheader->serial = rbtversion->serial; - /* - * XXXJT: dns_rdataslab_subtract() copied the pointers - * to additional info. We need to clear these fields - * to avoid having duplicated references. - */ - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - update_recordsandbytes(true, rbtversion, newheader); - } else if (result == DNS_R_NXRRSET) { - /* - * This subtraction would remove all of the rdata; - * add a nonexistent header instead. - */ - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - newheader = new_rdataset(rbtdb, rbtdb->common.mctx); - if (newheader == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - init_rdataset(rbtdb, newheader); - set_ttl(rbtdb, newheader, 0); - newheader->type = topheader->type; - newheader->attributes = RDATASET_ATTR_NONEXISTENT; - newheader->trust = 0; - newheader->serial = rbtversion->serial; - newheader->noqname = NULL; - newheader->closest = NULL; - newheader->count = 0; - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - newheader->node = rbtnode; - newheader->resign = 0; - newheader->resign_lsb = 0; - newheader->last_used = 0; - } else { - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - goto unlock; - } - - /* - * If we're here, we want to link newheader in front of - * topheader. - */ - INSIST(rbtversion->serial >= topheader->serial); - update_recordsandbytes(false, rbtversion, header); - if (topheader_prev != NULL) - topheader_prev->next = newheader; - else - rbtnode->data = newheader; - newheader->next = topheader->next; - newheader->down = topheader; - topheader->next = newheader; - rbtnode->dirty = 1; - changed->dirty = true; - resign_delete(rbtdb, rbtversion, header); - } else { - /* - * The rdataset doesn't exist, so we don't need to do anything - * to satisfy the deletion request. - */ - free_rdataset(rbtdb, rbtdb->common.mctx, newheader); - if ((options & DNS_DBSUB_EXACT) != 0) - result = DNS_R_NOTEXACT; - else - result = DNS_R_UNCHANGED; - } - - if (result == ISC_R_SUCCESS && newrdataset != NULL) { - bind_rdataset(rbtdb, rbtnode, newheader, 0, - isc_rwlocktype_write, newrdataset); - } - - if (result == DNS_R_NXRRSET && newrdataset != NULL && - (options & DNS_DBSUB_WANTOLD) != 0) - { - bind_rdataset(rbtdb, rbtnode, header, 0, isc_rwlocktype_write, - newrdataset); - } - - unlock: - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - /* - * Update the zone's secure status. If version is non-NULL - * this is deferred until closeversion() is called. - */ - if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) { - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - version = rbtdb->current_version; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - iszonesecure(db, version, rbtdb->origin_node); - } - - return (result); -} - -static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - rbtdb_version_t *rbtversion = version; - isc_result_t result; - rdatasetheader_t *newheader; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - if (type == dns_rdatatype_any) - return (ISC_R_NOTIMPLEMENTED); - if (type == dns_rdatatype_rrsig && covers == 0) - return (ISC_R_NOTIMPLEMENTED); - - newheader = new_rdataset(rbtdb, rbtdb->common.mctx); - if (newheader == NULL) - return (ISC_R_NOMEMORY); - init_rdataset(rbtdb, newheader); - set_ttl(rbtdb, newheader, 0); - newheader->type = RBTDB_RDATATYPE_VALUE(type, covers); - newheader->attributes = RDATASET_ATTR_NONEXISTENT; - newheader->trust = 0; - newheader->noqname = NULL; - newheader->closest = NULL; - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - if (rbtversion != NULL) - newheader->serial = rbtversion->serial; - else - newheader->serial = 0; - newheader->count = 0; - newheader->last_used = 0; - newheader->node = rbtnode; - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - result = add32(rbtdb, rbtnode, rbtversion, newheader, DNS_DBADD_FORCE, - false, NULL, 0); - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - - /* - * Update the zone's secure status. If version is non-NULL - * this is deferred until closeversion() is called. - */ - if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) { - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - version = rbtdb->current_version; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - iszonesecure(db, version, rbtdb->origin_node); - } - - return (result); -} - -/* - * load a non-NSEC3 node in the main tree and optionally to the auxiliary NSEC - */ -static isc_result_t -loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, - bool hasnsec) -{ - isc_result_t noderesult, rpzresult, nsecresult, tmpresult; - dns_rbtnode_t *nsecnode = NULL, *node = NULL; - - noderesult = dns_rbt_addnode(rbtdb->tree, name, &node); - if (rbtdb->rpzs != NULL && - (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS)) { - rpzresult = dns_rpz_add(rbtdb->load_rpzs, rbtdb->rpz_num, - name); - if (rpzresult == ISC_R_SUCCESS) { - node->rpz = 1; - } else if (noderesult != ISC_R_EXISTS) { - /* - * Remove the node we just added above. - */ - tmpresult = dns_rbt_deletenode(rbtdb->tree, node, - false); - if (tmpresult != ISC_R_SUCCESS) - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_WARNING, - "loading_addrdataset: " - "dns_rbt_deletenode: %s after " - "dns_rbt_addnode(NSEC): %s", - isc_result_totext(tmpresult), - isc_result_totext(ISC_R_SUCCESS)); - noderesult = rpzresult; - } - } - if (!hasnsec) - goto done; - if (noderesult == ISC_R_EXISTS) { - /* - * Add a node to the auxiliary NSEC tree for an old node - * just now getting an NSEC record. - */ - if (node->nsec == DNS_RBT_NSEC_HAS_NSEC) - goto done; - } else if (noderesult != ISC_R_SUCCESS) - goto done; - - /* - * Build the auxiliary tree for NSECs as we go. - * This tree speeds searches for closest NSECs that would otherwise - * need to examine many irrelevant nodes in large TLDs. - * - * Add nodes to the auxiliary tree after corresponding nodes have - * been added to the main tree. - */ - nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode); - if (nsecresult == ISC_R_SUCCESS) { - nsecnode->nsec = DNS_RBT_NSEC_NSEC; - node->nsec = DNS_RBT_NSEC_HAS_NSEC; - goto done; - } - - if (nsecresult == ISC_R_EXISTS) { -#if 1 /* 0 */ - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_WARNING, - "addnode: NSEC node already exists"); -#endif - node->nsec = DNS_RBT_NSEC_HAS_NSEC; - goto done; - } - - if (noderesult == ISC_R_SUCCESS) { - unsigned int node_has_rpz; - - /* - * Remove the node we just added above. - * dns_rbt_deletenode() may keep the node if it has a - * down pointer, but we mustn't call dns_rpz_delete() on - * it again. - */ - node_has_rpz = node->rpz; - node->rpz = 0; - tmpresult = dns_rbt_deletenode(rbtdb->tree, node, false); - if (tmpresult == ISC_R_SUCCESS) { - /* - * Clean rpz entries added above. - */ - if (rbtdb->rpzs != NULL && node_has_rpz) - dns_rpz_delete(rbtdb->load_rpzs, - rbtdb->rpz_num, name); - } else { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, - ISC_LOG_WARNING, - "loading_addrdataset: " - "dns_rbt_deletenode: %s after " - "dns_rbt_addnode(NSEC): %s", - isc_result_totext(tmpresult), - isc_result_totext(noderesult)); - } - } - - /* - * Set the error condition to be returned. - */ - noderesult = nsecresult; - - done: - if (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS) - *nodep = node; - - return (noderesult); -} - -static isc_result_t -loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) { - rbtdb_load_t *loadctx = arg; - dns_rbtdb_t *rbtdb = loadctx->rbtdb; - dns_rbtnode_t *node; - isc_result_t result; - isc_region_t region; - rdatasetheader_t *newheader; - - REQUIRE(rdataset->rdclass == rbtdb->common.rdclass); - - /* - * This routine does no node locking. See comments in - * 'load' below for more information on loading and - * locking. - */ - - /* - * SOA records are only allowed at top of zone. - */ - if (rdataset->type == dns_rdatatype_soa && - !IS_CACHE(rbtdb) && !dns_name_equal(name, &rbtdb->common.origin)) - return (DNS_R_NOTZONETOP); - - if (rdataset->type != dns_rdatatype_nsec3 && - rdataset->covers != dns_rdatatype_nsec3) - add_empty_wildcards(rbtdb, name); - - if (dns_name_iswildcard(name)) { - /* - * NS record owners cannot legally be wild cards. - */ - if (rdataset->type == dns_rdatatype_ns) - return (DNS_R_INVALIDNS); - /* - * NSEC3 record owners cannot legally be wild cards. - */ - if (rdataset->type == dns_rdatatype_nsec3) - return (DNS_R_INVALIDNSEC3); - result = add_wildcard_magic(rbtdb, name); - if (result != ISC_R_SUCCESS) - return (result); - } - - node = NULL; - if (rdataset->type == dns_rdatatype_nsec3 || - rdataset->covers == dns_rdatatype_nsec3) { - result = dns_rbt_addnode(rbtdb->nsec3, name, &node); - if (result == ISC_R_SUCCESS) - node->nsec = DNS_RBT_NSEC_NSEC3; - } else if (rdataset->type == dns_rdatatype_nsec) { - result = loadnode(rbtdb, name, &node, true); - } else { - result = loadnode(rbtdb, name, &node, false); - } - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) - return (result); - if (result == ISC_R_SUCCESS) { - dns_name_t foundname; - dns_name_init(&foundname, NULL); - dns_rbt_namefromnode(node, &foundname); -#ifdef DNS_RBT_USEHASH - node->locknum = node->hashval % rbtdb->node_lock_count; -#else - node->locknum = dns_name_hash(&foundname, true) % - rbtdb->node_lock_count; -#endif - } - - result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, - ®ion, - sizeof(rdatasetheader_t)); - if (result != ISC_R_SUCCESS) - return (result); - newheader = (rdatasetheader_t *)region.base; - init_rdataset(rbtdb, newheader); - set_ttl(rbtdb, newheader, - rdataset->ttl + loadctx->now); /* XXX overflow check */ - newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, - rdataset->covers); - newheader->attributes = 0; - newheader->trust = rdataset->trust; - newheader->serial = 1; - newheader->noqname = NULL; - newheader->closest = NULL; - newheader->count = DNS_RBTDB_INC(init_count); - newheader->additional_auth = NULL; - newheader->additional_glue = NULL; - newheader->last_used = 0; - newheader->node = node; - setownercase(newheader, name); - - if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { - newheader->attributes |= RDATASET_ATTR_RESIGN; - newheader->resign = (isc_stdtime_t) - (dns_time64_from32(rdataset->resign) >> 1); - newheader->resign_lsb = rdataset->resign & 0x1; - } else { - newheader->resign = 0; - newheader->resign_lsb = 0; - } - - NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, - isc_rwlocktype_write); - - result = add32(rbtdb, node, rbtdb->current_version, newheader, - DNS_DBADD_MERGE, true, NULL, 0); - - NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, - isc_rwlocktype_write); - - if (result == ISC_R_SUCCESS && - delegating_type(rbtdb, node, rdataset->type)) - node->find_callback = 1; - else if (result == DNS_R_UNCHANGED) - result = ISC_R_SUCCESS; - - return (result); -} - -static isc_result_t -rbt_datafixer(dns_rbtnode_t *rbtnode, void *base, size_t filesize, - void *arg, uint64_t *crc) -{ - isc_result_t result; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *) arg; - rdatasetheader_t *header; - unsigned char *limit = ((unsigned char *) base) + filesize; - - REQUIRE(rbtnode != NULL); - REQUIRE(VALID_RBTDB(rbtdb)); - - for (header = rbtnode->data; header != NULL; header = header->next) { - unsigned char *p = (unsigned char *) header; - size_t size = dns_rdataslab_size(p, sizeof(*header)); - isc_crc64_update(crc, p, size); -#ifdef DEBUG - hexdump("hashing header", p, sizeof(rdatasetheader_t)); - hexdump("hashing slab", p + sizeof(rdatasetheader_t), - size - sizeof(rdatasetheader_t)); -#endif - header->serial = 1; - header->is_mmapped = 1; - header->node = rbtnode; - header->node_is_relative = 0; - - if (RESIGN(header) && - (header->resign != 0 || header->resign_lsb != 0)) - { - int idx = header->node->locknum; - result = isc_heap_insert(rbtdb->heaps[idx], header); - if (result != ISC_R_SUCCESS) - return (result); - } - - if (header->next != NULL) { - size_t cooked = dns_rbt_serialize_align(size); - if ((uintptr_t)header->next != - (p - (unsigned char *)base) + cooked) - return (ISC_R_INVALIDFILE); - header->next = (rdatasetheader_t *)(p + cooked); - header->next_is_relative = 0; - if ((header->next < (rdatasetheader_t *) base) || - (header->next > (rdatasetheader_t *) limit)) - return (ISC_R_INVALIDFILE); - } - update_recordsandbytes(true, rbtdb->current_version, header); - } - - return (ISC_R_SUCCESS); -} - -/* - * Load the RBT database from the image in 'f' - */ -static isc_result_t -deserialize32(void *arg, FILE *f, off_t offset) { - isc_result_t result; - rbtdb_load_t *loadctx = arg; - dns_rbtdb_t *rbtdb = loadctx->rbtdb; - rbtdb_file_header_t *header; - int fd; - off_t filesize = 0; - char *base; - dns_rbt_t *tree = NULL, *nsec = NULL, *nsec3 = NULL; - int protect, flags; - dns_rbtnode_t *origin_node = NULL; - - REQUIRE(VALID_RBTDB(rbtdb)); - - /* - * TODO CKB: since this is read-write (had to be to add nodes later) - * we will need to lock the file or the nodes in it before modifying - * the nodes in the file. - */ - - /* Map in the whole file in one go */ - fd = fileno(f); - isc_file_getsizefd(fd, &filesize); - protect = PROT_READ|PROT_WRITE; - flags = MAP_PRIVATE; -#ifdef MAP_FILE - flags |= MAP_FILE; -#endif - - base = isc_file_mmap(NULL, filesize, protect, flags, fd, 0); - if (base == NULL || base == MAP_FAILED) { - return (ISC_R_FAILURE); - } - - header = (rbtdb_file_header_t *)(base + offset); - if (!match_header_version(header)) { - result = ISC_R_INVALIDFILE; - goto cleanup; - } - - if (header->tree != 0) { - result = dns_rbt_deserialize_tree(base, filesize, - (off_t) header->tree, - rbtdb->common.mctx, - delete_callback, rbtdb, - rbt_datafixer, rbtdb, - NULL, &tree); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rbt_findnode(tree, &rbtdb->common.origin, NULL, - &origin_node, NULL, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (header->nsec != 0) { - result = dns_rbt_deserialize_tree(base, filesize, - (off_t) header->nsec, - rbtdb->common.mctx, - delete_callback, rbtdb, - rbt_datafixer, rbtdb, - NULL, &nsec); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (header->nsec3 != 0) { - result = dns_rbt_deserialize_tree(base, filesize, - (off_t) header->nsec3, - rbtdb->common.mctx, - delete_callback, rbtdb, - rbt_datafixer, rbtdb, - NULL, &nsec3); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - /* - * We have a successfully loaded all the rbt trees now update - * rbtdb to use them. - */ - - rbtdb->mmap_location = base; - rbtdb->mmap_size = (size_t) filesize; - - if (tree != NULL) { - dns_rbt_destroy(&rbtdb->tree); - rbtdb->tree = tree; - rbtdb->origin_node = origin_node; - } - - if (nsec != NULL) { - dns_rbt_destroy(&rbtdb->nsec); - rbtdb->nsec = nsec; - } - - if (nsec3 != NULL) { - dns_rbt_destroy(&rbtdb->nsec3); - rbtdb->nsec3 = nsec3; - } - - return (ISC_R_SUCCESS); - - cleanup: - if (tree != NULL) - dns_rbt_destroy(&tree); - if (nsec != NULL) - dns_rbt_destroy(&nsec); - if (nsec3 != NULL) - dns_rbt_destroy(&nsec3); - isc_file_munmap(base, (size_t) filesize); - return (result); -} - -static isc_result_t -beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - rbtdb_load_t *loadctx; - dns_rbtdb_t *rbtdb; - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(DNS_CALLBACK_VALID(callbacks)); - REQUIRE(VALID_RBTDB(rbtdb)); - - loadctx = isc_mem_get(rbtdb->common.mctx, sizeof(*loadctx)); - if (loadctx == NULL) - return (ISC_R_NOMEMORY); - - loadctx->rbtdb = rbtdb; - if (IS_CACHE(rbtdb)) - isc_stdtime_get(&loadctx->now); - else - loadctx->now = 0; - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - - if (rbtdb->rpzs != NULL) { - isc_result_t result; - - result = dns_rpz_beginload(&rbtdb->load_rpzs, - rbtdb->rpzs, rbtdb->rpz_num); - if (result != ISC_R_SUCCESS) { - isc_mem_put(rbtdb->common.mctx, loadctx, - sizeof(*loadctx)); - return (result); - } - } - - REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING)) - == 0); - rbtdb->attributes |= RBTDB_ATTR_LOADING; - - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - - callbacks->add = loading_addrdataset; - callbacks->add_private = loadctx; - callbacks->deserialize = deserialize32; - callbacks->deserialize_private = loadctx; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - rbtdb_load_t *loadctx; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(DNS_CALLBACK_VALID(callbacks)); - loadctx = callbacks->add_private; - REQUIRE(loadctx != NULL); - REQUIRE(loadctx->rbtdb == rbtdb); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - - REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0); - REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0); - - rbtdb->attributes &= ~RBTDB_ATTR_LOADING; - rbtdb->attributes |= RBTDB_ATTR_LOADED; - - /* - * If there's a KEY rdataset at the zone origin containing a - * zone key, we consider the zone secure. - */ - if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL) { - dns_dbversion_t *version = rbtdb->current_version; - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - iszonesecure(db, version, rbtdb->origin_node); - } else { - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); - } - - callbacks->add = NULL; - callbacks->add_private = NULL; - callbacks->deserialize = NULL; - callbacks->deserialize_private = NULL; - - isc_mem_put(rbtdb->common.mctx, loadctx, sizeof(*loadctx)); - - return (ISC_R_SUCCESS); -} - -/* - * helper function to handle writing out the rdataset data pointed to - * by the void *data pointer in the dns_rbtnode - */ -static isc_result_t -rbt_datawriter(FILE *rbtfile, unsigned char *data, void *arg, - uint64_t *crc) -{ - rbtdb_version_t *version = (rbtdb_version_t *) arg; - rbtdb_serial_t serial; - rdatasetheader_t newheader; - rdatasetheader_t *header = (rdatasetheader_t *) data, *next; - off_t where; - size_t cooked, size; - unsigned char *p; - isc_result_t result = ISC_R_SUCCESS; - char pad[sizeof(char *)]; - uintptr_t off; - - REQUIRE(rbtfile != NULL); - REQUIRE(data != NULL); - REQUIRE(version != NULL); - - serial = version->serial; - - for (; header != NULL; header = next) { - next = header->next; - do { - if (header->serial <= serial && !IGNORE(header)) { - if (NONEXISTENT(header)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - - if (header == NULL) - continue; - - CHECK(isc_stdio_tell(rbtfile, &where)); - size = dns_rdataslab_size((unsigned char *) header, - sizeof(rdatasetheader_t)); - - p = (unsigned char *) header; - memmove(&newheader, p, sizeof(rdatasetheader_t)); - newheader.down = NULL; - newheader.next = NULL; - off = where; - if ((off_t)off != where) - return (ISC_R_RANGE); - newheader.node = (dns_rbtnode_t *) off; - newheader.node_is_relative = 1; - newheader.serial = 1; - - /* - * Round size up to the next pointer sized offset so it - * will be properly aligned when read back in. - */ - cooked = dns_rbt_serialize_align(size); - if (next != NULL) { - newheader.next = (rdatasetheader_t *) (off + cooked); - newheader.next_is_relative = 1; - } - -#ifdef DEBUG - hexdump("writing header", (unsigned char *) &newheader, - sizeof(rdatasetheader_t)); - hexdump("writing slab", p + sizeof(rdatasetheader_t), - size - sizeof(rdatasetheader_t)); -#endif - isc_crc64_update(crc, (unsigned char *) &newheader, - sizeof(rdatasetheader_t)); - CHECK(isc_stdio_write(&newheader, sizeof(rdatasetheader_t), 1, - rbtfile, NULL)); - - isc_crc64_update(crc, p + sizeof(rdatasetheader_t), - size - sizeof(rdatasetheader_t)); - CHECK(isc_stdio_write(p + sizeof(rdatasetheader_t), - size - sizeof(rdatasetheader_t), 1, - rbtfile, NULL)); - /* - * Pad to force alignment. - */ - if (size != (size_t) cooked) { - memset(pad, 0, sizeof(pad)); - CHECK(isc_stdio_write(pad, cooked - size, 1, - rbtfile, NULL)); - } - } - - failure: - return (result); -} - -/* - * Write out a zeroed header as a placeholder. Doing this ensures - * that the file will not read while it is partially written, should - * writing fail or be interrupted. - */ -static isc_result_t -rbtdb_zero_header(FILE *rbtfile) { - char buffer[RBTDB_HEADER_LENGTH]; - isc_result_t result; - - memset(buffer, 0, RBTDB_HEADER_LENGTH); - result = isc_stdio_write(buffer, 1, RBTDB_HEADER_LENGTH, rbtfile, NULL); - fflush(rbtfile); - - return (result); -} - -static isc_once_t once = ISC_ONCE_INIT; - -static void -init_file_version(void) { - int n; - - memset(FILE_VERSION, 0, sizeof(FILE_VERSION)); - n = snprintf(FILE_VERSION, sizeof(FILE_VERSION), - "RBTDB Image %s %s", dns_major, dns_mapapi); - INSIST(n > 0 && (unsigned int)n < sizeof(FILE_VERSION)); -} - -/* - * Write the file header out, recording the locations of the three - * RBT's used in the rbtdb: tree, nsec, and nsec3, and including NodeDump - * version information and any information stored in the rbtdb object - * itself that should be stored here. - */ -static isc_result_t -rbtdb_write_header(FILE *rbtfile, off_t tree_location, off_t nsec_location, - off_t nsec3_location) -{ - rbtdb_file_header_t header; - isc_result_t result; - - RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS); - - memset(&header, 0, sizeof(rbtdb_file_header_t)); - memmove(header.version1, FILE_VERSION, sizeof(header.version1)); - memmove(header.version2, FILE_VERSION, sizeof(header.version2)); - header.ptrsize = (uint32_t) sizeof(void *); - header.bigendian = (1 == htonl(1)) ? 1 : 0; - header.tree = (uint64_t) tree_location; - header.nsec = (uint64_t) nsec_location; - header.nsec3 = (uint64_t) nsec3_location; - result = isc_stdio_write(&header, 1, sizeof(rbtdb_file_header_t), - rbtfile, NULL); - fflush(rbtfile); - - return (result); -} - -static bool -match_header_version(rbtdb_file_header_t *header) { - RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS); - - if (memcmp(header->version1, FILE_VERSION, - sizeof(header->version1)) != 0 || - memcmp(header->version2, FILE_VERSION, - sizeof(header->version1)) != 0) - { - return (false); - } - - return (true); -} - -static isc_result_t -serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) { - rbtdb_version_t *version = (rbtdb_version_t *) ver; - dns_rbtdb_t *rbtdb; - isc_result_t result; - off_t tree_location, nsec_location, nsec3_location, header_location; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(rbtfile != NULL); - - /* Ensure we're writing to a plain file */ - CHECK(isc_file_isplainfilefd(fileno(rbtfile))); - - /* - * first, write out a zeroed header to store rbtdb information - * - * then for each of the three trees, store the current position - * in the file and call dns_rbt_serialize_tree - * - * finally, write out the rbtdb header, storing the locations of the - * rbtheaders - * - * NOTE: need to do something better with the return codes, &= will - * not work. - */ - CHECK(isc_stdio_tell(rbtfile, &header_location)); - CHECK(rbtdb_zero_header(rbtfile)); - CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->tree, rbt_datawriter, - version, &tree_location)); - CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec, rbt_datawriter, - version, &nsec_location)); - CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec3, rbt_datawriter, - version, &nsec3_location)); - - CHECK(isc_stdio_seek(rbtfile, header_location, SEEK_SET)); - CHECK(rbtdb_write_header(rbtfile, tree_location, nsec_location, - nsec3_location)); - failure: - return (result); -} - -static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat) -{ - dns_rbtdb_t *rbtdb; - rbtdb_version_t *rbtversion = version; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - return (dns_master_dump2(rbtdb->common.mctx, db, version, - &dns_master_style_default, - filename, masterformat)); -} - -static void -delete_callback(void *data, void *arg) { - dns_rbtdb_t *rbtdb = arg; - rdatasetheader_t *current, *next; - unsigned int locknum; - - current = data; - locknum = current->node->locknum; - NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); - while (current != NULL) { - next = current->next; - free_rdataset(rbtdb, rbtdb->common.mctx, current); - current = next; - } - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); -} - -static bool -issecure(dns_db_t *db) { - dns_rbtdb_t *rbtdb; - bool secure; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - secure = (rbtdb->current_version->secure == dns_db_secure); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - - return (secure); -} - -static bool -isdnssec(dns_db_t *db) { - dns_rbtdb_t *rbtdb; - bool dnssec; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - dnssec = (rbtdb->current_version->secure != dns_db_insecure); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - - return (dnssec); -} - -static unsigned int -nodecount(dns_db_t *db) { - dns_rbtdb_t *rbtdb; - unsigned int count; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - count = dns_rbt_nodecount(rbtdb->tree); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - return (count); -} - -static size_t -hashsize(dns_db_t *db) { - dns_rbtdb_t *rbtdb; - size_t size; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - size = dns_rbt_hashsize(rbtdb->tree); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - return (size); -} - -static void -settask(dns_db_t *db, isc_task_t *task) { - dns_rbtdb_t *rbtdb; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); - if (rbtdb->task != NULL) - isc_task_detach(&rbtdb->task); - if (task != NULL) - isc_task_attach(task, &rbtdb->task); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); -} - -static bool -ispersistent(dns_db_t *db) { - UNUSED(db); - return (false); -} - -static isc_result_t -getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *onode; - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(nodep != NULL && *nodep == NULL); - - /* Note that the access to origin_node doesn't require a DB lock */ - onode = (dns_rbtnode_t *)rbtdb->origin_node; - if (onode != NULL) { - NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock); - new_reference(rbtdb, onode, isc_rwlocktype_none); - NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock); - - *nodep = rbtdb->origin_node; - } else { - INSIST(IS_CACHE(rbtdb)); - result = ISC_R_NOTFOUND; - } - - return (result); -} - -static isc_result_t -getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, - uint8_t *flags, uint16_t *iterations, - unsigned char *salt, size_t *salt_length) -{ - dns_rbtdb_t *rbtdb; - isc_result_t result = ISC_R_NOTFOUND; - rbtdb_version_t *rbtversion = version; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - if (rbtversion == NULL) { - rbtversion = rbtdb->current_version; - } - - if (rbtversion->havensec3) { - if (hash != NULL) - *hash = rbtversion->hash; - if (salt != NULL && salt_length != NULL) { - REQUIRE(*salt_length >= rbtversion->salt_length); - memmove(salt, rbtversion->salt, - rbtversion->salt_length); - } - if (salt_length != NULL) - *salt_length = rbtversion->salt_length; - if (iterations != NULL) - *iterations = rbtversion->iterations; - if (flags != NULL) - *flags = rbtversion->flags; - result = ISC_R_SUCCESS; - } - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - - return (result); -} - -static isc_result_t -getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records, - uint64_t *bytes) -{ - dns_rbtdb_t *rbtdb; - isc_result_t result = ISC_R_SUCCESS; - rbtdb_version_t *rbtversion = version; - - rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); - - RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); - if (rbtversion == NULL) { - rbtversion = rbtdb->current_version; - } - - RWLOCK(&rbtversion->rwlock, isc_rwlocktype_read); - if (records != NULL) { - *records = rbtversion->records; - } - - if (bytes != NULL) { - *bytes = rbtversion->bytes; - } - RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_read); - RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); - - return (result); -} - -static isc_result_t -setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - isc_result_t result = ISC_R_SUCCESS; - rdatasetheader_t *header, oldheader; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(!IS_CACHE(rbtdb)); - REQUIRE(rdataset != NULL); - - header = rdataset->private3; - header--; - - NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock, - isc_rwlocktype_write); - - oldheader = *header; - /* - * Only break the heap invariant (by adjusting resign and resign_lsb) - * if we are going to be restoring it by calling isc_heap_increased - * or isc_heap_decreased. - */ - if (resign != 0) { - header->resign = - (isc_stdtime_t)(dns_time64_from32(resign) >> 1); - header->resign_lsb = resign & 0x1; - } - if (header->heap_index != 0) { - INSIST(RESIGN(header)); - if (resign == 0) { - isc_heap_delete(rbtdb->heaps[header->node->locknum], - header->heap_index); - header->heap_index = 0; - } else if (resign_sooner(header, &oldheader)) { - isc_heap_increased(rbtdb->heaps[header->node->locknum], - header->heap_index); - } else if (resign_sooner(&oldheader, header)) { - isc_heap_decreased(rbtdb->heaps[header->node->locknum], - header->heap_index); - } - } else if (resign != 0) { - header->attributes |= RDATASET_ATTR_RESIGN; - result = resign_insert(rbtdb, header->node->locknum, header); - } - NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock, - isc_rwlocktype_write); - return (result); -} - -static isc_result_t -getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, - dns_name_t *foundname) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - rdatasetheader_t *header = NULL, *this; - unsigned int i; - isc_result_t result = ISC_R_NOTFOUND; - unsigned int locknum = 0; - - REQUIRE(VALID_RBTDB(rbtdb)); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - for (i = 0; i < rbtdb->node_lock_count; i++) { - NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read); - - /* - * Find for the earliest signing time among all of the - * heaps, each of which is covered by a different bucket - * lock. - */ - this = isc_heap_element(rbtdb->heaps[i], 1); - if (this == NULL) { - /* Nothing found; unlock and try the next heap. */ - NODE_UNLOCK(&rbtdb->node_locks[i].lock, - isc_rwlocktype_read); - continue; - } - - if (header == NULL) { - /* - * Found a signing time: retain the bucket lock and - * preserve the lock number so we can unlock it - * later. - */ - header = this; - locknum = i; - } else if (resign_sooner(this, header)) { - /* - * Found an earlier signing time; release the - * previous bucket lock and retain this one instead. - */ - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_read); - header = this; - locknum = i; - } else { - /* - * Earliest signing time in this heap isn't - * an improvement; unlock and try the next heap. - */ - NODE_UNLOCK(&rbtdb->node_locks[i].lock, - isc_rwlocktype_read); - } - } - - if (header != NULL) { - /* - * Found something; pass back the answer and unlock - * the bucket. - */ - bind_rdataset(rbtdb, header->node, header, 0, - isc_rwlocktype_read, rdataset); - - if (foundname != NULL) { - dns_rbt_fullnamefromnode(header->node, foundname); - } - - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_read); - - result = ISC_R_SUCCESS; - } - - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - return (result); -} - -static void -resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) -{ - rbtdb_version_t *rbtversion = (rbtdb_version_t *)version; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *node; - rdatasetheader_t *header; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(rdataset != NULL); - REQUIRE(rdataset->methods == &rdataset_methods); - REQUIRE(rbtdb->future_version == rbtversion); - REQUIRE(rbtversion != NULL); - REQUIRE(rbtversion->writer); - REQUIRE(rbtversion->rbtdb == rbtdb); - - node = rdataset->private2; - INSIST(node != NULL); - header = rdataset->private3; - INSIST(header != NULL); - header--; - - if (header->heap_index == 0) - return; - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, - isc_rwlocktype_write); - /* - * Delete from heap and save to re-signed list so that it can - * be restored if we backout of this change. - */ - resign_delete(rbtdb, rbtversion, header); - NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, - isc_rwlocktype_write); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); -} - -static isc_result_t -setcachestats(dns_db_t *db, isc_stats_t *stats) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(IS_CACHE(rbtdb)); /* current restriction */ - REQUIRE(stats != NULL); - - isc_stats_attach(stats, &rbtdb->cachestats); - return (ISC_R_SUCCESS); -} - -static dns_stats_t * -getrrsetstats(dns_db_t *db) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(IS_CACHE(rbtdb)); /* current restriction */ - - return (rbtdb->rrsetstats); -} - -static isc_result_t -nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; - isc_result_t result; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(node != NULL); - REQUIRE(name != NULL); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - result = dns_rbt_fullnamefromnode(rbtnode, name); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - - return (result); -} - -static isc_result_t -setservestalettl(dns_db_t *db, dns_ttl_t ttl) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(IS_CACHE(rbtdb)); - - /* currently no bounds checking. 0 means disable. */ - rbtdb->serve_stale_ttl = ttl; - return ISC_R_SUCCESS; -} - -static isc_result_t -getservestalettl(dns_db_t *db, dns_ttl_t *ttl) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - - REQUIRE(VALID_RBTDB(rbtdb)); - REQUIRE(IS_CACHE(rbtdb)); - - *ttl = rbtdb->serve_stale_ttl; - return ISC_R_SUCCESS; -} - - -static dns_dbmethods_t zone_methods = { - attach, - detach, - beginload, - endload, - serialize, - dump, - currentversion, - newversion, - attachversion, - closeversion, - findnode, - zone_find, - zone_findzonecut, - attachnode, - detachnode, - expirenode, - printnode, - createiterator, - zone_findrdataset, - allrdatasets, - addrdataset, - subtractrdataset, - deleterdataset, - issecure, - nodecount, - ispersistent, - overmem, - settask, - getoriginnode, - NULL, - getnsec3parameters, - findnsec3node, - setsigningtime, - getsigningtime, - resigned, - isdnssec, - NULL, - rpz_attach, - rpz_ready, - NULL, - NULL, - NULL, - hashsize, - nodefullname, - getsize, - NULL, - NULL -}; - -static dns_dbmethods_t cache_methods = { - attach, - detach, - beginload, - endload, - NULL, - dump, - currentversion, - newversion, - attachversion, - closeversion, - findnode, - cache_find, - cache_findzonecut, - attachnode, - detachnode, - expirenode, - printnode, - createiterator, - cache_findrdataset, - allrdatasets, - addrdataset, - subtractrdataset, - deleterdataset, - issecure, - nodecount, - ispersistent, - overmem, - settask, - getoriginnode, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - isdnssec, - getrrsetstats, - NULL, - NULL, - NULL, - NULL, - setcachestats, - hashsize, - nodefullname, - NULL, - setservestalettl, - getservestalettl -}; - -isc_result_t -#ifdef DNS_RBTDB_VERSION64 -dns_rbtdb64_create -#else -dns_rbtdb_create -#endif - (isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) -{ - dns_rbtdb_t *rbtdb; - isc_result_t result; - int i; - dns_name_t name; - bool (*sooner)(void *, void *); - isc_mem_t *hmctx = mctx; - - /* Keep the compiler happy. */ - UNUSED(driverarg); - - rbtdb = isc_mem_get(mctx, sizeof(*rbtdb)); - if (rbtdb == NULL) - return (ISC_R_NOMEMORY); - - /* - * If argv[0] exists, it points to a memory context to use for heap - */ - if (argc != 0) - hmctx = (isc_mem_t *) argv[0]; - - memset(rbtdb, '\0', sizeof(*rbtdb)); - dns_name_init(&rbtdb->common.origin, NULL); - rbtdb->common.attributes = 0; - if (type == dns_dbtype_cache) { - rbtdb->common.methods = &cache_methods; - rbtdb->common.attributes |= DNS_DBATTR_CACHE; - } else if (type == dns_dbtype_stub) { - rbtdb->common.methods = &zone_methods; - rbtdb->common.attributes |= DNS_DBATTR_STUB; - } else - rbtdb->common.methods = &zone_methods; - rbtdb->common.rdclass = rdclass; - rbtdb->common.mctx = NULL; - - ISC_LIST_INIT(rbtdb->common.update_listeners); - - result = RBTDB_INITLOCK(&rbtdb->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_rbtdb; - - result = isc_rwlock_init(&rbtdb->tree_lock, 0, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - /* - * Initialize node_lock_count in a generic way to support future - * extension which allows the user to specify this value on creation. - * Note that when specified for a cache DB it must be larger than 1 - * as commented with the definition of DEFAULT_CACHE_NODE_LOCK_COUNT. - */ - if (rbtdb->node_lock_count == 0) { - if (IS_CACHE(rbtdb)) - rbtdb->node_lock_count = DEFAULT_CACHE_NODE_LOCK_COUNT; - else - rbtdb->node_lock_count = DEFAULT_NODE_LOCK_COUNT; - } else if (rbtdb->node_lock_count < 2 && IS_CACHE(rbtdb)) { - result = ISC_R_RANGE; - goto cleanup_tree_lock; - } - INSIST(rbtdb->node_lock_count < (1 << DNS_RBT_LOCKLENGTH)); - rbtdb->node_locks = isc_mem_get(mctx, rbtdb->node_lock_count * - sizeof(rbtdb_nodelock_t)); - if (rbtdb->node_locks == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_tree_lock; - } - - rbtdb->cachestats = NULL; - rbtdb->rrsetstats = NULL; - if (IS_CACHE(rbtdb)) { - result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats); - if (result != ISC_R_SUCCESS) - goto cleanup_node_locks; - rbtdb->rdatasets = isc_mem_get(mctx, rbtdb->node_lock_count * - sizeof(rdatasetheaderlist_t)); - if (rbtdb->rdatasets == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_rrsetstats; - } - for (i = 0; i < (int)rbtdb->node_lock_count; i++) - ISC_LIST_INIT(rbtdb->rdatasets[i]); - } else - rbtdb->rdatasets = NULL; - - /* - * Create the heaps. - */ - rbtdb->heaps = isc_mem_get(hmctx, rbtdb->node_lock_count * - sizeof(isc_heap_t *)); - if (rbtdb->heaps == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_rdatasets; - } - for (i = 0; i < (int)rbtdb->node_lock_count; i++) - rbtdb->heaps[i] = NULL; - sooner = IS_CACHE(rbtdb) ? ttl_sooner : resign_sooner; - for (i = 0; i < (int)rbtdb->node_lock_count; i++) { - result = isc_heap_create(hmctx, sooner, set_index, 0, - &rbtdb->heaps[i]); - if (result != ISC_R_SUCCESS) - goto cleanup_heaps; - } - - /* - * Create deadnode lists. - */ - rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count * - sizeof(rbtnodelist_t)); - if (rbtdb->deadnodes == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_heaps; - } - for (i = 0; i < (int)rbtdb->node_lock_count; i++) - ISC_LIST_INIT(rbtdb->deadnodes[i]); - - rbtdb->active = rbtdb->node_lock_count; - - for (i = 0; i < (int)(rbtdb->node_lock_count); i++) { - result = NODE_INITLOCK(&rbtdb->node_locks[i].lock); - if (result == ISC_R_SUCCESS) { - result = isc_refcount_init(&rbtdb->node_locks[i].references, 0); - if (result != ISC_R_SUCCESS) - NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); - } - if (result != ISC_R_SUCCESS) { - while (i-- > 0) { - NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); - isc_refcount_destroy(&rbtdb->node_locks[i].references); - } - goto cleanup_deadnodes; - } - rbtdb->node_locks[i].exiting = false; - } - - /* - * Attach to the mctx. The database will persist so long as there - * are references to it, and attaching to the mctx ensures that our - * mctx won't disappear out from under us. - */ - isc_mem_attach(mctx, &rbtdb->common.mctx); - isc_mem_attach(hmctx, &rbtdb->hmctx); - - /* - * Must be initialized before free_rbtdb() is called. - */ - isc_ondestroy_init(&rbtdb->common.ondest); - - /* - * Make a copy of the origin name. - */ - result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, false, NULL); - return (result); - } - - /* - * Make the Red-Black Trees. - */ - result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->tree); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, false, NULL); - return (result); - } - - result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, false, NULL); - return (result); - } - - result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec3); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, false, NULL); - return (result); - } - - /* - * In order to set the node callback bit correctly in zone databases, - * we need to know if the node has the origin name of the zone. - * In loading_addrdataset() we could simply compare the new name - * to the origin name, but this is expensive. Also, we don't know the - * node name in addrdataset(), so we need another way of knowing the - * zone's top. - * - * We now explicitly create a node for the zone's origin, and then - * we simply remember the node's address. This is safe, because - * the top-of-zone node can never be deleted, nor can its address - * change. - */ - if (!IS_CACHE(rbtdb)) { - rbtdb->origin_node = NULL; - result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin, - &rbtdb->origin_node); - if (result != ISC_R_SUCCESS) { - INSIST(result != ISC_R_EXISTS); - free_rbtdb(rbtdb, false, NULL); - return (result); - } - INSIST(rbtdb->origin_node != NULL); - rbtdb->origin_node->nsec = DNS_RBT_NSEC_NORMAL; - /* - * We need to give the origin node the right locknum. - */ - dns_name_init(&name, NULL); - dns_rbt_namefromnode(rbtdb->origin_node, &name); -#ifdef DNS_RBT_USEHASH - rbtdb->origin_node->locknum = - rbtdb->origin_node->hashval % - rbtdb->node_lock_count; -#else - rbtdb->origin_node->locknum = - dns_name_hash(&name, true) % - rbtdb->node_lock_count; -#endif - /* - * Add an apex node to the NSEC3 tree so that NSEC3 searches - * return partial matches when there is only a single NSEC3 - * record in the tree. - */ - rbtdb->nsec3_origin_node = NULL; - result = dns_rbt_addnode(rbtdb->nsec3, &rbtdb->common.origin, - &rbtdb->nsec3_origin_node); - if (result != ISC_R_SUCCESS) { - INSIST(result != ISC_R_EXISTS); - free_rbtdb(rbtdb, false, NULL); - return (result); - } - rbtdb->nsec3_origin_node->nsec = DNS_RBT_NSEC_NSEC3; - /* - * We need to give the nsec3 origin node the right locknum. - */ - dns_name_init(&name, NULL); - dns_rbt_namefromnode(rbtdb->nsec3_origin_node, &name); -#ifdef DNS_RBT_USEHASH - rbtdb->nsec3_origin_node->locknum = - rbtdb->nsec3_origin_node->hashval % - rbtdb->node_lock_count; -#else - rbtdb->nsec3_origin_node->locknum = - dns_name_hash(&name, true) % - rbtdb->node_lock_count; -#endif - } - - /* - * Misc. Initialization. - */ - result = isc_refcount_init(&rbtdb->references, 1); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, false, NULL); - return (result); - } - rbtdb->attributes = 0; - rbtdb->task = NULL; - rbtdb->rpzs = NULL; - rbtdb->load_rpzs = NULL; - rbtdb->rpz_num = DNS_RPZ_INVALID_NUM; - rbtdb->serve_stale_ttl = 0; - /* - * Version Initialization. - */ - rbtdb->current_serial = 1; - rbtdb->least_serial = 1; - rbtdb->next_serial = 2; - rbtdb->current_version = allocate_version(mctx, 1, 1, false); - if (rbtdb->current_version == NULL) { - isc_refcount_decrement(&rbtdb->references, NULL); - free_rbtdb(rbtdb, false, NULL); - return (ISC_R_NOMEMORY); - } - rbtdb->current_version->rbtdb = rbtdb; - rbtdb->current_version->secure = dns_db_insecure; - rbtdb->current_version->havensec3 = false; - rbtdb->current_version->flags = 0; - rbtdb->current_version->iterations = 0; - rbtdb->current_version->hash = 0; - rbtdb->current_version->salt_length = 0; - memset(rbtdb->current_version->salt, 0, - sizeof(rbtdb->current_version->salt)); - result = isc_rwlock_init(&rbtdb->current_version->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - isc_refcount_destroy(&rbtdb->current_version->references); - isc_mem_put(mctx, rbtdb->current_version, - sizeof(*rbtdb->current_version)); - rbtdb->current_version = NULL; - isc_refcount_decrement(&rbtdb->references, NULL); - free_rbtdb(rbtdb, false, NULL); - return (result); - } - - rbtdb->current_version->records = 0; - rbtdb->current_version->bytes = 0; - rbtdb->future_version = NULL; - ISC_LIST_INIT(rbtdb->open_versions); - /* - * Keep the current version in the open list so that list operation - * won't happen in normal lookup operations. - */ - PREPEND(rbtdb->open_versions, rbtdb->current_version, link); - - rbtdb->common.magic = DNS_DB_MAGIC; - rbtdb->common.impmagic = RBTDB_MAGIC; - - *dbp = (dns_db_t *)rbtdb; - - return (ISC_R_SUCCESS); - - cleanup_deadnodes: - isc_mem_put(mctx, rbtdb->deadnodes, - rbtdb->node_lock_count * sizeof(rbtnodelist_t)); - - cleanup_heaps: - if (rbtdb->heaps != NULL) { - for (i = 0 ; i < (int)rbtdb->node_lock_count ; i++) - if (rbtdb->heaps[i] != NULL) - isc_heap_destroy(&rbtdb->heaps[i]); - isc_mem_put(hmctx, rbtdb->heaps, - rbtdb->node_lock_count * sizeof(isc_heap_t *)); - } - - cleanup_rdatasets: - if (rbtdb->rdatasets != NULL) - isc_mem_put(mctx, rbtdb->rdatasets, rbtdb->node_lock_count * - sizeof(rdatasetheaderlist_t)); - cleanup_rrsetstats: - if (rbtdb->rrsetstats != NULL) - dns_stats_detach(&rbtdb->rrsetstats); - - cleanup_node_locks: - isc_mem_put(mctx, rbtdb->node_locks, - rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); - - cleanup_tree_lock: - isc_rwlock_destroy(&rbtdb->tree_lock); - - cleanup_lock: - RBTDB_DESTROYLOCK(&rbtdb->lock); - - cleanup_rbtdb: - isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); - return (result); -} - - -/* - * Slabbed Rdataset Methods - */ - -static void -rdataset_disassociate(dns_rdataset_t *rdataset) { - dns_db_t *db = rdataset->private1; - dns_dbnode_t *node = rdataset->private2; - - detachnode(db, &node); -} - -static isc_result_t -rdataset_first(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - unsigned int count; - - count = raw[0] * 256 + raw[1]; - if (count == 0) { - rdataset->private5 = NULL; - return (ISC_R_NOMORE); - } - - if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) { - raw += DNS_RDATASET_COUNT; - } - - raw += DNS_RDATASET_LENGTH; - - /* - * The privateuint4 field is the number of rdata beyond the - * cursor position, so we decrement the total count by one - * before storing it. - * - * If DNS_RDATASETATTR_LOADORDER is not set 'raw' points to the - * first record. If DNS_RDATASETATTR_LOADORDER is set 'raw' points - * to the first entry in the offset table. - */ - count--; - rdataset->privateuint4 = count; - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdataset_next(dns_rdataset_t *rdataset) { - unsigned int count; - unsigned int length; - unsigned char *raw; /* RDATASLAB */ - - count = rdataset->privateuint4; - if (count == 0) - return (ISC_R_NOMORE); - count--; - rdataset->privateuint4 = count; - - /* - * Skip forward one record (length + 4) or one offset (4). - */ - raw = rdataset->private5; -#if DNS_RDATASET_FIXED - if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) -#endif /* DNS_RDATASET_FIXED */ - { - length = raw[0] * 256 + raw[1]; - raw += length; - } - - rdataset->private5 = raw + DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH; - - return (ISC_R_SUCCESS); -} - -static void -rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - unsigned char *raw = rdataset->private5; /* RDATASLAB */ - unsigned int length; - isc_region_t r; - unsigned int flags = 0; - - REQUIRE(raw != NULL); - - /* - * Find the start of the record if not already in private5 - * then skip the length and order fields. - */ -#if DNS_RDATASET_FIXED - if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) != 0) { - unsigned int offset; - offset = (raw[0] << 24) + (raw[1] << 16) + - (raw[2] << 8) + raw[3]; - raw = rdataset->private3; - raw += offset; - } -#endif - - length = raw[0] * 256 + raw[1]; - - raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH; - - if (rdataset->type == dns_rdatatype_rrsig) { - if (*raw & DNS_RDATASLAB_OFFLINE) - flags |= DNS_RDATA_OFFLINE; - length--; - raw++; - } - r.length = length; - r.base = raw; - dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); - rdata->flags |= flags; -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - dns_db_t *db = source->private1; - dns_dbnode_t *node = source->private2; - dns_dbnode_t *cloned_node = NULL; - - attachnode(db, node, &cloned_node); - INSIST(!ISC_LINK_LINKED(target, link)); - *target = *source; - ISC_LINK_INIT(target, link); - - /* - * Reset iterator state. - */ - target->privateuint4 = 0; - target->private5 = NULL; -} - -static unsigned int -rdataset_count(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - unsigned int count; - - count = raw[0] * 256 + raw[1]; - - return (count); -} - -static isc_result_t -rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) -{ - dns_db_t *db = rdataset->private1; - dns_dbnode_t *node = rdataset->private2; - dns_dbnode_t *cloned_node; - struct noqname *noqname = rdataset->private6; - - cloned_node = NULL; - attachnode(db, node, &cloned_node); - nsec->methods = &slab_methods; - nsec->rdclass = db->rdclass; - nsec->type = noqname->type; - nsec->covers = 0; - nsec->ttl = rdataset->ttl; - nsec->trust = rdataset->trust; - nsec->private1 = rdataset->private1; - nsec->private2 = rdataset->private2; - nsec->private3 = noqname->neg; - nsec->privateuint4 = 0; - nsec->private5 = NULL; - nsec->private6 = NULL; - nsec->private7 = NULL; - - cloned_node = NULL; - attachnode(db, node, &cloned_node); - nsecsig->methods = &slab_methods; - nsecsig->rdclass = db->rdclass; - nsecsig->type = dns_rdatatype_rrsig; - nsecsig->covers = noqname->type; - nsecsig->ttl = rdataset->ttl; - nsecsig->trust = rdataset->trust; - nsecsig->private1 = rdataset->private1; - nsecsig->private2 = rdataset->private2; - nsecsig->private3 = noqname->negsig; - nsecsig->privateuint4 = 0; - nsecsig->private5 = NULL; - nsec->private6 = NULL; - nsec->private7 = NULL; - - dns_name_clone(&noqname->name, name); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) -{ - dns_db_t *db = rdataset->private1; - dns_dbnode_t *node = rdataset->private2; - dns_dbnode_t *cloned_node; - struct noqname *closest = rdataset->private7; - - cloned_node = NULL; - attachnode(db, node, &cloned_node); - nsec->methods = &slab_methods; - nsec->rdclass = db->rdclass; - nsec->type = closest->type; - nsec->covers = 0; - nsec->ttl = rdataset->ttl; - nsec->trust = rdataset->trust; - nsec->private1 = rdataset->private1; - nsec->private2 = rdataset->private2; - nsec->private3 = closest->neg; - nsec->privateuint4 = 0; - nsec->private5 = NULL; - nsec->private6 = NULL; - nsec->private7 = NULL; - - cloned_node = NULL; - attachnode(db, node, &cloned_node); - nsecsig->methods = &slab_methods; - nsecsig->rdclass = db->rdclass; - nsecsig->type = dns_rdatatype_rrsig; - nsecsig->covers = closest->type; - nsecsig->ttl = rdataset->ttl; - nsecsig->trust = rdataset->trust; - nsecsig->private1 = rdataset->private1; - nsecsig->private2 = rdataset->private2; - nsecsig->private3 = closest->negsig; - nsecsig->privateuint4 = 0; - nsecsig->private5 = NULL; - nsec->private6 = NULL; - nsec->private7 = NULL; - - dns_name_clone(&closest->name, name); - - return (ISC_R_SUCCESS); -} - -static void -rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - rdatasetheader_t *header = rdataset->private3; - - header--; - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - header->trust = rdataset->trust = trust; - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); -} - -static void -rdataset_expire(dns_rdataset_t *rdataset) { - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - rdatasetheader_t *header = rdataset->private3; - - header--; - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - expire_header(rbtdb, header, false, expire_flush); - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); -} - -static void -rdataset_clearprefetch(dns_rdataset_t *rdataset) { - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - rdatasetheader_t *header = rdataset->private3; - - header--; - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - header->attributes &= ~RDATASET_ATTR_PREFETCH; - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); -} - -/* - * Rdataset Iterator Methods - */ - -static void -rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { - rbtdb_rdatasetiter_t *rbtiterator; - - rbtiterator = (rbtdb_rdatasetiter_t *)(*iteratorp); - - if (rbtiterator->common.version != NULL) - closeversion(rbtiterator->common.db, - &rbtiterator->common.version, false); - detachnode(rbtiterator->common.db, &rbtiterator->common.node); - isc_mem_put(rbtiterator->common.db->mctx, rbtiterator, - sizeof(*rbtiterator)); - - *iteratorp = NULL; -} - -static isc_result_t -rdatasetiter_first(dns_rdatasetiter_t *iterator) { - rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); - dns_rbtnode_t *rbtnode = rbtiterator->common.node; - rbtdb_version_t *rbtversion = rbtiterator->common.version; - rdatasetheader_t *header, *top_next; - rbtdb_serial_t serial; - isc_stdtime_t now; - - if (IS_CACHE(rbtdb)) { - serial = 1; - now = rbtiterator->common.now; - } else { - serial = rbtversion->serial; - now = 0; - } - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - for (header = rbtnode->data; header != NULL; header = top_next) { - top_next = header->next; - do { - if (header->serial <= serial && !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't exist" - * record? Or is it too old in the cache? - * - * Note: unlike everywhere else, we - * check for now > header->rdh_ttl instead - * of now >= header->rdh_ttl. This allows - * ANY and RRSIG queries for 0 TTL - * rdatasets to work. - */ - if (NONEXISTENT(header) || - (now != 0 && now > header->rdh_ttl - + rbtdb->serve_stale_ttl)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) - break; - } - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - rbtiterator->current = header; - - if (header == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdatasetiter_next(dns_rdatasetiter_t *iterator) { - rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); - dns_rbtnode_t *rbtnode = rbtiterator->common.node; - rbtdb_version_t *rbtversion = rbtiterator->common.version; - rdatasetheader_t *header, *top_next; - rbtdb_serial_t serial; - isc_stdtime_t now; - rbtdb_rdatatype_t type, negtype; - dns_rdatatype_t rdtype, covers; - - header = rbtiterator->current; - if (header == NULL) - return (ISC_R_NOMORE); - - if (IS_CACHE(rbtdb)) { - serial = 1; - now = rbtiterator->common.now; - } else { - serial = rbtversion->serial; - now = 0; - } - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - type = header->type; - rdtype = RBTDB_RDATATYPE_BASE(header->type); - if (NEGATIVE(header)) { - covers = RBTDB_RDATATYPE_EXT(header->type); - negtype = RBTDB_RDATATYPE_VALUE(covers, 0); - } else - negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); - for (header = header->next; header != NULL; header = top_next) { - top_next = header->next; - /* - * If not walking back up the down list. - */ - if (header->type != type && header->type != negtype) { - do { - if (header->serial <= serial && - !IGNORE(header)) { - /* - * Is this a "this rdataset doesn't - * exist" record? - * - * Note: unlike everywhere else, we - * check for now > header->ttl instead - * of now >= header->ttl. This allows - * ANY and RRSIG queries for 0 TTL - * rdatasets to work. - */ - if (NONEXISTENT(header) || - (now != 0 && now > header->rdh_ttl)) - header = NULL; - break; - } else - header = header->down; - } while (header != NULL); - if (header != NULL) - break; - } - } - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - rbtiterator->current = header; - - if (header == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -static void -rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { - rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); - dns_rbtnode_t *rbtnode = rbtiterator->common.node; - rdatasetheader_t *header; - - header = rbtiterator->current; - REQUIRE(header != NULL); - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now, - isc_rwlocktype_read, rdataset); - - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); -} - - -/* - * Database Iterator Methods - */ - -static inline void -reference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; - dns_rbtnode_t *node = rbtdbiter->node; - - if (node == NULL) - return; - - INSIST(rbtdbiter->tree_locked != isc_rwlocktype_none); - reactivate_node(rbtdb, node, rbtdbiter->tree_locked); -} - -static inline void -dereference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; - dns_rbtnode_t *node = rbtdbiter->node; - nodelock_t *lock; - - if (node == NULL) - return; - - lock = &rbtdb->node_locks[node->locknum].lock; - NODE_LOCK(lock, isc_rwlocktype_read); - decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, - rbtdbiter->tree_locked, false); - NODE_UNLOCK(lock, isc_rwlocktype_read); - - rbtdbiter->node = NULL; -} - -static void -flush_deletions(rbtdb_dbiterator_t *rbtdbiter) { - dns_rbtnode_t *node; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; - bool was_read_locked = false; - nodelock_t *lock; - int i; - - if (rbtdbiter->delcnt != 0) { - /* - * Note that "%d node of %d in tree" can report things like - * "flush_deletions: 59 nodes of 41 in tree". This means - * That some nodes appear on the deletions list more than - * once. Only the last occurrence will actually be deleted. - */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "flush_deletions: %d nodes of %d in tree", - rbtdbiter->delcnt, - dns_rbt_nodecount(rbtdb->tree)); - - if (rbtdbiter->tree_locked == isc_rwlocktype_read) { - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - was_read_locked = true; - } - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - rbtdbiter->tree_locked = isc_rwlocktype_write; - - for (i = 0; i < rbtdbiter->delcnt; i++) { - node = rbtdbiter->deletions[i]; - lock = &rbtdb->node_locks[node->locknum].lock; - - NODE_LOCK(lock, isc_rwlocktype_read); - decrement_reference(rbtdb, node, 0, - isc_rwlocktype_read, - rbtdbiter->tree_locked, false); - NODE_UNLOCK(lock, isc_rwlocktype_read); - } - - rbtdbiter->delcnt = 0; - - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - if (was_read_locked) { - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - rbtdbiter->tree_locked = isc_rwlocktype_read; - - } else { - rbtdbiter->tree_locked = isc_rwlocktype_none; - } - } -} - -static inline void -resume_iteration(rbtdb_dbiterator_t *rbtdbiter) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; - - REQUIRE(rbtdbiter->paused); - REQUIRE(rbtdbiter->tree_locked == isc_rwlocktype_none); - - RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - rbtdbiter->tree_locked = isc_rwlocktype_read; - - rbtdbiter->paused = false; -} - -static void -dbiterator_destroy(dns_dbiterator_t **iteratorp) { - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)(*iteratorp); - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; - dns_db_t *db = NULL; - - if (rbtdbiter->tree_locked == isc_rwlocktype_read) { - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - rbtdbiter->tree_locked = isc_rwlocktype_none; - } else - INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none); - - dereference_iter_node(rbtdbiter); - - flush_deletions(rbtdbiter); - - dns_db_attach(rbtdbiter->common.db, &db); - dns_db_detach(&rbtdbiter->common.db); - - dns_rbtnodechain_reset(&rbtdbiter->chain); - dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); - isc_mem_put(db->mctx, rbtdbiter, sizeof(*rbtdbiter)); - dns_db_detach(&db); - - *iteratorp = NULL; -} - -static isc_result_t -dbiterator_first(dns_dbiterator_t *iterator) { - isc_result_t result; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - dns_name_t *name, *origin; - - if (rbtdbiter->result != ISC_R_SUCCESS && - rbtdbiter->result != ISC_R_NOTFOUND && - rbtdbiter->result != DNS_R_PARTIALMATCH && - rbtdbiter->result != ISC_R_NOMORE) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - dereference_iter_node(rbtdbiter); - - name = dns_fixedname_name(&rbtdbiter->name); - origin = dns_fixedname_name(&rbtdbiter->origin); - dns_rbtnodechain_reset(&rbtdbiter->chain); - dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); - - if (rbtdbiter->nsec3only) { - rbtdbiter->current = &rbtdbiter->nsec3chain; - result = dns_rbtnodechain_first(rbtdbiter->current, - rbtdb->nsec3, name, origin); - } else { - rbtdbiter->current = &rbtdbiter->chain; - result = dns_rbtnodechain_first(rbtdbiter->current, - rbtdb->tree, name, origin); - if (!rbtdbiter->nonsec3 && result == ISC_R_NOTFOUND) { - rbtdbiter->current = &rbtdbiter->nsec3chain; - result = dns_rbtnodechain_first(rbtdbiter->current, - rbtdb->nsec3, name, - origin); - } - } - if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - result = dns_rbtnodechain_current(rbtdbiter->current, NULL, - NULL, &rbtdbiter->node); - if (result == ISC_R_SUCCESS) { - rbtdbiter->new_origin = true; - reference_iter_node(rbtdbiter); - } - } else { - INSIST(result == ISC_R_NOTFOUND); - result = ISC_R_NOMORE; /* The tree is empty. */ - } - - rbtdbiter->result = result; - - if (result != ISC_R_SUCCESS) - ENSURE(!rbtdbiter->paused); - - return (result); -} - -static isc_result_t -dbiterator_last(dns_dbiterator_t *iterator) { - isc_result_t result; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - dns_name_t *name, *origin; - - if (rbtdbiter->result != ISC_R_SUCCESS && - rbtdbiter->result != ISC_R_NOTFOUND && - rbtdbiter->result != DNS_R_PARTIALMATCH && - rbtdbiter->result != ISC_R_NOMORE) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - dereference_iter_node(rbtdbiter); - - name = dns_fixedname_name(&rbtdbiter->name); - origin = dns_fixedname_name(&rbtdbiter->origin); - dns_rbtnodechain_reset(&rbtdbiter->chain); - dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); - - result = ISC_R_NOTFOUND; - if (rbtdbiter->nsec3only && !rbtdbiter->nonsec3) { - rbtdbiter->current = &rbtdbiter->nsec3chain; - result = dns_rbtnodechain_last(rbtdbiter->current, - rbtdb->nsec3, name, origin); - } - if (!rbtdbiter->nsec3only && result == ISC_R_NOTFOUND) { - rbtdbiter->current = &rbtdbiter->chain; - result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree, - name, origin); - } - if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { - result = dns_rbtnodechain_current(rbtdbiter->current, NULL, - NULL, &rbtdbiter->node); - if (result == ISC_R_SUCCESS) { - rbtdbiter->new_origin = true; - reference_iter_node(rbtdbiter); - } - } else { - INSIST(result == ISC_R_NOTFOUND); - result = ISC_R_NOMORE; /* The tree is empty. */ - } - - rbtdbiter->result = result; - - return (result); -} - -static isc_result_t -dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { - isc_result_t result, tresult; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - dns_name_t *iname, *origin; - - if (rbtdbiter->result != ISC_R_SUCCESS && - rbtdbiter->result != ISC_R_NOTFOUND && - rbtdbiter->result != DNS_R_PARTIALMATCH && - rbtdbiter->result != ISC_R_NOMORE) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - dereference_iter_node(rbtdbiter); - - iname = dns_fixedname_name(&rbtdbiter->name); - origin = dns_fixedname_name(&rbtdbiter->origin); - dns_rbtnodechain_reset(&rbtdbiter->chain); - dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); - - if (rbtdbiter->nsec3only) { - rbtdbiter->current = &rbtdbiter->nsec3chain; - result = dns_rbt_findnode(rbtdb->nsec3, name, NULL, - &rbtdbiter->node, - rbtdbiter->current, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - } else if (rbtdbiter->nonsec3) { - rbtdbiter->current = &rbtdbiter->chain; - result = dns_rbt_findnode(rbtdb->tree, name, NULL, - &rbtdbiter->node, - rbtdbiter->current, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - } else { - /* - * Stay on main chain if not found on either chain. - */ - rbtdbiter->current = &rbtdbiter->chain; - result = dns_rbt_findnode(rbtdb->tree, name, NULL, - &rbtdbiter->node, - rbtdbiter->current, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result == DNS_R_PARTIALMATCH) { - dns_rbtnode_t *node = NULL; - tresult = dns_rbt_findnode(rbtdb->nsec3, name, NULL, - &node, &rbtdbiter->nsec3chain, - DNS_RBTFIND_EMPTYDATA, - NULL, NULL); - if (tresult == ISC_R_SUCCESS) { - rbtdbiter->node = node; - rbtdbiter->current = &rbtdbiter->nsec3chain; - result = tresult; - } - } - } - - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { - tresult = dns_rbtnodechain_current(rbtdbiter->current, iname, - origin, NULL); - if (tresult == ISC_R_SUCCESS) { - rbtdbiter->new_origin = true; - reference_iter_node(rbtdbiter); - } else { - result = tresult; - rbtdbiter->node = NULL; - } - } else - rbtdbiter->node = NULL; - - rbtdbiter->result = (result == DNS_R_PARTIALMATCH) ? - ISC_R_SUCCESS : result; - - return (result); -} - -static isc_result_t -dbiterator_prev(dns_dbiterator_t *iterator) { - isc_result_t result; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_name_t *name, *origin; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - - REQUIRE(rbtdbiter->node != NULL); - - if (rbtdbiter->result != ISC_R_SUCCESS) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - name = dns_fixedname_name(&rbtdbiter->name); - origin = dns_fixedname_name(&rbtdbiter->origin); - result = dns_rbtnodechain_prev(rbtdbiter->current, name, origin); - if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only && - !rbtdbiter->nonsec3 && - &rbtdbiter->nsec3chain == rbtdbiter->current) { - rbtdbiter->current = &rbtdbiter->chain; - dns_rbtnodechain_reset(rbtdbiter->current); - result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree, - name, origin); - if (result == ISC_R_NOTFOUND) - result = ISC_R_NOMORE; - } - - dereference_iter_node(rbtdbiter); - - if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { - rbtdbiter->new_origin = (result == DNS_R_NEWORIGIN); - result = dns_rbtnodechain_current(rbtdbiter->current, NULL, - NULL, &rbtdbiter->node); - } - - if (result == ISC_R_SUCCESS) - reference_iter_node(rbtdbiter); - - rbtdbiter->result = result; - - return (result); -} - -static isc_result_t -dbiterator_next(dns_dbiterator_t *iterator) { - isc_result_t result; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_name_t *name, *origin; - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - - REQUIRE(rbtdbiter->node != NULL); - - if (rbtdbiter->result != ISC_R_SUCCESS) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - name = dns_fixedname_name(&rbtdbiter->name); - origin = dns_fixedname_name(&rbtdbiter->origin); - result = dns_rbtnodechain_next(rbtdbiter->current, name, origin); - if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only && - !rbtdbiter->nonsec3 && &rbtdbiter->chain == rbtdbiter->current) { - rbtdbiter->current = &rbtdbiter->nsec3chain; - dns_rbtnodechain_reset(rbtdbiter->current); - result = dns_rbtnodechain_first(rbtdbiter->current, - rbtdb->nsec3, name, origin); - if (result == ISC_R_NOTFOUND) - result = ISC_R_NOMORE; - } - - dereference_iter_node(rbtdbiter); - - if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { - rbtdbiter->new_origin = (result == DNS_R_NEWORIGIN); - result = dns_rbtnodechain_current(rbtdbiter->current, NULL, - NULL, &rbtdbiter->node); - } - if (result == ISC_R_SUCCESS) - reference_iter_node(rbtdbiter); - - rbtdbiter->result = result; - - return (result); -} - -static isc_result_t -dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, - dns_name_t *name) -{ - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_rbtnode_t *node = rbtdbiter->node; - isc_result_t result; - dns_name_t *nodename = dns_fixedname_name(&rbtdbiter->name); - dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin); - - REQUIRE(rbtdbiter->result == ISC_R_SUCCESS); - REQUIRE(rbtdbiter->node != NULL); - - if (rbtdbiter->paused) - resume_iteration(rbtdbiter); - - if (name != NULL) { - if (rbtdbiter->common.relative_names) - origin = NULL; - result = dns_name_concatenate(nodename, origin, name, NULL); - if (result != ISC_R_SUCCESS) - return (result); - if (rbtdbiter->common.relative_names && rbtdbiter->new_origin) - result = DNS_R_NEWORIGIN; - } else - result = ISC_R_SUCCESS; - - NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); - new_reference(rbtdb, node, isc_rwlocktype_none); - NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); - - *nodep = rbtdbiter->node; - - if (iterator->cleaning && result == ISC_R_SUCCESS) { - isc_result_t expire_result; - - /* - * If the deletion array is full, flush it before trying - * to expire the current node. The current node can't - * fully deleted while the iteration cursor is still on it. - */ - if (rbtdbiter->delcnt == DELETION_BATCH_MAX) - flush_deletions(rbtdbiter); - - expire_result = expirenode(iterator->db, *nodep, 0); - - /* - * expirenode() currently always returns success. - */ - if (expire_result == ISC_R_SUCCESS && node->down == NULL) { - unsigned int refs; - - rbtdbiter->deletions[rbtdbiter->delcnt++] = node; - NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); - dns_rbtnode_refincrement(node, &refs); - INSIST(refs != 0); - NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); - } - } - - return (result); -} - -static isc_result_t -dbiterator_pause(dns_dbiterator_t *iterator) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - - if (rbtdbiter->result != ISC_R_SUCCESS && - rbtdbiter->result != ISC_R_NOTFOUND && - rbtdbiter->result != DNS_R_PARTIALMATCH && - rbtdbiter->result != ISC_R_NOMORE) - return (rbtdbiter->result); - - if (rbtdbiter->paused) - return (ISC_R_SUCCESS); - - rbtdbiter->paused = true; - - if (rbtdbiter->tree_locked != isc_rwlocktype_none) { - INSIST(rbtdbiter->tree_locked == isc_rwlocktype_read); - RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - rbtdbiter->tree_locked = isc_rwlocktype_none; - } - - flush_deletions(rbtdbiter); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { - rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; - dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin); - - if (rbtdbiter->result != ISC_R_SUCCESS) - return (rbtdbiter->result); - - return (dns_name_copy(origin, name, NULL)); -} - -/*% - * Additional cache routines. - */ -static isc_result_t -rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, dns_acache_t *acache, - dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, dns_dbnode_t **nodep, - dns_name_t *fname, dns_message_t *msg, - isc_stdtime_t now) -{ - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - unsigned int current_count = rdataset->privateuint4; - unsigned int count; - rdatasetheader_t *header; - nodelock_t *nodelock; - unsigned int total_count; - acachectl_t *acarray; - dns_acacheentry_t *entry; - isc_result_t result; - - UNUSED(qtype); /* we do not use this value at least for now */ - UNUSED(acache); - - header = (struct rdatasetheader *)(raw - sizeof(*header)); - - total_count = raw[0] * 256 + raw[1]; - INSIST(total_count > current_count); - count = total_count - current_count - 1; - - acarray = NULL; - - nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; - NODE_LOCK(nodelock, isc_rwlocktype_read); - - switch (type) { - case dns_rdatasetadditional_fromauth: - acarray = header->additional_auth; - break; - case dns_rdatasetadditional_fromcache: - acarray = NULL; - break; - case dns_rdatasetadditional_fromglue: - acarray = header->additional_glue; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (acarray == NULL) { - if (type != dns_rdatasetadditional_fromcache) - dns_acache_countquerymiss(acache); - NODE_UNLOCK(nodelock, isc_rwlocktype_read); - return (ISC_R_NOTFOUND); - } - - if (acarray[count].entry == NULL) { - dns_acache_countquerymiss(acache); - NODE_UNLOCK(nodelock, isc_rwlocktype_read); - return (ISC_R_NOTFOUND); - } - - entry = NULL; - dns_acache_attachentry(acarray[count].entry, &entry); - - NODE_UNLOCK(nodelock, isc_rwlocktype_read); - - result = dns_acache_getentry(entry, zonep, dbp, versionp, - nodep, fname, msg, now); - - dns_acache_detachentry(&entry); - - return (result); -} - -static void -acache_callback(dns_acacheentry_t *entry, void **arg) { - dns_rbtdb_t *rbtdb; - dns_rbtnode_t *rbtnode; - nodelock_t *nodelock; - acachectl_t *acarray = NULL; - acache_cbarg_t *cbarg; - unsigned int count; - - REQUIRE(arg != NULL); - cbarg = *arg; - - /* - * The caller must hold the entry lock. - */ - - rbtdb = (dns_rbtdb_t *)cbarg->db; - rbtnode = (dns_rbtnode_t *)cbarg->node; - - nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; - NODE_LOCK(nodelock, isc_rwlocktype_write); - - switch (cbarg->type) { - case dns_rdatasetadditional_fromauth: - acarray = cbarg->header->additional_auth; - break; - case dns_rdatasetadditional_fromglue: - acarray = cbarg->header->additional_glue; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - count = cbarg->count; - if (acarray != NULL && acarray[count].entry == entry) { - acarray[count].entry = NULL; - INSIST(acarray[count].cbarg == cbarg); - acarray[count].cbarg = NULL; - isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); - dns_acache_detachentry(&entry); - } - - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - - dns_db_detachnode((dns_db_t *)rbtdb, (dns_dbnode_t **)(void*)&rbtnode); - dns_db_detach((dns_db_t **)(void*)&rbtdb); - - *arg = NULL; -} - -static void -acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry, - acache_cbarg_t **cbargp) -{ - acache_cbarg_t *cbarg; - - REQUIRE(mctx != NULL); - REQUIRE(entry != NULL); - REQUIRE(cbargp != NULL && *cbargp != NULL); - - cbarg = *cbargp; - - if (dns_acache_cancelentry(entry)) { - dns_db_detachnode(cbarg->db, &cbarg->node); - dns_db_detach(&cbarg->db); - } - - isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t)); - - *cbargp = NULL; -} - -static isc_result_t -rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, dns_acache_t *acache, - dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *version, dns_dbnode_t *node, - dns_name_t *fname) -{ - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - unsigned int current_count = rdataset->privateuint4; - rdatasetheader_t *header; - unsigned int total_count, count; - nodelock_t *nodelock; - isc_result_t result; - acachectl_t *acarray; - dns_acacheentry_t *newentry, *oldentry = NULL; - acache_cbarg_t *newcbarg, *oldcbarg = NULL; - - UNUSED(qtype); - - if (type == dns_rdatasetadditional_fromcache) - return (ISC_R_SUCCESS); - - header = (struct rdatasetheader *)(raw - sizeof(*header)); - - total_count = raw[0] * 256 + raw[1]; - INSIST(total_count > current_count); - count = total_count - current_count - 1; /* should be private data */ - - newcbarg = isc_mem_get(rbtdb->common.mctx, sizeof(*newcbarg)); - if (newcbarg == NULL) - return (ISC_R_NOMEMORY); - newcbarg->type = type; - newcbarg->count = count; - newcbarg->header = header; - newcbarg->db = NULL; - dns_db_attach((dns_db_t *)rbtdb, &newcbarg->db); - newcbarg->node = NULL; - dns_db_attachnode((dns_db_t *)rbtdb, (dns_dbnode_t *)rbtnode, - &newcbarg->node); - newentry = NULL; - result = dns_acache_createentry(acache, (dns_db_t *)rbtdb, - acache_callback, newcbarg, &newentry); - if (result != ISC_R_SUCCESS) - goto fail; - - /* Set cache data in the new entry. */ - result = dns_acache_setentry(acache, newentry, zone, db, - version, node, fname); - if (result != ISC_R_SUCCESS) - goto fail; - - nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; - NODE_LOCK(nodelock, isc_rwlocktype_write); - - acarray = NULL; - switch (type) { - case dns_rdatasetadditional_fromauth: - acarray = header->additional_auth; - break; - case dns_rdatasetadditional_fromglue: - acarray = header->additional_glue; - break; - default: - INSIST(0); - } - - if (acarray == NULL) { - unsigned int i; - - acarray = isc_mem_get(rbtdb->common.mctx, total_count * - sizeof(acachectl_t)); - - if (acarray == NULL) { - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - goto fail; - } - - for (i = 0; i < total_count; i++) { - acarray[i].entry = NULL; - acarray[i].cbarg = NULL; - } - } - switch (type) { - case dns_rdatasetadditional_fromauth: - header->additional_auth = acarray; - break; - case dns_rdatasetadditional_fromglue: - header->additional_glue = acarray; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (acarray[count].entry != NULL) { - /* - * Swap the entry. Delay cleaning-up the old entry since - * it would require a node lock. - */ - oldentry = acarray[count].entry; - INSIST(acarray[count].cbarg != NULL); - oldcbarg = acarray[count].cbarg; - } - acarray[count].entry = newentry; - acarray[count].cbarg = newcbarg; - - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - - if (oldentry != NULL) { - acache_cancelentry(rbtdb->common.mctx, oldentry, &oldcbarg); - dns_acache_detachentry(&oldentry); - } - - return (ISC_R_SUCCESS); - - fail: - if (newcbarg != NULL) { - if (newentry != NULL) { - acache_cancelentry(rbtdb->common.mctx, newentry, - &newcbarg); - dns_acache_detachentry(&newentry); - } else { - dns_db_detachnode((dns_db_t *)rbtdb, &newcbarg->node); - dns_db_detach(&newcbarg->db); - isc_mem_put(rbtdb->common.mctx, newcbarg, - sizeof(*newcbarg)); - } - } - - return (result); -} - -static isc_result_t -rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, dns_rdatatype_t qtype) -{ - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - unsigned int current_count = rdataset->privateuint4; - rdatasetheader_t *header; - nodelock_t *nodelock; - unsigned int total_count, count; - acachectl_t *acarray; - dns_acacheentry_t *entry; - acache_cbarg_t *cbarg; - - UNUSED(qtype); /* we do not use this value at least for now */ - UNUSED(acache); - - if (type == dns_rdatasetadditional_fromcache) - return (ISC_R_SUCCESS); - - header = (struct rdatasetheader *)(raw - sizeof(*header)); - - total_count = raw[0] * 256 + raw[1]; - INSIST(total_count > current_count); - count = total_count - current_count - 1; - - acarray = NULL; - entry = NULL; - - nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; - NODE_LOCK(nodelock, isc_rwlocktype_write); - - switch (type) { - case dns_rdatasetadditional_fromauth: - acarray = header->additional_auth; - break; - case dns_rdatasetadditional_fromglue: - acarray = header->additional_glue; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (acarray == NULL) { - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - return (ISC_R_NOTFOUND); - } - - entry = acarray[count].entry; - if (entry == NULL) { - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - return (ISC_R_NOTFOUND); - } - - acarray[count].entry = NULL; - cbarg = acarray[count].cbarg; - acarray[count].cbarg = NULL; - - NODE_UNLOCK(nodelock, isc_rwlocktype_write); - - if (entry != NULL) { - if (cbarg != NULL) - acache_cancelentry(rbtdb->common.mctx, entry, &cbarg); - dns_acache_detachentry(&entry); - } - - return (ISC_R_SUCCESS); -} - -static void -setownercase(rdatasetheader_t *header, const dns_name_t *name) { - unsigned int i; - bool fully_lower; - - /* - * We do not need to worry about label lengths as they are all - * less than or equal to 63. - */ - memset(header->upper, 0, sizeof(header->upper)); - fully_lower = true; - for (i = 0; i < name->length; i++) - if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) { - header->upper[i/8] |= 1 << (i%8); - fully_lower = false; - } - header->attributes |= RDATASET_ATTR_CASESET; - if (ISC_LIKELY(fully_lower)) - header->attributes |= RDATASET_ATTR_CASEFULLYLOWER; -} - -static void -rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) { - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - unsigned char *raw = rdataset->private3; /* RDATASLAB */ - rdatasetheader_t *header; - - header = (struct rdatasetheader *)(raw - sizeof(*header)); - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); - setownercase(header, name); - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_write); -} - -static const unsigned char charmask[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static unsigned char maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -static void -rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { - dns_rbtdb_t *rbtdb = rdataset->private1; - dns_rbtnode_t *rbtnode = rdataset->private2; - const unsigned char *raw = rdataset->private3; /* RDATASLAB */ - const rdatasetheader_t *header; - unsigned int i, j; - unsigned char bits; - unsigned char c, flip; - - header = (const struct rdatasetheader *)(raw - sizeof(*header)); - - NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); - - if (!CASESET(header)) { - goto unlock; - } - -#if 0 - /* - * This was the original code, and is implemented differently in - * the #else block that follows. - */ - for (i = 0; i < name->length; i++) { - /* - * Set the case bit if it does not match the recorded bit. - */ - if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a && - (header->upper[i/8] & (1 << (i%8))) != 0) - { - name->ndata[i] &= ~0x20; /* clear the lower case bit */ - } else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a && - (header->upper[i/8] & (1 << (i%8))) == 0) - { - name->ndata[i] |= 0x20; /* set the lower case bit */ - } - } -#else - if (ISC_LIKELY(CASEFULLYLOWER(header))) { - unsigned char *bp, *be; - bp = name->ndata; - be = bp + name->length; - - while (bp <= be - 4) { - c = bp[0]; - bp[0] = maptolower[c]; - c = bp[1]; - bp[1] = maptolower[c]; - c = bp[2]; - bp[2] = maptolower[c]; - c = bp[3]; - bp[3] = maptolower[c]; - bp += 4; - } - while (bp < be) { - c = *bp; - *bp++ = maptolower[c]; - } - goto unlock; - } - - i = 0; - for (j = 0; j < (name->length >> 3); j++) { - unsigned int k; - - bits = ~(header->upper[j]); - - for (k = 0; k < 8; k++) { - c = name->ndata[i]; - flip = (bits & 1) << 5; - flip ^= c; - flip &= charmask[c]; - name->ndata[i] ^= flip; - - i++; - bits >>= 1; - } - } - - if (ISC_UNLIKELY(i == name->length)) { - goto unlock; - } - - bits = ~(header->upper[j]); - - for (; i < name->length; i++) { - c = name->ndata[i]; - flip = (bits & 1) << 5; - flip ^= c; - flip &= charmask[c]; - name->ndata[i] ^= flip; - - bits >>= 1; - } -#endif - - unlock: - NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, - isc_rwlocktype_read); -} - -/*% - * Routines for LRU-based cache management. - */ - -/*% - * See if a given cache entry that is being reused needs to be updated - * in the LRU-list. From the LRU management point of view, this function is - * expected to return true for almost all cases. When used with threads, - * however, this may cause a non-negligible performance penalty because a - * writer lock will have to be acquired before updating the list. - * If DNS_RBTDB_LIMITLRUUPDATE is defined to be non 0 at compilation time, this - * function returns true if the entry has not been updated for some period of - * time. We differentiate the NS or glue address case and the others since - * experiments have shown that the former tends to be accessed relatively - * infrequently and the cost of cache miss is higher (e.g., a missing NS records - * may cause external queries at a higher level zone, involving more - * transactions). - * - * Caller must hold the node (read or write) lock. - */ -static inline bool -need_headerupdate(rdatasetheader_t *header, isc_stdtime_t now) { - if ((header->attributes & - (RDATASET_ATTR_NONEXISTENT | - RDATASET_ATTR_ANCIENT | - RDATASET_ATTR_ZEROTTL)) != 0) - return (false); - -#if DNS_RBTDB_LIMITLRUUPDATE - if (header->type == dns_rdatatype_ns || - (header->trust == dns_trust_glue && - (header->type == dns_rdatatype_a || - header->type == dns_rdatatype_aaaa))) { - /* - * Glue records are updated if at least 60 seconds have passed - * since the previous update time. - */ - return (header->last_used + 60 <= now); - } - - /* Other records are updated if 5 minutes have passed. */ - return (header->last_used + 300 <= now); -#else - UNUSED(now); - - return (true); -#endif -} - -/*% - * Update the timestamp of a given cache entry and move it to the head - * of the corresponding LRU list. - * - * Caller must hold the node (write) lock. - * - * Note that the we do NOT touch the heap here, as the TTL has not changed. - */ -static void -update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - isc_stdtime_t now) -{ - INSIST(IS_CACHE(rbtdb)); - - /* To be checked: can we really assume this? XXXMLG */ - INSIST(ISC_LINK_LINKED(header, link)); - - ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link); - header->last_used = now; - ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link); -} - -/*% - * Purge some expired and/or stale (i.e. unused for some period) cache entries - * under an overmem condition. To recover from this condition quickly, up to - * 2 entries will be purged. This process is triggered while adding a new - * entry, and we specifically avoid purging entries in the same LRU bucket as - * the one to which the new entry will belong. Otherwise, we might purge - * entries of the same name of different RR types while adding RRsets from a - * single response (consider the case where we're adding A and AAAA glue records - * of the same NS name). - */ -static void -overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, - isc_stdtime_t now, bool tree_locked) -{ - rdatasetheader_t *header, *header_prev; - unsigned int locknum; - int purgecount = 2; - - for (locknum = (locknum_start + 1) % rbtdb->node_lock_count; - locknum != locknum_start && purgecount > 0; - locknum = (locknum + 1) % rbtdb->node_lock_count) { - NODE_LOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - - header = isc_heap_element(rbtdb->heaps[locknum], 1); - if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) { - expire_header(rbtdb, header, tree_locked, - expire_ttl); - purgecount--; - } - - for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]); - header != NULL && purgecount > 0; - header = header_prev) { - header_prev = ISC_LIST_PREV(header, link); - /* - * Unlink the entry at this point to avoid checking it - * again even if it's currently used someone else and - * cannot be purged at this moment. This entry won't be - * referenced any more (so unlinking is safe) since the - * TTL was reset to 0. - */ - ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, - link); - expire_header(rbtdb, header, tree_locked, - expire_lru); - purgecount--; - } - - NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, - isc_rwlocktype_write); - } -} - -static void -expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - bool tree_locked, expire_t reason) -{ - set_ttl(rbtdb, header, 0); - mark_header_ancient(rbtdb, header); - - /* - * Caller must hold the node (write) lock. - */ - - if (dns_rbtnode_refcurrent(header->node) == 0) { - /* - * If no one else is using the node, we can clean it up now. - * We first need to gain a new reference to the node to meet a - * requirement of decrement_reference(). - */ - new_reference(rbtdb, header->node, isc_rwlocktype_write); - decrement_reference(rbtdb, header->node, 0, - isc_rwlocktype_write, - tree_locked ? isc_rwlocktype_write : - isc_rwlocktype_none, false); - - if (rbtdb->cachestats == NULL) - return; - - switch (reason) { - case expire_ttl: - isc_stats_increment(rbtdb->cachestats, - dns_cachestatscounter_deletettl); - break; - case expire_lru: - isc_stats_increment(rbtdb->cachestats, - dns_cachestatscounter_deletelru); - break; - default: - break; - } - - } -} diff --git a/lib/dns-pkcs11/rbtdb.h b/lib/dns-pkcs11/rbtdb.h deleted file mode 100644 index cd84b5b..0000000 --- a/lib/dns-pkcs11/rbtdb.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RBTDB_H -#define DNS_RBTDB_H 1 - -#include -#include - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * DNS Red-Black Tree DB Implementation - */ - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_rbtdb_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp); - -/*%< - * Create a new database of type "rbt" (or "rbt64"). Called via - * dns_db_create(); see documentation for that function for more details. - * - * If argv[0] is set, it points to a valid memory context to be used for - * allocation of heap memory. Generally this is used for cache databases - * only. - * - * Requires: - * - * \li argc == 0 or argv[0] is a valid memory context. - */ - -ISC_LANG_ENDDECLS - -#endif /* DNS_RBTDB_H */ diff --git a/lib/dns-pkcs11/rbtdb64.c b/lib/dns-pkcs11/rbtdb64.c deleted file mode 100644 index 0a0fb05..0000000 --- a/lib/dns-pkcs11/rbtdb64.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#define DNS_RBTDB_VERSION64 1 -#include "rbtdb.c" diff --git a/lib/dns-pkcs11/rbtdb64.h b/lib/dns-pkcs11/rbtdb64.h deleted file mode 100644 index 33b0115..0000000 --- a/lib/dns-pkcs11/rbtdb64.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef DNS_RBTDB64_H -#define DNS_RBTDB64_H 1 - -#include - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * DNS Red-Black Tree DB Implementation with 64-bit version numbers - */ - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -dns_rbtdb64_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RBTDB64_H */ diff --git a/lib/dns-pkcs11/rcode.c b/lib/dns-pkcs11/rcode.c deleted file mode 100644 index da9ec68..0000000 --- a/lib/dns-pkcs11/rcode.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define RETERR(x) \ - do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -#define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */ - -#define TOTEXTONLY 0x01 - -#define RCODENAMES \ - /* standard rcodes */ \ - { dns_rcode_noerror, "NOERROR", 0}, \ - { dns_rcode_formerr, "FORMERR", 0}, \ - { dns_rcode_servfail, "SERVFAIL", 0}, \ - { dns_rcode_nxdomain, "NXDOMAIN", 0}, \ - { dns_rcode_notimp, "NOTIMP", 0}, \ - { dns_rcode_refused, "REFUSED", 0}, \ - { dns_rcode_yxdomain, "YXDOMAIN", 0}, \ - { dns_rcode_yxrrset, "YXRRSET", 0}, \ - { dns_rcode_nxrrset, "NXRRSET", 0}, \ - { dns_rcode_notauth, "NOTAUTH", 0}, \ - { dns_rcode_notzone, "NOTZONE", 0}, \ - { 11, "RESERVED11", TOTEXTONLY}, \ - { 12, "RESERVED12", TOTEXTONLY}, \ - { 13, "RESERVED13", TOTEXTONLY}, \ - { 14, "RESERVED14", TOTEXTONLY}, \ - { 15, "RESERVED15", TOTEXTONLY}, - -#define ERCODENAMES \ - /* extended rcodes */ \ - { dns_rcode_badvers, "BADVERS", 0}, \ - { dns_rcode_badcookie, "BADCOOKIE", 0}, \ - { 0, NULL, 0 } - -#define TSIGRCODENAMES \ - /* extended rcodes */ \ - { dns_tsigerror_badsig, "BADSIG", 0}, \ - { dns_tsigerror_badkey, "BADKEY", 0}, \ - { dns_tsigerror_badtime, "BADTIME", 0}, \ - { dns_tsigerror_badmode, "BADMODE", 0}, \ - { dns_tsigerror_badname, "BADNAME", 0}, \ - { dns_tsigerror_badalg, "BADALG", 0}, \ - { dns_tsigerror_badtrunc, "BADTRUNC", 0}, \ - { 0, NULL, 0 } - -/* RFC4398 section 2.1 */ - -#define CERTNAMES \ - { 1, "PKIX", 0}, \ - { 2, "SPKI", 0}, \ - { 3, "PGP", 0}, \ - { 4, "IPKIX", 0}, \ - { 5, "ISPKI", 0}, \ - { 6, "IPGP", 0}, \ - { 7, "ACPKIX", 0}, \ - { 8, "IACPKIX", 0}, \ - { 253, "URI", 0}, \ - { 254, "OID", 0}, \ - { 0, NULL, 0} - -/* RFC2535 section 7, RFC3110 */ - -#ifndef PK11_MD5_DISABLE -#define MD5_SECALGNAMES \ - { DNS_KEYALG_RSAMD5, "RSAMD5", 0 }, \ - { DNS_KEYALG_RSAMD5, "RSA", 0 }, -#else -#define MD5_SECALGNAMES -#endif -#ifndef PK11_DH_DISABLE -#define DH_SECALGNAMES \ - { DNS_KEYALG_DH, "DH", 0 }, -#else -#define DH_SECALGNAMES -#endif -#ifndef PK11_DSA_DISABLE -#define DSA_SECALGNAMES \ - { DNS_KEYALG_DSA, "DSA", 0 }, \ - { DNS_KEYALG_NSEC3DSA, "NSEC3DSA", 0 }, -#else -#define DSA_SECALGNAMES -#endif - -#define SECALGNAMES \ - DH_SECALGNAMES \ - DSA_SECALGNAMES \ - { DNS_KEYALG_ECC, "ECC", 0 }, \ - { DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \ - { DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \ - { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \ - { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \ - { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \ - { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \ - { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \ - { DNS_KEYALG_ED25519, "ED25519", 0 }, \ - { DNS_KEYALG_ED448, "ED448", 0 }, \ - { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ - { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ - { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ - { 0, NULL, 0} - -/* RFC2535 section 7.1 */ - -#define SECPROTONAMES \ - { 0, "NONE", 0 }, \ - { 1, "TLS", 0 }, \ - { 2, "EMAIL", 0 }, \ - { 3, "DNSSEC", 0 }, \ - { 4, "IPSEC", 0 }, \ - { 255, "ALL", 0 }, \ - { 0, NULL, 0} - -#define HASHALGNAMES \ - { 1, "SHA-1", 0 }, \ - { 0, NULL, 0 } - -/* RFC3658, RFC4509, RFC5933, RFC6605 */ - -#define DSDIGESTNAMES \ - { DNS_DSDIGEST_SHA1, "SHA-1", 0 }, \ - { DNS_DSDIGEST_SHA256, "SHA-256", 0 }, \ - { DNS_DSDIGEST_GOST, "GOST", 0 }, \ - { DNS_DSDIGEST_SHA384, "SHA-384", 0 }, \ - { 0, NULL, 0} - -struct tbl { - unsigned int value; - const char *name; - int flags; -}; - -static struct tbl rcodes[] = { RCODENAMES ERCODENAMES }; -static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES }; -static struct tbl certs[] = { CERTNAMES }; -static struct tbl secalgs[] = { SECALGNAMES }; -static struct tbl md5_secalgs[] = { MD5_SECALGNAMES }; -static struct tbl secprotos[] = { SECPROTONAMES }; -static struct tbl hashalgs[] = { HASHALGNAMES }; -static struct tbl dsdigests[] = { DSDIGESTNAMES }; - -static struct keyflag { - const char *name; - unsigned int value; - unsigned int mask; -} keyflags[] = { - { "NOCONF", 0x4000, 0xC000 }, - { "NOAUTH", 0x8000, 0xC000 }, - { "NOKEY", 0xC000, 0xC000 }, - { "FLAG2", 0x2000, 0x2000 }, - { "EXTEND", 0x1000, 0x1000 }, - { "FLAG4", 0x0800, 0x0800 }, - { "FLAG5", 0x0400, 0x0400 }, - { "USER", 0x0000, 0x0300 }, - { "ZONE", 0x0100, 0x0300 }, - { "HOST", 0x0200, 0x0300 }, - { "NTYP3", 0x0300, 0x0300 }, - { "FLAG8", 0x0080, 0x0080 }, - { "FLAG9", 0x0040, 0x0040 }, - { "FLAG10", 0x0020, 0x0020 }, - { "FLAG11", 0x0010, 0x0010 }, - { "SIG0", 0x0000, 0x000F }, - { "SIG1", 0x0001, 0x000F }, - { "SIG2", 0x0002, 0x000F }, - { "SIG3", 0x0003, 0x000F }, - { "SIG4", 0x0004, 0x000F }, - { "SIG5", 0x0005, 0x000F }, - { "SIG6", 0x0006, 0x000F }, - { "SIG7", 0x0007, 0x000F }, - { "SIG8", 0x0008, 0x000F }, - { "SIG9", 0x0009, 0x000F }, - { "SIG10", 0x000A, 0x000F }, - { "SIG11", 0x000B, 0x000F }, - { "SIG12", 0x000C, 0x000F }, - { "SIG13", 0x000D, 0x000F }, - { "SIG14", 0x000E, 0x000F }, - { "SIG15", 0x000F, 0x000F }, - { "KSK", DNS_KEYFLAG_KSK, DNS_KEYFLAG_KSK }, - { NULL, 0, 0 } -}; - -static isc_result_t -str_totext(const char *source, isc_buffer_t *target) { - unsigned int l; - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - l = strlen(source); - - if (l > region.length) - return (ISC_R_NOSPACE); - - memmove(region.base, source, l); - isc_buffer_add(target, l); - return (ISC_R_SUCCESS); -} - -static isc_result_t -maybe_numeric(unsigned int *valuep, isc_textregion_t *source, - unsigned int max, bool hex_allowed) -{ - isc_result_t result; - uint32_t n; - char buffer[NUMBERSIZE]; - int v; - - if (! isdigit(source->base[0] & 0xff) || - source->length > NUMBERSIZE - 1) - { - return (ISC_R_BADNUMBER); - } - - /* - * We have a potential number. Try to parse it with - * isc_parse_uint32(). isc_parse_uint32() requires - * null termination, so we must make a copy. - */ - v = snprintf(buffer, sizeof(buffer), "%.*s", - (int)source->length, source->base); - if (v < 0 || (unsigned)v != source->length) { - return (ISC_R_BADNUMBER); - } - INSIST(buffer[source->length] == '\0'); - - result = isc_parse_uint32(&n, buffer, 10); - if (result == ISC_R_BADNUMBER && hex_allowed) { - result = isc_parse_uint32(&n, buffer, 16); - } - if (result != ISC_R_SUCCESS) { - return (result); - } - if (n > max) { - return (ISC_R_RANGE); - } - *valuep = n; - return (ISC_R_SUCCESS); -} - -static isc_result_t -dns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source, - struct tbl *table, unsigned int max) -{ - isc_result_t result; - int i; - - result = maybe_numeric(valuep, source, max, false); - if (result != ISC_R_BADNUMBER) - return (result); - - for (i = 0; table[i].name != NULL; i++) { - unsigned int n; - n = strlen(table[i].name); - if (n == source->length && - (table[i].flags & TOTEXTONLY) == 0 && - strncasecmp(source->base, table[i].name, n) == 0) { - *valuep = table[i].value; - return (ISC_R_SUCCESS); - } - } - return (DNS_R_UNKNOWN); -} - -static isc_result_t -dns_mnemonic_totext(unsigned int value, isc_buffer_t *target, - struct tbl *table) -{ - int i = 0; - char buf[sizeof("4294967296")]; - while (table[i].name != NULL) { - if (table[i].value == value) { - return (str_totext(table[i].name, target)); - } - i++; - } - snprintf(buf, sizeof(buf), "%u", value); - return (str_totext(buf, target)); -} - -isc_result_t -dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, rcodes, 0xffff)); - *rcodep = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) { - return (dns_mnemonic_totext(rcode, target, rcodes)); -} - -isc_result_t -dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, tsigrcodes, 0xffff)); - *rcodep = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target) { - return (dns_mnemonic_totext(rcode, target, tsigrcodes)); -} - -isc_result_t -dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, certs, 0xffff)); - *certp = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) { - return (dns_mnemonic_totext(cert, target, certs)); -} - -isc_result_t -dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) { - unsigned int value; - isc_result_t result; - - result = dns_mnemonic_fromtext(&value, source, - secalgs, 0xff); - if (result != ISC_R_SUCCESS) { - result = dns_mnemonic_fromtext(&value, source, - md5_secalgs, 0xff); - if (result != ISC_R_SUCCESS) { - return (result); - } else if (!isc_md5_available()) { - *secalgp = value; - return (ISC_R_DISABLED); - } - } - *secalgp = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) { - return (dns_mnemonic_totext(secalg, target, secalgs)); -} - -void -dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size) { - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - REQUIRE(cp != NULL && size > 0); - isc_buffer_init(&b, cp, size - 1); - result = dns_secalg_totext(alg, &b); - isc_buffer_usedregion(&b, &r); - r.base[r.length] = 0; - if (result != ISC_R_SUCCESS) { - r.base[0] = 0; - } -} - -isc_result_t -dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, secprotos, 0xff)); - *secprotop = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target) { - return (dns_mnemonic_totext(secproto, target, secprotos)); -} - -isc_result_t -dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, hashalgs, 0xff)); - *hashalg = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source) -{ - isc_result_t result; - char *text, *end; - unsigned int value = 0; -#ifdef notyet - unsigned int mask = 0; -#endif - - result = maybe_numeric(&value, source, 0xffff, true); - if (result == ISC_R_SUCCESS) { - *flagsp = value; - return (ISC_R_SUCCESS); - } - if (result != ISC_R_BADNUMBER) - return (result); - - text = source->base; - end = source->base + source->length; - - while (text < end) { - struct keyflag *p; - unsigned int len; - char *delim = memchr(text, '|', end - text); - if (delim != NULL) - len = (unsigned int)(delim - text); - else - len = (unsigned int)(end - text); - for (p = keyflags; p->name != NULL; p++) { - if (strncasecmp(p->name, text, len) == 0) - break; - } - if (p->name == NULL) - return (DNS_R_UNKNOWNFLAG); - value |= p->value; -#ifdef notyet - if ((mask & p->mask) != 0) - warn("overlapping key flags"); - mask |= p->mask; -#endif - text += len; - if (delim != NULL) - text++; /* Skip "|" */ - } - *flagsp = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dsdigest_fromtext(dns_dsdigest_t *dsdigestp, isc_textregion_t *source) { - unsigned int value; - RETERR(dns_mnemonic_fromtext(&value, source, dsdigests, 0xff)); - *dsdigestp = value; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_dsdigest_totext(dns_dsdigest_t dsdigest, isc_buffer_t *target) { - return (dns_mnemonic_totext(dsdigest, target, dsdigests)); -} - -void -dns_dsdigest_format(dns_dsdigest_t typ, char *cp, unsigned int size) { - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - REQUIRE(cp != NULL && size > 0); - isc_buffer_init(&b, cp, size - 1); - result = dns_dsdigest_totext(typ, &b); - isc_buffer_usedregion(&b, &r); - r.base[r.length] = 0; - if (result != ISC_R_SUCCESS) { - r.base[0] = 0; - } -} - -/* - * This uses lots of hard coded values, but how often do we actually - * add classes? - */ -isc_result_t -dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) { -#define COMPARE(string, rdclass) \ - if (((sizeof(string) - 1) == source->length) \ - && (strncasecmp(source->base, string, source->length) == 0)) { \ - *classp = rdclass; \ - return (ISC_R_SUCCESS); \ - } - - switch (tolower((unsigned char)source->base[0])) { - case 'a': - COMPARE("any", dns_rdataclass_any); - break; - case 'c': - /* - * RFC1035 says the mnemonic for the CHAOS class is CH, - * but historical BIND practice is to call it CHAOS. - * We will accept both forms, but only generate CH. - */ - COMPARE("ch", dns_rdataclass_chaos); - COMPARE("chaos", dns_rdataclass_chaos); - - if (source->length > 5 && - source->length < (5 + sizeof("65000")) && - strncasecmp("class", source->base, 5) == 0) { - char buf[sizeof("65000")]; - char *endp; - unsigned int val; - - /* - * source->base is not required to be NUL terminated. - * Copy up to remaining bytes and NUL terminate. - */ - snprintf(buf, sizeof(buf), "%.*s", - (int)(source->length - 5), source->base + 5); - val = strtoul(buf, &endp, 10); - if (*endp == '\0' && val <= 0xffff) { - *classp = (dns_rdataclass_t)val; - return (ISC_R_SUCCESS); - } - } - break; - case 'h': - COMPARE("hs", dns_rdataclass_hs); - COMPARE("hesiod", dns_rdataclass_hs); - break; - case 'i': - COMPARE("in", dns_rdataclass_in); - break; - case 'n': - COMPARE("none", dns_rdataclass_none); - break; - case 'r': - COMPARE("reserved0", dns_rdataclass_reserved0); - break; - } - -#undef COMPARE - - return (DNS_R_UNKNOWN); -} - -isc_result_t -dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) { - switch (rdclass) { - case dns_rdataclass_any: - return (str_totext("ANY", target)); - case dns_rdataclass_chaos: - return (str_totext("CH", target)); - case dns_rdataclass_hs: - return (str_totext("HS", target)); - case dns_rdataclass_in: - return (str_totext("IN", target)); - case dns_rdataclass_none: - return (str_totext("NONE", target)); - case dns_rdataclass_reserved0: - return (str_totext("RESERVED0", target)); - default: - return (dns_rdataclass_tounknowntext(rdclass, target)); - } -} - -isc_result_t -dns_rdataclass_tounknowntext(dns_rdataclass_t rdclass, isc_buffer_t *target) { - char buf[sizeof("CLASS65535")]; - - snprintf(buf, sizeof(buf), "CLASS%u", rdclass); - return (str_totext(buf, target)); -} - -void -dns_rdataclass_format(dns_rdataclass_t rdclass, - char *array, unsigned int size) -{ - isc_result_t result; - isc_buffer_t buf; - - if (size == 0U) - return; - - isc_buffer_init(&buf, array, size); - result = dns_rdataclass_totext(rdclass, &buf); - /* - * Null terminate. - */ - if (result == ISC_R_SUCCESS) { - if (isc_buffer_availablelength(&buf) >= 1) - isc_buffer_putuint8(&buf, 0); - else - result = ISC_R_NOSPACE; - } - if (result != ISC_R_SUCCESS) - strlcpy(array, "", size); -} diff --git a/lib/dns-pkcs11/rdata.c b/lib/dns-pkcs11/rdata.c deleted file mode 100644 index bccacde..0000000 --- a/lib/dns-pkcs11/rdata.c +++ /dev/null @@ -1,2187 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define RETERR(x) \ - do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -#define RETTOK(x) \ - do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) { \ - isc_lex_ungettoken(lexer, &token); \ - return (_r); \ - } \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -#define CHECKTOK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_lex_ungettoken(lexer, &token); \ - goto cleanup; \ - } \ - } while (0) - -#define DNS_AS_STR(t) ((t).value.as_textregion.base) - -#define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \ - isc_lex_t *lexer, dns_name_t *origin, \ - unsigned int options, isc_buffer_t *target, \ - dns_rdatacallbacks_t *callbacks - -#define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \ - isc_buffer_t *target - -#define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \ - isc_buffer_t *source, dns_decompress_t *dctx, \ - unsigned int options, isc_buffer_t *target - -#define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \ - isc_buffer_t *target - -#define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2 - -#define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \ - void *source, isc_buffer_t *target - -#define ARGS_TOSTRUCT const dns_rdata_t *rdata, void *target, isc_mem_t *mctx - -#define ARGS_FREESTRUCT void *source - -#define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \ - void *arg - -#define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg - -#define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \ - dns_rdatatype_t type, bool wildcard - -#define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad - - -/*% - * Context structure for the totext_ functions. - * Contains formatting options for rdata-to-text - * conversion. - */ -typedef struct dns_rdata_textctx { - dns_name_t *origin; /*%< Current origin, or NULL. */ - unsigned int flags; /*%< DNS_STYLEFLAG_* */ - unsigned int width; /*%< Width of rdata column. */ - const char *linebreak; /*%< Line break string. */ -} dns_rdata_textctx_t; - -static isc_result_t -txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target); - -static isc_result_t -txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); - -static isc_result_t -txt_fromwire(isc_buffer_t *source, isc_buffer_t *target); - -static isc_result_t -multitxt_totext(isc_region_t *source, isc_buffer_t *target); - -static isc_result_t -multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target); - -static bool -name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); - -static unsigned int -name_length(dns_name_t *name); - -static isc_result_t -str_totext(const char *source, isc_buffer_t *target); - -static isc_result_t -inet_totext(int af, uint32_t flags, isc_region_t *src, isc_buffer_t *target); - -static bool -buffer_empty(isc_buffer_t *source); - -static void -buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region); - -static isc_result_t -uint32_tobuffer(uint32_t, isc_buffer_t *target); - -static isc_result_t -uint16_tobuffer(uint32_t, isc_buffer_t *target); - -static isc_result_t -uint8_tobuffer(uint32_t, isc_buffer_t *target); - -static isc_result_t -name_tobuffer(dns_name_t *name, isc_buffer_t *target); - -static uint32_t -uint32_fromregion(isc_region_t *region); - -static uint16_t -uint16_fromregion(isc_region_t *region); - -static uint8_t -uint8_fromregion(isc_region_t *region); - -static uint8_t -uint8_consume_fromregion(isc_region_t *region); - -static isc_result_t -mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); - -static int -hexvalue(char value); - -static int -decvalue(char value); - -static void -default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...) - ISC_FORMAT_PRINTF(2, 3); - -static void -fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), - dns_rdatacallbacks_t *callbacks, const char *name, - unsigned long line, isc_token_t *token, isc_result_t result); - -static void -fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); - -static isc_result_t -rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, - isc_buffer_t *target); - -static void -warn_badname(dns_name_t *name, isc_lex_t *lexer, - dns_rdatacallbacks_t *callbacks); - -static void -warn_badmx(isc_token_t *token, isc_lex_t *lexer, - dns_rdatacallbacks_t *callbacks); - -static uint16_t -uint16_consume_fromregion(isc_region_t *region); - -static isc_result_t -unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, - isc_buffer_t *target); - -static inline isc_result_t -generic_fromtext_key(ARGS_FROMTEXT); - -static inline isc_result_t -generic_totext_key(ARGS_TOTEXT); - -static inline isc_result_t -generic_fromwire_key(ARGS_FROMWIRE); - -static inline isc_result_t -generic_fromstruct_key(ARGS_FROMSTRUCT); - -static inline isc_result_t -generic_tostruct_key(ARGS_TOSTRUCT); - -static inline void -generic_freestruct_key(ARGS_FREESTRUCT); - -static isc_result_t -generic_fromtext_txt(ARGS_FROMTEXT); - -static isc_result_t -generic_totext_txt(ARGS_TOTEXT); - -static isc_result_t -generic_fromwire_txt(ARGS_FROMWIRE); - -static isc_result_t -generic_fromstruct_txt(ARGS_FROMSTRUCT); - -static isc_result_t -generic_tostruct_txt(ARGS_TOSTRUCT); - -static void -generic_freestruct_txt(ARGS_FREESTRUCT); - -static isc_result_t -generic_txt_first(dns_rdata_txt_t *txt); - -static isc_result_t -generic_txt_next(dns_rdata_txt_t *txt); - -static isc_result_t -generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string); - -static isc_result_t -generic_totext_ds(ARGS_TOTEXT); - -static isc_result_t -generic_tostruct_ds(ARGS_TOSTRUCT); - -static isc_result_t -generic_fromtext_ds(ARGS_FROMTEXT); - -static isc_result_t -generic_fromwire_ds(ARGS_FROMWIRE); - -static isc_result_t -generic_fromstruct_ds(ARGS_FROMSTRUCT); - -static isc_result_t -generic_fromtext_tlsa(ARGS_FROMTEXT); - -static isc_result_t -generic_totext_tlsa(ARGS_TOTEXT); - -static isc_result_t -generic_fromwire_tlsa(ARGS_FROMWIRE); - -static isc_result_t -generic_fromstruct_tlsa(ARGS_FROMSTRUCT); - -static isc_result_t -generic_tostruct_tlsa(ARGS_TOSTRUCT); - -static void -generic_freestruct_tlsa(ARGS_FREESTRUCT); - -/*% INT16 Size */ -#define NS_INT16SZ 2 -/*% IPv6 Address Size */ -#define NS_LOCATORSZ 8 - -/* - * Active Directory gc._msdcs. prefix. - */ -static unsigned char gc_msdcs_data[] = "\002gc\006_msdcs"; -static unsigned char gc_msdcs_offset [] = { 0, 3 }; - -static dns_name_t const gc_msdcs = - DNS_NAME_INITNONABSOLUTE(gc_msdcs_data, gc_msdcs_offset); - -/*% - * convert presentation level address to network order binary form. - * \return - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * \note - * (1) does not touch `dst' unless it's returning 1. - */ -static inline int -locator_pton(const char *src, unsigned char *dst) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[NS_LOCATORSZ]; - unsigned char *tp = tmp, *endp; - const char *xdigits; - int ch, seen_xdigits; - unsigned int val; - - memset(tp, '\0', NS_LOCATORSZ); - endp = tp + NS_LOCATORSZ; - seen_xdigits = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - pch = strchr((xdigits = xdigits_l), ch); - if (pch == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (++seen_xdigits > 4) - return (0); - continue; - } - if (ch == ':') { - if (!seen_xdigits) - return (0); - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - seen_xdigits = 0; - val = 0; - continue; - } - return (0); - } - if (seen_xdigits) { - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (tp != endp) - return (0); - memmove(dst, tmp, NS_LOCATORSZ); - return (1); -} - -static inline int -getquad(const void *src, struct in_addr *dst, - isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) -{ - int result; - struct in_addr tmp; - - result = inet_aton(src, dst); - if (result == 1 && callbacks != NULL && - inet_pton(AF_INET, src, &tmp) != 1) { - const char *name = isc_lex_getsourcename(lexer); - if (name == NULL) - name = "UNKNOWN"; - (*callbacks->warn)(callbacks, "%s:%lu: \"%s\" " - "is not a decimal dotted quad", name, - isc_lex_getsourceline(lexer), src); - } - return (result); -} - -static inline isc_result_t -name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { - - if (mctx != NULL) - return (dns_name_dup(source, mctx, target)); - dns_name_clone(source, target); - return (ISC_R_SUCCESS); -} - -static inline void * -mem_maybedup(isc_mem_t *mctx, void *source, size_t length) { - void *copy; - - if (mctx == NULL) - return (source); - copy = isc_mem_allocate(mctx, length); - if (copy != NULL) - memmove(copy, source, length); - - return (copy); -} - -static inline isc_result_t -typemap_fromtext(isc_lex_t *lexer, isc_buffer_t *target, - bool allow_empty) -{ - isc_token_t token; - unsigned char bm[8*1024]; /* 64k bits */ - dns_rdatatype_t covered, max_used; - int octet; - unsigned int max_octet, newend, end; - int window; - bool first = true; - - max_used = 0; - bm[0] = 0; - end = 0; - - do { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, true)); - if (token.type != isc_tokentype_string) - break; - RETTOK(dns_rdatatype_fromtext(&covered, - &token.value.as_textregion)); - if (covered > max_used) { - newend = covered / 8; - if (newend > end) { - memset(&bm[end + 1], 0, newend - end); - end = newend; - } - max_used = covered; - } - bm[covered/8] |= (0x80>>(covered%8)); - first = false; - } while (1); - isc_lex_ungettoken(lexer, &token); - if (!allow_empty && first) - return (DNS_R_FORMERR); - - for (window = 0; window < 256 ; window++) { - if (max_used < window * 256) - break; - - max_octet = max_used - (window * 256); - if (max_octet >= 256) - max_octet = 31; - else - max_octet /= 8; - - /* - * Find if we have a type in this window. - */ - for (octet = max_octet; octet >= 0; octet--) { - if (bm[window * 32 + octet] != 0) - break; - } - if (octet < 0) - continue; - RETERR(uint8_tobuffer(window, target)); - RETERR(uint8_tobuffer(octet + 1, target)); - RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -typemap_totext(isc_region_t *sr, dns_rdata_textctx_t *tctx, - isc_buffer_t *target) -{ - unsigned int i, j, k; - unsigned int window, len; - bool first = true; - - for (i = 0; i < sr->length; i += len) { - if (tctx != NULL && - (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext(tctx->linebreak, target)); - first = true; - } - INSIST(i + 2 <= sr->length); - window = sr->base[i]; - len = sr->base[i + 1]; - INSIST(len > 0 && len <= 32); - i += 2; - INSIST(i + len <= sr->length); - for (j = 0; j < len; j++) { - dns_rdatatype_t t; - if (sr->base[i + j] == 0) - continue; - for (k = 0; k < 8; k++) { - if ((sr->base[i + j] & (0x80 >> k)) == 0) - continue; - t = window * 256 + j * 8 + k; - if (!first) - RETERR(str_totext(" ", target)); - first = false; - if (dns_rdatatype_isknown(t)) { - RETERR(dns_rdatatype_totext(t, target)); - } else { - char buf[sizeof("TYPE65535")]; - snprintf(buf, sizeof(buf), "TYPE%u", t); - RETERR(str_totext(buf, target)); - } - } - } - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -typemap_test(isc_region_t *sr, bool allow_empty) { - unsigned int window, lastwindow = 0; - unsigned int len; - bool first = true; - unsigned int i; - - for (i = 0; i < sr->length; i += len) { - /* - * Check for overflow. - */ - if (i + 2 > sr->length) - RETERR(DNS_R_FORMERR); - window = sr->base[i]; - len = sr->base[i + 1]; - i += 2; - /* - * Check that bitmap windows are in the correct order. - */ - if (!first && window <= lastwindow) - RETERR(DNS_R_FORMERR); - /* - * Check for legal lengths. - */ - if (len < 1 || len > 32) - RETERR(DNS_R_FORMERR); - /* - * Check for overflow. - */ - if (i + len > sr->length) - RETERR(DNS_R_FORMERR); - /* - * The last octet of the bitmap must be non zero. - */ - if (sr->base[i + len - 1] == 0) - RETERR(DNS_R_FORMERR); - lastwindow = window; - first = false; - } - if (i != sr->length) - return (DNS_R_EXTRADATA); - if (!allow_empty && first) - RETERR(DNS_R_FORMERR); - return (ISC_R_SUCCESS); -} - -static const char hexdigits[] = "0123456789abcdef"; -static const char decdigits[] = "0123456789"; - -#include "code.h" - -#define META 0x0001 -#define RESERVED 0x0002 - -/*** - *** Initialization - ***/ - -void -dns_rdata_init(dns_rdata_t *rdata) { - - REQUIRE(rdata != NULL); - - rdata->data = NULL; - rdata->length = 0; - rdata->rdclass = 0; - rdata->type = 0; - rdata->flags = 0; - ISC_LINK_INIT(rdata, link); - /* ISC_LIST_INIT(rdata->list); */ -} - -void -dns_rdata_reset(dns_rdata_t *rdata) { - - REQUIRE(rdata != NULL); - - REQUIRE(!ISC_LINK_LINKED(rdata, link)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - rdata->data = NULL; - rdata->length = 0; - rdata->rdclass = 0; - rdata->type = 0; - rdata->flags = 0; -} - -/*** - *** - ***/ - -void -dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) { - - REQUIRE(src != NULL); - REQUIRE(target != NULL); - - REQUIRE(DNS_RDATA_INITIALIZED(target)); - - REQUIRE(DNS_RDATA_VALIDFLAGS(src)); - REQUIRE(DNS_RDATA_VALIDFLAGS(target)); - - target->data = src->data; - target->length = src->length; - target->rdclass = src->rdclass; - target->type = src->type; - target->flags = src->flags; -} - - -/*** - *** Comparisons - ***/ - -int -dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { - int result = 0; - bool use_default = false; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->length == 0 || rdata1->data != NULL); - REQUIRE(rdata2->length == 0 || rdata2->data != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); - - if (rdata1->rdclass != rdata2->rdclass) - return (rdata1->rdclass < rdata2->rdclass ? -1 : 1); - - if (rdata1->type != rdata2->type) - return (rdata1->type < rdata2->type ? -1 : 1); - - COMPARESWITCH - - if (use_default) { - isc_region_t r1; - isc_region_t r2; - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - result = isc_region_compare(&r1, &r2); - } - return (result); -} - -int -dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { - int result = 0; - bool use_default = false; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->length == 0 || rdata1->data != NULL); - REQUIRE(rdata2->length == 0 || rdata2->data != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); - - if (rdata1->rdclass != rdata2->rdclass) - return (rdata1->rdclass < rdata2->rdclass ? -1 : 1); - - if (rdata1->type != rdata2->type) - return (rdata1->type < rdata2->type ? -1 : 1); - - CASECOMPARESWITCH - - if (use_default) { - isc_region_t r1; - isc_region_t r2; - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - result = isc_region_compare(&r1, &r2); - } - return (result); -} - -/*** - *** Conversions - ***/ - -void -dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_region_t *r) -{ - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - REQUIRE(r != NULL); - - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - rdata->data = r->base; - rdata->length = r->length; - rdata->rdclass = rdclass; - rdata->type = type; - rdata->flags = 0; -} - -void -dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) { - - REQUIRE(rdata != NULL); - REQUIRE(r != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - r->base = rdata->data; - r->length = rdata->length; -} - -isc_result_t -dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_buffer_t *source, - dns_decompress_t *dctx, unsigned int options, - isc_buffer_t *target) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - isc_region_t region; - isc_buffer_t ss; - isc_buffer_t st; - bool use_default = false; - uint32_t activelength; - unsigned int length; - - REQUIRE(dctx != NULL); - if (rdata != NULL) { - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - } - REQUIRE(source != NULL); - REQUIRE(target != NULL); - - if (type == 0) - return (DNS_R_FORMERR); - - ss = *source; - st = *target; - - activelength = isc_buffer_activelength(source); - INSIST(activelength < 65536); - - FROMWIRESWITCH - - if (use_default) { - if (activelength > isc_buffer_availablelength(target)) - result = ISC_R_NOSPACE; - else { - isc_buffer_putmem(target, isc_buffer_current(source), - activelength); - isc_buffer_forward(source, activelength); - result = ISC_R_SUCCESS; - } - } - - /* - * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH - * as we cannot transmit it. - */ - length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); - if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) - result = DNS_R_FORMERR; - - /* - * We should have consumed all of our buffer. - */ - if (result == ISC_R_SUCCESS && !buffer_empty(source)) - result = DNS_R_EXTRADATA; - - if (rdata != NULL && result == ISC_R_SUCCESS) { - region.base = isc_buffer_used(&st); - region.length = length; - dns_rdata_fromregion(rdata, rdclass, type, ®ion); - } - - if (result != ISC_R_SUCCESS) { - *source = ss; - *target = st; - } - return (result); -} - -isc_result_t -dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, - isc_buffer_t *target) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - bool use_default = false; - isc_region_t tr; - isc_buffer_t st; - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - /* - * Some DynDNS meta-RRs have empty rdata. - */ - if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { - INSIST(rdata->length == 0); - return (ISC_R_SUCCESS); - } - - st = *target; - - TOWIRESWITCH - - if (use_default) { - isc_buffer_availableregion(target, &tr); - if (tr.length < rdata->length) - return (ISC_R_NOSPACE); - memmove(tr.base, rdata->data, rdata->length); - isc_buffer_add(target, rdata->length); - return (ISC_R_SUCCESS); - } - if (result != ISC_R_SUCCESS) { - *target = st; - INSIST(target->used < 65536); - dns_compress_rollback(cctx, (uint16_t)target->used); - } - return (result); -} - -/* - * If the binary data in 'src' is valid uncompressed wire format - * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS - * and copy the validated rdata to 'dest'. Otherwise return an error. - */ -static isc_result_t -rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass, - dns_rdatatype_t type) -{ - dns_decompress_t dctx; - isc_result_t result; - - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); - isc_buffer_setactive(src, isc_buffer_usedlength(src)); - result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest); - dns_decompress_invalidate(&dctx); - - return (result); -} - -static isc_result_t -unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, - isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target) -{ - isc_result_t result; - isc_buffer_t *buf = NULL; - isc_token_t token; - - if (type == 0 || dns_rdatatype_ismeta(type)) - return (DNS_R_METATYPE); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 65535U) - return (ISC_R_RANGE); - result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong); - if (result != ISC_R_SUCCESS) - return (result); - - if (token.value.as_ulong != 0U) { - result = isc_hex_tobuffer(lexer, buf, - (unsigned int)token.value.as_ulong); - if (result != ISC_R_SUCCESS) { - goto failure; - } - if (isc_buffer_usedlength(buf) != token.value.as_ulong) { - result = ISC_R_UNEXPECTEDEND; - goto failure; - } - } - - if (dns_rdatatype_isknown(type)) { - result = rdata_validate(buf, target, rdclass, type); - } else { - isc_region_t r; - isc_buffer_usedregion(buf, &r); - result = isc_buffer_copyregion(target, &r); - } - if (result != ISC_R_SUCCESS) - goto failure; - - isc_buffer_free(&buf); - return (ISC_R_SUCCESS); - - failure: - isc_buffer_free(&buf); - return (result); -} - -isc_result_t -dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, isc_lex_t *lexer, - dns_name_t *origin, unsigned int options, isc_mem_t *mctx, - isc_buffer_t *target, dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - isc_region_t region; - isc_buffer_t st; - isc_token_t token; - unsigned int lexoptions = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | - ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; - char *name; - unsigned long line; - void (*callback)(dns_rdatacallbacks_t *, const char *, ...); - isc_result_t tresult; - unsigned int length; - bool unknown; - - REQUIRE(origin == NULL || dns_name_isabsolute(origin) == true); - if (rdata != NULL) { - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - } - if (callbacks != NULL) { - REQUIRE(callbacks->warn != NULL); - REQUIRE(callbacks->error != NULL); - } - - st = *target; - - if (callbacks != NULL) - callback = callbacks->error; - else - callback = default_fromtext_callback; - - result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - true); - if (result != ISC_R_SUCCESS) { - name = isc_lex_getsourcename(lexer); - line = isc_lex_getsourceline(lexer); - fromtext_error(callback, callbacks, name, line, NULL, result); - return (result); - } - - unknown = false; - if (token.type == isc_tokentype_string && - strcmp(DNS_AS_STR(token), "\\#") == 0) { - /* - * If this is a TXT record '\#' could be a escaped '#'. - * Look to see if the next token is a number and if so - * treat it as a unknown record format. - */ - if (type == dns_rdatatype_txt) { - result = isc_lex_getmastertoken(lexer, &token, - isc_tokentype_number, - false); - if (result == ISC_R_SUCCESS) - isc_lex_ungettoken(lexer, &token); - } - - if (result == ISC_R_SUCCESS) { - unknown = true; - result = unknown_fromtext(rdclass, type, lexer, - mctx, target); - } else - options |= DNS_RDATA_UNKNOWNESCAPE; - } else - isc_lex_ungettoken(lexer, &token); - - if (!unknown) - FROMTEXTSWITCH - - /* - * Consume to end of line / file. - * If not at end of line initially set error code. - * Call callback via fromtext_error once if there was an error. - */ - do { - name = isc_lex_getsourcename(lexer); - line = isc_lex_getsourceline(lexer); - tresult = isc_lex_gettoken(lexer, lexoptions, &token); - if (tresult != ISC_R_SUCCESS) { - if (result == ISC_R_SUCCESS) - result = tresult; - if (callback != NULL) - fromtext_error(callback, callbacks, name, - line, NULL, result); - break; - } else if (token.type != isc_tokentype_eol && - token.type != isc_tokentype_eof) { - if (result == ISC_R_SUCCESS) - result = DNS_R_EXTRATOKEN; - if (callback != NULL) { - fromtext_error(callback, callbacks, name, - line, &token, result); - callback = NULL; - } - } else if (result != ISC_R_SUCCESS && callback != NULL) { - fromtext_error(callback, callbacks, name, line, - &token, result); - break; - } else { - if (token.type == isc_tokentype_eof) - fromtext_warneof(lexer, callbacks); - break; - } - } while (1); - - length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); - if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) - result = ISC_R_NOSPACE; - - if (rdata != NULL && result == ISC_R_SUCCESS) { - region.base = isc_buffer_used(&st); - region.length = length; - dns_rdata_fromregion(rdata, rdclass, type, ®ion); - } - if (result != ISC_R_SUCCESS) { - *target = st; - } - return (result); -} - -static isc_result_t -unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, - isc_buffer_t *target) -{ - isc_result_t result; - char buf[sizeof("65535")]; - isc_region_t sr; - - strlcpy(buf, "\\# ", sizeof(buf)); - result = str_totext(buf, target); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdata_toregion(rdata, &sr); - INSIST(sr.length < 65536); - snprintf(buf, sizeof(buf), "%u", sr.length); - result = str_totext(buf, target); - if (result != ISC_R_SUCCESS) - return (result); - - if (sr.length != 0U) { - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - result = str_totext(" ( ", target); - else - result = str_totext(" ", target); - - if (result != ISC_R_SUCCESS) - return (result); - - if (tctx->width == 0) /* No splitting */ - result = isc_hex_totext(&sr, 0, "", target); - else - result = isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, - target); - if (result == ISC_R_SUCCESS && - (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - result = str_totext(" )", target); - } - return (result); -} - -static isc_result_t -rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, - isc_buffer_t *target) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - bool use_default = false; - unsigned int cur; - - REQUIRE(rdata != NULL); - REQUIRE(tctx->origin == NULL || - dns_name_isabsolute(tctx->origin) == true); - - /* - * Some DynDNS meta-RRs have empty rdata. - */ - if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { - INSIST(rdata->length == 0); - return (ISC_R_SUCCESS); - } - - if ((tctx->flags & DNS_STYLEFLAG_UNKNOWNFORMAT) != 0) - return (unknown_totext(rdata, tctx, target)); - - cur = isc_buffer_usedlength(target); - - TOTEXTSWITCH - - if (use_default || (result == ISC_R_NOTIMPLEMENTED)) { - unsigned int u = isc_buffer_usedlength(target); - - INSIST(u >= cur); - isc_buffer_subtract(target, u - cur); - result = unknown_totext(rdata, tctx, target); - } - - return (result); -} - -isc_result_t -dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) -{ - dns_rdata_textctx_t tctx; - - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - /* - * Set up formatting options for single-line output. - */ - tctx.origin = origin; - tctx.flags = 0; - tctx.width = 60; - tctx.linebreak = " "; - return (rdata_totext(rdata, &tctx, target)); -} - -isc_result_t -dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, - unsigned int flags, unsigned int width, - unsigned int split_width, const char *linebreak, - isc_buffer_t *target) -{ - dns_rdata_textctx_t tctx; - - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - /* - * Set up formatting options for formatted output. - */ - tctx.origin = origin; - tctx.flags = flags; - if (split_width == 0xffffffff) - tctx.width = width; - else - tctx.width = split_width; - - if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) - tctx.linebreak = linebreak; - else { - if (split_width == 0xffffffff) - tctx.width = 60; /* Used for hex word length only. */ - tctx.linebreak = " "; - } - return (rdata_totext(rdata, &tctx, target)); -} - -isc_result_t -dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t type, void *source, - isc_buffer_t *target) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - isc_buffer_t st; - isc_region_t region; - bool use_default = false; - unsigned int length; - - REQUIRE(source != NULL); - if (rdata != NULL) { - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - } - - st = *target; - - FROMSTRUCTSWITCH - - if (use_default) - (void)NULL; - - length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); - if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) - result = ISC_R_NOSPACE; - - if (rdata != NULL && result == ISC_R_SUCCESS) { - region.base = isc_buffer_used(&st); - region.length = length; - dns_rdata_fromregion(rdata, rdclass, type, ®ion); - } - if (result != ISC_R_SUCCESS) - *target = st; - return (result); -} - -isc_result_t -dns_rdata_tostruct(const dns_rdata_t *rdata, void *target, isc_mem_t *mctx) { - isc_result_t result = ISC_R_NOTIMPLEMENTED; - bool use_default = false; - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - TOSTRUCTSWITCH - - if (use_default) - (void)NULL; - - return (result); -} - -void -dns_rdata_freestruct(void *source) { - dns_rdatacommon_t *common; - - REQUIRE(source != NULL); - - common = source; - - FREESTRUCTSWITCH -} - -isc_result_t -dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, - void *arg) -{ - isc_result_t result = ISC_R_NOTIMPLEMENTED; - bool use_default = false; - - /* - * Call 'add' for each name and type from 'rdata' which is subject to - * additional section processing. - */ - - REQUIRE(rdata != NULL); - REQUIRE(add != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - ADDITIONALDATASWITCH - - /* No additional processing for unknown types */ - if (use_default) - result = ISC_R_SUCCESS; - - return (result); -} - -isc_result_t -dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) { - isc_result_t result = ISC_R_NOTIMPLEMENTED; - bool use_default = false; - isc_region_t r; - - /* - * Send 'rdata' in DNSSEC canonical form to 'digest'. - */ - - REQUIRE(rdata != NULL); - REQUIRE(digest != NULL); - REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); - - DIGESTSWITCH - - if (use_default) { - dns_rdata_toregion(rdata, &r); - result = (digest)(arg, &r); - } - - return (result); -} - -bool -dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass, - dns_rdatatype_t type, bool wildcard) -{ - bool result; - - CHECKOWNERSWITCH - return (result); -} - -bool -dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad) -{ - bool result; - - CHECKNAMESSWITCH - return (result); -} - -unsigned int -dns_rdatatype_attributes(dns_rdatatype_t type) -{ - RDATATYPE_ATTRIBUTE_SW - if (type >= (dns_rdatatype_t)128 && type <= (dns_rdatatype_t)255) { - return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META); - } - return (DNS_RDATATYPEATTR_UNKNOWN); -} - -isc_result_t -dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) { - unsigned int hash; - unsigned int n; - unsigned char a, b; - - n = source->length; - - if (n == 0) - return (DNS_R_UNKNOWN); - - a = tolower((unsigned char)source->base[0]); - b = tolower((unsigned char)source->base[n - 1]); - - hash = ((a + n) * b) % 256; - - /* - * This switch block is inlined via \#define, and will use "return" - * to return a result to the caller if it is a valid (known) - * rdatatype name. - */ - RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep); - - if (source->length > 4 && source->length < (4 + sizeof("65000")) && - strncasecmp("type", source->base, 4) == 0) { - char buf[sizeof("65000")]; - char *endp; - unsigned int val; - - /* - * source->base is not required to be NUL terminated. - * Copy up to remaining bytes and NUL terminate. - */ - snprintf(buf, sizeof(buf), "%.*s", - (int)(source->length - 4), source->base + 4); - val = strtoul(buf, &endp, 10); - if (*endp == '\0' && val <= 0xffff) { - *typep = (dns_rdatatype_t)val; - return (ISC_R_SUCCESS); - } - } - - return (DNS_R_UNKNOWN); -} - -isc_result_t -dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) { - RDATATYPE_TOTEXT_SW - - return (dns_rdatatype_tounknowntext(type, target)); -} - -isc_result_t -dns_rdatatype_tounknowntext(dns_rdatatype_t type, isc_buffer_t *target) { - char buf[sizeof("TYPE65535")]; - - snprintf(buf, sizeof(buf), "TYPE%u", type); - return (str_totext(buf, target)); -} - -void -dns_rdatatype_format(dns_rdatatype_t rdtype, - char *array, unsigned int size) -{ - isc_result_t result; - isc_buffer_t buf; - - if (size == 0U) - return; - - isc_buffer_init(&buf, array, size); - result = dns_rdatatype_totext(rdtype, &buf); - /* - * Null terminate. - */ - if (result == ISC_R_SUCCESS) { - if (isc_buffer_availablelength(&buf) >= 1) - isc_buffer_putuint8(&buf, 0); - else - result = ISC_R_NOSPACE; - } - if (result != ISC_R_SUCCESS) - strlcpy(array, "", size); -} - -/* - * Private function. - */ - -static unsigned int -name_length(dns_name_t *name) { - return (name->length); -} - -static isc_result_t -txt_totext(isc_region_t *source, bool quote, isc_buffer_t *target) { - unsigned int tl; - unsigned int n; - unsigned char *sp; - char *tp; - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - sp = source->base; - tp = (char *)region.base; - tl = region.length; - - n = *sp++; - - REQUIRE(n + 1 <= source->length); - if (n == 0U) - REQUIRE(quote == true); - - if (quote) { - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; - } - while (n--) { - /* - * \DDD space (0x20) if not quoting. - */ - if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { - if (tl < 4) - return (ISC_R_NOSPACE); - *tp++ = 0x5c; - *tp++ = 0x30 + ((*sp / 100) % 10); - *tp++ = 0x30 + ((*sp / 10) % 10); - *tp++ = 0x30 + (*sp % 10); - sp++; - tl -= 4; - continue; - } - /* - * Escape double quote and backslash. If we are not - * enclosing the string in double quotes also escape - * at sign and semicolon. - */ - if (*sp == 0x22 || *sp == 0x5c || - (!quote && (*sp == 0x40 || *sp == 0x3b))) { - if (tl < 2) - return (ISC_R_NOSPACE); - *tp++ = '\\'; - tl--; - } - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = *sp++; - tl--; - } - if (quote) { - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; - POST(tl); - } - isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); - isc_region_consume(source, *source->base + 1); - return (ISC_R_SUCCESS); -} - -static isc_result_t -txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { - isc_region_t tregion; - bool escape; - unsigned int n, nrem; - char *s; - unsigned char *t; - int d; - int c; - - isc_buffer_availableregion(target, &tregion); - s = source->base; - n = source->length; - t = tregion.base; - nrem = tregion.length; - escape = false; - if (nrem < 1) - return (ISC_R_NOSPACE); - /* - * Length byte. - */ - nrem--; - t++; - /* - * Maximum text string length. - */ - if (nrem > 255) - nrem = 255; - while (n-- != 0) { - c = (*s++) & 0xff; - if (escape && (d = decvalue((char)c)) != -1) { - c = d; - if (n == 0) - return (DNS_R_SYNTAX); - n--; - if ((d = decvalue(*s++)) != -1) - c = c * 10 + d; - else - return (DNS_R_SYNTAX); - if (n == 0) - return (DNS_R_SYNTAX); - n--; - if ((d = decvalue(*s++)) != -1) - c = c * 10 + d; - else - return (DNS_R_SYNTAX); - if (c > 255) - return (DNS_R_SYNTAX); - } else if (!escape && c == '\\') { - escape = true; - continue; - } - escape = false; - if (nrem == 0) - return ((tregion.length <= 256U) ? - ISC_R_NOSPACE : DNS_R_SYNTAX); - *t++ = c; - nrem--; - } - if (escape) - return (DNS_R_SYNTAX); - *tregion.base = (unsigned char)(t - tregion.base - 1); - isc_buffer_add(target, *tregion.base + 1); - return (ISC_R_SUCCESS); -} - -static isc_result_t -txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { - unsigned int n; - isc_region_t sregion; - isc_region_t tregion; - - isc_buffer_activeregion(source, &sregion); - if (sregion.length == 0) - return (ISC_R_UNEXPECTEDEND); - n = *sregion.base + 1; - if (n > sregion.length) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_availableregion(target, &tregion); - if (n > tregion.length) - return (ISC_R_NOSPACE); - - if (tregion.base != sregion.base) - memmove(tregion.base, sregion.base, n); - isc_buffer_forward(source, n); - isc_buffer_add(target, n); - return (ISC_R_SUCCESS); -} - -/* - * Conversion of TXT-like rdata fields without length limits. - */ -static isc_result_t -multitxt_totext(isc_region_t *source, isc_buffer_t *target) { - unsigned int tl; - unsigned int n0, n; - unsigned char *sp; - char *tp; - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - sp = source->base; - tp = (char *)region.base; - tl = region.length; - - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; - do { - n = source->length; - n0 = source->length - 1; - - while (n--) { - if (*sp < 0x20 || *sp >= 0x7f) { - if (tl < 4) - return (ISC_R_NOSPACE); - *tp++ = 0x5c; - *tp++ = 0x30 + ((*sp / 100) % 10); - *tp++ = 0x30 + ((*sp / 10) % 10); - *tp++ = 0x30 + (*sp % 10); - sp++; - tl -= 4; - continue; - } - /* double quote, backslash */ - if (*sp == 0x22 || *sp == 0x5c) { - if (tl < 2) - return (ISC_R_NOSPACE); - *tp++ = '\\'; - tl--; - } - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = *sp++; - tl--; - } - isc_region_consume(source, n0 + 1); - } while (source->length != 0); - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; - POST(tl); - isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); - return (ISC_R_SUCCESS); -} - -static isc_result_t -multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { - isc_region_t tregion; - bool escape; - unsigned int n, nrem; - char *s; - unsigned char *t0, *t; - int d; - int c; - - s = source->base; - n = source->length; - escape = false; - - do { - isc_buffer_availableregion(target, &tregion); - t0 = t = tregion.base; - nrem = tregion.length; - if (nrem < 1) - return (ISC_R_NOSPACE); - - while (n != 0) { - --n; - c = (*s++) & 0xff; - if (escape && (d = decvalue((char)c)) != -1) { - c = d; - if (n == 0) - return (DNS_R_SYNTAX); - n--; - if ((d = decvalue(*s++)) != -1) - c = c * 10 + d; - else - return (DNS_R_SYNTAX); - if (n == 0) - return (DNS_R_SYNTAX); - n--; - if ((d = decvalue(*s++)) != -1) - c = c * 10 + d; - else - return (DNS_R_SYNTAX); - if (c > 255) - return (DNS_R_SYNTAX); - } else if (!escape && c == '\\') { - escape = true; - continue; - } - escape = false; - *t++ = c; - nrem--; - if (nrem == 0) - break; - } - if (escape) - return (DNS_R_SYNTAX); - - isc_buffer_add(target, (unsigned int)(t - t0)); - } while (n != 0); - return (ISC_R_SUCCESS); -} - -static bool -name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { - int l1, l2; - - if (origin == NULL) - goto return_false; - - if (dns_name_compare(origin, dns_rootname) == 0) - goto return_false; - - if (!dns_name_issubdomain(name, origin)) - goto return_false; - - l1 = dns_name_countlabels(name); - l2 = dns_name_countlabels(origin); - - if (l1 == l2) - goto return_false; - - /* Master files should be case preserving. */ - dns_name_getlabelsequence(name, l1 - l2, l2, target); - if (!dns_name_caseequal(origin, target)) - goto return_false; - - dns_name_getlabelsequence(name, 0, l1 - l2, target); - return (true); - -return_false: - *target = *name; - return (false); -} - -static isc_result_t -str_totext(const char *source, isc_buffer_t *target) { - unsigned int l; - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - l = strlen(source); - - if (l > region.length) - return (ISC_R_NOSPACE); - - memmove(region.base, source, l); - isc_buffer_add(target, l); - return (ISC_R_SUCCESS); -} - -static isc_result_t -inet_totext(int af, uint32_t flags, isc_region_t *src, isc_buffer_t *target) { - char tmpbuf[64]; - - /* Note - inet_ntop doesn't do size checking on its input. */ - if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) - return (ISC_R_NOSPACE); - if (strlen(tmpbuf) > isc_buffer_availablelength(target)) - return (ISC_R_NOSPACE); - isc_buffer_putstr(target, tmpbuf); - - /* - * An IPv6 address ending in "::" breaks YAML - * parsing, so append 0 in that case. - */ - if (af == AF_INET6 && (flags & DNS_STYLEFLAG_YAML) != 0) { - isc_textregion_t tr; - isc_buffer_usedregion(target, (isc_region_t *)&tr); - if (tr.base[tr.length - 1] == ':') { - if (isc_buffer_availablelength(target) == 0) { - return (ISC_R_NOSPACE); - } - isc_buffer_putmem(target, (const unsigned char *)"0", - 1); - } - } - - return (ISC_R_SUCCESS); -} - -static bool -buffer_empty(isc_buffer_t *source) { - return((source->current == source->active) ? true : false); -} - -static void -buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { - isc_buffer_init(buffer, region->base, region->length); - isc_buffer_add(buffer, region->length); - isc_buffer_setactive(buffer, region->length); -} - -static isc_result_t -uint32_tobuffer(uint32_t value, isc_buffer_t *target) { - isc_region_t region; - - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) - return (ISC_R_NOSPACE); - isc_buffer_putuint32(target, value); - return (ISC_R_SUCCESS); -} - -static isc_result_t -uint16_tobuffer(uint32_t value, isc_buffer_t *target) { - isc_region_t region; - - if (value > 0xffff) - return (ISC_R_RANGE); - isc_buffer_availableregion(target, ®ion); - if (region.length < 2) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(target, (uint16_t)value); - return (ISC_R_SUCCESS); -} - -static isc_result_t -uint8_tobuffer(uint32_t value, isc_buffer_t *target) { - isc_region_t region; - - if (value > 0xff) - return (ISC_R_RANGE); - isc_buffer_availableregion(target, ®ion); - if (region.length < 1) - return (ISC_R_NOSPACE); - isc_buffer_putuint8(target, (uint8_t)value); - return (ISC_R_SUCCESS); -} - -static isc_result_t -name_tobuffer(dns_name_t *name, isc_buffer_t *target) { - isc_region_t r; - dns_name_toregion(name, &r); - return (isc_buffer_copyregion(target, &r)); -} - -static uint32_t -uint32_fromregion(isc_region_t *region) { - uint32_t value; - - REQUIRE(region->length >= 4); - value = (uint32_t)region->base[0] << 24; - value |= (uint32_t)region->base[1] << 16; - value |= (uint32_t)region->base[2] << 8; - value |= (uint32_t)region->base[3]; - return(value); -} - -static uint16_t -uint16_consume_fromregion(isc_region_t *region) { - uint16_t r = uint16_fromregion(region); - - isc_region_consume(region, 2); - return r; -} - -static uint16_t -uint16_fromregion(isc_region_t *region) { - - REQUIRE(region->length >= 2); - - return ((region->base[0] << 8) | region->base[1]); -} - -static uint8_t -uint8_fromregion(isc_region_t *region) { - - REQUIRE(region->length >= 1); - - return (region->base[0]); -} - -static uint8_t -uint8_consume_fromregion(isc_region_t *region) { - uint8_t r = uint8_fromregion(region); - - isc_region_consume(region, 1); - return r; -} - -static isc_result_t -mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { - isc_region_t tr; - - if (length == 0U) - return (ISC_R_SUCCESS); - - isc_buffer_availableregion(target, &tr); - if (length > tr.length) - return (ISC_R_NOSPACE); - if (tr.base != base) - memmove(tr.base, base, length); - isc_buffer_add(target, length); - return (ISC_R_SUCCESS); -} - -static int -hexvalue(char value) { - const char *s; - unsigned char c; - - c = (unsigned char)value; - - if (!isascii(c)) - return (-1); - if (isupper(c)) - c = tolower(c); - if ((s = strchr(hexdigits, c)) == NULL) - return (-1); - return (int)(s - hexdigits); -} - -static int -decvalue(char value) { - const char *s; - - /* - * isascii() is valid for full range of int values, no need to - * mask or cast. - */ - if (!isascii(value)) - return (-1); - if ((s = strchr(decdigits, value)) == NULL) - return (-1); - return (int)(s - decdigits); -} - -static void -default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, - ...) -{ - va_list ap; - - UNUSED(callbacks); - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void -fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { - if (isc_lex_isfile(lexer) && callbacks != NULL) { - const char *name = isc_lex_getsourcename(lexer); - if (name == NULL) - name = "UNKNOWN"; - (*callbacks->warn)(callbacks, - "%s:%lu: file does not end with newline", - name, isc_lex_getsourceline(lexer)); - } -} - -static void -warn_badmx(isc_token_t *token, isc_lex_t *lexer, - dns_rdatacallbacks_t *callbacks) -{ - const char *file; - unsigned long line; - - if (lexer != NULL) { - file = isc_lex_getsourcename(lexer); - line = isc_lex_getsourceline(lexer); - (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s", - file, line, DNS_AS_STR(*token), - dns_result_totext(DNS_R_MXISADDRESS)); - } -} - -static void -warn_badname(dns_name_t *name, isc_lex_t *lexer, - dns_rdatacallbacks_t *callbacks) -{ - const char *file; - unsigned long line; - char namebuf[DNS_NAME_FORMATSIZE]; - - if (lexer != NULL) { - file = isc_lex_getsourcename(lexer); - line = isc_lex_getsourceline(lexer); - dns_name_format(name, namebuf, sizeof(namebuf)); - (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s", - file, line, namebuf, - dns_result_totext(DNS_R_BADNAME)); - } -} - -static void -fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), - dns_rdatacallbacks_t *callbacks, const char *name, - unsigned long line, isc_token_t *token, isc_result_t result) -{ - if (name == NULL) - name = "UNKNOWN"; - - if (token != NULL) { - switch (token->type) { - case isc_tokentype_eol: - (*callback)(callbacks, "%s: %s:%lu: near eol: %s", - "dns_rdata_fromtext", name, line, - dns_result_totext(result)); - break; - case isc_tokentype_eof: - (*callback)(callbacks, "%s: %s:%lu: near eof: %s", - "dns_rdata_fromtext", name, line, - dns_result_totext(result)); - break; - case isc_tokentype_number: - (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", - "dns_rdata_fromtext", name, line, - token->value.as_ulong, - dns_result_totext(result)); - break; - case isc_tokentype_string: - case isc_tokentype_qstring: - (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", - "dns_rdata_fromtext", name, line, - DNS_AS_STR(*token), - dns_result_totext(result)); - break; - default: - (*callback)(callbacks, "%s: %s:%lu: %s", - "dns_rdata_fromtext", name, line, - dns_result_totext(result)); - break; - } - } else { - (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", - name, line, dns_result_totext(result)); - } -} - -dns_rdatatype_t -dns_rdata_covers(dns_rdata_t *rdata) { - if (rdata->type == dns_rdatatype_rrsig) - return (covers_rrsig(rdata)); - return (covers_sig(rdata)); -} - -bool -dns_rdatatype_ismeta(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) - return (true); - return (false); -} - -bool -dns_rdatatype_issingleton(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) - != 0) - return (true); - return (false); -} - -bool -dns_rdatatype_notquestion(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) - != 0) - return (true); - return (false); -} - -bool -dns_rdatatype_questiononly(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) - != 0) - return (true); - return (false); -} - -bool -dns_rdatatype_atcname(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATCNAME) != 0) { - return (true); - } - return (false); -} - -bool -dns_rdatatype_atparent(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) - return (true); - return (false); -} - -bool -dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { - - if (rdclass == dns_rdataclass_reserved0 - || rdclass == dns_rdataclass_none - || rdclass == dns_rdataclass_any) - return (true); - - return (false); /* Assume it is not a meta class. */ -} - -bool -dns_rdatatype_isdnssec(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) - return (true); - return (false); -} - -bool -dns_rdatatype_iszonecutauth(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ZONECUTAUTH) - != 0) - { - return (true); - } - return (false); -} - -bool -dns_rdatatype_isknown(dns_rdatatype_t type) { - if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) - == 0) - return (true); - return (false); -} - -void -dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) { - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - - rdata->data = NULL; - rdata->length = 0; - rdata->flags = DNS_RDATA_UPDATE; - rdata->type = type; - rdata->rdclass = dns_rdataclass_any; -} - -void -dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) { - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - - rdata->data = NULL; - rdata->length = 0; - rdata->flags = DNS_RDATA_UPDATE; - rdata->type = type; - rdata->rdclass = dns_rdataclass_none; -} - -void -dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) { - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - - rdata->data = NULL; - rdata->length = 0; - rdata->flags = DNS_RDATA_UPDATE; - rdata->type = type; - rdata->rdclass = dns_rdataclass_any; -} - -void -dns_rdata_makedelete(dns_rdata_t *rdata) { - REQUIRE(rdata != NULL); - - rdata->rdclass = dns_rdataclass_none; -} - -const char * -dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) { - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - - switch (section) { - case DNS_SECTION_PREREQUISITE: - switch (rdata->rdclass) { - case dns_rdataclass_none: - switch (rdata->type) { - case dns_rdatatype_any: - return ("domain doesn't exist"); - default: - return ("rrset doesn't exist"); - } - case dns_rdataclass_any: - switch (rdata->type) { - case dns_rdatatype_any: - return ("domain exists"); - default: - return ("rrset exists (value independent)"); - } - default: - return ("rrset exists (value dependent)"); - } - case DNS_SECTION_UPDATE: - switch (rdata->rdclass) { - case dns_rdataclass_none: - return ("delete"); - case dns_rdataclass_any: - switch (rdata->type) { - case dns_rdatatype_any: - return ("delete all rrsets"); - default: - return ("delete rrset"); - } - default: - return ("add"); - } - } - return ("invalid"); -} diff --git a/lib/dns-pkcs11/rdata/any_255/tsig_250.c b/lib/dns-pkcs11/rdata/any_255/tsig_250.c deleted file mode 100644 index e43fba8..0000000 --- a/lib/dns-pkcs11/rdata/any_255/tsig_250.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_ANY_255_TSIG_250_C -#define RDATA_ANY_255_TSIG_250_C - -#define RRTYPE_TSIG_ATTRIBUTES \ - (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION) - -static inline isc_result_t -fromtext_any_tsig(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - uint64_t sigtime; - isc_buffer_t buffer; - dns_rcode_t rcode; - long i; - char *e; - - REQUIRE(type == dns_rdatatype_tsig); - REQUIRE(rdclass == dns_rdataclass_any); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Algorithm Name. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - /* - * Time Signed: 48 bits. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - sigtime = isc_string_touint64(DNS_AS_STR(token), &e, 10); - if (*e != 0) - RETTOK(DNS_R_SYNTAX); - if ((sigtime >> 48) != 0) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer((uint16_t)(sigtime >> 32), target)); - RETERR(uint32_tobuffer((uint32_t)(sigtime & 0xffffffffU), target)); - - /* - * Fudge. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Signature Size. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Signature. - */ - RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); - - /* - * Original ID. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Error. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) - != ISC_R_SUCCESS) - { - i = strtol(DNS_AS_STR(token), &e, 10); - if (*e != 0) - RETTOK(DNS_R_UNKNOWN); - if (i < 0 || i > 0xffff) - RETTOK(ISC_R_RANGE); - rcode = (dns_rcode_t)i; - } - RETERR(uint16_tobuffer(rcode, target)); - - /* - * Other Len. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Other Data. - */ - return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); -} - -static inline isc_result_t -totext_any_tsig(ARGS_TOTEXT) { - isc_region_t sr; - isc_region_t sigr; - char buf[sizeof(" 281474976710655 ")]; - char *bufp; - dns_name_t name; - dns_name_t prefix; - bool sub; - uint64_t sigtime; - unsigned short n; - - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - /* - * Algorithm Name. - */ - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - dns_name_fromregion(&name, &sr); - sub = name_prefix(&name, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - RETERR(str_totext(" ", target)); - isc_region_consume(&sr, name_length(&name)); - - /* - * Time Signed. - */ - sigtime = ((uint64_t)sr.base[0] << 40) | - ((uint64_t)sr.base[1] << 32) | - ((uint64_t)sr.base[2] << 24) | - ((uint64_t)sr.base[3] << 16) | - ((uint64_t)sr.base[4] << 8) | - (uint64_t)sr.base[5]; - isc_region_consume(&sr, 6); - bufp = &buf[sizeof(buf) - 1]; - *bufp-- = 0; - *bufp-- = ' '; - do { - *bufp-- = decdigits[sigtime % 10]; - sigtime /= 10; - } while (sigtime != 0); - bufp++; - RETERR(str_totext(bufp, target)); - - /* - * Fudge. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Signature Size. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u", n); - RETERR(str_totext(buf, target)); - - /* - * Signature. - */ - if (n != 0U) { - REQUIRE(n <= sr.length); - sigr = sr; - sigr.length = n; - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sigr, 60, "", target)); - else - RETERR(isc_base64_totext(&sigr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ) ", target)); - else - RETERR(str_totext(" ", target)); - isc_region_consume(&sr, n); - } else { - RETERR(str_totext(" ", target)); - } - - /* - * Original ID. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Error. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); - - /* - * Other Size. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), " %u ", n); - RETERR(str_totext(buf, target)); - - /* - * Other. - */ - if (tctx->width == 0) /* No splitting */ - return (isc_base64_totext(&sr, 60, "", target)); - else - return (isc_base64_totext(&sr, 60, " ", target)); -} - -static inline isc_result_t -fromwire_any_tsig(ARGS_FROMWIRE) { - isc_region_t sr; - dns_name_t name; - unsigned long n; - - REQUIRE(type == dns_rdatatype_tsig); - REQUIRE(rdclass == dns_rdataclass_any); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - /* - * Algorithm Name. - */ - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - isc_buffer_activeregion(source, &sr); - /* - * Time Signed + Fudge. - */ - if (sr.length < 8) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 8)); - isc_region_consume(&sr, 8); - isc_buffer_forward(source, 8); - - /* - * Signature Length + Signature. - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - n = uint16_fromregion(&sr); - if (sr.length < n + 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, n + 2)); - isc_region_consume(&sr, n + 2); - isc_buffer_forward(source, n + 2); - - /* - * Original ID + Error. - */ - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - isc_buffer_forward(source, 4); - - /* - * Other Length + Other. - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - n = uint16_fromregion(&sr); - if (sr.length < n + 2) - return (ISC_R_UNEXPECTEDEND); - isc_buffer_forward(source, n + 2); - return (mem_tobuffer(target, sr.base, n + 2)); -} - -static inline isc_result_t -towire_any_tsig(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_rdata_toregion(rdata, &sr); - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - RETERR(dns_name_towire(&name, cctx, target)); - isc_region_consume(&sr, name_length(&name)); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_any_tsig(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_tsig); - REQUIRE(rdata1->rdclass == dns_rdataclass_any); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_any_tsig(ARGS_FROMSTRUCT) { - dns_rdata_any_tsig_t *tsig; - isc_region_t tr; - - REQUIRE(type == dns_rdatatype_tsig); - REQUIRE(rdclass == dns_rdataclass_any); - REQUIRE(((dns_rdata_any_tsig_t *)source) != NULL); - REQUIRE(((dns_rdata_any_tsig_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_any_tsig_t *)source)->common.rdtype == type); - - tsig = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Algorithm Name. - */ - RETERR(name_tobuffer(&tsig->algorithm, target)); - - isc_buffer_availableregion(target, &tr); - if (tr.length < 6 + 2 + 2) - return (ISC_R_NOSPACE); - - /* - * Time Signed: 48 bits. - */ - RETERR(uint16_tobuffer((uint16_t)(tsig->timesigned >> 32), - target)); - RETERR(uint32_tobuffer((uint32_t)(tsig->timesigned & 0xffffffffU), - target)); - - /* - * Fudge. - */ - RETERR(uint16_tobuffer(tsig->fudge, target)); - - /* - * Signature Size. - */ - RETERR(uint16_tobuffer(tsig->siglen, target)); - - /* - * Signature. - */ - RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen)); - - isc_buffer_availableregion(target, &tr); - if (tr.length < 2 + 2 + 2) - return (ISC_R_NOSPACE); - - /* - * Original ID. - */ - RETERR(uint16_tobuffer(tsig->originalid, target)); - - /* - * Error. - */ - RETERR(uint16_tobuffer(tsig->error, target)); - - /* - * Other Len. - */ - RETERR(uint16_tobuffer(tsig->otherlen, target)); - - /* - * Other Data. - */ - return (mem_tobuffer(target, tsig->other, tsig->otherlen)); -} - -static inline isc_result_t -tostruct_any_tsig(ARGS_TOSTRUCT) { - dns_rdata_any_tsig_t *tsig; - dns_name_t alg; - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - REQUIRE(rdata->length != 0); - - tsig = (dns_rdata_any_tsig_t *) target; - tsig->common.rdclass = rdata->rdclass; - tsig->common.rdtype = rdata->type; - ISC_LINK_INIT(&tsig->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Algorithm Name. - */ - dns_name_init(&alg, NULL); - dns_name_fromregion(&alg, &sr); - dns_name_init(&tsig->algorithm, NULL); - RETERR(name_duporclone(&alg, mctx, &tsig->algorithm)); - - isc_region_consume(&sr, name_length(&tsig->algorithm)); - - /* - * Time Signed. - */ - INSIST(sr.length >= 6); - tsig->timesigned = ((uint64_t)sr.base[0] << 40) | - ((uint64_t)sr.base[1] << 32) | - ((uint64_t)sr.base[2] << 24) | - ((uint64_t)sr.base[3] << 16) | - ((uint64_t)sr.base[4] << 8) | - (uint64_t)sr.base[5]; - isc_region_consume(&sr, 6); - - /* - * Fudge. - */ - tsig->fudge = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Signature Size. - */ - tsig->siglen = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Signature. - */ - INSIST(sr.length >= tsig->siglen); - tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen); - if (tsig->signature == NULL) - goto cleanup; - isc_region_consume(&sr, tsig->siglen); - - /* - * Original ID. - */ - tsig->originalid = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Error. - */ - tsig->error = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Other Size. - */ - tsig->otherlen = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Other. - */ - INSIST(sr.length == tsig->otherlen); - tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen); - if (tsig->other == NULL) - goto cleanup; - - tsig->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&tsig->algorithm, tsig->mctx); - if (mctx != NULL && tsig->signature != NULL) - isc_mem_free(mctx, tsig->signature); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_any_tsig(ARGS_FREESTRUCT) { - dns_rdata_any_tsig_t *tsig; - - REQUIRE(((dns_rdata_any_tsig_t *)source) != NULL); - REQUIRE(((dns_rdata_any_tsig_t *)source)->common.rdtype == dns_rdatatype_tsig); - REQUIRE(((dns_rdata_any_tsig_t *)source)->common.rdclass == dns_rdataclass_any); - - tsig = (dns_rdata_any_tsig_t *) source; - - if (tsig->mctx == NULL) - return; - - dns_name_free(&tsig->algorithm, tsig->mctx); - if (tsig->signature != NULL) - isc_mem_free(tsig->mctx, tsig->signature); - if (tsig->other != NULL) - isc_mem_free(tsig->mctx, tsig->other); - tsig->mctx = NULL; -} - -static inline isc_result_t -additionaldata_any_tsig(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_any_tsig(ARGS_DIGEST) { - - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - - UNUSED(rdata); - UNUSED(digest); - UNUSED(arg); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline bool -checkowner_any_tsig(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_tsig); - REQUIRE(rdclass == dns_rdataclass_any); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_any_tsig(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_tsig); - REQUIRE(rdata->rdclass == dns_rdataclass_any); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_any_tsig(ARGS_COMPARE) { - return (compare_any_tsig(rdata1, rdata2)); -} - -#endif /* RDATA_ANY_255_TSIG_250_C */ diff --git a/lib/dns-pkcs11/rdata/any_255/tsig_250.h b/lib/dns-pkcs11/rdata/any_255/tsig_250.h deleted file mode 100644 index 389b181..0000000 --- a/lib/dns-pkcs11/rdata/any_255/tsig_250.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef ANY_255_TSIG_250_H -#define ANY_255_TSIG_250_H 1 - -/*% RFC2845 */ -typedef struct dns_rdata_any_tsig { - dns_rdatacommon_t common; - isc_mem_t * mctx; - dns_name_t algorithm; - uint64_t timesigned; - uint16_t fudge; - uint16_t siglen; - unsigned char * signature; - uint16_t originalid; - uint16_t error; - uint16_t otherlen; - unsigned char * other; -} dns_rdata_any_tsig_t; - -#endif /* ANY_255_TSIG_250_H */ diff --git a/lib/dns-pkcs11/rdata/ch_3/a_1.c b/lib/dns-pkcs11/rdata/ch_3/a_1.c deleted file mode 100644 index ea69ae5..0000000 --- a/lib/dns-pkcs11/rdata/ch_3/a_1.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* by Bjorn.Victor@it.uu.se, 2005-05-07 */ -/* Based on generic/soa_6.c and generic/mx_15.c */ - -#ifndef RDATA_CH_3_A_1_C -#define RDATA_CH_3_A_1_C - -#include - -#define RRTYPE_A_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_ch_a(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */ - - UNUSED(type); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - /* get domain name */ - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - if ((options & DNS_RDATA_CHECKNAMES) != 0 && - (options & DNS_RDATA_CHECKREVERSE) != 0) { - bool ok; - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - } - - /* 16-bit octal address */ - RETERR(isc_lex_getoctaltoken(lexer, &token, false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - return (uint16_tobuffer(token.value.as_ulong, target)); -} - -static inline isc_result_t -totext_ch_a(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("0177777")]; - uint16_t addr; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */ - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - addr = uint16_fromregion(®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - snprintf(buf, sizeof(buf), "%o", addr); /* note octal */ - RETERR(str_totext(" ", target)); - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_ch_a(ARGS_FROMWIRE) { - isc_region_t sregion; - isc_region_t tregion; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_ch); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - if (tregion.length < 2) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 2); - isc_buffer_forward(source, 2); - isc_buffer_add(target, 2); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_ch_a(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - - dns_rdata_toregion(rdata, &sregion); - - dns_name_fromregion(&name, &sregion); - isc_region_consume(&sregion, name_length(&name)); - RETERR(dns_name_towire(&name, cctx, target)); - - isc_buffer_availableregion(target, &tregion); - if (tregion.length < 2) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 2); - isc_buffer_add(target, 2); - return (ISC_R_SUCCESS); -} - -static inline int -compare_ch_a(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_a); - REQUIRE(rdata1->rdclass == dns_rdataclass_ch); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - order = memcmp(region1.base, region2.base, 2); - if (order != 0) - order = (order < 0) ? -1 : 1; - return (order); -} - -static inline isc_result_t -fromstruct_ch_a(ARGS_FROMSTRUCT) { - dns_rdata_ch_a_t *a; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(((dns_rdata_ch_a_t *)source) != NULL); - REQUIRE(((dns_rdata_ch_a_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_ch_a_t *)source)->common.rdclass == rdclass); - - a = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&a->ch_addr_dom, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - - return (uint16_tobuffer(ntohs(a->ch_addr), target)); -} - -static inline isc_result_t -tostruct_ch_a(ARGS_TOSTRUCT) { - dns_rdata_ch_a_t *a; - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); - REQUIRE(rdata->length != 0); - - a = target; - - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - - dns_name_init(&a->ch_addr_dom, NULL); - RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom)); - a->ch_addr = htons(uint16_fromregion(®ion)); - a->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_ch_a(ARGS_FREESTRUCT) { - dns_rdata_ch_a_t *a; - - REQUIRE(((dns_rdata_ch_a_t *)source) != NULL); - REQUIRE(((dns_rdata_ch_a_t *)source)->common.rdtype == dns_rdatatype_a); - - a = source; - - if (a->mctx == NULL) - return; - - dns_name_free(&a->ch_addr_dom, a->mctx); - a->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ch_a(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ch_a(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - isc_region_consume(&r, name_length(&name)); - RETERR(dns_name_digest(&name, digest, arg)); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_ch_a(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_ch); - - UNUSED(type); - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_ch_a(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_ch); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - - return (true); -} - -static inline int -casecompare_ch_a(ARGS_COMPARE) { - return (compare_ch_a(rdata1, rdata2)); -} -#endif /* RDATA_CH_3_A_1_C */ diff --git a/lib/dns-pkcs11/rdata/ch_3/a_1.h b/lib/dns-pkcs11/rdata/ch_3/a_1.h deleted file mode 100644 index 9df0512..0000000 --- a/lib/dns-pkcs11/rdata/ch_3/a_1.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* by Bjorn.Victor@it.uu.se, 2005-05-07 */ -/* Based on generic/mx_15.h */ - -#ifndef CH_3_A_1_H -#define CH_3_A_1_H 1 - -typedef uint16_t ch_addr_t; - -typedef struct dns_rdata_ch_a { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t ch_addr_dom; /* ch-addr domain for back mapping */ - ch_addr_t ch_addr; /* chaos address (16 bit) network order */ -} dns_rdata_ch_a_t; - -#endif /* CH_3_A_1_H */ diff --git a/lib/dns-pkcs11/rdata/generic/afsdb_18.c b/lib/dns-pkcs11/rdata/generic/afsdb_18.c deleted file mode 100644 index 64ca534..0000000 --- a/lib/dns-pkcs11/rdata/generic/afsdb_18.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1183 */ - -#ifndef RDATA_GENERIC_AFSDB_18_C -#define RDATA_GENERIC_AFSDB_18_C - -#define RRTYPE_AFSDB_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_afsdb(ARGS_FROMTEXT) { - isc_token_t token; - isc_buffer_t buffer; - dns_name_t name; - bool ok; - - REQUIRE(type == dns_rdatatype_afsdb); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Subtype. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Hostname. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_afsdb(ARGS_TOTEXT) { - dns_name_t name; - dns_name_t prefix; - isc_region_t region; - char buf[sizeof("64000 ")]; - bool sub; - unsigned int num; - - REQUIRE(rdata->type == dns_rdatatype_afsdb); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u ", num); - RETERR(str_totext(buf, target)); - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_afsdb(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sr; - isc_region_t tr; - - REQUIRE(type == dns_rdatatype_afsdb); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, &sr); - isc_buffer_availableregion(target, &tr); - if (tr.length < 2) - return (ISC_R_NOSPACE); - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - memmove(tr.base, sr.base, 2); - isc_buffer_forward(source, 2); - isc_buffer_add(target, 2); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_afsdb(ARGS_TOWIRE) { - isc_region_t tr; - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_afsdb); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - isc_buffer_availableregion(target, &tr); - dns_rdata_toregion(rdata, &sr); - if (tr.length < 2) - return (ISC_R_NOSPACE); - memmove(tr.base, sr.base, 2); - isc_region_consume(&sr, 2); - isc_buffer_add(target, 2); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_afsdb(ARGS_COMPARE) { - int result; - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_afsdb); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - result = memcmp(rdata1->data, rdata2->data, 2); - if (result != 0) - return (result < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_afsdb(ARGS_FROMSTRUCT) { - dns_rdata_afsdb_t *afsdb; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_afsdb); - REQUIRE(((dns_rdata_afsdb_t *)source) != NULL); - REQUIRE(((dns_rdata_afsdb_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_afsdb_t *)source)->common.rdtype == type); - - afsdb = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(afsdb->subtype, target)); - dns_name_toregion(&afsdb->server, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_afsdb(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_afsdb_t *afsdb; - dns_name_t name; - - REQUIRE(((dns_rdata_afsdb_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_afsdb); - REQUIRE(rdata->length != 0); - - afsdb = target; - - afsdb->common.rdclass = rdata->rdclass; - afsdb->common.rdtype = rdata->type; - ISC_LINK_INIT(&afsdb->common, link); - - dns_name_init(&afsdb->server, NULL); - - dns_rdata_toregion(rdata, ®ion); - - afsdb->subtype = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - - RETERR(name_duporclone(&name, mctx, &afsdb->server)); - afsdb->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_afsdb(ARGS_FREESTRUCT) { - dns_rdata_afsdb_t *afsdb; - - REQUIRE(((dns_rdata_afsdb_t *)source) != NULL); - REQUIRE(((dns_rdata_afsdb_t *)source)->common.rdtype == - dns_rdatatype_afsdb); - - afsdb = source; - - if (afsdb->mctx == NULL) - return; - - dns_name_free(&afsdb->server, afsdb->mctx); - afsdb->mctx = NULL; -} - -static inline isc_result_t -additionaldata_afsdb(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_afsdb); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_afsdb(ARGS_DIGEST) { - isc_region_t r1, r2; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_afsdb); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 2); - r1.length = 2; - RETERR((digest)(arg, &r1)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_afsdb(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_afsdb); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_afsdb(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_afsdb); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_afsdb(ARGS_COMPARE) { - return (compare_afsdb(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_AFSDB_18_C */ diff --git a/lib/dns-pkcs11/rdata/generic/afsdb_18.h b/lib/dns-pkcs11/rdata/generic/afsdb_18.h deleted file mode 100644 index 0a1b059..0000000 --- a/lib/dns-pkcs11/rdata/generic/afsdb_18.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_AFSDB_18_H -#define GENERIC_AFSDB_18_H 1 - - -/*! - * \brief Per RFC1183 */ - -typedef struct dns_rdata_afsdb { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t subtype; - dns_name_t server; -} dns_rdata_afsdb_t; - -#endif /* GENERIC_AFSDB_18_H */ - diff --git a/lib/dns-pkcs11/rdata/generic/amtrelay_260.c b/lib/dns-pkcs11/rdata/generic/amtrelay_260.c deleted file mode 100644 index 208886d..0000000 --- a/lib/dns-pkcs11/rdata/generic/amtrelay_260.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef RDATA_GENERIC_AMTRELAY_260_C -#define RDATA_GENERIC_AMTRELAY_260_C - -#include - -#include - -#define RRTYPE_AMTRELAY_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_amtrelay(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - unsigned int discovery; - unsigned int gateway; - struct in_addr addr; - unsigned char addr6[16]; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_amtrelay); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Precedence. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) { - RETTOK(ISC_R_RANGE); - } - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Discovery. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 1U) { - RETTOK(ISC_R_RANGE); - } - discovery = token.value.as_ulong; - - /* - * Gateway type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0x7fU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong | (discovery << 7), target)); - gateway = token.value.as_ulong; - - if (gateway == 0) { - return (ISC_R_SUCCESS); - } - - if (gateway > 3) { - return (ISC_R_NOTIMPLEMENTED); - } - - /* - * Gateway. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - switch (gateway) { - case 1: - if (inet_pton(AF_INET, DNS_AS_STR(token), &addr) != 1) { - RETTOK(DNS_R_BADDOTTEDQUAD); - } - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) { - return (ISC_R_NOSPACE); - } - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); - - case 2: - if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1) { - RETTOK(DNS_R_BADAAAA); - } - isc_buffer_availableregion(target, ®ion); - if (region.length < 16) { - return (ISC_R_NOSPACE); - } - memmove(region.base, addr6, 16); - isc_buffer_add(target, 16); - return (ISC_R_SUCCESS); - - case 3: - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) { - origin = dns_rootname; - } - return (dns_name_fromtext(&name, &buffer, origin, options, - target)); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static inline isc_result_t -totext_amtrelay(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - char buf[sizeof("0 255 ")]; - unsigned char precedence; - unsigned char discovery; - unsigned char gateway; - const char *space; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - REQUIRE(rdata->length >= 2); - - if ((rdata->data[1] & 0x7f) > 3U) - return (ISC_R_NOTIMPLEMENTED); - - /* - * Precedence. - */ - dns_rdata_toregion(rdata, ®ion); - precedence = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u ", precedence); - RETERR(str_totext(buf, target)); - - /* - * Discovery and Gateway type. - */ - gateway = uint8_fromregion(®ion); - discovery = gateway >> 7; - gateway &= 0x7f; - space = (gateway != 0U) ? " " : ""; - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u %u%s", discovery, gateway, space); - RETERR(str_totext(buf, target)); - - /* - * Gateway. - */ - switch (gateway) { - case 0: - break; - case 1: - return (inet_totext(AF_INET, tctx->flags, ®ion, target)); - - case 2: - return (inet_totext(AF_INET6, tctx->flags, ®ion, target)); - - case 3: - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - return (dns_name_totext(&name, false, target)); - - default: - INSIST(0); - ISC_UNREACHABLE(); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_amtrelay(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_amtrelay); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 2) - return (ISC_R_UNEXPECTEDEND); - - switch (region.base[1] & 0x7f) { - case 0: - if (region.length != 2) { - return (DNS_R_FORMERR); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 1: - if (region.length != 6) { - return (DNS_R_FORMERR); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 2: - if (region.length != 18) { - return (DNS_R_FORMERR); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 3: - RETERR(mem_tobuffer(target, region.base, 2)); - isc_buffer_forward(source, 2); - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, - target)); - - default: - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - } -} - -static inline isc_result_t -towire_amtrelay(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_amtrelay(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_amtrelay); - REQUIRE(rdata1->length >= 2); - REQUIRE(rdata2->length >= 2); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_amtrelay(ARGS_FROMSTRUCT) { - dns_rdata_amtrelay_t *amtrelay; - isc_region_t region; - uint32_t n; - - REQUIRE(type == dns_rdatatype_amtrelay); - REQUIRE(((dns_rdata_amtrelay_t *)source) != NULL); - REQUIRE(((dns_rdata_amtrelay_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_amtrelay_t *)source)->common.rdclass == rdclass); - - amtrelay = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(amtrelay->precedence, target)); - n = (amtrelay->discovery ? 0x80 : 0) | amtrelay->gateway_type; - RETERR(uint8_tobuffer(n, target)); - - switch (amtrelay->gateway_type) { - case 0: - return (ISC_R_SUCCESS); - - case 1: - n = ntohl(amtrelay->in_addr.s_addr); - return (uint32_tobuffer(n, target)); - - case 2: - return (mem_tobuffer(target, amtrelay->in6_addr.s6_addr, 16)); - break; - - case 3: - dns_name_toregion(&amtrelay->gateway, ®ion); - return (isc_buffer_copyregion(target, ®ion)); - break; - - default: - return (mem_tobuffer(target, amtrelay->data, amtrelay->length)); - } -} - -static inline isc_result_t -tostruct_amtrelay(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_amtrelay_t *amtrelay; - dns_name_t name; - uint32_t n; - - REQUIRE(((dns_rdata_amtrelay_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - REQUIRE(rdata->length >= 2); - - amtrelay = target; - - amtrelay->common.rdclass = rdata->rdclass; - amtrelay->common.rdtype = rdata->type; - ISC_LINK_INIT(&amtrelay->common, link); - - dns_name_init(&amtrelay->gateway, NULL); - amtrelay->data = NULL; - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - - amtrelay->precedence = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - amtrelay->gateway_type = uint8_fromregion(®ion); - amtrelay->discovery = (amtrelay->gateway_type & 0x80) != 0; - amtrelay->gateway_type &= 0x7f; - isc_region_consume(®ion, 1); - - switch (amtrelay->gateway_type) { - case 0: - break; - - case 1: - n = uint32_fromregion(®ion); - amtrelay->in_addr.s_addr = htonl(n); - isc_region_consume(®ion, 4); - break; - - case 2: - memmove(amtrelay->in6_addr.s6_addr, region.base, 16); - isc_region_consume(®ion, 16); - break; - - case 3: - dns_name_fromregion(&name, ®ion); - RETERR(name_duporclone(&name, mctx, &amtrelay->gateway)); - isc_region_consume(®ion, name_length(&name)); - break; - - default: - if (region.length != 0) { - amtrelay->data = mem_maybedup(mctx, region.base, - region.length); - if (amtrelay->data == NULL) { - return (ISC_R_NOMEMORY); - } - } - amtrelay->length = region.length; - } - amtrelay->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_amtrelay(ARGS_FREESTRUCT) { - dns_rdata_amtrelay_t *amtrelay; - - REQUIRE(((dns_rdata_amtrelay_t *)source) != NULL); - REQUIRE(((dns_rdata_amtrelay_t *)source)->common.rdtype == - dns_rdatatype_amtrelay); - - amtrelay = source; - - if (amtrelay->mctx == NULL) - return; - - if (amtrelay->gateway_type == 3) - dns_name_free(&amtrelay->gateway, amtrelay->mctx); - - if (amtrelay->data != NULL) - isc_mem_free(amtrelay->mctx, amtrelay->data); - - amtrelay->mctx = NULL; -} - -static inline isc_result_t -additionaldata_amtrelay(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_amtrelay(ARGS_DIGEST) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - - dns_rdata_toregion(rdata, ®ion); - return ((digest)(arg, ®ion)); -} - -static inline bool -checkowner_amtrelay(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_amtrelay); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_amtrelay(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_amtrelay); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_amtrelay(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_amtrelay); - REQUIRE(rdata1->length >= 2); - REQUIRE(rdata2->length >= 2); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - if (memcmp(region1.base, region2.base, 2) != 0 || - (region1.base[1] & 0x7f) != 3) - return (isc_region_compare(®ion1, ®ion2)); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -#endif /* RDATA_GENERIC_AMTRELAY_260_C */ diff --git a/lib/dns-pkcs11/rdata/generic/amtrelay_260.h b/lib/dns-pkcs11/rdata/generic/amtrelay_260.h deleted file mode 100644 index c942fd6..0000000 --- a/lib/dns-pkcs11/rdata/generic/amtrelay_260.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_AMTRELAY_260_H -#define GENERIC_AMTRELAY_260_H 1 - -typedef struct dns_rdata_amtrelay { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint8_t precedence; - bool discovery; - uint8_t gateway_type; - struct in_addr in_addr; /* gateway type 1 */ - struct in6_addr in6_addr; /* gateway type 2 */ - dns_name_t gateway; /* gateway type 3 */ - unsigned char *data; /* gateway type > 3 */ - uint16_t length; -} dns_rdata_amtrelay_t; - -#endif /* GENERIC_AMTRELAY_260_H */ diff --git a/lib/dns-pkcs11/rdata/generic/avc_258.c b/lib/dns-pkcs11/rdata/generic/avc_258.c deleted file mode 100644 index d6a25da..0000000 --- a/lib/dns-pkcs11/rdata/generic/avc_258.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_AVC_258_C -#define RDATA_GENERIC_AVC_258_C - -#define RRTYPE_AVC_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_avc(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_avc); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - return (generic_fromtext_txt(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_avc(ARGS_TOTEXT) { - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_avc); - - return (generic_totext_txt(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_avc(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_avc); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - return (generic_fromwire_txt(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_avc(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_avc); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_avc(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_avc); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_avc(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_avc); - - return (generic_fromstruct_txt(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_avc(ARGS_TOSTRUCT) { - dns_rdata_avc_t *avc; - - REQUIRE(((dns_rdata_avc_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_avc); - - avc = target; - - avc->common.rdclass = rdata->rdclass; - avc->common.rdtype = rdata->type; - ISC_LINK_INIT(&avc->common, link); - - return (generic_tostruct_txt(rdata, target, mctx)); -} - -static inline void -freestruct_avc(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_avc_t *)source) != NULL); - REQUIRE(((dns_rdata_avc_t *)source)->common.rdtype == dns_rdatatype_avc); - - generic_freestruct_txt(source); -} - -static inline isc_result_t -additionaldata_avc(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_avc); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_avc(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_avc); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_avc(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_avc); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_avc(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_avc); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_avc(ARGS_COMPARE) { - return (compare_avc(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_AVC_258_C */ diff --git a/lib/dns-pkcs11/rdata/generic/avc_258.h b/lib/dns-pkcs11/rdata/generic/avc_258.h deleted file mode 100644 index b6f6378..0000000 --- a/lib/dns-pkcs11/rdata/generic/avc_258.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_AVC_258_H -#define GENERIC_AVC_258_H 1 - -typedef dns_rdata_txt_string_t dns_rdata_avc_string_t; - -typedef struct dns_rdata_avc { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *data; - uint16_t length; - /* private */ - uint16_t offset; -} dns_rdata_avc_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ -#endif /* GENERIC_AVC_258_H */ diff --git a/lib/dns-pkcs11/rdata/generic/caa_257.c b/lib/dns-pkcs11/rdata/generic/caa_257.c deleted file mode 100644 index 464e388..0000000 --- a/lib/dns-pkcs11/rdata/generic/caa_257.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_CAA_257_C -#define GENERIC_CAA_257_C 1 - -#define RRTYPE_CAA_ATTRIBUTES (0) - -static unsigned char const alphanumeric[256] = { - /* 0x00-0x0f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10-0x1f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x20-0x2f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x30-0x3f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - /* 0x40-0x4f */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x50-0x5f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - /* 0x60-0x6f */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x70-0x7f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - /* 0x80-0x8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x90-0x9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xa0-0xaf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xb0-0xbf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xc0-0xcf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xd0-0xdf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xe0-0xef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xf0-0xff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static inline isc_result_t -fromtext_caa(ARGS_FROMTEXT) { - isc_token_t token; - isc_textregion_t tr; - uint8_t flags; - unsigned int i; - - REQUIRE(type == dns_rdatatype_caa); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* Flags. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 255U) - RETTOK(ISC_R_RANGE); - flags = (uint8_t)(token.value.as_ulong & 255U); - RETERR(uint8_tobuffer(flags, target)); - - /* - * Tag - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - tr = token.value.as_textregion; - for (i = 0; i < tr.length; i++) - if (!alphanumeric[(unsigned char) tr.base[i]]) - RETTOK(DNS_R_SYNTAX); - RETERR(uint8_tobuffer(tr.length, target)); - RETERR(mem_tobuffer(target, tr.base, tr.length)); - - /* - * Value - */ - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_qstring, false)); - if (token.type != isc_tokentype_qstring && - token.type != isc_tokentype_string) - RETERR(DNS_R_SYNTAX); - RETERR(multitxt_fromtext(&token.value.as_textregion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_caa(ARGS_TOTEXT) { - isc_region_t region; - uint8_t flags; - char buf[256]; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->length >= 3U); - REQUIRE(rdata->data != NULL); - - dns_rdata_toregion(rdata, ®ion); - - /* - * Flags - */ - flags = uint8_consume_fromregion(®ion); - snprintf(buf, sizeof(buf), "%u ", flags); - RETERR(str_totext(buf, target)); - - /* - * Tag - */ - RETERR(txt_totext(®ion, false, target)); - RETERR(str_totext(" ", target)); - - /* - * Value - */ - RETERR(multitxt_totext(®ion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_caa(ARGS_FROMWIRE) { - isc_region_t sr; - unsigned int len, i; - - REQUIRE(type == dns_rdatatype_caa); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - /* - * Flags - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - - /* - * Flags, tag length - */ - RETERR(mem_tobuffer(target, sr.base, 2)); - len = sr.base[1]; - isc_region_consume(&sr, 2); - isc_buffer_forward(source, 2); - - /* - * Zero length tag fields are illegal. - */ - if (sr.length < len || len == 0) - RETERR(DNS_R_FORMERR); - - /* Check the Tag's value */ - for (i = 0; i < len; i++) - if (!alphanumeric[sr.base[i]]) - RETERR(DNS_R_FORMERR); - /* - * Tag + Value - */ - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_caa(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->length >= 3U); - REQUIRE(rdata->data != NULL); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_caa(ARGS_COMPARE) { - isc_region_t r1, r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_caa); - REQUIRE(rdata1->length >= 3U); - REQUIRE(rdata2->length >= 3U); - REQUIRE(rdata1->data != NULL); - REQUIRE(rdata2->data != NULL); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_caa(ARGS_FROMSTRUCT) { - dns_rdata_caa_t *caa; - isc_region_t region; - unsigned int i; - - REQUIRE(type == dns_rdatatype_caa); - REQUIRE(((dns_rdata_caa_t *)source) != NULL); - REQUIRE(((dns_rdata_caa_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_caa_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_caa_t *)source)->tag != NULL); - REQUIRE(((dns_rdata_caa_t *)source)->tag_len != 0); - REQUIRE(((dns_rdata_caa_t *)source)->value != NULL); - - caa = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Flags - */ - RETERR(uint8_tobuffer(caa->flags, target)); - - /* - * Tag length - */ - RETERR(uint8_tobuffer(caa->tag_len, target)); - - /* - * Tag - */ - region.base = caa->tag; - region.length = caa->tag_len; - for (i = 0; i < region.length; i++) - if (!alphanumeric[region.base[i]]) - RETERR(DNS_R_SYNTAX); - RETERR(isc_buffer_copyregion(target, ®ion)); - - /* - * Value - */ - region.base = caa->value; - region.length = caa->value_len; - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_caa(ARGS_TOSTRUCT) { - dns_rdata_caa_t *caa; - isc_region_t sr; - - REQUIRE(((dns_rdata_caa_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->length >= 3U); - REQUIRE(rdata->data != NULL); - - caa = target; - - caa->common.rdclass = rdata->rdclass; - caa->common.rdtype = rdata->type; - ISC_LINK_INIT(&caa->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Flags - */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - caa->flags = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Tag length - */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - caa->tag_len = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Tag - */ - if (sr.length < caa->tag_len) - return (ISC_R_UNEXPECTEDEND); - caa->tag = mem_maybedup(mctx, sr.base, caa->tag_len); - if (caa->tag == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(&sr, caa->tag_len); - - /* - * Value - */ - caa->value_len = sr.length; - caa->value = mem_maybedup(mctx, sr.base, sr.length); - if (caa->value == NULL) - return (ISC_R_NOMEMORY); - - caa->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_caa(ARGS_FREESTRUCT) { - dns_rdata_caa_t *caa; - - REQUIRE(((dns_rdata_caa_t *)source) != NULL); - REQUIRE(((dns_rdata_caa_t *)source)->common.rdtype == - dns_rdatatype_caa); - - caa = source; - - if (caa->mctx == NULL) - return; - - if (caa->tag != NULL) - isc_mem_free(caa->mctx, caa->tag); - if (caa->value != NULL) - isc_mem_free(caa->mctx, caa->value); - caa->mctx = NULL; -} - -static inline isc_result_t -additionaldata_caa(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->data != NULL); - REQUIRE(rdata->length >= 3U); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_caa(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->data != NULL); - REQUIRE(rdata->length >= 3U); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_caa(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_caa); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_caa(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_caa); - REQUIRE(rdata->data != NULL); - REQUIRE(rdata->length >= 3U); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_caa(ARGS_COMPARE) { - return (compare_caa(rdata1, rdata2)); -} - -#endif /* GENERIC_CAA_257_C */ diff --git a/lib/dns-pkcs11/rdata/generic/caa_257.h b/lib/dns-pkcs11/rdata/generic/caa_257.h deleted file mode 100644 index 8af6c17..0000000 --- a/lib/dns-pkcs11/rdata/generic/caa_257.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_CAA_257_H -#define GENERIC_CAA_257_H 1 - - -typedef struct dns_rdata_caa { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint8_t flags; - unsigned char * tag; - uint8_t tag_len; - unsigned char *value; - uint16_t value_len; -} dns_rdata_caa_t; - -#endif /* GENERIC_CAA_257_H */ diff --git a/lib/dns-pkcs11/rdata/generic/cdnskey_60.c b/lib/dns-pkcs11/rdata/generic/cdnskey_60.c deleted file mode 100644 index 9579f4e..0000000 --- a/lib/dns-pkcs11/rdata/generic/cdnskey_60.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* draft-ietf-dnsop-delegation-trust-maintainance-14 */ - -#ifndef RDATA_GENERIC_CDNSKEY_60_C -#define RDATA_GENERIC_CDNSKEY_60_C - -#include - -#define RRTYPE_CDNSKEY_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_cdnskey(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_cdnskey); - - return (generic_fromtext_key(rdclass, type, lexer, origin, - options, target, callbacks)); -} - -static inline isc_result_t -totext_cdnskey(ARGS_TOTEXT) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - - return (generic_totext_key(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_cdnskey(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_cdnskey); - - return (generic_fromwire_key(rdclass, type, source, dctx, - options, target)); -} - -static inline isc_result_t -towire_cdnskey(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_cdnskey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_cdnskey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_cdnskey(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_cdnskey); - - return (generic_fromstruct_key(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_cdnskey(ARGS_TOSTRUCT) { - dns_rdata_cdnskey_t *dnskey; - - REQUIRE(((dns_rdata_cdnskey_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - - dnskey = target; - - dnskey->common.rdclass = rdata->rdclass; - dnskey->common.rdtype = rdata->type; - ISC_LINK_INIT(&dnskey->common, link); - - return (generic_tostruct_key(rdata, target, mctx)); -} - -static inline void -freestruct_cdnskey(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_cdnskey_t *)source) != NULL); - REQUIRE(((dns_rdata_cdnskey_t *)source)->common.rdtype == - dns_rdatatype_cdnskey); - - generic_freestruct_key(source); -} - -static inline isc_result_t -additionaldata_cdnskey(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_cdnskey(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_cdnskey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_cdnskey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_cdnskey(ARGS_CHECKNAMES) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_cdnskey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_cdnskey(ARGS_COMPARE) { - - /* - * Treat ALG 253 (private DNS) subtype name case sensitively. - */ - return (compare_cdnskey(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_CDNSKEY_60_C */ diff --git a/lib/dns-pkcs11/rdata/generic/cdnskey_60.h b/lib/dns-pkcs11/rdata/generic/cdnskey_60.h deleted file mode 100644 index 84a6c97..0000000 --- a/lib/dns-pkcs11/rdata/generic/cdnskey_60.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_CDNSKEY_60_H -#define GENERIC_CDNSKEY_60_H 1 - -/* CDNSKEY records have the same RDATA fields as DNSKEY records. */ -typedef struct dns_rdata_key dns_rdata_cdnskey_t; - -#endif /* GENERIC_CDNSKEY_60_H */ diff --git a/lib/dns-pkcs11/rdata/generic/cds_59.c b/lib/dns-pkcs11/rdata/generic/cds_59.c deleted file mode 100644 index 968dabf..0000000 --- a/lib/dns-pkcs11/rdata/generic/cds_59.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* draft-ietf-dnsop-delegation-trust-maintainance-14 */ - -#ifndef RDATA_GENERIC_CDS_59_C -#define RDATA_GENERIC_CDS_59_C - -#define RRTYPE_CDS_ATTRIBUTES 0 - -#include -#include - -#include - -#include "dst_gost.h" - -static inline isc_result_t -fromtext_cds(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_cds); - - return (generic_fromtext_ds(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_cds(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_cds); - - return (generic_totext_ds(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_cds(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_cds); - - return (generic_fromwire_ds(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_cds(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_cds); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_cds(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_cds); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_cds(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_cds); - - return (generic_fromstruct_ds(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_cds(ARGS_TOSTRUCT) { - dns_rdata_cds_t *cds; - - REQUIRE(((dns_rdata_cds_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_cds); - REQUIRE(rdata->length != 0); - - cds = target; - - /* - * Checked by generic_tostruct_ds(). - */ - cds->common.rdclass = rdata->rdclass; - cds->common.rdtype = rdata->type; - ISC_LINK_INIT(&cds->common, link); - - return (generic_tostruct_ds(rdata, target, mctx)); -} - -static inline void -freestruct_cds(ARGS_FREESTRUCT) { - dns_rdata_cds_t *cds; - - REQUIRE(((dns_rdata_cds_t *)source) != NULL); - REQUIRE(((dns_rdata_cds_t *)source)->common.rdtype == - dns_rdatatype_cds); - - cds = source; - - if (cds->mctx == NULL) { - return; - } - - if (cds->digest != NULL) { - isc_mem_free(cds->mctx, cds->digest); - } - cds->mctx = NULL; -} - -static inline isc_result_t -additionaldata_cds(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_cds); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_cds(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_cds); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_cds(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_cds); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_cds(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_cds); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_cds(ARGS_COMPARE) { - return (compare_cds(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_CDS_59_C */ diff --git a/lib/dns-pkcs11/rdata/generic/cds_59.h b/lib/dns-pkcs11/rdata/generic/cds_59.h deleted file mode 100644 index a248266..0000000 --- a/lib/dns-pkcs11/rdata/generic/cds_59.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_CDS_59_H -#define GENERIC_CDS_59_H 1 - -/* CDS records have the same RDATA fields as DS records. */ -typedef struct dns_rdata_ds dns_rdata_cds_t; - -#endif /* GENERIC_CDS_59_H */ diff --git a/lib/dns-pkcs11/rdata/generic/cert_37.c b/lib/dns-pkcs11/rdata/generic/cert_37.c deleted file mode 100644 index 7b0a6aa..0000000 --- a/lib/dns-pkcs11/rdata/generic/cert_37.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2538 */ - -#ifndef RDATA_GENERIC_CERT_37_C -#define RDATA_GENERIC_CERT_37_C - -#define RRTYPE_CERT_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_cert(ARGS_FROMTEXT) { - isc_token_t token; - dns_secalg_t secalg; - dns_cert_t cert; - - REQUIRE(type == dns_rdatatype_cert); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Cert type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion)); - RETERR(uint16_tobuffer(cert, target)); - - /* - * Key tag. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &secalg, 1)); - - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_cert(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("64000 ")]; - unsigned int n; - - REQUIRE(rdata->type == dns_rdatatype_cert); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - /* - * Type. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - RETERR(dns_cert_totext((dns_cert_t)n, target)); - RETERR(str_totext(" ", target)); - - /* - * Key tag. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Algorithm. - */ - RETERR(dns_secalg_totext(sr.base[0], target)); - isc_region_consume(&sr, 1); - - /* - * Cert. - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_cert(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_cert); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 6) { - return (ISC_R_UNEXPECTEDEND); - } - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_cert(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_cert); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_cert(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_cert); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_cert(ARGS_FROMSTRUCT) { - dns_rdata_cert_t *cert; - - REQUIRE(type == dns_rdatatype_cert); - REQUIRE(((dns_rdata_cert_t *)source) != NULL); - REQUIRE(((dns_rdata_cert_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_cert_t *)source)->common.rdclass == rdclass); - - cert = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(cert->type, target)); - RETERR(uint16_tobuffer(cert->key_tag, target)); - RETERR(uint8_tobuffer(cert->algorithm, target)); - - return (mem_tobuffer(target, cert->certificate, cert->length)); -} - -static inline isc_result_t -tostruct_cert(ARGS_TOSTRUCT) { - dns_rdata_cert_t *cert; - isc_region_t region; - - REQUIRE(((dns_rdata_cert_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_cert); - REQUIRE(rdata->length != 0); - - cert = target; - - cert->common.rdclass = rdata->rdclass; - cert->common.rdtype = rdata->type; - ISC_LINK_INIT(&cert->common, link); - - dns_rdata_toregion(rdata, ®ion); - - cert->type = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - cert->key_tag = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - cert->algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - cert->length = region.length; - - cert->certificate = mem_maybedup(mctx, region.base, region.length); - if (cert->certificate == NULL) - return (ISC_R_NOMEMORY); - - cert->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_cert(ARGS_FREESTRUCT) { - dns_rdata_cert_t *cert; - - REQUIRE(((dns_rdata_cert_t *)source) != NULL); - REQUIRE(((dns_rdata_cert_t *)source)->common.rdtype == - dns_rdatatype_cert); - - cert = source; - - if (cert->mctx == NULL) - return; - - if (cert->certificate != NULL) - isc_mem_free(cert->mctx, cert->certificate); - cert->mctx = NULL; -} - -static inline isc_result_t -additionaldata_cert(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_cert); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_cert(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_cert); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_cert(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_cert); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_cert(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_cert); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - - -static inline int -casecompare_cert(ARGS_COMPARE) { - return (compare_cert(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_CERT_37_C */ diff --git a/lib/dns-pkcs11/rdata/generic/cert_37.h b/lib/dns-pkcs11/rdata/generic/cert_37.h deleted file mode 100644 index 39c29ab..0000000 --- a/lib/dns-pkcs11/rdata/generic/cert_37.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_CERT_37_H -#define GENERIC_CERT_37_H 1 - -/*% RFC2538 */ -typedef struct dns_rdata_cert { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t type; - uint16_t key_tag; - uint8_t algorithm; - uint16_t length; - unsigned char *certificate; -} dns_rdata_cert_t; - -#endif /* GENERIC_CERT_37_H */ diff --git a/lib/dns-pkcs11/rdata/generic/cname_5.c b/lib/dns-pkcs11/rdata/generic/cname_5.c deleted file mode 100644 index 591bbbc..0000000 --- a/lib/dns-pkcs11/rdata/generic/cname_5.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_CNAME_5_C -#define RDATA_GENERIC_CNAME_5_C - -#define RRTYPE_CNAME_ATTRIBUTES \ - (DNS_RDATATYPEATTR_EXCLUSIVE | DNS_RDATATYPEATTR_SINGLETON) - -static inline isc_result_t -fromtext_cname(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_cname); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_cname(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_cname); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_cname(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_cname); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_cname(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_cname); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_cname(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_cname); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_cname(ARGS_FROMSTRUCT) { - dns_rdata_cname_t *cname; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_cname); - REQUIRE(((dns_rdata_cname_t *)source) != NULL); - REQUIRE(((dns_rdata_cname_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_cname_t *)source)->common.rdclass == rdclass); - - cname = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&cname->cname, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_cname(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_cname_t *cname; - dns_name_t name; - - REQUIRE(((dns_rdata_cname_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_cname); - REQUIRE(rdata->length != 0); - - cname = target; - - cname->common.rdclass = rdata->rdclass; - cname->common.rdtype = rdata->type; - ISC_LINK_INIT(&cname->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&cname->cname, NULL); - RETERR(name_duporclone(&name, mctx, &cname->cname)); - cname->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_cname(ARGS_FREESTRUCT) { - dns_rdata_cname_t *cname; - - REQUIRE(((dns_rdata_cname_t *)source) != NULL); - - cname = source; - - if (cname->mctx == NULL) - return; - - dns_name_free(&cname->cname, cname->mctx); - cname->mctx = NULL; -} - -static inline isc_result_t -additionaldata_cname(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_cname); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_cname(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_cname); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_cname(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_cname); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_cname(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_cname); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_cname(ARGS_COMPARE) { - return (compare_cname(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_CNAME_5_C */ diff --git a/lib/dns-pkcs11/rdata/generic/cname_5.h b/lib/dns-pkcs11/rdata/generic/cname_5.h deleted file mode 100644 index d3c2a3f..0000000 --- a/lib/dns-pkcs11/rdata/generic/cname_5.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_CNAME_5_H -#define GENERIC_CNAME_5_H 1 - -typedef struct dns_rdata_cname { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t cname; -} dns_rdata_cname_t; - -#endif /* GENERIC_CNAME_5_H */ diff --git a/lib/dns-pkcs11/rdata/generic/csync_62.c b/lib/dns-pkcs11/rdata/generic/csync_62.c deleted file mode 100644 index 621cb08..0000000 --- a/lib/dns-pkcs11/rdata/generic/csync_62.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC 7477 */ - -#ifndef RDATA_GENERIC_CSYNC_62_C -#define RDATA_GENERIC_CSYNC_62_C - -#define RRTYPE_CSYNC_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_csync(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_csync); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* Serial. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* Flags. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* Type Map */ - return (typemap_fromtext(lexer, target, true)); -} - -static inline isc_result_t -totext_csync(ARGS_TOTEXT) { - unsigned long num; - char buf[sizeof("0123456789")]; /* Also TYPE65535 */ - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_csync); - REQUIRE(rdata->length >= 6); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - num = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - num = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu", num); - RETERR(str_totext(buf, target)); - - /* - * Don't leave a trailing space when there's no typemap present. - */ - if (sr.length > 0) { - RETERR(str_totext(" ", target)); - } - return (typemap_totext(&sr, NULL, target)); -} - -static /* inline */ isc_result_t -fromwire_csync(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_csync); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(options); - UNUSED(dctx); - - /* - * Serial + Flags - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 6) - return (ISC_R_UNEXPECTEDEND); - - RETERR(mem_tobuffer(target, sr.base, 6)); - isc_buffer_forward(source, 6); - isc_region_consume(&sr, 6); - - RETERR(typemap_test(&sr, true)); - - RETERR(mem_tobuffer(target, sr.base, sr.length)); - isc_buffer_forward(source, sr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_csync(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_csync); - REQUIRE(rdata->length >= 6); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_csync(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_csync); - REQUIRE(rdata1->length >= 6); - REQUIRE(rdata2->length >= 6); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_csync(ARGS_FROMSTRUCT) { - dns_rdata_csync_t *csync; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_csync); - REQUIRE(((dns_rdata_csync_t *)source) != NULL); - REQUIRE(((dns_rdata_csync_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_csync_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_csync_t *)source)->typebits != NULL || - ((dns_rdata_csync_t *)source)->len == 0); - - csync = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint32_tobuffer(csync->serial, target)); - RETERR(uint16_tobuffer(csync->flags, target)); - - region.base = csync->typebits; - region.length = csync->len; - RETERR(typemap_test(®ion, true)); - return (mem_tobuffer(target, csync->typebits, csync->len)); -} - -static inline isc_result_t -tostruct_csync(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_csync_t *csync; - - REQUIRE(((dns_rdata_csync_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_csync); - REQUIRE(rdata->length != 0); - - csync = target; - - csync->common.rdclass = rdata->rdclass; - csync->common.rdtype = rdata->type; - ISC_LINK_INIT(&csync->common, link); - - dns_rdata_toregion(rdata, ®ion); - - csync->serial = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - csync->flags = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - csync->len = region.length; - csync->typebits = mem_maybedup(mctx, region.base, region.length); - if (csync->typebits == NULL) - goto cleanup; - - csync->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_csync(ARGS_FREESTRUCT) { - dns_rdata_csync_t *csync; - - REQUIRE(((dns_rdata_csync_t *)source) != NULL); - REQUIRE(((dns_rdata_csync_t *)source)->common.rdtype == - dns_rdatatype_csync); - - csync = source; - - if (csync->mctx == NULL) - return; - - if (csync->typebits != NULL) - isc_mem_free(csync->mctx, csync->typebits); - csync->mctx = NULL; -} - -static inline isc_result_t -additionaldata_csync(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_csync); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_csync(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_csync); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_csync(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_csync); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_csync(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_csync); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_csync(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_csync); - REQUIRE(rdata1->length >= 6); - REQUIRE(rdata2->length >= 6); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} -#endif /* RDATA_GENERIC_CSYNC_62_C */ diff --git a/lib/dns-pkcs11/rdata/generic/csync_62.h b/lib/dns-pkcs11/rdata/generic/csync_62.h deleted file mode 100644 index 08f378e..0000000 --- a/lib/dns-pkcs11/rdata/generic/csync_62.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_CSYNC_62_H -#define GENERIC_CSYNC_62_H 1 - -/*! - * \brief Per RFC 7477 - */ - -typedef struct dns_rdata_csync { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint32_t serial; - uint16_t flags; - unsigned char *typebits; - uint16_t len; -} dns_rdata_csync_t; - -#endif /* GENERIC_CSYNC_62_H */ diff --git a/lib/dns-pkcs11/rdata/generic/dlv_32769.c b/lib/dns-pkcs11/rdata/generic/dlv_32769.c deleted file mode 100644 index ce96f1b..0000000 --- a/lib/dns-pkcs11/rdata/generic/dlv_32769.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC3658 */ - -#ifndef RDATA_GENERIC_DLV_32769_C -#define RDATA_GENERIC_DLV_32769_C - -#define RRTYPE_DLV_ATTRIBUTES 0 - -#include -#include - -#include - -#include "dst_gost.h" - -static inline isc_result_t -fromtext_dlv(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_dlv); - - return (generic_fromtext_ds(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_dlv(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_dlv); - - return (generic_totext_ds(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_dlv(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_dlv); - - return (generic_fromwire_ds(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_dlv(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_dlv); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_dlv(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_dlv); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_dlv(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_dlv); - - return (generic_fromstruct_ds(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_dlv(ARGS_TOSTRUCT) { - dns_rdata_dlv_t *dlv; - - REQUIRE(((dns_rdata_dlv_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_dlv); - - dlv = target; - - dlv->common.rdclass = rdata->rdclass; - dlv->common.rdtype = rdata->type; - ISC_LINK_INIT(&dlv->common, link); - - return (generic_tostruct_ds(rdata, target, mctx)); -} - -static inline void -freestruct_dlv(ARGS_FREESTRUCT) { - dns_rdata_dlv_t *dlv; - - REQUIRE(((dns_rdata_dlv_t *)source) != NULL); - REQUIRE(((dns_rdata_dlv_t *)source)->common.rdtype == - dns_rdatatype_dlv); - - dlv = source; - - if (dlv->mctx == NULL) - return; - - if (dlv->digest != NULL) - isc_mem_free(dlv->mctx, dlv->digest); - dlv->mctx = NULL; -} - -static inline isc_result_t -additionaldata_dlv(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_dlv); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_dlv(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_dlv); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_dlv(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_dlv); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_dlv(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_dlv); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_dlv(ARGS_COMPARE) { - return (compare_dlv(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_DLV_32769_C */ diff --git a/lib/dns-pkcs11/rdata/generic/dlv_32769.h b/lib/dns-pkcs11/rdata/generic/dlv_32769.h deleted file mode 100644 index c0b88f3..0000000 --- a/lib/dns-pkcs11/rdata/generic/dlv_32769.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* draft-ietf-dnsext-delegation-signer-05.txt */ -#ifndef GENERIC_DLV_32769_H -#define GENERIC_DLV_32769_H 1 - -typedef struct dns_rdata_ds dns_rdata_dlv_t; - -#endif /* GENERIC_DLV_32769_H */ diff --git a/lib/dns-pkcs11/rdata/generic/dname_39.c b/lib/dns-pkcs11/rdata/generic/dname_39.c deleted file mode 100644 index a43dfa8..0000000 --- a/lib/dns-pkcs11/rdata/generic/dname_39.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2672 */ - -#ifndef RDATA_GENERIC_DNAME_39_C -#define RDATA_GENERIC_DNAME_39_C - -#define RRTYPE_DNAME_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON) - -static inline isc_result_t -fromtext_dname(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_dname); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_dname(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_dname); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_dname(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_dname); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - return(dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_dname(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_dname); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_dname(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_dname); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_dname(ARGS_FROMSTRUCT) { - dns_rdata_dname_t *dname; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_dname); - REQUIRE(((dns_rdata_dname_t *)source) != NULL); - REQUIRE(((dns_rdata_dname_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_dname_t *)source)->common.rdclass == rdclass); - - dname = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&dname->dname, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_dname(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_dname_t *dname; - dns_name_t name; - - REQUIRE(((dns_rdata_dname_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_dname); - REQUIRE(rdata->length != 0); - - dname = target; - - dname->common.rdclass = rdata->rdclass; - dname->common.rdtype = rdata->type; - ISC_LINK_INIT(&dname->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&dname->dname, NULL); - RETERR(name_duporclone(&name, mctx, &dname->dname)); - dname->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_dname(ARGS_FREESTRUCT) { - dns_rdata_dname_t *dname; - - REQUIRE(((dns_rdata_dname_t *)source) != NULL); - REQUIRE(((dns_rdata_dname_t *)source)->common.rdtype == - dns_rdatatype_dname); - - dname = source; - - if (dname->mctx == NULL) - return; - - dns_name_free(&dname->dname, dname->mctx); - dname->mctx = NULL; -} - -static inline isc_result_t -additionaldata_dname(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_dname); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_dname(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_dname); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_dname(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_dname); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_dname(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_dname); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_dname(ARGS_COMPARE) { - return (compare_dname(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_DNAME_39_C */ diff --git a/lib/dns-pkcs11/rdata/generic/dname_39.h b/lib/dns-pkcs11/rdata/generic/dname_39.h deleted file mode 100644 index 2e7dbc1..0000000 --- a/lib/dns-pkcs11/rdata/generic/dname_39.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_DNAME_39_H -#define GENERIC_DNAME_39_H 1 - - -/*! - * \brief per RFC2672 */ - -typedef struct dns_rdata_dname { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t dname; -} dns_rdata_dname_t; - -#endif /* GENERIC_DNAME_39_H */ diff --git a/lib/dns-pkcs11/rdata/generic/dnskey_48.c b/lib/dns-pkcs11/rdata/generic/dnskey_48.c deleted file mode 100644 index ef53ba8..0000000 --- a/lib/dns-pkcs11/rdata/generic/dnskey_48.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2535 */ - -#ifndef RDATA_GENERIC_DNSKEY_48_C -#define RDATA_GENERIC_DNSKEY_48_C - -#include - -#define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) - -static inline isc_result_t -fromtext_dnskey(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_dnskey); - - return (generic_fromtext_key(rdclass, type, lexer, origin, - options, target, callbacks)); -} - -static inline isc_result_t -totext_dnskey(ARGS_TOTEXT) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_dnskey); - - return (generic_totext_key(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_dnskey(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_dnskey); - - return (generic_fromwire_key(rdclass, type, source, dctx, - options, target)); -} - -static inline isc_result_t -towire_dnskey(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_dnskey); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_dnskey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_dnskey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_dnskey(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_dnskey); - - return (generic_fromstruct_key(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_dnskey(ARGS_TOSTRUCT) { - dns_rdata_dnskey_t *dnskey; - - REQUIRE(((dns_rdata_dnskey_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_dnskey); - - dnskey = target; - - dnskey->common.rdclass = rdata->rdclass; - dnskey->common.rdtype = rdata->type; - ISC_LINK_INIT(&dnskey->common, link); - - return (generic_tostruct_key(rdata, target, mctx)); -} - -static inline void -freestruct_dnskey(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_dnskey_t *)source) != NULL); - REQUIRE(((dns_rdata_dnskey_t *)source)->common.rdtype == - dns_rdatatype_dnskey); - - generic_freestruct_key(source); -} - -static inline isc_result_t -additionaldata_dnskey(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_dnskey); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_dnskey(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_dnskey); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_dnskey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_dnskey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_dnskey(ARGS_CHECKNAMES) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_dnskey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_dnskey(ARGS_COMPARE) { - - /* - * Treat ALG 253 (private DNS) subtype name case sensitively. - */ - return (compare_dnskey(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_DNSKEY_48_C */ diff --git a/lib/dns-pkcs11/rdata/generic/dnskey_48.h b/lib/dns-pkcs11/rdata/generic/dnskey_48.h deleted file mode 100644 index a57c9f6..0000000 --- a/lib/dns-pkcs11/rdata/generic/dnskey_48.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_DNSKEY_48_H -#define GENERIC_DNSKEY_48_H 1 - -/*! - * \brief per RFC2535 - */ - -typedef struct dns_rdata_key dns_rdata_dnskey_t; - -#endif /* GENERIC_DNSKEY_48_H */ diff --git a/lib/dns-pkcs11/rdata/generic/doa_259.c b/lib/dns-pkcs11/rdata/generic/doa_259.c deleted file mode 100644 index 33585b4..0000000 --- a/lib/dns-pkcs11/rdata/generic/doa_259.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_DOA_259_C -#define RDATA_GENERIC_DOA_259_C - -#define RRTYPE_DOA_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_doa(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_doa); - - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * DOA-ENTERPRISE - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * DOA-TYPE - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * DOA-LOCATION - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) { - RETTOK(ISC_R_RANGE); - } - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * DOA-MEDIA-TYPE - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* - * DOA-DATA - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (strcmp(DNS_AS_STR(token), "-") == 0) { - return (ISC_R_SUCCESS); - } else { - isc_lex_ungettoken(lexer, &token); - return (isc_base64_tobuffer(lexer, target, -1)); - } -} - -static inline isc_result_t -totext_doa(ARGS_TOTEXT) { - char buf[sizeof("4294967295 ")]; - isc_region_t region; - uint32_t n; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_doa); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - - /* - * DOA-ENTERPRISE - */ - n = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * DOA-TYPE - */ - n = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * DOA-LOCATION - */ - n = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * DOA-MEDIA-TYPE - */ - RETERR(txt_totext(®ion, true, target)); - RETERR(str_totext(" ", target)); - - /* - * DOA-DATA - */ - if (region.length == 0) { - return (str_totext("-", target)); - } else { - return (isc_base64_totext(®ion, 60, "", target)); - } -} - -static inline isc_result_t -fromwire_doa(ARGS_FROMWIRE) { - isc_region_t region; - - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - REQUIRE(type == dns_rdatatype_doa); - - isc_buffer_activeregion(source, ®ion); - /* - * DOA-MEDIA-TYPE may be an empty (i.e., - * comprising of just the length octet) and DOA-DATA can have - * zero length. - */ - if (region.length < 4 + 4 + 1 + 1) { - return (ISC_R_UNEXPECTEDEND); - } - - /* - * Check whether DOA-MEDIA-TYPE length is not malformed. - */ - if (region.base[9] > region.length - 10) { - return (ISC_R_UNEXPECTEDEND); - } - - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline isc_result_t -towire_doa(ARGS_TOWIRE) { - isc_region_t region; - - UNUSED(cctx); - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_doa); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_doa(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->type == dns_rdatatype_doa); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_doa(ARGS_FROMSTRUCT) { - dns_rdata_doa_t *doa; - - REQUIRE(type == dns_rdatatype_doa); - REQUIRE(((dns_rdata_doa_t *)source) != NULL); - REQUIRE(((dns_rdata_doa_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_doa_t *)source)->common.rdtype == - dns_rdatatype_doa); - - doa = source; - - RETERR(uint32_tobuffer(doa->enterprise, target)); - RETERR(uint32_tobuffer(doa->type, target)); - RETERR(uint8_tobuffer(doa->location, target)); - RETERR(uint8_tobuffer(doa->mediatype_len, target)); - RETERR(mem_tobuffer(target, doa->mediatype, doa->mediatype_len)); - return (mem_tobuffer(target, doa->data, doa->data_len)); -} - -static inline isc_result_t -tostruct_doa(ARGS_TOSTRUCT) { - dns_rdata_doa_t *doa; - isc_region_t region; - - REQUIRE(((dns_rdata_doa_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_doa); - REQUIRE(rdata->length != 0); - - doa = target; - - doa->common.rdclass = rdata->rdclass; - doa->common.rdtype = rdata->type; - ISC_LINK_INIT(&doa->common, link); - - dns_rdata_toregion(rdata, ®ion); - - /* - * DOA-ENTERPRISE - */ - if (region.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - doa->enterprise = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - /* - * DOA-TYPE - */ - if (region.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - doa->type = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - /* - * DOA-LOCATION - */ - if (region.length < 1) { - return (ISC_R_UNEXPECTEDEND); - } - doa->location = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - /* - * DOA-MEDIA-TYPE - */ - if (region.length < 1) { - return (ISC_R_UNEXPECTEDEND); - } - doa->mediatype_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - INSIST(doa->mediatype_len <= region.length); - doa->mediatype = mem_maybedup(mctx, region.base, doa->mediatype_len); - if (doa->mediatype == NULL) { - goto cleanup; - } - isc_region_consume(®ion, doa->mediatype_len); - - /* - * DOA-DATA - */ - doa->data_len = region.length; - doa->data = NULL; - if (doa->data_len > 0) { - doa->data = mem_maybedup(mctx, region.base, doa->data_len); - if (doa->data == NULL) { - goto cleanup; - } - isc_region_consume(®ion, doa->data_len); - } - - doa->mctx = mctx; - - return (ISC_R_SUCCESS); - -cleanup: - if (mctx != NULL && doa->mediatype != NULL) { - isc_mem_free(mctx, doa->mediatype); - } - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_doa(ARGS_FREESTRUCT) { - dns_rdata_doa_t *doa; - - REQUIRE(((dns_rdata_doa_t *)source) != NULL); - REQUIRE(((dns_rdata_doa_t *)source)->common.rdtype == - dns_rdatatype_doa); - - doa = source; - - if (doa->mctx == NULL) { - return; - } - - if (doa->mediatype != NULL) { - isc_mem_free(doa->mctx, doa->mediatype); - } - if (doa->data != NULL) { - isc_mem_free(doa->mctx, doa->data); - } - - doa->mctx = NULL; -} - -static inline isc_result_t -additionaldata_doa(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_doa); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_doa(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_doa); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_doa(ARGS_CHECKOWNER) { - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - REQUIRE(type == dns_rdatatype_doa); - - return (true); -} - -static inline bool -checknames_doa(ARGS_CHECKNAMES) { - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - REQUIRE(rdata->type == dns_rdatatype_doa); - - return (true); -} - -static inline int -casecompare_doa(ARGS_COMPARE) { - return (compare_doa(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_DOA_259_C */ diff --git a/lib/dns-pkcs11/rdata/generic/doa_259.h b/lib/dns-pkcs11/rdata/generic/doa_259.h deleted file mode 100644 index a4f99d1..0000000 --- a/lib/dns-pkcs11/rdata/generic/doa_259.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_DOA_259_H -#define GENERIC_DOA_259_H 1 - -typedef struct dns_rdata_doa { - dns_rdatacommon_t common; - isc_mem_t * mctx; - unsigned char * mediatype; - unsigned char * data; - uint32_t enterprise; - uint32_t type; - uint16_t data_len; - uint8_t location; - uint8_t mediatype_len; -} dns_rdata_doa_t; - -#endif /* GENERIC_DOA_259_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ds_43.c b/lib/dns-pkcs11/rdata/generic/ds_43.c deleted file mode 100644 index 6651f77..0000000 --- a/lib/dns-pkcs11/rdata/generic/ds_43.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC3658 */ - -#ifndef RDATA_GENERIC_DS_43_C -#define RDATA_GENERIC_DS_43_C - -#define RRTYPE_DS_ATTRIBUTES \ - ( DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH | \ - DNS_RDATATYPEATTR_ATPARENT ) - -#include -#include - -#include - -#include "dst_gost.h" - -static inline isc_result_t -generic_fromtext_ds(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char c; - int length; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Key tag. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Digest type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_dsdigest_fromtext(&c, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Digest. - */ - switch (c) { - case DNS_DSDIGEST_SHA1: - length = ISC_SHA1_DIGESTLENGTH; - break; - case DNS_DSDIGEST_SHA256: - length = ISC_SHA256_DIGESTLENGTH; - break; -#ifdef ISC_GOST_DIGESTLENGTH - case DNS_DSDIGEST_GOST: - length = ISC_GOST_DIGESTLENGTH; - break; -#endif - case DNS_DSDIGEST_SHA384: - length = ISC_SHA384_DIGESTLENGTH; - break; - default: - length = -2; - break; - } - return (isc_hex_tobuffer(lexer, target, length)); -} - -static inline isc_result_t -fromtext_ds(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_ds); - - return (generic_fromtext_ds(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -generic_totext_ds(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("64000 ")]; - unsigned int n; - - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - /* - * Key tag. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Algorithm. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Digest type. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u", n); - RETERR(str_totext(buf, target)); - - /* - * Digest. - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_hex_totext(&sr, 0, "", target)); - else - RETERR(isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else - RETERR(str_totext("[omitted]", target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_ds(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_ds); - - return (generic_totext_ds(rdata, tctx, target)); -} - -static inline isc_result_t -generic_fromwire_ds(ARGS_FROMWIRE) { - isc_region_t sr; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - - /* - * Check digest lengths if we know them. - */ - if (sr.length < 5 || - (sr.base[3] == DNS_DSDIGEST_SHA1 && - sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || - (sr.base[3] == DNS_DSDIGEST_SHA256 && - sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || -#ifdef ISC_GOST_DIGESTLENGTH - (sr.base[3] == DNS_DSDIGEST_GOST && - sr.length < 4 + ISC_GOST_DIGESTLENGTH) || -#endif - (sr.base[3] == DNS_DSDIGEST_SHA384 && - sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) - return (ISC_R_UNEXPECTEDEND); - - /* - * Only copy digest lengths if we know them. - * If there is extra data dns_rdata_fromwire() will - * detect that. - */ - if (sr.base[3] == DNS_DSDIGEST_SHA1) - sr.length = 4 + ISC_SHA1_DIGESTLENGTH; - else if (sr.base[3] == DNS_DSDIGEST_SHA256) - sr.length = 4 + ISC_SHA256_DIGESTLENGTH; -#ifdef ISC_GOST_DIGESTLENGTH - else if (sr.base[3] == DNS_DSDIGEST_GOST) - sr.length = 4 + ISC_GOST_DIGESTLENGTH; -#endif - else if (sr.base[3] == DNS_DSDIGEST_SHA384) - sr.length = 4 + ISC_SHA384_DIGESTLENGTH; - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -fromwire_ds(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_ds); - - return (generic_fromwire_ds(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_ds(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_ds); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_ds(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ds); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -generic_fromstruct_ds(ARGS_FROMSTRUCT) { - dns_rdata_ds_t *ds; - - REQUIRE(((dns_rdata_ds_t *)source) != NULL); - REQUIRE(((dns_rdata_ds_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_ds_t *)source)->common.rdclass == rdclass); - - ds = source; - - UNUSED(type); - UNUSED(rdclass); - - switch (ds->digest_type) { - case DNS_DSDIGEST_SHA1: - REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH); - break; - case DNS_DSDIGEST_SHA256: - REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH); - break; -#ifdef ISC_GOST_DIGESTLENGTH - case DNS_DSDIGEST_GOST: - REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); - break; -#endif - case DNS_DSDIGEST_SHA384: - REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH); - break; - } - - RETERR(uint16_tobuffer(ds->key_tag, target)); - RETERR(uint8_tobuffer(ds->algorithm, target)); - RETERR(uint8_tobuffer(ds->digest_type, target)); - - return (mem_tobuffer(target, ds->digest, ds->length)); -} - -static inline isc_result_t -fromstruct_ds(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_ds); - - return (generic_fromstruct_ds(rdclass, type, source, target)); -} - -static inline isc_result_t -generic_tostruct_ds(ARGS_TOSTRUCT) { - dns_rdata_ds_t *ds; - isc_region_t region; - - REQUIRE(rdata->length != 0); - REQUIRE(((dns_rdata_ds_t *)target) != NULL); - REQUIRE(((dns_rdata_ds_t *)target)->common.rdtype == rdata->type); - REQUIRE(((dns_rdata_ds_t *)target)->common.rdclass == rdata->rdclass); - REQUIRE(!ISC_LINK_LINKED(&((dns_rdata_ds_t *)target)->common, link)); - - ds = target; - - dns_rdata_toregion(rdata, ®ion); - - ds->key_tag = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - ds->algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - ds->digest_type = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - ds->length = region.length; - - ds->digest = mem_maybedup(mctx, region.base, region.length); - if (ds->digest == NULL) - return (ISC_R_NOMEMORY); - - ds->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -tostruct_ds(ARGS_TOSTRUCT) { - dns_rdata_ds_t *ds; - - REQUIRE(((dns_rdata_ds_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_ds); - - ds = target; - - ds->common.rdclass = rdata->rdclass; - ds->common.rdtype = rdata->type; - ISC_LINK_INIT(&ds->common, link); - - return (generic_tostruct_ds(rdata, target, mctx)); -} - -static inline void -freestruct_ds(ARGS_FREESTRUCT) { - dns_rdata_ds_t *ds; - - REQUIRE(((dns_rdata_ds_t *)source) != NULL); - REQUIRE(((dns_rdata_ds_t *)source)->common.rdtype == dns_rdatatype_ds); - - ds = source; - - if (ds->mctx == NULL) - return; - - if (ds->digest != NULL) - isc_mem_free(ds->mctx, ds->digest); - ds->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ds(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_ds); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ds(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_ds); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_ds(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ds); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_ds(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_ds); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_ds(ARGS_COMPARE) { - return (compare_ds(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_DS_43_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ds_43.h b/lib/dns-pkcs11/rdata/generic/ds_43.h deleted file mode 100644 index a9c2706..0000000 --- a/lib/dns-pkcs11/rdata/generic/ds_43.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_DS_43_H -#define GENERIC_DS_43_H 1 - -/*! - * \brief per draft-ietf-dnsext-delegation-signer-05.txt */ -typedef struct dns_rdata_ds { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t key_tag; - dns_secalg_t algorithm; - dns_dsdigest_t digest_type; - uint16_t length; - unsigned char *digest; -} dns_rdata_ds_t; - -#endif /* GENERIC_DS_43_H */ diff --git a/lib/dns-pkcs11/rdata/generic/eui48_108.c b/lib/dns-pkcs11/rdata/generic/eui48_108.c deleted file mode 100644 index 8b4eb96..0000000 --- a/lib/dns-pkcs11/rdata/generic/eui48_108.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_EUI48_108_C -#define RDATA_GENERIC_EUI48_108_C - -#include - -#define RRTYPE_EUI48_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_eui48(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char eui48[6]; - unsigned int l0, l1, l2, l3, l4, l5; - int n; - - REQUIRE(type == dns_rdatatype_eui48); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x", - &l0, &l1, &l2, &l3, &l4, &l5); - if (n != 6 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || - l4 > 255U || l5 > 255U) - return (DNS_R_BADEUI); - - eui48[0] = l0; - eui48[1] = l1; - eui48[2] = l2; - eui48[3] = l3; - eui48[4] = l4; - eui48[5] = l5; - return (mem_tobuffer(target, eui48, sizeof(eui48))); -} - -static inline isc_result_t -totext_eui48(ARGS_TOTEXT) { - char buf[sizeof("xx-xx-xx-xx-xx-xx")]; - - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - UNUSED(tctx); - - (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x", - rdata->data[0], rdata->data[1], rdata->data[2], - rdata->data[3], rdata->data[4], rdata->data[5]); - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_eui48(ARGS_FROMWIRE) { - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_eui48); - - UNUSED(type); - UNUSED(options); - UNUSED(rdclass); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length != 6) - return (DNS_R_FORMERR); - isc_buffer_forward(source, sregion.length); - return (mem_tobuffer(target, sregion.base, sregion.length)); -} - -static inline isc_result_t -towire_eui48(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_eui48(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_eui48); - REQUIRE(rdata1->length == 6); - REQUIRE(rdata2->length == 6); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_eui48(ARGS_FROMSTRUCT) { - dns_rdata_eui48_t *eui48; - - REQUIRE(type == dns_rdatatype_eui48); - REQUIRE(((dns_rdata_eui48_t *)source) != NULL); - REQUIRE(((dns_rdata_eui48_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_eui48_t *)source)->common.rdclass == rdclass); - - eui48 = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, eui48->eui48, sizeof(eui48->eui48))); -} - -static inline isc_result_t -tostruct_eui48(ARGS_TOSTRUCT) { - dns_rdata_eui48_t *eui48; - - REQUIRE(((dns_rdata_eui48_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - eui48 = target; - - UNUSED(mctx); - - eui48->common.rdclass = rdata->rdclass; - eui48->common.rdtype = rdata->type; - ISC_LINK_INIT(&eui48->common, link); - - memmove(eui48->eui48, rdata->data, rdata->length); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_eui48(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_eui48_t *)source) != NULL); - REQUIRE(((dns_rdata_eui48_t *)source)->common.rdtype == - dns_rdatatype_eui48); - - return; -} - -static inline isc_result_t -additionaldata_eui48(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_eui48(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_eui48(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_eui48); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_eui48(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_eui48); - REQUIRE(rdata->length == 6); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_eui48(ARGS_COMPARE) { - return (compare_eui48(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_EUI48_108_C */ diff --git a/lib/dns-pkcs11/rdata/generic/eui48_108.h b/lib/dns-pkcs11/rdata/generic/eui48_108.h deleted file mode 100644 index 9da5c89..0000000 --- a/lib/dns-pkcs11/rdata/generic/eui48_108.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_EUI48_108_H -#define GENERIC_EUI48_108_H 1 - -typedef struct dns_rdata_eui48 { - dns_rdatacommon_t common; - unsigned char eui48[6]; -} dns_rdata_eui48_t; - -#endif /* GENERIC_EUI48_10k_H */ diff --git a/lib/dns-pkcs11/rdata/generic/eui64_109.c b/lib/dns-pkcs11/rdata/generic/eui64_109.c deleted file mode 100644 index 77953d1..0000000 --- a/lib/dns-pkcs11/rdata/generic/eui64_109.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_EUI64_109_C -#define RDATA_GENERIC_EUI64_109_C - -#include - -#define RRTYPE_EUI64_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_eui64(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char eui64[8]; - unsigned int l0, l1, l2, l3, l4, l5, l6, l7; - int n; - - REQUIRE(type == dns_rdatatype_eui64); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x", - &l0, &l1, &l2, &l3, &l4, &l5, &l6, &l7); - if (n != 8 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || - l4 > 255U || l5 > 255U || l6 > 255U || l7 > 255U) - return (DNS_R_BADEUI); - - eui64[0] = l0; - eui64[1] = l1; - eui64[2] = l2; - eui64[3] = l3; - eui64[4] = l4; - eui64[5] = l5; - eui64[6] = l6; - eui64[7] = l7; - return (mem_tobuffer(target, eui64, sizeof(eui64))); -} - -static inline isc_result_t -totext_eui64(ARGS_TOTEXT) { - char buf[sizeof("xx-xx-xx-xx-xx-xx-xx-xx")]; - - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - UNUSED(tctx); - - (void)snprintf(buf, sizeof(buf), - "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", - rdata->data[0], rdata->data[1], - rdata->data[2], rdata->data[3], - rdata->data[4], rdata->data[5], - rdata->data[6], rdata->data[7]); - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_eui64(ARGS_FROMWIRE) { - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_eui64); - - UNUSED(type); - UNUSED(options); - UNUSED(rdclass); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length != 8) - return (DNS_R_FORMERR); - isc_buffer_forward(source, sregion.length); - return (mem_tobuffer(target, sregion.base, sregion.length)); -} - -static inline isc_result_t -towire_eui64(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_eui64(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_eui64); - REQUIRE(rdata1->length == 8); - REQUIRE(rdata2->length == 8); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_eui64(ARGS_FROMSTRUCT) { - dns_rdata_eui64_t *eui64; - - REQUIRE(type == dns_rdatatype_eui64); - REQUIRE(((dns_rdata_eui64_t *)source) != NULL); - REQUIRE(((dns_rdata_eui64_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_eui64_t *)source)->common.rdclass == rdclass); - - eui64 = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, eui64->eui64, sizeof(eui64->eui64))); -} - -static inline isc_result_t -tostruct_eui64(ARGS_TOSTRUCT) { - dns_rdata_eui64_t *eui64; - - REQUIRE(((dns_rdata_eui64_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - eui64 = target; - - UNUSED(mctx); - - eui64->common.rdclass = rdata->rdclass; - eui64->common.rdtype = rdata->type; - ISC_LINK_INIT(&eui64->common, link); - - memmove(eui64->eui64, rdata->data, rdata->length); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_eui64(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_eui64_t *)source) != NULL); - REQUIRE(((dns_rdata_eui64_t *)source)->common.rdtype == - dns_rdatatype_eui64); - - return; -} - -static inline isc_result_t -additionaldata_eui64(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_eui64(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_eui64(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_eui64); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_eui64(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_eui64); - REQUIRE(rdata->length == 8); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_eui64(ARGS_COMPARE) { - return (compare_eui64(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_EUI64_109_C */ diff --git a/lib/dns-pkcs11/rdata/generic/eui64_109.h b/lib/dns-pkcs11/rdata/generic/eui64_109.h deleted file mode 100644 index 8c93137..0000000 --- a/lib/dns-pkcs11/rdata/generic/eui64_109.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_EUI64_109_H -#define GENERIC_EUI64_109_H 1 - -typedef struct dns_rdata_eui64 { - dns_rdatacommon_t common; - unsigned char eui64[8]; -} dns_rdata_eui64_t; - -#endif /* GENERIC_EUI64_10k_H */ diff --git a/lib/dns-pkcs11/rdata/generic/gpos_27.c b/lib/dns-pkcs11/rdata/generic/gpos_27.c deleted file mode 100644 index a54b8ee..0000000 --- a/lib/dns-pkcs11/rdata/generic/gpos_27.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1712 */ - -#ifndef RDATA_GENERIC_GPOS_27_C -#define RDATA_GENERIC_GPOS_27_C - -#define RRTYPE_GPOS_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_gpos(ARGS_FROMTEXT) { - isc_token_t token; - int i; - - REQUIRE(type == dns_rdatatype_gpos); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - for (i = 0; i < 3; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_gpos(ARGS_TOTEXT) { - isc_region_t region; - int i; - - REQUIRE(rdata->type == dns_rdatatype_gpos); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - - for (i = 0; i < 3; i++) { - RETERR(txt_totext(®ion, true, target)); - if (i != 2) - RETERR(str_totext(" ", target)); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_gpos(ARGS_FROMWIRE) { - int i; - - REQUIRE(type == dns_rdatatype_gpos); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - for (i = 0; i < 3; i++) - RETERR(txt_fromwire(source, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_gpos(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_gpos); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_gpos(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_gpos); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_gpos(ARGS_FROMSTRUCT) { - dns_rdata_gpos_t *gpos; - - REQUIRE(type == dns_rdatatype_gpos); - REQUIRE(((dns_rdata_gpos_t *)source) != NULL); - REQUIRE(((dns_rdata_gpos_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_gpos_t *)source)->common.rdclass == rdclass); - - gpos = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(gpos->long_len, target)); - RETERR(mem_tobuffer(target, gpos->longitude, gpos->long_len)); - RETERR(uint8_tobuffer(gpos->lat_len, target)); - RETERR(mem_tobuffer(target, gpos->latitude, gpos->lat_len)); - RETERR(uint8_tobuffer(gpos->alt_len, target)); - return (mem_tobuffer(target, gpos->altitude, gpos->alt_len)); -} - -static inline isc_result_t -tostruct_gpos(ARGS_TOSTRUCT) { - dns_rdata_gpos_t *gpos; - isc_region_t region; - - REQUIRE(((dns_rdata_gpos_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_gpos); - REQUIRE(rdata->length != 0); - - gpos = target; - - gpos->common.rdclass = rdata->rdclass; - gpos->common.rdtype = rdata->type; - ISC_LINK_INIT(&gpos->common, link); - - dns_rdata_toregion(rdata, ®ion); - gpos->long_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - gpos->longitude = mem_maybedup(mctx, region.base, gpos->long_len); - if (gpos->longitude == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(®ion, gpos->long_len); - - gpos->lat_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - gpos->latitude = mem_maybedup(mctx, region.base, gpos->lat_len); - if (gpos->latitude == NULL) - goto cleanup_longitude; - isc_region_consume(®ion, gpos->lat_len); - - gpos->alt_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - if (gpos->lat_len > 0) { - gpos->altitude = - mem_maybedup(mctx, region.base, gpos->alt_len); - if (gpos->altitude == NULL) - goto cleanup_latitude; - } else - gpos->altitude = NULL; - - gpos->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup_latitude: - if (mctx != NULL && gpos->longitude != NULL) - isc_mem_free(mctx, gpos->longitude); - - cleanup_longitude: - if (mctx != NULL && gpos->latitude != NULL) - isc_mem_free(mctx, gpos->latitude); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_gpos(ARGS_FREESTRUCT) { - dns_rdata_gpos_t *gpos; - - REQUIRE(((dns_rdata_gpos_t *)source) != NULL); - REQUIRE(((dns_rdata_gpos_t *)source)->common.rdtype == - dns_rdatatype_gpos); - - gpos = source; - - if (gpos->mctx == NULL) - return; - - if (gpos->longitude != NULL) - isc_mem_free(gpos->mctx, gpos->longitude); - if (gpos->latitude != NULL) - isc_mem_free(gpos->mctx, gpos->latitude); - if (gpos->altitude != NULL) - isc_mem_free(gpos->mctx, gpos->altitude); - gpos->mctx = NULL; -} - -static inline isc_result_t -additionaldata_gpos(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_gpos); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_gpos(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_gpos); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_gpos(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_gpos); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_gpos(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_gpos); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_gpos(ARGS_COMPARE) { - return (compare_gpos(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_GPOS_27_C */ diff --git a/lib/dns-pkcs11/rdata/generic/gpos_27.h b/lib/dns-pkcs11/rdata/generic/gpos_27.h deleted file mode 100644 index 45ceaf8..0000000 --- a/lib/dns-pkcs11/rdata/generic/gpos_27.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_GPOS_27_H -#define GENERIC_GPOS_27_H 1 - - -/*! - * \brief per RFC1712 */ - -typedef struct dns_rdata_gpos { - dns_rdatacommon_t common; - isc_mem_t *mctx; - char *longitude; - char *latitude; - char *altitude; - uint8_t long_len; - uint8_t lat_len; - uint8_t alt_len; -} dns_rdata_gpos_t; - -#endif /* GENERIC_GPOS_27_H */ diff --git a/lib/dns-pkcs11/rdata/generic/hinfo_13.c b/lib/dns-pkcs11/rdata/generic/hinfo_13.c deleted file mode 100644 index ce1c3c4..0000000 --- a/lib/dns-pkcs11/rdata/generic/hinfo_13.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_HINFO_13_C -#define RDATA_GENERIC_HINFO_13_C - -#define RRTYPE_HINFO_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_hinfo(ARGS_FROMTEXT) { - isc_token_t token; - int i; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - REQUIRE(type == dns_rdatatype_hinfo); - - for (i = 0; i < 2; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_hinfo(ARGS_TOTEXT) { - isc_region_t region; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_hinfo); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - RETERR(txt_totext(®ion, true, target)); - RETERR(str_totext(" ", target)); - return (txt_totext(®ion, true, target)); -} - -static inline isc_result_t -fromwire_hinfo(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_hinfo); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - RETERR(txt_fromwire(source, target)); - return (txt_fromwire(source, target)); -} - -static inline isc_result_t -towire_hinfo(ARGS_TOWIRE) { - - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_hinfo); - REQUIRE(rdata->length != 0); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_hinfo(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_hinfo); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_hinfo(ARGS_FROMSTRUCT) { - dns_rdata_hinfo_t *hinfo; - - REQUIRE(type == dns_rdatatype_hinfo); - REQUIRE(((dns_rdata_hinfo_t *)source) != NULL); - REQUIRE(((dns_rdata_hinfo_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_hinfo_t *)source)->common.rdclass == rdclass); - - hinfo = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(hinfo->cpu_len, target)); - RETERR(mem_tobuffer(target, hinfo->cpu, hinfo->cpu_len)); - RETERR(uint8_tobuffer(hinfo->os_len, target)); - return (mem_tobuffer(target, hinfo->os, hinfo->os_len)); -} - -static inline isc_result_t -tostruct_hinfo(ARGS_TOSTRUCT) { - dns_rdata_hinfo_t *hinfo; - isc_region_t region; - - REQUIRE(((dns_rdata_hinfo_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_hinfo); - REQUIRE(rdata->length != 0); - - hinfo = target; - - hinfo->common.rdclass = rdata->rdclass; - hinfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&hinfo->common, link); - - dns_rdata_toregion(rdata, ®ion); - hinfo->cpu_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - hinfo->cpu = mem_maybedup(mctx, region.base, hinfo->cpu_len); - if (hinfo->cpu == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(®ion, hinfo->cpu_len); - - hinfo->os_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - hinfo->os = mem_maybedup(mctx, region.base, hinfo->os_len); - if (hinfo->os == NULL) - goto cleanup; - - hinfo->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL && hinfo->cpu != NULL) - isc_mem_free(mctx, hinfo->cpu); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_hinfo(ARGS_FREESTRUCT) { - dns_rdata_hinfo_t *hinfo; - - REQUIRE(((dns_rdata_hinfo_t *)source) != NULL); - - hinfo = source; - - if (hinfo->mctx == NULL) - return; - - if (hinfo->cpu != NULL) - isc_mem_free(hinfo->mctx, hinfo->cpu); - if (hinfo->os != NULL) - isc_mem_free(hinfo->mctx, hinfo->os); - hinfo->mctx = NULL; -} - -static inline isc_result_t -additionaldata_hinfo(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_hinfo); - - UNUSED(add); - UNUSED(arg); - UNUSED(rdata); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_hinfo(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_hinfo); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_hinfo(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_hinfo); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_hinfo(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_hinfo); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_hinfo(ARGS_COMPARE) { - return (compare_hinfo(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_HINFO_13_C */ diff --git a/lib/dns-pkcs11/rdata/generic/hinfo_13.h b/lib/dns-pkcs11/rdata/generic/hinfo_13.h deleted file mode 100644 index 8583c75..0000000 --- a/lib/dns-pkcs11/rdata/generic/hinfo_13.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_HINFO_13_H -#define GENERIC_HINFO_13_H 1 - - -typedef struct dns_rdata_hinfo { - dns_rdatacommon_t common; - isc_mem_t *mctx; - char *cpu; - char *os; - uint8_t cpu_len; - uint8_t os_len; -} dns_rdata_hinfo_t; - -#endif /* GENERIC_HINFO_13_H */ diff --git a/lib/dns-pkcs11/rdata/generic/hip_55.c b/lib/dns-pkcs11/rdata/generic/hip_55.c deleted file mode 100644 index 7228097..0000000 --- a/lib/dns-pkcs11/rdata/generic/hip_55.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC 5205 */ - -#ifndef RDATA_GENERIC_HIP_5_C -#define RDATA_GENERIC_HIP_5_C - -#define RRTYPE_HIP_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_hip(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - isc_buffer_t hit_len; - isc_buffer_t key_len; - unsigned char *start; - size_t len; - - REQUIRE(type == dns_rdatatype_hip); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Dummy HIT len. - */ - hit_len = *target; - RETERR(uint8_tobuffer(0, target)); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Dummy KEY len. - */ - key_len = *target; - RETERR(uint16_tobuffer(0, target)); - - /* - * HIT (base16). - */ - start = isc_buffer_used(target); - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(isc_hex_decodestring(DNS_AS_STR(token), target)); - - /* - * Fill in HIT len. - */ - len = (unsigned char *)isc_buffer_used(target) - start; - if (len > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer((uint32_t)len, &hit_len)); - - /* - * Public key (base64). - */ - start = isc_buffer_used(target); - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(isc_base64_decodestring(DNS_AS_STR(token), target)); - - /* - * Fill in KEY len. - */ - len = (unsigned char *)isc_buffer_used(target) - start; - if (len > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer((uint32_t)len, &key_len)); - - if (origin == NULL) - origin = dns_rootname; - - /* - * Rendezvous Servers. - */ - dns_name_init(&name, NULL); - do { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - true)); - if (token.type != isc_tokentype_string) - break; - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, - target)); - } while (1); - - /* - * Let upper layer handle eol/eof. - */ - isc_lex_ungettoken(lexer, &token); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_hip(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - unsigned int length, key_len, hit_len; - unsigned char algorithm; - char buf[sizeof("225 ")]; - - REQUIRE(rdata->type == dns_rdatatype_hip); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - - hit_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - key_len = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext("( ", target)); - - /* - * Algorithm - */ - snprintf(buf, sizeof(buf), "%u ", algorithm); - RETERR(str_totext(buf, target)); - - /* - * HIT. - */ - INSIST(hit_len < region.length); - length = region.length; - region.length = hit_len; - RETERR(isc_hex_totext(®ion, 1, "", target)); - region.length = length - hit_len; - RETERR(str_totext(tctx->linebreak, target)); - - /* - * Public KEY. - */ - INSIST(key_len <= region.length); - length = region.length; - region.length = key_len; - RETERR(isc_base64_totext(®ion, 1, "", target)); - region.length = length - key_len; - if (region.length > 0) { - RETERR(str_totext(tctx->linebreak, target)); - } - - /* - * Rendezvous Servers. - */ - dns_name_init(&name, NULL); - while (region.length > 0) { - dns_name_fromregion(&name, ®ion); - - RETERR(dns_name_totext(&name, false, target)); - isc_region_consume(®ion, name.length); - if (region.length > 0) - RETERR(str_totext(tctx->linebreak, target)); - } - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_hip(ARGS_FROMWIRE) { - isc_region_t region, rr; - dns_name_t name; - uint8_t hit_len; - uint16_t key_len; - - REQUIRE(type == dns_rdatatype_hip); - - UNUSED(type); - UNUSED(rdclass); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 4U) - RETERR(DNS_R_FORMERR); - - rr = region; - hit_len = uint8_fromregion(®ion); - if (hit_len == 0) - RETERR(DNS_R_FORMERR); - isc_region_consume(®ion, 2); /* hit length + algorithm */ - key_len = uint16_fromregion(®ion); - if (key_len == 0) - RETERR(DNS_R_FORMERR); - isc_region_consume(®ion, 2); - if (region.length < (unsigned) (hit_len + key_len)) - RETERR(DNS_R_FORMERR); - - RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len)); - isc_buffer_forward(source, 4 + hit_len + key_len); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - while (isc_buffer_activelength(source) > 0) { - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_hip(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_hip); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_hip(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_hip); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_hip(ARGS_FROMSTRUCT) { - dns_rdata_hip_t *hip; - dns_rdata_hip_t myhip; - isc_result_t result; - - REQUIRE(type == dns_rdatatype_hip); - REQUIRE(((dns_rdata_hip_t *)source) != NULL); - REQUIRE(((dns_rdata_hip_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_hip_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_hip_t *)source)->hit_len > 0); - REQUIRE(((dns_rdata_hip_t *)source)->hit != NULL); - REQUIRE(((dns_rdata_hip_t *)source)->key_len > 0); - REQUIRE(((dns_rdata_hip_t *)source)->key != NULL); - REQUIRE((((dns_rdata_hip_t *)source)->servers == NULL && - ((dns_rdata_hip_t *)source)->servers_len == 0) || - (((dns_rdata_hip_t *)source)->servers != NULL && - ((dns_rdata_hip_t *)source)->servers_len != 0)); - - hip = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(hip->hit_len, target)); - RETERR(uint8_tobuffer(hip->algorithm, target)); - RETERR(uint16_tobuffer(hip->key_len, target)); - RETERR(mem_tobuffer(target, hip->hit, hip->hit_len)); - RETERR(mem_tobuffer(target, hip->key, hip->key_len)); - - myhip = *hip; - for (result = dns_rdata_hip_first(&myhip); - result == ISC_R_SUCCESS; - result = dns_rdata_hip_next(&myhip)) - /* empty */; - - return(mem_tobuffer(target, hip->servers, hip->servers_len)); -} - -static inline isc_result_t -tostruct_hip(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_hip_t *hip; - - REQUIRE(((dns_rdata_hip_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_hip); - REQUIRE(rdata->length != 0); - - hip = target; - - hip->common.rdclass = rdata->rdclass; - hip->common.rdtype = rdata->type; - ISC_LINK_INIT(&hip->common, link); - - dns_rdata_toregion(rdata, ®ion); - - hip->hit_len = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - hip->algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - hip->key_len = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - hip->hit = hip->key = hip->servers = NULL; - - hip->hit = mem_maybedup(mctx, region.base, hip->hit_len); - if (hip->hit == NULL) - goto cleanup; - isc_region_consume(®ion, hip->hit_len); - - INSIST(hip->key_len <= region.length); - - hip->key = mem_maybedup(mctx, region.base, hip->key_len); - if (hip->key == NULL) - goto cleanup; - isc_region_consume(®ion, hip->key_len); - - hip->servers_len = region.length; - if (hip->servers_len != 0) { - hip->servers = mem_maybedup(mctx, region.base, region.length); - if (hip->servers == NULL) - goto cleanup; - } - - hip->offset = hip->servers_len; - hip->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (hip->hit != NULL) - isc_mem_free(mctx, hip->hit); - if (hip->key != NULL) - isc_mem_free(mctx, hip->key); - if (hip->servers != NULL) - isc_mem_free(mctx, hip->servers); - return (ISC_R_NOMEMORY); - -} - -static inline void -freestruct_hip(ARGS_FREESTRUCT) { - dns_rdata_hip_t *hip; - - REQUIRE(((dns_rdata_hip_t *)source) != NULL); - - hip = source; - - if (hip->mctx == NULL) - return; - - isc_mem_free(hip->mctx, hip->hit); - isc_mem_free(hip->mctx, hip->key); - if (hip->servers != NULL) - isc_mem_free(hip->mctx, hip->servers); - hip->mctx = NULL; -} - -static inline isc_result_t -additionaldata_hip(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_hip); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_hip(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_hip); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_hip(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_hip); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_hip(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_hip); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -isc_result_t -dns_rdata_hip_first(dns_rdata_hip_t *hip) { - if (hip->servers_len == 0) - return (ISC_R_NOMORE); - hip->offset = 0; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdata_hip_next(dns_rdata_hip_t *hip) { - isc_region_t region; - dns_name_t name; - - if (hip->offset >= hip->servers_len) - return (ISC_R_NOMORE); - - region.base = hip->servers + hip->offset; - region.length = hip->servers_len - hip->offset; - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - hip->offset += name.length; - INSIST(hip->offset <= hip->servers_len); - return (hip->offset < hip->servers_len ? ISC_R_SUCCESS : ISC_R_NOMORE); -} - -void -dns_rdata_hip_current(dns_rdata_hip_t *hip, dns_name_t *name) { - isc_region_t region; - - REQUIRE(hip->offset < hip->servers_len); - - region.base = hip->servers + hip->offset; - region.length = hip->servers_len - hip->offset; - dns_name_fromregion(name, ®ion); - - INSIST(name->length + hip->offset <= hip->servers_len); -} - -static inline int -casecompare_hip(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - uint8_t hit_len; - uint16_t key_len; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_hip); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - - INSIST(r1.length > 4); - INSIST(r2.length > 4); - order = memcmp(r1.base, r2.base, 4); - if (order != 0) - return (order); - - hit_len = uint8_fromregion(&r1); - isc_region_consume(&r1, 2); /* hit length + algorithm */ - key_len = uint16_fromregion(&r1); - isc_region_consume(&r1, 2); /* key length */ - isc_region_consume(&r2, 4); - - INSIST(r1.length >= (unsigned) (hit_len + key_len)); - INSIST(r2.length >= (unsigned) (hit_len + key_len)); - order = memcmp(r1.base, r2.base, hit_len + key_len); - if (order != 0) - return (order); - isc_region_consume(&r1, hit_len + key_len); - isc_region_consume(&r2, hit_len + key_len); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - while (r1.length != 0 && r2.length != 0) { - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - } - return (isc_region_compare(&r1, &r2)); -} - -#endif /* RDATA_GENERIC_HIP_5_C */ diff --git a/lib/dns-pkcs11/rdata/generic/hip_55.h b/lib/dns-pkcs11/rdata/generic/hip_55.h deleted file mode 100644 index 7d88774..0000000 --- a/lib/dns-pkcs11/rdata/generic/hip_55.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_HIP_5_H -#define GENERIC_HIP_5_H 1 - -/* RFC 5205 */ - -typedef struct dns_rdata_hip { - dns_rdatacommon_t common; - isc_mem_t * mctx; - unsigned char * hit; - unsigned char * key; - unsigned char * servers; - uint8_t algorithm; - uint8_t hit_len; - uint16_t key_len; - uint16_t servers_len; - /* Private */ - uint16_t offset; -} dns_rdata_hip_t; - -isc_result_t -dns_rdata_hip_first(dns_rdata_hip_t *); - -isc_result_t -dns_rdata_hip_next(dns_rdata_hip_t *); - -void -dns_rdata_hip_current(dns_rdata_hip_t *, dns_name_t *); - -#endif /* GENERIC_HIP_5_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ipseckey_45.c b/lib/dns-pkcs11/rdata/generic/ipseckey_45.c deleted file mode 100644 index a02e48c..0000000 --- a/lib/dns-pkcs11/rdata/generic/ipseckey_45.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef RDATA_GENERIC_IPSECKEY_45_C -#define RDATA_GENERIC_IPSECKEY_45_C - -#include - -#include - -#define RRTYPE_IPSECKEY_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_ipseckey(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - unsigned int gateway; - struct in_addr addr; - unsigned char addr6[16]; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_ipseckey); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Precedence. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Gateway type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0x3U) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - gateway = token.value.as_ulong; - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Gateway. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - switch (gateway) { - case 0: - if (strcmp(DNS_AS_STR(token), ".") != 0) - RETTOK(DNS_R_SYNTAX); - break; - - case 1: - if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) - RETTOK(DNS_R_BADDOTTEDQUAD); - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) - return (ISC_R_NOSPACE); - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - break; - - case 2: - if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1) - RETTOK(DNS_R_BADAAAA); - isc_buffer_availableregion(target, ®ion); - if (region.length < 16) - return (ISC_R_NOSPACE); - memmove(region.base, addr6, 16); - isc_buffer_add(target, 16); - break; - - case 3: - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, - options, target)); - break; - } - - /* - * Public key. - */ - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_ipseckey(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - char buf[sizeof("255 ")]; - unsigned short num; - unsigned short gateway; - - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - REQUIRE(rdata->length >= 3); - - dns_name_init(&name, NULL); - - if (rdata->data[1] > 3U) - return (ISC_R_NOTIMPLEMENTED); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext("( ", target)); - - /* - * Precedence. - */ - dns_rdata_toregion(rdata, ®ion); - num = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u ", num); - RETERR(str_totext(buf, target)); - - /* - * Gateway type. - */ - gateway = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u ", gateway); - RETERR(str_totext(buf, target)); - - /* - * Algorithm. - */ - num = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - snprintf(buf, sizeof(buf), "%u ", num); - RETERR(str_totext(buf, target)); - - /* - * Gateway. - */ - switch (gateway) { - case 0: - RETERR(str_totext(".", target)); - break; - - case 1: - RETERR(inet_totext(AF_INET, tctx->flags, ®ion, target)); - isc_region_consume(®ion, 4); - break; - - case 2: - RETERR(inet_totext(AF_INET6, tctx->flags, ®ion, target)); - isc_region_consume(®ion, 16); - break; - - case 3: - dns_name_fromregion(&name, ®ion); - RETERR(dns_name_totext(&name, false, target)); - isc_region_consume(®ion, name_length(&name)); - break; - } - - /* - * Key. - */ - if (region.length > 0U) { - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(®ion, 60, "", target)); - else - RETERR(isc_base64_totext(®ion, tctx->width - 2, - tctx->linebreak, target)); - } - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_ipseckey(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_ipseckey); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 3) - return (ISC_R_UNEXPECTEDEND); - - switch (region.base[1]) { - case 0: - if (region.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 1: - if (region.length < 8) { - return (ISC_R_UNEXPECTEDEND); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 2: - if (region.length < 20) { - return (ISC_R_UNEXPECTEDEND); - } - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); - - case 3: - RETERR(mem_tobuffer(target, region.base, 3)); - isc_buffer_forward(source, 3); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - isc_buffer_activeregion(source, ®ion); - isc_buffer_forward(source, region.length); - if (region.length < 1) { - return (ISC_R_UNEXPECTEDEND); - } - return (mem_tobuffer(target, region.base, region.length)); - - default: - return (ISC_R_NOTIMPLEMENTED); - } -} - -static inline isc_result_t -towire_ipseckey(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_ipseckey(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ipseckey); - REQUIRE(rdata1->length >= 3); - REQUIRE(rdata2->length >= 3); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_ipseckey(ARGS_FROMSTRUCT) { - dns_rdata_ipseckey_t *ipseckey; - isc_region_t region; - uint32_t n; - - REQUIRE(type == dns_rdatatype_ipseckey); - REQUIRE(((dns_rdata_ipseckey_t *)source) != NULL); - REQUIRE(((dns_rdata_ipseckey_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_ipseckey_t *)source)->common.rdclass == rdclass); - - ipseckey = source; - - UNUSED(type); - UNUSED(rdclass); - - if (ipseckey->gateway_type > 3U) - return (ISC_R_NOTIMPLEMENTED); - - RETERR(uint8_tobuffer(ipseckey->precedence, target)); - RETERR(uint8_tobuffer(ipseckey->gateway_type, target)); - RETERR(uint8_tobuffer(ipseckey->algorithm, target)); - - switch (ipseckey->gateway_type) { - case 0: - break; - - case 1: - n = ntohl(ipseckey->in_addr.s_addr); - RETERR(uint32_tobuffer(n, target)); - break; - - case 2: - RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16)); - break; - - case 3: - dns_name_toregion(&ipseckey->gateway, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - break; - } - - return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength)); -} - -static inline isc_result_t -tostruct_ipseckey(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_ipseckey_t *ipseckey; - dns_name_t name; - uint32_t n; - - REQUIRE(((dns_rdata_ipseckey_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - REQUIRE(rdata->length >= 3); - - ipseckey = target; - - if (rdata->data[1] > 3U) - return (ISC_R_NOTIMPLEMENTED); - - ipseckey->common.rdclass = rdata->rdclass; - ipseckey->common.rdtype = rdata->type; - ISC_LINK_INIT(&ipseckey->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - - ipseckey->precedence = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - ipseckey->gateway_type = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - ipseckey->algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - - switch (ipseckey->gateway_type) { - case 0: - break; - - case 1: - n = uint32_fromregion(®ion); - ipseckey->in_addr.s_addr = htonl(n); - isc_region_consume(®ion, 4); - break; - - case 2: - memmove(ipseckey->in6_addr.s6_addr, region.base, 16); - isc_region_consume(®ion, 16); - break; - - case 3: - dns_name_init(&ipseckey->gateway, NULL); - dns_name_fromregion(&name, ®ion); - RETERR(name_duporclone(&name, mctx, &ipseckey->gateway)); - isc_region_consume(®ion, name_length(&name)); - break; - } - - ipseckey->keylength = region.length; - if (ipseckey->keylength != 0U) { - ipseckey->key = mem_maybedup(mctx, region.base, - ipseckey->keylength); - if (ipseckey->key == NULL) { - if (ipseckey->gateway_type == 3) - dns_name_free(&ipseckey->gateway, - ipseckey->mctx); - return (ISC_R_NOMEMORY); - } - } else - ipseckey->key = NULL; - - ipseckey->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_ipseckey(ARGS_FREESTRUCT) { - dns_rdata_ipseckey_t *ipseckey; - - REQUIRE(((dns_rdata_ipseckey_t *)source) != NULL); - REQUIRE(((dns_rdata_ipseckey_t *)source)->common.rdtype == - dns_rdatatype_ipseckey); - - ipseckey = source; - - if (ipseckey->mctx == NULL) - return; - - if (ipseckey->gateway_type == 3) - dns_name_free(&ipseckey->gateway, ipseckey->mctx); - - if (ipseckey->key != NULL) - isc_mem_free(ipseckey->mctx, ipseckey->key); - - ipseckey->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ipseckey(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ipseckey(ARGS_DIGEST) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - - dns_rdata_toregion(rdata, ®ion); - return ((digest)(arg, ®ion)); -} - -static inline bool -checkowner_ipseckey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ipseckey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_ipseckey(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_ipseckey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_ipseckey(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ipseckey); - REQUIRE(rdata1->length >= 3); - REQUIRE(rdata2->length >= 3); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3) - return (isc_region_compare(®ion1, ®ion2)); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - isc_region_consume(®ion1, 3); - isc_region_consume(®ion2, 3); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - return (isc_region_compare(®ion1, ®ion2)); -} - -#endif /* RDATA_GENERIC_IPSECKEY_45_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ipseckey_45.h b/lib/dns-pkcs11/rdata/generic/ipseckey_45.h deleted file mode 100644 index 642a7ba..0000000 --- a/lib/dns-pkcs11/rdata/generic/ipseckey_45.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_IPSECKEY_45_H -#define GENERIC_IPSECKEY_45_H 1 - -typedef struct dns_rdata_ipseckey { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint8_t precedence; - uint8_t gateway_type; - uint8_t algorithm; - struct in_addr in_addr; /* gateway type 1 */ - struct in6_addr in6_addr; /* gateway type 2 */ - dns_name_t gateway; /* gateway type 3 */ - unsigned char *key; - uint16_t keylength; -} dns_rdata_ipseckey_t; - -#endif /* GENERIC_IPSECKEY_45_H */ diff --git a/lib/dns-pkcs11/rdata/generic/isdn_20.c b/lib/dns-pkcs11/rdata/generic/isdn_20.c deleted file mode 100644 index 894d3f1..0000000 --- a/lib/dns-pkcs11/rdata/generic/isdn_20.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1183 */ - -#ifndef RDATA_GENERIC_ISDN_20_C -#define RDATA_GENERIC_ISDN_20_C - -#define RRTYPE_ISDN_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_isdn(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_isdn); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* ISDN-address */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* sa: optional */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - true)); - if (token.type != isc_tokentype_string && - token.type != isc_tokentype_qstring) { - isc_lex_ungettoken(lexer, &token); - return (ISC_R_SUCCESS); - } - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_isdn(ARGS_TOTEXT) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_isdn); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - RETERR(txt_totext(®ion, true, target)); - if (region.length == 0) - return (ISC_R_SUCCESS); - RETERR(str_totext(" ", target)); - return (txt_totext(®ion, true, target)); -} - -static inline isc_result_t -fromwire_isdn(ARGS_FROMWIRE) { - REQUIRE(type == dns_rdatatype_isdn); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - RETERR(txt_fromwire(source, target)); - if (buffer_empty(source)) - return (ISC_R_SUCCESS); - return (txt_fromwire(source, target)); -} - -static inline isc_result_t -towire_isdn(ARGS_TOWIRE) { - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_isdn); - REQUIRE(rdata->length != 0); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_isdn(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_isdn); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_isdn(ARGS_FROMSTRUCT) { - dns_rdata_isdn_t *isdn; - - REQUIRE(type == dns_rdatatype_isdn); - REQUIRE(((dns_rdata_isdn_t *)source) != NULL); - REQUIRE(((dns_rdata_isdn_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_isdn_t *)source)->common.rdclass == rdclass); - - isdn = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(isdn->isdn_len, target)); - RETERR(mem_tobuffer(target, isdn->isdn, isdn->isdn_len)); - if (isdn->subaddress == NULL) - return (ISC_R_SUCCESS); - RETERR(uint8_tobuffer(isdn->subaddress_len, target)); - return (mem_tobuffer(target, isdn->subaddress, isdn->subaddress_len)); -} - -static inline isc_result_t -tostruct_isdn(ARGS_TOSTRUCT) { - dns_rdata_isdn_t *isdn; - isc_region_t r; - - REQUIRE(((dns_rdata_isdn_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_isdn); - REQUIRE(rdata->length != 0); - - isdn = target; - - isdn->common.rdclass = rdata->rdclass; - isdn->common.rdtype = rdata->type; - ISC_LINK_INIT(&isdn->common, link); - - dns_rdata_toregion(rdata, &r); - - isdn->isdn_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - isdn->isdn = mem_maybedup(mctx, r.base, isdn->isdn_len); - if (isdn->isdn == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(&r, isdn->isdn_len); - - if (r.length == 0) { - isdn->subaddress_len = 0; - isdn->subaddress = NULL; - } else { - isdn->subaddress_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - isdn->subaddress = mem_maybedup(mctx, r.base, - isdn->subaddress_len); - if (isdn->subaddress == NULL) - goto cleanup; - } - - isdn->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL && isdn->isdn != NULL) - isc_mem_free(mctx, isdn->isdn); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_isdn(ARGS_FREESTRUCT) { - dns_rdata_isdn_t *isdn; - - REQUIRE(((dns_rdata_isdn_t *)source) != NULL); - - isdn = source; - - if (isdn->mctx == NULL) - return; - - if (isdn->isdn != NULL) - isc_mem_free(isdn->mctx, isdn->isdn); - if (isdn->subaddress != NULL) - isc_mem_free(isdn->mctx, isdn->subaddress); - isdn->mctx = NULL; -} - -static inline isc_result_t -additionaldata_isdn(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_isdn); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_isdn(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_isdn); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_isdn(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_isdn); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_isdn(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_isdn); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_isdn(ARGS_COMPARE) { - return (compare_isdn(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_ISDN_20_C */ diff --git a/lib/dns-pkcs11/rdata/generic/isdn_20.h b/lib/dns-pkcs11/rdata/generic/isdn_20.h deleted file mode 100644 index 63aa87d..0000000 --- a/lib/dns-pkcs11/rdata/generic/isdn_20.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_ISDN_20_H -#define GENERIC_ISDN_20_H 1 - - -/*! - * \brief Per RFC1183 */ - -typedef struct dns_rdata_isdn { - dns_rdatacommon_t common; - isc_mem_t *mctx; - char *isdn; - char *subaddress; - uint8_t isdn_len; - uint8_t subaddress_len; -} dns_rdata_isdn_t; - -#endif /* GENERIC_ISDN_20_H */ diff --git a/lib/dns-pkcs11/rdata/generic/key_25.c b/lib/dns-pkcs11/rdata/generic/key_25.c deleted file mode 100644 index 51f928b..0000000 --- a/lib/dns-pkcs11/rdata/generic/key_25.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2535 */ - -#ifndef RDATA_GENERIC_KEY_25_C -#define RDATA_GENERIC_KEY_25_C - -#include - -#define RRTYPE_KEY_ATTRIBUTES \ - ( DNS_RDATATYPEATTR_ATCNAME | DNS_RDATATYPEATTR_ZONECUTAUTH ) - -/* - * RFC 2535 section 3.1.2 says that if bits 0-1 of the Flags field are - * both set, it means there is no key information and the RR stops after - * the algorithm octet. However, this only applies to KEY records, as - * indicated by the specifications of the RR types based on KEY: - * - * CDNSKEY - RFC 7344 - * DNSKEY - RFC 4034 - * RKEY - draft-reid-dnsext-rkey-00 - */ -static inline bool -generic_key_nokey(dns_rdatatype_t type, unsigned int flags) { - switch (type) { - case dns_rdatatype_cdnskey: - case dns_rdatatype_dnskey: - case dns_rdatatype_rkey: - return (false); - case dns_rdatatype_key: - default: - return ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY); - } -} - -static inline isc_result_t -generic_fromtext_key(ARGS_FROMTEXT) { - isc_result_t result; - isc_token_t token; - dns_secalg_t alg; - dns_secproto_t proto; - dns_keyflags_t flags; - - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* flags */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); - if (type == dns_rdatatype_rkey && flags != 0U) { - RETTOK(DNS_R_FORMERR); - } - RETERR(uint16_tobuffer(flags, target)); - - /* protocol */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &proto, 1)); - - /* algorithm */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &alg, 1)); - - /* No Key? */ - if (generic_key_nokey(type, flags)) { - return (ISC_R_SUCCESS); - } - - result = isc_base64_tobuffer(lexer, target, -2); - if (result != ISC_R_SUCCESS) - return (result); - - /* Ensure there's at least enough data to compute a key ID for MD5 */ - if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) - return (ISC_R_UNEXPECTEDEND); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -generic_totext_key(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("[key id = 64000]")]; - unsigned int flags; - unsigned char algorithm; - char algbuf[DNS_NAME_FORMATSIZE]; - const char *keyinfo; - isc_region_t tmpr; - - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* flags */ - flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u", flags); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - if ((flags & DNS_KEYFLAG_KSK) != 0) { - if (flags & DNS_KEYFLAG_REVOKE) - keyinfo = "revoked KSK"; - else - keyinfo = "KSK"; - } else - keyinfo = "ZSK"; - - - /* protocol */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* algorithm */ - algorithm = sr.base[0]; - snprintf(buf, sizeof(buf), "%u", algorithm); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - - /* No Key? */ - if (generic_key_nokey(rdata->type, flags)) { - return (ISC_R_SUCCESS); - } - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && - algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &sr); - dns_name_format(&name, algbuf, sizeof(algbuf)); - } else { - dns_secalg_format((dns_secalg_t) algorithm, algbuf, - sizeof(algbuf)); - } - - /* key */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else { - dns_rdata_toregion(rdata, &tmpr); - snprintf(buf, sizeof(buf), "[key id = %u]", - dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) - RETERR(str_totext(tctx->linebreak, target)); - else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(")", target)); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { - - if (rdata->type == dns_rdatatype_dnskey || - rdata->type == dns_rdatatype_cdnskey) { - RETERR(str_totext(" ; ", target)); - RETERR(str_totext(keyinfo, target)); - } - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(algbuf, target)); - RETERR(str_totext(" ; key id = ", target)); - dns_rdata_toregion(rdata, &tmpr); - snprintf(buf, sizeof(buf), "%u", - dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -generic_fromwire_key(ARGS_FROMWIRE) { - unsigned char algorithm; - uint16_t flags; - isc_region_t sr; - - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - flags = (sr.base[0] << 8) | sr.base[1]; - - if (type == dns_rdatatype_rkey && flags != 0U) { - return (DNS_R_FORMERR); - } - - algorithm = sr.base[3]; - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - isc_buffer_forward(source, 4); - - if (generic_key_nokey(type, flags)) { - return (ISC_R_SUCCESS); - } - if (sr.length == 0) { - return (ISC_R_UNEXPECTEDEND); - } - - if (algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - } - - /* - * RSAMD5 computes key ID differently from other - * algorithms: we need to ensure there's enough data - * present for the computation - */ - if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -fromtext_key(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_key); - - return (generic_fromtext_key(rdclass, type, lexer, origin, - options, target, callbacks)); -} - -static inline isc_result_t -totext_key(ARGS_TOTEXT) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - - return (generic_totext_key(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_key(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_key); - - return (generic_fromwire_key(rdclass, type, source, dctx, - options, target)); -} - -static inline isc_result_t -towire_key(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_key(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_key); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -generic_fromstruct_key(ARGS_FROMSTRUCT) { - dns_rdata_key_t *key; - - REQUIRE(((dns_rdata_key_t *)source) != NULL); - REQUIRE(((dns_rdata_key_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_key_t *)source)->common.rdclass == rdclass); - - key = source; - - UNUSED(type); - UNUSED(rdclass); - - if (type == dns_rdatatype_rkey) { - INSIST(key->flags == 0U); - } - - /* Flags */ - RETERR(uint16_tobuffer(key->flags, target)); - - /* Protocol */ - RETERR(uint8_tobuffer(key->protocol, target)); - - /* Algorithm */ - RETERR(uint8_tobuffer(key->algorithm, target)); - - /* Data */ - return (mem_tobuffer(target, key->data, key->datalen)); -} - -static inline isc_result_t -generic_tostruct_key(ARGS_TOSTRUCT) { - dns_rdata_key_t *key; - isc_region_t sr; - - REQUIRE(rdata->length != 0); - REQUIRE(((dns_rdata_key_t *)target) != NULL); - REQUIRE(((dns_rdata_key_t *)target)->common.rdclass == rdata->rdclass); - REQUIRE(((dns_rdata_key_t *)target)->common.rdtype == rdata->type); - REQUIRE(!ISC_LINK_LINKED(&((dns_rdata_key_t *)target)->common, link)); - - key = target; - - dns_rdata_toregion(rdata, &sr); - - /* Flags */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - key->flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* Protocol */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - key->protocol = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Algorithm */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - key->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Data */ - key->datalen = sr.length; - key->data = mem_maybedup(mctx, sr.base, key->datalen); - if (key->data == NULL) - return (ISC_R_NOMEMORY); - - key->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -generic_freestruct_key(ARGS_FREESTRUCT) { - dns_rdata_key_t *key; - - REQUIRE(((dns_rdata_key_t *)source) != NULL); - - key = (dns_rdata_key_t *) source; - - if (key->mctx == NULL) - return; - - if (key->data != NULL) - isc_mem_free(key->mctx, key->data); - key->mctx = NULL; -} - -static inline isc_result_t -fromstruct_key(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_key); - - return (generic_fromstruct_key(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_key(ARGS_TOSTRUCT) { - dns_rdata_key_t *key; - - REQUIRE(((dns_rdata_key_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - - key = target; - - key->common.rdclass = rdata->rdclass; - key->common.rdtype = rdata->type; - ISC_LINK_INIT(&key->common, link); - - return (generic_tostruct_key(rdata, target, mctx)); -} - -static inline void -freestruct_key(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_key_t *)source) != NULL); - REQUIRE(((dns_rdata_key_t *)source)->common.rdtype == - dns_rdatatype_key); - - generic_freestruct_key(source); -} - -static inline isc_result_t -additionaldata_key(ARGS_ADDLDATA) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_key(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_key(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_key); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_key(ARGS_CHECKNAMES) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_key); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_key(ARGS_COMPARE) { - return (compare_key(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_KEY_25_C */ diff --git a/lib/dns-pkcs11/rdata/generic/key_25.h b/lib/dns-pkcs11/rdata/generic/key_25.h deleted file mode 100644 index 8b0620b..0000000 --- a/lib/dns-pkcs11/rdata/generic/key_25.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_KEY_25_H -#define GENERIC_KEY_25_H 1 - - -/*! - * \brief Per RFC2535 */ - -typedef struct dns_rdata_key { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint16_t flags; - dns_secproto_t protocol; - dns_secalg_t algorithm; - uint16_t datalen; - unsigned char * data; -} dns_rdata_key_t; - - -#endif /* GENERIC_KEY_25_H */ diff --git a/lib/dns-pkcs11/rdata/generic/keydata_65533.c b/lib/dns-pkcs11/rdata/generic/keydata_65533.c deleted file mode 100644 index 3a43eee..0000000 --- a/lib/dns-pkcs11/rdata/generic/keydata_65533.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_KEYDATA_65533_C -#define GENERIC_KEYDATA_65533_C 1 - -#include -#include - -#include - -#define RRTYPE_KEYDATA_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_keydata(ARGS_FROMTEXT) { - isc_result_t result; - isc_token_t token; - dns_secalg_t alg; - dns_secproto_t proto; - dns_keyflags_t flags; - uint32_t refresh, addhd, removehd; - - REQUIRE(type == dns_rdatatype_keydata); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* refresh timer */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); - RETERR(uint32_tobuffer(refresh, target)); - - /* add hold-down */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); - RETERR(uint32_tobuffer(addhd, target)); - - /* remove hold-down */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); - RETERR(uint32_tobuffer(removehd, target)); - - /* flags */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); - RETERR(uint16_tobuffer(flags, target)); - - /* protocol */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &proto, 1)); - - /* algorithm */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &alg, 1)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - result = isc_base64_tobuffer(lexer, target, -2); - if (result != ISC_R_SUCCESS) - return (result); - - /* Ensure there's at least enough data to compute a key ID for MD5 */ - if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 19) - return (ISC_R_UNEXPECTEDEND); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_keydata(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("64000")]; - unsigned int flags; - unsigned char algorithm; - unsigned long refresh, add, deltime; - char algbuf[DNS_NAME_FORMATSIZE]; - const char *keyinfo; - - REQUIRE(rdata->type == dns_rdatatype_keydata); - - if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) - return (unknown_totext(rdata, tctx, target)); - - dns_rdata_toregion(rdata, &sr); - - /* refresh timer */ - refresh = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(refresh, target)); - RETERR(str_totext(" ", target)); - - /* add hold-down */ - add = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(add, target)); - RETERR(str_totext(" ", target)); - - /* remove hold-down */ - deltime = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(deltime, target)); - RETERR(str_totext(" ", target)); - - /* flags */ - flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u", flags); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - if ((flags & DNS_KEYFLAG_KSK) != 0) { - if ((flags & DNS_KEYFLAG_REVOKE) != 0) { - keyinfo = "revoked KSK"; - } else { - keyinfo = "KSK"; - } - } else { - keyinfo = "ZSK"; - } - - /* protocol */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* algorithm */ - algorithm = sr.base[0]; - snprintf(buf, sizeof(buf), "%u", algorithm); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - /* key */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) - RETERR(str_totext(tctx->linebreak, target)); - else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(")", target)); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { - isc_region_t tmpr; - char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; - isc_time_t t; - - RETERR(str_totext(" ; ", target)); - RETERR(str_totext(keyinfo, target)); - dns_secalg_format((dns_secalg_t) algorithm, algbuf, - sizeof(algbuf)); - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(algbuf, target)); - RETERR(str_totext("; key id = ", target)); - dns_rdata_toregion(rdata, &tmpr); - /* Skip over refresh, addhd, and removehd */ - isc_region_consume(&tmpr, 12); - snprintf(buf, sizeof(buf), "%u", - dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - isc_stdtime_t now; - - isc_stdtime_get(&now); - - RETERR(str_totext(tctx->linebreak, target)); - RETERR(str_totext("; next refresh: ", target)); - isc_time_set(&t, refresh, 0); - isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf)); - RETERR(str_totext(rbuf, target)); - - if (add == 0U) { - RETERR(str_totext(tctx->linebreak, target)); - RETERR(str_totext("; no trust", target)); - } else { - RETERR(str_totext(tctx->linebreak, target)); - if (add < now) { - RETERR(str_totext("; trusted since: ", - target)); - } else { - RETERR(str_totext("; trust pending: ", - target)); - } - isc_time_set(&t, add, 0); - isc_time_formathttptimestamp(&t, abuf, - sizeof(abuf)); - RETERR(str_totext(abuf, target)); - } - - if (deltime != 0U) { - RETERR(str_totext(tctx->linebreak, target)); - RETERR(str_totext("; removal pending: ", - target)); - isc_time_set(&t, deltime, 0); - isc_time_formathttptimestamp(&t, dbuf, - sizeof(dbuf)); - RETERR(str_totext(dbuf, target)); - } - } - - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_keydata(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_keydata); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_keydata(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_keydata); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_keydata(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_keydata); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_keydata(ARGS_FROMSTRUCT) { - dns_rdata_keydata_t *keydata; - - REQUIRE(type == dns_rdatatype_keydata); - REQUIRE(((dns_rdata_keydata_t *)source) != NULL); - REQUIRE(((dns_rdata_keydata_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_keydata_t *)source)->common.rdclass == rdclass); - - keydata = source; - - UNUSED(type); - UNUSED(rdclass); - - /* Refresh timer */ - RETERR(uint32_tobuffer(keydata->refresh, target)); - - /* Add hold-down */ - RETERR(uint32_tobuffer(keydata->addhd, target)); - - /* Remove hold-down */ - RETERR(uint32_tobuffer(keydata->removehd, target)); - - /* Flags */ - RETERR(uint16_tobuffer(keydata->flags, target)); - - /* Protocol */ - RETERR(uint8_tobuffer(keydata->protocol, target)); - - /* Algorithm */ - RETERR(uint8_tobuffer(keydata->algorithm, target)); - - /* Data */ - return (mem_tobuffer(target, keydata->data, keydata->datalen)); -} - -static inline isc_result_t -tostruct_keydata(ARGS_TOSTRUCT) { - dns_rdata_keydata_t *keydata; - - REQUIRE(rdata->type == dns_rdatatype_keydata); - REQUIRE(((dns_rdata_keydata_t *)target) != NULL); - - keydata = target; - isc_region_t sr; - - keydata->common.rdclass = rdata->rdclass; - keydata->common.rdtype = rdata->type; - ISC_LINK_INIT(&keydata->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* Refresh timer */ - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - keydata->refresh = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* Add hold-down */ - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - keydata->addhd = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* Remove hold-down */ - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - keydata->removehd = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* Flags */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - keydata->flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* Protocol */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - keydata->protocol = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Algorithm */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - keydata->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Data */ - keydata->datalen = sr.length; - keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); - if (keydata->data == NULL) - return (ISC_R_NOMEMORY); - - keydata->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_keydata(ARGS_FREESTRUCT) { - dns_rdata_keydata_t *keydata; - - REQUIRE(((dns_rdata_keydata_t *)source) != NULL); - REQUIRE(((dns_rdata_keydata_t *)source)->common.rdtype == - dns_rdatatype_keydata); - - keydata = (dns_rdata_keydata_t *) source; - - if (keydata->mctx == NULL) - return; - - if (keydata->data != NULL) - isc_mem_free(keydata->mctx, keydata->data); - keydata->mctx = NULL; -} - -static inline isc_result_t -additionaldata_keydata(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_keydata); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_keydata(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_keydata); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_keydata(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_keydata); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_keydata(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_keydata); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_keydata(ARGS_COMPARE) { - return (compare_keydata(rdata1, rdata2)); -} - -#endif /* GENERIC_KEYDATA_65533_C */ diff --git a/lib/dns-pkcs11/rdata/generic/keydata_65533.h b/lib/dns-pkcs11/rdata/generic/keydata_65533.h deleted file mode 100644 index ba22d74..0000000 --- a/lib/dns-pkcs11/rdata/generic/keydata_65533.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_KEYDATA_65533_H -#define GENERIC_KEYDATA_65533_H 1 - - -typedef struct dns_rdata_keydata { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint32_t refresh; /* Timer for refreshing data */ - uint32_t addhd; /* Hold-down timer for adding */ - uint32_t removehd; /* Hold-down timer for removing */ - uint16_t flags; /* Copy of DNSKEY_48 */ - dns_secproto_t protocol; - dns_secalg_t algorithm; - uint16_t datalen; - unsigned char * data; -} dns_rdata_keydata_t; - -#endif /* GENERIC_KEYDATA_65533_H */ diff --git a/lib/dns-pkcs11/rdata/generic/l32_105.c b/lib/dns-pkcs11/rdata/generic/l32_105.c deleted file mode 100644 index 8f05b58..0000000 --- a/lib/dns-pkcs11/rdata/generic/l32_105.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_L32_105_C -#define RDATA_GENERIC_L32_105_C - -#include - -#include - -#define RRTYPE_L32_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_l32(ARGS_FROMTEXT) { - isc_token_t token; - struct in_addr addr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_l32); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) - RETTOK(DNS_R_BADDOTTEDQUAD); - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) - return (ISC_R_NOSPACE); - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_l32(ARGS_TOTEXT) { - isc_region_t region; - char buf[sizeof("65000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - return (inet_totext(AF_INET, tctx->flags, ®ion, target)); -} - -static inline isc_result_t -fromwire_l32(ARGS_FROMWIRE) { - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_l32); - - UNUSED(type); - UNUSED(options); - UNUSED(rdclass); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length != 6) - return (DNS_R_FORMERR); - isc_buffer_forward(source, sregion.length); - return (mem_tobuffer(target, sregion.base, sregion.length)); -} - -static inline isc_result_t -towire_l32(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_l32(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_l32); - REQUIRE(rdata1->length == 6); - REQUIRE(rdata2->length == 6); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_l32(ARGS_FROMSTRUCT) { - dns_rdata_l32_t *l32; - uint32_t n; - - REQUIRE(type == dns_rdatatype_l32); - REQUIRE(((dns_rdata_l32_t *)source) != NULL); - REQUIRE(((dns_rdata_l32_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_l32_t *)source)->common.rdclass == rdclass); - - l32 = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(l32->pref, target)); - n = ntohl(l32->l32.s_addr); - return (uint32_tobuffer(n, target)); -} - -static inline isc_result_t -tostruct_l32(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_l32_t *l32; - uint32_t n; - - REQUIRE(((dns_rdata_l32_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - l32 = target; - - UNUSED(mctx); - - l32->common.rdclass = rdata->rdclass; - l32->common.rdtype = rdata->type; - ISC_LINK_INIT(&l32->common, link); - - dns_rdata_toregion(rdata, ®ion); - l32->pref = uint16_fromregion(®ion); - n = uint32_fromregion(®ion); - l32->l32.s_addr = htonl(n); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_l32(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_l32_t *)source) != NULL); - REQUIRE(((dns_rdata_l32_t *)source)->common.rdtype == - dns_rdatatype_l32); - - return; -} - -static inline isc_result_t -additionaldata_l32(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_l32(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_l32(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_l32); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_l32(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_l32); - REQUIRE(rdata->length == 6); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_l32(ARGS_COMPARE) { - return (compare_l32(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_L32_105_C */ diff --git a/lib/dns-pkcs11/rdata/generic/l32_105.h b/lib/dns-pkcs11/rdata/generic/l32_105.h deleted file mode 100644 index 4b12b94..0000000 --- a/lib/dns-pkcs11/rdata/generic/l32_105.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_L32_105_H -#define GENERIC_L32_105_H 1 - -typedef struct dns_rdata_l32 { - dns_rdatacommon_t common; - uint16_t pref; - struct in_addr l32; -} dns_rdata_l32_t; - -#endif /* GENERIC_L32_105_H */ diff --git a/lib/dns-pkcs11/rdata/generic/l64_106.c b/lib/dns-pkcs11/rdata/generic/l64_106.c deleted file mode 100644 index 94d1cfc..0000000 --- a/lib/dns-pkcs11/rdata/generic/l64_106.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_L64_106_C -#define RDATA_GENERIC_L64_106_C - -#include - -#include - -#define RRTYPE_L64_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_l64(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char locator[NS_LOCATORSZ]; - - REQUIRE(type == dns_rdatatype_l64); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (locator_pton(DNS_AS_STR(token), locator) != 1) - RETTOK(DNS_R_SYNTAX); - return (mem_tobuffer(target, locator, NS_LOCATORSZ)); -} - -static inline isc_result_t -totext_l64(ARGS_TOTEXT) { - isc_region_t region; - char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - snprintf(buf, sizeof(buf), "%x:%x:%x:%x", - region.base[0]<<8 | region.base[1], - region.base[2]<<8 | region.base[3], - region.base[4]<<8 | region.base[5], - region.base[6]<<8 | region.base[7]); - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_l64(ARGS_FROMWIRE) { - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_l64); - - UNUSED(type); - UNUSED(options); - UNUSED(rdclass); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length != 10) - return (DNS_R_FORMERR); - isc_buffer_forward(source, sregion.length); - return (mem_tobuffer(target, sregion.base, sregion.length)); -} - -static inline isc_result_t -towire_l64(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_l64(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_l64); - REQUIRE(rdata1->length == 10); - REQUIRE(rdata2->length == 10); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_l64(ARGS_FROMSTRUCT) { - dns_rdata_l64_t *l64; - - REQUIRE(type == dns_rdatatype_l64); - REQUIRE(((dns_rdata_l64_t *)source) != NULL); - REQUIRE(((dns_rdata_l64_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_l64_t *)source)->common.rdclass == rdclass); - - l64 = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(l64->pref, target)); - return (mem_tobuffer(target, l64->l64, sizeof(l64->l64))); -} - -static inline isc_result_t -tostruct_l64(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_l64_t *l64; - - REQUIRE(((dns_rdata_l64_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - l64 = target; - - UNUSED(mctx); - - l64->common.rdclass = rdata->rdclass; - l64->common.rdtype = rdata->type; - ISC_LINK_INIT(&l64->common, link); - - dns_rdata_toregion(rdata, ®ion); - l64->pref = uint16_fromregion(®ion); - memmove(l64->l64, region.base, region.length); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_l64(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_l64_t *)source) != NULL); - REQUIRE(((dns_rdata_l64_t *)source)->common.rdtype == - dns_rdatatype_l64); - - return; -} - -static inline isc_result_t -additionaldata_l64(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_l64(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_l64(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_l64); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_l64(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_l64); - REQUIRE(rdata->length == 10); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_l64(ARGS_COMPARE) { - return (compare_l64(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_L64_106_C */ diff --git a/lib/dns-pkcs11/rdata/generic/l64_106.h b/lib/dns-pkcs11/rdata/generic/l64_106.h deleted file mode 100644 index 4f176ac..0000000 --- a/lib/dns-pkcs11/rdata/generic/l64_106.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_L64_106_H -#define GENERIC_L64_106_H 1 - -typedef struct dns_rdata_l64 { - dns_rdatacommon_t common; - uint16_t pref; - unsigned char l64[8]; -} dns_rdata_l64_t; - -#endif /* GENERIC_L64_106_H */ diff --git a/lib/dns-pkcs11/rdata/generic/loc_29.c b/lib/dns-pkcs11/rdata/generic/loc_29.c deleted file mode 100644 index 068c1d2..0000000 --- a/lib/dns-pkcs11/rdata/generic/loc_29.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1876 */ - -#ifndef RDATA_GENERIC_LOC_29_C -#define RDATA_GENERIC_LOC_29_C - -#define RRTYPE_LOC_ATTRIBUTES (0) - -static isc_result_t -loc_getdecimal(const char *str, unsigned long max, size_t precision, char units, - unsigned long *valuep) { - bool ok; - char *e; - size_t i; - long tmp; - unsigned long value; - - value = strtoul(str, &e, 10); - if (*e != 0 && *e != '.' && *e != units) { - return (DNS_R_SYNTAX); - } - if (value > max) { - return (ISC_R_RANGE); - } - ok = e != str; - if (*e == '.') { - e++; - for (i = 0; i < precision; i++) { - if (*e == 0 || *e == units) { - break; - } - if ((tmp = decvalue(*e++)) < 0) { - return (DNS_R_SYNTAX); - } - ok = true; - value *= 10; - value += tmp; - } - for (; i < precision; i++) { - value *= 10; - } - } else { - for (i = 0; i < precision; i++) { - value *= 10; - } - } - if (*e != 0 && *e == units) { - e++; - } - if (!ok || *e != 0) { - return (DNS_R_SYNTAX); - } - *valuep = value; - return (ISC_R_SUCCESS); -} - -static isc_result_t -loc_getprecision(const char *str, unsigned char *valuep) { - unsigned long poweroften[8] = { 1, 10, 100, 1000, - 10000, 100000, 1000000, 10000000 }; - unsigned long m, cm; - bool ok; - char *e; - size_t i; - long tmp; - int man; - int exp; - - m = strtoul(str, &e, 10); - if (*e != 0 && *e != '.' && *e != 'm') { - return (DNS_R_SYNTAX); - } - if (m > 90000000) { - return (ISC_R_RANGE); - } - cm = 0; - ok = e != str; - if (*e == '.') { - e++; - for (i = 0; i < 2; i++) { - if (*e == 0 || *e == 'm') { - break; - } - if ((tmp = decvalue(*e++)) < 0) { - return (DNS_R_SYNTAX); - } - ok = true; - cm *= 10; - cm += tmp; - } - for (; i < 2; i++) { - cm *= 10; - } - } - if (*e == 'm') { - e++; - } - if (!ok || *e != 0) { - return (DNS_R_SYNTAX); - } - - /* - * We don't just multiply out as we will overflow. - */ - if (m > 0) { - for (exp = 0; exp < 7; exp++) { - if (m < poweroften[exp + 1]) { - break; - } - } - man = m / poweroften[exp]; - exp += 2; - } else if (cm >= 10) { - man = cm / 10; - exp = 1; - } else { - man = cm; - exp = 0; - } - *valuep = (man << 4) + exp; - return (ISC_R_SUCCESS); -} - -static isc_result_t -get_degrees(isc_lex_t *lexer, isc_token_t *token, unsigned long *d) { - RETERR(isc_lex_getmastertoken(lexer, token, isc_tokentype_number, - false)); - *d = token->value.as_ulong; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -check_coordinate(unsigned long d, unsigned long m, unsigned long s, - unsigned long maxd) { - if (d > maxd || m > 59U) { - return (ISC_R_RANGE); - } - if (d == maxd && (m != 0 || s != 0)) { - return (ISC_R_RANGE); - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -get_minutes(isc_lex_t *lexer, isc_token_t *token, unsigned long *m) { - RETERR(isc_lex_getmastertoken(lexer, token, isc_tokentype_number, - false)); - - *m = token->value.as_ulong; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -get_seconds(isc_lex_t *lexer, isc_token_t *token, unsigned long *s) { - RETERR(isc_lex_getmastertoken(lexer, token, isc_tokentype_string, - false)); - RETERR(loc_getdecimal(DNS_AS_STR(*token), 59, 3, '\0', s)); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -get_direction(isc_lex_t *lexer, isc_token_t *token, const char *directions, - int *direction) { - RETERR(isc_lex_getmastertoken(lexer, token, isc_tokentype_string, - false)); - if (DNS_AS_STR(*token)[0] == directions[1] && - DNS_AS_STR(*token)[1] == 0) { - *direction = DNS_AS_STR(*token)[0]; - return (ISC_R_SUCCESS); - } - - if (DNS_AS_STR(*token)[0] == directions[0] && - DNS_AS_STR(*token)[1] == 0) { - *direction = DNS_AS_STR(*token)[0]; - return (ISC_R_SUCCESS); - } - - *direction = 0; - isc_lex_ungettoken(lexer, token); - return (ISC_R_SUCCESS); -} - -static isc_result_t -loc_getcoordinate(isc_lex_t *lexer, unsigned long *dp, unsigned long *mp, - unsigned long *sp, const char *directions, int *directionp, - unsigned long maxd) { - isc_result_t result = ISC_R_SUCCESS; - isc_token_t token; - unsigned long d, m, s; - int direction = 0; - - m = 0; - s = 0; - - /* - * Degrees. - */ - RETERR(get_degrees(lexer, &token, &d)); - RETTOK(check_coordinate(d, m, s, maxd)); - - /* - * Minutes. - */ - RETERR(get_direction(lexer, &token, directions, &direction)); - if (direction > 0) { - goto done; - } - - RETERR(get_minutes(lexer, &token, &m)); - RETTOK(check_coordinate(d, m, s, maxd)); - - /* - * Seconds. - */ - RETERR(get_direction(lexer, &token, directions, &direction)); - if (direction > 0) { - goto done; - } - - result = get_seconds(lexer, &token, &s); - if (result == ISC_R_RANGE || result == DNS_R_SYNTAX) { - RETTOK(result); - } - RETERR(result); - RETTOK(check_coordinate(d, m, s, maxd)); - - /* - * Direction. - */ - RETERR(get_direction(lexer, &token, directions, &direction)); - if (direction == -1) { - RETERR(DNS_R_SYNTAX); - } -done: - - *directionp = direction; - *dp = d; - *mp = m; - *sp = s; - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -loc_getlatitude(isc_lex_t *lexer, unsigned long *latitude) { - unsigned long d1 = 0, m1 = 0, s1 = 0; - int direction = 0; - - RETERR(loc_getcoordinate(lexer, &d1, &m1, &s1, "SN", &direction, 90U)); - - switch (direction) { - case 'N': - *latitude = 0x80000000 + (d1 * 3600 + m1 * 60) * 1000 + s1; - break; - case 'S': - *latitude = 0x80000000 - (d1 * 3600 + m1 * 60) * 1000 - s1; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -loc_getlongitude(isc_lex_t *lexer, unsigned long *longitude) { - unsigned long d2 = 0, m2 = 0, s2 = 0; - int direction = 0; - - RETERR(loc_getcoordinate(lexer, &d2, &m2, &s2, "WE", &direction, 180U)); - - switch (direction) { - case 'E': - *longitude = 0x80000000 + (d2 * 3600 + m2 * 60) * 1000 + s2; - break; - case 'W': - *longitude = 0x80000000 - (d2 * 3600 + m2 * 60) * 1000 - s2; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -loc_getaltitude(isc_lex_t *lexer, unsigned long *altitude) { - isc_token_t token; - unsigned long cm; - const char *str; - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - str = DNS_AS_STR(token); - if (DNS_AS_STR(token)[0] == '-') { - RETTOK(loc_getdecimal(str + 1, 100000, 2, 'm', &cm)); - if (cm > 10000000UL) { - RETTOK(ISC_R_RANGE); - } - *altitude = 10000000 - cm; - } else { - RETTOK(loc_getdecimal(str, 42849672, 2, 'm', &cm)); - if (cm > 4284967295UL) { - RETTOK(ISC_R_RANGE); - } - *altitude = 10000000 + cm; - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -loc_getoptionalprecision(isc_lex_t *lexer, unsigned char *valuep) { - isc_token_t token; - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - true)); - if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) - { - isc_lex_ungettoken(lexer, &token); - return (ISC_R_NOMORE); - } - RETTOK(loc_getprecision(DNS_AS_STR(token), valuep)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -loc_getsize(isc_lex_t *lexer, unsigned char *sizep) { - return (loc_getoptionalprecision(lexer, sizep)); -} - -static inline isc_result_t -loc_gethorizontalprecision(isc_lex_t *lexer, unsigned char *hpp) { - return (loc_getoptionalprecision(lexer, hpp)); -} - -static inline isc_result_t -loc_getverticalprecision(isc_lex_t *lexer, unsigned char *vpp) { - return (loc_getoptionalprecision(lexer, vpp)); -} - -/* The LOC record is expressed in a master file in the following format: - * - * LOC ( d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] - * {"E"|"W"} alt["m"] [siz["m"] [hp["m"] - * [vp["m"]]]] ) - * - * (The parentheses are used for multi-line data as specified in [RFC - * 1035] section 5.1.) - * - * where: - * - * d1: [0 .. 90] (degrees latitude) - * d2: [0 .. 180] (degrees longitude) - * m1, m2: [0 .. 59] (minutes latitude/longitude) - * s1, s2: [0 .. 59.999] (seconds latitude/longitude) - * alt: [-100000.00 .. 42849672.95] BY .01 (altitude in meters) - * siz, hp, vp: [0 .. 90000000.00] (size/precision in meters) - * - * If omitted, minutes and seconds default to zero, size defaults to 1m, - * horizontal precision defaults to 10000m, and vertical precision - * defaults to 10m. These defaults are chosen to represent typical - * ZIP/postal code area sizes, since it is often easy to find - * approximate geographical location by ZIP/postal code. - */ -static inline isc_result_t -fromtext_loc(ARGS_FROMTEXT) { - isc_result_t result = ISC_R_SUCCESS; - unsigned long latitude = 0; - unsigned long longitude = 0; - unsigned long altitude = 0; - unsigned char size = 0x12; /* Default: 1.00m */ - unsigned char hp = 0x16; /* Default: 10000.00 m */ - unsigned char vp = 0x13; /* Default: 10.00 m */ - unsigned char version = 0; - - REQUIRE(type == dns_rdatatype_loc); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(loc_getlatitude(lexer, &latitude)); - RETERR(loc_getlongitude(lexer, &longitude)); - RETERR(loc_getaltitude(lexer, &altitude)); - result = loc_getsize(lexer, &size); - if (result == ISC_R_NOMORE) { - result = ISC_R_SUCCESS; - goto encode; - } - RETERR(result); - result = loc_gethorizontalprecision(lexer, &hp); - if (result == ISC_R_NOMORE) { - result = ISC_R_SUCCESS; - goto encode; - } - RETERR(result); - result = loc_getverticalprecision(lexer, &vp); - if (result == ISC_R_NOMORE) { - result = ISC_R_SUCCESS; - goto encode; - } - RETERR(result); -encode: - RETERR(mem_tobuffer(target, &version, 1)); - RETERR(mem_tobuffer(target, &size, 1)); - RETERR(mem_tobuffer(target, &hp, 1)); - RETERR(mem_tobuffer(target, &vp, 1)); - - RETERR(uint32_tobuffer(latitude, target)); - RETERR(uint32_tobuffer(longitude, target)); - RETERR(uint32_tobuffer(altitude, target)); - - return (result); -} - -static inline isc_result_t -totext_loc(ARGS_TOTEXT) { - int d1, m1, s1, fs1; - int d2, m2, s2, fs2; - unsigned long latitude; - unsigned long longitude; - unsigned long altitude; - bool north; - bool east; - bool below; - isc_region_t sr; - char sbuf[sizeof("90000000m")]; - char hbuf[sizeof("90000000m")]; - char vbuf[sizeof("90000000m")]; - /* "89 59 59.999 N 179 59 59.999 E " */ - /* "-42849672.95m 90000000m 90000000m 90000000m"; */ - char buf[8 * 6 + 12 * 1 + 2 * 10 + sizeof(sbuf) + sizeof(hbuf) + - sizeof(vbuf)]; - unsigned char size, hp, vp; - unsigned long poweroften[8] = { 1, 10, 100, 1000, - 10000, 100000, 1000000, 10000000 }; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_loc); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - if (sr.base[0] != 0) { - return (ISC_R_NOTIMPLEMENTED); - } - - REQUIRE(rdata->length == 16); - - size = sr.base[1]; - INSIST((size & 0x0f) < 10 && (size >> 4) < 10); - if ((size & 0x0f) > 1) { - snprintf(sbuf, sizeof(sbuf), "%lum", - (size >> 4) * poweroften[(size & 0x0f) - 2]); - } else { - snprintf(sbuf, sizeof(sbuf), "0.%02lum", - (size >> 4) * poweroften[(size & 0x0f)]); - } - hp = sr.base[2]; - INSIST((hp & 0x0f) < 10 && (hp >> 4) < 10); - if ((hp & 0x0f) > 1) { - snprintf(hbuf, sizeof(hbuf), "%lum", - (hp >> 4) * poweroften[(hp & 0x0f) - 2]); - } else { - snprintf(hbuf, sizeof(hbuf), "0.%02lum", - (hp >> 4) * poweroften[(hp & 0x0f)]); - } - vp = sr.base[3]; - INSIST((vp & 0x0f) < 10 && (vp >> 4) < 10); - if ((vp & 0x0f) > 1) { - snprintf(vbuf, sizeof(vbuf), "%lum", - (vp >> 4) * poweroften[(vp & 0x0f) - 2]); - } else { - snprintf(vbuf, sizeof(vbuf), "0.%02lum", - (vp >> 4) * poweroften[(vp & 0x0f)]); - } - isc_region_consume(&sr, 4); - - latitude = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - if (latitude >= 0x80000000) { - north = true; - latitude -= 0x80000000; - } else { - north = false; - latitude = 0x80000000 - latitude; - } - fs1 = (int)(latitude % 1000); - latitude /= 1000; - s1 = (int)(latitude % 60); - latitude /= 60; - m1 = (int)(latitude % 60); - latitude /= 60; - d1 = (int)latitude; - INSIST(latitude <= 90U); - - longitude = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - if (longitude >= 0x80000000) { - east = true; - longitude -= 0x80000000; - } else { - east = false; - longitude = 0x80000000 - longitude; - } - fs2 = (int)(longitude % 1000); - longitude /= 1000; - s2 = (int)(longitude % 60); - longitude /= 60; - m2 = (int)(longitude % 60); - longitude /= 60; - d2 = (int)longitude; - INSIST(longitude <= 180U); - - altitude = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - if (altitude < 10000000U) { - below = true; - altitude = 10000000 - altitude; - } else { - below = false; - altitude -= 10000000; - } - - snprintf(buf, sizeof(buf), - "%d %d %d.%03d %s %d %d %d.%03d %s %s%lu.%02lum %s %s %s", d1, - m1, s1, fs1, north ? "N" : "S", d2, m2, s2, fs2, - east ? "E" : "W", below ? "-" : "", altitude / 100, - altitude % 100, sbuf, hbuf, vbuf); - - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_loc(ARGS_FROMWIRE) { - isc_region_t sr; - unsigned char c; - unsigned long latitude; - unsigned long longitude; - - REQUIRE(type == dns_rdatatype_loc); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - if (sr.base[0] != 0) { - /* Treat as unknown. */ - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); - } - if (sr.length < 16) - return (ISC_R_UNEXPECTEDEND); - - /* - * Size. - */ - c = sr.base[1]; - if (c != 0) - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - - /* - * Horizontal precision. - */ - c = sr.base[2]; - if (c != 0) - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - - /* - * Vertical precision. - */ - c = sr.base[3]; - if (c != 0) - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - isc_region_consume(&sr, 4); - - /* - * Latitude. - */ - latitude = uint32_fromregion(&sr); - if (latitude < (0x80000000UL - 90 * 3600000) || - latitude > (0x80000000UL + 90 * 3600000)) - return (ISC_R_RANGE); - isc_region_consume(&sr, 4); - - /* - * Longitude. - */ - longitude = uint32_fromregion(&sr); - if (longitude < (0x80000000UL - 180 * 3600000) || - longitude > (0x80000000UL + 180 * 3600000)) - return (ISC_R_RANGE); - - /* - * Altitude. - * All values possible. - */ - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, 16); - return (mem_tobuffer(target, sr.base, 16)); -} - -static inline isc_result_t -towire_loc(ARGS_TOWIRE) { - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_loc); - REQUIRE(rdata->length != 0); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_loc(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_loc); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_loc(ARGS_FROMSTRUCT) { - dns_rdata_loc_t *loc; - uint8_t c; - - REQUIRE(type == dns_rdatatype_loc); - REQUIRE(((dns_rdata_loc_t *)source) != NULL); - REQUIRE(((dns_rdata_loc_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_loc_t *)source)->common.rdclass == rdclass); - - loc = source; - - UNUSED(type); - UNUSED(rdclass); - - if (loc->v.v0.version != 0) - return (ISC_R_NOTIMPLEMENTED); - RETERR(uint8_tobuffer(loc->v.v0.version, target)); - - c = loc->v.v0.size; - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - RETERR(uint8_tobuffer(loc->v.v0.size, target)); - - c = loc->v.v0.horizontal; - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - RETERR(uint8_tobuffer(loc->v.v0.horizontal, target)); - - c = loc->v.v0.vertical; - if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) - return (ISC_R_RANGE); - RETERR(uint8_tobuffer(loc->v.v0.vertical, target)); - - if (loc->v.v0.latitude < (0x80000000UL - 90 * 3600000) || - loc->v.v0.latitude > (0x80000000UL + 90 * 3600000)) - return (ISC_R_RANGE); - RETERR(uint32_tobuffer(loc->v.v0.latitude, target)); - - if (loc->v.v0.longitude < (0x80000000UL - 180 * 3600000) || - loc->v.v0.longitude > (0x80000000UL + 180 * 3600000)) - return (ISC_R_RANGE); - RETERR(uint32_tobuffer(loc->v.v0.longitude, target)); - return (uint32_tobuffer(loc->v.v0.altitude, target)); -} - -static inline isc_result_t -tostruct_loc(ARGS_TOSTRUCT) { - dns_rdata_loc_t *loc; - isc_region_t r; - uint8_t version; - - REQUIRE(((dns_rdata_loc_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_loc); - REQUIRE(rdata->length != 0); - - loc = target; - - UNUSED(mctx); - - dns_rdata_toregion(rdata, &r); - version = uint8_fromregion(&r); - if (version != 0) - return (ISC_R_NOTIMPLEMENTED); - - loc->common.rdclass = rdata->rdclass; - loc->common.rdtype = rdata->type; - ISC_LINK_INIT(&loc->common, link); - - loc->v.v0.version = version; - isc_region_consume(&r, 1); - loc->v.v0.size = uint8_fromregion(&r); - isc_region_consume(&r, 1); - loc->v.v0.horizontal = uint8_fromregion(&r); - isc_region_consume(&r, 1); - loc->v.v0.vertical = uint8_fromregion(&r); - isc_region_consume(&r, 1); - loc->v.v0.latitude = uint32_fromregion(&r); - isc_region_consume(&r, 4); - loc->v.v0.longitude = uint32_fromregion(&r); - isc_region_consume(&r, 4); - loc->v.v0.altitude = uint32_fromregion(&r); - isc_region_consume(&r, 4); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_loc(ARGS_FREESTRUCT) { - dns_rdata_loc_t *loc; - - REQUIRE(((dns_rdata_loc_t *)source) != NULL); - REQUIRE(((dns_rdata_loc_t *)source)->common.rdtype == - dns_rdatatype_loc); - - loc = source; - - UNUSED(source); - UNUSED(loc); -} - -static inline isc_result_t -additionaldata_loc(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_loc); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_loc(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_loc); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_loc(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_loc); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_loc(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_loc); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_loc(ARGS_COMPARE) { - return (compare_loc(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_LOC_29_C */ diff --git a/lib/dns-pkcs11/rdata/generic/loc_29.h b/lib/dns-pkcs11/rdata/generic/loc_29.h deleted file mode 100644 index 2f37977..0000000 --- a/lib/dns-pkcs11/rdata/generic/loc_29.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_LOC_29_H -#define GENERIC_LOC_29_H 1 - - -/*! - * \brief Per RFC1876 */ - -typedef struct dns_rdata_loc_0 { - uint8_t version; /* must be first and zero */ - uint8_t size; - uint8_t horizontal; - uint8_t vertical; - uint32_t latitude; - uint32_t longitude; - uint32_t altitude; -} dns_rdata_loc_0_t; - -typedef struct dns_rdata_loc { - dns_rdatacommon_t common; - union { - dns_rdata_loc_0_t v0; - } v; -} dns_rdata_loc_t; - -#endif /* GENERIC_LOC_29_H */ diff --git a/lib/dns-pkcs11/rdata/generic/lp_107.c b/lib/dns-pkcs11/rdata/generic/lp_107.c deleted file mode 100644 index 14f5dda..0000000 --- a/lib/dns-pkcs11/rdata/generic/lp_107.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_LP_107_C -#define RDATA_GENERIC_LP_107_C - -#include - -#include - -#define RRTYPE_LP_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_lp(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_lp); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - return (dns_name_fromtext(&name, &buffer, origin, options, target)); -} - -static inline isc_result_t -totext_lp(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_lp); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_lp(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_lp); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sregion.base, 2)); - isc_buffer_forward(source, 2); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_lp(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_lp); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_lp(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_lp); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_lp(ARGS_FROMSTRUCT) { - dns_rdata_lp_t *lp; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_lp); - REQUIRE(((dns_rdata_lp_t *)source) != NULL); - REQUIRE(((dns_rdata_lp_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_lp_t *)source)->common.rdclass == rdclass); - - lp = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(lp->pref, target)); - dns_name_toregion(&lp->lp, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_lp(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_lp_t *lp; - dns_name_t name; - - REQUIRE(((dns_rdata_lp_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_lp); - REQUIRE(rdata->length != 0); - - lp = target; - - lp->common.rdclass = rdata->rdclass; - lp->common.rdtype = rdata->type; - ISC_LINK_INIT(&lp->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - lp->pref = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - dns_name_init(&lp->lp, NULL); - RETERR(name_duporclone(&name, mctx, &lp->lp)); - lp->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_lp(ARGS_FREESTRUCT) { - dns_rdata_lp_t *lp; - - REQUIRE(((dns_rdata_lp_t *)source) != NULL); - REQUIRE(((dns_rdata_lp_t *)source)->common.rdtype == dns_rdatatype_lp); - - lp = source; - - if (lp->mctx == NULL) - return; - - dns_name_free(&lp->lp, lp->mctx); - lp->mctx = NULL; -} - -static inline isc_result_t -additionaldata_lp(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_lp); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - result = (add)(arg, &name, dns_rdatatype_l32); - if (result != ISC_R_SUCCESS) - return (result); - return ((add)(arg, &name, dns_rdatatype_l64)); -} - -static inline isc_result_t -digest_lp(ARGS_DIGEST) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_lp); - - dns_rdata_toregion(rdata, ®ion); - return ((digest)(arg, ®ion)); -} - -static inline bool -checkowner_lp(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_lp); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(name); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_lp(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_lp); - - UNUSED(bad); - UNUSED(owner); - - return (true); -} - -static inline int -casecompare_lp(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_lp); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - order = memcmp(rdata1->data, rdata2->data, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -#endif /* RDATA_GENERIC_LP_107_C */ diff --git a/lib/dns-pkcs11/rdata/generic/lp_107.h b/lib/dns-pkcs11/rdata/generic/lp_107.h deleted file mode 100644 index 392c545..0000000 --- a/lib/dns-pkcs11/rdata/generic/lp_107.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_LP_107_H -#define GENERIC_LP_107_H 1 - -typedef struct dns_rdata_lp { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t pref; - dns_name_t lp; -} dns_rdata_lp_t; - -#endif /* GENERIC_LP_107_H */ diff --git a/lib/dns-pkcs11/rdata/generic/mb_7.c b/lib/dns-pkcs11/rdata/generic/mb_7.c deleted file mode 100644 index ee9cd13..0000000 --- a/lib/dns-pkcs11/rdata/generic/mb_7.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MB_7_C -#define RDATA_GENERIC_MB_7_C - -#define RRTYPE_MB_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_mb(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_mb); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_mb(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_mb); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_mb(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_mb); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_mb(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mb); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_mb(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_mb); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_mb(ARGS_FROMSTRUCT) { - dns_rdata_mb_t *mb; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_mb); - REQUIRE(((dns_rdata_mb_t *)source) != NULL); - REQUIRE(((dns_rdata_mb_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_mb_t *)source)->common.rdclass == rdclass); - - mb = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&mb->mb, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_mb(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_mb_t *mb; - dns_name_t name; - - REQUIRE(((dns_rdata_mb_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_mb); - REQUIRE(rdata->length != 0); - - mb = target; - - mb->common.rdclass = rdata->rdclass; - mb->common.rdtype = rdata->type; - ISC_LINK_INIT(&mb->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&mb->mb, NULL); - RETERR(name_duporclone(&name, mctx, &mb->mb)); - mb->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_mb(ARGS_FREESTRUCT) { - dns_rdata_mb_t *mb; - - REQUIRE(((dns_rdata_mb_t *)source) != NULL); - - mb = source; - - if (mb->mctx == NULL) - return; - - dns_name_free(&mb->mb, mb->mctx); - mb->mctx = NULL; -} - -static inline isc_result_t -additionaldata_mb(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mb); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_mb(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mb); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_mb(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_mb); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (dns_name_ismailbox(name)); -} - -static inline bool -checknames_mb(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_mb); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_mb(ARGS_COMPARE) { - return (compare_mb(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MB_7_C */ diff --git a/lib/dns-pkcs11/rdata/generic/mb_7.h b/lib/dns-pkcs11/rdata/generic/mb_7.h deleted file mode 100644 index c57497c..0000000 --- a/lib/dns-pkcs11/rdata/generic/mb_7.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MB_7_H -#define GENERIC_MB_7_H 1 - - -typedef struct dns_rdata_mb { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t mb; -} dns_rdata_mb_t; - -#endif /* GENERIC_MB_7_H */ diff --git a/lib/dns-pkcs11/rdata/generic/md_3.c b/lib/dns-pkcs11/rdata/generic/md_3.c deleted file mode 100644 index f9659c5..0000000 --- a/lib/dns-pkcs11/rdata/generic/md_3.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MD_3_C -#define RDATA_GENERIC_MD_3_C - -#define RRTYPE_MD_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_md(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_md); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_md(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_md); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_md(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_md); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_md(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_md); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_md(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_md); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_md(ARGS_FROMSTRUCT) { - dns_rdata_md_t *md; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_md); - REQUIRE(((dns_rdata_md_t *)source) != NULL); - REQUIRE(((dns_rdata_md_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_md_t *)source)->common.rdclass == rdclass); - - md = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&md->md, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_md(ARGS_TOSTRUCT) { - dns_rdata_md_t *md; - isc_region_t r; - dns_name_t name; - - REQUIRE(((dns_rdata_md_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_md); - REQUIRE(rdata->length != 0); - - md = target; - - md->common.rdclass = rdata->rdclass; - md->common.rdtype = rdata->type; - ISC_LINK_INIT(&md->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, &r); - dns_name_fromregion(&name, &r); - dns_name_init(&md->md, NULL); - RETERR(name_duporclone(&name, mctx, &md->md)); - md->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_md(ARGS_FREESTRUCT) { - dns_rdata_md_t *md; - - REQUIRE(((dns_rdata_md_t *)source) != NULL); - REQUIRE(((dns_rdata_md_t *)source)->common.rdtype == dns_rdatatype_md); - - md = source; - - if (md->mctx == NULL) - return; - - dns_name_free(&md->md, md->mctx); - md->mctx = NULL; -} - -static inline isc_result_t -additionaldata_md(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_md); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_md(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_md); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_md(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_md); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_md(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_md); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_md(ARGS_COMPARE) { - return (compare_md(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MD_3_C */ diff --git a/lib/dns-pkcs11/rdata/generic/md_3.h b/lib/dns-pkcs11/rdata/generic/md_3.h deleted file mode 100644 index 738bf70..0000000 --- a/lib/dns-pkcs11/rdata/generic/md_3.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MD_3_H -#define GENERIC_MD_3_H 1 - - -typedef struct dns_rdata_md { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t md; -} dns_rdata_md_t; - - -#endif /* GENERIC_MD_3_H */ diff --git a/lib/dns-pkcs11/rdata/generic/mf_4.c b/lib/dns-pkcs11/rdata/generic/mf_4.c deleted file mode 100644 index 42e3b35..0000000 --- a/lib/dns-pkcs11/rdata/generic/mf_4.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MF_4_C -#define RDATA_GENERIC_MF_4_C - -#define RRTYPE_MF_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_mf(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_mf); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_mf(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_mf); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_mf(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_mf); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_mf(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mf); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_mf(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_mf); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_mf(ARGS_FROMSTRUCT) { - dns_rdata_mf_t *mf; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_mf); - REQUIRE(((dns_rdata_mf_t *)source) != NULL); - REQUIRE(((dns_rdata_mf_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_mf_t *)source)->common.rdclass == rdclass); - - mf = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&mf->mf, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_mf(ARGS_TOSTRUCT) { - dns_rdata_mf_t *mf; - isc_region_t r; - dns_name_t name; - - REQUIRE(((dns_rdata_mf_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_mf); - REQUIRE(rdata->length != 0); - - mf = target; - - mf->common.rdclass = rdata->rdclass; - mf->common.rdtype = rdata->type; - ISC_LINK_INIT(&mf->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, &r); - dns_name_fromregion(&name, &r); - dns_name_init(&mf->mf, NULL); - RETERR(name_duporclone(&name, mctx, &mf->mf)); - mf->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_mf(ARGS_FREESTRUCT) { - dns_rdata_mf_t *mf; - - REQUIRE(((dns_rdata_mf_t *)source) != NULL); - REQUIRE(((dns_rdata_mf_t *)source)->common.rdtype == dns_rdatatype_mf); - - mf = source; - - if (mf->mctx == NULL) - return; - dns_name_free(&mf->mf, mf->mctx); - mf->mctx = NULL; -} - -static inline isc_result_t -additionaldata_mf(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mf); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_mf(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mf); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_mf(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_mf); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_mf(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_mf); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_mf(ARGS_COMPARE) { - return (compare_mf(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MF_4_C */ diff --git a/lib/dns-pkcs11/rdata/generic/mf_4.h b/lib/dns-pkcs11/rdata/generic/mf_4.h deleted file mode 100644 index 6036d85..0000000 --- a/lib/dns-pkcs11/rdata/generic/mf_4.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MF_4_H -#define GENERIC_MF_4_H 1 - - -typedef struct dns_rdata_mf { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t mf; -} dns_rdata_mf_t; - -#endif /* GENERIC_MF_4_H */ diff --git a/lib/dns-pkcs11/rdata/generic/mg_8.c b/lib/dns-pkcs11/rdata/generic/mg_8.c deleted file mode 100644 index 37aaa87..0000000 --- a/lib/dns-pkcs11/rdata/generic/mg_8.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MG_8_C -#define RDATA_GENERIC_MG_8_C - -#define RRTYPE_MG_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_mg(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_mg); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_mg(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_mg); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_mg(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_mg); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_mg(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mg); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_mg(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_mg); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_mg(ARGS_FROMSTRUCT) { - dns_rdata_mg_t *mg; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_mg); - REQUIRE(((dns_rdata_mg_t *)source) != NULL); - REQUIRE(((dns_rdata_mg_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_mg_t *)source)->common.rdclass == rdclass); - - mg = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&mg->mg, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_mg(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_mg_t *mg; - dns_name_t name; - - REQUIRE(((dns_rdata_mg_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_mg); - REQUIRE(rdata->length != 0); - - mg = target; - - mg->common.rdclass = rdata->rdclass; - mg->common.rdtype = rdata->type; - ISC_LINK_INIT(&mg->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&mg->mg, NULL); - RETERR(name_duporclone(&name, mctx, &mg->mg)); - mg->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_mg(ARGS_FREESTRUCT) { - dns_rdata_mg_t *mg; - - REQUIRE(((dns_rdata_mg_t *)source) != NULL); - REQUIRE(((dns_rdata_mg_t *)source)->common.rdtype == dns_rdatatype_mg); - - mg = source; - - if (mg->mctx == NULL) - return; - dns_name_free(&mg->mg, mg->mctx); - mg->mctx = NULL; -} - -static inline isc_result_t -additionaldata_mg(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_mg); - - UNUSED(add); - UNUSED(arg); - UNUSED(rdata); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_mg(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mg); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_mg(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_mg); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (dns_name_ismailbox(name)); -} - -static inline bool -checknames_mg(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_mg); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_mg(ARGS_COMPARE) { - return (compare_mg(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MG_8_C */ diff --git a/lib/dns-pkcs11/rdata/generic/mg_8.h b/lib/dns-pkcs11/rdata/generic/mg_8.h deleted file mode 100644 index cb27624..0000000 --- a/lib/dns-pkcs11/rdata/generic/mg_8.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MG_8_H -#define GENERIC_MG_8_H 1 - - -typedef struct dns_rdata_mg { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t mg; -} dns_rdata_mg_t; - -#endif /* GENERIC_MG_8_H */ diff --git a/lib/dns-pkcs11/rdata/generic/minfo_14.c b/lib/dns-pkcs11/rdata/generic/minfo_14.c deleted file mode 100644 index 7f0a1bf..0000000 --- a/lib/dns-pkcs11/rdata/generic/minfo_14.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MINFO_14_C -#define RDATA_GENERIC_MINFO_14_C - -#define RRTYPE_MINFO_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_minfo(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - int i; - bool ok; - - REQUIRE(type == dns_rdatatype_minfo); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - if (origin == NULL) - origin = dns_rootname; - - for (i = 0; i < 2; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, - options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ismailbox(&name); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_minfo(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t rmail; - dns_name_t email; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_minfo); - REQUIRE(rdata->length != 0); - - dns_name_init(&rmail, NULL); - dns_name_init(&email, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); - - dns_name_fromregion(&email, ®ion); - isc_region_consume(®ion, email.length); - - sub = name_prefix(&rmail, tctx->origin, &prefix); - - RETERR(dns_name_totext(&prefix, sub, target)); - - RETERR(str_totext(" ", target)); - - sub = name_prefix(&email, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_minfo(ARGS_FROMWIRE) { - dns_name_t rmail; - dns_name_t email; - - REQUIRE(type == dns_rdatatype_minfo); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&rmail, NULL); - dns_name_init(&email, NULL); - - RETERR(dns_name_fromwire(&rmail, source, dctx, options, target)); - return (dns_name_fromwire(&email, source, dctx, options, target)); -} - -static inline isc_result_t -towire_minfo(ARGS_TOWIRE) { - isc_region_t region; - dns_name_t rmail; - dns_name_t email; - dns_offsets_t roffsets; - dns_offsets_t eoffsets; - - REQUIRE(rdata->type == dns_rdatatype_minfo); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&rmail, roffsets); - dns_name_init(&email, eoffsets); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, name_length(&rmail)); - - RETERR(dns_name_towire(&rmail, cctx, target)); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); - - return (dns_name_towire(&rmail, cctx, target)); -} - -static inline int -compare_minfo(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_minfo); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - return (order); -} - -static inline isc_result_t -fromstruct_minfo(ARGS_FROMSTRUCT) { - dns_rdata_minfo_t *minfo; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_minfo); - REQUIRE(((dns_rdata_minfo_t *)source) != NULL); - REQUIRE(((dns_rdata_minfo_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_minfo_t *)source)->common.rdclass == rdclass); - - minfo = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&minfo->rmailbox, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - dns_name_toregion(&minfo->emailbox, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_minfo(ARGS_TOSTRUCT) { - dns_rdata_minfo_t *minfo; - isc_region_t region; - dns_name_t name; - isc_result_t result; - - REQUIRE(((dns_rdata_minfo_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_minfo); - REQUIRE(rdata->length != 0); - - minfo = target; - - minfo->common.rdclass = rdata->rdclass; - minfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&minfo->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&minfo->rmailbox, NULL); - RETERR(name_duporclone(&name, mctx, &minfo->rmailbox)); - isc_region_consume(®ion, name_length(&name)); - - dns_name_fromregion(&name, ®ion); - dns_name_init(&minfo->emailbox, NULL); - result = name_duporclone(&name, mctx, &minfo->emailbox); - if (result != ISC_R_SUCCESS) - goto cleanup; - minfo->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&minfo->rmailbox, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_minfo(ARGS_FREESTRUCT) { - dns_rdata_minfo_t *minfo; - - REQUIRE(((dns_rdata_minfo_t *)source) != NULL); - REQUIRE(((dns_rdata_minfo_t *)source)->common.rdtype == - dns_rdatatype_minfo); - - minfo = source; - - if (minfo->mctx == NULL) - return; - - dns_name_free(&minfo->rmailbox, minfo->mctx); - dns_name_free(&minfo->emailbox, minfo->mctx); - minfo->mctx = NULL; -} - -static inline isc_result_t -additionaldata_minfo(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_minfo); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_minfo(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_minfo); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - result = dns_name_digest(&name, digest, arg); - if (result != ISC_R_SUCCESS) - return (result); - isc_region_consume(&r, name_length(&name)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_minfo(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_minfo); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_minfo(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_minfo); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ismailbox(&name)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - isc_region_consume(®ion, name_length(&name)); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ismailbox(&name)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_minfo(ARGS_COMPARE) { - return (compare_minfo(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MINFO_14_C */ diff --git a/lib/dns-pkcs11/rdata/generic/minfo_14.h b/lib/dns-pkcs11/rdata/generic/minfo_14.h deleted file mode 100644 index 7d052c8..0000000 --- a/lib/dns-pkcs11/rdata/generic/minfo_14.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MINFO_14_H -#define GENERIC_MINFO_14_H 1 - - -typedef struct dns_rdata_minfo { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t rmailbox; - dns_name_t emailbox; -} dns_rdata_minfo_t; - -#endif /* GENERIC_MINFO_14_H */ diff --git a/lib/dns-pkcs11/rdata/generic/mr_9.c b/lib/dns-pkcs11/rdata/generic/mr_9.c deleted file mode 100644 index 17ab558..0000000 --- a/lib/dns-pkcs11/rdata/generic/mr_9.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MR_9_C -#define RDATA_GENERIC_MR_9_C - -#define RRTYPE_MR_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_mr(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_mr); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_mr(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_mr); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_mr(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_mr); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_mr(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mr); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_mr(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_mr); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_mr(ARGS_FROMSTRUCT) { - dns_rdata_mr_t *mr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_mr); - REQUIRE(((dns_rdata_mr_t *)source) != NULL); - REQUIRE(((dns_rdata_mr_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_mr_t *)source)->common.rdclass == rdclass); - - mr = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&mr->mr, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_mr(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_mr_t *mr; - dns_name_t name; - - REQUIRE(((dns_rdata_mr_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_mr); - REQUIRE(rdata->length != 0); - - mr = target; - - mr->common.rdclass = rdata->rdclass; - mr->common.rdtype = rdata->type; - ISC_LINK_INIT(&mr->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&mr->mr, NULL); - RETERR(name_duporclone(&name, mctx, &mr->mr)); - mr->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_mr(ARGS_FREESTRUCT) { - dns_rdata_mr_t *mr; - - REQUIRE(((dns_rdata_mr_t *)source) != NULL); - REQUIRE(((dns_rdata_mr_t *)source)->common.rdtype == dns_rdatatype_mr); - - mr = source; - - if (mr->mctx == NULL) - return; - dns_name_free(&mr->mr, mr->mctx); - mr->mctx = NULL; -} - -static inline isc_result_t -additionaldata_mr(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_mr); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_mr(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mr); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_mr(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_mr); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_mr(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_mr); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_mr(ARGS_COMPARE) { - return (compare_mr(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MR_9_C */ diff --git a/lib/dns-pkcs11/rdata/generic/mr_9.h b/lib/dns-pkcs11/rdata/generic/mr_9.h deleted file mode 100644 index 0314259..0000000 --- a/lib/dns-pkcs11/rdata/generic/mr_9.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MR_9_H -#define GENERIC_MR_9_H 1 - - -typedef struct dns_rdata_mr { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t mr; -} dns_rdata_mr_t; - -#endif /* GENERIC_MR_9_H */ diff --git a/lib/dns-pkcs11/rdata/generic/mx_15.c b/lib/dns-pkcs11/rdata/generic/mx_15.c deleted file mode 100644 index 8ab2706..0000000 --- a/lib/dns-pkcs11/rdata/generic/mx_15.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_MX_15_C -#define RDATA_GENERIC_MX_15_C - -#include - -#include - -#include - -#define RRTYPE_MX_ATTRIBUTES (0) - -static bool -check_mx(isc_token_t *token) { - char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; - struct in_addr addr; - struct in6_addr addr6; - - if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp)) - return (true); - - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - return (false); - - return (true); -} - -static inline isc_result_t -fromtext_mx(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - bool ok; - - REQUIRE(type == dns_rdatatype_mx); - - UNUSED(type); - UNUSED(rdclass); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - ok = true; - if ((options & DNS_RDATA_CHECKMX) != 0) - ok = check_mx(&token); - if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0) - RETTOK(DNS_R_MXISADDRESS); - if (!ok && callbacks != NULL) - warn_badmx(&token, lexer, callbacks); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_mx(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_mx); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_mx(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_mx); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sregion.base, 2)); - isc_buffer_forward(source, 2); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_mx(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mx); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_rdata_toregion(rdata, ®ion); - RETERR(mem_tobuffer(target, region.base, 2)); - isc_region_consume(®ion, 2); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_mx(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_mx); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - order = memcmp(rdata1->data, rdata2->data, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_mx(ARGS_FROMSTRUCT) { - dns_rdata_mx_t *mx; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_mx); - REQUIRE(((dns_rdata_mx_t *)source) != NULL); - REQUIRE(((dns_rdata_mx_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_mx_t *)source)->common.rdclass == rdclass); - - mx = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(mx->pref, target)); - dns_name_toregion(&mx->mx, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_mx(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_mx_t *mx; - dns_name_t name; - - REQUIRE(((dns_rdata_mx_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_mx); - REQUIRE(rdata->length != 0); - - mx = target; - - mx->common.rdclass = rdata->rdclass; - mx->common.rdtype = rdata->type; - ISC_LINK_INIT(&mx->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - mx->pref = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - dns_name_init(&mx->mx, NULL); - RETERR(name_duporclone(&name, mctx, &mx->mx)); - mx->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_mx(ARGS_FREESTRUCT) { - dns_rdata_mx_t *mx; - - REQUIRE(((dns_rdata_mx_t *)source) != NULL); - REQUIRE(((dns_rdata_mx_t *)source)->common.rdtype == dns_rdatatype_mx); - - mx = source; - - if (mx->mctx == NULL) - return; - - dns_name_free(&mx->mx, mx->mctx); - mx->mctx = NULL; -} - -static unsigned char port25_offset[] = { 0, 3 }; -static unsigned char port25_ndata[] = "\003_25\004_tcp"; -static dns_name_t port25 = - DNS_NAME_INITNONABSOLUTE(port25_ndata, port25_offset); - -static inline isc_result_t -additionaldata_mx(ARGS_ADDLDATA) { - isc_result_t result; - dns_fixedname_t fixed; - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_mx); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - if (dns_name_equal(&name, dns_rootname)) - return (ISC_R_SUCCESS); - - result = (add)(arg, &name, dns_rdatatype_a); - if (result != ISC_R_SUCCESS) - return (result); - - dns_fixedname_init(&fixed); - result = dns_name_concatenate(&port25, &name, - dns_fixedname_name(&fixed), NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa)); -} - -static inline isc_result_t -digest_mx(ARGS_DIGEST) { - isc_region_t r1, r2; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mx); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 2); - r1.length = 2; - RETERR((digest)(arg, &r1)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_mx(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_mx); - - UNUSED(type); - UNUSED(rdclass); - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_mx(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_mx); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_mx(ARGS_COMPARE) { - return (compare_mx(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_MX_15_C */ diff --git a/lib/dns-pkcs11/rdata/generic/mx_15.h b/lib/dns-pkcs11/rdata/generic/mx_15.h deleted file mode 100644 index e0e4eea..0000000 --- a/lib/dns-pkcs11/rdata/generic/mx_15.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_MX_15_H -#define GENERIC_MX_15_H 1 - - -typedef struct dns_rdata_mx { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t pref; - dns_name_t mx; -} dns_rdata_mx_t; - -#endif /* GENERIC_MX_15_H */ diff --git a/lib/dns-pkcs11/rdata/generic/naptr_35.c b/lib/dns-pkcs11/rdata/generic/naptr_35.c deleted file mode 100644 index ecae2c0..0000000 --- a/lib/dns-pkcs11/rdata/generic/naptr_35.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2915 */ - -#ifndef RDATA_GENERIC_NAPTR_35_C -#define RDATA_GENERIC_NAPTR_35_C - -#define RRTYPE_NAPTR_ATTRIBUTES (0) - -#include - -/* - * Check the wire format of the Regexp field. - * Don't allow embedded NUL's. - */ -static inline isc_result_t -txt_valid_regex(const unsigned char *txt) { - unsigned int nsub = 0; - char regex[256]; - char *cp; - bool flags = false; - bool replace = false; - unsigned char c; - unsigned char delim; - unsigned int len; - int n; - - len = *txt++; - if (len == 0U) - return (ISC_R_SUCCESS); - - delim = *txt++; - len--; - - /* - * Digits, backslash and flags can't be delimiters. - */ - switch (delim) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '\\': case 'i': case 0: - return (DNS_R_SYNTAX); - } - - cp = regex; - while (len-- > 0) { - c = *txt++; - if (c == 0) - return (DNS_R_SYNTAX); - if (c == delim && !replace) { - replace = true; - continue; - } else if (c == delim && !flags) { - flags = true; - continue; - } else if (c == delim) - return (DNS_R_SYNTAX); - /* - * Flags are not escaped. - */ - if (flags) { - switch (c) { - case 'i': - continue; - default: - return (DNS_R_SYNTAX); - } - } - if (!replace) - *cp++ = c; - if (c == '\\') { - if (len == 0) - return (DNS_R_SYNTAX); - c = *txt++; - if (c == 0) - return (DNS_R_SYNTAX); - len--; - if (replace) - switch (c) { - case '0': return (DNS_R_SYNTAX); - case '1': if (nsub < 1) nsub = 1; break; - case '2': if (nsub < 2) nsub = 2; break; - case '3': if (nsub < 3) nsub = 3; break; - case '4': if (nsub < 4) nsub = 4; break; - case '5': if (nsub < 5) nsub = 5; break; - case '6': if (nsub < 6) nsub = 6; break; - case '7': if (nsub < 7) nsub = 7; break; - case '8': if (nsub < 8) nsub = 8; break; - case '9': if (nsub < 9) nsub = 9; break; - } - if (!replace) - *cp++ = c; - } - } - if (!flags) - return (DNS_R_SYNTAX); - *cp = '\0'; - n = isc_regex_validate(regex); - if (n < 0 || nsub > (unsigned int)n) - return (DNS_R_SYNTAX); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromtext_naptr(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - unsigned char *regex; - - REQUIRE(type == dns_rdatatype_naptr); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Order. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Preference. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Flags. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* - * Service. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* - * Regexp. - */ - regex = isc_buffer_used(target); - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - RETTOK(txt_valid_regex(regex)); - - /* - * Replacement. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_naptr(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_naptr); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - - /* - * Order. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Preference. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Flags. - */ - RETERR(txt_totext(®ion, true, target)); - RETERR(str_totext(" ", target)); - - /* - * Service. - */ - RETERR(txt_totext(®ion, true, target)); - RETERR(str_totext(" ", target)); - - /* - * Regexp. - */ - RETERR(txt_totext(®ion, true, target)); - RETERR(str_totext(" ", target)); - - /* - * Replacement. - */ - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_naptr(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sr; - unsigned char *regex; - - REQUIRE(type == dns_rdatatype_naptr); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - /* - * Order, preference. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_buffer_forward(source, 4); - - /* - * Flags. - */ - RETERR(txt_fromwire(source, target)); - - /* - * Service. - */ - RETERR(txt_fromwire(source, target)); - - /* - * Regexp. - */ - regex = isc_buffer_used(target); - RETERR(txt_fromwire(source, target)); - RETERR(txt_valid_regex(regex)); - - /* - * Replacement. - */ - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_naptr(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_naptr); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - /* - * Order, preference. - */ - dns_rdata_toregion(rdata, &sr); - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - - /* - * Flags. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Service. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Regexp. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_naptr(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order, len; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_naptr); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - /* - * Order, preference. - */ - order = memcmp(region1.base, region2.base, 4); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, 4); - isc_region_consume(®ion2, 4); - - /* - * Flags. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Service. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Regexp. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_naptr(ARGS_FROMSTRUCT) { - dns_rdata_naptr_t *naptr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_naptr); - REQUIRE(((dns_rdata_naptr_t *)source) != NULL); - REQUIRE(((dns_rdata_naptr_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_naptr_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_naptr_t *)source)->flags != NULL || - ((dns_rdata_naptr_t *)source)->flags_len == 0); - REQUIRE(((dns_rdata_naptr_t *)source)->service != NULL || - ((dns_rdata_naptr_t *)source)->service_len == 0); - REQUIRE(((dns_rdata_naptr_t *)source)->regexp != NULL || - ((dns_rdata_naptr_t *)source)->regexp_len == 0); - - naptr = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(naptr->order, target)); - RETERR(uint16_tobuffer(naptr->preference, target)); - RETERR(uint8_tobuffer(naptr->flags_len, target)); - RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len)); - RETERR(uint8_tobuffer(naptr->service_len, target)); - RETERR(mem_tobuffer(target, naptr->service, naptr->service_len)); - RETERR(uint8_tobuffer(naptr->regexp_len, target)); - RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len)); - dns_name_toregion(&naptr->replacement, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_naptr(ARGS_TOSTRUCT) { - dns_rdata_naptr_t *naptr; - isc_region_t r; - isc_result_t result; - dns_name_t name; - - REQUIRE(((dns_rdata_naptr_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_naptr); - REQUIRE(rdata->length != 0); - - naptr = target; - - naptr->common.rdclass = rdata->rdclass; - naptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&naptr->common, link); - - naptr->flags = NULL; - naptr->service = NULL; - naptr->regexp = NULL; - - dns_rdata_toregion(rdata, &r); - - naptr->order = uint16_fromregion(&r); - isc_region_consume(&r, 2); - - naptr->preference = uint16_fromregion(&r); - isc_region_consume(&r, 2); - - naptr->flags_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->flags_len <= r.length); - naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len); - if (naptr->flags == NULL) - goto cleanup; - isc_region_consume(&r, naptr->flags_len); - - naptr->service_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->service_len <= r.length); - naptr->service = mem_maybedup(mctx, r.base, naptr->service_len); - if (naptr->service == NULL) - goto cleanup; - isc_region_consume(&r, naptr->service_len); - - naptr->regexp_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->regexp_len <= r.length); - naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len); - if (naptr->regexp == NULL) - goto cleanup; - isc_region_consume(&r, naptr->regexp_len); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - dns_name_init(&naptr->replacement, NULL); - result = name_duporclone(&name, mctx, &naptr->replacement); - if (result != ISC_R_SUCCESS) - goto cleanup; - naptr->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL && naptr->flags != NULL) - isc_mem_free(mctx, naptr->flags); - if (mctx != NULL && naptr->service != NULL) - isc_mem_free(mctx, naptr->service); - if (mctx != NULL && naptr->regexp != NULL) - isc_mem_free(mctx, naptr->regexp); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_naptr(ARGS_FREESTRUCT) { - dns_rdata_naptr_t *naptr; - - REQUIRE(((dns_rdata_naptr_t *)source) != NULL); - REQUIRE(((dns_rdata_naptr_t *)source)->common.rdtype == - dns_rdatatype_naptr); - - naptr = source; - - if (naptr->mctx == NULL) - return; - - if (naptr->flags != NULL) - isc_mem_free(naptr->mctx, naptr->flags); - if (naptr->service != NULL) - isc_mem_free(naptr->mctx, naptr->service); - if (naptr->regexp != NULL) - isc_mem_free(naptr->mctx, naptr->regexp); - dns_name_free(&naptr->replacement, naptr->mctx); - naptr->mctx = NULL; -} - -static inline isc_result_t -additionaldata_naptr(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sr; - dns_rdatatype_t atype; - unsigned int i, flagslen; - char *cp; - - REQUIRE(rdata->type == dns_rdatatype_naptr); - - /* - * Order, preference. - */ - dns_rdata_toregion(rdata, &sr); - isc_region_consume(&sr, 4); - - /* - * Flags. - */ - atype = 0; - flagslen = sr.base[0]; - cp = (char *)&sr.base[1]; - for (i = 0; i < flagslen; i++, cp++) { - if (*cp == 'S' || *cp == 's') { - atype = dns_rdatatype_srv; - break; - } - if (*cp == 'A' || *cp == 'a') { - atype = dns_rdatatype_a; - break; - } - } - isc_region_consume(&sr, flagslen + 1); - - /* - * Service. - */ - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Regexp. - */ - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - - if (atype != 0) - return ((add)(arg, &name, atype)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_naptr(ARGS_DIGEST) { - isc_region_t r1, r2; - unsigned int length, n; - isc_result_t result; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_naptr); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - length = 0; - - /* - * Order, preference. - */ - length += 4; - isc_region_consume(&r2, 4); - - /* - * Flags. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Service. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Regexp. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Digest the RR up to the replacement name. - */ - r1.length = length; - result = (digest)(arg, &r1); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Replacement. - */ - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_naptr(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_naptr); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_naptr(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_naptr); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_naptr(ARGS_COMPARE) { - return (compare_naptr(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NAPTR_35_C */ diff --git a/lib/dns-pkcs11/rdata/generic/naptr_35.h b/lib/dns-pkcs11/rdata/generic/naptr_35.h deleted file mode 100644 index 78b6645..0000000 --- a/lib/dns-pkcs11/rdata/generic/naptr_35.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_NAPTR_35_H -#define GENERIC_NAPTR_35_H 1 - - -/*! - * \brief Per RFC2915 */ - -typedef struct dns_rdata_naptr { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t order; - uint16_t preference; - char *flags; - uint8_t flags_len; - char *service; - uint8_t service_len; - char *regexp; - uint8_t regexp_len; - dns_name_t replacement; -} dns_rdata_naptr_t; - -#endif /* GENERIC_NAPTR_35_H */ diff --git a/lib/dns-pkcs11/rdata/generic/nid_104.c b/lib/dns-pkcs11/rdata/generic/nid_104.c deleted file mode 100644 index ca4f182..0000000 --- a/lib/dns-pkcs11/rdata/generic/nid_104.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_NID_104_C -#define RDATA_GENERIC_NID_104_C - -#include - -#include - -#define RRTYPE_NID_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_nid(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char locator[NS_LOCATORSZ]; - - REQUIRE(type == dns_rdatatype_nid); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (locator_pton(DNS_AS_STR(token), locator) != 1) - RETTOK(DNS_R_SYNTAX); - return (mem_tobuffer(target, locator, NS_LOCATORSZ)); -} - -static inline isc_result_t -totext_nid(ARGS_TOTEXT) { - isc_region_t region; - char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - snprintf(buf, sizeof(buf), "%x:%x:%x:%x", - region.base[0]<<8 | region.base[1], - region.base[2]<<8 | region.base[3], - region.base[4]<<8 | region.base[5], - region.base[6]<<8 | region.base[7]); - return (str_totext(buf, target)); -} - -static inline isc_result_t -fromwire_nid(ARGS_FROMWIRE) { - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_nid); - - UNUSED(type); - UNUSED(options); - UNUSED(rdclass); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length != 10) - return (DNS_R_FORMERR); - isc_buffer_forward(source, sregion.length); - return (mem_tobuffer(target, sregion.base, sregion.length)); -} - -static inline isc_result_t -towire_nid(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length == 10); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_nid(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nid); - REQUIRE(rdata1->length == 10); - REQUIRE(rdata2->length == 10); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_nid(ARGS_FROMSTRUCT) { - dns_rdata_nid_t *nid; - - REQUIRE(type == dns_rdatatype_nid); - REQUIRE(((dns_rdata_nid_t *)source) != NULL); - REQUIRE(((dns_rdata_nid_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_nid_t *)source)->common.rdclass == rdclass); - - nid = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(nid->pref, target)); - return (mem_tobuffer(target, nid->nid, sizeof(nid->nid))); -} - -static inline isc_result_t -tostruct_nid(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_nid_t *nid; - - REQUIRE(((dns_rdata_nid_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length == 10); - - nid = target; - - UNUSED(mctx); - - nid->common.rdclass = rdata->rdclass; - nid->common.rdtype = rdata->type; - ISC_LINK_INIT(&nid->common, link); - - dns_rdata_toregion(rdata, ®ion); - nid->pref = uint16_fromregion(®ion); - memmove(nid->nid, region.base, region.length); - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_nid(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_nid_t *)source) != NULL); - REQUIRE(((dns_rdata_nid_t *)source)->common.rdtype == - dns_rdatatype_nid); - - return; -} - -static inline isc_result_t -additionaldata_nid(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length == 10); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_nid(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length == 10); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_nid(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nid); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_nid(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nid); - REQUIRE(rdata->length == 10); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_nid(ARGS_COMPARE) { - return (compare_nid(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NID_104_C */ diff --git a/lib/dns-pkcs11/rdata/generic/nid_104.h b/lib/dns-pkcs11/rdata/generic/nid_104.h deleted file mode 100644 index ef041fd..0000000 --- a/lib/dns-pkcs11/rdata/generic/nid_104.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_NID_104_H -#define GENERIC_NID_104_H 1 - -typedef struct dns_rdata_nid { - dns_rdatacommon_t common; - uint16_t pref; - unsigned char nid[8]; -} dns_rdata_nid_t; - -#endif /* GENERIC_NID_104_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ninfo_56.c b/lib/dns-pkcs11/rdata/generic/ninfo_56.c deleted file mode 100644 index 700987d..0000000 --- a/lib/dns-pkcs11/rdata/generic/ninfo_56.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_NINFO_56_C -#define RDATA_GENERIC_NINFO_56_C - -#define RRTYPE_NINFO_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_ninfo(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_ninfo); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - return (generic_fromtext_txt(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_ninfo(ARGS_TOTEXT) { - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_ninfo); - - return (generic_totext_txt(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_ninfo(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_ninfo); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - return (generic_fromwire_txt(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_ninfo(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_ninfo); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_ninfo(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ninfo); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_ninfo(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_ninfo); - - return (generic_fromstruct_txt(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_ninfo(ARGS_TOSTRUCT) { - dns_rdata_ninfo_t *ninfo; - - REQUIRE(rdata->type == dns_rdatatype_ninfo); - REQUIRE(((dns_rdata_ninfo_t *)target) != NULL); - - ninfo = target; - - ninfo->common.rdclass = rdata->rdclass; - ninfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&ninfo->common, link); - - return (generic_tostruct_txt(rdata, target, mctx)); -} - -static inline void -freestruct_ninfo(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_ninfo_t *)source) != NULL); - REQUIRE(((dns_rdata_ninfo_t *)source)->common.rdtype == - dns_rdatatype_ninfo); - - generic_freestruct_txt(source); -} - -static inline isc_result_t -additionaldata_ninfo(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_ninfo); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ninfo(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_ninfo); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_ninfo(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ninfo); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_ninfo(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_ninfo); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_ninfo(ARGS_COMPARE) { - return (compare_ninfo(rdata1, rdata2)); -} - -isc_result_t -dns_rdata_ninfo_first(dns_rdata_ninfo_t *ninfo) { - - REQUIRE(ninfo != NULL); - REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo); - - return (generic_txt_first(ninfo)); -} - -isc_result_t -dns_rdata_ninfo_next(dns_rdata_ninfo_t *ninfo) { - - REQUIRE(ninfo != NULL); - REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo); - - return (generic_txt_next(ninfo)); -} - -isc_result_t -dns_rdata_ninfo_current(dns_rdata_ninfo_t *ninfo, - dns_rdata_ninfo_string_t *string) -{ - - REQUIRE(ninfo != NULL); - REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo); - - return (generic_txt_current(ninfo, string)); -} -#endif /* RDATA_GENERIC_NINFO_56_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ninfo_56.h b/lib/dns-pkcs11/rdata/generic/ninfo_56.h deleted file mode 100644 index 26ca2e2..0000000 --- a/lib/dns-pkcs11/rdata/generic/ninfo_56.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_NINFO_56_H -#define GENERIC_NINFO_56_H 1 - -typedef struct dns_rdata_txt_string dns_rdata_ninfo_string_t; - -typedef struct dns_rdata_txt dns_rdata_ninfo_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ - -isc_result_t -dns_rdata_ninfo_first(dns_rdata_ninfo_t *); - -isc_result_t -dns_rdata_ninfo_next(dns_rdata_ninfo_t *); - -isc_result_t -dns_rdata_ninfo_current(dns_rdata_ninfo_t *, dns_rdata_ninfo_string_t *); - -#endif /* GENERIC_NINFO_16_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ns_2.c b/lib/dns-pkcs11/rdata/generic/ns_2.c deleted file mode 100644 index de9032c..0000000 --- a/lib/dns-pkcs11/rdata/generic/ns_2.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_NS_2_C -#define RDATA_GENERIC_NS_2_C - -#define RRTYPE_NS_ATTRIBUTES (DNS_RDATATYPEATTR_ZONECUTAUTH) - -static inline isc_result_t -fromtext_ns(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - bool ok; - - REQUIRE(type == dns_rdatatype_ns); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token,isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_ns(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_ns); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_ns(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_ns); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_ns(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_ns); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_ns(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ns); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_ns(ARGS_FROMSTRUCT) { - dns_rdata_ns_t *ns; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_ns); - REQUIRE(((dns_rdata_ns_t *)source) != NULL); - REQUIRE(((dns_rdata_ns_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_ns_t *)source)->common.rdclass == rdclass); - - ns = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&ns->name, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_ns(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_ns_t *ns; - dns_name_t name; - - REQUIRE(((dns_rdata_ns_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_ns); - REQUIRE(rdata->length != 0); - - ns = target; - - ns->common.rdclass = rdata->rdclass; - ns->common.rdtype = rdata->type; - ISC_LINK_INIT(&ns->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&ns->name, NULL); - RETERR(name_duporclone(&name, mctx, &ns->name)); - ns->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_ns(ARGS_FREESTRUCT) { - dns_rdata_ns_t *ns; - - REQUIRE(((dns_rdata_ns_t *)source) != NULL); - - ns = source; - - if (ns->mctx == NULL) - return; - - dns_name_free(&ns->name, ns->mctx); - ns->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ns(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_ns); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_ns(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_ns); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_ns(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ns); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_ns(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_ns); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_ns(ARGS_COMPARE) { - return (compare_ns(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NS_2_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ns_2.h b/lib/dns-pkcs11/rdata/generic/ns_2.h deleted file mode 100644 index d1b0775..0000000 --- a/lib/dns-pkcs11/rdata/generic/ns_2.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_NS_2_H -#define GENERIC_NS_2_H 1 - - -typedef struct dns_rdata_ns { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t name; -} dns_rdata_ns_t; - - -#endif /* GENERIC_NS_2_H */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec3_50.c b/lib/dns-pkcs11/rdata/generic/nsec3_50.c deleted file mode 100644 index a4a4afa..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec3_50.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* - * Copyright (C) 2004 Nominet, Ltd. - * - * 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 NOMINET 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. - */ - -/* RFC 5155 */ - -#ifndef RDATA_GENERIC_NSEC3_50_C -#define RDATA_GENERIC_NSEC3_50_C - -#include -#include - -#define RRTYPE_NSEC3_ATTRIBUTES DNS_RDATATYPEATTR_DNSSEC - -static inline isc_result_t -fromtext_nsec3(ARGS_FROMTEXT) { - isc_token_t token; - unsigned int flags; - unsigned char hashalg; - isc_buffer_t b; - unsigned char buf[256]; - - REQUIRE(type == dns_rdatatype_nsec3); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - UNUSED(origin); - UNUSED(options); - - /* Hash. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); - RETERR(uint8_tobuffer(hashalg, target)); - - /* Flags. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - flags = token.value.as_ulong; - if (flags > 255U) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(flags, target)); - - /* Iterations. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* salt */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (token.value.as_textregion.length > (255*2)) - RETTOK(DNS_R_TEXTTOOLONG); - if (strcmp(DNS_AS_STR(token), "-") == 0) { - RETERR(uint8_tobuffer(0, target)); - } else { - RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); - RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); - } - - /* - * Next hash a single base32hex word. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - isc_buffer_init(&b, buf, sizeof(buf)); - RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b)); - if (isc_buffer_usedlength(&b) > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target)); - RETERR(mem_tobuffer(target, &buf, isc_buffer_usedlength(&b))); - - return (typemap_fromtext(lexer, target, true)); -} - -static inline isc_result_t -totext_nsec3(ARGS_TOTEXT) { - isc_region_t sr; - unsigned int i, j; - unsigned char hash; - unsigned char flags; - char buf[sizeof("TYPE65535")]; - uint32_t iterations; - - REQUIRE(rdata->type == dns_rdatatype_nsec3); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* Hash */ - hash = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", hash); - RETERR(str_totext(buf, target)); - - /* Flags */ - flags = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", flags); - RETERR(str_totext(buf, target)); - - /* Iterations */ - iterations = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%u ", iterations); - RETERR(str_totext(buf, target)); - - /* Salt */ - j = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - INSIST(j <= sr.length); - - if (j != 0) { - i = sr.length; - sr.length = j; - RETERR(isc_hex_totext(&sr, 1, "", target)); - sr.length = i - j; - } else - RETERR(str_totext("-", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - /* Next hash */ - j = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - INSIST(j <= sr.length); - - i = sr.length; - sr.length = j; - RETERR(isc_base32hexnp_totext(&sr, 1, "", target)); - sr.length = i - j; - - /* - * Don't leave a trailing space when there's no typemap present. - */ - if (((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) && (sr.length > 0)) { - RETERR(str_totext(" ", target)); - } - RETERR(typemap_totext(&sr, tctx, target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_nsec3(ARGS_FROMWIRE) { - isc_region_t sr, rr; - unsigned int saltlen, hashlen; - - REQUIRE(type == dns_rdatatype_nsec3); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(options); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sr); - rr = sr; - - /* hash(1), flags(1), iteration(2), saltlen(1) */ - if (sr.length < 5U) - RETERR(DNS_R_FORMERR); - saltlen = sr.base[4]; - isc_region_consume(&sr, 5); - - if (sr.length < saltlen) - RETERR(DNS_R_FORMERR); - isc_region_consume(&sr, saltlen); - - if (sr.length < 1U) - RETERR(DNS_R_FORMERR); - hashlen = sr.base[0]; - isc_region_consume(&sr, 1); - - if (hashlen < 1 || sr.length < hashlen) { - RETERR(DNS_R_FORMERR); - } - isc_region_consume(&sr, hashlen); - - RETERR(typemap_test(&sr, true)); - - RETERR(mem_tobuffer(target, rr.base, rr.length)); - isc_buffer_forward(source, rr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_nsec3(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_nsec3); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_nsec3(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsec3); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_nsec3(ARGS_FROMSTRUCT) { - dns_rdata_nsec3_t *nsec3; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nsec3); - REQUIRE(((dns_rdata_nsec3_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec3_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_nsec3_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_nsec3_t *)source)->typebits != NULL || - ((dns_rdata_nsec3_t *)source)->len == 0); - REQUIRE(((dns_rdata_nsec3_t *)source)->hash == dns_hash_sha1); - - nsec3 = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(nsec3->hash, target)); - RETERR(uint8_tobuffer(nsec3->flags, target)); - RETERR(uint16_tobuffer(nsec3->iterations, target)); - RETERR(uint8_tobuffer(nsec3->salt_length, target)); - RETERR(mem_tobuffer(target, nsec3->salt, nsec3->salt_length)); - RETERR(uint8_tobuffer(nsec3->next_length, target)); - RETERR(mem_tobuffer(target, nsec3->next, nsec3->next_length)); - - region.base = nsec3->typebits; - region.length = nsec3->len; - RETERR(typemap_test(®ion, true)); - return (mem_tobuffer(target, nsec3->typebits, nsec3->len)); -} - -static inline isc_result_t -tostruct_nsec3(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_nsec3_t *nsec3; - - REQUIRE(((dns_rdata_nsec3_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsec3); - REQUIRE(rdata->length != 0); - - nsec3 = target; - - nsec3->common.rdclass = rdata->rdclass; - nsec3->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec3->common, link); - - region.base = rdata->data; - region.length = rdata->length; - nsec3->hash = uint8_consume_fromregion(®ion); - nsec3->flags = uint8_consume_fromregion(®ion); - nsec3->iterations = uint16_consume_fromregion(®ion); - - nsec3->salt_length = uint8_consume_fromregion(®ion); - nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length); - if (nsec3->salt == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(®ion, nsec3->salt_length); - - nsec3->next_length = uint8_consume_fromregion(®ion); - nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length); - if (nsec3->next == NULL) - goto cleanup; - isc_region_consume(®ion, nsec3->next_length); - - nsec3->len = region.length; - nsec3->typebits = mem_maybedup(mctx, region.base, region.length); - if (nsec3->typebits == NULL) - goto cleanup; - - nsec3->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (nsec3->next != NULL) - isc_mem_free(mctx, nsec3->next); - isc_mem_free(mctx, nsec3->salt); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_nsec3(ARGS_FREESTRUCT) { - dns_rdata_nsec3_t *nsec3; - - REQUIRE(((dns_rdata_nsec3_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec3_t *)source)->common.rdtype == - dns_rdatatype_nsec3); - - nsec3 = source; - - if (nsec3->mctx == NULL) - return; - - if (nsec3->salt != NULL) - isc_mem_free(nsec3->mctx, nsec3->salt); - if (nsec3->next != NULL) - isc_mem_free(nsec3->mctx, nsec3->next); - if (nsec3->typebits != NULL) - isc_mem_free(nsec3->mctx, nsec3->typebits); - nsec3->mctx = NULL; -} - -static inline isc_result_t -additionaldata_nsec3(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nsec3); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_nsec3(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nsec3); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_nsec3(ARGS_CHECKOWNER) { - unsigned char owner[NSEC3_MAX_HASH_LENGTH]; - isc_buffer_t buffer; - dns_label_t label; - - REQUIRE(type == dns_rdatatype_nsec3); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - /* - * First label is a base32hex string without padding. - */ - dns_name_getlabel(name, 0, &label); - isc_region_consume(&label, 1); - isc_buffer_init(&buffer, owner, sizeof(owner)); - if (isc_base32hexnp_decoderegion(&label, &buffer) == ISC_R_SUCCESS) - return (true); - - return (false); -} - -static inline bool -checknames_nsec3(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nsec3); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_nsec3(ARGS_COMPARE) { - return (compare_nsec3(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NSEC3_50_C */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec3_50.h b/lib/dns-pkcs11/rdata/generic/nsec3_50.h deleted file mode 100644 index e0372eb..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec3_50.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_NSEC3_50_H -#define GENERIC_NSEC3_50_H 1 - - -/*! - * \brief Per RFC 5155 */ - -#include - -typedef struct dns_rdata_nsec3 { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_hash_t hash; - unsigned char flags; - dns_iterations_t iterations; - unsigned char salt_length; - unsigned char next_length; - uint16_t len; - unsigned char *salt; - unsigned char *next; - unsigned char *typebits; -} dns_rdata_nsec3_t; - -/* - * The corresponding NSEC3 interval is OPTOUT indicating possible - * insecure delegations. - */ -#define DNS_NSEC3FLAG_OPTOUT 0x01U - -/*% - * The following flags are used in the private-type record (implemented in - * lib/dns/private.c) which is used to store NSEC3PARAM data during the - * time when it is not legal to have an actual NSEC3PARAM record in the - * zone. They are defined here because the private-type record uses the - * same flags field for the OPTOUT flag above and for the private flags - * below. XXX: This should be considered for refactoring. - */ - -/*% - * Non-standard, private type only. - * - * Create a corresponding NSEC3 chain. - * Once the NSEC3 chain is complete this flag will be removed to signal - * that there is a complete chain. - * - * This flag is automatically set when a NSEC3PARAM record is added to - * the zone via UPDATE. - * - * NSEC3PARAM records containing this flag should never be published, - * but if they are, they should be ignored by RFC 5155 compliant - * nameservers. - */ -#define DNS_NSEC3FLAG_CREATE 0x80U - -/*% - * Non-standard, private type only. - * - * The corresponding NSEC3 set is to be removed once the NSEC chain - * has been generated. - * - * This flag is automatically set when the last active NSEC3PARAM record - * is removed from the zone via UPDATE. - * - * NSEC3PARAM records containing this flag should never be published, - * but if they are, they should be ignored by RFC 5155 compliant - * nameservers. - */ -#define DNS_NSEC3FLAG_REMOVE 0x40U - -/*% - * Non-standard, private type only. - * - * When set with the CREATE flag, a corresponding NSEC3 chain will be - * created when the zone becomes capable of supporting one (i.e., when it - * has a DNSKEY RRset containing at least one NSEC3-capable algorithm). - * Without this flag, NSEC3 chain creation would be attempted immediately, - * fail, and the private type record would be removed. With it, the NSEC3 - * parameters are stored until they can be used. When the zone has the - * necessary prerequisites for NSEC3, then the INITIAL flag can be cleared, - * and the record will be cleaned up normally. - * - * NSEC3PARAM records containing this flag should never be published, but - * if they are, they should be ignored by RFC 5155 compliant nameservers. - */ -#define DNS_NSEC3FLAG_INITIAL 0x20U - -/*% - * Non-standard, private type only. - * - * Prevent the creation of a NSEC chain before the last NSEC3 chain - * is removed. This will normally only be set when the zone is - * transitioning from secure with NSEC3 chains to insecure. - * - * NSEC3PARAM records containing this flag should never be published, - * but if they are, they should be ignored by RFC 5155 compliant - * nameservers. - */ -#define DNS_NSEC3FLAG_NONSEC 0x10U - -#endif /* GENERIC_NSEC3_50_H */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec3param_51.c b/lib/dns-pkcs11/rdata/generic/nsec3param_51.c deleted file mode 100644 index a3cf0bc..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec3param_51.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* - * Copyright (C) 2004 Nominet, Ltd. - * - * 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 NOMINET 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. - */ - -/* RFC 5155 */ - -#ifndef RDATA_GENERIC_NSEC3PARAM_51_C -#define RDATA_GENERIC_NSEC3PARAM_51_C - -#include -#include - -#define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) - -static inline isc_result_t -fromtext_nsec3param(ARGS_FROMTEXT) { - isc_token_t token; - unsigned int flags = 0; - unsigned char hashalg; - - REQUIRE(type == dns_rdatatype_nsec3param); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - UNUSED(origin); - UNUSED(options); - - /* Hash. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); - RETERR(uint8_tobuffer(hashalg, target)); - - /* Flags. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - flags = token.value.as_ulong; - if (flags > 255U) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(flags, target)); - - /* Iterations. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* Salt. */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (token.value.as_textregion.length > (255*2)) - RETTOK(DNS_R_TEXTTOOLONG); - if (strcmp(DNS_AS_STR(token), "-") == 0) { - RETERR(uint8_tobuffer(0, target)); - } else { - RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); - RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_nsec3param(ARGS_TOTEXT) { - isc_region_t sr; - unsigned int i, j; - unsigned char hash; - unsigned char flags; - char buf[sizeof("65535 ")]; - uint32_t iterations; - - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - hash = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - flags = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - iterations = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - snprintf(buf, sizeof(buf), "%u ", hash); - RETERR(str_totext(buf, target)); - - snprintf(buf, sizeof(buf), "%u ", flags); - RETERR(str_totext(buf, target)); - - snprintf(buf, sizeof(buf), "%u ", iterations); - RETERR(str_totext(buf, target)); - - j = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - INSIST(j <= sr.length); - - if (j != 0) { - i = sr.length; - sr.length = j; - RETERR(isc_hex_totext(&sr, 1, "", target)); - sr.length = i - j; - } else - RETERR(str_totext("-", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_nsec3param(ARGS_FROMWIRE) { - isc_region_t sr, rr; - unsigned int saltlen; - - REQUIRE(type == dns_rdatatype_nsec3param); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(options); - UNUSED(dctx); - - isc_buffer_activeregion(source, &sr); - rr = sr; - - /* hash(1), flags(1), iterations(2), saltlen(1) */ - if (sr.length < 5U) - RETERR(DNS_R_FORMERR); - saltlen = sr.base[4]; - isc_region_consume(&sr, 5); - - if (sr.length != saltlen) { - RETERR(DNS_R_FORMERR); - } - isc_region_consume(&sr, saltlen); - RETERR(mem_tobuffer(target, rr.base, rr.length)); - isc_buffer_forward(source, rr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_nsec3param(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_nsec3param(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsec3param); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_nsec3param(ARGS_FROMSTRUCT) { - dns_rdata_nsec3param_t *nsec3param; - - REQUIRE(type == dns_rdatatype_nsec3param); - REQUIRE(((dns_rdata_nsec3param_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec3param_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_nsec3param_t *)source)->common.rdclass == rdclass); - - nsec3param = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(nsec3param->hash, target)); - RETERR(uint8_tobuffer(nsec3param->flags, target)); - RETERR(uint16_tobuffer(nsec3param->iterations, target)); - RETERR(uint8_tobuffer(nsec3param->salt_length, target)); - RETERR(mem_tobuffer(target, nsec3param->salt, - nsec3param->salt_length)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -tostruct_nsec3param(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_nsec3param_t *nsec3param; - - REQUIRE(((dns_rdata_nsec3param_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - REQUIRE(rdata->length != 0); - - nsec3param = target; - - nsec3param->common.rdclass = rdata->rdclass; - nsec3param->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec3param->common, link); - - region.base = rdata->data; - region.length = rdata->length; - nsec3param->hash = uint8_consume_fromregion(®ion); - nsec3param->flags = uint8_consume_fromregion(®ion); - nsec3param->iterations = uint16_consume_fromregion(®ion); - - nsec3param->salt_length = uint8_consume_fromregion(®ion); - nsec3param->salt = mem_maybedup(mctx, region.base, - nsec3param->salt_length); - if (nsec3param->salt == NULL) - return (ISC_R_NOMEMORY); - isc_region_consume(®ion, nsec3param->salt_length); - - nsec3param->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_nsec3param(ARGS_FREESTRUCT) { - dns_rdata_nsec3param_t *nsec3param; - - REQUIRE(((dns_rdata_nsec3param_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec3param_t *)source)->common.rdtype == - dns_rdatatype_nsec3param); - - nsec3param = source; - - if (nsec3param->mctx == NULL) - return; - - if (nsec3param->salt != NULL) - isc_mem_free(nsec3param->mctx, nsec3param->salt); - nsec3param->mctx = NULL; -} - -static inline isc_result_t -additionaldata_nsec3param(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_nsec3param(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_nsec3param(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nsec3param); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_nsec3param(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nsec3param); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_nsec3param(ARGS_COMPARE) { - return (compare_nsec3param(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec3param_51.h b/lib/dns-pkcs11/rdata/generic/nsec3param_51.h deleted file mode 100644 index 5404fc6..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec3param_51.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_NSEC3PARAM_51_H -#define GENERIC_NSEC3PARAM_51_H 1 - - -/*! - * \brief Per RFC 5155 */ - -#include - -typedef struct dns_rdata_nsec3param { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_hash_t hash; - unsigned char flags; /* DNS_NSEC3FLAG_* */ - dns_iterations_t iterations; - unsigned char salt_length; - unsigned char *salt; -} dns_rdata_nsec3param_t; - -#endif /* GENERIC_NSEC3PARAM_51_H */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec_47.c b/lib/dns-pkcs11/rdata/generic/nsec_47.c deleted file mode 100644 index d20b628..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec_47.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC 3845 */ - -#ifndef RDATA_GENERIC_NSEC_47_C -#define RDATA_GENERIC_NSEC_47_C - -/* - * The attributes do not include DNS_RDATATYPEATTR_SINGLETON - * because we must be able to handle a parent/child NSEC pair. - */ -#define RRTYPE_NSEC_ATTRIBUTES \ - ( DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH | \ - DNS_RDATATYPEATTR_ATCNAME ) - -static inline isc_result_t -fromtext_nsec(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_nsec); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Next domain. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - return (typemap_fromtext(lexer, target, false)); -} - -static inline isc_result_t -totext_nsec(ARGS_TOTEXT) { - isc_region_t sr; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_nsec); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, &sr); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_totext(&name, false, target)); - /* - * Don't leave a trailing space when there's no typemap present. - */ - if (sr.length > 0) { - RETERR(str_totext(" ", target)); - } - return (typemap_totext(&sr, NULL, target)); -} - -static /* inline */ isc_result_t -fromwire_nsec(ARGS_FROMWIRE) { - isc_region_t sr; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_nsec); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - isc_buffer_activeregion(source, &sr); - RETERR(typemap_test(&sr, false)); - RETERR(mem_tobuffer(target, sr.base, sr.length)); - isc_buffer_forward(source, sr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_nsec(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_nsec); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, &sr); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_towire(&name, cctx, target)); - - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_nsec(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsec); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_nsec(ARGS_FROMSTRUCT) { - dns_rdata_nsec_t *nsec; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nsec); - REQUIRE(((dns_rdata_nsec_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_nsec_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_nsec_t *)source)->typebits != NULL || - ((dns_rdata_nsec_t *)source)->len == 0); - - nsec = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&nsec->next, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - - region.base = nsec->typebits; - region.length = nsec->len; - RETERR(typemap_test(®ion, false)); - return (mem_tobuffer(target, nsec->typebits, nsec->len)); -} - -static inline isc_result_t -tostruct_nsec(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_nsec_t *nsec; - dns_name_t name; - - REQUIRE(((dns_rdata_nsec_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsec); - REQUIRE(rdata->length != 0); - - nsec = target; - - nsec->common.rdclass = rdata->rdclass; - nsec->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&nsec->next, NULL); - RETERR(name_duporclone(&name, mctx, &nsec->next)); - - nsec->len = region.length; - nsec->typebits = mem_maybedup(mctx, region.base, region.length); - if (nsec->typebits == NULL) - goto cleanup; - - nsec->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&nsec->next, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_nsec(ARGS_FREESTRUCT) { - dns_rdata_nsec_t *nsec; - - REQUIRE(((dns_rdata_nsec_t *)source) != NULL); - REQUIRE(((dns_rdata_nsec_t *)source)->common.rdtype == - dns_rdatatype_nsec); - - nsec = source; - - if (nsec->mctx == NULL) - return; - - dns_name_free(&nsec->next, nsec->mctx); - if (nsec->typebits != NULL) - isc_mem_free(nsec->mctx, nsec->typebits); - nsec->mctx = NULL; -} - -static inline isc_result_t -additionaldata_nsec(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nsec); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_nsec(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nsec); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_nsec(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nsec); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_nsec(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nsec); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_nsec(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsec); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - return (isc_region_compare(®ion1, ®ion2)); -} -#endif /* RDATA_GENERIC_NSEC_47_C */ diff --git a/lib/dns-pkcs11/rdata/generic/nsec_47.h b/lib/dns-pkcs11/rdata/generic/nsec_47.h deleted file mode 100644 index b99f92a..0000000 --- a/lib/dns-pkcs11/rdata/generic/nsec_47.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_NSEC_47_H -#define GENERIC_NSEC_47_H 1 - - -/*! - * \brief Per RFC 3845 */ - -typedef struct dns_rdata_nsec { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t next; - unsigned char *typebits; - uint16_t len; -} dns_rdata_nsec_t; - -#endif /* GENERIC_NSEC_47_H */ diff --git a/lib/dns-pkcs11/rdata/generic/null_10.c b/lib/dns-pkcs11/rdata/generic/null_10.c deleted file mode 100644 index 1acccc4..0000000 --- a/lib/dns-pkcs11/rdata/generic/null_10.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_NULL_10_C -#define RDATA_GENERIC_NULL_10_C - -#define RRTYPE_NULL_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_null(ARGS_FROMTEXT) { - REQUIRE(type == dns_rdatatype_null); - - UNUSED(rdclass); - UNUSED(type); - UNUSED(lexer); - UNUSED(origin); - UNUSED(options); - UNUSED(target); - UNUSED(callbacks); - - return (DNS_R_SYNTAX); -} - -static inline isc_result_t -totext_null(ARGS_TOTEXT) { - REQUIRE(rdata->type == dns_rdatatype_null); - - return (unknown_totext(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_null(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_null); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_null(ARGS_TOWIRE) { - REQUIRE(rdata->type == dns_rdatatype_null); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_null(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_null); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_null(ARGS_FROMSTRUCT) { - dns_rdata_null_t *null; - - REQUIRE(type == dns_rdatatype_null); - REQUIRE(((dns_rdata_null_t *)source) != NULL); - REQUIRE(((dns_rdata_null_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_null_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_null_t *)source)->data != NULL || - ((dns_rdata_null_t *)source)->length == 0); - - null = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, null->data, null->length)); -} - -static inline isc_result_t -tostruct_null(ARGS_TOSTRUCT) { - dns_rdata_null_t *null; - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_null); - REQUIRE(((dns_rdata_null_t *)target) != NULL); - - null = target; - - null->common.rdclass = rdata->rdclass; - null->common.rdtype = rdata->type; - ISC_LINK_INIT(&null->common, link); - - dns_rdata_toregion(rdata, &r); - null->length = r.length; - null->data = mem_maybedup(mctx, r.base, r.length); - if (null->data == NULL) - return (ISC_R_NOMEMORY); - - null->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_null(ARGS_FREESTRUCT) { - dns_rdata_null_t *null; - - REQUIRE(((dns_rdata_null_t *)source) != NULL); - REQUIRE(((dns_rdata_null_t *)source)->common.rdtype == - dns_rdatatype_null); - - null = source; - - if (null->mctx == NULL) - return; - - if (null->data != NULL) - isc_mem_free(null->mctx, null->data); - null->mctx = NULL; -} - -static inline isc_result_t -additionaldata_null(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_null); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_null(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_null); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_null(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_null); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_null(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_null); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_null(ARGS_COMPARE) { - return (compare_null(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_NULL_10_C */ diff --git a/lib/dns-pkcs11/rdata/generic/null_10.h b/lib/dns-pkcs11/rdata/generic/null_10.h deleted file mode 100644 index 23328a5..0000000 --- a/lib/dns-pkcs11/rdata/generic/null_10.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_NULL_10_H -#define GENERIC_NULL_10_H 1 - - -typedef struct dns_rdata_null { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t length; - unsigned char *data; -} dns_rdata_null_t; - - -#endif /* GENERIC_NULL_10_H */ diff --git a/lib/dns-pkcs11/rdata/generic/nxt_30.c b/lib/dns-pkcs11/rdata/generic/nxt_30.c deleted file mode 100644 index 07ffedc..0000000 --- a/lib/dns-pkcs11/rdata/generic/nxt_30.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2535 */ - -#ifndef RDATA_GENERIC_NXT_30_C -#define RDATA_GENERIC_NXT_30_C - -/* - * The attributes do not include DNS_RDATATYPEATTR_SINGLETON - * because we must be able to handle a parent/child NXT pair. - */ -#define RRTYPE_NXT_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_nxt(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - char *e; - unsigned char bm[8*1024]; /* 64k bits */ - dns_rdatatype_t covered; - dns_rdatatype_t maxcovered = 0; - bool first = true; - long n; - - REQUIRE(type == dns_rdatatype_nxt); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Next domain. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - memset(bm, 0, sizeof(bm)); - do { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, true)); - if (token.type != isc_tokentype_string) - break; - n = strtol(DNS_AS_STR(token), &e, 10); - if (e != DNS_AS_STR(token) && *e == '\0') { - covered = (dns_rdatatype_t)n; - } else if (dns_rdatatype_fromtext(&covered, - &token.value.as_textregion) == DNS_R_UNKNOWN) - RETTOK(DNS_R_UNKNOWN); - /* - * NXT is only specified for types 1..127. - */ - if (covered < 1 || covered > 127) - return (ISC_R_RANGE); - if (first || covered > maxcovered) - maxcovered = covered; - first = false; - bm[covered/8] |= (0x80>>(covered%8)); - } while (1); - isc_lex_ungettoken(lexer, &token); - if (first) - return (ISC_R_SUCCESS); - n = (maxcovered + 8) / 8; - return (mem_tobuffer(target, bm, n)); -} - -static inline isc_result_t -totext_nxt(ARGS_TOTEXT) { - isc_region_t sr; - unsigned int i, j; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_nxt); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - dns_rdata_toregion(rdata, &sr); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - sub = name_prefix(&name, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - for (i = 0; i < sr.length; i++) { - if (sr.base[i] != 0) - for (j = 0; j < 8; j++) - if ((sr.base[i] & (0x80 >> j)) != 0) { - dns_rdatatype_t t = i * 8 + j; - RETERR(str_totext(" ", target)); - if (dns_rdatatype_isknown(t)) { - RETERR(dns_rdatatype_totext(t, - target)); - } else { - char buf[sizeof("65535")]; - snprintf(buf, sizeof(buf), - "%u", t); - RETERR(str_totext(buf, - target)); - } - } - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_nxt(ARGS_FROMWIRE) { - isc_region_t sr; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_nxt); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - isc_buffer_activeregion(source, &sr); - if (sr.length > 0 && ((sr.base[0] & 0x80) != 0 || sr.length > 16 || - sr.base[sr.length - 1] == 0)) - { - return (DNS_R_BADBITMAP); - } - RETERR(mem_tobuffer(target, sr.base, sr.length)); - isc_buffer_forward(source, sr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_nxt(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_nxt); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, &sr); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_towire(&name, cctx, target)); - - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_nxt(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nxt); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_nxt(ARGS_FROMSTRUCT) { - dns_rdata_nxt_t *nxt; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nxt); - REQUIRE(((dns_rdata_nxt_t *)source) != NULL); - nxt = source; - REQUIRE(nxt->common.rdtype == type); - REQUIRE(nxt->common.rdclass == rdclass); - REQUIRE(nxt->typebits != NULL || nxt->len == 0); - - if (nxt->typebits != NULL && (nxt->typebits[0] & 0x80) == 0) { - REQUIRE(nxt->len <= 16); - REQUIRE(nxt->typebits[nxt->len - 1] != 0); - } - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&nxt->next, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - - return (mem_tobuffer(target, nxt->typebits, nxt->len)); -} - -static inline isc_result_t -tostruct_nxt(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_nxt_t *nxt; - dns_name_t name; - - REQUIRE(((dns_rdata_nxt_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nxt); - REQUIRE(rdata->length != 0); - - nxt = target; - - nxt->common.rdclass = rdata->rdclass; - nxt->common.rdtype = rdata->type; - ISC_LINK_INIT(&nxt->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&nxt->next, NULL); - RETERR(name_duporclone(&name, mctx, &nxt->next)); - - nxt->len = region.length; - nxt->typebits = mem_maybedup(mctx, region.base, region.length); - if (nxt->typebits == NULL) - goto cleanup; - - nxt->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&nxt->next, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_nxt(ARGS_FREESTRUCT) { - dns_rdata_nxt_t *nxt; - - REQUIRE(((dns_rdata_nxt_t *)source) != NULL); - REQUIRE(((dns_rdata_nxt_t *)source)->common.rdtype == - dns_rdatatype_nxt); - - nxt = source; - - if (nxt->mctx == NULL) - return; - - dns_name_free(&nxt->next, nxt->mctx); - if (nxt->typebits != NULL) - isc_mem_free(nxt->mctx, nxt->typebits); - nxt->mctx = NULL; -} - -static inline isc_result_t -additionaldata_nxt(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nxt); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_nxt(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_nxt); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - result = dns_name_digest(&name, digest, arg); - if (result != ISC_R_SUCCESS) - return (result); - isc_region_consume(&r, name_length(&name)); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_nxt(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nxt); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_nxt(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nxt); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_nxt(ARGS_COMPARE) { - return (compare_nxt(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_NXT_30_C */ diff --git a/lib/dns-pkcs11/rdata/generic/nxt_30.h b/lib/dns-pkcs11/rdata/generic/nxt_30.h deleted file mode 100644 index 8fa0d84..0000000 --- a/lib/dns-pkcs11/rdata/generic/nxt_30.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_NXT_30_H -#define GENERIC_NXT_30_H 1 - - -/*! - * \brief RFC2535 */ - -typedef struct dns_rdata_nxt { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t next; - unsigned char *typebits; - uint16_t len; -} dns_rdata_nxt_t; - -#endif /* GENERIC_NXT_30_H */ diff --git a/lib/dns-pkcs11/rdata/generic/openpgpkey_61.c b/lib/dns-pkcs11/rdata/generic/openpgpkey_61.c deleted file mode 100644 index 69c3644..0000000 --- a/lib/dns-pkcs11/rdata/generic/openpgpkey_61.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_OPENPGPKEY_61_C -#define RDATA_GENERIC_OPENPGPKEY_61_C - -#define RRTYPE_OPENPGPKEY_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_openpgpkey(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_openpgpkey); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - UNUSED(options); - UNUSED(origin); - - /* - * Keyring. - */ - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_openpgpkey(ARGS_TOTEXT) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* - * Keyring - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext("( ", target)); - - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else - RETERR(str_totext("[omitted]", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_openpgpkey(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_openpgpkey); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - /* - * Keyring. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_openpgpkey(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_openpgpkey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_openpgpkey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_openpgpkey(ARGS_FROMSTRUCT) { - dns_rdata_openpgpkey_t *sig; - - REQUIRE(type == dns_rdatatype_openpgpkey); - REQUIRE(((dns_rdata_openpgpkey_t *)source) != NULL); - REQUIRE(((dns_rdata_openpgpkey_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_openpgpkey_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_openpgpkey_t *)source)->keyring != NULL); - REQUIRE(((dns_rdata_openpgpkey_t *)source)->length != 0); - - sig = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Keyring. - */ - return (mem_tobuffer(target, sig->keyring, sig->length)); -} - -static inline isc_result_t -tostruct_openpgpkey(ARGS_TOSTRUCT) { - isc_region_t sr; - dns_rdata_openpgpkey_t *sig; - - REQUIRE(((dns_rdata_openpgpkey_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - REQUIRE(rdata->length != 0); - - sig = target; - - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Keyring. - */ - sig->length = sr.length; - sig->keyring = mem_maybedup(mctx, sr.base, sig->length); - if (sig->keyring == NULL) - goto cleanup; - - sig->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_openpgpkey(ARGS_FREESTRUCT) { - dns_rdata_openpgpkey_t *sig; - - REQUIRE(((dns_rdata_openpgpkey_t *)source) != NULL); - REQUIRE(((dns_rdata_openpgpkey_t *)source)->common.rdtype == - dns_rdatatype_openpgpkey); - - sig = (dns_rdata_openpgpkey_t *) source; - - if (sig->mctx == NULL) - return; - - if (sig->keyring != NULL) - isc_mem_free(sig->mctx, sig->keyring); - sig->mctx = NULL; -} - -static inline isc_result_t -additionaldata_openpgpkey(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_openpgpkey(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_openpgpkey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_openpgpkey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_openpgpkey(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_openpgpkey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_openpgpkey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_openpgpkey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - - return (isc_region_compare(&r1, &r2)); -} - -#endif /* RDATA_GENERIC_OPENPGPKEY_61_C */ diff --git a/lib/dns-pkcs11/rdata/generic/openpgpkey_61.h b/lib/dns-pkcs11/rdata/generic/openpgpkey_61.h deleted file mode 100644 index 1197910..0000000 --- a/lib/dns-pkcs11/rdata/generic/openpgpkey_61.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_OPENPGPKEY_61_H -#define GENERIC_OPENPGPKEY_61_H 1 - -typedef struct dns_rdata_openpgpkey { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint16_t length; - unsigned char * keyring; -} dns_rdata_openpgpkey_t; - -#endif /* GENERIC_OPENPGPKEY_61_H */ diff --git a/lib/dns-pkcs11/rdata/generic/opt_41.c b/lib/dns-pkcs11/rdata/generic/opt_41.c deleted file mode 100644 index 40fcbe7..0000000 --- a/lib/dns-pkcs11/rdata/generic/opt_41.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2671 */ - -#ifndef RDATA_GENERIC_OPT_41_C -#define RDATA_GENERIC_OPT_41_C - -#define RRTYPE_OPT_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON | \ - DNS_RDATATYPEATTR_META | \ - DNS_RDATATYPEATTR_NOTQUESTION) - -#include - -static inline isc_result_t -fromtext_opt(ARGS_FROMTEXT) { - /* - * OPT records do not have a text format. - */ - - REQUIRE(type == dns_rdatatype_opt); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(lexer); - UNUSED(origin); - UNUSED(options); - UNUSED(target); - UNUSED(callbacks); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline isc_result_t -totext_opt(ARGS_TOTEXT) { - isc_region_t r; - isc_region_t or; - uint16_t option; - uint16_t length; - char buf[sizeof("64000 64000")]; - - /* - * OPT records do not have a text format. - */ - - REQUIRE(rdata->type == dns_rdatatype_opt); - - dns_rdata_toregion(rdata, &r); - while (r.length > 0) { - option = uint16_fromregion(&r); - isc_region_consume(&r, 2); - length = uint16_fromregion(&r); - isc_region_consume(&r, 2); - snprintf(buf, sizeof(buf), "%u %u", option, length); - RETERR(str_totext(buf, target)); - INSIST(r.length >= length); - if (length > 0) { - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - or = r; - or.length = length; - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&or, 60, "", target)); - else - RETERR(isc_base64_totext(&or, tctx->width - 2, - tctx->linebreak, - target)); - isc_region_consume(&r, length); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - } - if (r.length > 0) - RETERR(str_totext(" ", target)); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_opt(ARGS_FROMWIRE) { - isc_region_t sregion; - isc_region_t tregion; - uint16_t opt; - uint16_t length; - unsigned int total; - - REQUIRE(type == dns_rdatatype_opt); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length == 0) { - return (ISC_R_SUCCESS); - } - total = 0; - while (sregion.length != 0) { - if (sregion.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - opt = uint16_fromregion(&sregion); - isc_region_consume(&sregion, 2); - length = uint16_fromregion(&sregion); - isc_region_consume(&sregion, 2); - total += 4; - if (sregion.length < length) { - return (ISC_R_UNEXPECTEDEND); - } - switch (opt) { - case DNS_OPT_LLQ: - if (length != 18U) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - case DNS_OPT_CLIENT_SUBNET: { - uint16_t family; - uint8_t addrlen; - uint8_t scope; - uint8_t addrbytes; - - if (length < 4) { - return (DNS_R_OPTERR); - } - family = uint16_fromregion(&sregion); - isc_region_consume(&sregion, 2); - addrlen = uint8_fromregion(&sregion); - isc_region_consume(&sregion, 1); - scope = uint8_fromregion(&sregion); - isc_region_consume(&sregion, 1); - - switch (family) { - case 0: - /* - * XXXMUKS: In queries and replies, if - * FAMILY is set to 0, SOURCE - * PREFIX-LENGTH and SCOPE PREFIX-LENGTH - * must be 0 and ADDRESS should not be - * present as the address and prefix - * lengths don't make sense because the - * family is unknown. - */ - if (addrlen != 0U || scope != 0U) { - return (DNS_R_OPTERR); - } - break; - case 1: - if (addrlen > 32U || scope > 32U) { - return (DNS_R_OPTERR); - } - break; - case 2: - if (addrlen > 128U || scope > 128U) { - return (DNS_R_OPTERR); - } - break; - default: - return (DNS_R_OPTERR); - } - addrbytes = (addrlen + 7) / 8; - if (addrbytes + 4 != length) { - return (DNS_R_OPTERR); - } - - if (addrbytes != 0U && (addrlen % 8) != 0) { - uint8_t bits = ~0U << (8 - (addrlen % 8)); - bits &= sregion.base[addrbytes - 1]; - if (bits != sregion.base[addrbytes - 1]) { - return (DNS_R_OPTERR); - } - } - isc_region_consume(&sregion, addrbytes); - break; - } - case DNS_OPT_EXPIRE: - /* - * Request has zero length. Response is 32 bits. - */ - if (length != 0 && length != 4) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - case DNS_OPT_COOKIE: - /* - * Client cookie alone has length 8. - * Client + server cookie is 8 + [8..32]. - */ - if (length != 8 && (length < 16 || length > 40)) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - case DNS_OPT_KEY_TAG: - if (length == 0 || (length % 2) != 0) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - case DNS_OPT_EDE: - if (length < 2) { - return (DNS_R_OPTERR); - } - /* UTF-8 Byte Order Mark is not permitted. RFC 5198 */ - if (isc_utf8_bom(sregion.base + 2, length - 2)) { - return (DNS_R_OPTERR); - } - /* - * The EXTRA-TEXT field is specified as UTF-8, and - * therefore must be validated for correctness - * according to RFC 3269 security considerations. - */ - if (!isc_utf8_valid(sregion.base + 2, length - 2)) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - case DNS_OPT_CLIENT_TAG: - /* FALLTHROUGH */ - case DNS_OPT_SERVER_TAG: - if (length != 2) { - return (DNS_R_OPTERR); - } - isc_region_consume(&sregion, length); - break; - default: - isc_region_consume(&sregion, length); - break; - } - total += length; - } - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (tregion.length < total) { - return (ISC_R_NOSPACE); - } - memmove(tregion.base, sregion.base, total); - isc_buffer_forward(source, total); - isc_buffer_add(target, total); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_opt(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_opt); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_opt(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_opt); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_opt(ARGS_FROMSTRUCT) { - dns_rdata_opt_t *opt; - isc_region_t region; - uint16_t length; - - REQUIRE(type == dns_rdatatype_opt); - REQUIRE(((dns_rdata_opt_t *)source) != NULL); - REQUIRE(((dns_rdata_opt_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_opt_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_opt_t *)source)->options != NULL || - ((dns_rdata_opt_t *)source)->length == 0); - - opt = source; - - UNUSED(type); - UNUSED(rdclass); - - region.base = opt->options; - region.length = opt->length; - while (region.length >= 4) { - isc_region_consume(®ion, 2); /* opt */ - length = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - if (region.length < length) - return (ISC_R_UNEXPECTEDEND); - isc_region_consume(®ion, length); - } - if (region.length != 0) - return (ISC_R_UNEXPECTEDEND); - - return (mem_tobuffer(target, opt->options, opt->length)); -} - -static inline isc_result_t -tostruct_opt(ARGS_TOSTRUCT) { - dns_rdata_opt_t *opt; - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_opt); - REQUIRE(((dns_rdata_opt_t *)target) != NULL); - - opt = target; - - opt->common.rdclass = rdata->rdclass; - opt->common.rdtype = rdata->type; - ISC_LINK_INIT(&opt->common, link); - - dns_rdata_toregion(rdata, &r); - opt->length = r.length; - opt->options = mem_maybedup(mctx, r.base, r.length); - if (opt->options == NULL) - return (ISC_R_NOMEMORY); - - opt->offset = 0; - opt->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_opt(ARGS_FREESTRUCT) { - dns_rdata_opt_t *opt; - - REQUIRE(((dns_rdata_opt_t *)source) != NULL); - REQUIRE(((dns_rdata_opt_t *)source)->common.rdtype == - dns_rdatatype_opt); - - opt = source; - - if (opt->mctx == NULL) - return; - - if (opt->options != NULL) - isc_mem_free(opt->mctx, opt->options); - opt->mctx = NULL; -} - -static inline isc_result_t -additionaldata_opt(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_opt); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_opt(ARGS_DIGEST) { - - /* - * OPT records are not digested. - */ - - REQUIRE(rdata->type == dns_rdatatype_opt); - - UNUSED(rdata); - UNUSED(digest); - UNUSED(arg); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline bool -checkowner_opt(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_opt); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (dns_name_equal(name, dns_rootname)); -} - -static inline bool -checknames_opt(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_opt); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_opt(ARGS_COMPARE) { - return (compare_opt(rdata1, rdata2)); -} - -isc_result_t -dns_rdata_opt_first(dns_rdata_opt_t *opt) { - - REQUIRE(opt != NULL); - REQUIRE(opt->common.rdtype == dns_rdatatype_opt); - REQUIRE(opt->options != NULL || opt->length == 0); - - if (opt->length == 0) - return (ISC_R_NOMORE); - - opt->offset = 0; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdata_opt_next(dns_rdata_opt_t *opt) { - isc_region_t r; - uint16_t length; - - REQUIRE(opt != NULL); - REQUIRE(opt->common.rdtype == dns_rdatatype_opt); - REQUIRE(opt->options != NULL && opt->length != 0); - REQUIRE(opt->offset < opt->length); - - INSIST(opt->offset + 4 <= opt->length); - r.base = opt->options + opt->offset + 2; - r.length = opt->length - opt->offset - 2; - length = uint16_fromregion(&r); - INSIST(opt->offset + 4 + length <= opt->length); - opt->offset = opt->offset + 4 + length; - if (opt->offset == opt->length) - return (ISC_R_NOMORE); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdata_opt_current(dns_rdata_opt_t *opt, dns_rdata_opt_opcode_t *opcode) { - isc_region_t r; - - REQUIRE(opt != NULL); - REQUIRE(opcode != NULL); - REQUIRE(opt->common.rdtype == dns_rdatatype_opt); - REQUIRE(opt->options != NULL); - REQUIRE(opt->offset < opt->length); - - INSIST(opt->offset + 4 <= opt->length); - r.base = opt->options + opt->offset; - r.length = opt->length - opt->offset; - - opcode->opcode = uint16_fromregion(&r); - isc_region_consume(&r, 2); - opcode->length = uint16_fromregion(&r); - isc_region_consume(&r, 2); - opcode->data = r.base; - INSIST(opt->offset + 4 + opcode->length <= opt->length); - - return (ISC_R_SUCCESS); -} - -#endif /* RDATA_GENERIC_OPT_41_C */ diff --git a/lib/dns-pkcs11/rdata/generic/opt_41.h b/lib/dns-pkcs11/rdata/generic/opt_41.h deleted file mode 100644 index 7416728..0000000 --- a/lib/dns-pkcs11/rdata/generic/opt_41.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_OPT_41_H -#define GENERIC_OPT_41_H 1 - - -/*! - * \brief Per RFC2671 */ - -typedef struct dns_rdata_opt_opcode { - uint16_t opcode; - uint16_t length; - unsigned char *data; -} dns_rdata_opt_opcode_t; - -typedef struct dns_rdata_opt { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *options; - uint16_t length; - /* private */ - uint16_t offset; -} dns_rdata_opt_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ - -isc_result_t -dns_rdata_opt_first(dns_rdata_opt_t *); - -isc_result_t -dns_rdata_opt_next(dns_rdata_opt_t *); - -isc_result_t -dns_rdata_opt_current(dns_rdata_opt_t *, dns_rdata_opt_opcode_t *); - -#endif /* GENERIC_OPT_41_H */ diff --git a/lib/dns-pkcs11/rdata/generic/proforma.c b/lib/dns-pkcs11/rdata/generic/proforma.c deleted file mode 100644 index 890c958..0000000 --- a/lib/dns-pkcs11/rdata/generic/proforma.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef RDATA_GENERIC_#_#_C -#define RDATA_GENERIC_#_#_C - -#define RRTYPE_#_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_#(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_proforma.c#); - REQUIRE(rdclass == #); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline isc_result_t -totext_#(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - REQUIRE(rdata->length != 0); /* XXX */ - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline isc_result_t -fromwire_#(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_proforma.c#); - REQUIRE(rdclass == #); - - /* NONE or GLOBAL14 */ - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline isc_result_t -towire_#(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - REQUIRE(rdata->length != 0); /* XXX */ - - /* NONE or GLOBAL14 */ - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline int -compare_#(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == dns_rdatatype_proforma.crdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata1->rdclass == #); - REQUIRE(rdata1->length != 0); /* XXX */ - REQUIRE(rdata2->length != 0); /* XXX */ - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_#(ARGS_FROMSTRUCT) { - dns_rdata_#_t *# = source; - - REQUIRE(type == dns_rdatatype_proforma.c#); - REQUIRE(rdclass == #); - REQUIRE(# != NULL); - REQUIRE(#->common.rdtype == dns_rdatatype_proforma.ctype); - REQUIRE(#->common.rdclass == rdclass); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline isc_result_t -tostruct_#(ARGS_TOSTRUCT) { - - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - REQUIRE(rdata->length != 0); /* XXX */ - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline void -freestruct_#(ARGS_FREESTRUCT) { - dns_rdata_#_t *# = source; - - REQUIRE(# != NULL); - REQUIRE(#->common.rdtype == dns_rdatatype_proforma.c#); - REQUIRE(#->common.rdclass == #); - -} - -static inline isc_result_t -additionaldata_#(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - - (void)add; - (void)arg; - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_#(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_#(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_proforma.c#); - REQUIRE(rdclass == #); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_#(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata->rdclass == #); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_#(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == dns_rdatatype_proforma.crdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_proforma.c#); - REQUIRE(rdata1->rdclass == #); - REQUIRE(rdata1->length != 0); /* XXX */ - REQUIRE(rdata2->length != 0); /* XXX */ - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -#endif /* RDATA_GENERIC_#_#_C */ diff --git a/lib/dns-pkcs11/rdata/generic/proforma.h b/lib/dns-pkcs11/rdata/generic/proforma.h deleted file mode 100644 index d3cf5af..0000000 --- a/lib/dns-pkcs11/rdata/generic/proforma.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_PROFORMA_H -#define GENERIC_PROFORMA_H 1 - - -typedef struct dns_rdata_# { - dns_rdatacommon_t common; - isc_mem_t *mctx; /* if required */ - /* type & class specific elements */ -} dns_rdata_#_t; - -#endif /* GENERIC_PROFORMA_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ptr_12.c b/lib/dns-pkcs11/rdata/generic/ptr_12.c deleted file mode 100644 index 4fad2e7..0000000 --- a/lib/dns-pkcs11/rdata/generic/ptr_12.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_PTR_12_C -#define RDATA_GENERIC_PTR_12_C - -#define RRTYPE_PTR_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_ptr(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_ptr); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - if (rdclass == dns_rdataclass_in && - (options & DNS_RDATA_CHECKNAMES) != 0 && - (options & DNS_RDATA_CHECKREVERSE) != 0) { - bool ok; - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_ptr(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_ptr); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_ptr(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_ptr); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_ptr(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_ptr); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_ptr(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ptr); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_ptr(ARGS_FROMSTRUCT) { - dns_rdata_ptr_t *ptr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_ptr); - REQUIRE(((dns_rdata_ptr_t *)source) != NULL); - REQUIRE(((dns_rdata_ptr_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_ptr_t *)source)->common.rdclass == rdclass); - - ptr = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&ptr->ptr, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_ptr(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_ptr_t *ptr; - dns_name_t name; - - REQUIRE(((dns_rdata_ptr_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_ptr); - REQUIRE(rdata->length != 0); - - ptr = target; - - ptr->common.rdclass = rdata->rdclass; - ptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&ptr->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&ptr->ptr, NULL); - RETERR(name_duporclone(&name, mctx, &ptr->ptr)); - ptr->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_ptr(ARGS_FREESTRUCT) { - dns_rdata_ptr_t *ptr; - - REQUIRE(((dns_rdata_ptr_t *)source) != NULL); - REQUIRE(((dns_rdata_ptr_t *)source)->common.rdtype == - dns_rdatatype_ptr); - - ptr = source; - - if (ptr->mctx == NULL) - return; - - dns_name_free(&ptr->ptr, ptr->mctx); - ptr->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ptr(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_ptr); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ptr(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_ptr); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_ptr(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ptr); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; -static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; -static const dns_name_t ip6_arpa = - DNS_NAME_INITABSOLUTE(ip6_arpa_data, ip6_arpa_offsets); - -static unsigned char ip6_int_data[] = "\003IP6\003INT"; -static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; -static const dns_name_t ip6_int = - DNS_NAME_INITABSOLUTE(ip6_int_data, ip6_int_offsets); - -static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; -static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; -static const dns_name_t in_addr_arpa = - DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets); - -static inline bool -checknames_ptr(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_ptr); - - if (rdata->rdclass != dns_rdataclass_in) - return (true); - - if (dns_name_isdnssd(owner)) - return (true); - - if (dns_name_issubdomain(owner, &in_addr_arpa) || - dns_name_issubdomain(owner, &ip6_arpa) || - dns_name_issubdomain(owner, &ip6_int)) { - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - } - return (true); -} - -static inline int -casecompare_ptr(ARGS_COMPARE) { - return (compare_ptr(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_PTR_12_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ptr_12.h b/lib/dns-pkcs11/rdata/generic/ptr_12.h deleted file mode 100644 index d049ec1..0000000 --- a/lib/dns-pkcs11/rdata/generic/ptr_12.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_PTR_12_H -#define GENERIC_PTR_12_H 1 - - -typedef struct dns_rdata_ptr { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t ptr; -} dns_rdata_ptr_t; - -#endif /* GENERIC_PTR_12_H */ diff --git a/lib/dns-pkcs11/rdata/generic/rkey_57.c b/lib/dns-pkcs11/rdata/generic/rkey_57.c deleted file mode 100644 index 07834c3..0000000 --- a/lib/dns-pkcs11/rdata/generic/rkey_57.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_RKEY_57_C -#define RDATA_GENERIC_RKEY_57_C - -#define RRTYPE_RKEY_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_rkey(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_rkey); - - return (generic_fromtext_key(rdclass, type, lexer, origin, - options, target, callbacks)); -} - -static inline isc_result_t -totext_rkey(ARGS_TOTEXT) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_rkey); - - return (generic_totext_key(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_rkey(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_rkey); - - return (generic_fromwire_key(rdclass, type, source, dctx, - options, target)); -} - -static inline isc_result_t -towire_rkey(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_rkey); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_rkey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1 != NULL); - REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_rkey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_rkey(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_rkey); - - return (generic_fromstruct_key(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_rkey(ARGS_TOSTRUCT) { - dns_rdata_rkey_t *rkey; - - REQUIRE(((dns_rdata_rkey_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_rkey); - - rkey = target; - - rkey->common.rdclass = rdata->rdclass; - rkey->common.rdtype = rdata->type; - ISC_LINK_INIT(&rkey->common, link); - - return (generic_tostruct_key(rdata, target, mctx)); -} - -static inline void -freestruct_rkey(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_rkey_t *)source) != NULL); - REQUIRE(((dns_rdata_rkey_t *)source)->common.rdtype == - dns_rdatatype_rkey); - - generic_freestruct_key(source); -} - -static inline isc_result_t -additionaldata_rkey(ARGS_ADDLDATA) { - - REQUIRE(rdata->type == dns_rdatatype_rkey); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_rkey(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_rkey); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_rkey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_rkey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_rkey(ARGS_CHECKNAMES) { - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_rkey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_rkey(ARGS_COMPARE) { - - /* - * Treat ALG 253 (private DNS) subtype name case sensitively. - */ - return (compare_rkey(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_RKEY_57_C */ diff --git a/lib/dns-pkcs11/rdata/generic/rkey_57.h b/lib/dns-pkcs11/rdata/generic/rkey_57.h deleted file mode 100644 index 8408b3d..0000000 --- a/lib/dns-pkcs11/rdata/generic/rkey_57.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_RKEY_57_H -#define GENERIC_RKEY_57_H 1 - -typedef struct dns_rdata_key dns_rdata_rkey_t; - -#endif /* GENERIC_RKEY_57_H */ diff --git a/lib/dns-pkcs11/rdata/generic/rp_17.c b/lib/dns-pkcs11/rdata/generic/rp_17.c deleted file mode 100644 index 535680b..0000000 --- a/lib/dns-pkcs11/rdata/generic/rp_17.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC1183 */ - -#ifndef RDATA_GENERIC_RP_17_C -#define RDATA_GENERIC_RP_17_C - -#define RRTYPE_RP_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_rp(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - int i; - bool ok; - - REQUIRE(type == dns_rdatatype_rp); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - if (origin == NULL) - origin = dns_rootname; - - for (i = 0; i < 2; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, - options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0 && i == 0) - ok = dns_name_ismailbox(&name); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_rp(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t rmail; - dns_name_t email; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_rp); - REQUIRE(rdata->length != 0); - - dns_name_init(&rmail, NULL); - dns_name_init(&email, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); - - dns_name_fromregion(&email, ®ion); - isc_region_consume(®ion, email.length); - - sub = name_prefix(&rmail, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - RETERR(str_totext(" ", target)); - - sub = name_prefix(&email, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_rp(ARGS_FROMWIRE) { - dns_name_t rmail; - dns_name_t email; - - REQUIRE(type == dns_rdatatype_rp); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&rmail, NULL); - dns_name_init(&email, NULL); - - RETERR(dns_name_fromwire(&rmail, source, dctx, options, target)); - return (dns_name_fromwire(&email, source, dctx, options, target)); -} - -static inline isc_result_t -towire_rp(ARGS_TOWIRE) { - isc_region_t region; - dns_name_t rmail; - dns_name_t email; - dns_offsets_t roffsets; - dns_offsets_t eoffsets; - - REQUIRE(rdata->type == dns_rdatatype_rp); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_name_init(&rmail, roffsets); - dns_name_init(&email, eoffsets); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); - - RETERR(dns_name_towire(&rmail, cctx, target)); - - dns_name_fromregion(&rmail, ®ion); - isc_region_consume(®ion, rmail.length); - - return (dns_name_towire(&rmail, cctx, target)); -} - -static inline int -compare_rp(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_rp); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_rp(ARGS_FROMSTRUCT) { - dns_rdata_rp_t *rp; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_rp); - REQUIRE(((dns_rdata_rp_t *)source) != NULL); - REQUIRE(((dns_rdata_rp_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_rp_t *)source)->common.rdclass == rdclass); - - rp = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&rp->mail, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - dns_name_toregion(&rp->text, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_rp(ARGS_TOSTRUCT) { - isc_result_t result; - isc_region_t region; - dns_rdata_rp_t *rp; - dns_name_t name; - - REQUIRE(((dns_rdata_rp_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_rp); - REQUIRE(rdata->length != 0); - - rp = target; - - rp->common.rdclass = rdata->rdclass; - rp->common.rdtype = rdata->type; - ISC_LINK_INIT(&rp->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&rp->mail, NULL); - RETERR(name_duporclone(&name, mctx, &rp->mail)); - isc_region_consume(®ion, name_length(&name)); - dns_name_fromregion(&name, ®ion); - dns_name_init(&rp->text, NULL); - result = name_duporclone(&name, mctx, &rp->text); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rp->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&rp->mail, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_rp(ARGS_FREESTRUCT) { - dns_rdata_rp_t *rp; - - REQUIRE(((dns_rdata_rp_t *)source) != NULL); - REQUIRE(((dns_rdata_rp_t *)source)->common.rdtype == dns_rdatatype_rp); - - rp = source; - - if (rp->mctx == NULL) - return; - - dns_name_free(&rp->mail, rp->mctx); - dns_name_free(&rp->text, rp->mctx); - rp->mctx = NULL; -} - -static inline isc_result_t -additionaldata_rp(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_rp); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_rp(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_rp); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - - dns_name_fromregion(&name, &r); - RETERR(dns_name_digest(&name, digest, arg)); - isc_region_consume(&r, name_length(&name)); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_rp(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_rp); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_rp(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_rp); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ismailbox(&name)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_rp(ARGS_COMPARE) { - return (compare_rp(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_RP_17_C */ diff --git a/lib/dns-pkcs11/rdata/generic/rp_17.h b/lib/dns-pkcs11/rdata/generic/rp_17.h deleted file mode 100644 index 67ff39a..0000000 --- a/lib/dns-pkcs11/rdata/generic/rp_17.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_RP_17_H -#define GENERIC_RP_17_H 1 - - -/*! - * \brief Per RFC1183 */ - -typedef struct dns_rdata_rp { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t mail; - dns_name_t text; -} dns_rdata_rp_t; - - -#endif /* GENERIC_RP_17_H */ diff --git a/lib/dns-pkcs11/rdata/generic/rrsig_46.c b/lib/dns-pkcs11/rdata/generic/rrsig_46.c deleted file mode 100644 index 0d4df67..0000000 --- a/lib/dns-pkcs11/rdata/generic/rrsig_46.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2535 */ - -#ifndef RDATA_GENERIC_RRSIG_46_C -#define RDATA_GENERIC_RRSIG_46_C - -#define RRTYPE_RRSIG_ATTRIBUTES \ - ( DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH | \ - DNS_RDATATYPEATTR_ATCNAME ) - -static inline isc_result_t -fromtext_rrsig(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char c; - long i; - dns_rdatatype_t covered; - char *e; - isc_result_t result; - dns_name_t name; - isc_buffer_t buffer; - uint32_t time_signed, time_expire; - - REQUIRE(type == dns_rdatatype_rrsig); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Type covered. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { - i = strtol(DNS_AS_STR(token), &e, 10); - if (i < 0 || i > 65535) - RETTOK(ISC_R_RANGE); - if (*e != 0) - RETTOK(result); - covered = (dns_rdatatype_t)i; - } - RETERR(uint16_tobuffer(covered, target)); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Labels. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - c = (unsigned char)token.value.as_ulong; - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Original ttl. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * Signature expiration. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (strlen(DNS_AS_STR(token)) <= 10U && - *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') { - char *end; - unsigned long u; - uint64_t u64; - - u64 = u = strtoul(DNS_AS_STR(token), &end, 10); - if (u == ULONG_MAX || *end != 0) - RETTOK(DNS_R_SYNTAX); - if (u64 > 0xffffffffUL) - RETTOK(ISC_R_RANGE); - time_expire = u; - } else - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); - RETERR(uint32_tobuffer(time_expire, target)); - - /* - * Time signed. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (strlen(DNS_AS_STR(token)) <= 10U && - *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') { - char *end; - unsigned long u; - uint64_t u64; - - u64 = u = strtoul(DNS_AS_STR(token), &end, 10); - if (u == ULONG_MAX || *end != 0) - RETTOK(DNS_R_SYNTAX); - if (u64 > 0xffffffffUL) - RETTOK(ISC_R_RANGE); - time_signed = u; - } else - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); - RETERR(uint32_tobuffer(time_signed, target)); - - /* - * Key footprint. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Signer. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - /* - * Sig. - */ - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_rrsig(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("4294967295")]; /* Also TYPE65000. */ - dns_rdatatype_t covered; - unsigned long ttl; - unsigned long when; - unsigned long exp; - unsigned long foot; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_rrsig); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* - * Type covered. - */ - covered = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - /* - * XXXAG We should have something like dns_rdatatype_isknown() - * that does the right thing with type 0. - */ - if (dns_rdatatype_isknown(covered) && covered != 0) { - RETERR(dns_rdatatype_totext(covered, target)); - } else { - snprintf(buf, sizeof(buf), "TYPE%u", covered); - RETERR(str_totext(buf, target)); - } - RETERR(str_totext(" ", target)); - - /* - * Algorithm. - */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Labels. - */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Ttl. - */ - ttl = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu", ttl); - RETERR(str_totext(buf, target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - /* - * Sig exp. - */ - exp = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(exp, target)); - RETERR(str_totext(" ", target)); - - /* - * Time signed. - */ - when = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(when, target)); - RETERR(str_totext(" ", target)); - - /* - * Footprint. - */ - foot = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu", foot); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Signer. - */ - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_totext(&name, false, target)); - - /* - * Sig. - */ - RETERR(str_totext(tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else - RETERR(str_totext("[omitted]", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_rrsig(ARGS_FROMWIRE) { - isc_region_t sr; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_rrsig); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - isc_buffer_activeregion(source, &sr); - /* - * type covered: 2 - * algorithm: 1 - * labels: 1 - * original ttl: 4 - * signature expiration: 4 - * time signed: 4 - * key footprint: 2 - */ - if (sr.length < 18) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_forward(source, 18); - RETERR(mem_tobuffer(target, sr.base, 18)); - - /* - * Signer. - */ - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - /* - * Sig. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 1) { - return (DNS_R_FORMERR); - } - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_rrsig(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_rrsig); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_rdata_toregion(rdata, &sr); - /* - * type covered: 2 - * algorithm: 1 - * labels: 1 - * original ttl: 4 - * signature expiration: 4 - * time signed: 4 - * key footprint: 2 - */ - RETERR(mem_tobuffer(target, sr.base, 18)); - isc_region_consume(&sr, 18); - - /* - * Signer. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_towire(&name, cctx, target)); - - /* - * Signature. - */ - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_rrsig(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_rrsig); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_rrsig(ARGS_FROMSTRUCT) { - dns_rdata_rrsig_t *sig; - - REQUIRE(type == dns_rdatatype_rrsig); - REQUIRE(((dns_rdata_rrsig_t *)source) != NULL); - REQUIRE(((dns_rdata_rrsig_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_rrsig_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_rrsig_t *)source)->signature != NULL || - ((dns_rdata_rrsig_t *)source)->siglen == 0); - - sig = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Type covered. - */ - RETERR(uint16_tobuffer(sig->covered, target)); - - /* - * Algorithm. - */ - RETERR(uint8_tobuffer(sig->algorithm, target)); - - /* - * Labels. - */ - RETERR(uint8_tobuffer(sig->labels, target)); - - /* - * Original TTL. - */ - RETERR(uint32_tobuffer(sig->originalttl, target)); - - /* - * Expire time. - */ - RETERR(uint32_tobuffer(sig->timeexpire, target)); - - /* - * Time signed. - */ - RETERR(uint32_tobuffer(sig->timesigned, target)); - - /* - * Key ID. - */ - RETERR(uint16_tobuffer(sig->keyid, target)); - - /* - * Signer name. - */ - RETERR(name_tobuffer(&sig->signer, target)); - - /* - * Signature. - */ - return (mem_tobuffer(target, sig->signature, sig->siglen)); -} - -static inline isc_result_t -tostruct_rrsig(ARGS_TOSTRUCT) { - isc_region_t sr; - dns_rdata_rrsig_t *sig; - dns_name_t signer; - - REQUIRE(((dns_rdata_rrsig_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_rrsig); - REQUIRE(rdata->length != 0); - - sig = target; - - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Type covered. - */ - sig->covered = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Algorithm. - */ - sig->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Labels. - */ - sig->labels = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Original TTL. - */ - sig->originalttl = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Expire time. - */ - sig->timeexpire = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Time signed. - */ - sig->timesigned = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Key ID. - */ - sig->keyid = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - dns_name_init(&signer, NULL); - dns_name_fromregion(&signer, &sr); - dns_name_init(&sig->signer, NULL); - RETERR(name_duporclone(&signer, mctx, &sig->signer)); - isc_region_consume(&sr, name_length(&sig->signer)); - - /* - * Signature. - */ - sig->siglen = sr.length; - sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); - if (sig->signature == NULL) - goto cleanup; - - - sig->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&sig->signer, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_rrsig(ARGS_FREESTRUCT) { - dns_rdata_rrsig_t *sig; - - REQUIRE(((dns_rdata_rrsig_t *)source) != NULL); - REQUIRE(((dns_rdata_rrsig_t *)source)->common.rdtype == - dns_rdatatype_rrsig); - - sig = (dns_rdata_rrsig_t *) source; - - if (sig->mctx == NULL) - return; - - dns_name_free(&sig->signer, sig->mctx); - if (sig->signature != NULL) - isc_mem_free(sig->mctx, sig->signature); - sig->mctx = NULL; -} - -static inline isc_result_t -additionaldata_rrsig(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_rrsig); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_rrsig(ARGS_DIGEST) { - - REQUIRE(rdata->type == dns_rdatatype_rrsig); - - UNUSED(rdata); - UNUSED(digest); - UNUSED(arg); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline dns_rdatatype_t -covers_rrsig(dns_rdata_t *rdata) { - dns_rdatatype_t type; - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_rrsig); - - dns_rdata_toregion(rdata, &r); - type = uint16_fromregion(&r); - - return (type); -} - -static inline bool -checkowner_rrsig(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_rrsig); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_rrsig(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_rrsig); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_rrsig(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_rrsig); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - - INSIST(r1.length > 18); - INSIST(r2.length > 18); - r1.length = 18; - r2.length = 18; - order = isc_region_compare(&r1, &r2); - if (order != 0) - return (order); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - isc_region_consume(&r1, 18); - isc_region_consume(&r2, 18); - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - - return (isc_region_compare(&r1, &r2)); -} - -#endif /* RDATA_GENERIC_RRSIG_46_C */ diff --git a/lib/dns-pkcs11/rdata/generic/rrsig_46.h b/lib/dns-pkcs11/rdata/generic/rrsig_46.h deleted file mode 100644 index be362c6..0000000 --- a/lib/dns-pkcs11/rdata/generic/rrsig_46.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_DNSSIG_46_H -#define GENERIC_DNSSIG_46_H 1 - - -/*! - * \brief Per RFC2535 */ -typedef struct dns_rdata_rrsig { - dns_rdatacommon_t common; - isc_mem_t * mctx; - dns_rdatatype_t covered; - dns_secalg_t algorithm; - uint8_t labels; - uint32_t originalttl; - uint32_t timeexpire; - uint32_t timesigned; - uint16_t keyid; - dns_name_t signer; - uint16_t siglen; - unsigned char * signature; -} dns_rdata_rrsig_t; - - -#endif /* GENERIC_DNSSIG_46_H */ diff --git a/lib/dns-pkcs11/rdata/generic/rt_21.c b/lib/dns-pkcs11/rdata/generic/rt_21.c deleted file mode 100644 index ddde80e..0000000 --- a/lib/dns-pkcs11/rdata/generic/rt_21.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1183 */ - -#ifndef RDATA_GENERIC_RT_21_C -#define RDATA_GENERIC_RT_21_C - -#define RRTYPE_RT_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_rt(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - bool ok; - - REQUIRE(type == dns_rdatatype_rt); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_rt(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_rt); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_rt(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(type == dns_rdatatype_rt); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (tregion.length < 2) - return (ISC_R_NOSPACE); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - memmove(tregion.base, sregion.base, 2); - isc_buffer_forward(source, 2); - isc_buffer_add(target, 2); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_rt(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - isc_region_t tr; - - REQUIRE(rdata->type == dns_rdatatype_rt); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - isc_buffer_availableregion(target, &tr); - dns_rdata_toregion(rdata, ®ion); - if (tr.length < 2) - return (ISC_R_NOSPACE); - memmove(tr.base, region.base, 2); - isc_region_consume(®ion, 2); - isc_buffer_add(target, 2); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_rt(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_rt); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - order = memcmp(rdata1->data, rdata2->data, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_rt(ARGS_FROMSTRUCT) { - dns_rdata_rt_t *rt; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_rt); - REQUIRE(((dns_rdata_rt_t *)source) != NULL); - REQUIRE(((dns_rdata_rt_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_rt_t *)source)->common.rdclass == rdclass); - - rt = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(rt->preference, target)); - dns_name_toregion(&rt->host, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_rt(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_rt_t *rt; - dns_name_t name; - - REQUIRE(((dns_rdata_rt_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_rt); - REQUIRE(rdata->length != 0); - - rt = target; - - rt->common.rdclass = rdata->rdclass; - rt->common.rdtype = rdata->type; - ISC_LINK_INIT(&rt->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - rt->preference = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - dns_name_init(&rt->host, NULL); - RETERR(name_duporclone(&name, mctx, &rt->host)); - - rt->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_rt(ARGS_FREESTRUCT) { - dns_rdata_rt_t *rt; - - REQUIRE(((dns_rdata_rt_t *)source) != NULL); - REQUIRE(((dns_rdata_rt_t *)source)->common.rdtype == dns_rdatatype_rt); - - rt = source; - - if (rt->mctx == NULL) - return; - - dns_name_free(&rt->host, rt->mctx); - rt->mctx = NULL; -} - -static inline isc_result_t -additionaldata_rt(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_rt); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - result = (add)(arg, &name, dns_rdatatype_x25); - if (result != ISC_R_SUCCESS) - return (result); - result = (add)(arg, &name, dns_rdatatype_isdn); - if (result != ISC_R_SUCCESS) - return (result); - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_rt(ARGS_DIGEST) { - isc_region_t r1, r2; - isc_result_t result; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_rt); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 2); - r1.length = 2; - result = (digest)(arg, &r1); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_rt(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_rt); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_rt(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_rt); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_rt(ARGS_COMPARE) { - return (compare_rt(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_RT_21_C */ diff --git a/lib/dns-pkcs11/rdata/generic/rt_21.h b/lib/dns-pkcs11/rdata/generic/rt_21.h deleted file mode 100644 index 549a25b..0000000 --- a/lib/dns-pkcs11/rdata/generic/rt_21.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_RT_21_H -#define GENERIC_RT_21_H 1 - - -/*! - * \brief Per RFC1183 */ - -typedef struct dns_rdata_rt { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t preference; - dns_name_t host; -} dns_rdata_rt_t; - -#endif /* GENERIC_RT_21_H */ diff --git a/lib/dns-pkcs11/rdata/generic/sig_24.c b/lib/dns-pkcs11/rdata/generic/sig_24.c deleted file mode 100644 index 89a39ff..0000000 --- a/lib/dns-pkcs11/rdata/generic/sig_24.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2535 */ - -#ifndef RDATA_GENERIC_SIG_24_C -#define RDATA_GENERIC_SIG_24_C - -#define RRTYPE_SIG_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_sig(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char c; - long i; - dns_rdatatype_t covered; - char *e; - isc_result_t result; - dns_name_t name; - isc_buffer_t buffer; - uint32_t time_signed, time_expire; - - REQUIRE(type == dns_rdatatype_sig); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Type covered. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { - i = strtol(DNS_AS_STR(token), &e, 10); - if (i < 0 || i > 65535) - RETTOK(ISC_R_RANGE); - if (*e != 0) - RETTOK(result); - covered = (dns_rdatatype_t)i; - } - RETERR(uint16_tobuffer(covered, target)); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Labels. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - c = (unsigned char)token.value.as_ulong; - RETERR(mem_tobuffer(target, &c, 1)); - - /* - * Original ttl. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * Signature expiration. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); - RETERR(uint32_tobuffer(time_expire, target)); - - /* - * Time signed. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); - RETERR(uint32_tobuffer(time_signed, target)); - - /* - * Key footprint. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Signer. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - /* - * Sig. - */ - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_sig(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("4294967295")]; - dns_rdatatype_t covered; - unsigned long ttl; - unsigned long when; - unsigned long exp; - unsigned long foot; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_sig); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* - * Type covered. - */ - covered = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - /* - * XXXAG We should have something like dns_rdatatype_isknown() - * that does the right thing with type 0. - */ - if (dns_rdatatype_isknown(covered) && covered != 0) { - RETERR(dns_rdatatype_totext(covered, target)); - } else { - snprintf(buf, sizeof(buf), "%u", covered); - RETERR(str_totext(buf, target)); - } - RETERR(str_totext(" ", target)); - - /* - * Algorithm. - */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Labels. - */ - snprintf(buf, sizeof(buf), "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Ttl. - */ - ttl = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu", ttl); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Sig exp. - */ - exp = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(exp, target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - /* - * Time signed. - */ - when = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - RETERR(dns_time32_totext(when, target)); - RETERR(str_totext(" ", target)); - - /* - * Footprint. - */ - foot = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu", foot); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Signer. - */ - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - sub = name_prefix(&name, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - /* - * Sig. - */ - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_sig(ARGS_FROMWIRE) { - isc_region_t sr; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_sig); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - isc_buffer_activeregion(source, &sr); - /* - * type covered: 2 - * algorithm: 1 - * labels: 1 - * original ttl: 4 - * signature expiration: 4 - * time signed: 4 - * key footprint: 2 - */ - if (sr.length < 18) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_forward(source, 18); - RETERR(mem_tobuffer(target, sr.base, 18)); - - /* - * Signer. - */ - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - /* - * Sig. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length == 0) { - return (ISC_R_UNEXPECTEDEND); - } - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_sig(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_sig); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_rdata_toregion(rdata, &sr); - /* - * type covered: 2 - * algorithm: 1 - * labels: 1 - * original ttl: 4 - * signature expiration: 4 - * time signed: 4 - * key footprint: 2 - */ - RETERR(mem_tobuffer(target, sr.base, 18)); - isc_region_consume(&sr, 18); - - /* - * Signer. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - isc_region_consume(&sr, name_length(&name)); - RETERR(dns_name_towire(&name, cctx, target)); - - /* - * Signature. - */ - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_sig(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_sig); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - - INSIST(r1.length > 18); - INSIST(r2.length > 18); - r1.length = 18; - r2.length = 18; - order = isc_region_compare(&r1, &r2); - if (order != 0) - return (order); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - isc_region_consume(&r1, 18); - isc_region_consume(&r2, 18); - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_sig(ARGS_FROMSTRUCT) { - dns_rdata_sig_t *sig; - - REQUIRE(type == dns_rdatatype_sig); - REQUIRE(((dns_rdata_sig_t *)source) != NULL); - REQUIRE(((dns_rdata_sig_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_sig_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_sig_t *)source)->signature != NULL || - ((dns_rdata_sig_t *)source)->siglen == 0); - - sig = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Type covered. - */ - RETERR(uint16_tobuffer(sig->covered, target)); - - /* - * Algorithm. - */ - RETERR(uint8_tobuffer(sig->algorithm, target)); - - /* - * Labels. - */ - RETERR(uint8_tobuffer(sig->labels, target)); - - /* - * Original TTL. - */ - RETERR(uint32_tobuffer(sig->originalttl, target)); - - /* - * Expire time. - */ - RETERR(uint32_tobuffer(sig->timeexpire, target)); - - /* - * Time signed. - */ - RETERR(uint32_tobuffer(sig->timesigned, target)); - - /* - * Key ID. - */ - RETERR(uint16_tobuffer(sig->keyid, target)); - - /* - * Signer name. - */ - RETERR(name_tobuffer(&sig->signer, target)); - - /* - * Signature. - */ - return (mem_tobuffer(target, sig->signature, sig->siglen)); -} - -static inline isc_result_t -tostruct_sig(ARGS_TOSTRUCT) { - isc_region_t sr; - dns_rdata_sig_t *sig; - dns_name_t signer; - - REQUIRE(((dns_rdata_sig_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_sig); - REQUIRE(rdata->length != 0); - - sig = target; - - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Type covered. - */ - sig->covered = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Algorithm. - */ - sig->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Labels. - */ - sig->labels = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* - * Original TTL. - */ - sig->originalttl = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Expire time. - */ - sig->timeexpire = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Time signed. - */ - sig->timesigned = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Key ID. - */ - sig->keyid = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - dns_name_init(&signer, NULL); - dns_name_fromregion(&signer, &sr); - dns_name_init(&sig->signer, NULL); - RETERR(name_duporclone(&signer, mctx, &sig->signer)); - isc_region_consume(&sr, name_length(&sig->signer)); - - /* - * Signature. - */ - sig->siglen = sr.length; - sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); - if (sig->signature == NULL) - goto cleanup; - - - sig->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&sig->signer, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_sig(ARGS_FREESTRUCT) { - dns_rdata_sig_t *sig; - - REQUIRE(((dns_rdata_sig_t *)source) != NULL); - REQUIRE(((dns_rdata_sig_t *)source)->common.rdtype == - dns_rdatatype_sig); - - sig = (dns_rdata_sig_t *) source; - - if (sig->mctx == NULL) - return; - - dns_name_free(&sig->signer, sig->mctx); - if (sig->signature != NULL) - isc_mem_free(sig->mctx, sig->signature); - sig->mctx = NULL; -} - -static inline isc_result_t -additionaldata_sig(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_sig); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_sig(ARGS_DIGEST) { - - REQUIRE(rdata->type == dns_rdatatype_sig); - - UNUSED(rdata); - UNUSED(digest); - UNUSED(arg); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline dns_rdatatype_t -covers_sig(dns_rdata_t *rdata) { - dns_rdatatype_t type; - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_sig); - - dns_rdata_toregion(rdata, &r); - type = uint16_fromregion(&r); - - return (type); -} - -static inline bool -checkowner_sig(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_sig); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_sig(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_sig); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_sig(ARGS_COMPARE) { - return (compare_sig(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_SIG_24_C */ diff --git a/lib/dns-pkcs11/rdata/generic/sig_24.h b/lib/dns-pkcs11/rdata/generic/sig_24.h deleted file mode 100644 index d9627fb..0000000 --- a/lib/dns-pkcs11/rdata/generic/sig_24.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_SIG_24_H -#define GENERIC_SIG_24_H 1 - - -/*! - * \brief Per RFC2535 */ - -typedef struct dns_rdata_sig_t { - dns_rdatacommon_t common; - isc_mem_t * mctx; - dns_rdatatype_t covered; - dns_secalg_t algorithm; - uint8_t labels; - uint32_t originalttl; - uint32_t timeexpire; - uint32_t timesigned; - uint16_t keyid; - dns_name_t signer; - uint16_t siglen; - unsigned char * signature; -} dns_rdata_sig_t; - - -#endif /* GENERIC_SIG_24_H */ diff --git a/lib/dns-pkcs11/rdata/generic/sink_40.c b/lib/dns-pkcs11/rdata/generic/sink_40.c deleted file mode 100644 index 8fd9385..0000000 --- a/lib/dns-pkcs11/rdata/generic/sink_40.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_SINK_40_C -#define RDATA_GENERIC_SINK_40_C - -#include - -#define RRTYPE_SINK_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_sink(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_sink); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* meaning */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* coding */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* subcoding */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - return(isc_base64_tobuffer(lexer, target, -1)); -} - -static inline isc_result_t -totext_sink(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("255 255 255")]; - uint8_t meaning, coding, subcoding; - - REQUIRE(rdata->type == dns_rdatatype_sink); - REQUIRE(rdata->length >= 3); - - dns_rdata_toregion(rdata, &sr); - - /* Meaning, Coding and Subcoding */ - meaning = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - coding = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - subcoding = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u %u %u", meaning, coding, subcoding); - RETERR(str_totext(buf, target)); - - if (sr.length == 0U) - return (ISC_R_SUCCESS); - - /* data */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - - RETERR(str_totext(tctx->linebreak, target)); - - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_sink(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_sink); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 3) - return (ISC_R_UNEXPECTEDEND); - - RETERR(mem_tobuffer(target, sr.base, sr.length)); - isc_buffer_forward(source, sr.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_sink(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_sink); - REQUIRE(rdata->length >= 3); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_sink(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_sink); - REQUIRE(rdata1->length >= 3); - REQUIRE(rdata2->length >= 3); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_sink(ARGS_FROMSTRUCT) { - dns_rdata_sink_t *sink; - - REQUIRE(type == dns_rdatatype_sink); - REQUIRE(((dns_rdata_sink_t *)source) != NULL); - REQUIRE(((dns_rdata_sink_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_sink_t *)source)->common.rdclass == rdclass); - - sink = source; - - UNUSED(type); - UNUSED(rdclass); - - /* Meaning */ - RETERR(uint8_tobuffer(sink->meaning, target)); - - /* Coding */ - RETERR(uint8_tobuffer(sink->coding, target)); - - /* Subcoding */ - RETERR(uint8_tobuffer(sink->subcoding, target)); - - /* Data */ - return (mem_tobuffer(target, sink->data, sink->datalen)); -} - -static inline isc_result_t -tostruct_sink(ARGS_TOSTRUCT) { - dns_rdata_sink_t *sink; - isc_region_t sr; - - REQUIRE(((dns_rdata_sink_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_sink); - REQUIRE(rdata->length >= 3); - - sink = target; - - sink->common.rdclass = rdata->rdclass; - sink->common.rdtype = rdata->type; - ISC_LINK_INIT(&sink->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* Meaning */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - sink->meaning = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Coding */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - sink->coding = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Subcoding */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - sink->subcoding = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Data */ - sink->datalen = sr.length; - sink->data = mem_maybedup(mctx, sr.base, sink->datalen); - if (sink->data == NULL) - return (ISC_R_NOMEMORY); - - sink->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_sink(ARGS_FREESTRUCT) { - dns_rdata_sink_t *sink; - - REQUIRE(((dns_rdata_sink_t *)source) != NULL); - REQUIRE(((dns_rdata_sink_t *)source)->common.rdtype == - dns_rdatatype_sink); - - sink = (dns_rdata_sink_t *) source; - - if (sink->mctx == NULL) - return; - - if (sink->data != NULL) - isc_mem_free(sink->mctx, sink->data); - sink->mctx = NULL; -} - -static inline isc_result_t -additionaldata_sink(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_sink); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_sink(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_sink); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_sink(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_sink); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_sink(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_sink); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_sink(ARGS_COMPARE) { - return (compare_sink(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_SINK_40_C */ diff --git a/lib/dns-pkcs11/rdata/generic/sink_40.h b/lib/dns-pkcs11/rdata/generic/sink_40.h deleted file mode 100644 index eecf717..0000000 --- a/lib/dns-pkcs11/rdata/generic/sink_40.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_SINK_40_H -#define GENERIC_SINK_40_H 1 - -typedef struct dns_rdata_sink_t { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint8_t meaning; - uint8_t coding; - uint8_t subcoding; - uint16_t datalen; - unsigned char * data; -} dns_rdata_sink_t; - -#endif /* GENERIC_SINK_40_H */ diff --git a/lib/dns-pkcs11/rdata/generic/smimea_53.c b/lib/dns-pkcs11/rdata/generic/smimea_53.c deleted file mode 100644 index df70b2b..0000000 --- a/lib/dns-pkcs11/rdata/generic/smimea_53.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_SMIMEA_53_C -#define RDATA_GENERIC_SMIMEA_53_C - -#define RRTYPE_SMIMEA_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_smimea(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_smimea); - - return (generic_fromtext_tlsa(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_smimea(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_smimea); - - return (generic_totext_tlsa(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_smimea(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_smimea); - - return (generic_fromwire_tlsa(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_smimea(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_smimea); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_smimea(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_smimea); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_smimea(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_smimea); - - return (generic_fromstruct_tlsa(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_smimea(ARGS_TOSTRUCT) { - dns_rdata_smimea_t *smimea; - - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_smimea); - REQUIRE(((dns_rdata_smimea_t *)target) != NULL); - - smimea = target; - - smimea->common.rdclass = rdata->rdclass; - smimea->common.rdtype = rdata->type; - ISC_LINK_INIT(&smimea->common, link); - - return (generic_tostruct_tlsa(rdata, target, mctx)); -} - -static inline void -freestruct_smimea(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_smimea_t *)source) != NULL); - REQUIRE(((dns_rdata_smimea_t *)source)->common.rdtype == - dns_rdatatype_smimea); - - generic_freestruct_tlsa(source); -} - -static inline isc_result_t -additionaldata_smimea(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_smimea); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_smimea(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_smimea); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_smimea(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_smimea); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_smimea(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_smimea); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_smimea(ARGS_COMPARE) { - return (compare_smimea(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_SMIMEA_53_C */ diff --git a/lib/dns-pkcs11/rdata/generic/smimea_53.h b/lib/dns-pkcs11/rdata/generic/smimea_53.h deleted file mode 100644 index e23dd3b..0000000 --- a/lib/dns-pkcs11/rdata/generic/smimea_53.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_SMIMEA_53_H -#define GENERIC_SMIMEA_53_H 1 - -typedef struct dns_rdata_tlsa dns_rdata_smimea_t; - -#endif /* GENERIC_SMIMEA_53_H */ diff --git a/lib/dns-pkcs11/rdata/generic/soa_6.c b/lib/dns-pkcs11/rdata/generic/soa_6.c deleted file mode 100644 index 8d7df47..0000000 --- a/lib/dns-pkcs11/rdata/generic/soa_6.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_SOA_6_C -#define RDATA_GENERIC_SOA_6_C - -#define RRTYPE_SOA_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON) - -static inline isc_result_t -fromtext_soa(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - int i; - uint32_t n; - bool ok; - - REQUIRE(type == dns_rdatatype_soa); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - if (origin == NULL) - origin = dns_rootname; - - for (i = 0; i < 2; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, - options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - switch (i) { - case 0: - ok = dns_name_ishostname(&name, false); - break; - case 1: - ok = dns_name_ismailbox(&name); - break; - - } - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - } - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - for (i = 0; i < 4; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - RETTOK(dns_counter_fromtext(&token.value.as_textregion, &n)); - RETERR(uint32_tobuffer(n, target)); - } - - return (ISC_R_SUCCESS); -} - -static const char *soa_fieldnames[5] = { - "serial", "refresh", "retry", "expire", "minimum" -}; - -static inline isc_result_t -totext_soa(ARGS_TOTEXT) { - isc_region_t dregion; - dns_name_t mname; - dns_name_t rname; - dns_name_t prefix; - bool sub; - int i; - bool multiline; - bool comm; - - REQUIRE(rdata->type == dns_rdatatype_soa); - REQUIRE(rdata->length != 0); - - multiline = (tctx->flags & DNS_STYLEFLAG_MULTILINE); - if (multiline) { - comm = ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0); - } else { - comm = false; - } - - dns_name_init(&mname, NULL); - dns_name_init(&rname, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, &dregion); - - dns_name_fromregion(&mname, &dregion); - isc_region_consume(&dregion, name_length(&mname)); - - dns_name_fromregion(&rname, &dregion); - isc_region_consume(&dregion, name_length(&rname)); - - sub = name_prefix(&mname, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - RETERR(str_totext(" ", target)); - - sub = name_prefix(&rname, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - if (multiline) - RETERR(str_totext(" (" , target)); - RETERR(str_totext(tctx->linebreak, target)); - - for (i = 0; i < 5; i++) { - char buf[sizeof("0123456789 ; ")]; - unsigned long num; - num = uint32_fromregion(&dregion); - isc_region_consume(&dregion, 4); - snprintf(buf, sizeof(buf), comm ? "%-10lu ; " : "%lu", num); - RETERR(str_totext(buf, target)); - if (comm) { - RETERR(str_totext(soa_fieldnames[i], target)); - /* Print times in week/day/hour/minute/second form */ - if (i >= 1) { - RETERR(str_totext(" (", target)); - RETERR(dns_ttl_totext(num, true, target)); - RETERR(str_totext(")", target)); - } - RETERR(str_totext(tctx->linebreak, target)); - } else if (i < 4) { - RETERR(str_totext(tctx->linebreak, target)); - } - } - - if (multiline) - RETERR(str_totext(")", target)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_soa(ARGS_FROMWIRE) { - dns_name_t mname; - dns_name_t rname; - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(type == dns_rdatatype_soa); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&mname, NULL); - dns_name_init(&rname, NULL); - - RETERR(dns_name_fromwire(&mname, source, dctx, options, target)); - RETERR(dns_name_fromwire(&rname, source, dctx, options, target)); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - - if (sregion.length < 20) - return (ISC_R_UNEXPECTEDEND); - if (tregion.length < 20) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 20); - isc_buffer_forward(source, 20); - isc_buffer_add(target, 20); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_soa(ARGS_TOWIRE) { - isc_region_t sregion; - isc_region_t tregion; - dns_name_t mname; - dns_name_t rname; - dns_offsets_t moffsets; - dns_offsets_t roffsets; - - REQUIRE(rdata->type == dns_rdatatype_soa); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - - dns_name_init(&mname, moffsets); - dns_name_init(&rname, roffsets); - - dns_rdata_toregion(rdata, &sregion); - - dns_name_fromregion(&mname, &sregion); - isc_region_consume(&sregion, name_length(&mname)); - RETERR(dns_name_towire(&mname, cctx, target)); - - dns_name_fromregion(&rname, &sregion); - isc_region_consume(&sregion, name_length(&rname)); - RETERR(dns_name_towire(&rname, cctx, target)); - - isc_buffer_availableregion(target, &tregion); - if (tregion.length < 20) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 20); - isc_buffer_add(target, 20); - return (ISC_R_SUCCESS); -} - -static inline int -compare_soa(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_soa); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_soa(ARGS_FROMSTRUCT) { - dns_rdata_soa_t *soa; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_soa); - REQUIRE(((dns_rdata_soa_t *)source) != NULL); - REQUIRE(((dns_rdata_soa_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_soa_t *)source)->common.rdclass == rdclass); - - soa = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&soa->origin, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - dns_name_toregion(&soa->contact, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - RETERR(uint32_tobuffer(soa->serial, target)); - RETERR(uint32_tobuffer(soa->refresh, target)); - RETERR(uint32_tobuffer(soa->retry, target)); - RETERR(uint32_tobuffer(soa->expire, target)); - return (uint32_tobuffer(soa->minimum, target)); -} - -static inline isc_result_t -tostruct_soa(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_soa_t *soa; - dns_name_t name; - isc_result_t result; - - REQUIRE(((dns_rdata_soa_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_soa); - REQUIRE(rdata->length != 0); - - soa = target; - - soa->common.rdclass = rdata->rdclass; - soa->common.rdtype = rdata->type; - ISC_LINK_INIT(&soa->common, link); - - - dns_rdata_toregion(rdata, ®ion); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&soa->origin, NULL); - RETERR(name_duporclone(&name, mctx, &soa->origin)); - - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&soa->contact, NULL); - result = name_duporclone(&name, mctx, &soa->contact); - if (result != ISC_R_SUCCESS) - goto cleanup; - - soa->serial = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - soa->refresh = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - soa->retry = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - soa->expire = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - - soa->minimum = uint32_fromregion(®ion); - - soa->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&soa->origin, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_soa(ARGS_FREESTRUCT) { - dns_rdata_soa_t *soa; - - REQUIRE(((dns_rdata_soa_t *)source) != NULL); - REQUIRE(((dns_rdata_soa_t *)source)->common.rdtype == - dns_rdatatype_soa); - - soa = source; - - if (soa->mctx == NULL) - return; - - dns_name_free(&soa->origin, soa->mctx); - dns_name_free(&soa->contact, soa->mctx); - soa->mctx = NULL; -} - -static inline isc_result_t -additionaldata_soa(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_soa); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_soa(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_soa); - - dns_rdata_toregion(rdata, &r); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - RETERR(dns_name_digest(&name, digest, arg)); - isc_region_consume(&r, name_length(&name)); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - RETERR(dns_name_digest(&name, digest, arg)); - isc_region_consume(&r, name_length(&name)); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_soa(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_soa); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_soa(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_soa); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - isc_region_consume(®ion, name_length(&name)); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ismailbox(&name)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_soa(ARGS_COMPARE) { - return (compare_soa(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_SOA_6_C */ diff --git a/lib/dns-pkcs11/rdata/generic/soa_6.h b/lib/dns-pkcs11/rdata/generic/soa_6.h deleted file mode 100644 index 87269d8..0000000 --- a/lib/dns-pkcs11/rdata/generic/soa_6.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_SOA_6_H -#define GENERIC_SOA_6_H 1 - - -typedef struct dns_rdata_soa { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t origin; - dns_name_t contact; - uint32_t serial; /*%< host order */ - uint32_t refresh; /*%< host order */ - uint32_t retry; /*%< host order */ - uint32_t expire; /*%< host order */ - uint32_t minimum; /*%< host order */ -} dns_rdata_soa_t; - - -#endif /* GENERIC_SOA_6_H */ diff --git a/lib/dns-pkcs11/rdata/generic/spf_99.c b/lib/dns-pkcs11/rdata/generic/spf_99.c deleted file mode 100644 index 579619c..0000000 --- a/lib/dns-pkcs11/rdata/generic/spf_99.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_SPF_99_C -#define RDATA_GENERIC_SPF_99_C - -#define RRTYPE_SPF_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_spf(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_spf); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - return (generic_fromtext_txt(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_spf(ARGS_TOTEXT) { - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_spf); - - return (generic_totext_txt(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_spf(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_spf); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - return (generic_fromwire_txt(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_spf(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_spf); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_spf(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_spf); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_spf(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_spf); - - return (generic_fromstruct_txt(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_spf(ARGS_TOSTRUCT) { - dns_rdata_spf_t *spf; - - REQUIRE(((dns_rdata_spf_t *)target) != NULL); - REQUIRE(rdata != NULL); - REQUIRE(rdata->type == dns_rdatatype_spf); - - spf = target; - - spf->common.rdclass = rdata->rdclass; - spf->common.rdtype = rdata->type; - ISC_LINK_INIT(&spf->common, link); - - return (generic_tostruct_txt(rdata, target, mctx)); -} - -static inline void -freestruct_spf(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_spf_t *)source) != NULL); - REQUIRE(((dns_rdata_spf_t *)source)->common.rdtype == - dns_rdatatype_spf); - - generic_freestruct_txt(source); -} - -static inline isc_result_t -additionaldata_spf(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_spf); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_spf(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_spf); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_spf(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_spf); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_spf(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_spf); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_spf(ARGS_COMPARE) { - return (compare_spf(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_SPF_99_C */ diff --git a/lib/dns-pkcs11/rdata/generic/spf_99.h b/lib/dns-pkcs11/rdata/generic/spf_99.h deleted file mode 100644 index c414025..0000000 --- a/lib/dns-pkcs11/rdata/generic/spf_99.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_SPF_99_H -#define GENERIC_SPF_99_H 1 - - -typedef struct dns_rdata_spf_string { - uint8_t length; - unsigned char *data; -} dns_rdata_spf_string_t; - -typedef struct dns_rdata_spf { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *txt; - uint16_t txt_len; - /* private */ - uint16_t offset; -} dns_rdata_spf_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ -#endif /* GENERIC_SPF_99_H */ diff --git a/lib/dns-pkcs11/rdata/generic/sshfp_44.c b/lib/dns-pkcs11/rdata/generic/sshfp_44.c deleted file mode 100644 index 3cba0fd..0000000 --- a/lib/dns-pkcs11/rdata/generic/sshfp_44.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC 4255 */ - -#ifndef RDATA_GENERIC_SSHFP_44_C -#define RDATA_GENERIC_SSHFP_44_C - -#define RRTYPE_SSHFP_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_sshfp(ARGS_FROMTEXT) { - isc_token_t token; - int len = -1; - - REQUIRE(type == dns_rdatatype_sshfp); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Digest type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Enforce known digest lengths. - */ - switch (token.value.as_ulong) { - case 1: - len = ISC_SHA1_DIGESTLENGTH; - break; - case 2: - len = ISC_SHA256_DIGESTLENGTH; - break; - default: - break; - } - - /* - * Digest. - */ - return (isc_hex_tobuffer(lexer, target, len)); -} - -static inline isc_result_t -totext_sshfp(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("64000 ")]; - unsigned int n; - - REQUIRE(rdata->type == dns_rdatatype_sshfp); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - /* - * Algorithm. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Digest type. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u", n); - RETERR(str_totext(buf, target)); - - if (sr.length == 0U) { - return (ISC_R_SUCCESS); - } - - /* - * Digest. - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_hex_totext(&sr, 0, "", target)); - else - RETERR(isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_sshfp(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_sshfp); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 2) { - return (ISC_R_UNEXPECTEDEND); - } - - if ((sr.base[1] == 1 && sr.length != ISC_SHA1_DIGESTLENGTH + 2) || - (sr.base[1] == 2 && sr.length != ISC_SHA256_DIGESTLENGTH + 2)) { - return (DNS_R_FORMERR); - } - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_sshfp(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_sshfp); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_sshfp(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_sshfp); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_sshfp(ARGS_FROMSTRUCT) { - dns_rdata_sshfp_t *sshfp; - - REQUIRE(type == dns_rdatatype_sshfp); - REQUIRE(((dns_rdata_sshfp_t *)source) != NULL); - REQUIRE(((dns_rdata_sshfp_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_sshfp_t *)source)->common.rdclass == rdclass); - - sshfp = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(sshfp->algorithm, target)); - RETERR(uint8_tobuffer(sshfp->digest_type, target)); - - return (mem_tobuffer(target, sshfp->digest, sshfp->length)); -} - -static inline isc_result_t -tostruct_sshfp(ARGS_TOSTRUCT) { - dns_rdata_sshfp_t *sshfp; - isc_region_t region; - - REQUIRE(((dns_rdata_sshfp_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_sshfp); - REQUIRE(rdata->length != 0); - - sshfp = target; - - sshfp->common.rdclass = rdata->rdclass; - sshfp->common.rdtype = rdata->type; - ISC_LINK_INIT(&sshfp->common, link); - - dns_rdata_toregion(rdata, ®ion); - - sshfp->algorithm = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - sshfp->digest_type = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - sshfp->length = region.length; - - sshfp->digest = mem_maybedup(mctx, region.base, region.length); - if (sshfp->digest == NULL) - return (ISC_R_NOMEMORY); - - sshfp->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_sshfp(ARGS_FREESTRUCT) { - dns_rdata_sshfp_t *sshfp; - - REQUIRE(((dns_rdata_sshfp_t *)source) != NULL); - REQUIRE(((dns_rdata_sshfp_t *)source)->common.rdtype == - dns_rdatatype_sshfp); - - sshfp = source; - - if (sshfp->mctx == NULL) - return; - - if (sshfp->digest != NULL) - isc_mem_free(sshfp->mctx, sshfp->digest); - sshfp->mctx = NULL; -} - -static inline isc_result_t -additionaldata_sshfp(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_sshfp); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_sshfp(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_sshfp); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_sshfp(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_sshfp); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_sshfp(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_sshfp); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_sshfp(ARGS_COMPARE) { - return (compare_sshfp(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_SSHFP_44_C */ diff --git a/lib/dns-pkcs11/rdata/generic/sshfp_44.h b/lib/dns-pkcs11/rdata/generic/sshfp_44.h deleted file mode 100644 index f231c82..0000000 --- a/lib/dns-pkcs11/rdata/generic/sshfp_44.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! - * \brief Per RFC 4255 */ - -#ifndef GENERIC_SSHFP_44_H -#define GENERIC_SSHFP_44_H 1 - -typedef struct dns_rdata_sshfp { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint8_t algorithm; - uint8_t digest_type; - uint16_t length; - unsigned char *digest; -} dns_rdata_sshfp_t; - -#endif /* GENERIC_SSHFP_44_H */ diff --git a/lib/dns-pkcs11/rdata/generic/ta_32768.c b/lib/dns-pkcs11/rdata/generic/ta_32768.c deleted file mode 100644 index fdcc956..0000000 --- a/lib/dns-pkcs11/rdata/generic/ta_32768.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* http://www.watson.org/~weiler/INI1999-19.pdf */ - -#ifndef RDATA_GENERIC_TA_32768_C -#define RDATA_GENERIC_TA_32768_C - -#define RRTYPE_TA_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_ta(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_ta); - - return (generic_fromtext_ds(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_ta(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_ta); - - return (generic_totext_ds(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_ta(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_ta); - - return (generic_fromwire_ds(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_ta(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_ta); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_ta(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_ta); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_ta(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_ta); - - return (generic_fromstruct_ds(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_ta(ARGS_TOSTRUCT) { - dns_rdata_ds_t *ds; - - REQUIRE(rdata->type == dns_rdatatype_ta); - REQUIRE(((dns_rdata_ds_t *)target) != NULL); - - ds = target; - - /* - * Checked by generic_tostruct_ds(). - */ - ds->common.rdclass = rdata->rdclass; - ds->common.rdtype = rdata->type; - ISC_LINK_INIT(&ds->common, link); - - return (generic_tostruct_ds(rdata, target, mctx)); -} - -static inline void -freestruct_ta(ARGS_FREESTRUCT) { - dns_rdata_ta_t *ds; - - REQUIRE(((dns_rdata_ds_t *)source) != NULL); - REQUIRE(((dns_rdata_ds_t *)source)->common.rdtype == dns_rdatatype_ta); - - ds = source; - - if (ds->mctx == NULL) - return; - - if (ds->digest != NULL) - isc_mem_free(ds->mctx, ds->digest); - ds->mctx = NULL; -} - -static inline isc_result_t -additionaldata_ta(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_ta); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_ta(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_ta); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_ta(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_ta); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_ta(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_ta); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_ta(ARGS_COMPARE) { - return (compare_ta(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_TA_32768_C */ diff --git a/lib/dns-pkcs11/rdata/generic/ta_32768.h b/lib/dns-pkcs11/rdata/generic/ta_32768.h deleted file mode 100644 index a25f652..0000000 --- a/lib/dns-pkcs11/rdata/generic/ta_32768.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_TA_32768_H -#define GENERIC_TA_32768_H 1 - -/* - * TA records are identical to DS records. - */ -typedef struct dns_rdata_ds dns_rdata_ta_t; - -#endif /* GENERIC_TA_32768_H */ diff --git a/lib/dns-pkcs11/rdata/generic/talink_58.c b/lib/dns-pkcs11/rdata/generic/talink_58.c deleted file mode 100644 index af0588a..0000000 --- a/lib/dns-pkcs11/rdata/generic/talink_58.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_TALINK_58_C -#define RDATA_GENERIC_TALINK_58_C - -#define RRTYPE_TALINK_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_talink(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - int i; - - REQUIRE(type == dns_rdatatype_talink); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - if (origin == NULL) - origin = dns_rootname; - - for (i = 0; i < 2; i++) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, - options, target)); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_talink(ARGS_TOTEXT) { - isc_region_t dregion; - dns_name_t prev; - dns_name_t next; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_talink); - REQUIRE(rdata->length != 0); - - dns_name_init(&prev, NULL); - dns_name_init(&next, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, &dregion); - - dns_name_fromregion(&prev, &dregion); - isc_region_consume(&dregion, name_length(&prev)); - - dns_name_fromregion(&next, &dregion); - isc_region_consume(&dregion, name_length(&next)); - - sub = name_prefix(&prev, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - - RETERR(str_totext(" ", target)); - - sub = name_prefix(&next, tctx->origin, &prefix); - return(dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_talink(ARGS_FROMWIRE) { - dns_name_t prev; - dns_name_t next; - - REQUIRE(type == dns_rdatatype_talink); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&prev, NULL); - dns_name_init(&next, NULL); - - RETERR(dns_name_fromwire(&prev, source, dctx, options, target)); - return(dns_name_fromwire(&next, source, dctx, options, target)); -} - -static inline isc_result_t -towire_talink(ARGS_TOWIRE) { - isc_region_t sregion; - dns_name_t prev; - dns_name_t next; - dns_offsets_t moffsets; - dns_offsets_t roffsets; - - REQUIRE(rdata->type == dns_rdatatype_talink); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - - dns_name_init(&prev, moffsets); - dns_name_init(&next, roffsets); - - dns_rdata_toregion(rdata, &sregion); - - dns_name_fromregion(&prev, &sregion); - isc_region_consume(&sregion, name_length(&prev)); - RETERR(dns_name_towire(&prev, cctx, target)); - - dns_name_fromregion(&next, &sregion); - isc_region_consume(&sregion, name_length(&next)); - return(dns_name_towire(&next, cctx, target)); -} - -static inline int -compare_talink(ARGS_COMPARE) { - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_talink); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - return (isc_region_compare(®ion1, ®ion2)); -} - -static inline isc_result_t -fromstruct_talink(ARGS_FROMSTRUCT) { - dns_rdata_talink_t *talink; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_talink); - REQUIRE(((dns_rdata_talink_t *)source) != NULL); - REQUIRE(((dns_rdata_talink_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_talink_t *)source)->common.rdclass == rdclass); - - talink = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&talink->prev, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - dns_name_toregion(&talink->next, ®ion); - return(isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_talink(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_talink_t *talink; - dns_name_t name; - isc_result_t result; - - REQUIRE(((dns_rdata_talink_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_talink); - REQUIRE(rdata->length != 0); - - talink = target; - - talink->common.rdclass = rdata->rdclass; - talink->common.rdtype = rdata->type; - ISC_LINK_INIT(&talink->common, link); - - dns_rdata_toregion(rdata, ®ion); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&talink->prev, NULL); - RETERR(name_duporclone(&name, mctx, &talink->prev)); - - dns_name_fromregion(&name, ®ion); - isc_region_consume(®ion, name_length(&name)); - dns_name_init(&talink->next, NULL); - result = name_duporclone(&name, mctx, &talink->next); - if (result != ISC_R_SUCCESS) - goto cleanup; - - talink->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&talink->prev, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_talink(ARGS_FREESTRUCT) { - dns_rdata_talink_t *talink; - - REQUIRE(((dns_rdata_talink_t *)source) != NULL); - REQUIRE(((dns_rdata_talink_t *)source)->common.rdtype == - dns_rdatatype_talink); - - talink = source; - - if (talink->mctx == NULL) - return; - - dns_name_free(&talink->prev, talink->mctx); - dns_name_free(&talink->next, talink->mctx); - talink->mctx = NULL; -} - -static inline isc_result_t -additionaldata_talink(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_talink); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_talink(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_talink); - - dns_rdata_toregion(rdata, &r); - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_talink(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_talink); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_talink(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_talink); - - UNUSED(bad); - UNUSED(owner); - - return (true); -} - -static inline int -casecompare_talink(ARGS_COMPARE) { - return (compare_talink(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_TALINK_58_C */ diff --git a/lib/dns-pkcs11/rdata/generic/talink_58.h b/lib/dns-pkcs11/rdata/generic/talink_58.h deleted file mode 100644 index 3e9833b..0000000 --- a/lib/dns-pkcs11/rdata/generic/talink_58.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* http://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template */ - -#ifndef GENERIC_TALINK_58_H -#define GENERIC_TALINK_58_H 1 - -typedef struct dns_rdata_talink { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t prev; - dns_name_t next; -} dns_rdata_talink_t; - -#endif /* GENERIC_TALINK_58_H */ diff --git a/lib/dns-pkcs11/rdata/generic/tkey_249.c b/lib/dns-pkcs11/rdata/generic/tkey_249.c deleted file mode 100644 index 9d8e7a3..0000000 --- a/lib/dns-pkcs11/rdata/generic/tkey_249.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* draft-ietf-dnsext-tkey-01.txt */ - -#ifndef RDATA_GENERIC_TKEY_249_C -#define RDATA_GENERIC_TKEY_249_C - -#define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META) - -static inline isc_result_t -fromtext_tkey(ARGS_FROMTEXT) { - isc_token_t token; - dns_rcode_t rcode; - dns_name_t name; - isc_buffer_t buffer; - long i; - char *e; - - REQUIRE(type == dns_rdatatype_tkey); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Algorithm. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - - /* - * Inception. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * Expiration. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * Mode. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Error. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) - != ISC_R_SUCCESS) - { - i = strtol(DNS_AS_STR(token), &e, 10); - if (*e != 0) - RETTOK(DNS_R_UNKNOWN); - if (i < 0 || i > 0xffff) - RETTOK(ISC_R_RANGE); - rcode = (dns_rcode_t)i; - } - RETERR(uint16_tobuffer(rcode, target)); - - /* - * Key Size. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Key Data. - */ - RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); - - /* - * Other Size. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Other Data. - */ - return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); -} - -static inline isc_result_t -totext_tkey(ARGS_TOTEXT) { - isc_region_t sr, dr; - char buf[sizeof("4294967295 ")]; - unsigned long n; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_tkey); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - - /* - * Algorithm. - */ - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - dns_name_fromregion(&name, &sr); - sub = name_prefix(&name, tctx->origin, &prefix); - RETERR(dns_name_totext(&prefix, sub, target)); - RETERR(str_totext(" ", target)); - isc_region_consume(&sr, name_length(&name)); - - /* - * Inception. - */ - n = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu ", n); - RETERR(str_totext(buf, target)); - - /* - * Expiration. - */ - n = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu ", n); - RETERR(str_totext(buf, target)); - - /* - * Mode. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu ", n); - RETERR(str_totext(buf, target)); - - /* - * Error. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) - RETERR(str_totext(" ", target)); - else { - snprintf(buf, sizeof(buf), "%lu ", n); - RETERR(str_totext(buf, target)); - } - - /* - * Key Size. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu", n); - RETERR(str_totext(buf, target)); - - /* - * Key Data. - */ - REQUIRE(n <= sr.length); - dr = sr; - dr.length = n; - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&dr, 60, "", target)); - else - RETERR(isc_base64_totext(&dr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ) ", target)); - else - RETERR(str_totext(" ", target)); - isc_region_consume(&sr, n); - - /* - * Other Size. - */ - n = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - snprintf(buf, sizeof(buf), "%lu", n); - RETERR(str_totext(buf, target)); - - /* - * Other Data. - */ - REQUIRE(n <= sr.length); - if (n != 0U) { - dr = sr; - dr.length = n; - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&dr, 60, "", target)); - else - RETERR(isc_base64_totext(&dr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_tkey(ARGS_FROMWIRE) { - isc_region_t sr; - unsigned long n; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_tkey); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - /* - * Algorithm. - */ - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - /* - * Inception: 4 - * Expiration: 4 - * Mode: 2 - * Error: 2 - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 12) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 12)); - isc_region_consume(&sr, 12); - isc_buffer_forward(source, 12); - - /* - * Key Length + Key Data. - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - n = uint16_fromregion(&sr); - if (sr.length < n + 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, n + 2)); - isc_region_consume(&sr, n + 2); - isc_buffer_forward(source, n + 2); - - /* - * Other Length + Other Data. - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - n = uint16_fromregion(&sr); - if (sr.length < n + 2) - return (ISC_R_UNEXPECTEDEND); - isc_buffer_forward(source, n + 2); - return (mem_tobuffer(target, sr.base, n + 2)); -} - -static inline isc_result_t -towire_tkey(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - - REQUIRE(rdata->type == dns_rdatatype_tkey); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - /* - * Algorithm. - */ - dns_rdata_toregion(rdata, &sr); - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - RETERR(dns_name_towire(&name, cctx, target)); - isc_region_consume(&sr, name_length(&name)); - - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_tkey(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - dns_name_t name1; - dns_name_t name2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_tkey); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - /* - * Algorithm. - */ - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_name_fromregion(&name1, &r1); - dns_name_fromregion(&name2, &r2); - if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) - return (order); - isc_region_consume(&r1, name_length(&name1)); - isc_region_consume(&r2, name_length(&name2)); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_tkey(ARGS_FROMSTRUCT) { - dns_rdata_tkey_t *tkey; - - REQUIRE(type == dns_rdatatype_tkey); - REQUIRE(((dns_rdata_tkey_t *)source) != NULL); - REQUIRE(((dns_rdata_tkey_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_tkey_t *)source)->common.rdclass == rdclass); - - tkey = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Algorithm Name. - */ - RETERR(name_tobuffer(&tkey->algorithm, target)); - - /* - * Inception: 32 bits. - */ - RETERR(uint32_tobuffer(tkey->inception, target)); - - /* - * Expire: 32 bits. - */ - RETERR(uint32_tobuffer(tkey->expire, target)); - - /* - * Mode: 16 bits. - */ - RETERR(uint16_tobuffer(tkey->mode, target)); - - /* - * Error: 16 bits. - */ - RETERR(uint16_tobuffer(tkey->error, target)); - - /* - * Key size: 16 bits. - */ - RETERR(uint16_tobuffer(tkey->keylen, target)); - - /* - * Key. - */ - RETERR(mem_tobuffer(target, tkey->key, tkey->keylen)); - - /* - * Other size: 16 bits. - */ - RETERR(uint16_tobuffer(tkey->otherlen, target)); - - /* - * Other data. - */ - return (mem_tobuffer(target, tkey->other, tkey->otherlen)); -} - -static inline isc_result_t -tostruct_tkey(ARGS_TOSTRUCT) { - dns_rdata_tkey_t *tkey; - dns_name_t alg; - isc_region_t sr; - - REQUIRE(((dns_rdata_tkey_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_tkey); - REQUIRE(rdata->length != 0); - - tkey = target; - - tkey->common.rdclass = rdata->rdclass; - tkey->common.rdtype = rdata->type; - ISC_LINK_INIT(&tkey->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Algorithm Name. - */ - dns_name_init(&alg, NULL); - dns_name_fromregion(&alg, &sr); - dns_name_init(&tkey->algorithm, NULL); - RETERR(name_duporclone(&alg, mctx, &tkey->algorithm)); - isc_region_consume(&sr, name_length(&tkey->algorithm)); - - /* - * Inception. - */ - tkey->inception = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Expire. - */ - tkey->expire = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - - /* - * Mode. - */ - tkey->mode = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Error. - */ - tkey->error = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Key size. - */ - tkey->keylen = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Key. - */ - INSIST(tkey->keylen + 2U <= sr.length); - tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen); - if (tkey->key == NULL) - goto cleanup; - isc_region_consume(&sr, tkey->keylen); - - /* - * Other size. - */ - tkey->otherlen = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Other. - */ - INSIST(tkey->otherlen <= sr.length); - tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen); - if (tkey->other == NULL) - goto cleanup; - - tkey->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL) - dns_name_free(&tkey->algorithm, mctx); - if (mctx != NULL && tkey->key != NULL) - isc_mem_free(mctx, tkey->key); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_tkey(ARGS_FREESTRUCT) { - dns_rdata_tkey_t *tkey; - - REQUIRE(((dns_rdata_tkey_t *)source) != NULL); - - tkey = (dns_rdata_tkey_t *) source; - - if (tkey->mctx == NULL) - return; - - dns_name_free(&tkey->algorithm, tkey->mctx); - if (tkey->key != NULL) - isc_mem_free(tkey->mctx, tkey->key); - if (tkey->other != NULL) - isc_mem_free(tkey->mctx, tkey->other); - tkey->mctx = NULL; -} - -static inline isc_result_t -additionaldata_tkey(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_tkey); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_tkey(ARGS_DIGEST) { - UNUSED(rdata); - UNUSED(digest); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_tkey); - - return (ISC_R_NOTIMPLEMENTED); -} - -static inline bool -checkowner_tkey(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_tkey); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_tkey(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_tkey); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_tkey(ARGS_COMPARE) { - return (compare_tkey(rdata1, rdata2)); -} -#endif /* RDATA_GENERIC_TKEY_249_C */ diff --git a/lib/dns-pkcs11/rdata/generic/tkey_249.h b/lib/dns-pkcs11/rdata/generic/tkey_249.h deleted file mode 100644 index 896ff4f..0000000 --- a/lib/dns-pkcs11/rdata/generic/tkey_249.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_TKEY_249_H -#define GENERIC_TKEY_249_H 1 - - -/*! - * \brief Per draft-ietf-dnsind-tkey-00.txt */ - -typedef struct dns_rdata_tkey { - dns_rdatacommon_t common; - isc_mem_t * mctx; - dns_name_t algorithm; - uint32_t inception; - uint32_t expire; - uint16_t mode; - uint16_t error; - uint16_t keylen; - unsigned char * key; - uint16_t otherlen; - unsigned char * other; -} dns_rdata_tkey_t; - - -#endif /* GENERIC_TKEY_249_H */ diff --git a/lib/dns-pkcs11/rdata/generic/tlsa_52.c b/lib/dns-pkcs11/rdata/generic/tlsa_52.c deleted file mode 100644 index 581fb92..0000000 --- a/lib/dns-pkcs11/rdata/generic/tlsa_52.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* rfc6698.txt */ - -#ifndef RDATA_GENERIC_TLSA_52_C -#define RDATA_GENERIC_TLSA_52_C - -#define RRTYPE_TLSA_ATTRIBUTES 0 - -static inline isc_result_t -generic_fromtext_tlsa(ARGS_FROMTEXT) { - isc_token_t token; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Certificate Usage. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Selector. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Matching type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffU) - RETTOK(ISC_R_RANGE); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Certificate Association Data. - */ - return (isc_hex_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -generic_totext_tlsa(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("64000 ")]; - unsigned int n; - - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - /* - * Certificate Usage. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Selector. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u ", n); - RETERR(str_totext(buf, target)); - - /* - * Matching type. - */ - n = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u", n); - RETERR(str_totext(buf, target)); - - /* - * Certificate Association Data. - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_hex_totext(&sr, 0, "", target)); - else - RETERR(isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" )", target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -generic_fromwire_tlsa(ARGS_FROMWIRE) { - isc_region_t sr; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - - /* Usage(1), Selector(1), Type(1), Data(1+) */ - if (sr.length < 4) { - return (ISC_R_UNEXPECTEDEND); - } - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -fromtext_tlsa(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_tlsa); - - return (generic_fromtext_tlsa(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_tlsa(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_tlsa); - - return (generic_totext_tlsa(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_tlsa(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_tlsa); - - return (generic_fromwire_tlsa(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_tlsa(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_tlsa); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_tlsa(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_tlsa); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -generic_fromstruct_tlsa(ARGS_FROMSTRUCT) { - dns_rdata_tlsa_t *tlsa; - - REQUIRE(((dns_rdata_tlsa_t *)source) != NULL); - REQUIRE(((dns_rdata_tlsa_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_tlsa_t *)source)->common.rdclass == rdclass); - - tlsa = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint8_tobuffer(tlsa->usage, target)); - RETERR(uint8_tobuffer(tlsa->selector, target)); - RETERR(uint8_tobuffer(tlsa->match, target)); - - return (mem_tobuffer(target, tlsa->data, tlsa->length)); -} - -static inline isc_result_t -generic_tostruct_tlsa(ARGS_TOSTRUCT) { - dns_rdata_tlsa_t *tlsa; - isc_region_t region; - - REQUIRE(rdata->length != 0); - REQUIRE(((dns_rdata_tlsa_t *)target) != NULL); - REQUIRE(((dns_rdata_tlsa_t *)target)->common.rdclass == rdata->rdclass); - REQUIRE(((dns_rdata_tlsa_t *)target)->common.rdtype == rdata->type); - REQUIRE(!ISC_LINK_LINKED(&((dns_rdata_tlsa_t *)target)->common, link)); - - tlsa = target; - - dns_rdata_toregion(rdata, ®ion); - - tlsa->usage = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - tlsa->selector = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - tlsa->match = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - tlsa->length = region.length; - - tlsa->data = mem_maybedup(mctx, region.base, region.length); - if (tlsa->data == NULL) - return (ISC_R_NOMEMORY); - - tlsa->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -generic_freestruct_tlsa(ARGS_FREESTRUCT) { - dns_rdata_tlsa_t *tlsa; - - REQUIRE(((dns_rdata_tlsa_t *)source) != NULL); - - tlsa = source; - - if (tlsa->mctx == NULL) - return; - - if (tlsa->data != NULL) - isc_mem_free(tlsa->mctx, tlsa->data); - tlsa->mctx = NULL; -} - -static inline isc_result_t -fromstruct_tlsa(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_tlsa); - - return (generic_fromstruct_tlsa(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_tlsa(ARGS_TOSTRUCT) { - dns_rdata_tlsa_t *tlsa; - - REQUIRE(rdata->type == dns_rdatatype_tlsa); - REQUIRE(((dns_rdata_tlsa_t *)target) != NULL); - - tlsa = target; - - tlsa->common.rdclass = rdata->rdclass; - tlsa->common.rdtype = rdata->type; - ISC_LINK_INIT(&tlsa->common, link); - - return (generic_tostruct_tlsa(rdata, target, mctx)); -} - -static inline void -freestruct_tlsa(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_tlsa_t *)source) != NULL); - REQUIRE(((dns_rdata_tlsa_t *)source)->common.rdtype == - dns_rdatatype_tlsa); - - generic_freestruct_tlsa(source); -} - -static inline isc_result_t -additionaldata_tlsa(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_tlsa); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_tlsa(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_tlsa); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_tlsa(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_tlsa); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_tlsa(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_tlsa); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_tlsa(ARGS_COMPARE) { - return (compare_tlsa(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_TLSA_52_C */ diff --git a/lib/dns-pkcs11/rdata/generic/tlsa_52.h b/lib/dns-pkcs11/rdata/generic/tlsa_52.h deleted file mode 100644 index d589314..0000000 --- a/lib/dns-pkcs11/rdata/generic/tlsa_52.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_TLSA_52_H -#define GENERIC_TLSA_52_H 1 - -/*! - * \brief per rfc6698.txt - */ -typedef struct dns_rdata_tlsa { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint8_t usage; - uint8_t selector; - uint8_t match; - uint16_t length; - unsigned char *data; -} dns_rdata_tlsa_t; - -#endif /* GENERIC_TLSA_52_H */ diff --git a/lib/dns-pkcs11/rdata/generic/txt_16.c b/lib/dns-pkcs11/rdata/generic/txt_16.c deleted file mode 100644 index b1427d1..0000000 --- a/lib/dns-pkcs11/rdata/generic/txt_16.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_GENERIC_TXT_16_C -#define RDATA_GENERIC_TXT_16_C - -#define RRTYPE_TXT_ATTRIBUTES (0) - -static inline isc_result_t -generic_fromtext_txt(ARGS_FROMTEXT) { - isc_token_t token; - int strings; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - strings = 0; - if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { - isc_textregion_t r; - DE_CONST("#", r.base); - r.length = 1; - RETERR(txt_fromtext(&r, target)); - strings++; - } - for (;;) { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_qstring, - true)); - if (token.type != isc_tokentype_qstring && - token.type != isc_tokentype_string) - break; - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - strings++; - } - /* Let upper layer handle eol/eof. */ - isc_lex_ungettoken(lexer, &token); - return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS); -} - -static inline isc_result_t -generic_totext_txt(ARGS_TOTEXT) { - isc_region_t region; - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - - while (region.length > 0) { - RETERR(txt_totext(®ion, true, target)); - if (region.length > 0) - RETERR(str_totext(" ", target)); - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -generic_fromwire_txt(ARGS_FROMWIRE) { - isc_result_t result; - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - do { - result = txt_fromwire(source, target); - if (result != ISC_R_SUCCESS) - return (result); - } while (!buffer_empty(source)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromtext_txt(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_txt); - - return (generic_fromtext_txt(rdclass, type, lexer, origin, options, - target, callbacks)); -} - -static inline isc_result_t -totext_txt(ARGS_TOTEXT) { - - REQUIRE(rdata->type == dns_rdatatype_txt); - - return (generic_totext_txt(rdata, tctx, target)); -} - -static inline isc_result_t -fromwire_txt(ARGS_FROMWIRE) { - - REQUIRE(type == dns_rdatatype_txt); - - return (generic_fromwire_txt(rdclass, type, source, dctx, options, - target)); -} - -static inline isc_result_t -towire_txt(ARGS_TOWIRE) { - - REQUIRE(rdata->type == dns_rdatatype_txt); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_txt(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_txt); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -generic_fromstruct_txt(ARGS_FROMSTRUCT) { - dns_rdata_txt_t *txt; - isc_region_t region; - uint8_t length; - - REQUIRE(((dns_rdata_txt_t *)source) != NULL); - REQUIRE(((dns_rdata_txt_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_txt_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_txt_t *)source)->txt != NULL); - REQUIRE(((dns_rdata_txt_t *)source)->txt_len != 0); - - txt = source; - - UNUSED(type); - UNUSED(rdclass); - - region.base = txt->txt; - region.length = txt->txt_len; - while (region.length > 0) { - length = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - if (region.length < length) - return (ISC_R_UNEXPECTEDEND); - isc_region_consume(®ion, length); - } - - return (mem_tobuffer(target, txt->txt, txt->txt_len)); -} - -static inline isc_result_t -generic_tostruct_txt(ARGS_TOSTRUCT) { - dns_rdata_txt_t *txt; - isc_region_t r; - - REQUIRE(((dns_rdata_txt_t *)target) != NULL); - REQUIRE(((dns_rdata_txt_t *)target)->common.rdclass == rdata->rdclass); - REQUIRE(((dns_rdata_txt_t *)target)->common.rdtype == rdata->type); - REQUIRE(!ISC_LINK_LINKED(&((dns_rdata_txt_t *)target)->common, link)); - - txt = target; - - dns_rdata_toregion(rdata, &r); - txt->txt_len = r.length; - txt->txt = mem_maybedup(mctx, r.base, r.length); - if (txt->txt == NULL) - return (ISC_R_NOMEMORY); - - txt->offset = 0; - txt->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -generic_freestruct_txt(ARGS_FREESTRUCT) { - dns_rdata_txt_t *txt; - - REQUIRE(((dns_rdata_txt_t *)source) != NULL); - - txt = source; - - if (txt->mctx == NULL) - return; - - if (txt->txt != NULL) - isc_mem_free(txt->mctx, txt->txt); - txt->mctx = NULL; -} - -static inline isc_result_t -fromstruct_txt(ARGS_FROMSTRUCT) { - - REQUIRE(type == dns_rdatatype_txt); - - return (generic_fromstruct_txt(rdclass, type, source, target)); -} - -static inline isc_result_t -tostruct_txt(ARGS_TOSTRUCT) { - dns_rdata_txt_t *txt; - - REQUIRE(rdata->type == dns_rdatatype_txt); - REQUIRE(((dns_rdata_txt_t *)target) != NULL); - - txt = target; - - txt->common.rdclass = rdata->rdclass; - txt->common.rdtype = rdata->type; - ISC_LINK_INIT(&txt->common, link); - - return (generic_tostruct_txt(rdata, target, mctx)); -} - -static inline void -freestruct_txt(ARGS_FREESTRUCT) { - REQUIRE(((dns_rdata_txt_t *)source) != NULL); - REQUIRE(((dns_rdata_txt_t *)source)->common.rdtype == - dns_rdatatype_txt); - - generic_freestruct_txt(source); -} - -static inline isc_result_t -additionaldata_txt(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_txt); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_txt(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_txt); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_txt(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_txt); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_txt(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_txt); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_txt(ARGS_COMPARE) { - return (compare_txt(rdata1, rdata2)); -} - -static isc_result_t -generic_txt_first(dns_rdata_txt_t *txt) { - - REQUIRE(txt != NULL); - REQUIRE(txt->txt != NULL || txt->txt_len == 0); - - if (txt->txt_len == 0) - return (ISC_R_NOMORE); - - txt->offset = 0; - return (ISC_R_SUCCESS); -} - -static isc_result_t -generic_txt_next(dns_rdata_txt_t *txt) { - isc_region_t r; - uint8_t length; - - REQUIRE(txt != NULL); - REQUIRE(txt->txt != NULL && txt->txt_len != 0); - - INSIST(txt->offset + 1 <= txt->txt_len); - r.base = txt->txt + txt->offset; - r.length = txt->txt_len - txt->offset; - length = uint8_fromregion(&r); - INSIST(txt->offset + 1 + length <= txt->txt_len); - txt->offset = txt->offset + 1 + length; - if (txt->offset == txt->txt_len) - return (ISC_R_NOMORE); - return (ISC_R_SUCCESS); -} - -static isc_result_t -generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { - isc_region_t r; - - REQUIRE(txt != NULL); - REQUIRE(string != NULL); - REQUIRE(txt->txt != NULL); - REQUIRE(txt->offset < txt->txt_len); - - INSIST(txt->offset + 1 <= txt->txt_len); - r.base = txt->txt + txt->offset; - r.length = txt->txt_len - txt->offset; - - string->length = uint8_fromregion(&r); - isc_region_consume(&r, 1); - string->data = r.base; - INSIST(txt->offset + 1 + string->length <= txt->txt_len); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdata_txt_first(dns_rdata_txt_t *txt) { - - REQUIRE(txt != NULL); - REQUIRE(txt->common.rdtype == dns_rdatatype_txt); - - return (generic_txt_first(txt)); -} - -isc_result_t -dns_rdata_txt_next(dns_rdata_txt_t *txt) { - - REQUIRE(txt != NULL); - REQUIRE(txt->common.rdtype == dns_rdatatype_txt); - - return (generic_txt_next(txt)); -} - -isc_result_t -dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { - - REQUIRE(txt != NULL); - REQUIRE(txt->common.rdtype == dns_rdatatype_txt); - - return (generic_txt_current(txt, string)); -} -#endif /* RDATA_GENERIC_TXT_16_C */ diff --git a/lib/dns-pkcs11/rdata/generic/txt_16.h b/lib/dns-pkcs11/rdata/generic/txt_16.h deleted file mode 100644 index cdb0c21..0000000 --- a/lib/dns-pkcs11/rdata/generic/txt_16.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef GENERIC_TXT_16_H -#define GENERIC_TXT_16_H 1 - - -typedef struct dns_rdata_txt_string { - uint8_t length; - unsigned char *data; -} dns_rdata_txt_string_t; - -typedef struct dns_rdata_txt { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *txt; - uint16_t txt_len; - /* private */ - uint16_t offset; -} dns_rdata_txt_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ - -isc_result_t -dns_rdata_txt_first(dns_rdata_txt_t *); - -isc_result_t -dns_rdata_txt_next(dns_rdata_txt_t *); - -isc_result_t -dns_rdata_txt_current(dns_rdata_txt_t *, dns_rdata_txt_string_t *); - -#endif /* GENERIC_TXT_16_H */ diff --git a/lib/dns-pkcs11/rdata/generic/uri_256.c b/lib/dns-pkcs11/rdata/generic/uri_256.c deleted file mode 100644 index 36f95bd..0000000 --- a/lib/dns-pkcs11/rdata/generic/uri_256.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef GENERIC_URI_256_C -#define GENERIC_URI_256_C 1 - -#define RRTYPE_URI_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_uri(ARGS_FROMTEXT) { - isc_token_t token; - - REQUIRE(type == dns_rdatatype_uri); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Priority - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Weight - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Target URI - */ - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_qstring, false)); - if (token.type != isc_tokentype_qstring) - RETTOK(DNS_R_SYNTAX); - RETTOK(multitxt_fromtext(&token.value.as_textregion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_uri(ARGS_TOTEXT) { - isc_region_t region; - unsigned short priority, weight; - char buf[sizeof("65000 ")]; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_uri); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - - /* - * Priority - */ - priority = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u ", priority); - RETERR(str_totext(buf, target)); - - /* - * Weight - */ - weight = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u ", weight); - RETERR(str_totext(buf, target)); - - /* - * Target URI - */ - RETERR(multitxt_totext(®ion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_uri(ARGS_FROMWIRE) { - isc_region_t region; - - REQUIRE(type == dns_rdatatype_uri); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - /* - * Priority, weight - */ - isc_buffer_activeregion(source, ®ion); - if (region.length < 4) - return (ISC_R_UNEXPECTEDEND); - - /* - * Priority, weight and target URI - */ - isc_buffer_forward(source, region.length); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline isc_result_t -towire_uri(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_uri); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, ®ion); - return (mem_tobuffer(target, region.base, region.length)); -} - -static inline int -compare_uri(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_uri); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - - /* - * Priority - */ - order = memcmp(r1.base, r2.base, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(&r1, 2); - isc_region_consume(&r2, 2); - - /* - * Weight - */ - order = memcmp(r1.base, r2.base, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(&r1, 2); - isc_region_consume(&r2, 2); - - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_uri(ARGS_FROMSTRUCT) { - dns_rdata_uri_t *uri; - - REQUIRE(type == dns_rdatatype_uri); - REQUIRE(((dns_rdata_uri_t *)source) != NULL); - REQUIRE(((dns_rdata_uri_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_uri_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_uri_t *)source)->target != NULL); - REQUIRE(((dns_rdata_uri_t *)source)->tgt_len != 0); - - uri = source; - - UNUSED(type); - UNUSED(rdclass); - - /* - * Priority - */ - RETERR(uint16_tobuffer(uri->priority, target)); - - /* - * Weight - */ - RETERR(uint16_tobuffer(uri->weight, target)); - - /* - * Target URI - */ - return (mem_tobuffer(target, uri->target, uri->tgt_len)); -} - -static inline isc_result_t -tostruct_uri(ARGS_TOSTRUCT) { - dns_rdata_uri_t *uri; - isc_region_t sr; - - REQUIRE(((dns_rdata_uri_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_uri); - REQUIRE(rdata->length != 0); - - uri = target; - - uri->common.rdclass = rdata->rdclass; - uri->common.rdtype = rdata->type; - ISC_LINK_INIT(&uri->common, link); - - dns_rdata_toregion(rdata, &sr); - - /* - * Priority - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - uri->priority = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Weight - */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - uri->weight = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* - * Target URI - */ - uri->tgt_len = sr.length; - uri->target = mem_maybedup(mctx, sr.base, sr.length); - if (uri->target == NULL) - return (ISC_R_NOMEMORY); - - uri->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_uri(ARGS_FREESTRUCT) { - dns_rdata_uri_t *uri; - - REQUIRE(((dns_rdata_uri_t *)source) != NULL); - REQUIRE(((dns_rdata_uri_t *)source)->common.rdtype == - dns_rdatatype_uri); - - uri = (dns_rdata_uri_t *) source; - - if (uri->mctx == NULL) - return; - - if (uri->target != NULL) - isc_mem_free(uri->mctx, uri->target); - uri->mctx = NULL; -} - -static inline isc_result_t -additionaldata_uri(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_uri); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_uri(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_uri); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_uri(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_uri); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_uri(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_uri); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_uri(ARGS_COMPARE) { - return (compare_uri(rdata1, rdata2)); -} - -#endif /* GENERIC_URI_256_C */ diff --git a/lib/dns-pkcs11/rdata/generic/uri_256.h b/lib/dns-pkcs11/rdata/generic/uri_256.h deleted file mode 100644 index 4b8871e..0000000 --- a/lib/dns-pkcs11/rdata/generic/uri_256.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_URI_256_H -#define GENERIC_URI_256_H 1 - - -typedef struct dns_rdata_uri { - dns_rdatacommon_t common; - isc_mem_t * mctx; - uint16_t priority; - uint16_t weight; - unsigned char * target; - uint16_t tgt_len; -} dns_rdata_uri_t; - -#endif /* GENERIC_URI_256_H */ diff --git a/lib/dns-pkcs11/rdata/generic/x25_19.c b/lib/dns-pkcs11/rdata/generic/x25_19.c deleted file mode 100644 index 667c37f..0000000 --- a/lib/dns-pkcs11/rdata/generic/x25_19.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1183 */ - -#ifndef RDATA_GENERIC_X25_19_C -#define RDATA_GENERIC_X25_19_C - -#define RRTYPE_X25_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_x25(ARGS_FROMTEXT) { - isc_token_t token; - unsigned int i; - - REQUIRE(type == dns_rdatatype_x25); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - false)); - if (token.value.as_textregion.length < 4) - RETTOK(DNS_R_SYNTAX); - for (i = 0; i < token.value.as_textregion.length; i++) - if (!isdigit(token.value.as_textregion.base[i] & 0xff)) - RETTOK(ISC_R_RANGE); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_x25(ARGS_TOTEXT) { - isc_region_t region; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_x25); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - return (txt_totext(®ion, true, target)); -} - -static inline isc_result_t -fromwire_x25(ARGS_FROMWIRE) { - isc_region_t sr; - unsigned int i; - - REQUIRE(type == dns_rdatatype_x25); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 5 || sr.base[0] != (sr.length - 1)) { - return (DNS_R_FORMERR); - } - for (i = 1; i < sr.length; i++) { - if (sr.base[i] < 0x30 || sr.base[i] > 0x39) { - return (DNS_R_FORMERR); - } - } - return (txt_fromwire(source, target)); -} - -static inline isc_result_t -towire_x25(ARGS_TOWIRE) { - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_x25); - REQUIRE(rdata->length != 0); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_x25(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_x25); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_x25(ARGS_FROMSTRUCT) { - dns_rdata_x25_t *x25; - uint8_t i; - - REQUIRE(type == dns_rdatatype_x25); - REQUIRE(((dns_rdata_x25_t *)source) != NULL); - REQUIRE(((dns_rdata_x25_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_x25_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_x25_t *)source)->x25 != NULL); - REQUIRE(((dns_rdata_x25_t *)source)->x25_len != 0); - - x25 = source; - - UNUSED(type); - UNUSED(rdclass); - - if (x25->x25_len < 4) - return (ISC_R_RANGE); - - for (i = 0; i < x25->x25_len; i++) - if (!isdigit(x25->x25[i] & 0xff)) - return (ISC_R_RANGE); - - RETERR(uint8_tobuffer(x25->x25_len, target)); - return (mem_tobuffer(target, x25->x25, x25->x25_len)); -} - -static inline isc_result_t -tostruct_x25(ARGS_TOSTRUCT) { - dns_rdata_x25_t *x25; - isc_region_t r; - - REQUIRE(((dns_rdata_x25_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_x25); - REQUIRE(rdata->length != 0); - - x25 = target; - - x25->common.rdclass = rdata->rdclass; - x25->common.rdtype = rdata->type; - ISC_LINK_INIT(&x25->common, link); - - dns_rdata_toregion(rdata, &r); - x25->x25_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - x25->x25 = mem_maybedup(mctx, r.base, x25->x25_len); - if (x25->x25 == NULL) - return (ISC_R_NOMEMORY); - - x25->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_x25(ARGS_FREESTRUCT) { - dns_rdata_x25_t *x25; - - REQUIRE(((dns_rdata_x25_t *)source) != NULL); - REQUIRE(((dns_rdata_x25_t *)source)->common.rdtype == - dns_rdatatype_x25); - - x25 = source; - - if (x25->mctx == NULL) - return; - - if (x25->x25 != NULL) - isc_mem_free(x25->mctx, x25->x25); - x25->mctx = NULL; -} - -static inline isc_result_t -additionaldata_x25(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_x25); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_x25(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_x25); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_x25(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_x25); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_x25(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_x25); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_x25(ARGS_COMPARE) { - return (compare_x25(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_X25_19_C */ diff --git a/lib/dns-pkcs11/rdata/generic/x25_19.h b/lib/dns-pkcs11/rdata/generic/x25_19.h deleted file mode 100644 index b308176..0000000 --- a/lib/dns-pkcs11/rdata/generic/x25_19.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_X25_19_H -#define GENERIC_X25_19_H 1 - - -/*! - * \brief Per RFC1183 */ - -typedef struct dns_rdata_x25 { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *x25; - uint8_t x25_len; -} dns_rdata_x25_t; - -#endif /* GENERIC_X25_19_H */ diff --git a/lib/dns-pkcs11/rdata/generic/zonemd_63.c b/lib/dns-pkcs11/rdata/generic/zonemd_63.c deleted file mode 100644 index 7026fde..0000000 --- a/lib/dns-pkcs11/rdata/generic/zonemd_63.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* draft-wessels-zone-digest-05 */ - -#ifndef RDATA_GENERIC_ZONEMD_63_C -#define RDATA_GENERIC_ZONEMD_63_C - -#define RRTYPE_ZONEMD_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_zonemd(ARGS_FROMTEXT) { - isc_token_t token; - int digest_type, length; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* - * Serial. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); - - /* - * Digest type. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - digest_type = token.value.as_ulong; - RETERR(uint8_tobuffer(digest_type, target)); - - /* - * Reserved. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - RETERR(uint8_tobuffer(token.value.as_ulong, target)); - - /* - * Digest. - */ - switch (digest_type) { - case DNS_ZONEMD_DIGEST_SHA384: - length = ISC_SHA384_DIGESTLENGTH; - break; - default: - length = -2; - break; - } - - return (isc_hex_tobuffer(lexer, target, length)); -} - -static inline isc_result_t -totext_zonemd(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("0123456789")]; - unsigned long num; - - REQUIRE(rdata->length > 6); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - - /* - * Serial. - */ - num = uint32_fromregion(&sr); - isc_region_consume(&sr, 4); - snprintf(buf, sizeof(buf), "%lu", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - /* - * Digest type. - */ - num = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%lu", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - /* - * Reserved. - */ - num = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%lu", num); - RETERR(str_totext(buf, target)); - - /* - * Digest. - */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_hex_totext(&sr, 0, "", target)); - else - RETERR(isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else { - RETERR(str_totext("[omitted]", target)); - } - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext(" )", target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_zonemd(ARGS_FROMWIRE) { - isc_region_t sr; - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - - /* - * If we do not recognize the digest type, only ensure that the digest - * is present at all. - * - * If we do recognize the digest type, ensure that the digest is of the - * correct length. - */ - if (sr.length < 7 || - (sr.base[4] == DNS_ZONEMD_DIGEST_SHA384 && - sr.length < 6 + ISC_SHA384_DIGESTLENGTH)) - { - return (ISC_R_UNEXPECTEDEND); - } - - /* - * Only specify the number of octets to consume if we recognize the - * digest type. - * - * If there is extra data, dns_rdata_fromwire() will detect that. - */ - if (sr.base[4] == DNS_ZONEMD_DIGEST_SHA384) { - sr.length = 6 + ISC_SHA384_DIGESTLENGTH; - } - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_zonemd(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_zonemd); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_zonemd(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_zonemd); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_zonemd(ARGS_FROMSTRUCT) { - dns_rdata_zonemd_t *zonemd; - - REQUIRE(((dns_rdata_zonemd_t *)source) != NULL); - REQUIRE(((dns_rdata_zonemd_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_zonemd_t *)source)->common.rdclass == rdclass); - - zonemd = source; - - UNUSED(type); - UNUSED(rdclass); - - switch (zonemd->digest_type) { - case DNS_ZONEMD_DIGEST_SHA384: - REQUIRE(zonemd->length == ISC_SHA384_DIGESTLENGTH); - break; - } - - RETERR(uint32_tobuffer(zonemd->serial, target)); - RETERR(uint8_tobuffer(zonemd->digest_type, target)); - RETERR(uint8_tobuffer(zonemd->reserved, target)); - - return (mem_tobuffer(target, zonemd->digest, zonemd->length)); -} - -static inline isc_result_t -tostruct_zonemd(ARGS_TOSTRUCT) { - dns_rdata_zonemd_t *zonemd; - isc_region_t region; - - REQUIRE(((dns_rdata_zonemd_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_zonemd); - REQUIRE(rdata->length != 0); - - zonemd = target; - - zonemd->common.rdclass = rdata->rdclass; - zonemd->common.rdtype = rdata->type; - ISC_LINK_INIT(&zonemd->common, link); - - dns_rdata_toregion(rdata, ®ion); - - zonemd->serial = uint32_fromregion(®ion); - isc_region_consume(®ion, 4); - zonemd->digest_type = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - zonemd->reserved = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - zonemd->length = region.length; - - zonemd->digest = mem_maybedup(mctx, region.base, region.length); - if (zonemd->digest == NULL) { - return (ISC_R_NOMEMORY); - } - - zonemd->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_zonemd(ARGS_FREESTRUCT) { - dns_rdata_zonemd_t *zonemd; - - REQUIRE(((dns_rdata_zonemd_t *)source) != NULL); - REQUIRE(((dns_rdata_zonemd_t *)source)->common.rdtype == - dns_rdatatype_zonemd); - - zonemd = source; - - if (zonemd->mctx == NULL) { - return; - } - - if (zonemd->digest != NULL) { - isc_mem_free(zonemd->mctx, zonemd->digest); - } - zonemd->mctx = NULL; -} - -static inline isc_result_t -additionaldata_zonemd(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_zonemd); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_zonemd(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_zonemd); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_zonemd(ARGS_CHECKOWNER) { - REQUIRE(type == dns_rdatatype_zonemd); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_zonemd(ARGS_CHECKNAMES) { - REQUIRE(rdata->type == dns_rdatatype_zonemd); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_zonemd(ARGS_COMPARE) { - return (compare_zonemd(rdata1, rdata2)); -} - -#endif /* RDATA_GENERIC_ZONEMD_63_C */ diff --git a/lib/dns-pkcs11/rdata/generic/zonemd_63.h b/lib/dns-pkcs11/rdata/generic/zonemd_63.h deleted file mode 100644 index ff4e292..0000000 --- a/lib/dns-pkcs11/rdata/generic/zonemd_63.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef GENERIC_ZONEMD_63_H -#define GENERIC_ZONEMD_63_H 1 - -/* Digest type(s). Currently only SHA-384 is defined. */ -#define DNS_ZONEMD_DIGEST_SHA384 (1) - -/* - * \brief per draft-wessels-zone-digest-05 - */ -typedef struct dns_rdata_zonemd { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint32_t serial; - uint8_t digest_type; - uint8_t reserved; - unsigned char *digest; - uint16_t length; -} dns_rdata_zonemd_t; - -#endif /* GENERIC_ZONEMD_63_H */ diff --git a/lib/dns-pkcs11/rdata/hs_4/a_1.c b/lib/dns-pkcs11/rdata/hs_4/a_1.c deleted file mode 100644 index 9a7a2a0..0000000 --- a/lib/dns-pkcs11/rdata/hs_4/a_1.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_HS_4_A_1_C -#define RDATA_HS_4_A_1_C - -#include - -#define RRTYPE_A_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_hs_a(ARGS_FROMTEXT) { - isc_token_t token; - struct in_addr addr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_hs); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) - RETTOK(DNS_R_BADDOTTEDQUAD); - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) - return (ISC_R_NOSPACE); - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_hs_a(ARGS_TOTEXT) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - REQUIRE(rdata->length == 4); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - return (inet_totext(AF_INET, tctx->flags, ®ion, target)); -} - -static inline isc_result_t -fromwire_hs_a(ARGS_FROMWIRE) { - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_hs); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (sregion.length < 4) - return (ISC_R_UNEXPECTEDEND); - if (tregion.length < 4) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 4); - isc_buffer_forward(source, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_hs_a(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - REQUIRE(rdata->length == 4); - - UNUSED(cctx); - - isc_buffer_availableregion(target, ®ion); - if (region.length < rdata->length) - return (ISC_R_NOSPACE); - memmove(region.base, rdata->data, rdata->length); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline int -compare_hs_a(ARGS_COMPARE) { - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_a); - REQUIRE(rdata1->rdclass == dns_rdataclass_hs); - REQUIRE(rdata1->length == 4); - REQUIRE(rdata2->length == 4); - - order = memcmp(rdata1->data, rdata2->data, 4); - if (order != 0) - order = (order < 0) ? -1 : 1; - - return (order); -} - -static inline isc_result_t -fromstruct_hs_a(ARGS_FROMSTRUCT) { - dns_rdata_hs_a_t *a; - uint32_t n; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_hs); - REQUIRE(((dns_rdata_hs_a_t *)source) != NULL); - REQUIRE(((dns_rdata_hs_a_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_hs_a_t *)source)->common.rdclass == rdclass); - - a = source; - - UNUSED(type); - UNUSED(rdclass); - - n = ntohl(a->in_addr.s_addr); - - return (uint32_tobuffer(n, target)); -} - -static inline isc_result_t -tostruct_hs_a(ARGS_TOSTRUCT) { - dns_rdata_hs_a_t *a; - uint32_t n; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - REQUIRE(rdata->length == 4); - REQUIRE(((dns_rdata_hs_a_t *)target) != NULL); - - a = target; - - UNUSED(mctx); - - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); - - dns_rdata_toregion(rdata, ®ion); - n = uint32_fromregion(®ion); - a->in_addr.s_addr = htonl(n); - - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_hs_a(ARGS_FREESTRUCT) { - UNUSED(source); - - REQUIRE(source != NULL); -} - -static inline isc_result_t -additionaldata_hs_a(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_hs_a(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_hs_a(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_hs); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_hs_a(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_hs); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_hs_a(ARGS_COMPARE) { - return (compare_hs_a(rdata1, rdata2)); -} - -#endif /* RDATA_HS_4_A_1_C */ diff --git a/lib/dns-pkcs11/rdata/hs_4/a_1.h b/lib/dns-pkcs11/rdata/hs_4/a_1.h deleted file mode 100644 index 270dd16..0000000 --- a/lib/dns-pkcs11/rdata/hs_4/a_1.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef HS_4_A_1_H -#define HS_4_A_1_H 1 - - -typedef struct dns_rdata_hs_a { - dns_rdatacommon_t common; - struct in_addr in_addr; -} dns_rdata_hs_a_t; - -#endif /* HS_4_A_1_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/a6_38.c b/lib/dns-pkcs11/rdata/in_1/a6_38.c deleted file mode 100644 index ff205e3..0000000 --- a/lib/dns-pkcs11/rdata/in_1/a6_38.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC2874 */ - -#ifndef RDATA_IN_1_A6_28_C -#define RDATA_IN_1_A6_28_C - -#include - -#define RRTYPE_A6_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_a6(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char addr[16]; - unsigned char prefixlen; - unsigned char octets; - unsigned char mask; - dns_name_t name; - isc_buffer_t buffer; - bool ok; - - REQUIRE(type == dns_rdatatype_a6); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Prefix length. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 128U) - RETTOK(ISC_R_RANGE); - - prefixlen = (unsigned char)token.value.as_ulong; - RETERR(mem_tobuffer(target, &prefixlen, 1)); - - /* - * Suffix. - */ - if (prefixlen != 128) { - /* - * Prefix 0..127. - */ - octets = prefixlen/8; - /* - * Octets 0..15. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, - false)); - if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1) - RETTOK(DNS_R_BADAAAA); - mask = 0xff >> (prefixlen % 8); - addr[octets] &= mask; - RETERR(mem_tobuffer(target, &addr[octets], 16 - octets)); - } - - if (prefixlen == 0) - return (ISC_R_SUCCESS); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_a6(ARGS_TOTEXT) { - isc_region_t sr, ar; - unsigned char addr[16]; - unsigned char prefixlen; - unsigned char octets; - unsigned char mask; - char buf[sizeof("128")]; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - prefixlen = sr.base[0]; - INSIST(prefixlen <= 128); - isc_region_consume(&sr, 1); - snprintf(buf, sizeof(buf), "%u", prefixlen); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - if (prefixlen != 128) { - octets = prefixlen/8; - memset(addr, 0, sizeof(addr)); - memmove(&addr[octets], sr.base, 16 - octets); - mask = 0xff >> (prefixlen % 8); - addr[octets] &= mask; - ar.base = addr; - ar.length = sizeof(addr); - RETERR(inet_totext(AF_INET6, tctx->flags, &ar, target)); - isc_region_consume(&sr, 16 - octets); - } - - if (prefixlen == 0) - return (ISC_R_SUCCESS); - - RETERR(str_totext(" ", target)); - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - dns_name_fromregion(&name, &sr); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_a6(ARGS_FROMWIRE) { - isc_region_t sr; - unsigned char prefixlen; - unsigned char octets; - unsigned char mask; - dns_name_t name; - - REQUIRE(type == dns_rdatatype_a6); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - isc_buffer_activeregion(source, &sr); - /* - * Prefix length. - */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - prefixlen = sr.base[0]; - if (prefixlen > 128) - return (ISC_R_RANGE); - isc_region_consume(&sr, 1); - RETERR(mem_tobuffer(target, &prefixlen, 1)); - isc_buffer_forward(source, 1); - - /* - * Suffix. - */ - if (prefixlen != 128) { - octets = 16 - prefixlen / 8; - if (sr.length < octets) - return (ISC_R_UNEXPECTEDEND); - mask = 0xff >> (prefixlen % 8); - if ((sr.base[0] & ~mask) != 0) { - return (DNS_R_FORMERR); - } - RETERR(mem_tobuffer(target, sr.base, octets)); - isc_buffer_forward(source, octets); - } - - if (prefixlen == 0) - return (ISC_R_SUCCESS); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_a6(ARGS_TOWIRE) { - isc_region_t sr; - dns_name_t name; - dns_offsets_t offsets; - unsigned char prefixlen; - unsigned char octets; - - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_rdata_toregion(rdata, &sr); - prefixlen = sr.base[0]; - INSIST(prefixlen <= 128); - - octets = 1 + 16 - prefixlen / 8; - RETERR(mem_tobuffer(target, sr.base, octets)); - isc_region_consume(&sr, octets); - - if (prefixlen == 0) - return (ISC_R_SUCCESS); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_a6(ARGS_COMPARE) { - int order; - unsigned char prefixlen1, prefixlen2; - unsigned char octets; - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_a6); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - prefixlen1 = region1.base[0]; - prefixlen2 = region2.base[0]; - isc_region_consume(®ion1, 1); - isc_region_consume(®ion2, 1); - if (prefixlen1 < prefixlen2) - return (-1); - else if (prefixlen1 > prefixlen2) - return (1); - /* - * Prefix lengths are equal. - */ - octets = 16 - prefixlen1 / 8; - - if (octets > 0) { - order = memcmp(region1.base, region2.base, octets); - if (order < 0) - return (-1); - else if (order > 0) - return (1); - /* - * Address suffixes are equal. - */ - if (prefixlen1 == 0) - return (order); - isc_region_consume(®ion1, octets); - isc_region_consume(®ion2, octets); - } - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_a6(ARGS_FROMSTRUCT) { - dns_rdata_in_a6_t *a6; - isc_region_t region; - int octets; - uint8_t bits; - uint8_t first; - uint8_t mask; - - REQUIRE(type == dns_rdatatype_a6); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_a6_t *)source) != NULL); - REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdclass == rdclass); - - a6 = source; - - UNUSED(type); - UNUSED(rdclass); - - if (a6->prefixlen > 128) - return (ISC_R_RANGE); - - RETERR(uint8_tobuffer(a6->prefixlen, target)); - - /* Suffix */ - if (a6->prefixlen != 128) { - octets = 16 - a6->prefixlen / 8; - bits = a6->prefixlen % 8; - if (bits != 0) { - mask = 0xffU >> bits; - first = a6->in6_addr.s6_addr[16 - octets] & mask; - RETERR(uint8_tobuffer(first, target)); - octets--; - } - if (octets > 0) - RETERR(mem_tobuffer(target, - a6->in6_addr.s6_addr + 16 - octets, - octets)); - } - - if (a6->prefixlen == 0) - return (ISC_R_SUCCESS); - dns_name_toregion(&a6->prefix, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_a6(ARGS_TOSTRUCT) { - dns_rdata_in_a6_t *a6; - unsigned char octets; - dns_name_t name; - isc_region_t r; - - REQUIRE(((dns_rdata_in_a6_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - a6 = target; - - a6->common.rdclass = rdata->rdclass; - a6->common.rdtype = rdata->type; - ISC_LINK_INIT(&a6->common, link); - - dns_rdata_toregion(rdata, &r); - - a6->prefixlen = uint8_fromregion(&r); - isc_region_consume(&r, 1); - memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr)); - - /* - * Suffix. - */ - if (a6->prefixlen != 128) { - octets = 16 - a6->prefixlen / 8; - INSIST(r.length >= octets); - memmove(a6->in6_addr.s6_addr + 16 - octets, r.base, octets); - isc_region_consume(&r, octets); - } - - /* - * Prefix. - */ - dns_name_init(&a6->prefix, NULL); - if (a6->prefixlen != 0) { - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - RETERR(name_duporclone(&name, mctx, &a6->prefix)); - } - a6->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_a6(ARGS_FREESTRUCT) { - dns_rdata_in_a6_t *a6; - - REQUIRE(((dns_rdata_in_a6_t *)source) != NULL); - REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdtype == - dns_rdatatype_a6); - REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdclass == - dns_rdataclass_in); - - a6 = source; - - if (a6->mctx == NULL) - return; - - if (dns_name_dynamic(&a6->prefix)) - dns_name_free(&a6->prefix, a6->mctx); - a6->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_a6(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_a6(ARGS_DIGEST) { - isc_region_t r1, r2; - unsigned char prefixlen, octets; - isc_result_t result; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - prefixlen = r1.base[0]; - octets = 1 + 16 - prefixlen / 8; - - r1.length = octets; - result = (digest)(arg, &r1); - if (result != ISC_R_SUCCESS) - return (result); - if (prefixlen == 0) - return (ISC_R_SUCCESS); - - isc_region_consume(&r2, octets); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_in_a6(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_a6); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_in_a6(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - unsigned int prefixlen; - - REQUIRE(rdata->type == dns_rdatatype_a6); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - prefixlen = uint8_fromregion(®ion); - if (prefixlen == 0) - return (true); - isc_region_consume(®ion, 1 + 16 - prefixlen / 8); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_in_a6(ARGS_COMPARE) { - return (compare_in_a6(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_A6_38_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/a6_38.h b/lib/dns-pkcs11/rdata/in_1/a6_38.h deleted file mode 100644 index 901936b..0000000 --- a/lib/dns-pkcs11/rdata/in_1/a6_38.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_A6_38_H -#define IN_1_A6_38_H 1 - - -/*! - * \brief Per RFC2874 */ - -typedef struct dns_rdata_in_a6 { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t prefix; - uint8_t prefixlen; - struct in6_addr in6_addr; -} dns_rdata_in_a6_t; - -#endif /* IN_1_A6_38_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/a_1.c b/lib/dns-pkcs11/rdata/in_1/a_1.c deleted file mode 100644 index f664d64..0000000 --- a/lib/dns-pkcs11/rdata/in_1/a_1.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_IN_1_A_1_C -#define RDATA_IN_1_A_1_C - -#include - -#include - -#define RRTYPE_A_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_a(ARGS_FROMTEXT) { - isc_token_t token; - struct in_addr addr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) - RETTOK(DNS_R_BADDOTTEDQUAD); - isc_buffer_availableregion(target, ®ion); - if (region.length < 4) - return (ISC_R_NOSPACE); - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_a(ARGS_TOTEXT) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 4); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - return (inet_totext(AF_INET, tctx->flags, ®ion, target)); -} - -static inline isc_result_t -fromwire_in_a(ARGS_FROMWIRE) { - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (sregion.length < 4) - return (ISC_R_UNEXPECTEDEND); - if (tregion.length < 4) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 4); - isc_buffer_forward(source, 4); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_a(ARGS_TOWIRE) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 4); - - UNUSED(cctx); - - isc_buffer_availableregion(target, ®ion); - if (region.length < rdata->length) - return (ISC_R_NOSPACE); - memmove(region.base, rdata->data, rdata->length); - isc_buffer_add(target, 4); - return (ISC_R_SUCCESS); -} - -static inline int -compare_in_a(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_a); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length == 4); - REQUIRE(rdata2->length == 4); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_a(ARGS_FROMSTRUCT) { - dns_rdata_in_a_t *a; - uint32_t n; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_a_t *)source) != NULL); - REQUIRE(((dns_rdata_in_a_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_a_t *)source)->common.rdclass == rdclass); - - a = source; - - UNUSED(type); - UNUSED(rdclass); - - n = ntohl(a->in_addr.s_addr); - - return (uint32_tobuffer(n, target)); -} - - -static inline isc_result_t -tostruct_in_a(ARGS_TOSTRUCT) { - dns_rdata_in_a_t *a; - uint32_t n; - isc_region_t region; - - REQUIRE(((dns_rdata_in_a_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 4); - - a = target; - - UNUSED(mctx); - - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); - - dns_rdata_toregion(rdata, ®ion); - n = uint32_fromregion(®ion); - a->in_addr.s_addr = htonl(n); - - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_a(ARGS_FREESTRUCT) { - dns_rdata_in_a_t *a; - - REQUIRE(((dns_rdata_in_a_t *)source) != NULL); - REQUIRE(((dns_rdata_in_a_t *)source)->common.rdtype == dns_rdatatype_a); - REQUIRE(((dns_rdata_in_a_t *)source)->common.rdclass == - dns_rdataclass_in); - - a = source; - - UNUSED(a); -} - -static inline isc_result_t -additionaldata_in_a(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_a(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_a(ARGS_CHECKOWNER) { - dns_name_t prefix, suffix; - - REQUIRE(type == dns_rdatatype_a); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - /* - * Handle Active Directory gc._msdcs. name. - */ - if (dns_name_countlabels(name) > 2U) { - dns_name_init(&prefix, NULL); - dns_name_init(&suffix, NULL); - dns_name_split(name, dns_name_countlabels(name) - 2, - &prefix, &suffix); - if (dns_name_equal(&gc_msdcs, &prefix) && - dns_name_ishostname(&suffix, false)) - return (true); - } - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_in_a(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_a); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_a(ARGS_COMPARE) { - return (compare_in_a(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_A_1_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/a_1.h b/lib/dns-pkcs11/rdata/in_1/a_1.h deleted file mode 100644 index 3b5489a..0000000 --- a/lib/dns-pkcs11/rdata/in_1/a_1.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef IN_1_A_1_H -#define IN_1_A_1_H 1 - - -typedef struct dns_rdata_in_a { - dns_rdatacommon_t common; - struct in_addr in_addr; -} dns_rdata_in_a_t; - -#endif /* IN_1_A_1_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/aaaa_28.c b/lib/dns-pkcs11/rdata/in_1/aaaa_28.c deleted file mode 100644 index 416c5f6..0000000 --- a/lib/dns-pkcs11/rdata/in_1/aaaa_28.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1886 */ - -#ifndef RDATA_IN_1_AAAA_28_C -#define RDATA_IN_1_AAAA_28_C - -#include - -#define RRTYPE_AAAA_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_aaaa(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char addr[16]; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_aaaa); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1) - RETTOK(DNS_R_BADAAAA); - isc_buffer_availableregion(target, ®ion); - if (region.length < 16) - return (ISC_R_NOSPACE); - memmove(region.base, addr, 16); - isc_buffer_add(target, 16); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_aaaa(ARGS_TOTEXT) { - isc_region_t region; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 16); - - dns_rdata_toregion(rdata, ®ion); - return (inet_totext(AF_INET6, tctx->flags, ®ion, target)); -} - -static inline isc_result_t -fromwire_in_aaaa(ARGS_FROMWIRE) { - isc_region_t sregion; - isc_region_t tregion; - - REQUIRE(type == dns_rdatatype_aaaa); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, &sregion); - isc_buffer_availableregion(target, &tregion); - if (sregion.length < 16) - return (ISC_R_UNEXPECTEDEND); - if (tregion.length < 16) - return (ISC_R_NOSPACE); - - memmove(tregion.base, sregion.base, 16); - isc_buffer_forward(source, 16); - isc_buffer_add(target, 16); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_aaaa(ARGS_TOWIRE) { - isc_region_t region; - - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 16); - - isc_buffer_availableregion(target, ®ion); - if (region.length < rdata->length) - return (ISC_R_NOSPACE); - memmove(region.base, rdata->data, rdata->length); - isc_buffer_add(target, 16); - return (ISC_R_SUCCESS); -} - -static inline int -compare_in_aaaa(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_aaaa); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length == 16); - REQUIRE(rdata2->length == 16); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_aaaa(ARGS_FROMSTRUCT) { - dns_rdata_in_aaaa_t *aaaa; - - REQUIRE(type == dns_rdatatype_aaaa); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_aaaa_t *)source) != NULL); - REQUIRE(((dns_rdata_in_aaaa_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_aaaa_t *)source)->common.rdclass == rdclass); - - aaaa = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, aaaa->in6_addr.s6_addr, 16)); -} - -static inline isc_result_t -tostruct_in_aaaa(ARGS_TOSTRUCT) { - dns_rdata_in_aaaa_t *aaaa; - isc_region_t r; - - REQUIRE(((dns_rdata_in_aaaa_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length == 16); - - aaaa = target; - - UNUSED(mctx); - - aaaa->common.rdclass = rdata->rdclass; - aaaa->common.rdtype = rdata->type; - ISC_LINK_INIT(&aaaa->common, link); - - dns_rdata_toregion(rdata, &r); - INSIST(r.length == 16); - memmove(aaaa->in6_addr.s6_addr, r.base, 16); - - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_aaaa(ARGS_FREESTRUCT) { - dns_rdata_in_aaaa_t *aaaa; - - REQUIRE(((dns_rdata_in_aaaa_t *)source) != NULL); - REQUIRE(((dns_rdata_in_aaaa_t *)source)->common.rdtype == - dns_rdatatype_aaaa); - REQUIRE(((dns_rdata_in_aaaa_t *)source)->common.rdclass == - dns_rdataclass_in); - - aaaa = source; - - UNUSED(aaaa); -} - -static inline isc_result_t -additionaldata_in_aaaa(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_aaaa(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_aaaa(ARGS_CHECKOWNER) { - dns_name_t prefix, suffix; - - REQUIRE(type == dns_rdatatype_aaaa); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - /* - * Handle Active Directory gc._msdcs. name. - */ - if (dns_name_countlabels(name) > 2U) { - dns_name_init(&prefix, NULL); - dns_name_init(&suffix, NULL); - dns_name_split(name, dns_name_countlabels(name) - 2, - &prefix, &suffix); - if (dns_name_equal(&gc_msdcs, &prefix) && - dns_name_ishostname(&suffix, false)) - return (true); - } - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_in_aaaa(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_aaaa); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_aaaa(ARGS_COMPARE) { - return (compare_in_aaaa(rdata1, rdata2)); -} -#endif /* RDATA_IN_1_AAAA_28_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/aaaa_28.h b/lib/dns-pkcs11/rdata/in_1/aaaa_28.h deleted file mode 100644 index 821a559..0000000 --- a/lib/dns-pkcs11/rdata/in_1/aaaa_28.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_AAAA_28_H -#define IN_1_AAAA_28_H 1 - - -/*! - * \brief Per RFC1886 */ - -typedef struct dns_rdata_in_aaaa { - dns_rdatacommon_t common; - struct in6_addr in6_addr; -} dns_rdata_in_aaaa_t; - -#endif /* IN_1_AAAA_28_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/apl_42.c b/lib/dns-pkcs11/rdata/in_1/apl_42.c deleted file mode 100644 index 82b2841..0000000 --- a/lib/dns-pkcs11/rdata/in_1/apl_42.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC3123 */ - -#ifndef RDATA_IN_1_APL_42_C -#define RDATA_IN_1_APL_42_C - -#define RRTYPE_APL_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_apl(ARGS_FROMTEXT) { - isc_token_t token; - unsigned char addr[16]; - unsigned long afi; - uint8_t prefix; - uint8_t len; - bool neg; - char *cp, *ap, *slash; - int n; - - REQUIRE(type == dns_rdatatype_apl); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - do { - RETERR(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, true)); - if (token.type != isc_tokentype_string) - break; - - cp = DNS_AS_STR(token); - neg = (*cp == '!'); - if (neg) - cp++; - afi = strtoul(cp, &ap, 10); - if (*ap++ != ':' || cp == ap) - RETTOK(DNS_R_SYNTAX); - if (afi > 0xffffU) - RETTOK(ISC_R_RANGE); - slash = strchr(ap, '/'); - if (slash == NULL || slash == ap) - RETTOK(DNS_R_SYNTAX); - RETTOK(isc_parse_uint8(&prefix, slash + 1, 10)); - switch (afi) { - case 1: - *slash = '\0'; - n = inet_pton(AF_INET, ap, addr); - *slash = '/'; - if (n != 1) - RETTOK(DNS_R_BADDOTTEDQUAD); - if (prefix > 32) - RETTOK(ISC_R_RANGE); - for (len = 4; len > 0; len--) - if (addr[len - 1] != 0) - break; - break; - - case 2: - *slash = '\0'; - n = inet_pton(AF_INET6, ap, addr); - *slash = '/'; - if (n != 1) - RETTOK(DNS_R_BADAAAA); - if (prefix > 128) - RETTOK(ISC_R_RANGE); - for (len = 16; len > 0; len--) - if (addr[len - 1] != 0) - break; - break; - - default: - RETTOK(ISC_R_NOTIMPLEMENTED); - } - RETERR(uint16_tobuffer(afi, target)); - RETERR(uint8_tobuffer(prefix, target)); - RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target)); - RETERR(mem_tobuffer(target, addr, len)); - } while (1); - - /* - * Let upper layer handle eol/eof. - */ - isc_lex_ungettoken(lexer, &token); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_apl(ARGS_TOTEXT) { - isc_region_t sr; - isc_region_t ir; - uint16_t afi; - uint8_t prefix; - uint8_t len; - bool neg; - unsigned char buf[16]; - char txt[sizeof(" !64000:")]; - const char *sep = ""; - int n; - - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, &sr); - ir.base = buf; - ir.length = sizeof(buf); - - while (sr.length > 0) { - INSIST(sr.length >= 4); - afi = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - prefix = *sr.base; - isc_region_consume(&sr, 1); - len = (*sr.base & 0x7f); - neg = (*sr.base & 0x80); - isc_region_consume(&sr, 1); - INSIST(len <= sr.length); - n = snprintf(txt, sizeof(txt), "%s%s%u:", sep, - neg ? "!" : "", afi); - INSIST(n < (int)sizeof(txt)); - RETERR(str_totext(txt, target)); - switch (afi) { - case 1: - INSIST(len <= 4); - INSIST(prefix <= 32); - memset(buf, 0, sizeof(buf)); - memmove(buf, sr.base, len); - RETERR(inet_totext(AF_INET, tctx->flags, &ir, target)); - break; - - case 2: - INSIST(len <= 16); - INSIST(prefix <= 128); - memset(buf, 0, sizeof(buf)); - memmove(buf, sr.base, len); - RETERR(inet_totext(AF_INET6, tctx->flags, &ir, target)); - break; - - default: - return (ISC_R_NOTIMPLEMENTED); - } - n = snprintf(txt, sizeof(txt), "/%u", prefix); - INSIST(n < (int)sizeof(txt)); - RETERR(str_totext(txt, target)); - isc_region_consume(&sr, len); - sep = " "; - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_apl(ARGS_FROMWIRE) { - isc_region_t sr, sr2; - isc_region_t tr; - uint16_t afi; - uint8_t prefix; - uint8_t len; - - REQUIRE(type == dns_rdatatype_apl); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(rdclass); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - isc_buffer_availableregion(target, &tr); - if (sr.length > tr.length) - return (ISC_R_NOSPACE); - sr2 = sr; - - /* Zero or more items */ - while (sr.length > 0) { - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - afi = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - prefix = *sr.base; - isc_region_consume(&sr, 1); - len = (*sr.base & 0x7f); - isc_region_consume(&sr, 1); - if (len > sr.length) - return (ISC_R_UNEXPECTEDEND); - switch (afi) { - case 1: - if (prefix > 32 || len > 4) - return (ISC_R_RANGE); - break; - case 2: - if (prefix > 128 || len > 16) - return (ISC_R_RANGE); - } - if (len > 0 && sr.base[len - 1] == 0) - return (DNS_R_FORMERR); - isc_region_consume(&sr, len); - } - isc_buffer_forward(source, sr2.length); - return (mem_tobuffer(target, sr2.base, sr2.length)); -} - -static inline isc_result_t -towire_in_apl(ARGS_TOWIRE) { - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_in_apl(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_apl); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_apl(ARGS_FROMSTRUCT) { - dns_rdata_in_apl_t *apl; - isc_buffer_t b; - - REQUIRE(type == dns_rdatatype_apl); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_apl_t *)source) != NULL); - REQUIRE(((dns_rdata_in_apl_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_apl_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_apl_t *)source)->apl != NULL || - ((dns_rdata_in_apl_t *)source)->apl_len == 0); - - apl = source; - - isc_buffer_init(&b, apl->apl, apl->apl_len); - isc_buffer_add(&b, apl->apl_len); - isc_buffer_setactive(&b, apl->apl_len); - return(fromwire_in_apl(rdclass, type, &b, NULL, false, target)); -} - -static inline isc_result_t -tostruct_in_apl(ARGS_TOSTRUCT) { - dns_rdata_in_apl_t *apl; - isc_region_t r; - - REQUIRE(((dns_rdata_in_apl_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - apl = target; - - apl->common.rdclass = rdata->rdclass; - apl->common.rdtype = rdata->type; - ISC_LINK_INIT(&apl->common, link); - - dns_rdata_toregion(rdata, &r); - apl->apl_len = r.length; - apl->apl = mem_maybedup(mctx, r.base, r.length); - if (apl->apl == NULL) - return (ISC_R_NOMEMORY); - - apl->offset = 0; - apl->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_apl(ARGS_FREESTRUCT) { - dns_rdata_in_apl_t *apl; - - REQUIRE(((dns_rdata_in_apl_t *)source) != NULL); - REQUIRE(((dns_rdata_in_apl_t *)source)->common.rdtype == - dns_rdatatype_apl); - REQUIRE(((dns_rdata_in_apl_t *)source)->common.rdclass == - dns_rdataclass_in); - - apl = source; - - if (apl->mctx == NULL) - return; - if (apl->apl != NULL) - isc_mem_free(apl->mctx, apl->apl); - apl->mctx = NULL; -} - -isc_result_t -dns_rdata_apl_first(dns_rdata_in_apl_t *apl) { - uint32_t length; - - REQUIRE(apl != NULL); - REQUIRE(apl->common.rdtype == dns_rdatatype_apl); - REQUIRE(apl->common.rdclass == dns_rdataclass_in); - REQUIRE(apl->apl != NULL || apl->apl_len == 0); - - /* - * If no APL return ISC_R_NOMORE. - */ - if (apl->apl == NULL) - return (ISC_R_NOMORE); - - /* - * Sanity check data. - */ - INSIST(apl->apl_len > 3U); - length = apl->apl[apl->offset + 3] & 0x7f; - INSIST(4 + length <= apl->apl_len); - - apl->offset = 0; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdata_apl_next(dns_rdata_in_apl_t *apl) { - uint32_t length; - - REQUIRE(apl != NULL); - REQUIRE(apl->common.rdtype == dns_rdatatype_apl); - REQUIRE(apl->common.rdclass == dns_rdataclass_in); - REQUIRE(apl->apl != NULL || apl->apl_len == 0); - - /* - * No APL or have already reached the end return ISC_R_NOMORE. - */ - if (apl->apl == NULL || apl->offset == apl->apl_len) - return (ISC_R_NOMORE); - - /* - * Sanity check data. - */ - INSIST(apl->offset < apl->apl_len); - INSIST(apl->apl_len > 3U); - INSIST(apl->offset <= apl->apl_len - 4U); - length = apl->apl[apl->offset + 3] & 0x7f; - /* - * 16 to 32 bits promotion as 'length' is 32 bits so there is - * no overflow problems. - */ - INSIST(4 + length + apl->offset <= apl->apl_len); - - apl->offset += 4 + length; - return ((apl->offset < apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE); -} - -isc_result_t -dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) { - uint32_t length; - - REQUIRE(apl != NULL); - REQUIRE(apl->common.rdtype == dns_rdatatype_apl); - REQUIRE(apl->common.rdclass == dns_rdataclass_in); - REQUIRE(ent != NULL); - REQUIRE(apl->apl != NULL || apl->apl_len == 0); - REQUIRE(apl->offset <= apl->apl_len); - - if (apl->offset == apl->apl_len) - return (ISC_R_NOMORE); - - /* - * Sanity check data. - */ - INSIST(apl->apl_len > 3U); - INSIST(apl->offset <= apl->apl_len - 4U); - length = (apl->apl[apl->offset + 3] & 0x7f); - /* - * 16 to 32 bits promotion as 'length' is 32 bits so there is - * no overflow problems. - */ - INSIST(4 + length + apl->offset <= apl->apl_len); - - ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1]; - ent->prefix = apl->apl[apl->offset + 2]; - ent->length = length; - ent->negative = (apl->apl[apl->offset + 3] & 0x80); - if (ent->length != 0) - ent->data = &apl->apl[apl->offset + 4]; - else - ent->data = NULL; - return (ISC_R_SUCCESS); -} - -unsigned int -dns_rdata_apl_count(const dns_rdata_in_apl_t *apl) { - return (apl->apl_len); -} - -static inline isc_result_t -additionaldata_in_apl(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - (void)add; - (void)arg; - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_apl(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_apl(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_apl); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - - -static inline bool -checknames_in_apl(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_apl); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_apl(ARGS_COMPARE) { - return (compare_in_apl(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_APL_42_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/apl_42.h b/lib/dns-pkcs11/rdata/in_1/apl_42.h deleted file mode 100644 index a6eaeda..0000000 --- a/lib/dns-pkcs11/rdata/in_1/apl_42.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef IN_1_APL_42_H -#define IN_1_APL_42_H 1 - - -typedef struct dns_rdata_apl_ent { - bool negative; - uint16_t family; - uint8_t prefix; - uint8_t length; - unsigned char *data; -} dns_rdata_apl_ent_t; - -typedef struct dns_rdata_in_apl { - dns_rdatacommon_t common; - isc_mem_t *mctx; - /* type & class specific elements */ - unsigned char *apl; - uint16_t apl_len; - /* private */ - uint16_t offset; -} dns_rdata_in_apl_t; - -/* - * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done - * via rdatastructpre.h and rdatastructsuf.h. - */ - -isc_result_t -dns_rdata_apl_first(dns_rdata_in_apl_t *); - -isc_result_t -dns_rdata_apl_next(dns_rdata_in_apl_t *); - -isc_result_t -dns_rdata_apl_current(dns_rdata_in_apl_t *, dns_rdata_apl_ent_t *); - -unsigned int -dns_rdata_apl_count(const dns_rdata_in_apl_t *apl); - -#endif /* IN_1_APL_42_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/atma_34.c b/lib/dns-pkcs11/rdata/in_1/atma_34.c deleted file mode 100644 index 28b1f63..0000000 --- a/lib/dns-pkcs11/rdata/in_1/atma_34.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* http://www.broadband-forum.org/ftp/pub/approved-specs/af-dans-0152.000.pdf */ - -#ifndef RDATA_IN_1_ATMA_22_C -#define RDATA_IN_1_ATMA_22_C - -#define RRTYPE_ATMA_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_atma(ARGS_FROMTEXT) { - isc_token_t token; - isc_textregion_t *sr; - int n; - bool valid = false; - bool lastwasperiod = true; /* leading periods not allowed */ - int digits = 0; - unsigned char c = 0; - - REQUIRE(type == dns_rdatatype_atma); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - UNUSED(callbacks); - - /* ATM End System Address (AESA) format or E.164 */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - sr = &token.value.as_textregion; - if (sr->length < 1) { - RETTOK(ISC_R_UNEXPECTEDEND); - } - - if (sr->base[0] != '+') { - /* - * Format 0: ATM End System Address (AESA) format. - */ - c = 0; - RETERR(mem_tobuffer(target, &c, 1)); - while (sr->length > 0) { - if (sr->base[0] == '.') { - if (lastwasperiod) { - RETTOK(DNS_R_SYNTAX); - } - isc_textregion_consume(sr, 1); - lastwasperiod = true; - continue; - } - if ((n = hexvalue(sr->base[0])) == -1) { - RETTOK(DNS_R_SYNTAX); - } - c <<= 4; - c += n; - if (++digits == 2) { - RETERR(mem_tobuffer(target, &c, 1)); - valid = true; - digits = 0; - c = 0; - } - isc_textregion_consume(sr, 1); - lastwasperiod = false; - } - if (digits != 0 || !valid || lastwasperiod) { - RETTOK(ISC_R_UNEXPECTEDEND); - } - } else { - /* - * Format 1: E.164. - */ - c = 1; - RETERR(mem_tobuffer(target, &c, 1)); - isc_textregion_consume(sr, 1); - while (sr->length > 0) { - if (sr->base[0] == '.') { - if (lastwasperiod) { - RETTOK(DNS_R_SYNTAX); - } - isc_textregion_consume(sr, 1); - lastwasperiod = true; - continue; - } - if ((sr->base[0] < '0') || (sr->base[0] > '9')) { - RETTOK(DNS_R_SYNTAX); - } - RETERR(mem_tobuffer(target, sr->base, 1)); - isc_textregion_consume(sr, 1); - lastwasperiod = false; - } - if (lastwasperiod) { - RETTOK(ISC_R_UNEXPECTEDEND); - } - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_atma(ARGS_TOTEXT) { - isc_region_t region; - char buf[sizeof("xx")]; - - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - INSIST(region.length > 1); - switch (region.base[0]) { - case 0: - isc_region_consume(®ion, 1); - while (region.length != 0) { - snprintf(buf, sizeof(buf), "%02x", region.base[0]); - isc_region_consume(®ion, 1); - RETERR(str_totext(buf, target)); - } - break; - case 1: - RETERR(str_totext("+", target)); - isc_region_consume(®ion, 1); - RETERR(mem_tobuffer(target, region.base, region.length)); - break; - default: - return (ISC_R_NOTIMPLEMENTED); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_atma(ARGS_FROMWIRE) { - isc_region_t region; - - REQUIRE(type == dns_rdatatype_atma); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 2) { - return (ISC_R_UNEXPECTEDEND); - } - if (region.base[0] == 1) { - unsigned int i; - for (i = 1; i < region.length; i++) { - if (region.base[i] < '0' || region.base[i] > '9') { - return (DNS_R_FORMERR); - } - } - } - RETERR(mem_tobuffer(target, region.base, region.length)); - isc_buffer_forward(source, region.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_atma(ARGS_TOWIRE) { - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_in_atma(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_atma); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_atma(ARGS_FROMSTRUCT) { - dns_rdata_in_atma_t *atma; - - REQUIRE(type == dns_rdatatype_atma); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_atma_t *)source) != NULL); - REQUIRE(((dns_rdata_in_atma_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_atma_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_atma_t *)source)->atma != NULL || - ((dns_rdata_in_atma_t *)source)->atma_len == 0); - - atma = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(mem_tobuffer(target, &atma->format, 1)); - return (mem_tobuffer(target, atma->atma, atma->atma_len)); -} - -static inline isc_result_t -tostruct_in_atma(ARGS_TOSTRUCT) { - dns_rdata_in_atma_t *atma; - isc_region_t r; - - REQUIRE(((dns_rdata_in_atma_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - atma = target; - - atma->common.rdclass = rdata->rdclass; - atma->common.rdtype = rdata->type; - ISC_LINK_INIT(&atma->common, link); - - dns_rdata_toregion(rdata, &r); - atma->format = r.base[0]; - isc_region_consume(&r, 1); - atma->atma_len = r.length; - atma->atma = mem_maybedup(mctx, r.base, r.length); - if (atma->atma == NULL) { - return (ISC_R_NOMEMORY); - } - - atma->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_atma(ARGS_FREESTRUCT) { - dns_rdata_in_atma_t *atma; - - REQUIRE(((dns_rdata_in_atma_t *)source) != NULL); - REQUIRE(((dns_rdata_in_atma_t *)source)->common.rdtype == - dns_rdatatype_atma); - REQUIRE(((dns_rdata_in_atma_t *)source)->common.rdclass == - dns_rdataclass_in); - - atma = source; - - if (atma->mctx == NULL) { - return; - } - - if (atma->atma != NULL) { - isc_mem_free(atma->mctx, atma->atma); - } - atma->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_atma(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_atma(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_atma(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_atma); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_atma(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_atma); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_atma(ARGS_COMPARE) { - return (compare_in_atma(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_atma_22_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/atma_34.h b/lib/dns-pkcs11/rdata/in_1/atma_34.h deleted file mode 100644 index bb5c11d..0000000 --- a/lib/dns-pkcs11/rdata/in_1/atma_34.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_ATMA_22_H -#define IN_1_ATMA_22_H 1 - - -/*! - * \brief Per RFC1706 */ - -typedef struct dns_rdata_in_atma { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char format; - unsigned char *atma; - uint16_t atma_len; -} dns_rdata_in_atma_t; - -#endif /* IN_1_ATMA_22_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/dhcid_49.c b/lib/dns-pkcs11/rdata/in_1/dhcid_49.c deleted file mode 100644 index d685628..0000000 --- a/lib/dns-pkcs11/rdata/in_1/dhcid_49.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* RFC 4701 */ - -#ifndef RDATA_IN_1_DHCID_49_C -#define RDATA_IN_1_DHCID_49_C 1 - -#define RRTYPE_DHCID_ATTRIBUTES 0 - -static inline isc_result_t -fromtext_in_dhcid(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_dhcid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - return (isc_base64_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_in_dhcid(ARGS_TOTEXT) { - isc_region_t sr, sr2; - /* " ; 64000 255 64000" */ - char buf[5 + 3*11 + 1]; - - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - sr2 = sr; - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext("( " /*)*/, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext(/* ( */ " )", target)); - if (rdata->length > 2) { - snprintf(buf, sizeof(buf), " ; %u %u %u", - sr2.base[0] * 256U + sr2.base[1], - sr2.base[2], rdata->length - 3U); - RETERR(str_totext(buf, target)); - } - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_dhcid(ARGS_FROMWIRE) { - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_dhcid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length == 0) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline isc_result_t -towire_in_dhcid(ARGS_TOWIRE) { - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_in_dhcid(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_dhcid); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_dhcid(ARGS_FROMSTRUCT) { - dns_rdata_in_dhcid_t *dhcid; - - REQUIRE(type == dns_rdatatype_dhcid); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_dhcid_t *)source) != NULL); - REQUIRE(((dns_rdata_in_dhcid_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_dhcid_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_dhcid_t *)source)->length != 0); - - dhcid = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, dhcid->dhcid, dhcid->length)); -} - -static inline isc_result_t -tostruct_in_dhcid(ARGS_TOSTRUCT) { - dns_rdata_in_dhcid_t *dhcid; - isc_region_t region; - - REQUIRE(((dns_rdata_in_dhcid_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dhcid = target; - - dhcid->common.rdclass = rdata->rdclass; - dhcid->common.rdtype = rdata->type; - ISC_LINK_INIT(&dhcid->common, link); - - dns_rdata_toregion(rdata, ®ion); - - dhcid->dhcid = mem_maybedup(mctx, region.base, region.length); - if (dhcid->dhcid == NULL) - return (ISC_R_NOMEMORY); - - dhcid->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_dhcid(ARGS_FREESTRUCT) { - dns_rdata_in_dhcid_t *dhcid; - - REQUIRE(((dns_rdata_in_dhcid_t *)source) != NULL); - REQUIRE(((dns_rdata_in_dhcid_t *)source)->common.rdtype == - dns_rdatatype_dhcid); - REQUIRE(((dns_rdata_in_dhcid_t *)source)->common.rdclass == - dns_rdataclass_in); - - dhcid = source; - - if (dhcid->mctx == NULL) - return; - - if (dhcid->dhcid != NULL) - isc_mem_free(dhcid->mctx, dhcid->dhcid); - dhcid->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_dhcid(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_dhcid(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_dhcid(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_dhcid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_dhcid(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_dhcid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_dhcid(ARGS_COMPARE) { - return (compare_in_dhcid(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_DHCID_49_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/dhcid_49.h b/lib/dns-pkcs11/rdata/in_1/dhcid_49.h deleted file mode 100644 index 43e16e4..0000000 --- a/lib/dns-pkcs11/rdata/in_1/dhcid_49.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* */ -#ifndef IN_1_DHCID_49_H -#define IN_1_DHCID_49_H 1 - - -typedef struct dns_rdata_in_dhcid { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *dhcid; - unsigned int length; -} dns_rdata_in_dhcid_t; - -#endif /* IN_1_DHCID_49_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/eid_31.c b/lib/dns-pkcs11/rdata/in_1/eid_31.c deleted file mode 100644 index 6a8176a..0000000 --- a/lib/dns-pkcs11/rdata/in_1/eid_31.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt */ - -#ifndef RDATA_IN_1_EID_31_C -#define RDATA_IN_1_EID_31_C - -#define RRTYPE_EID_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_eid(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_eid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - UNUSED(callbacks); - - return (isc_hex_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_in_eid(ARGS_TOTEXT) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext("( ", target)); - } - if (tctx->width == 0) { - RETERR(isc_hex_totext(®ion, 60, "", target)); - } else { - RETERR(isc_hex_totext(®ion, tctx->width - 2, - tctx->linebreak, target)); - } - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext(" )", target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_eid(ARGS_FROMWIRE) { - isc_region_t region; - - REQUIRE(type == dns_rdatatype_eid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 1) { - return (ISC_R_UNEXPECTEDEND); - } - - RETERR(mem_tobuffer(target, region.base, region.length)); - isc_buffer_forward(source, region.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_eid(ARGS_TOWIRE) { - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_in_eid(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_eid); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_eid(ARGS_FROMSTRUCT) { - dns_rdata_in_eid_t *eid; - - REQUIRE(type == dns_rdatatype_eid); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_eid_t *)source) != NULL); - REQUIRE(((dns_rdata_in_eid_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_eid_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_eid_t *)source)->eid != NULL || - ((dns_rdata_in_eid_t *)source)->eid_len == 0); - - eid = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, eid->eid, eid->eid_len)); -} - -static inline isc_result_t -tostruct_in_eid(ARGS_TOSTRUCT) { - dns_rdata_in_eid_t *eid; - isc_region_t r; - - REQUIRE(((dns_rdata_in_eid_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - eid = target; - - eid->common.rdclass = rdata->rdclass; - eid->common.rdtype = rdata->type; - ISC_LINK_INIT(&eid->common, link); - - dns_rdata_toregion(rdata, &r); - eid->eid_len = r.length; - eid->eid = mem_maybedup(mctx, r.base, r.length); - if (eid->eid == NULL) { - return (ISC_R_NOMEMORY); - } - - eid->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_eid(ARGS_FREESTRUCT) { - dns_rdata_in_eid_t *eid; - - REQUIRE(((dns_rdata_in_eid_t *)source) != NULL); - REQUIRE(((dns_rdata_in_eid_t *)source)->common.rdtype == - dns_rdatatype_eid); - REQUIRE(((dns_rdata_in_eid_t *)source)->common.rdclass == - dns_rdataclass_in); - - eid = source; - - if (eid->mctx == NULL) { - return; - } - - if (eid->eid != NULL) { - isc_mem_free(eid->mctx, eid->eid); - } - eid->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_eid(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_eid(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_eid(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_eid); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_eid(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_eid); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_eid(ARGS_COMPARE) { - return (compare_in_eid(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_EID_31_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/eid_31.h b/lib/dns-pkcs11/rdata/in_1/eid_31.h deleted file mode 100644 index 3d8d625..0000000 --- a/lib/dns-pkcs11/rdata/in_1/eid_31.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_EID_31_H -#define IN_1_EID_31_H 1 - - -/*! - * \brief http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt - */ - -typedef struct dns_rdata_in_eid { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *eid; - uint16_t eid_len; -} dns_rdata_in_eid_t; - -#endif /* IN_1_EID_31_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/kx_36.c b/lib/dns-pkcs11/rdata/in_1/kx_36.c deleted file mode 100644 index c302e65..0000000 --- a/lib/dns-pkcs11/rdata/in_1/kx_36.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2230 */ - -#ifndef RDATA_IN_1_KX_36_C -#define RDATA_IN_1_KX_36_C - -#define RRTYPE_KX_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_kx(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_kx); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_kx(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - - RETERR(str_totext(" ", target)); - - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_kx(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_kx); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - isc_buffer_activeregion(source, &sregion); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sregion.base, 2)); - isc_buffer_forward(source, 2); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_kx(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_rdata_toregion(rdata, ®ion); - RETERR(mem_tobuffer(target, region.base, 2)); - isc_region_consume(®ion, 2); - - dns_name_init(&name, offsets); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_kx(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_kx); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - order = memcmp(rdata1->data, rdata2->data, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_kx(ARGS_FROMSTRUCT) { - dns_rdata_in_kx_t *kx; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_kx); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_kx_t *)source) != NULL); - REQUIRE(((dns_rdata_in_kx_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_kx_t *)source)->common.rdclass == rdclass); - - kx = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(kx->preference, target)); - dns_name_toregion(&kx->exchange, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_kx(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_in_kx_t *kx; - dns_name_t name; - - REQUIRE(((dns_rdata_in_kx_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - kx = target; - - kx->common.rdclass = rdata->rdclass; - kx->common.rdtype = rdata->type; - ISC_LINK_INIT(&kx->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - - kx->preference = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - dns_name_fromregion(&name, ®ion); - dns_name_init(&kx->exchange, NULL); - RETERR(name_duporclone(&name, mctx, &kx->exchange)); - kx->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_kx(ARGS_FREESTRUCT) { - dns_rdata_in_kx_t *kx; - - REQUIRE(((dns_rdata_in_kx_t *)source) != NULL); - REQUIRE(((dns_rdata_in_kx_t *)source)->common.rdtype == - dns_rdatatype_kx); - REQUIRE(((dns_rdata_in_kx_t *)source)->common.rdclass == - dns_rdataclass_in); - - kx = source; - - if (kx->mctx == NULL) - return; - - dns_name_free(&kx->exchange, kx->mctx); - kx->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_kx(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - return ((add)(arg, &name, dns_rdatatype_a)); -} - -static inline isc_result_t -digest_in_kx(ARGS_DIGEST) { - isc_region_t r1, r2; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 2); - r1.length = 2; - RETERR((digest)(arg, &r1)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_in_kx(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_kx); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_kx(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_kx); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_kx(ARGS_COMPARE) { - return (compare_in_kx(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_KX_36_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/kx_36.h b/lib/dns-pkcs11/rdata/in_1/kx_36.h deleted file mode 100644 index 458a137..0000000 --- a/lib/dns-pkcs11/rdata/in_1/kx_36.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_KX_36_H -#define IN_1_KX_36_H 1 - - -/*! - * \brief Per RFC2230 */ - -typedef struct dns_rdata_in_kx { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t preference; - dns_name_t exchange; -} dns_rdata_in_kx_t; - -#endif /* IN_1_KX_36_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/nimloc_32.c b/lib/dns-pkcs11/rdata/in_1/nimloc_32.c deleted file mode 100644 index d2e7db0..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nimloc_32.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt */ - -#ifndef RDATA_IN_1_NIMLOC_32_C -#define RDATA_IN_1_NIMLOC_32_C - -#define RRTYPE_NIMLOC_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_nimloc(ARGS_FROMTEXT) { - - REQUIRE(type == dns_rdatatype_nimloc); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - UNUSED(callbacks); - - return (isc_hex_tobuffer(lexer, target, -2)); -} - -static inline isc_result_t -totext_in_nimloc(ARGS_TOTEXT) { - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, ®ion); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext("( ", target)); - } - if (tctx->width == 0) { - RETERR(isc_hex_totext(®ion, 60, "", target)); - } else { - RETERR(isc_hex_totext(®ion, tctx->width - 2, - tctx->linebreak, target)); - } - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { - RETERR(str_totext(" )", target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_nimloc(ARGS_FROMWIRE) { - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nimloc); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 1) { - return (ISC_R_UNEXPECTEDEND); - } - - RETERR(mem_tobuffer(target, region.base, region.length)); - isc_buffer_forward(source, region.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_nimloc(ARGS_TOWIRE) { - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_in_nimloc(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nimloc); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_nimloc(ARGS_FROMSTRUCT) { - dns_rdata_in_nimloc_t *nimloc; - - REQUIRE(type == dns_rdatatype_nimloc); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_nimloc_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nimloc_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_nimloc_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_nimloc_t *)source)->nimloc != NULL || - ((dns_rdata_in_nimloc_t *)source)->nimloc_len == 0); - - nimloc = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, nimloc->nimloc, nimloc->nimloc_len)); -} - -static inline isc_result_t -tostruct_in_nimloc(ARGS_TOSTRUCT) { - dns_rdata_in_nimloc_t *nimloc; - isc_region_t r; - - REQUIRE(((dns_rdata_in_nimloc_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - nimloc = target; - - nimloc->common.rdclass = rdata->rdclass; - nimloc->common.rdtype = rdata->type; - ISC_LINK_INIT(&nimloc->common, link); - - dns_rdata_toregion(rdata, &r); - nimloc->nimloc_len = r.length; - nimloc->nimloc = mem_maybedup(mctx, r.base, r.length); - if (nimloc->nimloc == NULL) { - return (ISC_R_NOMEMORY); - } - - nimloc->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_nimloc(ARGS_FREESTRUCT) { - dns_rdata_in_nimloc_t *nimloc; - - REQUIRE(((dns_rdata_in_nimloc_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nimloc_t *)source)->common.rdtype == - dns_rdatatype_nimloc); - REQUIRE(((dns_rdata_in_nimloc_t *)source)->common.rdclass == - dns_rdataclass_in); - - nimloc = source; - - if (nimloc->mctx == NULL) { - return; - } - - if (nimloc->nimloc != NULL) { - isc_mem_free(nimloc->mctx, nimloc->nimloc); - } - nimloc->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_nimloc(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_nimloc(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_nimloc(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nimloc); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_nimloc(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nimloc); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_nimloc(ARGS_COMPARE) { - return (compare_in_nimloc(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_NIMLOC_32_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/nimloc_32.h b/lib/dns-pkcs11/rdata/in_1/nimloc_32.h deleted file mode 100644 index ed1d581..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nimloc_32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_NIMLOC_32_H -#define IN_1_NIMLOC_32_H 1 - - -/*! - * \brief http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt - */ - -typedef struct dns_rdata_in_nimloc { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *nimloc; - uint16_t nimloc_len; -} dns_rdata_in_nimloc_t; - -#endif /* IN_1_NIMLOC_32_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.c b/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.c deleted file mode 100644 index 10eafc0..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ - -#ifndef RDATA_IN_1_NSAP_PTR_23_C -#define RDATA_IN_1_NSAP_PTR_23_C - -#define RRTYPE_NSAP_PTR_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_nsap_ptr(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_nsap_ptr); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_nsap_ptr(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - sub = name_prefix(&name, tctx->origin, &prefix); - - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_nsap_ptr(ARGS_FROMWIRE) { - dns_name_t name; - - REQUIRE(type == dns_rdatatype_nsap_ptr); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_nsap_ptr(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_nsap_ptr(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_nsap_ptr(ARGS_FROMSTRUCT) { - dns_rdata_in_nsap_ptr_t *nsap_ptr; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nsap_ptr); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source)->common.rdclass == rdclass); - - nsap_ptr = source; - - UNUSED(type); - UNUSED(rdclass); - - dns_name_toregion(&nsap_ptr->owner, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_nsap_ptr(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_in_nsap_ptr_t *nsap_ptr; - dns_name_t name; - - REQUIRE(((dns_rdata_in_nsap_ptr_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - nsap_ptr = target; - - nsap_ptr->common.rdclass = rdata->rdclass; - nsap_ptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsap_ptr->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - dns_name_init(&nsap_ptr->owner, NULL); - RETERR(name_duporclone(&name, mctx, &nsap_ptr->owner)); - nsap_ptr->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_nsap_ptr(ARGS_FREESTRUCT) { - dns_rdata_in_nsap_ptr_t *nsap_ptr; - - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source)->common.rdtype == - dns_rdatatype_nsap_ptr); - REQUIRE(((dns_rdata_in_nsap_ptr_t *)source)->common.rdclass == - dns_rdataclass_in); - - nsap_ptr = source; - - if (nsap_ptr->mctx == NULL) - return; - - dns_name_free(&nsap_ptr->owner, nsap_ptr->mctx); - nsap_ptr->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_nsap_ptr(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_nsap_ptr(ARGS_DIGEST) { - isc_region_t r; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_in_nsap_ptr(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nsap_ptr); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_nsap_ptr(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_nsap_ptr(ARGS_COMPARE) { - return (compare_in_nsap_ptr(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_NSAP_PTR_23_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.h b/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.h deleted file mode 100644 index da77614..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nsap-ptr_23.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_NSAP_PTR_23_H -#define IN_1_NSAP_PTR_23_H 1 - - -/*! - * \brief Per RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ - -typedef struct dns_rdata_in_nsap_ptr { - dns_rdatacommon_t common; - isc_mem_t *mctx; - dns_name_t owner; -} dns_rdata_in_nsap_ptr_t; - -#endif /* IN_1_NSAP_PTR_23_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/nsap_22.c b/lib/dns-pkcs11/rdata/in_1/nsap_22.c deleted file mode 100644 index 9c977ec..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nsap_22.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC1706 */ - -#ifndef RDATA_IN_1_NSAP_22_C -#define RDATA_IN_1_NSAP_22_C - -#define RRTYPE_NSAP_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_nsap(ARGS_FROMTEXT) { - isc_token_t token; - isc_textregion_t *sr; - int n; - bool valid = false; - int digits = 0; - unsigned char c = 0; - - REQUIRE(type == dns_rdatatype_nsap); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - UNUSED(callbacks); - - /* 0x */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - sr = &token.value.as_textregion; - if (sr->length < 2) - RETTOK(ISC_R_UNEXPECTEDEND); - if (sr->base[0] != '0' || (sr->base[1] != 'x' && sr->base[1] != 'X')) - RETTOK(DNS_R_SYNTAX); - isc_textregion_consume(sr, 2); - while (sr->length > 0) { - if (sr->base[0] == '.') { - isc_textregion_consume(sr, 1); - continue; - } - if ((n = hexvalue(sr->base[0])) == -1) - RETTOK(DNS_R_SYNTAX); - c <<= 4; - c += n; - if (++digits == 2) { - RETERR(mem_tobuffer(target, &c, 1)); - valid = true; - digits = 0; - c = 0; - } - isc_textregion_consume(sr, 1); - } - if (digits != 0 || !valid) - RETTOK(ISC_R_UNEXPECTEDEND); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_nsap(ARGS_TOTEXT) { - isc_region_t region; - char buf[sizeof("xx")]; - - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(tctx); - - dns_rdata_toregion(rdata, ®ion); - RETERR(str_totext("0x", target)); - while (region.length != 0) { - snprintf(buf, sizeof(buf), "%02x", region.base[0]); - isc_region_consume(®ion, 1); - RETERR(str_totext(buf, target)); - } - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_nsap(ARGS_FROMWIRE) { - isc_region_t region; - - REQUIRE(type == dns_rdatatype_nsap); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, ®ion); - if (region.length < 1) - return (ISC_R_UNEXPECTEDEND); - - RETERR(mem_tobuffer(target, region.base, region.length)); - isc_buffer_forward(source, region.length); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_nsap(ARGS_TOWIRE) { - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - UNUSED(cctx); - - return (mem_tobuffer(target, rdata->data, rdata->length)); -} - -static inline int -compare_in_nsap(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_nsap); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_nsap(ARGS_FROMSTRUCT) { - dns_rdata_in_nsap_t *nsap; - - REQUIRE(type == dns_rdatatype_nsap); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_nsap_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nsap_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_nsap_t *)source)->common.rdclass == rdclass); - REQUIRE(((dns_rdata_in_nsap_t *)source)->nsap != NULL || - ((dns_rdata_in_nsap_t *)source)->nsap_len == 0); - - nsap = source; - - UNUSED(type); - UNUSED(rdclass); - - return (mem_tobuffer(target, nsap->nsap, nsap->nsap_len)); -} - -static inline isc_result_t -tostruct_in_nsap(ARGS_TOSTRUCT) { - dns_rdata_in_nsap_t *nsap; - isc_region_t r; - - REQUIRE(((dns_rdata_in_nsap_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - nsap = target; - - nsap->common.rdclass = rdata->rdclass; - nsap->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsap->common, link); - - dns_rdata_toregion(rdata, &r); - nsap->nsap_len = r.length; - nsap->nsap = mem_maybedup(mctx, r.base, r.length); - if (nsap->nsap == NULL) - return (ISC_R_NOMEMORY); - - nsap->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_nsap(ARGS_FREESTRUCT) { - dns_rdata_in_nsap_t *nsap; - - REQUIRE(((dns_rdata_in_nsap_t *)source) != NULL); - REQUIRE(((dns_rdata_in_nsap_t *)source)->common.rdclass == - dns_rdataclass_in); - REQUIRE(((dns_rdata_in_nsap_t *)source)->common.rdtype == - dns_rdatatype_nsap); - - nsap = source; - - if (nsap->mctx == NULL) - return; - - if (nsap->nsap != NULL) - isc_mem_free(nsap->mctx, nsap->nsap); - nsap->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_nsap(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_nsap(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_nsap(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_nsap); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_nsap(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_nsap); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_nsap(ARGS_COMPARE) { - return (compare_in_nsap(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_NSAP_22_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/nsap_22.h b/lib/dns-pkcs11/rdata/in_1/nsap_22.h deleted file mode 100644 index 1efb35c..0000000 --- a/lib/dns-pkcs11/rdata/in_1/nsap_22.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_NSAP_22_H -#define IN_1_NSAP_22_H 1 - - -/*! - * \brief Per RFC1706 */ - -typedef struct dns_rdata_in_nsap { - dns_rdatacommon_t common; - isc_mem_t *mctx; - unsigned char *nsap; - uint16_t nsap_len; -} dns_rdata_in_nsap_t; - -#endif /* IN_1_NSAP_22_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/px_26.c b/lib/dns-pkcs11/rdata/in_1/px_26.c deleted file mode 100644 index d525f71..0000000 --- a/lib/dns-pkcs11/rdata/in_1/px_26.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2163 */ - -#ifndef RDATA_IN_1_PX_26_C -#define RDATA_IN_1_PX_26_C - -#define RRTYPE_PX_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_px(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - - REQUIRE(type == dns_rdatatype_px); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - if (origin == NULL) - origin = dns_rootname; - - /* - * Preference. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * MAP822. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - - /* - * MAPX400. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_px(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - /* - * Preference. - */ - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * MAP822. - */ - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - isc_region_consume(®ion, name_length(&name)); - RETERR(dns_name_totext(&prefix, sub, target)); - RETERR(str_totext(" ", target)); - - /* - * MAPX400. - */ - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return(dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_px(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sregion; - - REQUIRE(type == dns_rdatatype_px); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - /* - * Preference. - */ - isc_buffer_activeregion(source, &sregion); - if (sregion.length < 2) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sregion.base, 2)); - isc_buffer_forward(source, 2); - - /* - * MAP822. - */ - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - - /* - * MAPX400. - */ - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_px(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - /* - * Preference. - */ - dns_rdata_toregion(rdata, ®ion); - RETERR(mem_tobuffer(target, region.base, 2)); - isc_region_consume(®ion, 2); - - /* - * MAP822. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, ®ion); - RETERR(dns_name_towire(&name, cctx, target)); - isc_region_consume(®ion, name_length(&name)); - - /* - * MAPX400. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, ®ion); - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_px(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_px); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - order = memcmp(rdata1->data, rdata2->data, 2); - if (order != 0) - return (order < 0 ? -1 : 1); - - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 2); - isc_region_consume(®ion2, 2); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - order = dns_name_rdatacompare(&name1, &name2); - if (order != 0) - return (order); - - isc_region_consume(®ion1, name_length(&name1)); - isc_region_consume(®ion2, name_length(&name2)); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_px(ARGS_FROMSTRUCT) { - dns_rdata_in_px_t *px; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_px); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_px_t *)source) != NULL); - REQUIRE(((dns_rdata_in_px_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_px_t *)source)->common.rdclass == rdclass); - - px = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(px->preference, target)); - dns_name_toregion(&px->map822, ®ion); - RETERR(isc_buffer_copyregion(target, ®ion)); - dns_name_toregion(&px->mapx400, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_px(ARGS_TOSTRUCT) { - dns_rdata_in_px_t *px; - dns_name_t name; - isc_region_t region; - isc_result_t result; - - REQUIRE(((dns_rdata_in_px_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - px = target; - - px->common.rdclass = rdata->rdclass; - px->common.rdtype = rdata->type; - ISC_LINK_INIT(&px->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - - px->preference = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - - dns_name_fromregion(&name, ®ion); - - dns_name_init(&px->map822, NULL); - RETERR(name_duporclone(&name, mctx, &px->map822)); - isc_region_consume(®ion, name_length(&px->map822)); - - dns_name_init(&px->mapx400, NULL); - result = name_duporclone(&name, mctx, &px->mapx400); - if (result != ISC_R_SUCCESS) - goto cleanup; - - px->mctx = mctx; - return (result); - - cleanup: - dns_name_free(&px->map822, mctx); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_in_px(ARGS_FREESTRUCT) { - dns_rdata_in_px_t *px; - - REQUIRE(((dns_rdata_in_px_t *)source) != NULL); - REQUIRE(((dns_rdata_in_px_t *)source)->common.rdtype == - dns_rdatatype_px); - REQUIRE(((dns_rdata_in_px_t *)source)->common.rdclass == - dns_rdataclass_in); - - px = source; - - if (px->mctx == NULL) - return; - - dns_name_free(&px->map822, px->mctx); - dns_name_free(&px->mapx400, px->mctx); - px->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_px(ARGS_ADDLDATA) { - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_px(ARGS_DIGEST) { - isc_region_t r1, r2; - dns_name_t name; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 2); - r1.length = 2; - result = (digest)(arg, &r1); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - result = dns_name_digest(&name, digest, arg); - if (result != ISC_R_SUCCESS) - return (result); - isc_region_consume(&r2, name_length(&name)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_in_px(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_px); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_px(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_px); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_px(ARGS_COMPARE) { - return (compare_in_px(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_PX_26_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/px_26.h b/lib/dns-pkcs11/rdata/in_1/px_26.h deleted file mode 100644 index ad45924..0000000 --- a/lib/dns-pkcs11/rdata/in_1/px_26.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_PX_26_H -#define IN_1_PX_26_H 1 - - -/*! - * \brief Per RFC2163 */ - -typedef struct dns_rdata_in_px { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t preference; - dns_name_t map822; - dns_name_t mapx400; -} dns_rdata_in_px_t; - -#endif /* IN_1_PX_26_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/srv_33.c b/lib/dns-pkcs11/rdata/in_1/srv_33.c deleted file mode 100644 index b96938d..0000000 --- a/lib/dns-pkcs11/rdata/in_1/srv_33.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* RFC2782 */ - -#ifndef RDATA_IN_1_SRV_33_C -#define RDATA_IN_1_SRV_33_C - -#define RRTYPE_SRV_ATTRIBUTES (0) - -static inline isc_result_t -fromtext_in_srv(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - bool ok; - - REQUIRE(type == dns_rdatatype_srv); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Priority. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Weight. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Port. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - false)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Target. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - if (origin == NULL) - origin = dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - ok = true; - if ((options & DNS_RDATA_CHECKNAMES) != 0) - ok = dns_name_ishostname(&name, false); - if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) - RETTOK(DNS_R_BADNAME); - if (!ok && callbacks != NULL) - warn_badname(&name, lexer, callbacks); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_srv(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - bool sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - /* - * Priority. - */ - dns_rdata_toregion(rdata, ®ion); - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Weight. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Port. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - snprintf(buf, sizeof(buf), "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Target. - */ - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_srv(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sr; - - REQUIRE(type == dns_rdatatype_srv); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - /* - * Priority, weight, port. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 6) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 6)); - isc_buffer_forward(source, 6); - - /* - * Target. - */ - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_srv(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sr; - - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - /* - * Priority, weight, port. - */ - dns_rdata_toregion(rdata, &sr); - RETERR(mem_tobuffer(target, sr.base, 6)); - isc_region_consume(&sr, 6); - - /* - * Target. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_srv(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_srv); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - /* - * Priority, weight, port. - */ - order = memcmp(rdata1->data, rdata2->data, 6); - if (order != 0) - return (order < 0 ? -1 : 1); - - /* - * Target. - */ - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - isc_region_consume(®ion1, 6); - isc_region_consume(®ion2, 6); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_srv(ARGS_FROMSTRUCT) { - dns_rdata_in_srv_t *srv; - isc_region_t region; - - REQUIRE(type == dns_rdatatype_srv); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_srv_t *)source) != NULL); - REQUIRE(((dns_rdata_in_srv_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_srv_t *)source)->common.rdclass == rdclass); - - srv = source; - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(srv->priority, target)); - RETERR(uint16_tobuffer(srv->weight, target)); - RETERR(uint16_tobuffer(srv->port, target)); - dns_name_toregion(&srv->target, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_srv(ARGS_TOSTRUCT) { - isc_region_t region; - dns_rdata_in_srv_t *srv; - dns_name_t name; - - REQUIRE(((dns_rdata_in_srv_t *)target) != NULL); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->length != 0); - - srv = target; - - srv->common.rdclass = rdata->rdclass; - srv->common.rdtype = rdata->type; - ISC_LINK_INIT(&srv->common, link); - - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - srv->priority = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - srv->weight = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - srv->port = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - dns_name_init(&srv->target, NULL); - RETERR(name_duporclone(&name, mctx, &srv->target)); - srv->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_srv(ARGS_FREESTRUCT) { - dns_rdata_in_srv_t *srv; - - REQUIRE(((dns_rdata_in_srv_t *)source) != NULL); - REQUIRE(((dns_rdata_in_srv_t *)source)->common.rdtype == - dns_rdatatype_srv); - REQUIRE(((dns_rdata_in_srv_t *)source)->common.rdclass == - dns_rdataclass_in); - - srv = source; - - if (srv->mctx == NULL) - return; - - dns_name_free(&srv->target, srv->mctx); - srv->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_srv(ARGS_ADDLDATA) { - char buf[sizeof("_65000._tcp")]; - dns_fixedname_t fixed; - dns_name_t name; - dns_offsets_t offsets; - isc_region_t region; - uint16_t port; - isc_result_t result; - - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_name_init(&name, offsets); - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 4); - port = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - dns_name_fromregion(&name, ®ion); - - if (dns_name_equal(&name, dns_rootname)) - return (ISC_R_SUCCESS); - - result = (add)(arg, &name, dns_rdatatype_a); - if (result != ISC_R_SUCCESS) - return (result); - - dns_fixedname_init(&fixed); - snprintf(buf, sizeof(buf), "_%u._tcp", port); - result = dns_name_fromstring2(dns_fixedname_name(&fixed), buf, NULL, - 0, NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - result = dns_name_concatenate(dns_fixedname_name(&fixed), &name, - dns_fixedname_name(&fixed), NULL); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa)); -} - -static inline isc_result_t -digest_in_srv(ARGS_DIGEST) { - isc_region_t r1, r2; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - isc_region_consume(&r2, 6); - r1.length = 6; - RETERR((digest)(arg, &r1)); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - return (dns_name_digest(&name, digest, arg)); -} - -static inline bool -checkowner_in_srv(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_srv); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (true); -} - -static inline bool -checknames_in_srv(ARGS_CHECKNAMES) { - isc_region_t region; - dns_name_t name; - - REQUIRE(rdata->type == dns_rdatatype_srv); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(owner); - - dns_rdata_toregion(rdata, ®ion); - isc_region_consume(®ion, 6); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, ®ion); - if (!dns_name_ishostname(&name, false)) { - if (bad != NULL) - dns_name_clone(&name, bad); - return (false); - } - return (true); -} - -static inline int -casecompare_in_srv(ARGS_COMPARE) { - return (compare_in_srv(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_SRV_33_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/srv_33.h b/lib/dns-pkcs11/rdata/in_1/srv_33.h deleted file mode 100644 index 8da1512..0000000 --- a/lib/dns-pkcs11/rdata/in_1/srv_33.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_SRV_33_H -#define IN_1_SRV_33_H 1 - -/*! - * \brief Per RFC2782 */ - -typedef struct dns_rdata_in_srv { - dns_rdatacommon_t common; - isc_mem_t *mctx; - uint16_t priority; - uint16_t weight; - uint16_t port; - dns_name_t target; -} dns_rdata_in_srv_t; - -#endif /* IN_1_SRV_33_H */ diff --git a/lib/dns-pkcs11/rdata/in_1/wks_11.c b/lib/dns-pkcs11/rdata/in_1/wks_11.c deleted file mode 100644 index 452b4a5..0000000 --- a/lib/dns-pkcs11/rdata/in_1/wks_11.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef RDATA_IN_1_WKS_11_C -#define RDATA_IN_1_WKS_11_C - -#include -#include - -#include -#include -#include - -/* - * Redefine CHECK here so cppcheck "sees" the define. - */ -#ifndef CHECK -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) -#endif - -#define RRTYPE_WKS_ATTRIBUTES (0) - -static isc_mutex_t wks_lock; - -static void init_lock(void) { - RUNTIME_CHECK(isc_mutex_init(&wks_lock) == ISC_R_SUCCESS); -} - -static bool -mygetprotobyname(const char *name, long *proto) { - struct protoent *pe; - - LOCK(&wks_lock); - pe = getprotobyname(name); - if (pe != NULL) - *proto = pe->p_proto; - UNLOCK(&wks_lock); - return (pe != NULL); -} - -static bool -mygetservbyname(const char *name, const char *proto, long *port) { - struct servent *se; - - LOCK(&wks_lock); - se = getservbyname(name, proto); - if (se != NULL) - *port = ntohs(se->s_port); - UNLOCK(&wks_lock); - return (se != NULL); -} - -#ifdef _WIN32 -#include -#include -#include -#endif - -static inline isc_result_t -fromtext_in_wks(ARGS_FROMTEXT) { - static isc_once_t once = ISC_ONCE_INIT; - isc_token_t token; - isc_region_t region; - struct in_addr addr; - char *e = NULL; - long proto; - unsigned char bm[8*1024]; /* 64k bits */ - long port; - long maxport = -1; - const char *ps = NULL; - unsigned int n; - char service[32]; - int i; - isc_result_t result; - - REQUIRE(type == dns_rdatatype_wks); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(origin); - UNUSED(options); - UNUSED(rdclass); - - RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); - -#ifdef _WIN32 - { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup(wVersionRequested, &wsaData ); - if (err != 0) - return (ISC_R_FAILURE); - } -#endif - - /* - * IPv4 dotted quad. - */ - CHECK(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - isc_buffer_availableregion(target, ®ion); - if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) { - CHECKTOK(DNS_R_BADDOTTEDQUAD); - } - if (region.length < 4) { - return (ISC_R_NOSPACE); - } - memmove(region.base, &addr, 4); - isc_buffer_add(target, 4); - - /* - * Protocol. - */ - CHECK(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - false)); - - proto = strtol(DNS_AS_STR(token), &e, 10); - if (*e != '\0' && !mygetprotobyname(DNS_AS_STR(token), &proto)) { - CHECKTOK(DNS_R_UNKNOWNPROTO); - } - - if (proto < 0 || proto > 0xff) { - CHECKTOK(ISC_R_RANGE); - } - - if (proto == IPPROTO_TCP) { - ps = "tcp"; - } else if (proto == IPPROTO_UDP) { - ps = "udp"; - } - - CHECK(uint8_tobuffer(proto, target)); - - memset(bm, 0, sizeof(bm)); - do { - CHECK(isc_lex_getmastertoken(lexer, &token, - isc_tokentype_string, true)); - if (token.type != isc_tokentype_string) { - break; - } - - /* - * Lowercase the service string as some getservbyname() are - * case sensitive and the database is usually in lowercase. - */ - strlcpy(service, DNS_AS_STR(token), sizeof(service)); - for (i = strlen(service) - 1; i >= 0; i--) - if (isupper(service[i]&0xff)) - service[i] = tolower(service[i]&0xff); - - port = strtol(DNS_AS_STR(token), &e, 10); - if (*e != 0 && !mygetservbyname(service, ps, &port) && - !mygetservbyname(DNS_AS_STR(token), ps, &port)) - { - CHECKTOK(DNS_R_UNKNOWNSERVICE); - } - - if (port < 0 || port > 0xffff) { - CHECKTOK(ISC_R_RANGE); - } - if (port > maxport) { - maxport = port; - } - bm[port / 8] |= (0x80 >> (port % 8)); - } while (1); - - /* - * Let upper layer handle eol/eof. - */ - isc_lex_ungettoken(lexer, &token); - - n = (maxport + 8) / 8; - result = mem_tobuffer(target, bm, n); - - cleanup: -#ifdef _WIN32 - WSACleanup(); -#endif - - return (result); -} - -static inline isc_result_t -totext_in_wks(ARGS_TOTEXT) { - isc_region_t sr; - unsigned short proto; - char buf[sizeof("65535")]; - unsigned int i, j; - - UNUSED(tctx); - - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length >= 5); - - dns_rdata_toregion(rdata, &sr); - RETERR(inet_totext(AF_INET, tctx->flags, &sr, target)); - isc_region_consume(&sr, 4); - - proto = uint8_fromregion(&sr); - snprintf(buf, sizeof(buf), "%u", proto); - RETERR(str_totext(" ", target)); - RETERR(str_totext(buf, target)); - isc_region_consume(&sr, 1); - - INSIST(sr.length <= 8*1024); - for (i = 0; i < sr.length; i++) { - if (sr.base[i] != 0) - for (j = 0; j < 8; j++) - if ((sr.base[i] & (0x80 >> j)) != 0) { - snprintf(buf, sizeof(buf), - "%u", i * 8 + j); - RETERR(str_totext(" ", target)); - RETERR(str_totext(buf, target)); - } - } - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromwire_in_wks(ARGS_FROMWIRE) { - isc_region_t sr; - isc_region_t tr; - - REQUIRE(type == dns_rdatatype_wks); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(dctx); - UNUSED(options); - UNUSED(rdclass); - - isc_buffer_activeregion(source, &sr); - isc_buffer_availableregion(target, &tr); - - if (sr.length < 5) { - return (ISC_R_UNEXPECTEDEND); - } - if (sr.length > 8 * 1024 + 5) { - return (DNS_R_EXTRADATA); - } - if (sr.length > 5 && sr.base[sr.length - 1] == 0) { - return (DNS_R_FORMERR); - } - if (tr.length < sr.length) { - return (ISC_R_NOSPACE); - } - - memmove(tr.base, sr.base, sr.length); - isc_buffer_add(target, sr.length); - isc_buffer_forward(source, sr.length); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -towire_in_wks(ARGS_TOWIRE) { - isc_region_t sr; - - UNUSED(cctx); - - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - dns_rdata_toregion(rdata, &sr); - return (mem_tobuffer(target, sr.base, sr.length)); -} - -static inline int -compare_in_wks(ARGS_COMPARE) { - isc_region_t r1; - isc_region_t r2; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == dns_rdatatype_wks); - REQUIRE(rdata1->rdclass == dns_rdataclass_in); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, &r1); - dns_rdata_toregion(rdata2, &r2); - return (isc_region_compare(&r1, &r2)); -} - -static inline isc_result_t -fromstruct_in_wks(ARGS_FROMSTRUCT) { - dns_rdata_in_wks_t *wks; - uint32_t a; - - REQUIRE(type == dns_rdatatype_wks); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(((dns_rdata_in_wks_t *)source) != NULL); - REQUIRE(((dns_rdata_in_wks_t *)source)->common.rdtype == type); - REQUIRE(((dns_rdata_in_wks_t *)source)->common.rdclass == rdclass); - REQUIRE((((dns_rdata_in_wks_t *)source)->map != NULL && - ((dns_rdata_in_wks_t *)source)->map_len <= 8*1024) || - ((dns_rdata_in_wks_t *)source)->map_len == 0); - - wks = source; - - UNUSED(type); - UNUSED(rdclass); - - a = ntohl(wks->in_addr.s_addr); - RETERR(uint32_tobuffer(a, target)); - RETERR(uint8_tobuffer(wks->protocol, target)); - return (mem_tobuffer(target, wks->map, wks->map_len)); -} - -static inline isc_result_t -tostruct_in_wks(ARGS_TOSTRUCT) { - dns_rdata_in_wks_t *wks; - uint32_t n; - isc_region_t region; - - REQUIRE(((dns_rdata_in_wks_t *)target) != NULL); - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - REQUIRE(rdata->length != 0); - - wks = target; - - wks->common.rdclass = rdata->rdclass; - wks->common.rdtype = rdata->type; - ISC_LINK_INIT(&wks->common, link); - - dns_rdata_toregion(rdata, ®ion); - n = uint32_fromregion(®ion); - wks->in_addr.s_addr = htonl(n); - isc_region_consume(®ion, 4); - wks->protocol = uint8_fromregion(®ion); - isc_region_consume(®ion, 1); - wks->map_len = region.length; - wks->map = mem_maybedup(mctx, region.base, region.length); - if (wks->map == NULL) - return (ISC_R_NOMEMORY); - wks->mctx = mctx; - return (ISC_R_SUCCESS); -} - -static inline void -freestruct_in_wks(ARGS_FREESTRUCT) { - dns_rdata_in_wks_t *wks; - - REQUIRE(((dns_rdata_in_wks_t *)source) != NULL); - REQUIRE(((dns_rdata_in_wks_t *)source)->common.rdtype == - dns_rdatatype_wks); - REQUIRE(((dns_rdata_in_wks_t *)source)->common.rdclass == - dns_rdataclass_in); - - wks = source; - - if (wks->mctx == NULL) - return; - - if (wks->map != NULL) - isc_mem_free(wks->mctx, wks->map); - wks->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_wks(ARGS_ADDLDATA) { - UNUSED(rdata); - UNUSED(add); - UNUSED(arg); - - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_wks(ARGS_DIGEST) { - isc_region_t r; - - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - dns_rdata_toregion(rdata, &r); - - return ((digest)(arg, &r)); -} - -static inline bool -checkowner_in_wks(ARGS_CHECKOWNER) { - - REQUIRE(type == dns_rdatatype_wks); - REQUIRE(rdclass == dns_rdataclass_in); - - UNUSED(type); - UNUSED(rdclass); - - return (dns_name_ishostname(name, wildcard)); -} - -static inline bool -checknames_in_wks(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == dns_rdatatype_wks); - REQUIRE(rdata->rdclass == dns_rdataclass_in); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (true); -} - -static inline int -casecompare_in_wks(ARGS_COMPARE) { - return (compare_in_wks(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_WKS_11_C */ diff --git a/lib/dns-pkcs11/rdata/in_1/wks_11.h b/lib/dns-pkcs11/rdata/in_1/wks_11.h deleted file mode 100644 index 12e4e48..0000000 --- a/lib/dns-pkcs11/rdata/in_1/wks_11.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#ifndef IN_1_WKS_11_H -#define IN_1_WKS_11_H 1 - - -typedef struct dns_rdata_in_wks { - dns_rdatacommon_t common; - isc_mem_t *mctx; - struct in_addr in_addr; - uint16_t protocol; - unsigned char *map; - uint16_t map_len; -} dns_rdata_in_wks_t; - -#endif /* IN_1_WKS_11_H */ diff --git a/lib/dns-pkcs11/rdata/rdatastructpre.h b/lib/dns-pkcs11/rdata/rdatastructpre.h deleted file mode 100644 index 8d78458..0000000 --- a/lib/dns-pkcs11/rdata/rdatastructpre.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATASTRUCT_H -#define DNS_RDATASTRUCT_H 1 - -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -typedef struct dns_rdatacommon { - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - ISC_LINK(struct dns_rdatacommon) link; -} dns_rdatacommon_t; - -#define DNS_RDATACOMMON_INIT(_data, _rdtype, _rdclass) \ - do { \ - (_data)->common.rdtype = (_rdtype); \ - (_data)->common.rdclass = (_rdclass); \ - ISC_LINK_INIT(&(_data)->common, link); \ - } while (0) diff --git a/lib/dns-pkcs11/rdata/rdatastructsuf.h b/lib/dns-pkcs11/rdata/rdatastructsuf.h deleted file mode 100644 index aaa23b0..0000000 --- a/lib/dns-pkcs11/rdata/rdatastructsuf.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATASTRUCT_H */ diff --git a/lib/dns-pkcs11/rdatalist.c b/lib/dns-pkcs11/rdatalist.c deleted file mode 100644 index cc2619c..0000000 --- a/lib/dns-pkcs11/rdatalist.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "rdatalist_p.h" - -static dns_rdatasetmethods_t methods = { - isc__rdatalist_disassociate, - isc__rdatalist_first, - isc__rdatalist_next, - isc__rdatalist_current, - isc__rdatalist_clone, - isc__rdatalist_count, - isc__rdatalist_addnoqname, - isc__rdatalist_getnoqname, - isc__rdatalist_addclosest, - isc__rdatalist_getclosest, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - isc__rdatalist_setownercase, - isc__rdatalist_getownercase -}; - -void -dns_rdatalist_init(dns_rdatalist_t *rdatalist) { - - REQUIRE(rdatalist != NULL); - - /* - * Initialize rdatalist. - */ - - rdatalist->rdclass = 0; - rdatalist->type = 0; - rdatalist->covers = 0; - rdatalist->ttl = 0; - ISC_LIST_INIT(rdatalist->rdata); - ISC_LINK_INIT(rdatalist, link); - memset(rdatalist->upper, 0xeb, sizeof(rdatalist->upper)); - /* - * Clear upper set bit. - */ - rdatalist->upper[0] &= ~0x01; -} - -isc_result_t -dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, - dns_rdataset_t *rdataset) -{ - /* - * Make 'rdataset' refer to the rdata in 'rdatalist'. - */ - - REQUIRE(rdatalist != NULL); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(! dns_rdataset_isassociated(rdataset)); - - /* Check if dns_rdatalist_init has was called. */ - REQUIRE(rdatalist->upper[0] == 0xea); - - rdataset->methods = &methods; - rdataset->rdclass = rdatalist->rdclass; - rdataset->type = rdatalist->type; - rdataset->covers = rdatalist->covers; - rdataset->ttl = rdatalist->ttl; - rdataset->trust = 0; - rdataset->private1 = rdatalist; - rdataset->private2 = NULL; - rdataset->private3 = NULL; - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset, - dns_rdatalist_t **rdatalist) -{ - REQUIRE(rdatalist != NULL && rdataset != NULL); - *rdatalist = rdataset->private1; - - return (ISC_R_SUCCESS); -} - -void -isc__rdatalist_disassociate(dns_rdataset_t *rdataset) { - UNUSED(rdataset); -} - -isc_result_t -isc__rdatalist_first(dns_rdataset_t *rdataset) { - dns_rdatalist_t *rdatalist; - - rdatalist = rdataset->private1; - rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata); - - if (rdataset->private2 == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc__rdatalist_next(dns_rdataset_t *rdataset) { - dns_rdata_t *rdata; - - REQUIRE(rdataset != NULL); - - rdata = rdataset->private2; - if (rdata == NULL) - return (ISC_R_NOMORE); - - rdataset->private2 = ISC_LIST_NEXT(rdata, link); - - if (rdataset->private2 == NULL) - return (ISC_R_NOMORE); - - return (ISC_R_SUCCESS); -} - -void -isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - dns_rdata_t *list_rdata; - - REQUIRE(rdataset != NULL); - - list_rdata = rdataset->private2; - INSIST(list_rdata != NULL); - - dns_rdata_clone(list_rdata, rdata); -} - -void -isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - - REQUIRE(source != NULL); - REQUIRE(target != NULL); - - *target = *source; - - /* - * Reset iterator state. - */ - target->private2 = NULL; -} - -unsigned int -isc__rdatalist_count(dns_rdataset_t *rdataset) { - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - unsigned int count; - - REQUIRE(rdataset != NULL); - - rdatalist = rdataset->private1; - - count = 0; - for (rdata = ISC_LIST_HEAD(rdatalist->rdata); - rdata != NULL; - rdata = ISC_LIST_NEXT(rdata, link)) - count++; - - return (count); -} - -isc_result_t -isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) { - dns_rdataset_t *neg = NULL; - dns_rdataset_t *negsig = NULL; - dns_rdataset_t *rdset; - dns_ttl_t ttl; - - REQUIRE(rdataset != NULL); - - for (rdset = ISC_LIST_HEAD(name->list); - rdset != NULL; - rdset = ISC_LIST_NEXT(rdset, link)) - { - if (rdset->rdclass != rdataset->rdclass) - continue; - if (rdset->type == dns_rdatatype_nsec || - rdset->type == dns_rdatatype_nsec3) - neg = rdset; - } - if (neg == NULL) - return (ISC_R_NOTFOUND); - - for (rdset = ISC_LIST_HEAD(name->list); - rdset != NULL; - rdset = ISC_LIST_NEXT(rdset, link)) - { - if (rdset->type == dns_rdatatype_rrsig && - rdset->covers == neg->type) - negsig = rdset; - } - - if (negsig == NULL) - return (ISC_R_NOTFOUND); - /* - * Minimise ttl. - */ - ttl = rdataset->ttl; - if (neg->ttl < ttl) - ttl = neg->ttl; - if (negsig->ttl < ttl) - ttl = negsig->ttl; - rdataset->ttl = neg->ttl = negsig->ttl = ttl; - rdataset->attributes |= DNS_RDATASETATTR_NOQNAME; - rdataset->private6 = name; - return (ISC_R_SUCCESS); -} - -isc_result_t -isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig) -{ - dns_rdataclass_t rdclass; - dns_rdataset_t *tneg = NULL; - dns_rdataset_t *tnegsig = NULL; - dns_name_t *noqname; - - REQUIRE(rdataset != NULL); - REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0); - - rdclass = rdataset->rdclass; - noqname = rdataset->private6; - - (void)dns_name_dynamic(noqname); /* Sanity Check. */ - - for (rdataset = ISC_LIST_HEAD(noqname->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->rdclass != rdclass) - continue; - if (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3) - tneg = rdataset; - } - if (tneg == NULL) - return (ISC_R_NOTFOUND); - - for (rdataset = ISC_LIST_HEAD(noqname->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->type == dns_rdatatype_rrsig && - rdataset->covers == tneg->type) - tnegsig = rdataset; - } - if (tnegsig == NULL) - return (ISC_R_NOTFOUND); - - dns_name_clone(noqname, name); - dns_rdataset_clone(tneg, neg); - dns_rdataset_clone(tnegsig, negsig); - return (ISC_R_SUCCESS); -} - -isc_result_t -isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) { - dns_rdataset_t *neg = NULL; - dns_rdataset_t *negsig = NULL; - dns_rdataset_t *rdset; - dns_ttl_t ttl; - - REQUIRE(rdataset != NULL); - - for (rdset = ISC_LIST_HEAD(name->list); - rdset != NULL; - rdset = ISC_LIST_NEXT(rdset, link)) - { - if (rdset->rdclass != rdataset->rdclass) - continue; - if (rdset->type == dns_rdatatype_nsec || - rdset->type == dns_rdatatype_nsec3) - neg = rdset; - } - if (neg == NULL) - return (ISC_R_NOTFOUND); - - for (rdset = ISC_LIST_HEAD(name->list); - rdset != NULL; - rdset = ISC_LIST_NEXT(rdset, link)) - { - if (rdset->type == dns_rdatatype_rrsig && - rdset->covers == neg->type) - negsig = rdset; - } - - if (negsig == NULL) - return (ISC_R_NOTFOUND); - /* - * Minimise ttl. - */ - ttl = rdataset->ttl; - if (neg->ttl < ttl) - ttl = neg->ttl; - if (negsig->ttl < ttl) - ttl = negsig->ttl; - rdataset->ttl = neg->ttl = negsig->ttl = ttl; - rdataset->attributes |= DNS_RDATASETATTR_CLOSEST; - rdataset->private7 = name; - return (ISC_R_SUCCESS); -} - -isc_result_t -isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig) -{ - dns_rdataclass_t rdclass; - dns_rdataset_t *tneg = NULL; - dns_rdataset_t *tnegsig = NULL; - dns_name_t *closest; - - REQUIRE(rdataset != NULL); - REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0); - - rdclass = rdataset->rdclass; - closest = rdataset->private7; - - (void)dns_name_dynamic(closest); /* Sanity Check. */ - - for (rdataset = ISC_LIST_HEAD(closest->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->rdclass != rdclass) - continue; - if (rdataset->type == dns_rdatatype_nsec || - rdataset->type == dns_rdatatype_nsec3) - tneg = rdataset; - } - if (tneg == NULL) - return (ISC_R_NOTFOUND); - - for (rdataset = ISC_LIST_HEAD(closest->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->type == dns_rdatatype_rrsig && - rdataset->covers == tneg->type) - tnegsig = rdataset; - } - if (tnegsig == NULL) - return (ISC_R_NOTFOUND); - - dns_name_clone(closest, name); - dns_rdataset_clone(tneg, neg); - dns_rdataset_clone(tnegsig, negsig); - return (ISC_R_SUCCESS); -} - -void -isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) { - dns_rdatalist_t *rdatalist; - unsigned int i; - - /* - * We do not need to worry about label lengths as they are all - * less than or equal to 63. - */ - rdatalist = rdataset->private1; - memset(rdatalist->upper, 0, sizeof(rdatalist->upper)); - for (i = 1; i < name->length; i++) - if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) - rdatalist->upper[i/8] |= 1 << (i%8); - /* - * Record that upper has been set. - */ - rdatalist->upper[0] |= 0x01; -} - -void -isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { - dns_rdatalist_t *rdatalist; - unsigned int i; - - rdatalist = rdataset->private1; - if ((rdatalist->upper[0] & 0x01) == 0) - return; - for (i = 0; i < name->length; i++) { - /* - * Set the case bit if it does not match the recorded bit. - */ - if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a && - (rdatalist->upper[i/8] & (1 << (i%8))) != 0) - name->ndata[i] &= ~0x20; /* clear the lower case bit */ - else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a && - (rdatalist->upper[i/8] & (1 << (i%8))) == 0) - name->ndata[i] |= 0x20; /* set the lower case bit */ - } -} diff --git a/lib/dns-pkcs11/rdatalist_p.h b/lib/dns-pkcs11/rdatalist_p.h deleted file mode 100644 index 605a2b1..0000000 --- a/lib/dns-pkcs11/rdatalist_p.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#ifndef DNS_RDATALIST_P_H -#define DNS_RDATALIST_P_H - -/*! \file */ - -#include -#include - -ISC_LANG_BEGINDECLS - -void -isc__rdatalist_disassociate(dns_rdataset_t *rdatasetp); - -isc_result_t -isc__rdatalist_first(dns_rdataset_t *rdataset); - -isc_result_t -isc__rdatalist_next(dns_rdataset_t *rdataset); - -void -isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); - -void -isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target); - -unsigned int -isc__rdatalist_count(dns_rdataset_t *rdataset); - -isc_result_t -isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name); - -isc_result_t -isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig); - -isc_result_t -isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name); - -isc_result_t -isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig); - -void -isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name); - -void -isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name); - -ISC_LANG_ENDDECLS - -#endif /* DNS_RDATALIST_P_H */ diff --git a/lib/dns-pkcs11/rdataset.c b/lib/dns-pkcs11/rdataset.c deleted file mode 100644 index b42dea5..0000000 --- a/lib/dns-pkcs11/rdataset.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static const char *trustnames[] = { - "none", - "pending-additional", - "pending-answer", - "additional", - "glue", - "answer", - "authauthority", - "authanswer", - "secure", - "local" /* aka ultimate */ -}; - -const char * -dns_trust_totext(dns_trust_t trust) { - if (trust >= sizeof(trustnames)/sizeof(*trustnames)) - return ("bad"); - return (trustnames[trust]); -} - -void -dns_rdataset_init(dns_rdataset_t *rdataset) { - - /* - * Make 'rdataset' a valid, disassociated rdataset. - */ - - REQUIRE(rdataset != NULL); - - rdataset->magic = DNS_RDATASET_MAGIC; - rdataset->methods = NULL; - ISC_LINK_INIT(rdataset, link); - rdataset->rdclass = 0; - rdataset->type = 0; - rdataset->ttl = 0; - rdataset->trust = 0; - rdataset->covers = 0; - rdataset->attributes = 0; - rdataset->count = UINT32_MAX; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - rdataset->private3 = NULL; - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - rdataset->private6 = NULL; - rdataset->private7 = NULL; - rdataset->resign = 0; -} - -void -dns_rdataset_invalidate(dns_rdataset_t *rdataset) { - - /* - * Invalidate 'rdataset'. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods == NULL); - - rdataset->magic = 0; - ISC_LINK_INIT(rdataset, link); - rdataset->rdclass = 0; - rdataset->type = 0; - rdataset->ttl = 0; - rdataset->trust = 0; - rdataset->covers = 0; - rdataset->attributes = 0; - rdataset->count = UINT32_MAX; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - rdataset->private3 = NULL; - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; -} - -void -dns_rdataset_disassociate(dns_rdataset_t *rdataset) { - - /* - * Disassociate 'rdataset' from its rdata, allowing it to be reused. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - (rdataset->methods->disassociate)(rdataset); - rdataset->methods = NULL; - ISC_LINK_INIT(rdataset, link); - rdataset->rdclass = 0; - rdataset->type = 0; - rdataset->ttl = 0; - rdataset->trust = 0; - rdataset->covers = 0; - rdataset->attributes = 0; - rdataset->count = UINT32_MAX; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - rdataset->private3 = NULL; - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; - rdataset->private6 = NULL; -} - -bool -dns_rdataset_isassociated(dns_rdataset_t *rdataset) { - /* - * Is 'rdataset' associated? - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - - if (rdataset->methods != NULL) - return (true); - - return (false); -} - -static void -question_disassociate(dns_rdataset_t *rdataset) { - UNUSED(rdataset); -} - -static isc_result_t -question_cursor(dns_rdataset_t *rdataset) { - UNUSED(rdataset); - - return (ISC_R_NOMORE); -} - -static void -question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - /* - * This routine should never be called. - */ - UNUSED(rdataset); - UNUSED(rdata); - - REQUIRE(0); -} - -static void -question_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - *target = *source; -} - -static unsigned int -question_count(dns_rdataset_t *rdataset) { - /* - * This routine should never be called. - */ - UNUSED(rdataset); - REQUIRE(0); - - return (0); -} - -static dns_rdatasetmethods_t question_methods = { - question_disassociate, - question_cursor, - question_cursor, - question_current, - question_clone, - question_count, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -void -dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass, - dns_rdatatype_t type) -{ - - /* - * Make 'rdataset' a valid, associated, question rdataset, with a - * question class of 'rdclass' and type 'type'. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods == NULL); - - rdataset->methods = &question_methods; - rdataset->rdclass = rdclass; - rdataset->type = type; - rdataset->attributes |= DNS_RDATASETATTR_QUESTION; -} - -unsigned int -dns_rdataset_count(dns_rdataset_t *rdataset) { - - /* - * Return the number of records in 'rdataset'. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - return ((rdataset->methods->count)(rdataset)); -} - -void -dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - - /* - * Make 'target' refer to the same rdataset as 'source'. - */ - - REQUIRE(DNS_RDATASET_VALID(source)); - REQUIRE(source->methods != NULL); - REQUIRE(DNS_RDATASET_VALID(target)); - REQUIRE(target->methods == NULL); - - (source->methods->clone)(source, target); -} - -isc_result_t -dns_rdataset_first(dns_rdataset_t *rdataset) { - - /* - * Move the rdata cursor to the first rdata in the rdataset (if any). - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - return ((rdataset->methods->first)(rdataset)); -} - -isc_result_t -dns_rdataset_next(dns_rdataset_t *rdataset) { - - /* - * Move the rdata cursor to the next rdata in the rdataset (if any). - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - return ((rdataset->methods->next)(rdataset)); -} - -void -dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - - /* - * Make 'rdata' refer to the current rdata. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - (rdataset->methods->current)(rdataset, rdata); -} - -#define MAX_SHUFFLE 32 -#define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0) -#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0) - -struct towire_sort { - int key; - dns_rdata_t *rdata; -}; - -static int -towire_compare(const void *av, const void *bv) { - const struct towire_sort *a = (const struct towire_sort *) av; - const struct towire_sort *b = (const struct towire_sort *) bv; - return (a->key - b->key); -} - -static isc_result_t -towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, - dns_compress_t *cctx, isc_buffer_t *target, - dns_rdatasetorderfunc_t order, const void *order_arg, - bool partial, unsigned int options, - unsigned int *countp, void **state) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_region_t r; - isc_result_t result; - unsigned int i, count = 0, added, choice; - isc_buffer_t savedbuffer, rdlen, rrbuffer; - unsigned int headlen; - bool question = false; - bool shuffle = false; - dns_rdata_t *in = NULL, in_fixed[MAX_SHUFFLE]; - struct towire_sort *out = NULL, out_fixed[MAX_SHUFFLE]; - dns_fixedname_t fixed; - dns_name_t *name; - - UNUSED(state); - - /* - * Convert 'rdataset' to wire format, compressing names as specified - * in cctx, and storing the result in 'target'. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - REQUIRE(countp != NULL); - REQUIRE((order == NULL) == (order_arg == NULL)); - REQUIRE(cctx != NULL && cctx->mctx != NULL); - - if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) { - question = true; - count = 1; - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_NOMORE); - } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { - /* - * This is a negative caching rdataset. - */ - unsigned int ncache_opts = 0; - if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0) - ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC; - return (dns_ncache_towire(rdataset, cctx, target, ncache_opts, - countp)); - } else { - count = (rdataset->methods->count)(rdataset); - result = dns_rdataset_first(rdataset); - if (result == ISC_R_NOMORE) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - } - - /* - * Do we want to shuffle this answer? - */ - if (!question && count > 1 && - (!WANT_FIXED(rdataset) || order != NULL) && - rdataset->type != dns_rdatatype_rrsig) - shuffle = true; - - if (shuffle && count > MAX_SHUFFLE) { - in = isc_mem_get(cctx->mctx, count * sizeof(*in)); - out = isc_mem_get(cctx->mctx, count * sizeof(*out)); - if (in == NULL || out == NULL) - shuffle = false; - } else { - in = in_fixed; - out = out_fixed; - } - - if (shuffle) { - /* - * First we get handles to all of the rdata. - */ - i = 0; - do { - INSIST(i < count); - dns_rdata_init(&in[i]); - dns_rdataset_current(rdataset, &in[i]); - i++; - result = dns_rdataset_next(rdataset); - } while (result == ISC_R_SUCCESS); - if (result != ISC_R_NOMORE) - goto cleanup; - INSIST(i == count); - - /* - * Now we shuffle. - */ - if (WANT_FIXED(rdataset)) { - /* - * 'Fixed' order. - */ - INSIST(order != NULL); - for (i = 0; i < count; i++) { - out[i].key = (*order)(&in[i], order_arg); - out[i].rdata = &in[i]; - } - } else if (WANT_RANDOM(rdataset)) { - /* - * 'Random' order. - */ - for (i = 0; i < count; i++) { - uint32_t val; - - isc_random_get(&val); - choice = i + (val % (count - i)); - rdata = in[i]; - in[i] = in[choice]; - in[choice] = rdata; - if (order != NULL) - out[i].key = (*order)(&in[i], - order_arg); - else - out[i].key = 0; /* Unused */ - out[i].rdata = &in[i]; - } - } else { - /* - * "Cyclic" order. - */ - uint32_t val; - unsigned int j; - - val = rdataset->count; - if (val == UINT32_MAX) - isc_random_get(&val); - j = val % count; - for (i = 0; i < count; i++) { - if (order != NULL) - out[i].key = (*order)(&in[j], - order_arg); - else - out[i].key = 0; /* Unused */ - out[i].rdata = &in[j]; - j++; - if (j == count) - j = 0; /* Wrap around. */ - } - } - - /* - * Sorted order. - */ - if (order != NULL) - qsort(out, count, sizeof(out[0]), towire_compare); - } - - savedbuffer = *target; - i = 0; - added = 0; - - name = dns_fixedname_initname(&fixed); - dns_name_copy(owner_name, name, NULL); - dns_rdataset_getownercase(rdataset, name); - - name->attributes |= owner_name->attributes & - DNS_NAMEATTR_NOCOMPRESS; - - do { - /* - * Copy out the name, type, class, ttl. - */ - - rrbuffer = *target; - dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); - result = dns_name_towire(name, cctx, target); - if (result != ISC_R_SUCCESS) - goto rollback; - headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t); - if (!question) - headlen += sizeof(dns_ttl_t) - + 2; /* XXX 2 for rdata len */ - isc_buffer_availableregion(target, &r); - if (r.length < headlen) { - result = ISC_R_NOSPACE; - goto rollback; - } - isc_buffer_putuint16(target, rdataset->type); - isc_buffer_putuint16(target, rdataset->rdclass); - if (!question) { - isc_buffer_putuint32(target, rdataset->ttl); - - /* - * Save space for rdlen. - */ - rdlen = *target; - isc_buffer_add(target, 2); - - /* - * Copy out the rdata - */ - if (shuffle) - rdata = *(out[i].rdata); - else { - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - } - result = dns_rdata_towire(&rdata, cctx, target); - if (result != ISC_R_SUCCESS) - goto rollback; - INSIST((target->used >= rdlen.used + 2) && - (target->used - rdlen.used - 2 < 65536)); - isc_buffer_putuint16(&rdlen, - (uint16_t)(target->used - - rdlen.used - 2)); - added++; - } - - if (shuffle) { - i++; - if (i == count) - result = ISC_R_NOMORE; - else - result = ISC_R_SUCCESS; - } else { - result = dns_rdataset_next(rdataset); - } - } while (result == ISC_R_SUCCESS); - - if (result != ISC_R_NOMORE) - goto rollback; - - *countp += count; - - result = ISC_R_SUCCESS; - goto cleanup; - - rollback: - if (partial && result == ISC_R_NOSPACE) { - INSIST(rrbuffer.used < 65536); - dns_compress_rollback(cctx, (uint16_t)rrbuffer.used); - *countp += added; - *target = rrbuffer; - goto cleanup; - } - INSIST(savedbuffer.used < 65536); - dns_compress_rollback(cctx, (uint16_t)savedbuffer.used); - *countp = 0; - *target = savedbuffer; - - cleanup: - if (out != NULL && out != out_fixed) - isc_mem_put(cctx->mctx, out, count * sizeof(*out)); - if (in != NULL && in != in_fixed) - isc_mem_put(cctx->mctx, in, count * sizeof(*in)); - return (result); -} - -isc_result_t -dns_rdataset_towiresorted(dns_rdataset_t *rdataset, - const dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - dns_rdatasetorderfunc_t order, - const void *order_arg, - unsigned int options, - unsigned int *countp) -{ - return (towiresorted(rdataset, owner_name, cctx, target, - order, order_arg, false, options, - countp, NULL)); -} - -isc_result_t -dns_rdataset_towirepartial(dns_rdataset_t *rdataset, - const dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - dns_rdatasetorderfunc_t order, - const void *order_arg, - unsigned int options, - unsigned int *countp, - void **state) -{ - REQUIRE(state == NULL); /* XXX remove when implemented */ - return (towiresorted(rdataset, owner_name, cctx, target, - order, order_arg, true, options, - countp, state)); -} - -isc_result_t -dns_rdataset_towire(dns_rdataset_t *rdataset, - dns_name_t *owner_name, - dns_compress_t *cctx, - isc_buffer_t *target, - unsigned int options, - unsigned int *countp) -{ - return (towiresorted(rdataset, owner_name, cctx, target, - NULL, NULL, false, options, countp, NULL)); -} - -isc_result_t -dns_rdataset_additionaldata(dns_rdataset_t *rdataset, - dns_additionaldatafunc_t add, void *arg) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - - /* - * For each rdata in rdataset, call 'add' for each name and type in the - * rdata which is subject to additional section processing. - */ - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0); - - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) - return (result); - - do { - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_additionaldata(&rdata, add, arg); - if (result == ISC_R_SUCCESS) - result = dns_rdataset_next(rdataset); - dns_rdata_reset(&rdata); - } while (result == ISC_R_SUCCESS); - - if (result != ISC_R_NOMORE) - return (result); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) { - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - if (rdataset->methods->addnoqname == NULL) - return (ISC_R_NOTIMPLEMENTED); - return((rdataset->methods->addnoqname)(rdataset, name)); -} - -isc_result_t -dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig) -{ - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->getnoqname == NULL) - return (ISC_R_NOTIMPLEMENTED); - return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig)); -} - -isc_result_t -dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) { - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - if (rdataset->methods->addclosest == NULL) - return (ISC_R_NOTIMPLEMENTED); - return((rdataset->methods->addclosest)(rdataset, name)); -} - -isc_result_t -dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, - dns_rdataset_t *neg, dns_rdataset_t *negsig) -{ - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->getclosest == NULL) - return (ISC_R_NOTIMPLEMENTED); - return((rdataset->methods->getclosest)(rdataset, name, neg, negsig)); -} - -/* - * Additional cache stuff - */ -isc_result_t -dns_rdataset_getadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t **zonep, - dns_db_t **dbp, - dns_dbversion_t **versionp, - dns_dbnode_t **nodep, - dns_name_t *fname, - dns_message_t *msg, - isc_stdtime_t now) -{ - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - REQUIRE(zonep == NULL || *zonep == NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(versionp != NULL && *versionp == NULL); - REQUIRE(nodep != NULL && *nodep == NULL); - REQUIRE(fname != NULL); - REQUIRE(msg != NULL); - - if (acache != NULL && rdataset->methods->getadditional != NULL) { - return ((rdataset->methods->getadditional)(rdataset, type, - qtype, acache, - zonep, dbp, - versionp, nodep, - fname, msg, now)); - } - - return (ISC_R_FAILURE); -} - -isc_result_t -dns_rdataset_setadditional(dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype, - dns_acache_t *acache, - dns_zone_t *zone, - dns_db_t *db, - dns_dbversion_t *version, - dns_dbnode_t *node, - dns_name_t *fname) -{ - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (acache != NULL && rdataset->methods->setadditional != NULL) { - return ((rdataset->methods->setadditional)(rdataset, type, - qtype, acache, zone, - db, version, - node, fname)); - } - - return (ISC_R_FAILURE); -} - -isc_result_t -dns_rdataset_putadditional(dns_acache_t *acache, - dns_rdataset_t *rdataset, - dns_rdatasetadditional_t type, - dns_rdatatype_t qtype) -{ - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (acache != NULL && rdataset->methods->putadditional != NULL) { - return ((rdataset->methods->putadditional)(acache, rdataset, - type, qtype)); - } - - return (ISC_R_FAILURE); -} - -void -dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->settrust != NULL) - (rdataset->methods->settrust)(rdataset, trust); - else - rdataset->trust = trust; -} - -void -dns_rdataset_expire(dns_rdataset_t *rdataset) { - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->expire != NULL) - (rdataset->methods->expire)(rdataset); -} - -void -dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) { - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->clearprefetch != NULL) - (rdataset->methods->clearprefetch)(rdataset); -} - -void -dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) { - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->setownercase != NULL) - (rdataset->methods->setownercase)(rdataset, name); -} - -void -dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(rdataset->methods != NULL); - - if (rdataset->methods->getownercase != NULL) - (rdataset->methods->getownercase)(rdataset, name); -} - -void -dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, - bool acceptexpired) -{ - uint32_t ttl = 0; - - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(DNS_RDATASET_VALID(sigrdataset)); - REQUIRE(rrsig != NULL); - - /* - * If we accept expired RRsets keep them for no more than 120 seconds. - */ - if (acceptexpired && - (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) || - isc_serial_le(rrsig->timeexpire, now))) - ttl = 120; - else if (isc_serial_ge(rrsig->timeexpire, now)) - ttl = rrsig->timeexpire - now; - - ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl), - ISC_MIN(rrsig->originalttl, ttl)); - rdataset->ttl = ttl; - sigrdataset->ttl = ttl; -} diff --git a/lib/dns-pkcs11/rdatasetiter.c b/lib/dns-pkcs11/rdatasetiter.c deleted file mode 100644 index c9e670f..0000000 --- a/lib/dns-pkcs11/rdatasetiter.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include - -#include -#include - -void -dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { - /* - * Destroy '*iteratorp'. - */ - - REQUIRE(iteratorp != NULL); - REQUIRE(DNS_RDATASETITER_VALID(*iteratorp)); - - (*iteratorp)->methods->destroy(iteratorp); - - ENSURE(*iteratorp == NULL); -} - -isc_result_t -dns_rdatasetiter_first(dns_rdatasetiter_t *iterator) { - /* - * Move the rdataset cursor to the first rdataset at the node (if any). - */ - - REQUIRE(DNS_RDATASETITER_VALID(iterator)); - - return (iterator->methods->first(iterator)); -} - -isc_result_t -dns_rdatasetiter_next(dns_rdatasetiter_t *iterator) { - /* - * Move the rdataset cursor to the next rdataset at the node (if any). - */ - - REQUIRE(DNS_RDATASETITER_VALID(iterator)); - - return (iterator->methods->next(iterator)); -} - -void -dns_rdatasetiter_current(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset) -{ - /* - * Return the current rdataset. - */ - - REQUIRE(DNS_RDATASETITER_VALID(iterator)); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - REQUIRE(! dns_rdataset_isassociated(rdataset)); - - iterator->methods->current(iterator, rdataset); -} diff --git a/lib/dns-pkcs11/rdataslab.c b/lib/dns-pkcs11/rdataslab.c deleted file mode 100644 index b0f77b1..0000000 --- a/lib/dns-pkcs11/rdataslab.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include - -/* - * The rdataslab structure allows iteration to occur in both load order - * and DNSSEC order. The structure is as follows: - * - * header (reservelen bytes) - * record count (2 bytes) - * offset table (4 x record count bytes in load order) - * data records - * data length (2 bytes) - * order (2 bytes) - * meta data (1 byte for RRSIG's) - * data (data length bytes) - * - * If DNS_RDATASET_FIXED is defined to be zero (0) the format of a - * rdataslab is as follows: - * - * header (reservelen bytes) - * record count (2 bytes) - * data records - * data length (2 bytes) - * meta data (1 byte for RRSIG's) - * data (data length bytes) - * - * Offsets are from the end of the header. - * - * Load order traversal is performed by walking the offset table to find - * the start of the record (DNS_RDATASET_FIXED = 1). - * - * DNSSEC order traversal is performed by walking the data records. - * - * The order is stored with record to allow for efficient reconstruction - * of the offset table following a merge or subtraction. - * - * The iterator methods here currently only support DNSSEC order iteration. - * - * The iterator methods in rbtdb support both load order and DNSSEC order - * iteration. - * - * WARNING: - * rbtdb.c directly interacts with the slab's raw structures. If the - * structure changes then rbtdb.c also needs to be updated to reflect - * the changes. See the areas tagged with "RDATASLAB". - */ - -struct xrdata { - dns_rdata_t rdata; - unsigned int order; -}; - -/*% Note: the "const void *" are just to make qsort happy. */ -static int -compare_rdata(const void *p1, const void *p2) { - const struct xrdata *x1 = p1; - const struct xrdata *x2 = p2; - return (dns_rdata_compare(&x1->rdata, &x2->rdata)); -} - -#if DNS_RDATASET_FIXED -static void -fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable, - unsigned length) -{ - unsigned int i, j; - unsigned char *raw; - - for (i = 0, j = 0; i < length; i++) { - - if (offsettable[i] == 0) - continue; - - /* - * Fill in offset table. - */ - raw = &offsetbase[j*4 + 2]; - *raw++ = (offsettable[i] & 0xff000000) >> 24; - *raw++ = (offsettable[i] & 0xff0000) >> 16; - *raw++ = (offsettable[i] & 0xff00) >> 8; - *raw = offsettable[i] & 0xff; - - /* - * Fill in table index. - */ - raw = offsetbase + offsettable[i] + 2; - *raw++ = (j & 0xff00) >> 8; - *raw = j++ & 0xff; - } -} -#endif - -isc_result_t -dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, - isc_region_t *region, unsigned int reservelen) -{ - /* - * Use &removed as a sentinel pointer for duplicate - * rdata as rdata.data == NULL is valid. - */ - static unsigned char removed; - struct xrdata *x; - unsigned char *rawbuf; -#if DNS_RDATASET_FIXED - unsigned char *offsetbase; -#endif - unsigned int buflen; - isc_result_t result; - unsigned int nitems; - unsigned int nalloc; - unsigned int i; -#if DNS_RDATASET_FIXED - unsigned int *offsettable; -#endif - unsigned int length; - - buflen = reservelen + 2; - - nitems = dns_rdataset_count(rdataset); - - /* - * If there are no rdata then we can just need to allocate a header - * with zero a record count. - */ - if (nitems == 0) { - if (rdataset->type != 0) - return (ISC_R_FAILURE); - rawbuf = isc_mem_get(mctx, buflen); - if (rawbuf == NULL) - return (ISC_R_NOMEMORY); - region->base = rawbuf; - region->length = buflen; - rawbuf += reservelen; - *rawbuf++ = 0; - *rawbuf = 0; - return (ISC_R_SUCCESS); - } - - if (nitems > 0xffff) - return (ISC_R_NOSPACE); - - /* - * Remember the original number of items. - */ - nalloc = nitems; - x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata)); - if (x == NULL) - return (ISC_R_NOMEMORY); - - /* - * Save all of the rdata members into an array. - */ - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) - goto free_rdatas; - for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) { - INSIST(result == ISC_R_SUCCESS); - dns_rdata_init(&x[i].rdata); - dns_rdataset_current(rdataset, &x[i].rdata); - INSIST(x[i].rdata.data != &removed); -#if DNS_RDATASET_FIXED - x[i].order = i; -#endif - result = dns_rdataset_next(rdataset); - } - if (i != nalloc || result != ISC_R_NOMORE) { - /* - * Somehow we iterated over fewer rdatas than - * dns_rdataset_count() said there were or there - * were more items than dns_rdataset_count said - * there were. - */ - result = ISC_R_FAILURE; - goto free_rdatas; - } - - /* - * Put into DNSSEC order. - */ - if (nalloc > 1U) - qsort(x, nalloc, sizeof(struct xrdata), compare_rdata); - - /* - * Remove duplicates and compute the total storage required. - * - * If an rdata is not a duplicate, accumulate the storage size - * required for the rdata. We do not store the class, type, etc, - * just the rdata, so our overhead is 2 bytes for the number of - * records, and 8 for each rdata, (length(2), offset(4) and order(2)) - * and then the rdata itself. - */ - for (i = 1; i < nalloc; i++) { - if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) { - x[i-1].rdata.data = &removed; -#if DNS_RDATASET_FIXED - /* - * Preserve the least order so A, B, A -> A, B - * after duplicate removal. - */ - if (x[i-1].order < x[i].order) - x[i].order = x[i-1].order; -#endif - nitems--; - } else { -#if DNS_RDATASET_FIXED - buflen += (8 + x[i-1].rdata.length); -#else - buflen += (2 + x[i-1].rdata.length); -#endif - /* - * Provide space to store the per RR meta data. - */ - if (rdataset->type == dns_rdatatype_rrsig) - buflen++; - } - } - - /* - * Don't forget the last item! - */ -#if DNS_RDATASET_FIXED - buflen += (8 + x[i-1].rdata.length); -#else - buflen += (2 + x[i-1].rdata.length); -#endif - /* - * Provide space to store the per RR meta data. - */ - if (rdataset->type == dns_rdatatype_rrsig) - buflen++; - - /* - * Ensure that singleton types are actually singletons. - */ - if (nitems > 1 && dns_rdatatype_issingleton(rdataset->type)) { - /* - * We have a singleton type, but there's more than one - * RR in the rdataset. - */ - result = DNS_R_SINGLETON; - goto free_rdatas; - } - - /* - * Allocate the memory, set up a buffer, start copying in - * data. - */ - rawbuf = isc_mem_get(mctx, buflen); - if (rawbuf == NULL) { - result = ISC_R_NOMEMORY; - goto free_rdatas; - } - -#if DNS_RDATASET_FIXED - /* Allocate temporary offset table. */ - offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int)); - if (offsettable == NULL) { - isc_mem_put(mctx, rawbuf, buflen); - result = ISC_R_NOMEMORY; - goto free_rdatas; - } - memset(offsettable, 0, nalloc * sizeof(unsigned int)); -#endif - - region->base = rawbuf; - region->length = buflen; - - memset(rawbuf, 0, buflen); - rawbuf += reservelen; - -#if DNS_RDATASET_FIXED - offsetbase = rawbuf; -#endif - - *rawbuf++ = (nitems & 0xff00) >> 8; - *rawbuf++ = (nitems & 0x00ff); - -#if DNS_RDATASET_FIXED - /* Skip load order table. Filled in later. */ - rawbuf += nitems * 4; -#endif - - for (i = 0; i < nalloc; i++) { - if (x[i].rdata.data == &removed) - continue; -#if DNS_RDATASET_FIXED - offsettable[x[i].order] = rawbuf - offsetbase; -#endif - length = x[i].rdata.length; - if (rdataset->type == dns_rdatatype_rrsig) - length++; - INSIST(length <= 0xffff); - *rawbuf++ = (length & 0xff00) >> 8; - *rawbuf++ = (length & 0x00ff); -#if DNS_RDATASET_FIXED - rawbuf += 2; /* filled in later */ -#endif - /* - * Store the per RR meta data. - */ - if (rdataset->type == dns_rdatatype_rrsig) { - *rawbuf++ = (x[i].rdata.flags & DNS_RDATA_OFFLINE) ? - DNS_RDATASLAB_OFFLINE : 0; - } - memmove(rawbuf, x[i].rdata.data, x[i].rdata.length); - rawbuf += x[i].rdata.length; - } - -#if DNS_RDATASET_FIXED - fillin_offsets(offsetbase, offsettable, nalloc); - isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int)); -#endif - - result = ISC_R_SUCCESS; - - free_rdatas: - isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata)); - return (result); -} - -static void -rdataset_disassociate(dns_rdataset_t *rdataset) { - UNUSED(rdataset); -} - -static isc_result_t -rdataset_first(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - if (count == 0) { - rdataset->private5 = NULL; - return (ISC_R_NOMORE); - } -#if DNS_RDATASET_FIXED - raw += 2 + (4 * count); -#else - raw += 2; -#endif - /* - * The privateuint4 field is the number of rdata beyond the cursor - * position, so we decrement the total count by one before storing - * it. - */ - count--; - rdataset->privateuint4 = count; - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdataset_next(dns_rdataset_t *rdataset) { - unsigned int count; - unsigned int length; - unsigned char *raw; - - count = rdataset->privateuint4; - if (count == 0) - return (ISC_R_NOMORE); - count--; - rdataset->privateuint4 = count; - raw = rdataset->private5; - length = raw[0] * 256 + raw[1]; -#if DNS_RDATASET_FIXED - raw += length + 4; -#else - raw += length + 2; -#endif - rdataset->private5 = raw; - - return (ISC_R_SUCCESS); -} - -static void -rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - unsigned char *raw; - isc_region_t r; - unsigned int length; - unsigned int flags = 0; - - REQUIRE(rdataset != NULL); - REQUIRE(rdataset->private5 != NULL); - - raw = rdataset->private5; - - length = raw[0] * 256 + raw[1]; -#if DNS_RDATASET_FIXED - raw += 4; -#else - raw += 2; -#endif - if (rdataset->type == dns_rdatatype_rrsig) { - if (*raw & DNS_RDATASLAB_OFFLINE) - flags |= DNS_RDATA_OFFLINE; - length--; - raw++; - } - r.length = length; - r.base = raw; - dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); - rdata->flags |= flags; -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - *target = *source; - - /* - * Reset iterator state. - */ - target->privateuint4 = 0; - target->private5 = NULL; -} - -static unsigned int -rdataset_count(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; - unsigned int count; - - count = raw[0] * 256 + raw[1]; - - return (count); -} - -static dns_rdatasetmethods_t rdataset_methods = { - rdataset_disassociate, - rdataset_first, - rdataset_next, - rdataset_current, - rdataset_clone, - rdataset_count, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -void -dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, - dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, - dns_rdatatype_t covers, dns_ttl_t ttl, - dns_rdataset_t *rdataset) -{ - REQUIRE(slab != NULL); - REQUIRE(!dns_rdataset_isassociated(rdataset)); - - rdataset->methods = &rdataset_methods; - rdataset->rdclass = rdclass; - rdataset->type = rdtype; - rdataset->covers = covers; - rdataset->ttl = ttl; - rdataset->trust = 0; - rdataset->private1 = NULL; - rdataset->private2 = NULL; - rdataset->private3 = slab + reservelen; - - /* - * Reset iterator state. - */ - rdataset->privateuint4 = 0; - rdataset->private5 = NULL; -} - -unsigned int -dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) { - unsigned int count, length; - unsigned char *current; - - REQUIRE(slab != NULL); - - current = slab + reservelen; - count = *current++ * 256; - count += *current++; -#if DNS_RDATASET_FIXED - current += (4 * count); -#endif - while (count > 0) { - count--; - length = *current++ * 256; - length += *current++; -#if DNS_RDATASET_FIXED - current += length + 2; -#else - current += length; -#endif - } - - return ((unsigned int)(current - slab)); -} - -unsigned int -dns_rdataslab_count(unsigned char *slab, unsigned int reservelen) { - unsigned int count; - unsigned char *current; - - REQUIRE(slab != NULL); - - current = slab + reservelen; - count = *current++ * 256; - count += *current++; - return (count); -} - -/* - * Make the dns_rdata_t 'rdata' refer to the slab item - * beginning at '*current', which is part of a slab of type - * 'type' and class 'rdclass', and advance '*current' to - * point to the next item in the slab. - */ -static inline void -rdata_from_slab(unsigned char **current, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - dns_rdata_t *rdata) -{ - unsigned char *tcurrent = *current; - isc_region_t region; - unsigned int length; - bool offline = false; - - length = *tcurrent++ * 256; - length += *tcurrent++; - - if (type == dns_rdatatype_rrsig) { - if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0) - offline = true; - length--; - tcurrent++; - } - region.length = length; -#if DNS_RDATASET_FIXED - tcurrent += 2; -#endif - region.base = tcurrent; - tcurrent += region.length; - dns_rdata_fromregion(rdata, rdclass, type, ®ion); - if (offline) - rdata->flags |= DNS_RDATA_OFFLINE; - *current = tcurrent; -} - -/* - * Return true iff 'slab' (slab data of type 'type' and class 'rdclass') - * contains an rdata identical to 'rdata'. This does case insensitive - * comparisons per DNSSEC. - */ -static inline bool -rdata_in_slab(unsigned char *slab, unsigned int reservelen, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - dns_rdata_t *rdata) -{ - unsigned int count, i; - unsigned char *current; - dns_rdata_t trdata = DNS_RDATA_INIT; - int n; - - current = slab + reservelen; - count = *current++ * 256; - count += *current++; - -#if DNS_RDATASET_FIXED - current += (4 * count); -#endif - - for (i = 0; i < count; i++) { - rdata_from_slab(¤t, rdclass, type, &trdata); - - n = dns_rdata_compare(&trdata, rdata); - if (n == 0) - return (true); - if (n > 0) /* In DNSSEC order. */ - break; - dns_rdata_reset(&trdata); - } - return (false); -} - -isc_result_t -dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, - unsigned int reservelen, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int flags, unsigned char **tslabp) -{ - unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data; - unsigned int ocount, ncount, count, olength, tlength, tcount, length; - dns_rdata_t ordata = DNS_RDATA_INIT; - dns_rdata_t nrdata = DNS_RDATA_INIT; - bool added_something = false; - unsigned int oadded = 0; - unsigned int nadded = 0; - unsigned int nncount = 0; -#if DNS_RDATASET_FIXED - unsigned int oncount; - unsigned int norder = 0; - unsigned int oorder = 0; - unsigned char *offsetbase; - unsigned int *offsettable; -#endif - - /* - * XXX Need parameter to allow "delete rdatasets in nslab" merge, - * or perhaps another merge routine for this purpose. - */ - - REQUIRE(tslabp != NULL && *tslabp == NULL); - REQUIRE(oslab != NULL && nslab != NULL); - - ocurrent = oslab + reservelen; - ocount = *ocurrent++ * 256; - ocount += *ocurrent++; -#if DNS_RDATASET_FIXED - ocurrent += (4 * ocount); -#endif - ostart = ocurrent; - ncurrent = nslab + reservelen; - ncount = *ncurrent++ * 256; - ncount += *ncurrent++; -#if DNS_RDATASET_FIXED - ncurrent += (4 * ncount); -#endif - INSIST(ocount > 0 && ncount > 0); - -#if DNS_RDATASET_FIXED - oncount = ncount; -#endif - - /* - * Yes, this is inefficient! - */ - - /* - * Figure out the length of the old slab's data. - */ - olength = 0; - for (count = 0; count < ocount; count++) { - length = *ocurrent++ * 256; - length += *ocurrent++; -#if DNS_RDATASET_FIXED - olength += length + 8; - ocurrent += length + 2; -#else - olength += length + 2; - ocurrent += length; -#endif - } - - /* - * Start figuring out the target length and count. - */ - tlength = reservelen + 2 + olength; - tcount = ocount; - - /* - * Add in the length of rdata in the new slab that aren't in - * the old slab. - */ - do { - dns_rdata_init(&nrdata); - rdata_from_slab(&ncurrent, rdclass, type, &nrdata); - if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata)) - { - /* - * This rdata isn't in the old slab. - */ -#if DNS_RDATASET_FIXED - tlength += nrdata.length + 8; -#else - tlength += nrdata.length + 2; -#endif - if (type == dns_rdatatype_rrsig) - tlength++; - tcount++; - nncount++; - added_something = true; - } - ncount--; - } while (ncount > 0); - ncount = nncount; - - if (((flags & DNS_RDATASLAB_EXACT) != 0) && - (tcount != ncount + ocount)) - return (DNS_R_NOTEXACT); - - if (!added_something && (flags & DNS_RDATASLAB_FORCE) == 0) - return (DNS_R_UNCHANGED); - - /* - * Ensure that singleton types are actually singletons. - */ - if (tcount > 1 && dns_rdatatype_issingleton(type)) { - /* - * We have a singleton type, but there's more than one - * RR in the rdataset. - */ - return (DNS_R_SINGLETON); - } - - if (tcount > 0xffff) - return (ISC_R_NOSPACE); - - /* - * Copy the reserved area from the new slab. - */ - tstart = isc_mem_get(mctx, tlength); - if (tstart == NULL) - return (ISC_R_NOMEMORY); - memmove(tstart, nslab, reservelen); - tcurrent = tstart + reservelen; -#if DNS_RDATASET_FIXED - offsetbase = tcurrent; -#endif - - /* - * Write the new count. - */ - *tcurrent++ = (tcount & 0xff00) >> 8; - *tcurrent++ = (tcount & 0x00ff); - -#if DNS_RDATASET_FIXED - /* - * Skip offset table. - */ - tcurrent += (tcount * 4); - - offsettable = isc_mem_get(mctx, - (ocount + oncount) * sizeof(unsigned int)); - if (offsettable == NULL) { - isc_mem_put(mctx, tstart, tlength); - return (ISC_R_NOMEMORY); - } - memset(offsettable, 0, (ocount + oncount) * sizeof(unsigned int)); -#endif - - /* - * Merge the two slabs. - */ - ocurrent = ostart; - INSIST(ocount != 0); -#if DNS_RDATASET_FIXED - oorder = ocurrent[2] * 256 + ocurrent[3]; - INSIST(oorder < ocount); -#endif - rdata_from_slab(&ocurrent, rdclass, type, &ordata); - - ncurrent = nslab + reservelen + 2; -#if DNS_RDATASET_FIXED - ncurrent += (4 * oncount); -#endif - - if (ncount > 0) { - do { - dns_rdata_reset(&nrdata); -#if DNS_RDATASET_FIXED - norder = ncurrent[2] * 256 + ncurrent[3]; - - INSIST(norder < oncount); -#endif - rdata_from_slab(&ncurrent, rdclass, type, &nrdata); - } while (rdata_in_slab(oslab, reservelen, rdclass, - type, &nrdata)); - } - - while (oadded < ocount || nadded < ncount) { - bool fromold; - if (oadded == ocount) - fromold = false; - else if (nadded == ncount) - fromold = true; - else - fromold = dns_rdata_compare(&ordata, &nrdata) < 0; - if (fromold) { -#if DNS_RDATASET_FIXED - offsettable[oorder] = tcurrent - offsetbase; -#endif - length = ordata.length; - data = ordata.data; - if (type == dns_rdatatype_rrsig) { - length++; - data--; - } - *tcurrent++ = (length & 0xff00) >> 8; - *tcurrent++ = (length & 0x00ff); -#if DNS_RDATASET_FIXED - tcurrent += 2; /* fill in later */ -#endif - memmove(tcurrent, data, length); - tcurrent += length; - oadded++; - if (oadded < ocount) { - dns_rdata_reset(&ordata); -#if DNS_RDATASET_FIXED - oorder = ocurrent[2] * 256 + ocurrent[3]; - INSIST(oorder < ocount); -#endif - rdata_from_slab(&ocurrent, rdclass, type, - &ordata); - } - } else { -#if DNS_RDATASET_FIXED - offsettable[ocount + norder] = tcurrent - offsetbase; -#endif - length = nrdata.length; - data = nrdata.data; - if (type == dns_rdatatype_rrsig) { - length++; - data--; - } - *tcurrent++ = (length & 0xff00) >> 8; - *tcurrent++ = (length & 0x00ff); -#if DNS_RDATASET_FIXED - tcurrent += 2; /* fill in later */ -#endif - memmove(tcurrent, data, length); - tcurrent += length; - nadded++; - if (nadded < ncount) { - do { - dns_rdata_reset(&nrdata); -#if DNS_RDATASET_FIXED - norder = ncurrent[2] * 256 + ncurrent[3]; - INSIST(norder < oncount); -#endif - rdata_from_slab(&ncurrent, rdclass, - type, &nrdata); - } while (rdata_in_slab(oslab, reservelen, - rdclass, type, - &nrdata)); - } - } - } - -#if DNS_RDATASET_FIXED - fillin_offsets(offsetbase, offsettable, ocount + oncount); - - isc_mem_put(mctx, offsettable, - (ocount + oncount) * sizeof(unsigned int)); -#endif - - INSIST(tcurrent == tstart + tlength); - - *tslabp = tstart; - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, - unsigned int reservelen, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned int flags, unsigned char **tslabp) -{ - unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent; - unsigned int mcount, scount, rcount ,count, tlength, tcount, i; - dns_rdata_t srdata = DNS_RDATA_INIT; - dns_rdata_t mrdata = DNS_RDATA_INIT; -#if DNS_RDATASET_FIXED - unsigned char *offsetbase; - unsigned int *offsettable; - unsigned int order; -#endif - - REQUIRE(tslabp != NULL && *tslabp == NULL); - REQUIRE(mslab != NULL && sslab != NULL); - - mcurrent = mslab + reservelen; - mcount = *mcurrent++ * 256; - mcount += *mcurrent++; - scurrent = sslab + reservelen; - scount = *scurrent++ * 256; - scount += *scurrent++; - INSIST(mcount > 0 && scount > 0); - - /* - * Yes, this is inefficient! - */ - - /* - * Start figuring out the target length and count. - */ - tlength = reservelen + 2; - tcount = 0; - rcount = 0; - -#if DNS_RDATASET_FIXED - mcurrent += 4 * mcount; - scurrent += 4 * scount; -#endif - sstart = scurrent; - - /* - * Add in the length of rdata in the mslab that aren't in - * the sslab. - */ - for (i = 0; i < mcount; i++) { - unsigned char *mrdatabegin = mcurrent; - rdata_from_slab(&mcurrent, rdclass, type, &mrdata); - scurrent = sstart; - for (count = 0; count < scount; count++) { - dns_rdata_reset(&srdata); - rdata_from_slab(&scurrent, rdclass, type, &srdata); - if (dns_rdata_compare(&mrdata, &srdata) == 0) - break; - } - if (count == scount) { - /* - * This rdata isn't in the sslab, and thus isn't - * being subtracted. - */ - tlength += (unsigned int)(mcurrent - mrdatabegin); - tcount++; - } else - rcount++; - dns_rdata_reset(&mrdata); - } - -#if DNS_RDATASET_FIXED - tlength += (4 * tcount); -#endif - - /* - * Check that all the records originally existed. The numeric - * check only works as rdataslabs do not contain duplicates. - */ - if (((flags & DNS_RDATASLAB_EXACT) != 0) && (rcount != scount)) - return (DNS_R_NOTEXACT); - - /* - * Don't continue if the new rdataslab would be empty. - */ - if (tcount == 0) - return (DNS_R_NXRRSET); - - /* - * If nothing is going to change, we can stop. - */ - if (rcount == 0) - return (DNS_R_UNCHANGED); - - /* - * Copy the reserved area from the mslab. - */ - tstart = isc_mem_get(mctx, tlength); - if (tstart == NULL) - return (ISC_R_NOMEMORY); - memmove(tstart, mslab, reservelen); - tcurrent = tstart + reservelen; -#if DNS_RDATASET_FIXED - offsetbase = tcurrent; - - offsettable = isc_mem_get(mctx, mcount * sizeof(unsigned int)); - if (offsettable == NULL) { - isc_mem_put(mctx, tstart, tlength); - return (ISC_R_NOMEMORY); - } - memset(offsettable, 0, mcount * sizeof(unsigned int)); -#endif - - /* - * Write the new count. - */ - *tcurrent++ = (tcount & 0xff00) >> 8; - *tcurrent++ = (tcount & 0x00ff); - -#if DNS_RDATASET_FIXED - tcurrent += (4 * tcount); -#endif - - /* - * Copy the parts of mslab not in sslab. - */ - mcurrent = mslab + reservelen; - mcount = *mcurrent++ * 256; - mcount += *mcurrent++; -#if DNS_RDATASET_FIXED - mcurrent += (4 * mcount); -#endif - for (i = 0; i < mcount; i++) { - unsigned char *mrdatabegin = mcurrent; -#if DNS_RDATASET_FIXED - order = mcurrent[2] * 256 + mcurrent[3]; - INSIST(order < mcount); -#endif - rdata_from_slab(&mcurrent, rdclass, type, &mrdata); - scurrent = sstart; - for (count = 0; count < scount; count++) { - dns_rdata_reset(&srdata); - rdata_from_slab(&scurrent, rdclass, type, &srdata); - if (dns_rdata_compare(&mrdata, &srdata) == 0) - break; - } - if (count == scount) { - /* - * This rdata isn't in the sslab, and thus should be - * copied to the tslab. - */ - unsigned int length; - length = (unsigned int)(mcurrent - mrdatabegin); -#if DNS_RDATASET_FIXED - offsettable[order] = tcurrent - offsetbase; -#endif - memmove(tcurrent, mrdatabegin, length); - tcurrent += length; - } - dns_rdata_reset(&mrdata); - } - -#if DNS_RDATASET_FIXED - fillin_offsets(offsetbase, offsettable, mcount); - - isc_mem_put(mctx, offsettable, mcount * sizeof(unsigned int)); -#endif - - INSIST(tcurrent == tstart + tlength); - - *tslabp = tstart; - - return (ISC_R_SUCCESS); -} - -bool -dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen) -{ - unsigned char *current1, *current2; - unsigned int count1, count2; - unsigned int length1, length2; - - current1 = slab1 + reservelen; - count1 = *current1++ * 256; - count1 += *current1++; - - current2 = slab2 + reservelen; - count2 = *current2++ * 256; - count2 += *current2++; - - if (count1 != count2) - return (false); - -#if DNS_RDATASET_FIXED - current1 += (4 * count1); - current2 += (4 * count2); -#endif - - while (count1 > 0) { - length1 = *current1++ * 256; - length1 += *current1++; - - length2 = *current2++ * 256; - length2 += *current2++; - -#if DNS_RDATASET_FIXED - current1 += 2; - current2 += 2; -#endif - - if (length1 != length2 || - memcmp(current1, current2, length1) != 0) - return (false); - - current1 += length1; - current2 += length1; - - count1--; - } - return (true); -} - -bool -dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen, dns_rdataclass_t rdclass, - dns_rdatatype_t type) -{ - unsigned char *current1, *current2; - unsigned int count1, count2; - dns_rdata_t rdata1 = DNS_RDATA_INIT; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - - current1 = slab1 + reservelen; - count1 = *current1++ * 256; - count1 += *current1++; - - current2 = slab2 + reservelen; - count2 = *current2++ * 256; - count2 += *current2++; - - if (count1 != count2) - return (false); - -#if DNS_RDATASET_FIXED - current1 += (4 * count1); - current2 += (4 * count2); -#endif - - while (count1-- > 0) { - rdata_from_slab(¤t1, rdclass, type, &rdata1); - rdata_from_slab(¤t2, rdclass, type, &rdata2); - if (dns_rdata_compare(&rdata1, &rdata2) != 0) - return (false); - dns_rdata_reset(&rdata1); - dns_rdata_reset(&rdata2); - } - return (true); -} diff --git a/lib/dns-pkcs11/request.c b/lib/dns-pkcs11/request.c deleted file mode 100644 index 58ca40f..0000000 --- a/lib/dns-pkcs11/request.c +++ /dev/null @@ -1,1603 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M') -#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC) - -#define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!') -#define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC) - -typedef ISC_LIST(dns_request_t) dns_requestlist_t; - -#define DNS_REQUEST_NLOCKS 7 - -struct dns_requestmgr { - unsigned int magic; - isc_mutex_t lock; - isc_mem_t *mctx; - - /* locked */ - int32_t eref; - int32_t iref; - isc_timermgr_t *timermgr; - isc_socketmgr_t *socketmgr; - isc_taskmgr_t *taskmgr; - dns_dispatchmgr_t *dispatchmgr; - dns_dispatch_t *dispatchv4; - dns_dispatch_t *dispatchv6; - bool exiting; - isc_eventlist_t whenshutdown; - unsigned int hash; - isc_mutex_t locks[DNS_REQUEST_NLOCKS]; - dns_requestlist_t requests; -}; - -struct dns_request { - unsigned int magic; - unsigned int hash; - isc_mem_t *mctx; - int32_t flags; - ISC_LINK(dns_request_t) link; - isc_buffer_t *query; - isc_buffer_t *answer; - dns_requestevent_t *event; - dns_dispatch_t *dispatch; - dns_dispentry_t *dispentry; - isc_timer_t *timer; - dns_requestmgr_t *requestmgr; - isc_buffer_t *tsig; - dns_tsigkey_t *tsigkey; - isc_event_t ctlevent; - bool canceling; /* ctlevent outstanding */ - isc_sockaddr_t destaddr; - unsigned int udpcount; - isc_dscp_t dscp; -}; - -#define DNS_REQUEST_F_CONNECTING 0x0001 -#define DNS_REQUEST_F_SENDING 0x0002 -#define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise - synchronously canceled */ -#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */ -#define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */ -#define DNS_REQUEST_CANCELED(r) \ - (((r)->flags & DNS_REQUEST_F_CANCELED) != 0) -#define DNS_REQUEST_CONNECTING(r) \ - (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0) -#define DNS_REQUEST_SENDING(r) \ - (((r)->flags & DNS_REQUEST_F_SENDING) != 0) -#define DNS_REQUEST_TIMEDOUT(r) \ - (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0) - - -/*** - *** Forward - ***/ - -static void mgr_destroy(dns_requestmgr_t *requestmgr); -static void mgr_shutdown(dns_requestmgr_t *requestmgr); -static unsigned int mgr_gethash(dns_requestmgr_t *requestmgr); -static void send_shutdown_events(dns_requestmgr_t *requestmgr); - -static isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer, - unsigned int options, isc_mem_t *mctx); -static void req_senddone(isc_task_t *task, isc_event_t *event); -static void req_response(isc_task_t *task, isc_event_t *event); -static void req_timeout(isc_task_t *task, isc_event_t *event); -static isc_socket_t * req_getsocket(dns_request_t *request); -static void req_connected(isc_task_t *task, isc_event_t *event); -static void req_sendevent(dns_request_t *request, isc_result_t result); -static void req_cancel(dns_request_t *request); -static void req_destroy(dns_request_t *request); -static void req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); -static void do_cancel(isc_task_t *task, isc_event_t *event); - -/*** - *** Public - ***/ - -isc_result_t -dns_requestmgr_create(isc_mem_t *mctx, - isc_timermgr_t *timermgr, - isc_socketmgr_t *socketmgr, - isc_taskmgr_t *taskmgr, - dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, - dns_dispatch_t *dispatchv6, - dns_requestmgr_t **requestmgrp) -{ - dns_requestmgr_t *requestmgr; - isc_result_t result; - int i; - unsigned int dispattr; - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create"); - - REQUIRE(requestmgrp != NULL && *requestmgrp == NULL); - REQUIRE(timermgr != NULL); - REQUIRE(socketmgr != NULL); - REQUIRE(taskmgr != NULL); - REQUIRE(dispatchmgr != NULL); - - if (dispatchv4 != NULL) { - dispattr = dns_dispatch_getattributes(dispatchv4); - REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); - } - if (dispatchv6 != NULL) { - dispattr = dns_dispatch_getattributes(dispatchv6); - REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); - } - - requestmgr = isc_mem_get(mctx, sizeof(*requestmgr)); - if (requestmgr == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&requestmgr->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); - return (result); - } - for (i = 0; i < DNS_REQUEST_NLOCKS; i++) { - result = isc_mutex_init(&requestmgr->locks[i]); - if (result != ISC_R_SUCCESS) { - while (--i >= 0) - DESTROYLOCK(&requestmgr->locks[i]); - DESTROYLOCK(&requestmgr->lock); - isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); - return (result); - } - } - requestmgr->timermgr = timermgr; - requestmgr->socketmgr = socketmgr; - requestmgr->taskmgr = taskmgr; - requestmgr->dispatchmgr = dispatchmgr; - requestmgr->dispatchv4 = NULL; - if (dispatchv4 != NULL) - dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4); - requestmgr->dispatchv6 = NULL; - if (dispatchv6 != NULL) - dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6); - requestmgr->mctx = NULL; - isc_mem_attach(mctx, &requestmgr->mctx); - requestmgr->eref = 1; /* implicit attach */ - requestmgr->iref = 0; - ISC_LIST_INIT(requestmgr->whenshutdown); - ISC_LIST_INIT(requestmgr->requests); - requestmgr->exiting = false; - requestmgr->hash = 0; - requestmgr->magic = REQUESTMGR_MAGIC; - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr); - - *requestmgrp = requestmgr; - return (ISC_R_SUCCESS); -} - -void -dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, - isc_event_t **eventp) -{ - isc_task_t *tclone; - isc_event_t *event; - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown"); - - REQUIRE(VALID_REQUESTMGR(requestmgr)); - REQUIRE(eventp != NULL); - - event = *eventp; - *eventp = NULL; - - LOCK(&requestmgr->lock); - - if (requestmgr->exiting) { - /* - * We're already shutdown. Send the event. - */ - event->ev_sender = requestmgr; - isc_task_send(task, &event); - } else { - tclone = NULL; - isc_task_attach(task, &tclone); - event->ev_sender = tclone; - ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link); - } - UNLOCK(&requestmgr->lock); -} - -void -dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) { - - REQUIRE(VALID_REQUESTMGR(requestmgr)); - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr); - - LOCK(&requestmgr->lock); - mgr_shutdown(requestmgr); - UNLOCK(&requestmgr->lock); -} - -static void -mgr_shutdown(dns_requestmgr_t *requestmgr) { - dns_request_t *request; - - /* - * Caller holds lock. - */ - if (!requestmgr->exiting) { - requestmgr->exiting = true; - for (request = ISC_LIST_HEAD(requestmgr->requests); - request != NULL; - request = ISC_LIST_NEXT(request, link)) { - dns_request_cancel(request); - } - if (requestmgr->iref == 0) { - INSIST(ISC_LIST_EMPTY(requestmgr->requests)); - send_shutdown_events(requestmgr); - } - } -} - -static void -requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) { - - /* - * Locked by caller. - */ - - REQUIRE(VALID_REQUESTMGR(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - REQUIRE(!source->exiting); - - source->iref++; - *targetp = source; - - req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d", - source, source->eref, source->iref); -} - -static void -requestmgr_detach(dns_requestmgr_t **requestmgrp) { - dns_requestmgr_t *requestmgr; - bool need_destroy = false; - - REQUIRE(requestmgrp != NULL); - requestmgr = *requestmgrp; - REQUIRE(VALID_REQUESTMGR(requestmgr)); - - *requestmgrp = NULL; - LOCK(&requestmgr->lock); - INSIST(requestmgr->iref > 0); - requestmgr->iref--; - - req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d", - requestmgr, requestmgr->eref, requestmgr->iref); - - if (requestmgr->iref == 0 && requestmgr->exiting) { - INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL); - send_shutdown_events(requestmgr); - if (requestmgr->eref == 0) - need_destroy = true; - } - UNLOCK(&requestmgr->lock); - - if (need_destroy) - mgr_destroy(requestmgr); -} - -void -dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) { - - REQUIRE(VALID_REQUESTMGR(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - REQUIRE(!source->exiting); - - LOCK(&source->lock); - source->eref++; - *targetp = source; - UNLOCK(&source->lock); - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d", - source, source->eref, source->iref); -} - -void -dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) { - dns_requestmgr_t *requestmgr; - bool need_destroy = false; - - REQUIRE(requestmgrp != NULL); - requestmgr = *requestmgrp; - REQUIRE(VALID_REQUESTMGR(requestmgr)); - - LOCK(&requestmgr->lock); - INSIST(requestmgr->eref > 0); - requestmgr->eref--; - - req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d", - requestmgr, requestmgr->eref, requestmgr->iref); - - if (requestmgr->eref == 0 && requestmgr->iref == 0) { - INSIST(requestmgr->exiting && - ISC_LIST_HEAD(requestmgr->requests) == NULL); - need_destroy = true; - } - UNLOCK(&requestmgr->lock); - - if (need_destroy) - mgr_destroy(requestmgr); - - *requestmgrp = NULL; -} - -static void -send_shutdown_events(dns_requestmgr_t *requestmgr) { - isc_event_t *event, *next_event; - isc_task_t *etask; - - req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr); - - /* - * Caller must be holding the manager lock. - */ - for (event = ISC_LIST_HEAD(requestmgr->whenshutdown); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link); - etask = event->ev_sender; - event->ev_sender = requestmgr; - isc_task_sendanddetach(&etask, &event); - } -} - -static void -mgr_destroy(dns_requestmgr_t *requestmgr) { - int i; - isc_mem_t *mctx; - - req_log(ISC_LOG_DEBUG(3), "mgr_destroy"); - - REQUIRE(requestmgr->eref == 0); - REQUIRE(requestmgr->iref == 0); - - DESTROYLOCK(&requestmgr->lock); - for (i = 0; i < DNS_REQUEST_NLOCKS; i++) - DESTROYLOCK(&requestmgr->locks[i]); - if (requestmgr->dispatchv4 != NULL) - dns_dispatch_detach(&requestmgr->dispatchv4); - if (requestmgr->dispatchv6 != NULL) - dns_dispatch_detach(&requestmgr->dispatchv6); - requestmgr->magic = 0; - mctx = requestmgr->mctx; - isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); - isc_mem_detach(&mctx); -} - -static unsigned int -mgr_gethash(dns_requestmgr_t *requestmgr) { - req_log(ISC_LOG_DEBUG(3), "mgr_gethash"); - /* - * Locked by caller. - */ - requestmgr->hash++; - return (requestmgr->hash % DNS_REQUEST_NLOCKS); -} - -static inline isc_result_t -req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) { - isc_region_t r; - isc_socket_t *sock; - isc_socketevent_t *sendevent; - isc_result_t result; - - req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); - - REQUIRE(VALID_REQUEST(request)); - sock = req_getsocket(request); - isc_buffer_usedregion(request->query, &r); - /* - * We could connect the socket when we are using an exclusive dispatch - * as we do in resolver.c, but we prefer implementation simplicity - * at this moment. - */ - sendevent = isc_socket_socketevent(request->mctx, sock, - ISC_SOCKEVENT_SENDDONE, - req_senddone, request); - if (sendevent == NULL) - return (ISC_R_NOMEMORY); - if (request->dscp == -1) { - sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; - sendevent->dscp = 0; - } else { - sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; - sendevent->dscp = request->dscp; - } - - request->flags |= DNS_REQUEST_F_SENDING; - result = isc_socket_sendto2(sock, &r, task, address, NULL, - sendevent, 0); - if (result != ISC_R_SUCCESS) - request->flags &= ~DNS_REQUEST_F_SENDING; - return (result); -} - -static isc_result_t -new_request(isc_mem_t *mctx, dns_request_t **requestp) -{ - dns_request_t *request; - - request = isc_mem_get(mctx, sizeof(*request)); - if (request == NULL) - return (ISC_R_NOMEMORY); - - /* - * Zero structure. - */ - request->magic = 0; - request->mctx = NULL; - request->flags = 0; - ISC_LINK_INIT(request, link); - request->query = NULL; - request->answer = NULL; - request->event = NULL; - request->dispatch = NULL; - request->dispentry = NULL; - request->timer = NULL; - request->requestmgr = NULL; - request->tsig = NULL; - request->tsigkey = NULL; - request->dscp = -1; - ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL, - DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL, - NULL, NULL); - request->canceling = false; - request->udpcount = 0; - - isc_mem_attach(mctx, &request->mctx); - - request->magic = REQUEST_MAGIC; - *requestp = request; - return (ISC_R_SUCCESS); -} - - -static bool -isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) { - dns_acl_t *blackhole; - isc_netaddr_t netaddr; - int match; - bool drop = false; - char netaddrstr[ISC_NETADDR_FORMATSIZE]; - - blackhole = dns_dispatchmgr_getblackhole(dispatchmgr); - if (blackhole != NULL) { - isc_netaddr_fromsockaddr(&netaddr, destaddr); - if (dns_acl_match(&netaddr, NULL, blackhole, - NULL, &match, NULL) == ISC_R_SUCCESS && - match > 0) - drop = true; - } - if (drop) { - isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr)); - req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr); - } - return (drop); -} - -static isc_result_t -create_tcp_dispatch(bool newtcp, bool share, - dns_requestmgr_t *requestmgr, - isc_sockaddr_t *srcaddr, - isc_sockaddr_t *destaddr, isc_dscp_t dscp, - bool *connected, dns_dispatch_t **dispatchp) -{ - isc_result_t result; - isc_socket_t *sock = NULL; - isc_sockaddr_t src; - unsigned int attrs; - isc_sockaddr_t bind_any; - - if (!newtcp && share) { - result = dns_dispatch_gettcp2(requestmgr->dispatchmgr, - destaddr, srcaddr, - connected, dispatchp); - if (result == ISC_R_SUCCESS) { - char peer[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(destaddr, peer, sizeof(peer)); - req_log(ISC_LOG_DEBUG(1), "attached to %s TCP " - "connection to %s", - *connected ? "existing" : "pending", peer); - return (result); - } - } else if (!newtcp) { - result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr, - srcaddr, dispatchp); - if (result == ISC_R_SUCCESS) { - char peer[ISC_SOCKADDR_FORMATSIZE]; - - *connected = true; - isc_sockaddr_format(destaddr, peer, sizeof(peer)); - req_log(ISC_LOG_DEBUG(1), "attached to existing TCP " - "connection to %s", peer); - return (result); - } - } - - result = isc_socket_create(requestmgr->socketmgr, - isc_sockaddr_pf(destaddr), - isc_sockettype_tcp, &sock); - if (result != ISC_R_SUCCESS) - return (result); -#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT - if (srcaddr == NULL) { - isc_sockaddr_anyofpf(&bind_any, - isc_sockaddr_pf(destaddr)); - result = isc_socket_bind(sock, &bind_any, 0); - } else { - src = *srcaddr; - isc_sockaddr_setport(&src, 0); - result = isc_socket_bind(sock, &src, 0); - } - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - attrs = 0; - attrs |= DNS_DISPATCHATTR_TCP; - if (isc_sockaddr_pf(destaddr) == AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - - isc_socket_dscp(sock, dscp); - result = dns_dispatch_createtcp2(requestmgr->dispatchmgr, - sock, requestmgr->taskmgr, - srcaddr, destaddr, - 4096, 32768, 32768, 16411, 16433, - attrs, dispatchp); -cleanup: - isc_socket_detach(&sock); - return (result); -} - -static isc_result_t -find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, - isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp) -{ - dns_dispatch_t *disp = NULL; - unsigned int attrs, attrmask; - - if (srcaddr == NULL) { - switch (isc_sockaddr_pf(destaddr)) { - case PF_INET: - disp = requestmgr->dispatchv4; - break; - - case PF_INET6: - disp = requestmgr->dispatchv6; - break; - - default: - return (ISC_R_NOTIMPLEMENTED); - } - if (disp == NULL) - return (ISC_R_FAMILYNOSUPPORT); - dns_dispatch_attach(disp, dispatchp); - return (ISC_R_SUCCESS); - } - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(srcaddr)) { - case PF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - - case PF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - - default: - return (ISC_R_NOTIMPLEMENTED); - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - return (dns_dispatch_getudp(requestmgr->dispatchmgr, - requestmgr->socketmgr, - requestmgr->taskmgr, - srcaddr, 4096, - 32768, 32768, 16411, 16433, - attrs, attrmask, - dispatchp)); -} - -static isc_result_t -get_dispatch(bool tcp, bool newtcp, bool share, - dns_requestmgr_t *requestmgr, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - isc_dscp_t dscp, bool *connected, - dns_dispatch_t **dispatchp) -{ - isc_result_t result; - - if (tcp) - result = create_tcp_dispatch(newtcp, share, requestmgr, - srcaddr, destaddr, dscp, - connected, dispatchp); - else - result = find_udp_dispatch(requestmgr, srcaddr, - destaddr, dispatchp); - return (result); -} - -static isc_result_t -set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) { - isc_time_t expires; - isc_interval_t interval; - isc_result_t result; - isc_timertype_t timertype; - - isc_interval_set(&interval, timeout, 0); - result = isc_time_nowplusinterval(&expires, &interval); - isc_interval_set(&interval, udpresend, 0); - - timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once; - if (result == ISC_R_SUCCESS) - result = isc_timer_reset(timer, timertype, &expires, - &interval, false); - return (result); -} - -isc_result_t -dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - return(dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, - -1, options, timeout, 0, 0, task, action, - arg, requestp)); -} - -isc_result_t -dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - unsigned int udptimeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - unsigned int udpretries = 0; - - if (udptimeout != 0) - udpretries = timeout / udptimeout; - - return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, - -1, options, timeout, udptimeout, - udpretries, task, action, arg, - requestp)); -} - -isc_result_t -dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, - -1, options, timeout, udptimeout, - udpretries, task, action, arg, - requestp)); -} - -isc_result_t -dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - isc_dscp_t dscp, unsigned int options, - unsigned int timeout, unsigned int udptimeout, - unsigned int udpretries, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - dns_request_t *request = NULL; - isc_task_t *tclone = NULL; - isc_socket_t *sock = NULL; - isc_result_t result; - isc_mem_t *mctx; - dns_messageid_t id; - bool tcp = false; - bool newtcp = false; - bool share = false; - isc_region_t r; - bool connected = false; - unsigned int dispopt = 0; - - REQUIRE(VALID_REQUESTMGR(requestmgr)); - REQUIRE(msgbuf != NULL); - REQUIRE(destaddr != NULL); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - REQUIRE(requestp != NULL && *requestp == NULL); - REQUIRE(timeout > 0); - if (srcaddr != NULL) - REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); - - mctx = requestmgr->mctx; - - req_log(ISC_LOG_DEBUG(3), "dns_request_createraw"); - - if (isblackholed(requestmgr->dispatchmgr, destaddr)) - return (DNS_R_BLACKHOLED); - - request = NULL; - result = new_request(mctx, &request); - if (result != ISC_R_SUCCESS) - return (result); - - if (udptimeout == 0 && udpretries != 0) { - udptimeout = timeout / (udpretries + 1); - if (udptimeout == 0) - udptimeout = 1; - } - request->udpcount = udpretries; - request->dscp = dscp; - - /* - * Create timer now. We will set it below once. - */ - result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive, - NULL, NULL, task, req_timeout, request, - &request->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - request->event = (dns_requestevent_t *) - isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE, - action, arg, sizeof(dns_requestevent_t)); - if (request->event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_task_attach(task, &tclone); - request->event->ev_sender = task; - request->event->request = request; - request->event->result = ISC_R_FAILURE; - - isc_buffer_usedregion(msgbuf, &r); - if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) { - result = DNS_R_FORMERR; - goto cleanup; - } - - if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) - tcp = true; - share = (options & DNS_REQUESTOPT_SHARE); - - again: - result = get_dispatch(tcp, newtcp, share, requestmgr, - srcaddr, destaddr, dscp, - &connected, &request->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if ((options & DNS_REQUESTOPT_FIXEDID) != 0) { - id = (r.base[0] << 8) | r.base[1]; - dispopt |= DNS_DISPATCHOPT_FIXEDID; - } - - result = dns_dispatch_addresponse3(request->dispatch, dispopt, - destaddr, task, req_response, - request, &id, &request->dispentry, - requestmgr->socketmgr); - if (result != ISC_R_SUCCESS) { - if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) { - newtcp = true; - connected = false; - dns_dispatch_detach(&request->dispatch); - goto again; - } - goto cleanup; - } - - sock = req_getsocket(request); - INSIST(sock != NULL); - - result = isc_buffer_allocate(mctx, &request->query, - r.length + (tcp ? 2 : 0)); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (tcp) - isc_buffer_putuint16(request->query, (uint16_t)r.length); - result = isc_buffer_copyregion(request->query, &r); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* Add message ID. */ - isc_buffer_usedregion(request->query, &r); - if (tcp) - isc_region_consume(&r, 2); - r.base[0] = (id>>8) & 0xff; - r.base[1] = id & 0xff; - - LOCK(&requestmgr->lock); - if (requestmgr->exiting) { - UNLOCK(&requestmgr->lock); - result = ISC_R_SHUTTINGDOWN; - goto cleanup; - } - requestmgr_attach(requestmgr, &request->requestmgr); - request->hash = mgr_gethash(requestmgr); - ISC_LIST_APPEND(requestmgr->requests, request, link); - UNLOCK(&requestmgr->lock); - - result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout); - if (result != ISC_R_SUCCESS) - goto unlink; - - request->destaddr = *destaddr; - if (tcp && !connected) { - result = isc_socket_connect(sock, destaddr, task, - req_connected, request); - if (result != ISC_R_SUCCESS) - goto unlink; - request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP; - } else { - result = req_send(request, task, connected ? NULL : destaddr); - if (result != ISC_R_SUCCESS) - goto unlink; - } - - req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", - request); - *requestp = request; - return (ISC_R_SUCCESS); - - unlink: - LOCK(&requestmgr->lock); - ISC_LIST_UNLINK(requestmgr->requests, request, link); - UNLOCK(&requestmgr->lock); - - cleanup: - if (tclone != NULL) - isc_task_detach(&tclone); - req_destroy(request); - req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s", - dns_result_totext(result)); - return (result); -} - -isc_result_t -dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *address, unsigned int options, - dns_tsigkey_t *key, - unsigned int timeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - return (dns_request_createvia4(requestmgr, message, NULL, address, - -1, options, key, timeout, 0, 0, task, - action, arg, requestp)); -} - -isc_result_t -dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - return(dns_request_createvia4(requestmgr, message, srcaddr, destaddr, - -1, options, key, timeout, 0, 0, task, - action, arg, requestp)); -} - -isc_result_t -dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, unsigned int udptimeout, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - unsigned int udpretries = 0; - - if (udptimeout != 0) - udpretries = timeout / udptimeout; - return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr, - -1, options, key, timeout, udptimeout, - udpretries, task, action, arg, - requestp)); -} - -isc_result_t -dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - unsigned int options, dns_tsigkey_t *key, - unsigned int timeout, unsigned int udptimeout, - unsigned int udpretries, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr, - -1, options, key, timeout, udptimeout, - udpretries, task, action, arg, - requestp)); -} - -isc_result_t -dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - isc_dscp_t dscp, unsigned int options, - dns_tsigkey_t *key, unsigned int timeout, - unsigned int udptimeout, unsigned int udpretries, - isc_task_t *task, isc_taskaction_t action, void *arg, - dns_request_t **requestp) -{ - dns_request_t *request = NULL; - isc_task_t *tclone = NULL; - isc_socket_t *sock = NULL; - isc_result_t result; - isc_mem_t *mctx; - dns_messageid_t id; - bool tcp; - bool share; - bool settsigkey = true; - bool connected = false; - - REQUIRE(VALID_REQUESTMGR(requestmgr)); - REQUIRE(message != NULL); - REQUIRE(destaddr != NULL); - REQUIRE(task != NULL); - REQUIRE(action != NULL); - REQUIRE(requestp != NULL && *requestp == NULL); - REQUIRE(timeout > 0); - - mctx = requestmgr->mctx; - - req_log(ISC_LOG_DEBUG(3), "dns_request_createvia"); - - if (srcaddr != NULL && - isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr)) - return (ISC_R_FAMILYMISMATCH); - - if (isblackholed(requestmgr->dispatchmgr, destaddr)) - return (DNS_R_BLACKHOLED); - - request = NULL; - result = new_request(mctx, &request); - if (result != ISC_R_SUCCESS) - return (result); - - if (udptimeout == 0 && udpretries != 0) { - udptimeout = timeout / (udpretries + 1); - if (udptimeout == 0) - udptimeout = 1; - } - request->udpcount = udpretries; - request->dscp = dscp; - - /* - * Create timer now. We will set it below once. - */ - result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive, - NULL, NULL, task, req_timeout, request, - &request->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - request->event = (dns_requestevent_t *) - isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE, - action, arg, sizeof(dns_requestevent_t)); - if (request->event == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_task_attach(task, &tclone); - request->event->ev_sender = task; - request->event->request = request; - request->event->result = ISC_R_FAILURE; - if (key != NULL) - dns_tsigkey_attach(key, &request->tsigkey); - - use_tcp: - tcp = ((options & DNS_REQUESTOPT_TCP) != 0); - share = ((options & DNS_REQUESTOPT_SHARE) != 0); - result = get_dispatch(tcp, false, share, - requestmgr, srcaddr, destaddr, - dscp, &connected, &request->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_dispatch_addresponse2(request->dispatch, destaddr, task, - req_response, request, &id, - &request->dispentry, - requestmgr->socketmgr); - if (result != ISC_R_SUCCESS) - goto cleanup; - sock = req_getsocket(request); - INSIST(sock != NULL); - - message->id = id; - if (settsigkey) { - result = dns_message_settsigkey(message, request->tsigkey); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - result = req_render(message, &request->query, options, mctx); - if (result == DNS_R_USETCP && - (options & DNS_REQUESTOPT_TCP) == 0) { - /* - * Try again using TCP. - */ - dns_message_renderreset(message); - dns_dispatch_removeresponse(&request->dispentry, NULL); - dns_dispatch_detach(&request->dispatch); - sock = NULL; - options |= DNS_REQUESTOPT_TCP; - settsigkey = false; - goto use_tcp; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_message_getquerytsig(message, mctx, &request->tsig); - if (result != ISC_R_SUCCESS) - goto cleanup; - - LOCK(&requestmgr->lock); - if (requestmgr->exiting) { - UNLOCK(&requestmgr->lock); - result = ISC_R_SHUTTINGDOWN; - goto cleanup; - } - requestmgr_attach(requestmgr, &request->requestmgr); - request->hash = mgr_gethash(requestmgr); - ISC_LIST_APPEND(requestmgr->requests, request, link); - UNLOCK(&requestmgr->lock); - - result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout); - if (result != ISC_R_SUCCESS) - goto unlink; - - request->destaddr = *destaddr; - if (tcp && !connected) { - result = isc_socket_connect(sock, destaddr, task, - req_connected, request); - if (result != ISC_R_SUCCESS) - goto unlink; - request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP; - } else { - result = req_send(request, task, connected ? NULL : destaddr); - if (result != ISC_R_SUCCESS) - goto unlink; - } - - req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", - request); - *requestp = request; - return (ISC_R_SUCCESS); - - unlink: - LOCK(&requestmgr->lock); - ISC_LIST_UNLINK(requestmgr->requests, request, link); - UNLOCK(&requestmgr->lock); - - cleanup: - if (tclone != NULL) - isc_task_detach(&tclone); - req_destroy(request); - req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s", - dns_result_totext(result)); - return (result); -} - -static isc_result_t -req_render(dns_message_t *message, isc_buffer_t **bufferp, - unsigned int options, isc_mem_t *mctx) -{ - isc_buffer_t *buf1 = NULL; - isc_buffer_t *buf2 = NULL; - isc_result_t result; - isc_region_t r; - bool tcp = false; - dns_compress_t cctx; - bool cleanup_cctx = false; - - REQUIRE(bufferp != NULL && *bufferp == NULL); - - req_log(ISC_LOG_DEBUG(3), "request_render"); - - /* - * Create buffer able to hold largest possible message. - */ - result = isc_buffer_allocate(mctx, &buf1, 65535); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_compress_init(&cctx, -1, mctx); - if (result != ISC_R_SUCCESS) - return (result); - cleanup_cctx = true; - - if ((options & DNS_REQUESTOPT_CASE) != 0) - dns_compress_setsensitive(&cctx, true); - - /* - * Render message. - */ - result = dns_message_renderbegin(message, &cctx, buf1); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_renderend(message); - if (result != ISC_R_SUCCESS) - goto cleanup; - - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - - /* - * Copy rendered message to exact sized buffer. - */ - isc_buffer_usedregion(buf1, &r); - if ((options & DNS_REQUESTOPT_TCP) != 0) { - tcp = true; - } else if (r.length > 512) { - result = DNS_R_USETCP; - goto cleanup; - } - result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0)); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (tcp) - isc_buffer_putuint16(buf2, (uint16_t)r.length); - result = isc_buffer_copyregion(buf2, &r); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Cleanup and return. - */ - isc_buffer_free(&buf1); - *bufferp = buf2; - return (ISC_R_SUCCESS); - - cleanup: - dns_message_renderreset(message); - if (buf1 != NULL) - isc_buffer_free(&buf1); - if (buf2 != NULL) - isc_buffer_free(&buf2); - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - return (result); -} - - -/* - * If this request is no longer waiting for events, - * send the completion event. This will ultimately - * cause the request to be destroyed. - * - * Requires: - * 'request' is locked by the caller. - */ -static void -send_if_done(dns_request_t *request, isc_result_t result) { - if (request->event != NULL && !request->canceling) - req_sendevent(request, result); -} - -/* - * Handle the control event. - */ -static void -do_cancel(isc_task_t *task, isc_event_t *event) { - dns_request_t *request = event->ev_arg; - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL); - LOCK(&request->requestmgr->locks[request->hash]); - request->canceling = false; - if (!DNS_REQUEST_CANCELED(request)) - req_cancel(request); - send_if_done(request, ISC_R_CANCELED); - UNLOCK(&request->requestmgr->locks[request->hash]); -} - -void -dns_request_cancel(dns_request_t *request) { - REQUIRE(VALID_REQUEST(request)); - - req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request); - - REQUIRE(VALID_REQUEST(request)); - - LOCK(&request->requestmgr->locks[request->hash]); - if (!request->canceling && !DNS_REQUEST_CANCELED(request)) { - isc_event_t *ev = &request->ctlevent; - isc_task_send(request->event->ev_sender, &ev); - request->canceling = true; - } - UNLOCK(&request->requestmgr->locks[request->hash]); -} - -isc_result_t -dns_request_getresponse(dns_request_t *request, dns_message_t *message, - unsigned int options) -{ - isc_result_t result; - - REQUIRE(VALID_REQUEST(request)); - REQUIRE(request->answer != NULL); - - req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p", - request); - - result = dns_message_setquerytsig(message, request->tsig); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_settsigkey(message, request->tsigkey); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_message_parse(message, request->answer, options); - if (result != ISC_R_SUCCESS) - return (result); - if (request->tsigkey != NULL) - result = dns_tsig_verify(request->answer, message, NULL, NULL); - return (result); -} - -bool -dns_request_usedtcp(dns_request_t *request) { - REQUIRE(VALID_REQUEST(request)); - - return ((request->flags & DNS_REQUEST_F_TCP) != 0); -} - -void -dns_request_destroy(dns_request_t **requestp) { - dns_request_t *request; - - REQUIRE(requestp != NULL && VALID_REQUEST(*requestp)); - - request = *requestp; - - req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request); - - LOCK(&request->requestmgr->lock); - LOCK(&request->requestmgr->locks[request->hash]); - ISC_LIST_UNLINK(request->requestmgr->requests, request, link); - INSIST(!DNS_REQUEST_CONNECTING(request)); - INSIST(!DNS_REQUEST_SENDING(request)); - UNLOCK(&request->requestmgr->locks[request->hash]); - UNLOCK(&request->requestmgr->lock); - - /* - * These should have been cleaned up by req_cancel() before - * the completion event was sent. - */ - INSIST(!ISC_LINK_LINKED(request, link)); - INSIST(request->dispentry == NULL); - INSIST(request->dispatch == NULL); - INSIST(request->timer == NULL); - - req_destroy(request); - - *requestp = NULL; -} - -/*** - *** Private: request. - ***/ - -static isc_socket_t * -req_getsocket(dns_request_t *request) { - unsigned int dispattr; - isc_socket_t *sock; - - dispattr = dns_dispatch_getattributes(request->dispatch); - if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - INSIST(request->dispentry != NULL); - sock = dns_dispatch_getentrysocket(request->dispentry); - } else - sock = dns_dispatch_getsocket(request->dispatch); - - return (sock); -} - -static void -req_connected(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - isc_result_t result; - dns_request_t *request = event->ev_arg; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); - REQUIRE(VALID_REQUEST(request)); - REQUIRE(DNS_REQUEST_CONNECTING(request)); - - req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request); - - LOCK(&request->requestmgr->locks[request->hash]); - request->flags &= ~DNS_REQUEST_F_CONNECTING; - - if (DNS_REQUEST_CANCELED(request)) { - /* - * Send delayed event. - */ - if (DNS_REQUEST_TIMEDOUT(request)) - send_if_done(request, ISC_R_TIMEDOUT); - else - send_if_done(request, ISC_R_CANCELED); - } else { - dns_dispatch_starttcp(request->dispatch); - result = sevent->result; - if (result == ISC_R_SUCCESS) - result = req_send(request, task, NULL); - - if (result != ISC_R_SUCCESS) { - req_cancel(request); - send_if_done(request, ISC_R_CANCELED); - } - } - UNLOCK(&request->requestmgr->locks[request->hash]); - isc_event_free(&event); -} - -static void -req_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - dns_request_t *request = event->ev_arg; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); - REQUIRE(VALID_REQUEST(request)); - REQUIRE(DNS_REQUEST_SENDING(request)); - - req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request); - - UNUSED(task); - - LOCK(&request->requestmgr->locks[request->hash]); - request->flags &= ~DNS_REQUEST_F_SENDING; - - if (DNS_REQUEST_CANCELED(request)) { - /* - * Send delayed event. - */ - if (DNS_REQUEST_TIMEDOUT(request)) - send_if_done(request, ISC_R_TIMEDOUT); - else - send_if_done(request, ISC_R_CANCELED); - } else if (sevent->result != ISC_R_SUCCESS) { - req_cancel(request); - send_if_done(request, ISC_R_CANCELED); - } - UNLOCK(&request->requestmgr->locks[request->hash]); - - isc_event_free(&event); -} - -static void -req_response(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_request_t *request = event->ev_arg; - dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; - isc_region_t r; - - REQUIRE(VALID_REQUEST(request)); - REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); - - UNUSED(task); - - req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request, - dns_result_totext(devent->result)); - - LOCK(&request->requestmgr->locks[request->hash]); - result = devent->result; - if (result != ISC_R_SUCCESS) - goto done; - - /* - * Copy buffer to request. - */ - isc_buffer_usedregion(&devent->buffer, &r); - result = isc_buffer_allocate(request->mctx, &request->answer, - r.length); - if (result != ISC_R_SUCCESS) - goto done; - result = isc_buffer_copyregion(request->answer, &r); - if (result != ISC_R_SUCCESS) - isc_buffer_free(&request->answer); - done: - /* - * Cleanup. - */ - dns_dispatch_removeresponse(&request->dispentry, &devent); - req_cancel(request); - /* - * Send completion event. - */ - send_if_done(request, result); - UNLOCK(&request->requestmgr->locks[request->hash]); -} - -static void -req_timeout(isc_task_t *task, isc_event_t *event) { - dns_request_t *request = event->ev_arg; - isc_result_t result; - - REQUIRE(VALID_REQUEST(request)); - - req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request); - - UNUSED(task); - LOCK(&request->requestmgr->locks[request->hash]); - if (event->ev_type == ISC_TIMEREVENT_TICK && - request->udpcount-- != 0) { - if (! DNS_REQUEST_SENDING(request)) { - result = req_send(request, task, &request->destaddr); - if (result != ISC_R_SUCCESS) { - req_cancel(request); - send_if_done(request, result); - } - } - } else { - request->flags |= DNS_REQUEST_F_TIMEDOUT; - req_cancel(request); - send_if_done(request, ISC_R_TIMEDOUT); - } - UNLOCK(&request->requestmgr->locks[request->hash]); - isc_event_free(&event); -} - -static void -req_sendevent(dns_request_t *request, isc_result_t result) { - isc_task_t *task; - - REQUIRE(VALID_REQUEST(request)); - - req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request); - - /* - * Lock held by caller. - */ - task = request->event->ev_sender; - request->event->ev_sender = request; - request->event->result = result; - isc_task_sendanddetach(&task, (isc_event_t **)&request->event); -} - -static void -req_destroy(dns_request_t *request) { - isc_mem_t *mctx; - - REQUIRE(VALID_REQUEST(request)); - - req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request); - - request->magic = 0; - if (request->query != NULL) - isc_buffer_free(&request->query); - if (request->answer != NULL) - isc_buffer_free(&request->answer); - if (request->event != NULL) - isc_event_free((isc_event_t **)&request->event); - if (request->dispentry != NULL) - dns_dispatch_removeresponse(&request->dispentry, NULL); - if (request->dispatch != NULL) - dns_dispatch_detach(&request->dispatch); - if (request->timer != NULL) - isc_timer_detach(&request->timer); - if (request->tsig != NULL) - isc_buffer_free(&request->tsig); - if (request->tsigkey != NULL) - dns_tsigkey_detach(&request->tsigkey); - if (request->requestmgr != NULL) - requestmgr_detach(&request->requestmgr); - mctx = request->mctx; - isc_mem_put(mctx, request, sizeof(*request)); - isc_mem_detach(&mctx); -} - -/* - * Stop the current request. Must be called from the request's task. - */ -static void -req_cancel(dns_request_t *request) { - isc_socket_t *sock; - unsigned int dispattr; - - REQUIRE(VALID_REQUEST(request)); - - req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request); - - /* - * Lock held by caller. - */ - request->flags |= DNS_REQUEST_F_CANCELED; - - if (request->timer != NULL) - isc_timer_detach(&request->timer); - dispattr = dns_dispatch_getattributes(request->dispatch); - sock = NULL; - if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) { - if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { - if (request->dispentry != NULL) { - sock = dns_dispatch_getentrysocket( - request->dispentry); - } - } else - sock = dns_dispatch_getsocket(request->dispatch); - if (DNS_REQUEST_CONNECTING(request) && sock != NULL) - isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT); - if (DNS_REQUEST_SENDING(request) && sock != NULL) - isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND); - } - if (request->dispentry != NULL) - dns_dispatch_removeresponse(&request->dispentry, NULL); - dns_dispatch_detach(&request->dispatch); -} - -static void -req_log(int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_REQUEST, level, fmt, ap); - va_end(ap); -} diff --git a/lib/dns-pkcs11/resolver.c b/lib/dns-pkcs11/resolver.c deleted file mode 100644 index 2de70a6..0000000 --- a/lib/dns-pkcs11/resolver.c +++ /dev/null @@ -1,10589 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WANT_QUERYTRACE -#define RTRACE(m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "res %p: %s", res, (m)) -#define RRTRACE(r, m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "res %p: %s", (r), (m)) -#define FCTXTRACE(m) \ - isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fctx %p(%s): %s", \ - fctx, fctx->info, (m)) -#define FCTXTRACE2(m1, m2) \ - isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fctx %p(%s): %s %s", \ - fctx, fctx->info, (m1), (m2)) -#define FCTXTRACE3(m, res) \ - isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fctx %p(%s): [result: %s] %s", \ - fctx, fctx->info, \ - isc_result_totext(res), (m)) -#define FCTXTRACE4(m1, m2, res) \ - isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fctx %p(%s): [result: %s] %s %s", \ - fctx, fctx->info, \ - isc_result_totext(res), (m1), (m2)) -#define FCTXTRACE5(m1, m2, v) \ - isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fctx %p(%s): %s %s%u", \ - fctx, fctx->info, (m1), (m2), (v)) -#define FTRACE(m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "fetch %p (fctx %p(%s)): %s", \ - fetch, fetch->private, \ - fetch->private->info, (m)) -#define QTRACE(m) isc_log_write(dns_lctx, \ - DNS_LOGCATEGORY_RESOLVER, \ - DNS_LOGMODULE_RESOLVER, \ - ISC_LOG_DEBUG(3), \ - "resquery %p (fctx %p(%s)): %s", \ - query, query->fctx, \ - query->fctx->info, (m)) -#else -#define RTRACE(m) do { UNUSED(m); } while (0) -#define RRTRACE(r, m) do { UNUSED(r); UNUSED(m); } while (0) -#define FCTXTRACE(m) do { UNUSED(m); } while (0) -#define FCTXTRACE2(m1, m2) do { UNUSED(m1); UNUSED(m2); } while (0) -#define FCTXTRACE3(m1, res) do { UNUSED(m1); UNUSED(res); } while (0) -#define FCTXTRACE4(m1, m2, res) \ - do { UNUSED(m1); UNUSED(m2); UNUSED(res); } while (0) -#define FCTXTRACE5(m1, m2, v) \ - do { UNUSED(m1); UNUSED(m2); UNUSED(v); } while (0) -#define FTRACE(m) do { UNUSED(m); } while (0) -#define QTRACE(m) do { UNUSED(m); } while (0) -#endif /* WANT_QUERYTRACE */ - -#define US_PER_SEC 1000000U -#define US_PER_MSEC 1000U -/* - * The maximum time we will wait for a single query. - */ -#define MAX_SINGLE_QUERY_TIMEOUT 9000U -#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_MSEC) - -/* - * We need to allow a individual query time to complete / timeout. - */ -#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1000U) - -/* The default time in seconds for the whole query to live. */ -#ifndef DEFAULT_QUERY_TIMEOUT -#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT -#endif - -/* The maximum time in seconds for the whole query to live. */ -#ifndef MAXIMUM_QUERY_TIMEOUT -#define MAXIMUM_QUERY_TIMEOUT 30000 -#endif - -/* The default maximum number of recursions to follow before giving up. */ -#ifndef DEFAULT_RECURSION_DEPTH -#define DEFAULT_RECURSION_DEPTH 7 -#endif - -/* The default maximum number of iterative queries to allow before giving up. */ -#ifndef DEFAULT_MAX_QUERIES -#define DEFAULT_MAX_QUERIES 100 -#endif /* ifndef DEFAULT_MAX_QUERIES */ - -/* - * After NS_FAIL_LIMIT attempts to fetch a name server address, - * if the number of addresses in the NS RRset exceeds NS_RR_LIMIT, - * stop trying to fetch, in order to avoid wasting resources. - */ -#define NS_FAIL_LIMIT 4 -#define NS_RR_LIMIT 5 - -/* Number of hash buckets for zone counters */ -#ifndef RES_DOMAIN_BUCKETS -#define RES_DOMAIN_BUCKETS 523 -#endif -#define RES_NOBUCKET 0xffffffff - -/*% - * Maximum EDNS0 input packet size. - */ -#define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */ - -/*% - * This defines the maximum number of timeouts we will permit before we - * disable EDNS0 on the query. - */ -#define MAX_EDNS0_TIMEOUTS 3 - -#define DNS_RESOLVER_BADCACHESIZE 1021 -#define DNS_RESOLVER_BADCACHETTL(fctx) \ - (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30) - -typedef struct fetchctx fetchctx_t; - -typedef struct query { - /* Locked by task event serialization. */ - unsigned int magic; - fetchctx_t * fctx; - dns_message_t * rmessage; - isc_mem_t * mctx; - dns_dispatchmgr_t * dispatchmgr; - dns_dispatch_t * dispatch; - bool exclusivesocket; - dns_adbaddrinfo_t * addrinfo; - isc_socket_t * tcpsocket; - isc_time_t start; - dns_messageid_t id; - dns_dispentry_t * dispentry; - ISC_LINK(struct query) link; - isc_buffer_t buffer; - isc_buffer_t *tsig; - dns_tsigkey_t *tsigkey; - isc_socketevent_t sendevent; - isc_dscp_t dscp; - int ednsversion; - unsigned int options; - unsigned int attributes; - unsigned int sends; - unsigned int connects; - unsigned int udpsize; - unsigned char data[512]; -} resquery_t; - -struct tried { - isc_sockaddr_t addr; - unsigned int count; - ISC_LINK(struct tried) link; -}; - -#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!') -#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC) - -#define RESQUERY_ATTR_CANCELED 0x02 - -#define RESQUERY_CONNECTING(q) ((q)->connects > 0) -#define RESQUERY_CANCELED(q) (((q)->attributes & \ - RESQUERY_ATTR_CANCELED) != 0) -#define RESQUERY_SENDING(q) ((q)->sends > 0) - -typedef enum { - fetchstate_init = 0, /*%< Start event has not run yet. */ - fetchstate_active, - fetchstate_done /*%< FETCHDONE events posted. */ -} fetchstate; - -typedef enum { - badns_unreachable = 0, - badns_response, - badns_validation, - badns_forwarder, -} badnstype_t; - -struct fetchctx { - /*% Not locked. */ - unsigned int magic; - dns_resolver_t * res; - dns_name_t name; - dns_rdatatype_t type; - unsigned int options; - unsigned int bucketnum; - unsigned int dbucketnum; - char * info; - isc_mem_t * mctx; - - /*% Locked by appropriate bucket lock. */ - fetchstate state; - bool want_shutdown; - bool cloned; - bool spilled; - bool shuttingdown; - unsigned int references; - isc_event_t control_event; - ISC_LINK(struct fetchctx) link; - ISC_LIST(dns_fetchevent_t) events; - /*% Locked by task event serialization. */ - dns_name_t domain; - dns_rdataset_t nameservers; - unsigned int attributes; - isc_timer_t * timer; - isc_time_t expires; - isc_interval_t interval; - dns_message_t * qmessage; - ISC_LIST(resquery_t) queries; - dns_adbfindlist_t finds; - dns_adbfind_t * find; - dns_adbfindlist_t altfinds; - dns_adbfind_t * altfind; - dns_adbaddrinfolist_t forwaddrs; - dns_adbaddrinfolist_t altaddrs; - dns_forwarderlist_t forwarders; - dns_fwdpolicy_t fwdpolicy; - isc_sockaddrlist_t bad; - ISC_LIST(struct tried) edns; - ISC_LIST(struct tried) edns512; - isc_sockaddrlist_t bad_edns; - dns_validator_t * validator; - ISC_LIST(dns_validator_t) validators; - dns_db_t * cache; - dns_adb_t * adb; - bool ns_ttl_ok; - uint32_t ns_ttl; - isc_counter_t * qc; - - /*% - * The number of events we're waiting for. - */ - unsigned int pending; /* Bucket lock. */ - - /*% - * The number of times we've "restarted" the current - * nameserver set. This acts as a failsafe to prevent - * us from pounding constantly on a particular set of - * servers that, for whatever reason, are not giving - * us useful responses, but are responding in such a - * way that they are not marked "bad". - */ - unsigned int restarts; - - /*% - * The number of timeouts that have occurred since we - * last successfully received a response packet. This - * is used for EDNS0 black hole detection. - */ - unsigned int timeouts; - - /*% - * Look aside state for DS lookups. - */ - dns_name_t nsname; - dns_fetch_t * nsfetch; - dns_rdataset_t nsrrset; - - /*% - * Number of queries that reference this context. - */ - unsigned int nqueries; /* Bucket lock. */ - - /*% - * The reason to print when logging a successful - * response to a query. - */ - const char * reason; - - /*% - * Random numbers to use for mixing up server addresses. - */ - uint32_t rand_buf; - uint32_t rand_bits; - - /*% - * Fetch-local statistics for detailed logging. - */ - isc_result_t result; /*%< fetch result */ - isc_result_t vresult; /*%< validation result */ - int exitline; - isc_time_t start; - uint64_t duration; - bool logged; - unsigned int querysent; - unsigned int referrals; - unsigned int lamecount; - unsigned int quotacount; - unsigned int neterr; - unsigned int badresp; - unsigned int adberr; - unsigned int findfail; - unsigned int valfail; - bool timeout; - dns_adbaddrinfo_t *addrinfo; - unsigned int depth; - char clientstr[ISC_SOCKADDR_FORMATSIZE]; -}; - -#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') -#define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC) - -#define FCTX_ATTR_HAVEANSWER 0x0001 -#define FCTX_ATTR_GLUING 0x0002 -#define FCTX_ATTR_ADDRWAIT 0x0004 -#define FCTX_ATTR_WANTCACHE 0x0010 -#define FCTX_ATTR_WANTNCACHE 0x0020 -#define FCTX_ATTR_NEEDEDNS0 0x0040 -#define FCTX_ATTR_TRIEDFIND 0x0080 -#define FCTX_ATTR_TRIEDALT 0x0100 - -#define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \ - 0) -#define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \ - 0) -#define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \ - 0) -#define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0) -#define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0) -#define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0) -#define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0) -#define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0) - -#define FCTX_ATTR_SET(f, x) do { (f)->attributes |= (x); } while (0) -#define FCTX_ATTR_CLR(f, x) do { (f)->attributes &= ~(x); } while (0) - -typedef struct { - dns_adbaddrinfo_t * addrinfo; - fetchctx_t * fctx; - dns_message_t * rmessage; -} dns_valarg_t; - -typedef struct { - fetchctx_t * fctx; - dns_message_t * rmessage; -} dns_chkarg_t; - -struct dns_fetch { - unsigned int magic; - isc_mem_t * mctx; - fetchctx_t * private; -}; - -#define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h') -#define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC) - -typedef struct fctxbucket { - isc_task_t * task; - isc_mutex_t lock; - ISC_LIST(fetchctx_t) fctxs; - bool exiting; - isc_mem_t * mctx; -} fctxbucket_t; - -typedef struct fctxcount fctxcount_t; -struct fctxcount { - dns_fixedname_t fdname; - dns_name_t *domain; - uint32_t count; - uint32_t allowed; - uint32_t dropped; - isc_stdtime_t logged; - ISC_LINK(fctxcount_t) link; -}; - -typedef struct zonebucket { - isc_mutex_t lock; - isc_mem_t *mctx; - ISC_LIST(fctxcount_t) list; -} zonebucket_t; - -typedef struct alternate { - bool isaddress; - union { - isc_sockaddr_t addr; - struct { - dns_name_t name; - in_port_t port; - } _n; - } _u; - ISC_LINK(struct alternate) link; -} alternate_t; - -struct dns_resolver { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_mutex_t lock; - isc_mutex_t nlock; - isc_mutex_t primelock; - isc_mutex_t spill_lock; - dns_rdataclass_t rdclass; - isc_socketmgr_t * socketmgr; - isc_timermgr_t * timermgr; - isc_taskmgr_t * taskmgr; - dns_view_t * view; - bool frozen; - unsigned int options; - dns_dispatchmgr_t * dispatchmgr; - dns_dispatchset_t * dispatches4; - bool exclusivev4; - dns_dispatchset_t * dispatches6; - isc_dscp_t querydscp4; - isc_dscp_t querydscp6; - bool exclusivev6; - unsigned int nbuckets; - fctxbucket_t * buckets; - zonebucket_t * dbuckets; - uint32_t lame_ttl; - ISC_LIST(alternate_t) alternates; - uint16_t udpsize; -#if USE_ALGLOCK - isc_rwlock_t alglock; -#endif - dns_rbt_t * algorithms; - dns_rbt_t * digests; -#if USE_MBSLOCK - isc_rwlock_t mbslock; -#endif - dns_rbt_t * mustbesecure; - unsigned int spillatmax; - unsigned int spillatmin; - isc_timer_t * spillattimer; - bool zero_no_soa_ttl; - unsigned int query_timeout; - unsigned int maxdepth; - unsigned int maxqueries; - isc_result_t quotaresp[2]; - - /* Locked by lock. */ - unsigned int zspill; /* fetches-per-zone */ - - /* Locked by lock. */ - unsigned int references; - bool exiting; - isc_eventlist_t whenshutdown; - unsigned int activebuckets; - bool priming; - unsigned int spillat; /* clients-per-query */ - - dns_badcache_t * badcache; /* Bad cache. */ - - /* Locked by primelock. */ - dns_fetch_t * primefetch; - /* Locked by nlock. */ - unsigned int nfctx; - - /* Unlocked. Additions for serve-stale feature. */ - unsigned int retryinterval; /* in milliseconds */ - unsigned int nonbackofftries; - -}; - -#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') -#define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC) - -/*% - * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0 - * (0x008) which we also use as an addrinfo flag. - */ -#define FCTX_ADDRINFO_MARK 0x00001 -#define FCTX_ADDRINFO_FORWARDER 0x01000 -#define FCTX_ADDRINFO_EDNSOK 0x04000 -#define FCTX_ADDRINFO_NOCOOKIE 0x08000 -#define FCTX_ADDRINFO_BADCOOKIE 0x10000 - -#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \ - == 0) -#define ISFORWARDER(a) (((a)->flags & \ - FCTX_ADDRINFO_FORWARDER) != 0) -#define NOCOOKIE(a) (((a)->flags & \ - FCTX_ADDRINFO_NOCOOKIE) != 0) -#define EDNSOK(a) (((a)->flags & \ - FCTX_ADDRINFO_EDNSOK) != 0) -#define BADCOOKIE(a) (((a)->flags & \ - FCTX_ADDRINFO_BADCOOKIE) != 0) - -#define NONTA(o) (((o) & DNS_FETCHOPT_NONTA) != 0) - -#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) -#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) - -#ifdef ENABLE_AFL -bool dns_fuzzing_resolver = false; -void dns_resolver_setfuzzing() { - dns_fuzzing_resolver = true; -} -#endif - -static void destroy(dns_resolver_t *res); -static void empty_bucket(dns_resolver_t *res); -static isc_result_t resquery_send(resquery_t *query); -static void resquery_response(isc_task_t *task, isc_event_t *event); -static void resquery_connected(isc_task_t *task, isc_event_t *event); -static void fctx_try(fetchctx_t *fctx, bool retrying, - bool badcache); -static void fctx_destroy(fetchctx_t *fctx); -static bool fctx_unlink(fetchctx_t *fctx); -static isc_result_t ncache_adderesult(dns_message_t *message, - dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, - bool secure, - dns_rdataset_t *ardataset, - isc_result_t *eresultp); -static void validated(isc_task_t *task, isc_event_t *event); -static bool maybe_destroy(fetchctx_t *fctx, bool locked); -static void add_bad(fetchctx_t *fctx, dns_message_t *rmessage, - dns_adbaddrinfo_t *addrinfo, isc_result_t reason, - badnstype_t badtype); -static inline isc_result_t findnoqname(fetchctx_t *fctx, - dns_message_t *rmessage, - dns_name_t *name, - dns_rdatatype_t type, - dns_name_t **noqname); -static void fctx_increference(fetchctx_t *fctx); -static bool fctx_decreference(fetchctx_t *fctx); - -/*% - * Increment resolver-related statistics counters. - */ -static inline void -inc_stats(dns_resolver_t *res, isc_statscounter_t counter) { - if (res->view->resstats != NULL) - isc_stats_increment(res->view->resstats, counter); -} - -static inline void -dec_stats(dns_resolver_t *res, isc_statscounter_t counter) { - if (res->view->resstats != NULL) - isc_stats_decrement(res->view->resstats, counter); -} - -static isc_result_t -valcreate(fetchctx_t *fctx, dns_message_t *rmessage, - dns_adbaddrinfo_t *addrinfo, dns_name_t *name, - dns_rdatatype_t type, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, unsigned int valoptions, - isc_task_t *task) -{ - dns_validator_t *validator = NULL; - dns_valarg_t *valarg; - isc_result_t result; - - valarg = isc_mem_get(fctx->mctx, sizeof(*valarg)); - if (valarg == NULL) - return (ISC_R_NOMEMORY); - - valarg->fctx = fctx; - valarg->addrinfo = addrinfo; - dns_message_attach(rmessage, &valarg->rmessage); - - if (!ISC_LIST_EMPTY(fctx->validators)) - valoptions |= DNS_VALIDATOR_DEFER; - else - valoptions &= ~DNS_VALIDATOR_DEFER; - - result = dns_validator_create(fctx->res->view, name, type, rdataset, - sigrdataset, rmessage, - valoptions, task, validated, valarg, - &validator); - if (result == ISC_R_SUCCESS) { - inc_stats(fctx->res, dns_resstatscounter_val); - if ((valoptions & DNS_VALIDATOR_DEFER) == 0) { - INSIST(fctx->validator == NULL); - fctx->validator = validator; - } - ISC_LIST_APPEND(fctx->validators, validator, link); - } else { - dns_message_detach(&valarg->rmessage); - isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); - } - return (result); -} - -static bool -rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) { - dns_namereln_t namereln; - dns_rdata_rrsig_t rrsig; - dns_rdata_t rdata = DNS_RDATA_INIT; - int order; - isc_result_t result; - unsigned int labels; - - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rrsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain, - &order, &labels); - if (namereln == dns_namereln_subdomain) - return (true); - dns_rdata_reset(&rdata); - } - return (false); -} - -static bool -fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) { - dns_name_t *name; - dns_name_t *domain = &fctx->domain; - dns_rdataset_t *rdataset; - dns_rdatatype_t type; - isc_result_t result; - bool keep_auth = false; - - if (message->rcode == dns_rcode_nxdomain) - return (false); - - /* - * A DS RRset can appear anywhere in a zone, even for a delegation-only - * zone. So a response to an explicit query for this type should be - * excluded from delegation-only fixup. - * - * SOA, NS, and DNSKEY can only exist at a zone apex, so a positive - * response to a query for these types can never violate the - * delegation-only assumption: if the query name is below a - * zone cut, the response should normally be a referral, which should - * be accepted; if the query name is below a zone cut but the server - * happens to have authority for the zone of the query name, the - * response is a (non-referral) answer. But this does not violate - * delegation-only because the query name must be in a different zone - * due to the "apex-only" nature of these types. Note that if the - * remote server happens to have authority for a child zone of a - * delegation-only zone, we may still incorrectly "fix" the response - * with NXDOMAIN for queries for other types. Unfortunately it's - * generally impossible to differentiate this case from violation of - * the delegation-only assumption. Once the resolver learns the - * correct zone cut, possibly via a separate query for an "apex-only" - * type, queries for other types will be resolved correctly. - * - * A query for type ANY will be accepted if it hits an exceptional - * type above in the answer section as it should be from a child - * zone. - * - * Also accept answers with RRSIG records from the child zone. - * Direct queries for RRSIG records should not be answered from - * the parent zone. - */ - - if (message->counts[DNS_SECTION_ANSWER] != 0 && - (fctx->type == dns_rdatatype_ns || - fctx->type == dns_rdatatype_ds || - fctx->type == dns_rdatatype_soa || - fctx->type == dns_rdatatype_any || - fctx->type == dns_rdatatype_rrsig || - fctx->type == dns_rdatatype_dnskey)) { - result = dns_message_firstname(message, DNS_SECTION_ANSWER); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, DNS_SECTION_ANSWER, - &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (!dns_name_equal(name, &fctx->name)) - continue; - type = rdataset->type; - /* - * RRsig from child? - */ - if (type == dns_rdatatype_rrsig && - rrsig_fromchildzone(fctx, rdataset)) - return (false); - /* - * Direct query for apex records or DS. - */ - if (fctx->type == type && - (type == dns_rdatatype_ds || - type == dns_rdatatype_ns || - type == dns_rdatatype_soa || - type == dns_rdatatype_dnskey)) - return (false); - /* - * Indirect query for apex records or DS. - */ - if (fctx->type == dns_rdatatype_any && - (type == dns_rdatatype_ns || - type == dns_rdatatype_ds || - type == dns_rdatatype_soa || - type == dns_rdatatype_dnskey)) - return (false); - } - result = dns_message_nextname(message, - DNS_SECTION_ANSWER); - } - } - - /* - * A NODATA response to a DS query? - */ - if (fctx->type == dns_rdatatype_ds && - message->counts[DNS_SECTION_ANSWER] == 0) - return (false); - - /* Look for referral or indication of answer from child zone? */ - if (message->counts[DNS_SECTION_AUTHORITY] == 0) - goto munge; - - result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - type = rdataset->type; - if (type == dns_rdatatype_soa && - dns_name_equal(name, domain)) - keep_auth = true; - - if (type != dns_rdatatype_ns && - type != dns_rdatatype_soa && - type != dns_rdatatype_rrsig) - continue; - - if (type == dns_rdatatype_rrsig) { - if (rrsig_fromchildzone(fctx, rdataset)) - return (false); - else - continue; - } - - /* NS or SOA records. */ - if (dns_name_equal(name, domain)) { - /* - * If a query for ANY causes a negative - * response, we can be sure that this is - * an empty node. For other type of queries - * we cannot differentiate an empty node - * from a node that just doesn't have that - * type of record. We only accept the former - * case. - */ - if (message->counts[DNS_SECTION_ANSWER] == 0 && - fctx->type == dns_rdatatype_any) - return (false); - } else if (dns_name_issubdomain(name, domain)) { - /* Referral or answer from child zone. */ - return (false); - } - } - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); - } - - munge: - message->rcode = dns_rcode_nxdomain; - message->counts[DNS_SECTION_ANSWER] = 0; - if (!keep_auth) - message->counts[DNS_SECTION_AUTHORITY] = 0; - message->counts[DNS_SECTION_ADDITIONAL] = 0; - return (true); -} - -static inline isc_result_t -fctx_starttimer(fetchctx_t *fctx) { - /* - * Start the lifetime timer for fctx. - * - * This is also used for stopping the idle timer; in that - * case we must purge events already posted to ensure that - * no further idle events are delivered. - */ - return (isc_timer_reset(fctx->timer, isc_timertype_once, - &fctx->expires, NULL, true)); -} - -static inline void -fctx_stoptimer(fetchctx_t *fctx) { - isc_result_t result; - - /* - * We don't return a result if resetting the timer to inactive fails - * since there's nothing to be done about it. Resetting to inactive - * should never fail anyway, since the code as currently written - * cannot fail in that case. - */ - result = isc_timer_reset(fctx->timer, isc_timertype_inactive, - NULL, NULL, true); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timer_reset(): %s", - isc_result_totext(result)); - } -} - -static inline isc_result_t -fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) { - /* - * Start the idle timer for fctx. The lifetime timer continues - * to be in effect. - */ - return (isc_timer_reset(fctx->timer, isc_timertype_once, - &fctx->expires, interval, false)); -} - -/* - * Stopping the idle timer is equivalent to calling fctx_starttimer(), but - * we use fctx_stopidletimer for readability in the code below. - */ -#define fctx_stopidletimer fctx_starttimer - -static inline void -resquery_destroy(resquery_t **queryp) { - dns_resolver_t *res; - bool empty; - resquery_t *query; - fetchctx_t *fctx; - unsigned int bucket; - - REQUIRE(queryp != NULL); - query = *queryp; - REQUIRE(!ISC_LINK_LINKED(query, link)); - - INSIST(query->tcpsocket == NULL); - - fctx = query->fctx; - res = fctx->res; - bucket = fctx->bucketnum; - - LOCK(&res->buckets[bucket].lock); - fctx->nqueries--; - empty = fctx_decreference(query->fctx); - UNLOCK(&res->buckets[bucket].lock); - - dns_message_detach(&query->rmessage); - - query->magic = 0; - isc_mem_put(query->mctx, query, sizeof(*query)); - *queryp = NULL; - - if (empty) - empty_bucket(res); -} - -/*% - * Update EDNS statistics for a server after not getting a response to a UDP - * query sent to it. - */ -static void -update_edns_stats(resquery_t *query) { - fetchctx_t *fctx = query->fctx; - - if ((query->options & DNS_FETCHOPT_TCP) != 0) { - return; - } - - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - dns_adb_ednsto(fctx->adb, query->addrinfo, query->udpsize); - } else { - dns_adb_timeout(fctx->adb, query->addrinfo); - } -} - -static void -fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, - isc_time_t *finish, bool no_response, - bool age_untried) -{ - fetchctx_t *fctx; - resquery_t *query; - unsigned int rtt, rttms; - unsigned int factor; - dns_adbfind_t *find; - dns_adbaddrinfo_t *addrinfo; - isc_socket_t *sock; - isc_stdtime_t now; - - query = *queryp; - fctx = query->fctx; - - FCTXTRACE("cancelquery"); - - REQUIRE(!RESQUERY_CANCELED(query)); - - query->attributes |= RESQUERY_ATTR_CANCELED; - - /* - * Should we update the RTT? - */ - if (finish != NULL || no_response) { - if (finish != NULL) { - /* - * We have both the start and finish times for this - * packet, so we can compute a real RTT. - */ - rtt = (unsigned int)isc_time_microdiff(finish, - &query->start); - factor = DNS_ADB_RTTADJDEFAULT; - - rttms = rtt / 1000; - if (rttms < DNS_RESOLVER_QRYRTTCLASS0) { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt0); - } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt1); - } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt2); - } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt3); - } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt4); - } else { - inc_stats(fctx->res, - dns_resstatscounter_queryrtt5); - } - } else { - uint32_t value; - uint32_t mask; - - update_edns_stats(query); - - /* - * If "forward first;" is used and a forwarder timed - * out, do not attempt to query it again in this fetch - * context. - */ - if (fctx->fwdpolicy == dns_fwdpolicy_first && - ISFORWARDER(query->addrinfo)) - { - add_bad(fctx, query->rmessage, - query->addrinfo, ISC_R_TIMEDOUT, - badns_forwarder); - } - - /* - * We don't have an RTT for this query. Maybe the - * packet was lost, or maybe this server is very - * slow. We don't know. Increase the RTT. - */ - INSIST(no_response); - isc_random_get(&value); - if (query->addrinfo->srtt > 800000) - mask = 0x3fff; - else if (query->addrinfo->srtt > 400000) - mask = 0x7fff; - else if (query->addrinfo->srtt > 200000) - mask = 0xffff; - else if (query->addrinfo->srtt > 100000) - mask = 0x1ffff; - else if (query->addrinfo->srtt > 50000) - mask = 0x3ffff; - else if (query->addrinfo->srtt > 25000) - mask = 0x7ffff; - else - mask = 0xfffff; - - /* - * Don't adjust timeout on EDNS queries unless we have - * seen a EDNS response. - */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && - !EDNSOK(query->addrinfo)) { - mask >>= 2; - } - - rtt = query->addrinfo->srtt + (value & mask); - if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US) - rtt = MAX_SINGLE_QUERY_TIMEOUT_US; - - /* - * Replace the current RTT with our value. - */ - factor = DNS_ADB_RTTADJREPLACE; - } - - dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor); - } - if ((query->options & DNS_FETCHOPT_TCP) == 0) { - /* Inform the ADB that we're ending a UDP fetch */ - dns_adb_endudpfetch(fctx->adb, query->addrinfo); - } - - /* - * Age RTTs of servers not tried. - */ - isc_stdtime_get(&now); - if (finish != NULL || age_untried) - for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) - if (UNMARKED(addrinfo)) - dns_adb_agesrtt(fctx->adb, addrinfo, now); - - if ((finish != NULL || age_untried) && TRIEDFIND(fctx)) - for (find = ISC_LIST_HEAD(fctx->finds); - find != NULL; - find = ISC_LIST_NEXT(find, publink)) - for (addrinfo = ISC_LIST_HEAD(find->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) - if (UNMARKED(addrinfo)) - dns_adb_agesrtt(fctx->adb, addrinfo, - now); - - if ((finish != NULL || age_untried) && TRIEDALT(fctx)) { - for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) - if (UNMARKED(addrinfo)) - dns_adb_agesrtt(fctx->adb, addrinfo, now); - for (find = ISC_LIST_HEAD(fctx->altfinds); - find != NULL; - find = ISC_LIST_NEXT(find, publink)) - for (addrinfo = ISC_LIST_HEAD(find->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) - if (UNMARKED(addrinfo)) - dns_adb_agesrtt(fctx->adb, addrinfo, - now); - } - - /* - * Check for any outstanding socket events. If they exist, cancel - * them and let the event handlers finish the cleanup. The resolver - * only needs to worry about managing the connect and send events; - * the dispatcher manages the recv events. - */ - if (RESQUERY_CONNECTING(query)) { - /* - * Cancel the connect. - */ - if (query->tcpsocket != NULL) { - isc_socket_cancel(query->tcpsocket, NULL, - ISC_SOCKCANCEL_CONNECT); - } else if (query->dispentry != NULL) { - INSIST(query->exclusivesocket); - sock = dns_dispatch_getentrysocket(query->dispentry); - if (sock != NULL) - isc_socket_cancel(sock, NULL, - ISC_SOCKCANCEL_CONNECT); - } - } - if (RESQUERY_SENDING(query)) { - /* - * Cancel the pending send. - */ - if (query->exclusivesocket && query->dispentry != NULL) - sock = dns_dispatch_getentrysocket(query->dispentry); - else - sock = dns_dispatch_getsocket(query->dispatch); - if (sock != NULL) - isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND); - } - - if (query->dispentry != NULL) - dns_dispatch_removeresponse(&query->dispentry, deventp); - - ISC_LIST_UNLINK(fctx->queries, query, link); - - if (query->tsig != NULL) - isc_buffer_free(&query->tsig); - - if (query->tsigkey != NULL) - dns_tsigkey_detach(&query->tsigkey); - - if (query->dispatch != NULL) - dns_dispatch_detach(&query->dispatch); - - if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query))) - /* - * It's safe to destroy the query now. - */ - resquery_destroy(&query); -} - -static void -fctx_cancelqueries(fetchctx_t *fctx, bool no_response, - bool age_untried) -{ - resquery_t *query, *next_query; - - FCTXTRACE("cancelqueries"); - - for (query = ISC_LIST_HEAD(fctx->queries); - query != NULL; - query = next_query) { - next_query = ISC_LIST_NEXT(query, link); - fctx_cancelquery(&query, NULL, NULL, no_response, - age_untried); - } -} - -static void -fctx_cleanupfinds(fetchctx_t *fctx) { - dns_adbfind_t *find, *next_find; - - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - - for (find = ISC_LIST_HEAD(fctx->finds); - find != NULL; - find = next_find) - { - next_find = ISC_LIST_NEXT(find, publink); - ISC_LIST_UNLINK(fctx->finds, find, publink); - dns_adb_destroyfind(&find); - } - fctx->find = NULL; -} - -static void -fctx_cleanupaltfinds(fetchctx_t *fctx) { - dns_adbfind_t *find, *next_find; - - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - - for (find = ISC_LIST_HEAD(fctx->altfinds); - find != NULL; - find = next_find) - { - next_find = ISC_LIST_NEXT(find, publink); - ISC_LIST_UNLINK(fctx->altfinds, find, publink); - dns_adb_destroyfind(&find); - } - fctx->altfind = NULL; -} - -static void -fctx_cleanupforwaddrs(fetchctx_t *fctx) { - dns_adbaddrinfo_t *addr, *next_addr; - - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - - for (addr = ISC_LIST_HEAD(fctx->forwaddrs); - addr != NULL; - addr = next_addr) - { - next_addr = ISC_LIST_NEXT(addr, publink); - ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink); - dns_adb_freeaddrinfo(fctx->adb, &addr); - } -} - -static void -fctx_cleanupaltaddrs(fetchctx_t *fctx) { - dns_adbaddrinfo_t *addr, *next_addr; - - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - - for (addr = ISC_LIST_HEAD(fctx->altaddrs); - addr != NULL; - addr = next_addr) - { - next_addr = ISC_LIST_NEXT(addr, publink); - ISC_LIST_UNLINK(fctx->altaddrs, addr, publink); - dns_adb_freeaddrinfo(fctx->adb, &addr); - } -} - -static inline void -fctx_stopqueries(fetchctx_t *fctx, bool no_response, - bool age_untried) -{ - FCTXTRACE("stopqueries"); - fctx_cancelqueries(fctx, no_response, age_untried); - fctx_stoptimer(fctx); -} - -static inline void -fctx_cleanupall(fetchctx_t *fctx) { - fctx_cleanupfinds(fctx); - fctx_cleanupaltfinds(fctx); - fctx_cleanupforwaddrs(fctx); - fctx_cleanupaltaddrs(fctx); -} - -static void -fcount_logspill(fetchctx_t *fctx, fctxcount_t *counter) { - char dbuf[DNS_NAME_FORMATSIZE]; - isc_stdtime_t now; - - if (! isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) - return; - - isc_stdtime_get(&now); - if (counter->logged > now - 60) - return; - - dns_name_format(&fctx->domain, dbuf, sizeof(dbuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_SPILL, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "too many simultaneous fetches for %s " - "(allowed %d spilled %d)", - dbuf, counter->allowed, counter->dropped); - - counter->logged = now; -} - -static isc_result_t -fcount_incr(fetchctx_t *fctx, bool force) { - isc_result_t result = ISC_R_SUCCESS; - zonebucket_t *dbucket; - fctxcount_t *counter; - unsigned int bucketnum; - - REQUIRE(fctx != NULL); - REQUIRE(fctx->res != NULL); - - INSIST(fctx->dbucketnum == RES_NOBUCKET); - bucketnum = dns_name_fullhash(&fctx->domain, false) - % RES_DOMAIN_BUCKETS; - - dbucket = &fctx->res->dbuckets[bucketnum]; - - LOCK(&dbucket->lock); - for (counter = ISC_LIST_HEAD(dbucket->list); - counter != NULL; - counter = ISC_LIST_NEXT(counter, link)) - { - if (dns_name_equal(counter->domain, &fctx->domain)) - break; - } - - if (counter == NULL) { - counter = isc_mem_get(dbucket->mctx, sizeof(fctxcount_t)); - if (counter == NULL) - result = ISC_R_NOMEMORY; - else { - ISC_LINK_INIT(counter, link); - counter->count = 1; - counter->logged = 0; - counter->allowed = 1; - counter->dropped = 0; - counter->domain = - dns_fixedname_initname(&counter->fdname); - dns_name_copy(&fctx->domain, counter->domain, NULL); - ISC_LIST_APPEND(dbucket->list, counter, link); - } - } else { - unsigned int spill; - - LOCK(&fctx->res->spill_lock); - spill = fctx->res->zspill; - UNLOCK(&fctx->res->spill_lock); - - if (!force && spill != 0 && counter->count >= spill) { - counter->dropped++; - fcount_logspill(fctx, counter); - result = ISC_R_QUOTA; - } else { - counter->count++; - counter->allowed++; - } - } - UNLOCK(&dbucket->lock); - - if (result == ISC_R_SUCCESS) - fctx->dbucketnum = bucketnum; - - return (result); -} - -static void -fcount_decr(fetchctx_t *fctx) { - zonebucket_t *dbucket; - fctxcount_t *counter; - - REQUIRE(fctx != NULL); - - if (fctx->dbucketnum == RES_NOBUCKET) - return; - - dbucket = &fctx->res->dbuckets[fctx->dbucketnum]; - - LOCK(&dbucket->lock); - for (counter = ISC_LIST_HEAD(dbucket->list); - counter != NULL; - counter = ISC_LIST_NEXT(counter, link)) - { - if (dns_name_equal(counter->domain, &fctx->domain)) - break; - } - - if (counter != NULL) { - INSIST(counter->count != 0); - counter->count--; - fctx->dbucketnum = RES_NOBUCKET; - - if (counter->count == 0) { - ISC_LIST_UNLINK(dbucket->list, counter, link); - isc_mem_put(dbucket->mctx, counter, sizeof(*counter)); - } - } - - UNLOCK(&dbucket->lock); -} - -static inline void -fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) { - dns_fetchevent_t *event, *next_event; - isc_task_t *task; - unsigned int count = 0; - isc_interval_t i; - bool logit = false; - isc_time_t now; - unsigned int old_spillat; - unsigned int new_spillat = 0; /* initialized to silence - compiler warnings */ - - /* - * Caller must be holding the appropriate bucket lock. - */ - REQUIRE(fctx->state == fetchstate_done); - - FCTXTRACE("sendevents"); - - /* - * Keep some record of fetch result for logging later (if required). - */ - fctx->result = result; - fctx->exitline = line; - TIME_NOW(&now); - fctx->duration = isc_time_microdiff(&now, &fctx->start); - - for (event = ISC_LIST_HEAD(fctx->events); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(fctx->events, event, ev_link); - task = event->ev_sender; - event->ev_sender = fctx; - event->vresult = fctx->vresult; - if (!HAVE_ANSWER(fctx)) - event->result = result; - - INSIST(event->result != ISC_R_SUCCESS || - dns_rdataset_isassociated(event->rdataset) || - fctx->type == dns_rdatatype_any || - fctx->type == dns_rdatatype_rrsig || - fctx->type == dns_rdatatype_sig); - - /* - * Negative results must be indicated in event->result. - */ - if (dns_rdataset_isassociated(event->rdataset) && - NEGATIVE(event->rdataset)) { - INSIST(event->result == DNS_R_NCACHENXDOMAIN || - event->result == DNS_R_NCACHENXRRSET); - } - - isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); - count++; - } - - LOCK(&fctx->res->spill_lock); - if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 && - fctx->spilled && - (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) { - if (count == fctx->res->spillat && !fctx->res->exiting) { - old_spillat = fctx->res->spillat; - fctx->res->spillat += 5; - if (fctx->res->spillat > fctx->res->spillatmax && - fctx->res->spillatmax != 0) - fctx->res->spillat = fctx->res->spillatmax; - new_spillat = fctx->res->spillat; - if (new_spillat != old_spillat) { - logit = true; - } - isc_interval_set(&i, 20 * 60, 0); - result = isc_timer_reset(fctx->res->spillattimer, - isc_timertype_ticker, NULL, - &i, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - if (logit) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "clients-per-query increased to %u", - new_spillat); - } - UNLOCK(&fctx->res->spill_lock); -} - -static inline void -log_edns(fetchctx_t *fctx) { - char domainbuf[DNS_NAME_FORMATSIZE]; - - if (fctx->reason == NULL) - return; - - /* - * We do not know if fctx->domain is the actual domain the record - * lives in or a parent domain so we have a '?' after it. - */ - dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), - "success resolving '%s' (in '%s'?) after %s", - fctx->info, domainbuf, fctx->reason); - - fctx->reason = NULL; -} - -static void -fctx_done(fetchctx_t *fctx, isc_result_t result, int line) { - dns_resolver_t *res; - bool no_response = false; - bool age_untried = false; - - REQUIRE(line >= 0); - - FCTXTRACE("done"); - - res = fctx->res; - - if (result == ISC_R_SUCCESS) { - /*% - * Log any deferred EDNS timeout messages. - */ - log_edns(fctx); - no_response = true; - } else if (result == ISC_R_TIMEDOUT) - age_untried = true; - - fctx->reason = NULL; - - fctx_stopqueries(fctx, no_response, age_untried); - - LOCK(&res->buckets[fctx->bucketnum].lock); - - fctx->state = fetchstate_done; - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - fctx_sendevents(fctx, result, line); - - UNLOCK(&res->buckets[fctx->bucketnum].lock); -} - -static void -process_sendevent(resquery_t *query, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - bool destroy_query = false; - bool retry = false; - isc_result_t result; - fetchctx_t *fctx; - - fctx = query->fctx; - - if (RESQUERY_CANCELED(query)) { - if (query->sends == 0 && query->connects == 0) { - /* - * This query was canceled while the - * isc_socket_sendto/connect() was in progress. - */ - if (query->tcpsocket != NULL) - isc_socket_detach(&query->tcpsocket); - destroy_query = true; - } - } else { - switch (sevent->result) { - case ISC_R_SUCCESS: - break; - - case ISC_R_HOSTUNREACH: - case ISC_R_NETUNREACH: - case ISC_R_NOPERM: - case ISC_R_ADDRNOTAVAIL: - case ISC_R_CONNREFUSED: - FCTXTRACE3("query canceled in sendevent(): " - "no route to host; no response", - sevent->result); - - /* - * No route to remote. - */ - add_bad(fctx, query->rmessage, query->addrinfo, - sevent->result, - badns_unreachable); - fctx_cancelquery(&query, NULL, NULL, true, - false); - retry = true; - break; - - default: - FCTXTRACE3("query canceled in sendevent() due to " - "unexpected event result; responding", - sevent->result); - - fctx_cancelquery(&query, NULL, NULL, false, - false); - break; - } - } - - if (event->ev_type == ISC_SOCKEVENT_CONNECT) - isc_event_free(&event); - - if (retry) { - /* - * Behave as if the idle timer has expired. For TCP - * this may not actually reflect the latest timer. - */ - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - result = fctx_stopidletimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - else - fctx_try(fctx, true, false); - } - - if (destroy_query) - resquery_destroy(&query); -} - -static void -resquery_udpconnected(isc_task_t *task, isc_event_t *event) { - resquery_t *query = event->ev_arg; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); - - QTRACE("udpconnected"); - - UNUSED(task); - - INSIST(RESQUERY_CONNECTING(query)); - - query->connects--; - - process_sendevent(query, event); -} - -static void -resquery_senddone(isc_task_t *task, isc_event_t *event) { - resquery_t *query = event->ev_arg; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - QTRACE("senddone"); - - /* - * XXXRTH - * - * Currently we don't wait for the senddone event before retrying - * a query. This means that if we get really behind, we may end - * up doing extra work! - */ - - UNUSED(task); - - INSIST(RESQUERY_SENDING(query)); - - query->sends--; - - process_sendevent(query, event); -} - -static inline isc_result_t -fctx_addopt(dns_message_t *message, unsigned int version, - uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count) -{ - dns_rdataset_t *rdataset = NULL; - isc_result_t result; - - result = dns_message_buildopt(message, &rdataset, version, udpsize, - DNS_MESSAGEEXTFLAG_DO, ednsopts, count); - if (result != ISC_R_SUCCESS) - return (result); - return (dns_message_setopt(message, rdataset)); -} - -static inline void -fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { - unsigned int seconds; - unsigned int us; - - us = fctx->res->retryinterval * 1000; - /* - * Exponential backoff after the first few tries. - */ - if (fctx->restarts >= fctx->res->nonbackofftries) - us <<= (fctx->restarts - fctx->res->nonbackofftries - 1); - - /* - * Add a fudge factor to the expected rtt based on the current - * estimate. - */ - if (rtt < 50000) - rtt += 50000; - else if (rtt < 100000) - rtt += 100000; - else - rtt += 200000; - - /* - * Always wait for at least the expected rtt. - */ - if (us < rtt) - us = rtt; - - /* - * But don't ever wait for more than 10 seconds. - */ - if (us > MAX_SINGLE_QUERY_TIMEOUT_US) - us = MAX_SINGLE_QUERY_TIMEOUT_US; - - seconds = us / US_PER_SEC; - us -= seconds * US_PER_SEC; - isc_interval_set(&fctx->interval, seconds, us * 1000); -} - -static isc_result_t -fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, - unsigned int options) -{ - dns_resolver_t *res; - isc_task_t *task; - isc_result_t result; - resquery_t *query; - isc_sockaddr_t addr; - bool have_addr = false; - unsigned int srtt; - isc_dscp_t dscp = -1; - unsigned int bucketnum; - - FCTXTRACE("query"); - - res = fctx->res; - task = res->buckets[fctx->bucketnum].task; - - srtt = addrinfo->srtt; - - /* - * Allow an additional second for the kernel to resend the SYN (or - * SYN without ECN in the case of stupid firewalls blocking ECN - * negotiation) over the current RTT estimate. - */ - if ((options & DNS_FETCHOPT_TCP) != 0) { - srtt += 1000000; - } - - /* - * A forwarder needs to make multiple queries. Give it at least - * a second to do these in. - */ - if (ISFORWARDER(addrinfo) && srtt < 1000000) - srtt = 1000000; - - fctx_setretryinterval(fctx, srtt); - result = fctx_startidletimer(fctx, &fctx->interval); - if (result != ISC_R_SUCCESS) - return (result); - - INSIST(ISC_LIST_EMPTY(fctx->validators)); - - query = isc_mem_get(fctx->mctx, sizeof(*query)); - if (query == NULL) { - result = ISC_R_NOMEMORY; - goto stop_idle_timer; - } - query->rmessage = NULL; - result = dns_message_create(fctx->mctx, DNS_MESSAGE_INTENTPARSE, - &query->rmessage); - if (result != ISC_R_SUCCESS) { - goto cleanup_query; - } - query->mctx = fctx->mctx; - query->options = options; - query->attributes = 0; - query->sends = 0; - query->connects = 0; - query->dscp = addrinfo->dscp; - query->udpsize = 0; - /* - * Note that the caller MUST guarantee that 'addrinfo' will remain - * valid until this query is canceled. - */ - query->addrinfo = addrinfo; - TIME_NOW(&query->start); - - /* - * If this is a TCP query, then we need to make a socket and - * a dispatch for it here. Otherwise we use the resolver's - * shared dispatch. - */ - query->dispatchmgr = res->dispatchmgr; - query->dispatch = NULL; - query->exclusivesocket = false; - query->tcpsocket = NULL; - if (res->view->peers != NULL) { - dns_peer_t *peer = NULL; - isc_netaddr_t dstip; - bool usetcp = false; - isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr); - result = dns_peerlist_peerbyaddr(res->view->peers, - &dstip, &peer); - if (result == ISC_R_SUCCESS) { - result = dns_peer_getquerysource(peer, &addr); - if (result == ISC_R_SUCCESS) - have_addr = true; - result = dns_peer_getquerydscp(peer, &dscp); - if (result == ISC_R_SUCCESS) - query->dscp = dscp; - result = dns_peer_getforcetcp(peer, &usetcp); - if (result == ISC_R_SUCCESS && usetcp) - query->options |= DNS_FETCHOPT_TCP; - } - } - - dscp = -1; - if ((query->options & DNS_FETCHOPT_TCP) != 0) { - int pf; - - pf = isc_sockaddr_pf(&addrinfo->sockaddr); - if (!have_addr) { - switch (pf) { - case PF_INET: - result = dns_dispatch_getlocaladdress( - res->dispatches4->dispatches[0], - &addr); - dscp = dns_resolver_getquerydscp4(fctx->res); - break; - case PF_INET6: - result = dns_dispatch_getlocaladdress( - res->dispatches6->dispatches[0], - &addr); - dscp = dns_resolver_getquerydscp6(fctx->res); - break; - default: - result = ISC_R_NOTIMPLEMENTED; - break; - } - if (result != ISC_R_SUCCESS) - goto cleanup_rmessage; - } - isc_sockaddr_setport(&addr, 0); - if (query->dscp == -1) - query->dscp = dscp; - - result = isc_socket_create(res->socketmgr, pf, - isc_sockettype_tcp, - &query->tcpsocket); - if (result != ISC_R_SUCCESS) - goto cleanup_rmessage; - -#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT - result = isc_socket_bind(query->tcpsocket, &addr, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_socket; -#endif - /* - * A dispatch will be created once the connect succeeds. - */ - } else { - if (have_addr) { - unsigned int attrs, attrmask; - attrs = DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(&addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - dscp = dns_resolver_getquerydscp4(fctx->res); - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - dscp = dns_resolver_getquerydscp6(fctx->res); - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup_query; - } - attrmask = DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - result = dns_dispatch_getudp(res->dispatchmgr, - res->socketmgr, - res->taskmgr, &addr, - 4096, 20000, 32768, 16411, - 16433, attrs, attrmask, - &query->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup_query; - } else { - switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { - case PF_INET: - dns_dispatch_attach( - dns_resolver_dispatchv4(res), - &query->dispatch); - query->exclusivesocket = res->exclusivev4; - dscp = dns_resolver_getquerydscp4(fctx->res); - break; - case PF_INET6: - dns_dispatch_attach( - dns_resolver_dispatchv6(res), - &query->dispatch); - query->exclusivesocket = res->exclusivev6; - dscp = dns_resolver_getquerydscp6(fctx->res); - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup_query; - } - } - - if (query->dscp == -1) - query->dscp = dscp; - /* - * We should always have a valid dispatcher here. If we - * don't support a protocol family, then its dispatcher - * will be NULL, but we shouldn't be finding addresses for - * protocol types we don't support, so the dispatcher - * we found should never be NULL. - */ - INSIST(query->dispatch != NULL); - } - - query->dispentry = NULL; - query->fctx = fctx; /* reference added by caller */ - query->tsig = NULL; - query->tsigkey = NULL; - ISC_LINK_INIT(query, link); - query->magic = QUERY_MAGIC; - - if ((query->options & DNS_FETCHOPT_TCP) != 0) { - /* - * Connect to the remote server. - * - * XXXRTH Should we attach to the socket? - */ - if (query->dscp != -1) - isc_socket_dscp(query->tcpsocket, query->dscp); - result = isc_socket_connect(query->tcpsocket, - &addrinfo->sockaddr, task, - resquery_connected, query); - if (result != ISC_R_SUCCESS) - goto cleanup_socket; - query->connects++; - QTRACE("connecting via TCP"); - } else { - if (dns_adbentry_overquota(fctx->adb, addrinfo->entry)) - goto cleanup_dispatch; - - /* Inform the ADB that we're starting a UDP fetch */ - dns_adb_beginudpfetch(fctx->adb, addrinfo); - - result = resquery_send(query); - if (result != ISC_R_SUCCESS) - goto cleanup_dispatch; - } - - fctx->querysent++; - - ISC_LIST_APPEND(fctx->queries, query, link); - bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); - fctx->nqueries++; - UNLOCK(&res->buckets[bucketnum].lock); - if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET) - inc_stats(res, dns_resstatscounter_queryv4); - else - inc_stats(res, dns_resstatscounter_queryv6); - if (res->view->resquerystats != NULL) - dns_rdatatypestats_increment(res->view->resquerystats, - fctx->type); - - return (ISC_R_SUCCESS); - - cleanup_socket: - isc_socket_detach(&query->tcpsocket); - - cleanup_dispatch: - if (query->dispatch != NULL) - dns_dispatch_detach(&query->dispatch); - - cleanup_rmessage: - dns_message_detach(&query->rmessage); - - cleanup_query: - if (query->connects == 0) { - query->magic = 0; - isc_mem_put(fctx->mctx, query, sizeof(*query)); - } - - stop_idle_timer: - RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS); - - return (result); -} - -static bool -bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { - isc_sockaddr_t *sa; - - for (sa = ISC_LIST_HEAD(fctx->bad_edns); - sa != NULL; - sa = ISC_LIST_NEXT(sa, link)) { - if (isc_sockaddr_equal(sa, address)) - return (true); - } - - return (false); -} - -static void -add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { - isc_sockaddr_t *sa; - -#ifdef ENABLE_AFL - if (dns_fuzzing_resolver) - return; -#endif - if (bad_edns(fctx, address)) - return; - - sa = isc_mem_get(fctx->mctx, sizeof(*sa)); - if (sa == NULL) - return; - - *sa = *address; - ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link); -} - -static struct tried * -triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { - struct tried *tried; - - for (tried = ISC_LIST_HEAD(fctx->edns); - tried != NULL; - tried = ISC_LIST_NEXT(tried, link)) { - if (isc_sockaddr_equal(&tried->addr, address)) - return (tried); - } - - return (NULL); -} - -static void -add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { - struct tried *tried; - - tried = triededns(fctx, address); - if (tried != NULL) { - tried->count++; - return; - } - - tried = isc_mem_get(fctx->mctx, sizeof(*tried)); - if (tried == NULL) - return; - - tried->addr = *address; - tried->count = 1; - ISC_LIST_INITANDAPPEND(fctx->edns, tried, link); -} - -static struct tried * -triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { - struct tried *tried; - - for (tried = ISC_LIST_HEAD(fctx->edns512); - tried != NULL; - tried = ISC_LIST_NEXT(tried, link)) { - if (isc_sockaddr_equal(&tried->addr, address)) - return (tried); - } - - return (NULL); -} - -static void -add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { - struct tried *tried; - - tried = triededns512(fctx, address); - if (tried != NULL) { - tried->count++; - return; - } - - tried = isc_mem_get(fctx->mctx, sizeof(*tried)); - if (tried == NULL) - return; - - tried->addr = *address; - tried->count = 1; - ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link); -} - -static inline size_t -addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) { - isc_netaddr_t netaddr; - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - switch (netaddr.family) { - case AF_INET: - INSIST(bufsize >= 4); - memmove(buf, &netaddr.type.in, 4); - return (4); - case AF_INET6: - INSIST(bufsize >= 16); - memmove(buf, &netaddr.type.in6, 16); - return (16); - default: - INSIST(0); - ISC_UNREACHABLE(); - } - return (0); -} - -static inline size_t -add_serveraddr(uint8_t *buf, const size_t bufsize, const resquery_t *query) -{ - return (addr2buf(buf, bufsize, &query->addrinfo->sockaddr)); -} - -/* - * Client cookie is 8 octets. - * Server cookie is [8..32] octets. - */ -#define CLIENT_COOKIE_SIZE 8U -#define COOKIE_BUFFER_SIZE (8U + 32U) - -static void -compute_cc(const resquery_t *query, uint8_t *cookie, const size_t len) { - INSIST(len >= CLIENT_COOKIE_SIZE); - INSIST(sizeof(query->fctx->res->view->secret) - >= ISC_SIPHASH24_KEY_LENGTH); - - uint8_t buf[16] = { 0 }; - size_t buflen = add_serveraddr(buf, sizeof(buf), query); - - uint8_t digest[ISC_SIPHASH24_TAG_LENGTH] = { 0 }; - isc_siphash24(query->fctx->res->view->secret, buf, buflen, digest); - memmove(cookie, digest, CLIENT_COOKIE_SIZE); -} - -static isc_result_t -issecuredomain(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, - isc_stdtime_t now, bool checknta, bool *ntap, bool *issecure) -{ - dns_name_t suffix; - unsigned int labels; - - /* - * For DS variants we need to check fom the parent domain, - * since there may be a negative trust anchor for the name, - * while the enclosing domain where the DS record lives is - * under a secure entry point. - */ - labels = dns_name_countlabels(name); - if (dns_rdatatype_atparent(type) && labels > 1) { - dns_name_init(&suffix, NULL); - dns_name_getlabelsequence(name, 1, labels - 1, &suffix); - name = &suffix; - } - - return (dns_view_issecuredomain(view, name, now, checknta, - ntap, issecure)); -} - -static bool -wouldvalidate(fetchctx_t *fctx) { - bool secure_domain; - isc_result_t result; - isc_stdtime_t now; - - if (!fctx->res->view->enablevalidation) { - return (false); - } - - if (fctx->res->view->dlv != NULL) { - return (true); - } - - isc_stdtime_get(&now); - result = dns_view_issecuredomain(fctx->res->view, &fctx->name, - now, true, NULL, &secure_domain); - if (result != ISC_R_SUCCESS) { - return (false); - } - return (secure_domain); -} - -static isc_result_t -resquery_send(resquery_t *query) { - fetchctx_t *fctx; - isc_result_t result; - dns_name_t *qname = NULL; - dns_rdataset_t *qrdataset = NULL; - isc_region_t r; - dns_resolver_t *res; - isc_task_t *task; - isc_socket_t *sock; - isc_buffer_t tcpbuffer; - isc_sockaddr_t *address; - isc_buffer_t *buffer; - isc_netaddr_t ipaddr; - dns_tsigkey_t *tsigkey = NULL; - dns_peer_t *peer = NULL; - bool useedns; - dns_compress_t cctx; - bool cleanup_cctx = false; - bool secure_domain; - bool connecting = false; - bool tcp = ((query->options & DNS_FETCHOPT_TCP) != 0); - dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; - unsigned ednsopt = 0; - uint16_t hint = 0, udpsize = 0; /* No EDNS */ -#ifdef HAVE_DNSTAP - isc_sockaddr_t localaddr, *la = NULL; - unsigned char zone[DNS_NAME_MAXWIRE]; - dns_dtmsgtype_t dtmsgtype; - isc_region_t zr; - isc_buffer_t zb; -#endif /* HAVE_DNSTAP */ - - fctx = query->fctx; - QTRACE("send"); - - res = fctx->res; - task = res->buckets[fctx->bucketnum].task; - address = NULL; - - if (tcp) { - /* - * Reserve space for the TCP message length. - */ - isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data)); - isc_buffer_init(&query->buffer, query->data + 2, - sizeof(query->data) - 2); - buffer = &tcpbuffer; - } else { - isc_buffer_init(&query->buffer, query->data, - sizeof(query->data)); - buffer = &query->buffer; - } - - result = dns_message_gettempname(fctx->qmessage, &qname); - if (result != ISC_R_SUCCESS) - goto cleanup_temps; - result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset); - if (result != ISC_R_SUCCESS) - goto cleanup_temps; - - /* - * Get a query id from the dispatch. - */ - result = dns_dispatch_addresponse2(query->dispatch, - &query->addrinfo->sockaddr, - task, - resquery_response, - query, - &query->id, - &query->dispentry, - res->socketmgr); - if (result != ISC_R_SUCCESS) - goto cleanup_temps; - - fctx->qmessage->opcode = dns_opcode_query; - - /* - * Set up question. - */ - dns_name_init(qname, NULL); - dns_name_clone(&fctx->name, qname); - dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type); - ISC_LIST_APPEND(qname->list, qrdataset, link); - dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION); - qname = NULL; - qrdataset = NULL; - - /* - * Set RD if the client has requested that we do a recursive query, - * or if we're sending to a forwarder. - */ - if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 || - ISFORWARDER(query->addrinfo)) - fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD; - - /* - * Set CD if the client says not to validate, or if the - * question is under a secure entry point and this is a - * recursive/forward query -- unless the client said not to. - */ - if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) { - /* Do nothing */ - } else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) { - fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; - } else if (res->view->enablevalidation && - ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0)) - { - bool checknta = !NONTA(query->options); - bool ntacovered = false; - result = issecuredomain(res->view, &fctx->name, fctx->type, - isc_time_seconds(&query->start), - checknta, &ntacovered, &secure_domain); - if (result != ISC_R_SUCCESS) { - secure_domain = false; - } - if (res->view->dlv != NULL) { - secure_domain = true; - } - - if (secure_domain || - (ISFORWARDER(query->addrinfo) && ntacovered)) - { - fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; - } - } - - /* - * We don't have to set opcode because it defaults to query. - */ - fctx->qmessage->id = query->id; - - /* - * Convert the question to wire format. - */ - result = dns_compress_init(&cctx, -1, fctx->res->mctx); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - cleanup_cctx = true; - - result = dns_message_renderbegin(fctx->qmessage, &cctx, - &query->buffer); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - - result = dns_message_rendersection(fctx->qmessage, - DNS_SECTION_QUESTION, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - - peer = NULL; - isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr); - (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer); - - /* - * The ADB does not know about servers with "edns no". Check this, - * and then inform the ADB for future use. - */ - if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 && - peer != NULL && - dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS && - !useedns) - { - query->options |= DNS_FETCHOPT_NOEDNS0; - dns_adb_changeflags(fctx->adb, query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); - } - - /* Sync NOEDNS0 flag in addrinfo->flags and options now. */ - if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0) - query->options |= DNS_FETCHOPT_NOEDNS0; - - /* See if response history indicates that EDNS is not supported. */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && - dns_adb_noedns(fctx->adb, query->addrinfo)) - query->options |= DNS_FETCHOPT_NOEDNS0; - - if (fctx->timeout && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr; - struct tried *tried; - - if (fctx->timeouts > (MAX_EDNS0_TIMEOUTS * 2) && - (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { - query->options |= DNS_FETCHOPT_NOEDNS0; - fctx->reason = "disabling EDNS"; - } else if ((tried = triededns512(fctx, sockaddr)) != NULL && - tried->count >= 2U && - (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { - query->options |= DNS_FETCHOPT_NOEDNS0; - fctx->reason = "disabling EDNS"; - } else if ((tried = triededns(fctx, sockaddr)) != NULL) { - if (tried->count == 1U) { - hint = dns_adb_getudpsize(fctx->adb, - query->addrinfo); - } else if (tried->count >= 2U) { - query->options |= DNS_FETCHOPT_EDNS512; - fctx->reason = "reducing the advertised EDNS " - "UDP packet size to 512 octets"; - } - } - } - fctx->timeout = false; - - /* - * Use EDNS0, unless the caller doesn't want it, or we know that - * the remote server doesn't like it. - */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { - unsigned int version = DNS_EDNS_VERSION; - unsigned int flags = query->addrinfo->flags; - bool reqnsid = res->view->requestnsid; - bool sendcookie = res->view->sendcookie; - unsigned char cookie[COOKIE_BUFFER_SIZE]; - - if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 && - (query->options & DNS_FETCHOPT_EDNS512) == 0) { - udpsize = dns_adb_probesize2(fctx->adb, - query->addrinfo, - fctx->timeouts); - if (udpsize > res->udpsize) - udpsize = res->udpsize; - } - - if (peer != NULL) - (void)dns_peer_getudpsize(peer, &udpsize); - - if (udpsize == 0U && res->udpsize == 512U) - udpsize = 512; - - /* - * Was the size forced to 512 in the configuration? - */ - if (udpsize == 512U) - query->options |= DNS_FETCHOPT_EDNS512; - - /* - * We have talked to this server before. - */ - if (hint != 0U) - udpsize = hint; - - /* - * We know nothing about the peer's capabilities - * so start with minimal EDNS UDP size. - */ - if (udpsize == 0U) - udpsize = 512; - - if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { - version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; - version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT; - } - - /* Request NSID/COOKIE/VERSION for current peer? */ - if (peer != NULL) { - uint8_t ednsversion; - (void) dns_peer_getrequestnsid(peer, &reqnsid); - (void) dns_peer_getsendcookie(peer, - &sendcookie); - result = dns_peer_getednsversion(peer, - &ednsversion); - if (result == ISC_R_SUCCESS && - ednsversion < version) - version = ednsversion; - } - if (NOCOOKIE(query->addrinfo)) - sendcookie = false; - if (reqnsid) { - INSIST(ednsopt < DNS_EDNSOPTIONS); - ednsopts[ednsopt].code = DNS_OPT_NSID; - ednsopts[ednsopt].length = 0; - ednsopts[ednsopt].value = NULL; - ednsopt++; - } -#if DNS_EDNS_VERSION > 0 - /* - * Some EDNS(0) servers don't ignore unknown options - * as it was not a explicit requirement of RFC 2671. - * Only send COOKIE to EDNS(1) servers. - */ - if (version < 1) - sendcookie = false; -#endif - if (sendcookie) { - INSIST(ednsopt < DNS_EDNSOPTIONS); - ednsopts[ednsopt].code = DNS_OPT_COOKIE; - ednsopts[ednsopt].length = (uint16_t) - dns_adb_getcookie(fctx->adb, - query->addrinfo, - cookie, - sizeof(cookie)); - if (ednsopts[ednsopt].length != 0) { - ednsopts[ednsopt].value = cookie; - inc_stats(fctx->res, - dns_resstatscounter_cookieout); - } else { - compute_cc(query, cookie, - CLIENT_COOKIE_SIZE); - ednsopts[ednsopt].value = cookie; - ednsopts[ednsopt].length = - CLIENT_COOKIE_SIZE; - inc_stats(fctx->res, - dns_resstatscounter_cookienew); - } - ednsopt++; - } - query->ednsversion = version; - result = fctx_addopt(fctx->qmessage, version, - udpsize, ednsopts, ednsopt); - if (reqnsid && result == ISC_R_SUCCESS) { - query->options |= DNS_FETCHOPT_WANTNSID; - } else if (result != ISC_R_SUCCESS) { - /* - * We couldn't add the OPT, but we'll press on. - * We're not using EDNS0, so set the NOEDNS0 - * bit. - */ - query->options |= DNS_FETCHOPT_NOEDNS0; - query->ednsversion = -1; - udpsize = 0; - } - } else { - /* - * We know this server doesn't like EDNS0, so we - * won't use it. Set the NOEDNS0 bit since we're - * not using EDNS0. - */ - query->options |= DNS_FETCHOPT_NOEDNS0; - query->ednsversion = -1; - } - } else - query->ednsversion = -1; - - /* - * Record the UDP EDNS size chosen. - */ - query->udpsize = udpsize; - - /* - * If we need EDNS0 to do this query and aren't using it, we lose. - */ - if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) { - result = DNS_R_SERVFAIL; - goto cleanup_message; - } - - if (udpsize > 512U) - add_triededns(fctx, &query->addrinfo->sockaddr); - - if (udpsize == 512U) - add_triededns512(fctx, &query->addrinfo->sockaddr); - - /* - * Clear CD if EDNS is not in use. - */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) - fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; - - /* - * Add TSIG record tailored to the current recipient. - */ - result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto cleanup_message; - - if (tsigkey != NULL) { - result = dns_message_settsigkey(fctx->qmessage, tsigkey); - dns_tsigkey_detach(&tsigkey); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - } - - result = dns_message_rendersection(fctx->qmessage, - DNS_SECTION_ADDITIONAL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - - result = dns_message_renderend(fctx->qmessage); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - -#ifdef HAVE_DNSTAP - memset(&zr, 0, sizeof(zr)); - isc_buffer_init(&zb, zone, sizeof(zone)); - dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE); - result = dns_name_towire(&fctx->domain, &cctx, &zb); - if (result == ISC_R_SUCCESS) - isc_buffer_usedregion(&zb, &zr); -#endif /* HAVE_DNSTAP */ - - dns_compress_invalidate(&cctx); - cleanup_cctx = false; - - if (dns_message_gettsigkey(fctx->qmessage) != NULL) { - dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage), - &query->tsigkey); - result = dns_message_getquerytsig(fctx->qmessage, - fctx->res->mctx, - &query->tsig); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - } - - /* - * If using TCP, write the length of the message at the beginning - * of the buffer. - */ - if (tcp) { - isc_buffer_usedregion(&query->buffer, &r); - isc_buffer_putuint16(&tcpbuffer, (uint16_t)r.length); - isc_buffer_add(&tcpbuffer, r.length); - } - - /* - * Log the outgoing packet. - */ - dns_message_logfmtpacket2(fctx->qmessage, "sending packet to", - &query->addrinfo->sockaddr, - DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_PACKETS, - &dns_master_style_comment, - ISC_LOG_DEBUG(11), - fctx->res->mctx); - - /* - * We're now done with the query message. - */ - dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); - - if (query->exclusivesocket) { - sock = dns_dispatch_getentrysocket(query->dispentry); - } else { - sock = dns_dispatch_getsocket(query->dispatch); - } - - /* - * Send the query! - */ - if (!tcp) { - address = &query->addrinfo->sockaddr; - if (query->exclusivesocket) { - result = isc_socket_connect(sock, address, task, - resquery_udpconnected, - query); - if (result != ISC_R_SUCCESS) - goto cleanup_message; - connecting = true; - query->connects++; - } - } - isc_buffer_usedregion(buffer, &r); - - /* - * XXXRTH Make sure we don't send to ourselves! We should probably - * prune out these addresses when we get them from the ADB. - */ - memset(&query->sendevent, 0, sizeof(query->sendevent)); - ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL, - ISC_SOCKEVENT_SENDDONE, resquery_senddone, query, - NULL, NULL, NULL); - - if (query->dscp == -1) { - query->sendevent.attributes &= ~ISC_SOCKEVENTATTR_DSCP; - query->sendevent.dscp = 0; - } else { - query->sendevent.attributes |= ISC_SOCKEVENTATTR_DSCP; - query->sendevent.dscp = query->dscp; - if (tcp) - isc_socket_dscp(sock, query->dscp); - } - - result = isc_socket_sendto2(sock, &r, task, address, NULL, - &query->sendevent, 0); - if (result != ISC_R_SUCCESS) { - if (connecting) { - /* - * This query is still connecting. - * Mark it as canceled so that it will just be - * cleaned up when the connected event is received. - * Keep fctx around until the event is processed. - */ - query->fctx->nqueries++; - query->attributes |= RESQUERY_ATTR_CANCELED; - } - goto cleanup_message; - } - - query->sends++; - - QTRACE("sent"); - -#ifdef HAVE_DNSTAP - /* - * Log the outgoing query via dnstap. - */ - if ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0) - dtmsgtype = DNS_DTTYPE_FQ; - else - dtmsgtype = DNS_DTTYPE_RQ; - - result = isc_socket_getsockname(sock, &localaddr); - if (result == ISC_R_SUCCESS) - la = &localaddr; - - dns_dt_send(fctx->res->view, dtmsgtype, la, &query->addrinfo->sockaddr, - tcp, &zr, &query->start, NULL, &query->buffer); -#endif /* HAVE_DNSTAP */ - - return (ISC_R_SUCCESS); - - cleanup_message: - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - - dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); - - /* - * Stop the dispatcher from listening. - */ - dns_dispatch_removeresponse(&query->dispentry, NULL); - - cleanup_temps: - if (qname != NULL) - dns_message_puttempname(fctx->qmessage, &qname); - if (qrdataset != NULL) - dns_message_puttemprdataset(fctx->qmessage, &qrdataset); - - return (result); -} - -static void -resquery_connected(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - resquery_t *query = event->ev_arg; - bool retry = false; - isc_interval_t interval; - isc_result_t result; - unsigned int attrs; - fetchctx_t *fctx; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); - REQUIRE(VALID_QUERY(query)); - - QTRACE("connected"); - - UNUSED(task); - - /* - * XXXRTH - * - * Currently we don't wait for the connect event before retrying - * a query. This means that if we get really behind, we may end - * up doing extra work! - */ - - query->connects--; - fctx = query->fctx; - - if (RESQUERY_CANCELED(query)) { - /* - * This query was canceled while the connect() was in - * progress. - */ - isc_socket_detach(&query->tcpsocket); - resquery_destroy(&query); - } else { - switch (sevent->result) { - case ISC_R_SUCCESS: - - /* - * Extend the idle timer for TCP. 20 seconds - * should be long enough for a TCP connection to be - * established, a single DNS request to be sent, - * and the response received. - */ - isc_interval_set(&interval, 20, 0); - result = fctx_startidletimer(query->fctx, &interval); - if (result != ISC_R_SUCCESS) { - FCTXTRACE("query canceled: idle timer failed; " - "responding"); - - fctx_cancelquery(&query, NULL, NULL, false, - false); - fctx_done(fctx, result, __LINE__); - break; - } - /* - * We are connected. Create a dispatcher and - * send the query. - */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_TCP; - attrs |= DNS_DISPATCHATTR_PRIVATE; - attrs |= DNS_DISPATCHATTR_CONNECTED; - if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == - AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - - result = dns_dispatch_createtcp(query->dispatchmgr, - query->tcpsocket, - query->fctx->res->taskmgr, - 4096, 2, 1, 1, 3, attrs, - &query->dispatch); - - /* - * Regardless of whether dns_dispatch_create() - * succeeded or not, we don't need our reference - * to the socket anymore. - */ - isc_socket_detach(&query->tcpsocket); - - if (result == ISC_R_SUCCESS) - result = resquery_send(query); - - if (result != ISC_R_SUCCESS) { - FCTXTRACE("query canceled: " - "resquery_send() failed; responding"); - - fctx_cancelquery(&query, NULL, NULL, false, false); - fctx_done(fctx, result, __LINE__); - } - break; - - case ISC_R_NETUNREACH: - case ISC_R_HOSTUNREACH: - case ISC_R_CONNREFUSED: - case ISC_R_NOPERM: - case ISC_R_ADDRNOTAVAIL: - case ISC_R_CONNECTIONRESET: - FCTXTRACE3("query canceled in connected(): " - "no route to host; no response", - sevent->result); - - /* - * No route to remote. - */ - isc_socket_detach(&query->tcpsocket); - /* - * Do not query this server again in this fetch context - * if we already tried reducing the advertised EDNS UDP - * payload size to 512 bytes and the server is - * unavailable over TCP. This prevents query loops - * lasting until the fetch context restart limit is - * reached when attempting to get answers whose size - * exceeds 512 bytes from broken servers. - */ - if ((query->options & DNS_FETCHOPT_EDNS512) != 0) { - add_bad(fctx, query->rmessage, - query->addrinfo, sevent->result, - badns_unreachable); - } - fctx_cancelquery(&query, NULL, NULL, true, false); - retry = true; - break; - - default: - FCTXTRACE3("query canceled in connected() due to " - "unexpected event result; responding", - sevent->result); - - isc_socket_detach(&query->tcpsocket); - fctx_cancelquery(&query, NULL, NULL, false, false); - break; - } - } - - isc_event_free(&event); - - if (retry) { - /* - * Behave as if the idle timer has expired. For TCP - * connections this may not actually reflect the latest timer. - */ - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - result = fctx_stopidletimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - else - fctx_try(fctx, true, false); - } -} - -static void -fctx_finddone(isc_task_t *task, isc_event_t *event) { - fetchctx_t *fctx; - dns_adbfind_t *find; - dns_resolver_t *res; - bool want_try = false; - bool want_done = false; - bool bucket_empty = false; - unsigned int bucketnum; - bool dodestroy = false; - - find = event->ev_sender; - fctx = event->ev_arg; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - - UNUSED(task); - - FCTXTRACE("finddone"); - - bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); - - INSIST(fctx->pending > 0); - fctx->pending--; - - if (ADDRWAIT(fctx)) { - /* - * The fetch is waiting for a name to be found. - */ - INSIST(!fctx->shuttingdown); - if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) { - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - want_try = true; - } else { - fctx->findfail++; - if (fctx->pending == 0) { - /* - * We've got nothing else to wait for and don't - * know the answer. There's nothing to do but - * fail the fctx. - */ - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - want_done = true; - } - } - } else if (fctx->shuttingdown && fctx->pending == 0 && - fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { - - if (fctx->references == 0) { - bucket_empty = fctx_unlink(fctx); - dodestroy = true; - } - } - UNLOCK(&res->buckets[bucketnum].lock); - - isc_event_free(&event); - dns_adb_destroyfind(&find); - - if (want_try) { - fctx_try(fctx, true, false); - } else if (want_done) { - FCTXTRACE("fetch failed in finddone(); return ISC_R_FAILURE"); - fctx_done(fctx, ISC_R_FAILURE, __LINE__); - } else if (dodestroy) { - fctx_destroy(fctx); - if (bucket_empty) - empty_bucket(res); - } -} - - -static inline bool -bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) { - isc_sockaddr_t *sa; - - for (sa = ISC_LIST_HEAD(fctx->bad); - sa != NULL; - sa = ISC_LIST_NEXT(sa, link)) { - if (isc_sockaddr_equal(sa, address)) - return (true); - } - - return (false); -} - -static inline bool -mark_bad(fetchctx_t *fctx) { - dns_adbfind_t *curr; - dns_adbaddrinfo_t *addrinfo; - bool all_bad = true; - -#ifdef ENABLE_AFL - if (dns_fuzzing_resolver) - return false; -#endif - - /* - * Mark all known bad servers, so we don't try to talk to them - * again. - */ - - /* - * Mark any bad nameservers. - */ - for (curr = ISC_LIST_HEAD(fctx->finds); - curr != NULL; - curr = ISC_LIST_NEXT(curr, publink)) { - for (addrinfo = ISC_LIST_HEAD(curr->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, &addrinfo->sockaddr)) - addrinfo->flags |= FCTX_ADDRINFO_MARK; - else - all_bad = false; - } - } - - /* - * Mark any bad forwarders. - */ - for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, &addrinfo->sockaddr)) - addrinfo->flags |= FCTX_ADDRINFO_MARK; - else - all_bad = false; - } - - /* - * Mark any bad alternates. - */ - for (curr = ISC_LIST_HEAD(fctx->altfinds); - curr != NULL; - curr = ISC_LIST_NEXT(curr, publink)) { - for (addrinfo = ISC_LIST_HEAD(curr->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, &addrinfo->sockaddr)) - addrinfo->flags |= FCTX_ADDRINFO_MARK; - else - all_bad = false; - } - } - - for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (bad_server(fctx, &addrinfo->sockaddr)) - addrinfo->flags |= FCTX_ADDRINFO_MARK; - else - all_bad = false; - } - - return (all_bad); -} - -static void -add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo, - isc_result_t reason, badnstype_t badtype) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - char classbuf[64]; - char typebuf[64]; - char code[64]; - isc_buffer_t b; - isc_sockaddr_t *sa; - const char *spc = ""; - isc_sockaddr_t *address = &addrinfo->sockaddr; - -#ifdef ENABLE_AFL - if (dns_fuzzing_resolver) - return; -#endif - - if (reason == DNS_R_LAME) - fctx->lamecount++; - else { - switch (badtype) { - case badns_unreachable: - fctx->neterr++; - break; - case badns_response: - fctx->badresp++; - break; - case badns_validation: - break; /* counted as 'valfail' */ - case badns_forwarder: - /* - * We were called to prevent the given forwarder from - * being used again for this fetch context. - */ - break; - } - } - - if (bad_server(fctx, address)) { - /* - * We already know this server is bad. - */ - return; - } - - FCTXTRACE("add_bad"); - - sa = isc_mem_get(fctx->mctx, sizeof(*sa)); - if (sa == NULL) - return; - *sa = *address; - ISC_LIST_INITANDAPPEND(fctx->bad, sa, link); - - if (reason == DNS_R_LAME) /* already logged */ - return; - - if (reason == DNS_R_UNEXPECTEDRCODE && - rmessage->rcode == dns_rcode_servfail && - ISFORWARDER(addrinfo)) - return; - - if (reason == DNS_R_UNEXPECTEDRCODE) { - isc_buffer_init(&b, code, sizeof(code) - 1); - dns_rcode_totext(rmessage->rcode, &b); - code[isc_buffer_usedlength(&b)] = '\0'; - spc = " "; - } else if (reason == DNS_R_UNEXPECTEDOPCODE) { - isc_buffer_init(&b, code, sizeof(code) - 1); - dns_opcode_totext((dns_opcode_t)rmessage->opcode, &b); - code[isc_buffer_usedlength(&b)] = '\0'; - spc = " "; - } else { - code[0] = '\0'; - } - dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf)); - isc_sockaddr_format(address, addrbuf, sizeof(addrbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "%s%s%s resolving '%s/%s/%s': %s", - code, spc, dns_result_totext(reason), - namebuf, typebuf, classbuf, addrbuf); -} - -/* - * Sort addrinfo list by RTT. - */ -static void -sort_adbfind(dns_adbfind_t *find, unsigned int bias) { - dns_adbaddrinfo_t *best, *curr; - dns_adbaddrinfolist_t sorted; - unsigned int best_srtt, curr_srtt; - - /* Lame N^2 bubble sort. */ - ISC_LIST_INIT(sorted); - while (!ISC_LIST_EMPTY(find->list)) { - best = ISC_LIST_HEAD(find->list); - best_srtt = best->srtt; - if (isc_sockaddr_pf(&best->sockaddr) != AF_INET6) - best_srtt += bias; - curr = ISC_LIST_NEXT(best, publink); - while (curr != NULL) { - curr_srtt = curr->srtt; - if (isc_sockaddr_pf(&curr->sockaddr) != AF_INET6) - curr_srtt += bias; - if (curr_srtt < best_srtt) { - best = curr; - best_srtt = curr_srtt; - } - curr = ISC_LIST_NEXT(curr, publink); - } - ISC_LIST_UNLINK(find->list, best, publink); - ISC_LIST_APPEND(sorted, best, publink); - } - find->list = sorted; -} - -/* - * Sort a list of finds by server RTT. - */ -static void -sort_finds(dns_adbfindlist_t *findlist, unsigned int bias) { - dns_adbfind_t *best, *curr; - dns_adbfindlist_t sorted; - dns_adbaddrinfo_t *addrinfo, *bestaddrinfo; - unsigned int best_srtt, curr_srtt; - - /* Sort each find's addrinfo list by SRTT. */ - for (curr = ISC_LIST_HEAD(*findlist); - curr != NULL; - curr = ISC_LIST_NEXT(curr, publink)) - sort_adbfind(curr, bias); - - /* Lame N^2 bubble sort. */ - ISC_LIST_INIT(sorted); - while (!ISC_LIST_EMPTY(*findlist)) { - best = ISC_LIST_HEAD(*findlist); - bestaddrinfo = ISC_LIST_HEAD(best->list); - INSIST(bestaddrinfo != NULL); - best_srtt = bestaddrinfo->srtt; - if (isc_sockaddr_pf(&bestaddrinfo->sockaddr) != AF_INET6) - best_srtt += bias; - curr = ISC_LIST_NEXT(best, publink); - while (curr != NULL) { - addrinfo = ISC_LIST_HEAD(curr->list); - INSIST(addrinfo != NULL); - curr_srtt = addrinfo->srtt; - if (isc_sockaddr_pf(&addrinfo->sockaddr) != AF_INET6) - curr_srtt += bias; - if (curr_srtt < best_srtt) { - best = curr; - best_srtt = curr_srtt; - } - curr = ISC_LIST_NEXT(curr, publink); - } - ISC_LIST_UNLINK(*findlist, best, publink); - ISC_LIST_APPEND(sorted, best, publink); - } - *findlist = sorted; -} - -static void -findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, - unsigned int options, unsigned int flags, isc_stdtime_t now, - bool *overquota, bool *need_alternate, unsigned int *no_addresses) { - dns_adbaddrinfo_t *ai; - dns_adbfind_t *find; - dns_resolver_t *res; - bool unshared; - isc_result_t result; - - res = fctx->res; - unshared = ((fctx->options & DNS_FETCHOPT_UNSHARED) != 0); - /* - * If this name is a subdomain of the query domain, tell - * the ADB to start looking using zone/hint data. This keeps us - * from getting stuck if the nameserver is beneath the zone cut - * and we don't know its address (e.g. because the A record has - * expired). - */ - if (dns_name_issubdomain(name, &fctx->domain)) - options |= DNS_ADBFIND_STARTATZONE; - options |= DNS_ADBFIND_GLUEOK; - options |= DNS_ADBFIND_HINTOK; - - /* - * See what we know about this address. - */ - find = NULL; - result = dns_adb_createfind2(fctx->adb, - res->buckets[fctx->bucketnum].task, - fctx_finddone, fctx, name, - &fctx->name, fctx->type, - options, now, NULL, - res->view->dstport, - fctx->depth + 1, fctx->qc, &find); - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_ALIAS) { - char namebuf[DNS_NAME_FORMATSIZE]; - - /* - * XXXRTH Follow the CNAME/DNAME chain? - */ - dns_adb_destroyfind(&find); - fctx->adberr++; - dns_name_format(name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_CNAME, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "skipping nameserver '%s' because it " - "is a CNAME, while resolving '%s'", - namebuf, fctx->info); - } - } else if (!ISC_LIST_EMPTY(find->list)) { - /* - * We have at least some of the addresses for the - * name. - */ - INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0); - if (flags != 0 || port != 0) { - for (ai = ISC_LIST_HEAD(find->list); - ai != NULL; - ai = ISC_LIST_NEXT(ai, publink)) { - ai->flags |= flags; - if (port != 0) - isc_sockaddr_setport(&ai->sockaddr, - port); - } - } - if ((flags & FCTX_ADDRINFO_FORWARDER) != 0) - ISC_LIST_APPEND(fctx->altfinds, find, publink); - else - ISC_LIST_APPEND(fctx->finds, find, publink); - } else { - /* - * We don't know any of the addresses for this - * name. - */ - if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) { - /* - * We're looking for them and will get an - * event about it later. - */ - fctx->pending++; - /* - * Bootstrap. - */ - if (need_alternate != NULL && - !*need_alternate && unshared && - ((res->dispatches4 == NULL && - find->result_v6 != DNS_R_NXDOMAIN) || - (res->dispatches6 == NULL && - find->result_v4 != DNS_R_NXDOMAIN))) - { - *need_alternate = true; - } - if (no_addresses != NULL) { - (*no_addresses)++; - } - } else { - if ((find->options & DNS_ADBFIND_OVERQUOTA) != 0) { - if (overquota != NULL) - *overquota = true; - fctx->quotacount++; /* quota exceeded */ - } - else if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) - fctx->lamecount++; /* cached lame server */ - else - fctx->adberr++; /* unreachable server, etc. */ - - /* - * If we know there are no addresses for - * the family we are using then try to add - * an alternative server. - */ - if (need_alternate != NULL && !*need_alternate && - ((res->dispatches4 == NULL && - find->result_v6 == DNS_R_NXRRSET) || - (res->dispatches6 == NULL && - find->result_v4 == DNS_R_NXRRSET))) - *need_alternate = true; - dns_adb_destroyfind(&find); - } - } -} - -static bool -isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { - int order; - unsigned int nlabels; - dns_namereln_t namereln; - - namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); - return (namereln == dns_namereln_subdomain); -} - -static isc_result_t -fctx_getaddresses(fetchctx_t *fctx, bool badcache) { - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_resolver_t *res; - isc_stdtime_t now; - unsigned int stdoptions = 0; - dns_forwarder_t *fwd; - dns_adbaddrinfo_t *ai; - bool all_bad; - dns_rdata_ns_t ns; - bool need_alternate = false; - bool all_spilled = true; - unsigned int no_addresses = 0; - - FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth); - - /* - * Don't pound on remote servers. (Failsafe!) - */ - fctx->restarts++; - if (fctx->restarts > 100) { - FCTXTRACE("too many restarts"); - return (DNS_R_SERVFAIL); - } - - res = fctx->res; - - if (fctx->depth > res->maxdepth) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), - "too much NS indirection resolving '%s' " - "(depth=%u, maxdepth=%u)", - fctx->info, fctx->depth, res->maxdepth); - return (DNS_R_SERVFAIL); - } - - /* - * Forwarders. - */ - - INSIST(ISC_LIST_EMPTY(fctx->forwaddrs)); - INSIST(ISC_LIST_EMPTY(fctx->altaddrs)); - - /* - * If we have DNS_FETCHOPT_NOFORWARD set and forwarding policy - * allows us to not forward - skip forwarders and go straight - * to NSes. This is currently used to make sure that priming query - * gets root servers' IP addresses in ADDITIONAL section. - */ - if ((fctx->options & DNS_FETCHOPT_NOFORWARD) != 0 && - (fctx->fwdpolicy != dns_fwdpolicy_only)) - { - goto normal_nses; - } - - /* - * If this fctx has forwarders, use them; otherwise use any - * selective forwarders specified in the view; otherwise use the - * resolver's forwarders (if any). - */ - fwd = ISC_LIST_HEAD(fctx->forwarders); - if (fwd == NULL) { - dns_forwarders_t *forwarders = NULL; - dns_name_t *name = &fctx->name; - dns_name_t suffix; - unsigned int labels; - dns_fixedname_t fixed; - dns_name_t *domain; - - /* - * DS records are found in the parent server. - * Strip label to get the correct forwarder (if any). - */ - if (dns_rdatatype_atparent(fctx->type) && - dns_name_countlabels(name) > 1) { - dns_name_init(&suffix, NULL); - labels = dns_name_countlabels(name); - dns_name_getlabelsequence(name, 1, labels - 1, &suffix); - name = &suffix; - } - - domain = dns_fixedname_initname(&fixed); - result = dns_fwdtable_find2(res->view->fwdtable, name, - domain, &forwarders); - if (result == ISC_R_SUCCESS) { - fwd = ISC_LIST_HEAD(forwarders->fwdrs); - fctx->fwdpolicy = forwarders->fwdpolicy; - if (fctx->fwdpolicy == dns_fwdpolicy_only && - isstrictsubdomain(domain, &fctx->domain)) { - fcount_decr(fctx); - dns_name_free(&fctx->domain, fctx->mctx); - dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(domain, fctx->mctx, - &fctx->domain); - if (result != ISC_R_SUCCESS) - return (result); - result = fcount_incr(fctx, true); - if (result != ISC_R_SUCCESS) - return (result); - } - } - } - - while (fwd != NULL) { - if ((isc_sockaddr_pf(&fwd->addr) == AF_INET && - res->dispatches4 == NULL) || - (isc_sockaddr_pf(&fwd->addr) == AF_INET6 && - res->dispatches6 == NULL)) - { - fwd = ISC_LIST_NEXT(fwd, link); - continue; - } - ai = NULL; - result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0); - if (result == ISC_R_SUCCESS) { - dns_adbaddrinfo_t *cur; - ai->flags |= FCTX_ADDRINFO_FORWARDER; - ai->dscp = fwd->dscp; - cur = ISC_LIST_HEAD(fctx->forwaddrs); - while (cur != NULL && cur->srtt < ai->srtt) - cur = ISC_LIST_NEXT(cur, publink); - if (cur != NULL) - ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur, - ai, publink); - else - ISC_LIST_APPEND(fctx->forwaddrs, ai, publink); - } - fwd = ISC_LIST_NEXT(fwd, link); - } - - /* - * If the forwarding policy is "only", we don't need the addresses - * of the nameservers. - */ - if (fctx->fwdpolicy == dns_fwdpolicy_only) - goto out; - - /* - * Normal nameservers. - */ - normal_nses: - stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT; - if (fctx->restarts == 1) { - /* - * To avoid sending out a flood of queries likely to - * result in NXRRSET, we suppress fetches for address - * families we don't have the first time through, - * provided that we have addresses in some family we - * can use. - * - * We don't want to set this option all the time, since - * if fctx->restarts > 1, we've clearly been having trouble - * with the addresses we had, so getting more could help. - */ - stdoptions |= DNS_ADBFIND_AVOIDFETCHES; - } - if (res->dispatches4 != NULL) - stdoptions |= DNS_ADBFIND_INET; - if (res->dispatches6 != NULL) - stdoptions |= DNS_ADBFIND_INET6; - - if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0) - return (DNS_R_SERVFAIL); - - isc_stdtime_get(&now); - - INSIST(ISC_LIST_EMPTY(fctx->finds)); - INSIST(ISC_LIST_EMPTY(fctx->altfinds)); - - for (result = dns_rdataset_first(&fctx->nameservers); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&fctx->nameservers)) - { - bool overquota = false; - - dns_rdataset_current(&fctx->nameservers, &rdata); - /* - * Extract the name from the NS record. - */ - result = dns_rdata_tostruct(&rdata, &ns, NULL); - if (result != ISC_R_SUCCESS) { - continue; - } - - if (no_addresses > NS_FAIL_LIMIT && - dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT) - { - stdoptions |= DNS_ADBFIND_NOFETCH; - } - findname(fctx, &ns.name, 0, stdoptions, 0, now, &overquota, - &need_alternate, &no_addresses); - - if (!overquota) { - all_spilled = false; - } - - dns_rdata_reset(&rdata); - dns_rdata_freestruct(&ns); - } - if (result != ISC_R_NOMORE) { - return (result); - } - - /* - * Do we need to use 6 to 4? - */ - if (need_alternate) { - int family; - alternate_t *a; - family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET; - for (a = ISC_LIST_HEAD(res->alternates); - a != NULL; - a = ISC_LIST_NEXT(a, link)) { - if (!a->isaddress) { - findname(fctx, &a->_u._n.name, a->_u._n.port, - stdoptions, FCTX_ADDRINFO_FORWARDER, - now, NULL, NULL, NULL); - continue; - } - if (isc_sockaddr_pf(&a->_u.addr) != family) - continue; - ai = NULL; - result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr, - &ai, 0); - if (result == ISC_R_SUCCESS) { - dns_adbaddrinfo_t *cur; - ai->flags |= FCTX_ADDRINFO_FORWARDER; - cur = ISC_LIST_HEAD(fctx->altaddrs); - while (cur != NULL && cur->srtt < ai->srtt) - cur = ISC_LIST_NEXT(cur, publink); - if (cur != NULL) - ISC_LIST_INSERTBEFORE(fctx->altaddrs, - cur, ai, publink); - else - ISC_LIST_APPEND(fctx->altaddrs, ai, - publink); - } - } - } - - out: - /* - * Mark all known bad servers. - */ - all_bad = mark_bad(fctx); - - /* - * How are we doing? - */ - if (all_bad) { - /* - * We've got no addresses. - */ - if (fctx->pending > 0) { - /* - * We're fetching the addresses, but don't have any - * yet. Tell the caller to wait for an answer. - */ - result = DNS_R_WAIT; - } else { - isc_time_t expire; - isc_interval_t i; - /* - * We've lost completely. We don't know any - * addresses, and the ADB has told us it can't get - * them. - */ - FCTXTRACE("no addresses"); - isc_interval_set(&i, DNS_RESOLVER_BADCACHETTL(fctx), 0); - result = isc_time_nowplusinterval(&expire, &i); - if (badcache && - (fctx->type == dns_rdatatype_dnskey || - fctx->type == dns_rdatatype_dlv || - fctx->type == dns_rdatatype_ds) && - result == ISC_R_SUCCESS) - dns_resolver_addbadcache(res, &fctx->name, - fctx->type, &expire); - - result = ISC_R_FAILURE; - - /* - * If all of the addresses found were over the - * fetches-per-server quota, return the configured - * response. - */ - if (all_spilled) { - result = res->quotaresp[dns_quotatype_server]; - inc_stats(res, dns_resstatscounter_serverquota); - } - } - } else { - /* - * We've found some addresses. We might still be looking - * for more addresses. - */ - sort_finds(&fctx->finds, res->view->v6bias); - sort_finds(&fctx->altfinds, 0); - result = ISC_R_SUCCESS; - } - - return (result); -} - -static inline void -possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) { - isc_netaddr_t na; - char buf[ISC_NETADDR_FORMATSIZE]; - isc_sockaddr_t *sa; - bool aborted = false; - bool bogus; - dns_acl_t *blackhole; - isc_netaddr_t ipaddr; - dns_peer_t *peer = NULL; - dns_resolver_t *res; - const char *msg = NULL; - - sa = &addr->sockaddr; - - res = fctx->res; - isc_netaddr_fromsockaddr(&ipaddr, sa); - blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr); - (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer); - - if (blackhole != NULL) { - int match; - - if (dns_acl_match(&ipaddr, NULL, blackhole, - &res->view->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - aborted = true; - } - - if (peer != NULL && - dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS && - bogus) - aborted = true; - - if (aborted) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring blackholed / bogus server: "; - } else if (isc_sockaddr_isnetzero(sa)) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring net zero address: "; - } else if (isc_sockaddr_ismulticast(sa)) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring multicast address: "; - } else if (isc_sockaddr_isexperimental(sa)) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring experimental address: "; - } else if (sa->type.sa.sa_family != AF_INET6) { - return; - } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring IPv6 mapped IPV4 address: "; - } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) { - addr->flags |= FCTX_ADDRINFO_MARK; - msg = "ignoring IPv6 compatibility IPV4 address: "; - } else - return; - - if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { - isc_netaddr_fromsockaddr(&na, sa); - isc_netaddr_format(&na, buf, sizeof(buf)); - FCTXTRACE2(msg, buf); - } -} - -static inline dns_adbaddrinfo_t * -fctx_nextaddress(fetchctx_t *fctx) { - dns_adbfind_t *find, *start; - dns_adbaddrinfo_t *addrinfo; - dns_adbaddrinfo_t *faddrinfo; - - /* - * Return the next untried address, if any. - */ - - /* - * Find the first unmarked forwarder (if any). - */ - for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (!UNMARKED(addrinfo)) - continue; - possibly_mark(fctx, addrinfo); - if (UNMARKED(addrinfo)) { - addrinfo->flags |= FCTX_ADDRINFO_MARK; - fctx->find = NULL; - return (addrinfo); - } - } - - /* - * No forwarders. Move to the next find. - */ - - FCTX_ATTR_SET(fctx, FCTX_ATTR_TRIEDFIND); - - find = fctx->find; - if (find == NULL) - find = ISC_LIST_HEAD(fctx->finds); - else { - find = ISC_LIST_NEXT(find, publink); - if (find == NULL) - find = ISC_LIST_HEAD(fctx->finds); - } - - /* - * Find the first unmarked addrinfo. - */ - addrinfo = NULL; - if (find != NULL) { - start = find; - do { - for (addrinfo = ISC_LIST_HEAD(find->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (!UNMARKED(addrinfo)) - continue; - possibly_mark(fctx, addrinfo); - if (UNMARKED(addrinfo)) { - addrinfo->flags |= FCTX_ADDRINFO_MARK; - break; - } - } - if (addrinfo != NULL) - break; - find = ISC_LIST_NEXT(find, publink); - if (find == NULL) - find = ISC_LIST_HEAD(fctx->finds); - } while (find != start); - } - - fctx->find = find; - if (addrinfo != NULL) - return (addrinfo); - - /* - * No nameservers left. Try alternates. - */ - - FCTX_ATTR_SET(fctx, FCTX_ATTR_TRIEDALT); - - find = fctx->altfind; - if (find == NULL) - find = ISC_LIST_HEAD(fctx->altfinds); - else { - find = ISC_LIST_NEXT(find, publink); - if (find == NULL) - find = ISC_LIST_HEAD(fctx->altfinds); - } - - /* - * Find the first unmarked addrinfo. - */ - addrinfo = NULL; - if (find != NULL) { - start = find; - do { - for (addrinfo = ISC_LIST_HEAD(find->list); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (!UNMARKED(addrinfo)) - continue; - possibly_mark(fctx, addrinfo); - if (UNMARKED(addrinfo)) { - addrinfo->flags |= FCTX_ADDRINFO_MARK; - break; - } - } - if (addrinfo != NULL) - break; - find = ISC_LIST_NEXT(find, publink); - if (find == NULL) - find = ISC_LIST_HEAD(fctx->altfinds); - } while (find != start); - } - - faddrinfo = addrinfo; - - /* - * See if we have a better alternate server by address. - */ - - for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); - addrinfo != NULL; - addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { - if (!UNMARKED(addrinfo)) - continue; - possibly_mark(fctx, addrinfo); - if (UNMARKED(addrinfo) && - (faddrinfo == NULL || - addrinfo->srtt < faddrinfo->srtt)) { - if (faddrinfo != NULL) - faddrinfo->flags &= ~FCTX_ADDRINFO_MARK; - addrinfo->flags |= FCTX_ADDRINFO_MARK; - break; - } - } - - if (addrinfo == NULL) { - addrinfo = faddrinfo; - fctx->altfind = find; - } - - return (addrinfo); -} - -static void -fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) { - isc_result_t result; - dns_adbaddrinfo_t *addrinfo = NULL; - dns_resolver_t *res; - unsigned int bucketnum; - bool bucket_empty; - - FCTXTRACE5("try", "fctx->qc=", isc_counter_used(fctx->qc)); - - REQUIRE(!ADDRWAIT(fctx)); - - res = fctx->res; - - /* We've already exceeded maximum query count */ - if (isc_counter_used(fctx->qc) > res->maxqueries) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), - "exceeded max queries resolving '%s' " - "(querycount=%u, maxqueries=%u)", - fctx->info, - isc_counter_used(fctx->qc), res->maxqueries); - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - return; - } - - addrinfo = fctx_nextaddress(fctx); - - /* Try to find an address that isn't over quota */ - while (addrinfo != NULL && dns_adbentry_overquota(fctx->adb, addrinfo->entry)) - addrinfo = fctx_nextaddress(fctx); - - if (addrinfo == NULL) { - /* We have no more addresses. Start over. */ - fctx_cancelqueries(fctx, true, false); - fctx_cleanupall(fctx); - result = fctx_getaddresses(fctx, badcache); - if (result == DNS_R_WAIT) { - /* - * Sleep waiting for addresses. - */ - FCTXTRACE("addrwait"); - FCTX_ATTR_SET(fctx, FCTX_ATTR_ADDRWAIT); - return; - } else if (result != ISC_R_SUCCESS) { - /* - * Something bad happened. - */ - fctx_done(fctx, result, __LINE__); - return; - } - - addrinfo = fctx_nextaddress(fctx); - - while (addrinfo != NULL && - dns_adbentry_overquota(fctx->adb, addrinfo->entry)) - addrinfo = fctx_nextaddress(fctx); - - /* - * While we may have addresses from the ADB, they - * might be bad ones. In this case, return SERVFAIL. - */ - if (addrinfo == NULL) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - return; - } - } - - result = isc_counter_increment(fctx->qc); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), - "exceeded max queries resolving '%s'", - fctx->info); - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - return; - } - - bucketnum = fctx->bucketnum; - fctx_increference(fctx); - result = fctx_query(fctx, addrinfo, fctx->options); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, result, __LINE__); - LOCK(&res->buckets[bucketnum].lock); - bucket_empty = fctx_decreference(fctx); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) - empty_bucket(res); - } else if (retrying) - inc_stats(res, dns_resstatscounter_retry); -} - -static bool -fctx_unlink(fetchctx_t *fctx) { - dns_resolver_t *res; - unsigned int bucketnum; - - /* - * Caller must be holding the bucket lock. - */ - - REQUIRE(VALID_FCTX(fctx)); - REQUIRE(fctx->state == fetchstate_done || - fctx->state == fetchstate_init); - REQUIRE(ISC_LIST_EMPTY(fctx->events)); - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - REQUIRE(ISC_LIST_EMPTY(fctx->finds)); - REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); - REQUIRE(fctx->pending == 0); - REQUIRE(fctx->references == 0); - REQUIRE(ISC_LIST_EMPTY(fctx->validators)); - - FCTXTRACE("unlink"); - - res = fctx->res; - bucketnum = fctx->bucketnum; - - ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link); - - LOCK(&res->nlock); - res->nfctx--; - UNLOCK(&res->nlock); - dec_stats(res, dns_resstatscounter_nfetch); - - if (res->buckets[bucketnum].exiting && - ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs)) - return (true); - - return (false); -} - -static void -fctx_destroy(fetchctx_t *fctx) { - isc_sockaddr_t *sa, *next_sa; - struct tried *tried; - - REQUIRE(VALID_FCTX(fctx)); - REQUIRE(fctx->state == fetchstate_done || - fctx->state == fetchstate_init); - REQUIRE(ISC_LIST_EMPTY(fctx->events)); - REQUIRE(ISC_LIST_EMPTY(fctx->queries)); - REQUIRE(ISC_LIST_EMPTY(fctx->finds)); - REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); - REQUIRE(fctx->pending == 0); - REQUIRE(fctx->references == 0); - REQUIRE(ISC_LIST_EMPTY(fctx->validators)); - REQUIRE(!ISC_LINK_LINKED(fctx, link)); - - FCTXTRACE("destroy"); - - /* - * Free bad. - */ - for (sa = ISC_LIST_HEAD(fctx->bad); - sa != NULL; - sa = next_sa) { - next_sa = ISC_LIST_NEXT(sa, link); - ISC_LIST_UNLINK(fctx->bad, sa, link); - isc_mem_put(fctx->mctx, sa, sizeof(*sa)); - } - - for (tried = ISC_LIST_HEAD(fctx->edns); - tried != NULL; - tried = ISC_LIST_HEAD(fctx->edns)) { - ISC_LIST_UNLINK(fctx->edns, tried, link); - isc_mem_put(fctx->mctx, tried, sizeof(*tried)); - } - - for (tried = ISC_LIST_HEAD(fctx->edns512); - tried != NULL; - tried = ISC_LIST_HEAD(fctx->edns512)) { - ISC_LIST_UNLINK(fctx->edns512, tried, link); - isc_mem_put(fctx->mctx, tried, sizeof(*tried)); - } - - for (sa = ISC_LIST_HEAD(fctx->bad_edns); - sa != NULL; - sa = next_sa) { - next_sa = ISC_LIST_NEXT(sa, link); - ISC_LIST_UNLINK(fctx->bad_edns, sa, link); - isc_mem_put(fctx->mctx, sa, sizeof(*sa)); - } - - isc_counter_detach(&fctx->qc); - fcount_decr(fctx); - isc_timer_detach(&fctx->timer); - dns_message_detach(&fctx->qmessage); - if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, fctx->mctx); - if (dns_rdataset_isassociated(&fctx->nameservers)) - dns_rdataset_disassociate(&fctx->nameservers); - dns_name_free(&fctx->name, fctx->mctx); - dns_db_detach(&fctx->cache); - dns_adb_detach(&fctx->adb); - isc_mem_free(fctx->mctx, fctx->info); - isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx)); -} - -/* - * Fetch event handlers. - */ - -static void -fctx_timeout(isc_task_t *task, isc_event_t *event) { - fetchctx_t *fctx = event->ev_arg; - isc_timerevent_t *tevent = (isc_timerevent_t *)event; - resquery_t *query; - - REQUIRE(VALID_FCTX(fctx)); - - UNUSED(task); - - FCTXTRACE("timeout"); - - inc_stats(fctx->res, dns_resstatscounter_querytimeout); - - if (event->ev_type == ISC_TIMEREVENT_LIFE) { - fctx->reason = NULL; - fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__); - } else { - isc_result_t result; - - fctx->timeouts++; - fctx->timeout = true; - - /* - * We could cancel the running queries here, or we could let - * them keep going. Since we normally use separate sockets for - * different queries, we adopt the former approach to reduce - * the number of open sockets: cancel the oldest query if it - * expired after the query had started (this is usually the - * case but is not always so, depending on the task schedule - * timing). - */ - query = ISC_LIST_HEAD(fctx->queries); - if (query != NULL && - isc_time_compare(&tevent->due, &query->start) >= 0) - { - FCTXTRACE("query timed out; no response"); - fctx_cancelquery(&query, NULL, NULL, true, false); - } - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - - /* - * Our timer has triggered. Reestablish the fctx lifetime - * timer. - */ - result = fctx_starttimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - else - /* - * Keep trying. - */ - fctx_try(fctx, true, false); - } - - isc_event_free(&event); -} - -static void -fctx_shutdown(fetchctx_t *fctx) { - isc_event_t *cevent; - - /* - * Start the shutdown process for fctx, if it isn't already underway. - */ - - FCTXTRACE("shutdown"); - - /* - * The caller must be holding the appropriate bucket lock. - */ - - if (fctx->want_shutdown) - return; - - fctx->want_shutdown = true; - - /* - * Unless we're still initializing (in which case the - * control event is still outstanding), we need to post - * the control event to tell the fetch we want it to - * exit. - */ - if (fctx->state != fetchstate_init) { - cevent = &fctx->control_event; - isc_task_send(fctx->res->buckets[fctx->bucketnum].task, - &cevent); - } -} - -static void -fctx_doshutdown(isc_task_t *task, isc_event_t *event) { - fetchctx_t *fctx = event->ev_arg; - bool bucket_empty = false; - dns_resolver_t *res; - unsigned int bucketnum; - dns_validator_t *validator; - bool dodestroy = false; - - REQUIRE(VALID_FCTX(fctx)); - - UNUSED(task); - - res = fctx->res; - bucketnum = fctx->bucketnum; - - FCTXTRACE("doshutdown"); - - /* - * An fctx that is shutting down is no longer in ADDRWAIT mode. - */ - FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT); - - /* - * Cancel all pending validators. Note that this must be done - * without the bucket lock held, since that could cause deadlock. - */ - validator = ISC_LIST_HEAD(fctx->validators); - while (validator != NULL) { - dns_validator_cancel(validator); - validator = ISC_LIST_NEXT(validator, link); - } - - if (fctx->nsfetch != NULL) - dns_resolver_cancelfetch(fctx->nsfetch); - - /* - * Shut down anything still running on behalf of this - * fetch, and clean up finds and addresses. To avoid deadlock - * with the ADB, we must do this before we lock the bucket lock. - */ - fctx_stopqueries(fctx, false, false); - fctx_cleanupall(fctx); - - LOCK(&res->buckets[bucketnum].lock); - - fctx->shuttingdown = true; - - INSIST(fctx->state == fetchstate_active || - fctx->state == fetchstate_done); - INSIST(fctx->want_shutdown); - - if (fctx->state != fetchstate_done) { - fctx->state = fetchstate_done; - fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); - } - - if (fctx->references == 0 && fctx->pending == 0 && - fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { - bucket_empty = fctx_unlink(fctx); - dodestroy = true; - } - - UNLOCK(&res->buckets[bucketnum].lock); - - if (dodestroy) { - fctx_destroy(fctx); - if (bucket_empty) - empty_bucket(res); - } -} - -static void -fctx_start(isc_task_t *task, isc_event_t *event) { - fetchctx_t *fctx = event->ev_arg; - bool done = false, bucket_empty = false; - dns_resolver_t *res; - unsigned int bucketnum; - bool dodestroy = false; - - REQUIRE(VALID_FCTX(fctx)); - - UNUSED(task); - - res = fctx->res; - bucketnum = fctx->bucketnum; - - FCTXTRACE("start"); - - LOCK(&res->buckets[bucketnum].lock); - - INSIST(fctx->state == fetchstate_init); - if (fctx->want_shutdown) { - /* - * We haven't started this fctx yet, and we've been requested - * to shut it down. - */ - fctx->shuttingdown = true; - fctx->state = fetchstate_done; - fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); - /* - * Since we haven't started, we INSIST that we have no - * pending ADB finds and no pending validations. - */ - INSIST(fctx->pending == 0); - INSIST(fctx->nqueries == 0); - INSIST(ISC_LIST_EMPTY(fctx->validators)); - if (fctx->references == 0) { - /* - * It's now safe to destroy this fctx. - */ - bucket_empty = fctx_unlink(fctx); - dodestroy = true; - } - done = true; - } else { - /* - * Normal fctx startup. - */ - fctx->state = fetchstate_active; - /* - * Reset the control event for later use in shutting down - * the fctx. - */ - ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, - DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx, - NULL, NULL, NULL); - } - - UNLOCK(&res->buckets[bucketnum].lock); - - if (!done) { - isc_result_t result; - - INSIST(!dodestroy); - - /* - * All is well. Start working on the fetch. - */ - result = fctx_starttimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - else - fctx_try(fctx, false, false); - } else if (dodestroy) { - fctx_destroy(fctx); - if (bucket_empty) - empty_bucket(res); - } -} - -/* - * Fetch Creation, Joining, and Cancellation. - */ - -static inline isc_result_t -fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client, - dns_messageid_t id, isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, - dns_fetch_t *fetch) -{ - isc_task_t *tclone; - dns_fetchevent_t *event; - - FCTXTRACE("join"); - - /* - * We store the task we're going to send this event to in the - * sender field. We'll make the fetch the sender when we actually - * send the event. - */ - tclone = NULL; - isc_task_attach(task, &tclone); - event = (dns_fetchevent_t *) - isc_event_allocate(fctx->res->mctx, tclone, DNS_EVENT_FETCHDONE, - action, arg, sizeof(*event)); - if (event == NULL) { - isc_task_detach(&tclone); - return (ISC_R_NOMEMORY); - } - event->result = DNS_R_SERVFAIL; - event->qtype = fctx->type; - event->db = NULL; - event->node = NULL; - event->rdataset = rdataset; - event->sigrdataset = sigrdataset; - event->fetch = fetch; - event->client = client; - event->id = id; - dns_fixedname_init(&event->foundname); - - /* - * Make sure that we can store the sigrdataset in the - * first event if it is needed by any of the events. - */ - if (event->sigrdataset != NULL) - ISC_LIST_PREPEND(fctx->events, event, ev_link); - else - ISC_LIST_APPEND(fctx->events, event, ev_link); - fctx->references++; - - fetch->magic = DNS_FETCH_MAGIC; - fetch->private = fctx; - - return (ISC_R_SUCCESS); -} - -static inline void -log_ns_ttl(fetchctx_t *fctx, const char *where) { - char namebuf[DNS_NAME_FORMATSIZE]; - char domainbuf[DNS_NAME_FORMATSIZE]; - - dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); - dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), - "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u", - fctx, where, namebuf, domainbuf, - fctx->ns_ttl_ok, fctx->ns_ttl); -} - -static isc_result_t -fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - const isc_sockaddr_t *client, unsigned int options, - unsigned int bucketnum, unsigned int depth, isc_counter_t *qc, - fetchctx_t **fctxp) -{ - fetchctx_t *fctx; - isc_result_t result; - isc_result_t iresult; - isc_interval_t interval; - dns_fixedname_t fixed; - unsigned int findoptions = 0; - char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - isc_mem_t *mctx; - - /* - * Caller must be holding the lock for bucket number 'bucketnum'. - */ - REQUIRE(fctxp != NULL && *fctxp == NULL); - - mctx = res->buckets[bucketnum].mctx; - fctx = isc_mem_get(mctx, sizeof(*fctx)); - if (fctx == NULL) - return (ISC_R_NOMEMORY); - - fctx->qc = NULL; - if (qc != NULL) { - isc_counter_attach(qc, &fctx->qc); - } else { - result = isc_counter_create(res->mctx, - res->maxqueries, &fctx->qc); - if (result != ISC_R_SUCCESS) - goto cleanup_fetch; - } - - /* - * Make fctx->info point to a copy of a formatted string - * "name/type". - */ - dns_name_format(name, buf, sizeof(buf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - strlcat(buf, "/", sizeof(buf)); - strlcat(buf, typebuf, sizeof(buf)); - fctx->info = isc_mem_strdup(mctx, buf); - if (fctx->info == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_counter; - } - - FCTXTRACE("create"); - dns_name_init(&fctx->name, NULL); - result = dns_name_dup(name, mctx, &fctx->name); - if (result != ISC_R_SUCCESS) - goto cleanup_info; - dns_name_init(&fctx->domain, NULL); - dns_rdataset_init(&fctx->nameservers); - - fctx->type = type; - fctx->options = options; - /* - * Note! We do not attach to the task. We are relying on the - * resolver to ensure that this task doesn't go away while we are - * using it. - */ - fctx->res = res; - fctx->references = 0; - fctx->bucketnum = bucketnum; - fctx->dbucketnum = RES_NOBUCKET; - fctx->state = fetchstate_init; - fctx->want_shutdown = false; - fctx->cloned = false; - fctx->depth = depth; - ISC_LIST_INIT(fctx->queries); - ISC_LIST_INIT(fctx->finds); - ISC_LIST_INIT(fctx->altfinds); - ISC_LIST_INIT(fctx->forwaddrs); - ISC_LIST_INIT(fctx->altaddrs); - ISC_LIST_INIT(fctx->forwarders); - fctx->fwdpolicy = dns_fwdpolicy_none; - ISC_LIST_INIT(fctx->bad); - ISC_LIST_INIT(fctx->edns); - ISC_LIST_INIT(fctx->edns512); - ISC_LIST_INIT(fctx->bad_edns); - ISC_LIST_INIT(fctx->validators); - fctx->validator = NULL; - fctx->find = NULL; - fctx->altfind = NULL; - fctx->pending = 0; - fctx->restarts = 0; - fctx->querysent = 0; - fctx->referrals = 0; - TIME_NOW(&fctx->start); - fctx->timeouts = 0; - fctx->lamecount = 0; - fctx->quotacount = 0; - fctx->adberr = 0; - fctx->neterr = 0; - fctx->badresp = 0; - fctx->findfail = 0; - fctx->valfail = 0; - fctx->result = ISC_R_FAILURE; - fctx->vresult = ISC_R_SUCCESS; - fctx->exitline = -1; /* sentinel */ - fctx->logged = false; - fctx->attributes = 0; - fctx->spilled = false; - fctx->shuttingdown = false; - fctx->nqueries = 0; - fctx->reason = NULL; - fctx->rand_buf = 0; - fctx->rand_bits = 0; - fctx->timeout = false; - fctx->addrinfo = NULL; - if (client != NULL) { - isc_sockaddr_format(client, fctx->clientstr, - sizeof(fctx->clientstr)); - } else { - strlcpy(fctx->clientstr, "", sizeof(fctx->clientstr)); - } - fctx->ns_ttl = 0; - fctx->ns_ttl_ok = false; - - dns_name_init(&fctx->nsname, NULL); - fctx->nsfetch = NULL; - dns_rdataset_init(&fctx->nsrrset); - - if (domain == NULL) { - dns_forwarders_t *forwarders = NULL; - unsigned int labels; - dns_name_t *fwdname = name; - dns_name_t suffix; - - /* - * DS records are found in the parent server. Strip one - * leading label from the name (to be used in finding - * the forwarder). - */ - if (dns_rdatatype_atparent(fctx->type) && - dns_name_countlabels(name) > 1) { - dns_name_init(&suffix, NULL); - labels = dns_name_countlabels(name); - dns_name_getlabelsequence(name, 1, labels - 1, &suffix); - fwdname = &suffix; - } - - /* Find the forwarder for this name. */ - domain = dns_fixedname_initname(&fixed); - result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname, - domain, &forwarders); - if (result == ISC_R_SUCCESS) - fctx->fwdpolicy = forwarders->fwdpolicy; - - if (fctx->fwdpolicy != dns_fwdpolicy_only) { - /* - * The caller didn't supply a query domain and - * nameservers, and we're not in forward-only mode, - * so find the best nameservers to use. - */ - if (dns_rdatatype_atparent(fctx->type)) - findoptions |= DNS_DBFIND_NOEXACT; - result = dns_view_findzonecut(res->view, name, - domain, 0, findoptions, - true, - &fctx->nameservers, - NULL); - if (result != ISC_R_SUCCESS) - goto cleanup_nameservers; - - result = dns_name_dup(domain, mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) - goto cleanup_nameservers; - - fctx->ns_ttl = fctx->nameservers.ttl; - fctx->ns_ttl_ok = true; - } else { - /* - * We're in forward-only mode. Set the query domain. - */ - result = dns_name_dup(domain, mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) - goto cleanup_name; - } - } else { - result = dns_name_dup(domain, mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) - goto cleanup_name; - dns_rdataset_clone(nameservers, &fctx->nameservers); - fctx->ns_ttl = fctx->nameservers.ttl; - fctx->ns_ttl_ok = true; - } - - /* - * Are there too many simultaneous queries for this domain? - */ - result = fcount_incr(fctx, false); - if (result != ISC_R_SUCCESS) { - result = fctx->res->quotaresp[dns_quotatype_zone]; - inc_stats(res, dns_resstatscounter_zonequota); - goto cleanup_domain; - } - - log_ns_ttl(fctx, "fctx_create"); - - INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain)); - - fctx->qmessage = NULL; - result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, - &fctx->qmessage); - - if (result != ISC_R_SUCCESS) - goto cleanup_fcount; - - /* - * Compute an expiration time for the entire fetch. - */ - isc_interval_set(&interval, res->query_timeout / 1000, - res->query_timeout % 1000 * 1000000); - iresult = isc_time_nowplusinterval(&fctx->expires, &interval); - if (iresult != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_time_nowplusinterval: %s", - isc_result_totext(iresult)); - result = ISC_R_UNEXPECTED; - goto cleanup_qmessage; - } - - /* - * Default retry interval initialization. We set the interval now - * mostly so it won't be uninitialized. It will be set to the - * correct value before a query is issued. - */ - isc_interval_set(&fctx->interval, 2, 0); - - /* - * Create an inactive timer. It will be made active when the fetch - * is actually started. - */ - fctx->timer = NULL; - iresult = isc_timer_create(res->timermgr, isc_timertype_inactive, - NULL, NULL, - res->buckets[bucketnum].task, fctx_timeout, - fctx, &fctx->timer); - if (iresult != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timer_create: %s", - isc_result_totext(iresult)); - result = ISC_R_UNEXPECTED; - goto cleanup_qmessage; - } - - /* - * Attach to the view's cache and adb. - */ - fctx->cache = NULL; - dns_db_attach(res->view->cachedb, &fctx->cache); - fctx->adb = NULL; - dns_adb_attach(res->view->adb, &fctx->adb); - fctx->mctx = NULL; - isc_mem_attach(mctx, &fctx->mctx); - - ISC_LIST_INIT(fctx->events); - ISC_LINK_INIT(fctx, link); - fctx->magic = FCTX_MAGIC; - - ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link); - - LOCK(&res->nlock); - res->nfctx++; - UNLOCK(&res->nlock); - inc_stats(res, dns_resstatscounter_nfetch); - - *fctxp = fctx; - - return (ISC_R_SUCCESS); - - cleanup_qmessage: - dns_message_detach(&fctx->qmessage); - - cleanup_fcount: - fcount_decr(fctx); - - cleanup_domain: - if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, mctx); - - cleanup_nameservers: - if (dns_rdataset_isassociated(&fctx->nameservers)) - dns_rdataset_disassociate(&fctx->nameservers); - - cleanup_name: - dns_name_free(&fctx->name, mctx); - - cleanup_info: - isc_mem_free(mctx, fctx->info); - - cleanup_counter: - isc_counter_detach(&fctx->qc); - - cleanup_fetch: - isc_mem_put(mctx, fctx, sizeof(*fctx)); - - return (result); -} - -/* - * Handle Responses - */ -static inline bool -is_lame(fetchctx_t *fctx, dns_message_t *message) { - dns_name_t *name; - dns_rdataset_t *rdataset; - isc_result_t result; - - if (message->rcode != dns_rcode_noerror && - message->rcode != dns_rcode_yxdomain && - message->rcode != dns_rcode_nxdomain) - return (false); - - if (message->counts[DNS_SECTION_ANSWER] != 0) - return (false); - - if (message->counts[DNS_SECTION_AUTHORITY] == 0) - return (false); - - result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - dns_namereln_t namereln; - int order; - unsigned int labels; - if (rdataset->type != dns_rdatatype_ns) - continue; - namereln = dns_name_fullcompare(name, &fctx->domain, - &order, &labels); - if (namereln == dns_namereln_equal && - (message->flags & DNS_MESSAGEFLAG_AA) != 0) - return (false); - if (namereln == dns_namereln_subdomain) - return (false); - return (true); - } - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); - } - - return (false); -} - -static inline void -log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) { - char namebuf[DNS_NAME_FORMATSIZE]; - char domainbuf[DNS_NAME_FORMATSIZE]; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - - dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); - dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); - isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), - "lame server resolving '%s' (in '%s'?): %s", - namebuf, domainbuf, addrbuf); -} - -static inline void -log_formerr(fetchctx_t *fctx, const char *format, ...) { - char nsbuf[ISC_SOCKADDR_FORMATSIZE]; - char msgbuf[2048]; - va_list args; - - va_start(args, format); - vsnprintf(msgbuf, sizeof(msgbuf), format, args); - va_end(args); - - isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), - "DNS format error from %s resolving %s for %s: %s", - nsbuf, fctx->info, fctx->clientstr, msgbuf); -} - -static isc_result_t -same_question(fetchctx_t *fctx, dns_message_t *message) { - isc_result_t result; - dns_name_t *name; - dns_rdataset_t *rdataset; - - /* - * Caller must be holding the fctx lock. - */ - - /* - * XXXRTH Currently we support only one question. - */ - if (ISC_UNLIKELY(message->counts[DNS_SECTION_QUESTION] == 0)) { - if ((message->flags & DNS_MESSAGEFLAG_TC) != 0) { - /* - * If TC=1 and the question section is empty, we - * accept the reply message as a truncated - * answer, to be retried over TCP. - * - * It is really a FORMERR condition, but this is - * a workaround to accept replies from some - * implementations. - * - * Because the question section matching is not - * performed, the worst that could happen is - * that an attacker who gets past the ID and - * source port checks can force the use of - * TCP. This is considered an acceptable risk. - */ - log_formerr(fctx, - "empty question section, " - "accepting it anyway as TC=1"); - return (ISC_R_SUCCESS); - } else { - log_formerr(fctx, "empty question section"); - return (DNS_R_FORMERR); - } - } else if (ISC_UNLIKELY(message->counts[DNS_SECTION_QUESTION] > 1)) { - log_formerr(fctx, "too many questions"); - return (DNS_R_FORMERR); - } - - result = dns_message_firstname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) - return (result); - name = NULL; - dns_message_currentname(message, DNS_SECTION_QUESTION, &name); - rdataset = ISC_LIST_HEAD(name->list); - INSIST(rdataset != NULL); - INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); - - if (fctx->type != rdataset->type || - fctx->res->rdclass != rdataset->rdclass || - !dns_name_equal(&fctx->name, name)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - log_formerr(fctx, "question section mismatch: got %s/%s/%s", - namebuf, classbuf, typebuf); - return (DNS_R_FORMERR); - } - - return (ISC_R_SUCCESS); -} - -static void -clone_results(fetchctx_t *fctx) { - dns_fetchevent_t *event, *hevent; - isc_result_t result; - dns_name_t *name, *hname; - - FCTXTRACE("clone_results"); - - /* - * Set up any other events to have the same data as the first - * event. - * - * Caller must be holding the appropriate lock. - */ - - fctx->cloned = true; - hevent = ISC_LIST_HEAD(fctx->events); - if (hevent == NULL) - return; - hname = dns_fixedname_name(&hevent->foundname); - for (event = ISC_LIST_NEXT(hevent, ev_link); - event != NULL; - event = ISC_LIST_NEXT(event, ev_link)) { - name = dns_fixedname_name(&event->foundname); - result = dns_name_copy(hname, name, NULL); - if (result != ISC_R_SUCCESS) - event->result = result; - else - event->result = hevent->result; - dns_db_attach(hevent->db, &event->db); - dns_db_attachnode(hevent->db, hevent->node, &event->node); - INSIST(hevent->rdataset != NULL); - INSIST(event->rdataset != NULL); - if (dns_rdataset_isassociated(hevent->rdataset)) - dns_rdataset_clone(hevent->rdataset, event->rdataset); - INSIST(! (hevent->sigrdataset == NULL && - event->sigrdataset != NULL)); - if (hevent->sigrdataset != NULL && - dns_rdataset_isassociated(hevent->sigrdataset) && - event->sigrdataset != NULL) - dns_rdataset_clone(hevent->sigrdataset, - event->sigrdataset); - } -} - -#define CACHE(r) (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0) -#define ANSWER(r) (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0) -#define ANSWERSIG(r) (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0) -#define EXTERNAL(r) (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0) -#define CHAINING(r) (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0) -#define CHASE(r) (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0) -#define CHECKNAMES(r) (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0) - -/* - * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has - * no references and is no longer waiting for any events). - * - * Requires: - * '*fctx' is shutting down. - * - * Returns: - * true if the resolver is exiting and this is the last fctx in the bucket. - */ -static bool -maybe_destroy(fetchctx_t *fctx, bool locked) { - unsigned int bucketnum; - bool bucket_empty = false; - dns_resolver_t *res = fctx->res; - dns_validator_t *validator, *next_validator; - bool dodestroy = false; - - bucketnum = fctx->bucketnum; - if (!locked) - LOCK(&res->buckets[bucketnum].lock); - - REQUIRE(fctx->shuttingdown); - - if (fctx->pending != 0 || fctx->nqueries != 0) - goto unlock; - - for (validator = ISC_LIST_HEAD(fctx->validators); - validator != NULL; validator = next_validator) { - next_validator = ISC_LIST_NEXT(validator, link); - dns_validator_cancel(validator); - } - - if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) { - bucket_empty = fctx_unlink(fctx); - dodestroy = true; - } - unlock: - if (!locked) - UNLOCK(&res->buckets[bucketnum].lock); - if (dodestroy) - fctx_destroy(fctx); - return (bucket_empty); -} - -/* - * The validator has finished. - */ -static void -validated(isc_task_t *task, isc_event_t *event) { - dns_adbaddrinfo_t *addrinfo; - dns_dbnode_t *node = NULL; - dns_dbnode_t *nsnode = NULL; - dns_fetchevent_t *hevent; - dns_name_t *name; - dns_rdataset_t *ardataset = NULL; - dns_rdataset_t *asigrdataset = NULL; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - dns_resolver_t *res; - dns_valarg_t *valarg; - dns_validatorevent_t *vevent; - fetchctx_t *fctx; - bool chaining; - bool negative; - bool sentresponse; - isc_result_t eresult = ISC_R_SUCCESS; - isc_result_t result = ISC_R_SUCCESS; - isc_stdtime_t now; - uint32_t ttl; - unsigned options; - uint32_t bucketnum; - dns_message_t *rmessage = NULL; - - UNUSED(task); /* for now */ - - REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE); - valarg = event->ev_arg; - fctx = valarg->fctx; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - addrinfo = valarg->addrinfo; - REQUIRE(!ISC_LIST_EMPTY(fctx->validators)); - dns_message_attach(valarg->rmessage, &rmessage); - - vevent = (dns_validatorevent_t *)event; - fctx->vresult = vevent->result; - - FCTXTRACE("received validation completion event"); - - bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); - - ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); - fctx->validator = NULL; - UNLOCK(&res->buckets[bucketnum].lock); - - /* - * Destroy the validator early so that we can - * destroy the fctx if necessary. - */ - dns_validator_destroy(&vevent->validator); - dns_message_detach(&valarg->rmessage); - isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); - - negative = (vevent->rdataset == NULL); - - LOCK(&res->buckets[bucketnum].lock); - sentresponse = ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0); - - /* - * If shutting down, ignore the results. Check to see if we're - * done waiting for validator completions and ADB pending events; if - * so, destroy the fctx. - */ - if (fctx->shuttingdown && !sentresponse) { - bool bucket_empty; - bucket_empty = maybe_destroy(fctx, true); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) - empty_bucket(res); - goto cleanup_event; - } - - isc_stdtime_get(&now); - - /* - * If chaining, we need to make sure that the right result code is - * returned, and that the rdatasets are bound. - */ - if (vevent->result == ISC_R_SUCCESS && - !negative && - vevent->rdataset != NULL && - CHAINING(vevent->rdataset)) - { - if (vevent->rdataset->type == dns_rdatatype_cname) - eresult = DNS_R_CNAME; - else { - INSIST(vevent->rdataset->type == dns_rdatatype_dname); - eresult = DNS_R_DNAME; - } - chaining = true; - } else - chaining = false; - - /* - * Either we're not shutting down, or we are shutting down but want - * to cache the result anyway (if this was a validation started by - * a query with cd set) - */ - - hevent = ISC_LIST_HEAD(fctx->events); - if (hevent != NULL) { - if (!negative && !chaining && - (fctx->type == dns_rdatatype_any || - fctx->type == dns_rdatatype_rrsig || - fctx->type == dns_rdatatype_sig)) { - /* - * Don't bind rdatasets; the caller - * will iterate the node. - */ - } else { - ardataset = hevent->rdataset; - asigrdataset = hevent->sigrdataset; - } - } - - if (vevent->result != ISC_R_SUCCESS) { - FCTXTRACE("validation failed"); - inc_stats(res, dns_resstatscounter_valfail); - fctx->valfail++; - fctx->vresult = vevent->result; - if (fctx->vresult != DNS_R_BROKENCHAIN) { - result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) - result = dns_db_findnode(fctx->cache, - vevent->name, - true, &node); - if (result == ISC_R_SUCCESS) - (void)dns_db_deleterdataset(fctx->cache, node, - NULL, - vevent->type, 0); - if (result == ISC_R_SUCCESS && - vevent->sigrdataset != NULL) - (void)dns_db_deleterdataset(fctx->cache, node, - NULL, - dns_rdatatype_rrsig, - vevent->type); - if (result == ISC_R_SUCCESS) - dns_db_detachnode(fctx->cache, &node); - } - if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) { - /* - * Cache the data as pending for later validation. - */ - result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) - result = dns_db_findnode(fctx->cache, - vevent->name, - true, &node); - if (result == ISC_R_SUCCESS) { - (void)dns_db_addrdataset(fctx->cache, node, - NULL, now, - vevent->rdataset, 0, - NULL); - } - if (result == ISC_R_SUCCESS && - vevent->sigrdataset != NULL) - (void)dns_db_addrdataset(fctx->cache, node, - NULL, now, - vevent->sigrdataset, - 0, NULL); - if (result == ISC_R_SUCCESS) - dns_db_detachnode(fctx->cache, &node); - } - result = fctx->vresult; - add_bad(fctx, rmessage, addrinfo, result, - badns_validation); - isc_event_free(&event); - UNLOCK(&res->buckets[bucketnum].lock); - INSIST(fctx->validator == NULL); - fctx->validator = ISC_LIST_HEAD(fctx->validators); - if (fctx->validator != NULL) - dns_validator_send(fctx->validator); - else if (sentresponse) - fctx_done(fctx, result, __LINE__); /* Locks bucket. */ - else if (result == DNS_R_BROKENCHAIN) { - isc_result_t tresult; - isc_time_t expire; - isc_interval_t i; - - isc_interval_set(&i, DNS_RESOLVER_BADCACHETTL(fctx), 0); - tresult = isc_time_nowplusinterval(&expire, &i); - if (negative && - (fctx->type == dns_rdatatype_dnskey || - fctx->type == dns_rdatatype_dlv || - fctx->type == dns_rdatatype_ds) && - tresult == ISC_R_SUCCESS) - dns_resolver_addbadcache(res, &fctx->name, - fctx->type, &expire); - fctx_done(fctx, result, __LINE__); /* Locks bucket. */ - } else { - fctx_try(fctx, true, true); /* Locks bucket. */ - } - goto cleanup_rmessage; - } - - - if (negative) { - dns_rdatatype_t covers; - FCTXTRACE("nonexistence validation OK"); - - inc_stats(res, dns_resstatscounter_valnegsuccess); - - /* - * Cache DS NXDOMAIN separately to other types. - */ - if (rmessage->rcode == dns_rcode_nxdomain && - fctx->type != dns_rdatatype_ds) - covers = dns_rdatatype_any; - else - covers = fctx->type; - - result = dns_db_findnode(fctx->cache, vevent->name, true, - &node); - if (result != ISC_R_SUCCESS) - goto noanswer_response; - - /* - * If we are asking for a SOA record set the cache time - * to zero to facilitate locating the containing zone of - * a arbitrary zone. - */ - ttl = res->view->maxncachettl; - if (fctx->type == dns_rdatatype_soa && - covers == dns_rdatatype_any && res->zero_no_soa_ttl) - ttl = 0; - - result = ncache_adderesult(rmessage, fctx->cache, node, - covers, now, ttl, vevent->optout, - vevent->secure, ardataset, &eresult); - if (result != ISC_R_SUCCESS) - goto noanswer_response; - goto answer_response; - } else - inc_stats(res, dns_resstatscounter_valsuccess); - - FCTXTRACE("validation OK"); - - if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { - result = dns_rdataset_addnoqname(vevent->rdataset, - vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - INSIST(vevent->sigrdataset != NULL); - vevent->sigrdataset->ttl = vevent->rdataset->ttl; - if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) { - result = dns_rdataset_addclosest(vevent->rdataset, - vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - } else if (vevent->rdataset->trust == dns_trust_answer && - vevent->rdataset->type != dns_rdatatype_rrsig) - { - isc_result_t tresult; - dns_name_t *noqname = NULL; - tresult = findnoqname(fctx, rmessage, vevent->name, - vevent->rdataset->type, &noqname); - if (tresult == ISC_R_SUCCESS && noqname != NULL) { - tresult = dns_rdataset_addnoqname(vevent->rdataset, - noqname); - RUNTIME_CHECK(tresult == ISC_R_SUCCESS); - } - } - - /* - * The data was already cached as pending data. - * Re-cache it as secure and bind the cached - * rdatasets to the first event on the fetch - * event list. - */ - result = dns_db_findnode(fctx->cache, vevent->name, true, &node); - if (result != ISC_R_SUCCESS) - goto noanswer_response; - - options = 0; - if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) - options = DNS_DBADD_PREFETCH; - result = dns_db_addrdataset(fctx->cache, node, NULL, now, - vevent->rdataset, options, ardataset); - if (result != ISC_R_SUCCESS && - result != DNS_R_UNCHANGED) - goto noanswer_response; - if (ardataset != NULL && NEGATIVE(ardataset)) { - if (NXDOMAIN(ardataset)) - eresult = DNS_R_NCACHENXDOMAIN; - else - eresult = DNS_R_NCACHENXRRSET; - } else if (vevent->sigrdataset != NULL) { - result = dns_db_addrdataset(fctx->cache, node, NULL, now, - vevent->sigrdataset, options, - asigrdataset); - if (result != ISC_R_SUCCESS && - result != DNS_R_UNCHANGED) - goto noanswer_response; - } - - if (sentresponse) { - bool bucket_empty = false; - /* - * If we only deferred the destroy because we wanted to cache - * the data, destroy now. - */ - dns_db_detachnode(fctx->cache, &node); - if (fctx->shuttingdown) { - bucket_empty = maybe_destroy(fctx, true); - } - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) { - empty_bucket(res); - } - goto cleanup_event; - } - - if (!ISC_LIST_EMPTY(fctx->validators)) { - INSIST(!negative); - INSIST(fctx->type == dns_rdatatype_any || - fctx->type == dns_rdatatype_rrsig || - fctx->type == dns_rdatatype_sig); - /* - * Don't send a response yet - we have - * more rdatasets that still need to - * be validated. - */ - dns_db_detachnode(fctx->cache, &node); - UNLOCK(&res->buckets[bucketnum].lock); - dns_validator_send(ISC_LIST_HEAD(fctx->validators)); - goto cleanup_event; - } - - answer_response: - /* - * Cache any NS/NSEC records that happened to be validated. - */ - result = dns_message_firstname(rmessage, DNS_SECTION_AUTHORITY); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(rmessage, DNS_SECTION_AUTHORITY, - &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if ((rdataset->type != dns_rdatatype_ns && - rdataset->type != dns_rdatatype_nsec) || - rdataset->trust != dns_trust_secure) - continue; - for (sigrdataset = ISC_LIST_HEAD(name->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { - if (sigrdataset->type != dns_rdatatype_rrsig || - sigrdataset->covers != rdataset->type) - continue; - break; - } - if (sigrdataset == NULL || - sigrdataset->trust != dns_trust_secure) - continue; - result = dns_db_findnode(fctx->cache, name, true, - &nsnode); - if (result != ISC_R_SUCCESS) - continue; - - result = dns_db_addrdataset(fctx->cache, nsnode, NULL, - now, rdataset, 0, NULL); - if (result == ISC_R_SUCCESS) - result = dns_db_addrdataset(fctx->cache, nsnode, - NULL, now, - sigrdataset, 0, - NULL); - dns_db_detachnode(fctx->cache, &nsnode); - if (result != ISC_R_SUCCESS) - continue; - } - result = dns_message_nextname(rmessage, - DNS_SECTION_AUTHORITY); - } - - result = ISC_R_SUCCESS; - - /* - * Respond with an answer, positive or negative, - * as opposed to an error. 'node' must be non-NULL. - */ - - FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); - - if (hevent != NULL) { - /* - * Negative results must be indicated in event->result. - */ - INSIST(hevent->rdataset != NULL); - if (dns_rdataset_isassociated(hevent->rdataset) && - NEGATIVE(hevent->rdataset)) { - INSIST(eresult == DNS_R_NCACHENXDOMAIN || - eresult == DNS_R_NCACHENXRRSET); - } - hevent->result = eresult; - RUNTIME_CHECK(dns_name_copy(vevent->name, - dns_fixedname_name(&hevent->foundname), NULL) - == ISC_R_SUCCESS); - dns_db_attach(fctx->cache, &hevent->db); - dns_db_transfernode(fctx->cache, &node, &hevent->node); - clone_results(fctx); - } - - noanswer_response: - if (node != NULL) - dns_db_detachnode(fctx->cache, &node); - - UNLOCK(&res->buckets[bucketnum].lock); - fctx_done(fctx, result, __LINE__); /* Locks bucket. */ - - cleanup_event: - INSIST(node == NULL); - isc_event_free(&event); - cleanup_rmessage: - dns_message_detach(&rmessage); -} - -static void -fctx_log(void *arg, int level, const char *fmt, ...) { - char msgbuf[2048]; - va_list args; - fetchctx_t *fctx = arg; - - va_start(args, fmt); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); - va_end(args); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, level, - "fctx %p(%s): %s", fctx, fctx->info, msgbuf); -} - -static inline isc_result_t -findnoqname(fetchctx_t *fctx, dns_message_t *rmessage, - dns_name_t *name, dns_rdatatype_t type, - dns_name_t **noqnamep) -{ - dns_rdataset_t *nrdataset, *next, *sigrdataset; - dns_rdata_rrsig_t rrsig; - isc_result_t result; - unsigned int labels; - dns_section_t section; - dns_name_t *zonename; - dns_fixedname_t fzonename; - dns_name_t *closest; - dns_fixedname_t fclosest; - dns_name_t *nearest; - dns_fixedname_t fnearest; - dns_rdatatype_t found = dns_rdatatype_none; - dns_name_t *noqname = NULL; - - FCTXTRACE("findnoqname"); - - REQUIRE(noqnamep != NULL && *noqnamep == NULL); - - /* - * Find the SIG for this rdataset, if we have it. - */ - for (sigrdataset = ISC_LIST_HEAD(name->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { - if (sigrdataset->type == dns_rdatatype_rrsig && - sigrdataset->covers == type) - break; - } - - if (sigrdataset == NULL) - return (ISC_R_NOTFOUND); - - labels = dns_name_countlabels(name); - - for (result = dns_rdataset_first(sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(sigrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(sigrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rrsig, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* Wildcard has rrsig.labels < labels - 1. */ - if (rrsig.labels + 1U >= labels) - continue; - break; - } - - if (result == ISC_R_NOMORE) - return (ISC_R_NOTFOUND); - if (result != ISC_R_SUCCESS) - return (result); - - zonename = dns_fixedname_initname(&fzonename); - closest = dns_fixedname_initname(&fclosest); - nearest = dns_fixedname_initname(&fnearest); - -#define NXND(x) ((x) == ISC_R_SUCCESS) - - section = DNS_SECTION_AUTHORITY; - for (result = dns_message_firstname(rmessage, section); - result == ISC_R_SUCCESS; - result = dns_message_nextname(rmessage, section)) { - dns_name_t *nsec = NULL; - dns_message_currentname(rmessage, section, &nsec); - for (nrdataset = ISC_LIST_HEAD(nsec->list); - nrdataset != NULL; nrdataset = next) { - bool data = false, exists = false; - bool optout = false, unknown = false; - bool setclosest = false; - bool setnearest = false; - - next = ISC_LIST_NEXT(nrdataset, link); - if (nrdataset->type != dns_rdatatype_nsec && - nrdataset->type != dns_rdatatype_nsec3) - continue; - - if (nrdataset->type == dns_rdatatype_nsec && - NXND(dns_nsec_noexistnodata(type, name, nsec, - nrdataset, &exists, - &data, NULL, fctx_log, - fctx))) - { - if (!exists) { - noqname = nsec; - found = dns_rdatatype_nsec; - } - } - - if (nrdataset->type == dns_rdatatype_nsec3 && - NXND(dns_nsec3_noexistnodata(type, name, nsec, - nrdataset, zonename, - &exists, &data, - &optout, &unknown, - &setclosest, - &setnearest, - closest, nearest, - fctx_log, fctx))) - { - if (!exists && setnearest) { - noqname = nsec; - found = dns_rdatatype_nsec3; - } - } - } - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - if (noqname != NULL) { - for (sigrdataset = ISC_LIST_HEAD(noqname->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { - if (sigrdataset->type == dns_rdatatype_rrsig && - sigrdataset->covers == found) - break; - } - if (sigrdataset != NULL) - *noqnamep = noqname; - } - return (result); -} - -static inline isc_result_t -cache_name(fetchctx_t *fctx, dns_message_t *rmessage, - dns_name_t *name, dns_adbaddrinfo_t *addrinfo, - isc_stdtime_t now) -{ - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t *addedrdataset = NULL; - dns_rdataset_t *ardataset = NULL, *asigrdataset = NULL; - dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL; - dns_dbnode_t *node = NULL, **anodep = NULL; - dns_db_t **adbp = NULL; - dns_name_t *aname = NULL; - dns_resolver_t *res = fctx->res; - bool need_validation = false; - bool secure_domain = false; - bool have_answer = false; - isc_result_t result, eresult = ISC_R_SUCCESS; - dns_fetchevent_t *event = NULL; - unsigned int options; - isc_task_t *task; - bool fail; - unsigned int valoptions = 0; - bool checknta = true; - - /* - * The appropriate bucket lock must be held. - */ - task = res->buckets[fctx->bucketnum].task; - - /* - * Is DNSSEC validation required for this name? - */ - if (NONTA(fctx->options)) { - valoptions |= DNS_VALIDATOR_NONTA; - checknta = false; - } - - if (res->view->enablevalidation) { - result = issecuredomain(res->view, name, fctx->type, - now, checknta, NULL, &secure_domain); - if (result != ISC_R_SUCCESS) { - return (result); - } - - if (!secure_domain && res->view->dlv != NULL) { - valoptions |= DNS_VALIDATOR_DLV; - secure_domain = true; - } - } - - if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) { - valoptions |= DNS_VALIDATOR_NOCDFLAG; - } - - if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) { - need_validation = false; - } else { - need_validation = secure_domain; - } - - if (((name->attributes & DNS_NAMEATTR_ANSWER) != 0) && - (!need_validation)) - { - have_answer = true; - event = ISC_LIST_HEAD(fctx->events); - if (event != NULL) { - adbp = &event->db; - aname = dns_fixedname_name(&event->foundname); - result = dns_name_copy(name, aname, NULL); - if (result != ISC_R_SUCCESS) { - return (result); - } - anodep = &event->node; - /* - * If this is an ANY, SIG or RRSIG query, we're not - * going to return any rdatasets, unless we encountered - * a CNAME or DNAME as "the answer". In this case, - * we're going to return DNS_R_CNAME or DNS_R_DNAME - * and we must set up the rdatasets. - */ - if ((fctx->type != dns_rdatatype_any && - fctx->type != dns_rdatatype_rrsig && - fctx->type != dns_rdatatype_sig) || - (name->attributes & DNS_NAMEATTR_CHAINING) != 0) - { - ardataset = event->rdataset; - asigrdataset = event->sigrdataset; - } - } - } - - /* - * Find or create the cache node. - */ - node = NULL; - result = dns_db_findnode(fctx->cache, name, true, &node); - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * Cache or validate each cacheable rdataset. - */ - fail = ((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (!CACHE(rdataset)) { - continue; - } - if (CHECKNAMES(rdataset)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "check-names %s %s/%s/%s", - fail ? "failure" : "warning", - namebuf, typebuf, classbuf); - if (fail) { - if (ANSWER(rdataset)) { - dns_db_detachnode(fctx->cache, &node); - return (DNS_R_BADNAME); - } - continue; - } - } - - /* - * Enforce the configure maximum cache TTL. - */ - if (rdataset->ttl > res->view->maxcachettl) { - rdataset->ttl = res->view->maxcachettl; - } - - /* - * Mark the rdataset as being prefetch eligible. - */ - if (rdataset->ttl > fctx->res->view->prefetch_eligible) { - rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; - } - - /* - * Find the SIG for this rdataset, if we have it. - */ - for (sigrdataset = ISC_LIST_HEAD(name->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) - { - if (sigrdataset->type == dns_rdatatype_rrsig && - sigrdataset->covers == rdataset->type) - { - break; - } - } - - /* - * If this RRset is in a secure domain, is in bailiwick, - * and is not glue, attempt DNSSEC validation. (We do not - * attempt to validate glue or out-of-bailiwick data--even - * though there might be some performance benefit to doing - * so--because it makes it simpler and safer to ensure that - * records from a secure domain are only cached if validated - * within the context of a query to the domain that owns - * them.) - */ - if (secure_domain && rdataset->trust != dns_trust_glue && - !EXTERNAL(rdataset)) - { - dns_trust_t trust; - - /* - * RRSIGs are validated as part of validating the - * type they cover. - */ - if (rdataset->type == dns_rdatatype_rrsig) { - continue; - } - - if (sigrdataset == NULL && need_validation && - !ANSWER(rdataset)) - { - /* - * Ignore unrelated non-answer - * rdatasets that are missing signatures. - */ - continue; - } - - /* - * Normalize the rdataset and sigrdataset TTLs. - */ - if (sigrdataset != NULL) { - rdataset->ttl = ISC_MIN(rdataset->ttl, - sigrdataset->ttl); - sigrdataset->ttl = rdataset->ttl; - } - - /* - * Mark the rdataset as being prefetch eligible. - */ - if (rdataset->ttl > fctx->res->view->prefetch_eligible) - { - rdataset->attributes |= - DNS_RDATASETATTR_PREFETCH; - } - - /* - * Cache this rdataset/sigrdataset pair as - * pending data. Track whether it was additional - * or not. If this was a priming query, additional - * should be cached as glue. - */ - if (rdataset->trust == dns_trust_additional) { - trust = dns_trust_pending_additional; - } else { - trust = dns_trust_pending_answer; - } - - rdataset->trust = trust; - if (sigrdataset != NULL) { - sigrdataset->trust = trust; - } - if (!need_validation || !ANSWER(rdataset)) { - options = 0; - if (ANSWER(rdataset) && - rdataset->type != dns_rdatatype_rrsig) - { - isc_result_t tresult; - dns_name_t *noqname = NULL; - tresult = findnoqname(fctx, rmessage, - name, - rdataset->type, - &noqname); - if (tresult == ISC_R_SUCCESS && - noqname != NULL) - { - (void) dns_rdataset_addnoqname( - rdataset, noqname); - } - } - if ((fctx->options & - DNS_FETCHOPT_PREFETCH) != 0) - { - options = DNS_DBADD_PREFETCH; - } - if ((fctx->options & - DNS_FETCHOPT_NOCACHED) != 0) - { - options |= DNS_DBADD_FORCE; - } - addedrdataset = ardataset; - result = dns_db_addrdataset(fctx->cache, node, - NULL, now, rdataset, - options, - addedrdataset); - if (result == DNS_R_UNCHANGED) { - result = ISC_R_SUCCESS; - if (!need_validation && - ardataset != NULL && - NEGATIVE(ardataset)) - { - /* - * The answer in the cache is - * better than the answer we - * found, and is a negative - * cache entry, so we must set - * eresult appropriately. - */ - if (NXDOMAIN(ardataset)) { - eresult = - DNS_R_NCACHENXDOMAIN; - } else { - eresult = - DNS_R_NCACHENXRRSET; - } - /* - * We have a negative response - * from the cache so don't - * attempt to add the RRSIG - * rrset. - */ - continue; - } - } - if (result != ISC_R_SUCCESS) { - break; - } - if (sigrdataset != NULL) { - addedrdataset = asigrdataset; - result = dns_db_addrdataset(fctx->cache, - node, NULL, now, - sigrdataset, - options, - addedrdataset); - if (result == DNS_R_UNCHANGED) { - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - break; - } - } else if (!ANSWER(rdataset)) { - continue; - } - } - - if (ANSWER(rdataset) && need_validation) { - if (fctx->type != dns_rdatatype_any && - fctx->type != dns_rdatatype_rrsig && - fctx->type != dns_rdatatype_sig) - { - /* - * This is The Answer. We will - * validate it, but first we cache - * the rest of the response - it may - * contain useful keys. - */ - INSIST(valrdataset == NULL && - valsigrdataset == NULL); - valrdataset = rdataset; - valsigrdataset = sigrdataset; - } else { - /* - * This is one of (potentially) - * multiple answers to an ANY - * or SIG query. To keep things - * simple, we just start the - * validator right away rather - * than caching first and - * having to remember which - * rdatasets needed validation. - */ - result = valcreate(fctx, rmessage, - addrinfo, name, - rdataset->type, - rdataset, - sigrdataset, - valoptions, task); - } - } else if (CHAINING(rdataset)) { - if (rdataset->type == dns_rdatatype_cname) { - eresult = DNS_R_CNAME; - } else { - INSIST(rdataset->type == - dns_rdatatype_dname); - eresult = DNS_R_DNAME; - } - } - } else if (!EXTERNAL(rdataset)) { - /* - * It's OK to cache this rdataset now. - */ - if (ANSWER(rdataset)) { - addedrdataset = ardataset; - } else if (ANSWERSIG(rdataset)) { - addedrdataset = asigrdataset; - } else { - addedrdataset = NULL; - } - if (CHAINING(rdataset)) { - if (rdataset->type == dns_rdatatype_cname) { - eresult = DNS_R_CNAME; - } else { - INSIST(rdataset->type == - dns_rdatatype_dname); - eresult = DNS_R_DNAME; - } - } - if (rdataset->trust == dns_trust_glue && - (rdataset->type == dns_rdatatype_ns || - (rdataset->type == dns_rdatatype_rrsig && - rdataset->covers == dns_rdatatype_ns))) - { - /* - * If the trust level is 'dns_trust_glue' - * then we are adding data from a referral - * we got while executing the search algorithm. - * New referral data always takes precedence - * over the existing cache contents. - */ - options = DNS_DBADD_FORCE; - } else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) - { - options = DNS_DBADD_PREFETCH; - } else { - options = 0; - } - - if (ANSWER(rdataset) && - rdataset->type != dns_rdatatype_rrsig) - { - isc_result_t tresult; - dns_name_t *noqname = NULL; - tresult = findnoqname(fctx, rmessage, name, - rdataset->type, &noqname); - if (tresult == ISC_R_SUCCESS && - noqname != NULL) - { - (void) dns_rdataset_addnoqname( - rdataset, noqname); - } - } - - /* - * Now we can add the rdataset. - */ - result = dns_db_addrdataset(fctx->cache, - node, NULL, now, - rdataset, - options, - addedrdataset); - - if (result == DNS_R_UNCHANGED) { - if (ANSWER(rdataset) && - ardataset != NULL && - NEGATIVE(ardataset)) - { - /* - * The answer in the cache is better - * than the answer we found, and is - * a negative cache entry, so we - * must set eresult appropriately. - */ - if (NXDOMAIN(ardataset)) { - eresult = DNS_R_NCACHENXDOMAIN; - } else { - eresult = DNS_R_NCACHENXRRSET; - } - } - result = ISC_R_SUCCESS; - } else if (result != ISC_R_SUCCESS) { - break; - } - } - } - - if (valrdataset != NULL) { - dns_rdatatype_t vtype = fctx->type; - if (CHAINING(valrdataset)) { - if (valrdataset->type == dns_rdatatype_cname) { - vtype = dns_rdatatype_cname; - } else { - vtype = dns_rdatatype_dname; - } - } - result = valcreate(fctx, rmessage, addrinfo, name, vtype, - valrdataset, valsigrdataset, valoptions, - task); - } - - if (result == ISC_R_SUCCESS && have_answer) { - FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); - if (event != NULL) { - /* - * Negative results must be indicated in event->result. - */ - if (dns_rdataset_isassociated(event->rdataset) && - NEGATIVE(event->rdataset)) - { - INSIST(eresult == DNS_R_NCACHENXDOMAIN || - eresult == DNS_R_NCACHENXRRSET); - } - event->result = eresult; - if (adbp != NULL && *adbp != NULL) { - if (anodep != NULL && *anodep != NULL) { - dns_db_detachnode(*adbp, anodep); - } - dns_db_detach(adbp); - } - dns_db_attach(fctx->cache, adbp); - dns_db_transfernode(fctx->cache, &node, anodep); - clone_results(fctx); - } - } - - if (node != NULL) { - dns_db_detachnode(fctx->cache, &node); - } - - return (result); -} - -static inline isc_result_t -cache_message(fetchctx_t *fctx, dns_message_t *rmessage, - dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) -{ - isc_result_t result; - dns_section_t section; - dns_name_t *name; - - FCTXTRACE("cache_message"); - - FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTCACHE); - - LOCK(&fctx->res->buckets[fctx->bucketnum].lock); - - for (section = DNS_SECTION_ANSWER; - section <= DNS_SECTION_ADDITIONAL; - section++) { - result = dns_message_firstname(rmessage, section); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(rmessage, section, - &name); - if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) { - result = cache_name(fctx, rmessage, name, - addrinfo, now); - if (result != ISC_R_SUCCESS) - break; - } - result = dns_message_nextname(rmessage, section); - } - if (result != ISC_R_NOMORE) - break; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); - - return (result); -} - -/* - * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult. - */ -static isc_result_t -ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, - bool optout, bool secure, - dns_rdataset_t *ardataset, isc_result_t *eresultp) -{ - isc_result_t result; - dns_rdataset_t rdataset; - - if (ardataset == NULL) { - dns_rdataset_init(&rdataset); - ardataset = &rdataset; - } - if (secure) - result = dns_ncache_addoptout(message, cache, node, covers, - now, maxttl, optout, ardataset); - else - result = dns_ncache_add(message, cache, node, covers, now, - maxttl, ardataset); - if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) { - /* - * If the cache now contains a negative entry and we - * care about whether it is DNS_R_NCACHENXDOMAIN or - * DNS_R_NCACHENXRRSET then extract it. - */ - if (NEGATIVE(ardataset)) { - /* - * The cache data is a negative cache entry. - */ - if (NXDOMAIN(ardataset)) - *eresultp = DNS_R_NCACHENXDOMAIN; - else - *eresultp = DNS_R_NCACHENXRRSET; - } else { - /* - * Either we don't care about the nature of the - * cache rdataset (because no fetch is interested - * in the outcome), or the cache rdataset is not - * a negative cache entry. Whichever case it is, - * we can return success. - * - * XXXRTH There's a CNAME/DNAME problem here. - */ - *eresultp = ISC_R_SUCCESS; - } - result = ISC_R_SUCCESS; - } - if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset)) - dns_rdataset_disassociate(ardataset); - - return (result); -} - -static inline isc_result_t -ncache_message(fetchctx_t *fctx, dns_message_t *rmessage, - dns_adbaddrinfo_t *addrinfo, dns_rdatatype_t covers, - isc_stdtime_t now) -{ - isc_result_t result, eresult; - dns_name_t *name; - dns_resolver_t *res; - dns_db_t **adbp; - dns_dbnode_t *node, **anodep; - dns_rdataset_t *ardataset; - bool need_validation, secure_domain; - dns_name_t *aname; - dns_fetchevent_t *event; - uint32_t ttl; - unsigned int valoptions = 0; - bool checknta = true; - - FCTXTRACE("ncache_message"); - - FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTNCACHE); - - res = fctx->res; - need_validation = false; - POST(need_validation); - secure_domain = false; - eresult = ISC_R_SUCCESS; - name = &fctx->name; - node = NULL; - - /* - * XXXMPA remove when we follow cnames and adjust the setting - * of FCTX_ATTR_WANTNCACHE in noanswer_response(). - */ - INSIST(rmessage->counts[DNS_SECTION_ANSWER] == 0); - - /* - * Is DNSSEC validation required for this name? - */ - if (NONTA(fctx->options)) { - valoptions |= DNS_VALIDATOR_NONTA; - checknta = false; - } - - if (fctx->res->view->enablevalidation) { - result = issecuredomain(res->view, name, fctx->type, - now, checknta, NULL, &secure_domain); - if (result != ISC_R_SUCCESS) - return (result); - - if (!secure_domain && res->view->dlv != NULL) { - valoptions |= DNS_VALIDATOR_DLV; - secure_domain = true; - } - } - - if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) - valoptions |= DNS_VALIDATOR_NOCDFLAG; - - if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) - need_validation = false; - else - need_validation = secure_domain; - - if (secure_domain) { - /* - * Mark all rdatasets as pending. - */ - dns_rdataset_t *trdataset; - dns_name_t *tname; - - result = dns_message_firstname(rmessage, - DNS_SECTION_AUTHORITY); - while (result == ISC_R_SUCCESS) { - tname = NULL; - dns_message_currentname(rmessage, - DNS_SECTION_AUTHORITY, - &tname); - for (trdataset = ISC_LIST_HEAD(tname->list); - trdataset != NULL; - trdataset = ISC_LIST_NEXT(trdataset, link)) - trdataset->trust = dns_trust_pending_answer; - result = dns_message_nextname(rmessage, - DNS_SECTION_AUTHORITY); - } - if (result != ISC_R_NOMORE) - return (result); - - } - - if (need_validation) { - /* - * Do negative response validation. - */ - result = valcreate(fctx, rmessage, addrinfo, name, fctx->type, - NULL, NULL, valoptions, - res->buckets[fctx->bucketnum].task); - /* - * If validation is necessary, return now. Otherwise continue - * to process the message, letting the validation complete - * in its own good time. - */ - return (result); - } - - LOCK(&res->buckets[fctx->bucketnum].lock); - - adbp = NULL; - aname = NULL; - anodep = NULL; - ardataset = NULL; - if (!HAVE_ANSWER(fctx)) { - event = ISC_LIST_HEAD(fctx->events); - if (event != NULL) { - adbp = &event->db; - aname = dns_fixedname_name(&event->foundname); - result = dns_name_copy(name, aname, NULL); - if (result != ISC_R_SUCCESS) - goto unlock; - anodep = &event->node; - ardataset = event->rdataset; - } - } else - event = NULL; - - result = dns_db_findnode(fctx->cache, name, true, &node); - if (result != ISC_R_SUCCESS) - goto unlock; - - /* - * If we are asking for a SOA record set the cache time - * to zero to facilitate locating the containing zone of - * a arbitrary zone. - */ - ttl = fctx->res->view->maxncachettl; - if (fctx->type == dns_rdatatype_soa && - covers == dns_rdatatype_any && - fctx->res->zero_no_soa_ttl) - ttl = 0; - - result = ncache_adderesult(rmessage, fctx->cache, node, - covers, now, ttl, false, - false, ardataset, &eresult); - if (result != ISC_R_SUCCESS) - goto unlock; - - if (!HAVE_ANSWER(fctx)) { - FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); - if (event != NULL) { - event->result = eresult; - if (adbp != NULL && *adbp != NULL) { - if (anodep != NULL && *anodep != NULL) - dns_db_detachnode(*adbp, anodep); - dns_db_detach(adbp); - } - dns_db_attach(fctx->cache, adbp); - dns_db_transfernode(fctx->cache, &node, anodep); - clone_results(fctx); - } - } - - unlock: - UNLOCK(&res->buckets[fctx->bucketnum].lock); - - if (node != NULL) - dns_db_detachnode(fctx->cache, &node); - - return (result); -} - -static inline void -mark_related(dns_name_t *name, dns_rdataset_t *rdataset, - bool external, bool gluing) -{ - name->attributes |= DNS_NAMEATTR_CACHE; - if (gluing) { - rdataset->trust = dns_trust_glue; - /* - * Glue with 0 TTL causes problems. We force the TTL to - * 1 second to prevent this. - */ - if (rdataset->ttl == 0) - rdataset->ttl = 1; - } else - rdataset->trust = dns_trust_additional; - /* - * Avoid infinite loops by only marking new rdatasets. - */ - if (!CACHE(rdataset)) { - name->attributes |= DNS_NAMEATTR_CHASE; - rdataset->attributes |= DNS_RDATASETATTR_CHASE; - } - rdataset->attributes |= DNS_RDATASETATTR_CACHE; - if (external) - rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; -} - -static isc_result_t -check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type, - dns_section_t section) -{ - dns_chkarg_t *chkarg = arg; - fetchctx_t *fctx = chkarg->fctx; - dns_message_t *rmessage = chkarg->rmessage; - isc_result_t result; - dns_name_t *name = NULL; - dns_rdataset_t *rdataset = NULL; - bool external; - dns_rdatatype_t rtype; - bool gluing; - - REQUIRE(VALID_FCTX(fctx)); - -#if CHECK_FOR_GLUE_IN_ANSWER - if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a) - return (ISC_R_SUCCESS); -#endif - - gluing = (GLUING(fctx) || - (fctx->type == dns_rdatatype_ns && - dns_name_equal(&fctx->name, dns_rootname))); - - result = dns_message_findname(rmessage, section, addname, - dns_rdatatype_any, 0, &name, NULL); - if (result == ISC_R_SUCCESS) { - external = !dns_name_issubdomain(name, &fctx->domain); - if (type == dns_rdatatype_a) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (rdataset->type == dns_rdatatype_rrsig) - rtype = rdataset->covers; - else - rtype = rdataset->type; - if (rtype == dns_rdatatype_a || - rtype == dns_rdatatype_aaaa) - mark_related(name, rdataset, external, - gluing); - } - } else { - result = dns_message_findtype(name, type, 0, - &rdataset); - if (result == ISC_R_SUCCESS) { - mark_related(name, rdataset, external, gluing); - /* - * Do we have its SIG too? - */ - rdataset = NULL; - result = dns_message_findtype(name, - dns_rdatatype_rrsig, - type, &rdataset); - if (result == ISC_R_SUCCESS) - mark_related(name, rdataset, external, - gluing); - } - } - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) { - return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL)); -} - -#ifndef CHECK_FOR_GLUE_IN_ANSWER -#define CHECK_FOR_GLUE_IN_ANSWER 0 -#endif -#if CHECK_FOR_GLUE_IN_ANSWER -static isc_result_t -check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) { - return (check_section(arg, addname, type, DNS_SECTION_ANSWER)); -} -#endif - -static void -chase_additional(fetchctx_t *fctx, dns_message_t *rmessage) { - bool rescan; - dns_section_t section = DNS_SECTION_ADDITIONAL; - isc_result_t result; - - again: - rescan = false; - - for (result = dns_message_firstname(rmessage, section); - result == ISC_R_SUCCESS; - result = dns_message_nextname(rmessage, section)) { - dns_name_t *name = NULL; - dns_rdataset_t *rdataset; - dns_message_currentname(rmessage, DNS_SECTION_ADDITIONAL, - &name); - if ((name->attributes & DNS_NAMEATTR_CHASE) == 0) - continue; - name->attributes &= ~DNS_NAMEATTR_CHASE; - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (CHASE(rdataset)) { - dns_chkarg_t chkarg; - chkarg.fctx = fctx; - chkarg.rmessage = rmessage; - rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; - (void)dns_rdataset_additionaldata(rdataset, - check_related, - &chkarg); - rescan = true; - } - } - } - if (rescan) - goto again; -} - -static bool -is_answeraddress_allowed(dns_view_t *view, dns_name_t *name, - dns_rdataset_t *rdataset) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - struct in_addr ina; - struct in6_addr in6a; - isc_netaddr_t netaddr; - char addrbuf[ISC_NETADDR_FORMATSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[64]; - char typebuf[64]; - int match; - - /* By default, we allow any addresses. */ - if (view->denyansweracl == NULL) - return (true); - - /* - * If the owner name matches one in the exclusion list, either exactly - * or partially, allow it. - */ - if (view->answeracl_exclude != NULL) { - dns_rbtnode_t *node = NULL; - - result = dns_rbt_findnode(view->answeracl_exclude, name, NULL, - &node, NULL, 0, NULL, NULL); - - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - return (true); - } - - /* - * Otherwise, search the filter list for a match for each address - * record. If a match is found, the address should be filtered, - * so should the entire answer. - */ - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - if (rdataset->type == dns_rdatatype_a) { - INSIST(rdata.length == sizeof(ina.s_addr)); - memmove(&ina.s_addr, rdata.data, sizeof(ina.s_addr)); - isc_netaddr_fromin(&netaddr, &ina); - } else { - INSIST(rdata.length == sizeof(in6a.s6_addr)); - memmove(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr)); - isc_netaddr_fromin6(&netaddr, &in6a); - } - - result = dns_acl_match(&netaddr, NULL, view->denyansweracl, - &view->aclenv, &match, NULL); - - if (result == ISC_R_SUCCESS && match > 0) { - isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(rdataset->type, typebuf, - sizeof(typebuf)); - dns_rdataclass_format(rdataset->rdclass, classbuf, - sizeof(classbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "answer address %s denied for %s/%s/%s", - addrbuf, namebuf, typebuf, classbuf); - return (false); - } - } - - return (true); -} - -static bool -is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname, - dns_rdataset_t *rdataset, bool *chainingp) -{ - isc_result_t result; - dns_rbtnode_t *node = NULL; - char qnamebuf[DNS_NAME_FORMATSIZE]; - char tnamebuf[DNS_NAME_FORMATSIZE]; - char classbuf[64]; - char typebuf[64]; - dns_name_t *tname = NULL; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - dns_view_t *view = fctx->res->view; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned int nlabels; - dns_fixedname_t fixed; - dns_name_t prefix; - int order; - - REQUIRE(rdataset != NULL); - REQUIRE(rdataset->type == dns_rdatatype_cname || - rdataset->type == dns_rdatatype_dname); - - /* - * By default, we allow any target name. - * If newqname != NULL we also need to extract the newqname. - */ - if (chainingp == NULL && view->denyanswernames == NULL) - return (true); - - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - switch (rdataset->type) { - case dns_rdatatype_cname: - result = dns_rdata_tostruct(&rdata, &cname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tname = &cname.cname; - break; - case dns_rdatatype_dname: - if (dns_name_fullcompare(qname, rname, &order, &nlabels) != - dns_namereln_subdomain) - { - return (true); - } - result = dns_rdata_tostruct(&rdata, &dname, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_name_init(&prefix, NULL); - tname = dns_fixedname_initname(&fixed); - nlabels = dns_name_countlabels(rname); - dns_name_split(qname, nlabels, &prefix, NULL); - result = dns_name_concatenate(&prefix, &dname.dname, tname, - NULL); - if (result == DNS_R_NAMETOOLONG) { - if (chainingp != NULL) { - *chainingp = true; - } - return (true); - } - RUNTIME_CHECK(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (chainingp != NULL) - *chainingp = true; - - if (view->denyanswernames == NULL) - return (true); - - /* - * If the owner name matches one in the exclusion list, either exactly - * or partially, allow it. - */ - if (view->answernames_exclude != NULL) { - result = dns_rbt_findnode(view->answernames_exclude, qname, - NULL, &node, NULL, 0, NULL, NULL); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - return (true); - } - - /* - * If the target name is a subdomain of the search domain, allow it. - * - * Note that if BIND is configured as a forwarding DNS server, the - * search domain will always match the root domain ("."), so we - * must also check whether forwarding is enabled so that filters - * can be applied; see GL #1574. - */ - if ((fctx->fwdpolicy == dns_fwdpolicy_none) && - dns_name_issubdomain(tname, &fctx->domain)) { - return (true); - } - - /* - * Otherwise, apply filters. - */ - result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node, - NULL, 0, NULL, NULL); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { - dns_name_format(qname, qnamebuf, sizeof(qnamebuf)); - dns_name_format(tname, tnamebuf, sizeof(tnamebuf)); - dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(view->rdclass, classbuf, - sizeof(classbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "%s target %s denied for %s/%s", - typebuf, tnamebuf, qnamebuf, classbuf); - return (false); - } - - return (true); -} - -static void -trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) { - char ns_namebuf[DNS_NAME_FORMATSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; - - if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) { - dns_name_format(name, ns_namebuf, sizeof(ns_namebuf)); - dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), - "fctx %p: trimming ttl of %s/NS for %s/%s: " - "%u -> %u", fctx, ns_namebuf, namebuf, tbuf, - rdataset->ttl, fctx->ns_ttl); - rdataset->ttl = fctx->ns_ttl; - } -} - -/* - * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral). - * If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer - * section for the NS RRset if the query type is NS; if it has - * LOOK_FOR_GLUE_IN_ANSWER we look for glue incorrectly returned in the answer - * section for A and AAAA queries. - */ -#define LOOK_FOR_NS_IN_ANSWER 0x1 -#define LOOK_FOR_GLUE_IN_ANSWER 0x2 - -static isc_result_t -noanswer_response(fetchctx_t *fctx, dns_message_t *message, - dns_name_t *oqname, unsigned int look_in_options) -{ - isc_result_t result; - dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name; - dns_rdataset_t *rdataset, *ns_rdataset; - bool aa, negative_response; - dns_rdatatype_t type, save_type; - dns_section_t section; - - FCTXTRACE("noanswer_response"); - - if ((look_in_options & LOOK_FOR_NS_IN_ANSWER) != 0) { - INSIST(fctx->type == dns_rdatatype_ns); - section = DNS_SECTION_ANSWER; - } else - section = DNS_SECTION_AUTHORITY; - - /* - * Setup qname. - */ - if (oqname == NULL) { - /* - * We have a normal, non-chained negative response or - * referral. - */ - if ((message->flags & DNS_MESSAGEFLAG_AA) != 0) - aa = true; - else - aa = false; - qname = &fctx->name; - } else { - /* - * We're being invoked by answer_response() after it has - * followed a CNAME/DNAME chain. - */ - qname = oqname; - aa = false; - /* - * If the current qname is not a subdomain of the query - * domain, there's no point in looking at the authority - * section without doing DNSSEC validation. - * - * Until we do that validation, we'll just return success - * in this case. - */ - if (!dns_name_issubdomain(qname, &fctx->domain)) - return (ISC_R_SUCCESS); - } - - /* - * We have to figure out if this is a negative response, or a - * referral. - */ - - /* - * Sometimes we can tell if its a negative response by looking at - * the message header. - */ - negative_response = false; - if (message->rcode == dns_rcode_nxdomain || - (message->counts[DNS_SECTION_ANSWER] == 0 && - message->counts[DNS_SECTION_AUTHORITY] == 0)) - negative_response = true; - - /* - * Process the authority section. - */ - ns_name = NULL; - ns_rdataset = NULL; - soa_name = NULL; - ds_name = NULL; - save_name = NULL; - save_type = dns_rdatatype_none; - result = dns_message_firstname(message, section); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, section, &name); - if (dns_name_issubdomain(name, &fctx->domain)) { - /* - * Look for NS/SOA RRsets first. - */ - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - type = rdataset->type; - if (type == dns_rdatatype_rrsig) - type = rdataset->covers; - if (((type == dns_rdatatype_ns || - type == dns_rdatatype_soa) && - !dns_name_issubdomain(qname, name))) { - char qbuf[DNS_NAME_FORMATSIZE]; - char nbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; - dns_rdatatype_format(type, tbuf, - sizeof(tbuf)); - dns_name_format(name, nbuf, - sizeof(nbuf)); - dns_name_format(qname, qbuf, - sizeof(qbuf)); - log_formerr(fctx, - "unrelated %s %s in " - "%s authority section", - tbuf, nbuf, qbuf); - goto nextname; - } - if (type == dns_rdatatype_ns) { - /* - * NS or RRSIG NS. - * - * Only one set of NS RRs is allowed. - */ - if (rdataset->type == - dns_rdatatype_ns) { - if (ns_name != NULL && - name != ns_name) { - log_formerr(fctx, - "multiple NS " - "RRsets in " - "authority " - "section"); - return (DNS_R_FORMERR); - } - ns_name = name; - ns_rdataset = rdataset; - } - name->attributes |= - DNS_NAMEATTR_CACHE; - rdataset->attributes |= - DNS_RDATASETATTR_CACHE; - rdataset->trust = dns_trust_glue; - } - if (type == dns_rdatatype_soa) { - /* - * SOA, or RRSIG SOA. - * - * Only one SOA is allowed. - */ - if (rdataset->type == - dns_rdatatype_soa) { - if (soa_name != NULL && - name != soa_name) { - log_formerr(fctx, - "multiple SOA " - "RRs in " - "authority " - "section"); - return (DNS_R_FORMERR); - } - soa_name = name; - } - name->attributes |= - DNS_NAMEATTR_NCACHE; - rdataset->attributes |= - DNS_RDATASETATTR_NCACHE; - if (aa) - rdataset->trust = - dns_trust_authauthority; - else if (ISFORWARDER(fctx->addrinfo)) - rdataset->trust = - dns_trust_answer; - else - rdataset->trust = - dns_trust_additional; - } - } - } - nextname: - result = dns_message_nextname(message, section); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) - return (result); - } - - log_ns_ttl(fctx, "noanswer_response"); - - if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && - !dns_name_equal(ns_name, dns_rootname)) - trim_ns_ttl(fctx, ns_name, ns_rdataset); - - /* - * A negative response has a SOA record (Type 2) - * and a optional NS RRset (Type 1) or it has neither - * a SOA or a NS RRset (Type 3, handled above) or - * rcode is NXDOMAIN (handled above) in which case - * the NS RRset is allowed (Type 4). - */ - if (soa_name != NULL) - negative_response = true; - - result = dns_message_firstname(message, section); - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(message, section, &name); - if (dns_name_issubdomain(name, &fctx->domain)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - type = rdataset->type; - if (type == dns_rdatatype_rrsig) - type = rdataset->covers; - if (type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3) { - /* - * NSEC or RRSIG NSEC. - */ - if (negative_response) { - name->attributes |= - DNS_NAMEATTR_NCACHE; - rdataset->attributes |= - DNS_RDATASETATTR_NCACHE; - } else if (type == dns_rdatatype_nsec) { - name->attributes |= - DNS_NAMEATTR_CACHE; - rdataset->attributes |= - DNS_RDATASETATTR_CACHE; - } - if (aa) - rdataset->trust = - dns_trust_authauthority; - else if (ISFORWARDER(fctx->addrinfo)) - rdataset->trust = - dns_trust_answer; - else - rdataset->trust = - dns_trust_additional; - /* - * No additional data needs to be - * marked. - */ - } else if (type == dns_rdatatype_ds) { - bool checknta = true; - bool secure_domain = false; - isc_stdtime_t now; - - /* - * DS or SIG DS. - * - * These should only be here if - * this is a referral, and there - * should only be one DS RRset. - */ - if (ns_name == NULL) { - log_formerr(fctx, - "DS with no " - "referral"); - return (DNS_R_FORMERR); - } - if (rdataset->type == - dns_rdatatype_ds) { - if (ds_name != NULL && - name != ds_name) { - log_formerr(fctx, - "DS doesn't " - "match " - "referral " - "(NS)"); - return (DNS_R_FORMERR); - } - ds_name = name; - } - name->attributes |= - DNS_NAMEATTR_CACHE; - rdataset->attributes |= - DNS_RDATASETATTR_CACHE; - - isc_stdtime_get(&now); - if (NONTA(fctx->options)) { - checknta = false; - } - result = issecuredomain(fctx->res->view, - name, type, now, - checknta, NULL, - &secure_domain); - if (result != ISC_R_SUCCESS) { - return (result); - } - if (secure_domain) { - rdataset->trust = - dns_trust_pending_answer; - } else if (aa) { - rdataset->trust = - dns_trust_authauthority; - } else if (ISFORWARDER(fctx->addrinfo)) - { - rdataset->trust = - dns_trust_answer; - } else { - rdataset->trust = - dns_trust_additional; - } - } - } - } else { - save_name = name; - save_type = ISC_LIST_HEAD(name->list)->type; - } - result = dns_message_nextname(message, section); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) - return (result); - } - - /* - * Trigger lookups for DNS nameservers. - */ - if (negative_response && message->rcode == dns_rcode_noerror && - fctx->type == dns_rdatatype_ds && soa_name != NULL && - dns_name_equal(soa_name, qname) && - !dns_name_equal(qname, dns_rootname)) - return (DNS_R_CHASEDSSERVERS); - - /* - * Did we find anything? - */ - if (!negative_response && ns_name == NULL) { - /* - * Nope. - */ - if (oqname != NULL) { - /* - * We've already got a partial CNAME/DNAME chain, - * and haven't found else anything useful here, but - * no error has occurred since we have an answer. - */ - return (ISC_R_SUCCESS); - } else { - /* - * The responder is insane. - */ - if (save_name == NULL) { - log_formerr(fctx, "invalid response"); - return (DNS_R_FORMERR); - } - if (!dns_name_issubdomain(save_name, &fctx->domain)) { - char nbuf[DNS_NAME_FORMATSIZE]; - char dbuf[DNS_NAME_FORMATSIZE]; - char tbuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(save_type, tbuf, - sizeof(tbuf)); - dns_name_format(save_name, nbuf, sizeof(nbuf)); - dns_name_format(&fctx->domain, dbuf, - sizeof(dbuf)); - - log_formerr(fctx, "Name %s (%s) not subdomain" - " of zone %s -- invalid response", - nbuf, tbuf, dbuf); - } else { - log_formerr(fctx, "invalid response"); - } - return (DNS_R_FORMERR); - } - } - - /* - * If we found both NS and SOA, they should be the same name. - */ - if (ns_name != NULL && soa_name != NULL && ns_name != soa_name) { - log_formerr(fctx, "NS/SOA mismatch"); - return (DNS_R_FORMERR); - } - - /* - * Do we have a referral? (We only want to follow a referral if - * we're not following a chain.) - */ - if (!negative_response && ns_name != NULL && oqname == NULL) { - dns_chkarg_t chkarg; - /* - * We already know ns_name is a subdomain of fctx->domain. - * If ns_name is equal to fctx->domain, we're not making - * progress. We return DNS_R_FORMERR so that we'll keep - * trying other servers. - */ - if (dns_name_equal(ns_name, &fctx->domain)) { - log_formerr(fctx, "non-improving referral"); - return (DNS_R_FORMERR); - } - - /* - * If the referral name is not a parent of the query - * name, consider the responder insane. - */ - if (! dns_name_issubdomain(&fctx->name, ns_name)) { - /* Logged twice */ - log_formerr(fctx, "referral to non-parent"); - FCTXTRACE("referral to non-parent"); - return (DNS_R_FORMERR); - } - - /* - * Mark any additional data related to this rdataset. - * It's important that we do this before we change the - * query domain. - */ - INSIST(ns_rdataset != NULL); - FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING); - chkarg.fctx = fctx; - chkarg.rmessage = message; - (void)dns_rdataset_additionaldata(ns_rdataset, check_related, - &chkarg); -#if CHECK_FOR_GLUE_IN_ANSWER - /* - * Look in the answer section for "glue" that is incorrectly - * returned as a answer. This is needed if the server also - * minimizes the response size by not adding records to the - * additional section that are in the answer section or if - * the record gets dropped due to message size constraints. - */ - if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 && - (fctx->type == dns_rdatatype_aaaa || - fctx->type == dns_rdatatype_a)) { - dns_chkarg_t chkarg; - chkarg.fcx = fctx; - chkarg.rmessage = message; - (void)dns_rdataset_additionaldata(ns_rdataset, - check_answer, &chkarg); - } -#endif - FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING); - /* - * NS rdatasets with 0 TTL cause problems. - * dns_view_findzonecut() will not find them when we - * try to follow the referral, and we'll SERVFAIL - * because the best nameservers are now above QDOMAIN. - * We force the TTL to 1 second to prevent this. - */ - if (ns_rdataset->ttl == 0) - ns_rdataset->ttl = 1; - /* - * Set the current query domain to the referral name. - * - * XXXRTH We should check if we're in forward-only mode, and - * if so we should bail out. - */ - INSIST(dns_name_countlabels(&fctx->domain) > 0); - fcount_decr(fctx); - dns_name_free(&fctx->domain, fctx->mctx); - if (dns_rdataset_isassociated(&fctx->nameservers)) - dns_rdataset_disassociate(&fctx->nameservers); - dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) - return (result); - result = fcount_incr(fctx, true); - if (result != ISC_R_SUCCESS) - return (result); - FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTCACHE); - fctx->ns_ttl_ok = false; - log_ns_ttl(fctx, "DELEGATION"); - return (DNS_R_DELEGATION); - } - - /* - * Since we're not doing a referral, we don't want to cache any - * NS RRs we may have found. - */ - if (ns_name != NULL) - ns_name->attributes &= ~DNS_NAMEATTR_CACHE; - - if (negative_response && oqname == NULL) - FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTNCACHE); - - return (ISC_R_SUCCESS); -} - -static bool -validinanswer(dns_rdataset_t *rdataset, fetchctx_t *fctx) { - if (rdataset->type == dns_rdatatype_nsec3) { - /* - * NSEC3 records are not allowed to - * appear in the answer section. - */ - log_formerr(fctx, "NSEC3 in answer"); - return (false); - } - if (rdataset->type == dns_rdatatype_tkey) { - /* - * TKEY is not a valid record in a - * response to any query we can make. - */ - log_formerr(fctx, "TKEY in answer"); - return (false); - } - if (rdataset->rdclass != fctx->res->rdclass) { - log_formerr(fctx, "Mismatched class in answer"); - return (false); - } - return (true); -} - -static isc_result_t -answer_response(fetchctx_t *fctx, dns_message_t *message) { - isc_result_t result; - dns_name_t *name = NULL, *qname = NULL, *ns_name = NULL; - dns_name_t *aname = NULL, *cname = NULL, *dname = NULL; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t *ardataset = NULL, *crdataset = NULL; - dns_rdataset_t *drdataset = NULL, *ns_rdataset = NULL; - bool done = false, aa; - unsigned int dname_labels, domain_labels; - bool chaining = false; - dns_rdatatype_t type; - dns_view_t *view = NULL; - dns_trust_t trust; - - REQUIRE(VALID_FCTX(fctx)); - - FCTXTRACE("answer_response"); - - qname = &fctx->name; - view = fctx->res->view; - type = fctx->type; - - /* - * There can be multiple RRSIG and SIG records at a name so - * we treat these types as a subset of ANY. - */ - if (type == dns_rdatatype_rrsig || type == dns_rdatatype_sig) { - type = dns_rdatatype_any; - } - - /* - * Bigger than any valid DNAME label count. - */ - dname_labels = dns_name_countlabels(qname); - domain_labels = dns_name_countlabels(&fctx->domain); - - /* - * Perform a single pass looking for the answer, cname or covering - * dname. - */ - for (result = dns_message_firstname(message, DNS_SECTION_ANSWER); - result == ISC_R_SUCCESS; - result = dns_message_nextname(message, DNS_SECTION_ANSWER)) - { - int order; - unsigned int nlabels; - dns_namereln_t namereln; - - name = NULL; - dns_message_currentname(message, DNS_SECTION_ANSWER, &name); - namereln = dns_name_fullcompare(qname, name, &order, &nlabels); - switch (namereln) { - case dns_namereln_equal: - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->type == type || - type == dns_rdatatype_any) - { - aname = name; - if (type != dns_rdatatype_any) { - ardataset = rdataset; - } - break; - } - if (rdataset->type == dns_rdatatype_cname) { - cname = name; - crdataset = rdataset; - break; - } - } - break; - - case dns_namereln_subdomain: - /* - * In-scope DNAME records must have at least - * as many labels as the domain being queried. - * They also must be less that qname's labels - * and any previously found dname. - */ - if (nlabels >= dname_labels || nlabels < domain_labels) - { - continue; - } - - /* - * We are looking for the shortest DNAME if there - * are multiple ones (which there shouldn't be). - */ - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->type != dns_rdatatype_dname) { - continue; - } - dname = name; - drdataset = rdataset; - dname_labels = nlabels; - break; - } - break; - default: - break; - } - } - - if (dname != NULL) { - aname = NULL; - ardataset = NULL; - cname = NULL; - crdataset = NULL; - } else if (aname != NULL) { - cname = NULL; - crdataset = NULL; - } - - aa = (message->flags & DNS_MESSAGEFLAG_AA); - trust = aa ? dns_trust_authanswer : dns_trust_answer; - - if (aname != NULL && type == dns_rdatatype_any) { - for (rdataset = ISC_LIST_HEAD(aname->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - dns_chkarg_t chkarg; - if (!validinanswer(rdataset, fctx)) { - return (DNS_R_FORMERR); - } - if ((fctx->type == dns_rdatatype_sig || - fctx->type == dns_rdatatype_rrsig) && - rdataset->type != fctx->type) - { - continue; - } - if ((rdataset->type == dns_rdatatype_a || - rdataset->type == dns_rdatatype_aaaa) && - !is_answeraddress_allowed(view, aname, rdataset)) - { - return (DNS_R_SERVFAIL); - } - if ((rdataset->type == dns_rdatatype_cname || - rdataset->type == dns_rdatatype_dname) && - !is_answertarget_allowed(fctx, qname, aname, - rdataset, NULL)) - { - return (DNS_R_SERVFAIL); - } - aname->attributes |= DNS_NAMEATTR_CACHE; - aname->attributes |= DNS_NAMEATTR_ANSWER; - rdataset->attributes |= DNS_RDATASETATTR_ANSWER; - rdataset->attributes |= DNS_RDATASETATTR_CACHE; - rdataset->trust = trust; - rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; - chkarg.fctx = fctx; - chkarg.rmessage = message; - (void)dns_rdataset_additionaldata(rdataset, - check_related, - &chkarg); - } - } else if (aname != NULL) { - dns_chkarg_t chkarg; - if (!validinanswer(ardataset, fctx)) - return (DNS_R_FORMERR); - if ((ardataset->type == dns_rdatatype_a || - ardataset->type == dns_rdatatype_aaaa) && - !is_answeraddress_allowed(view, aname, ardataset)) { - return (DNS_R_SERVFAIL); - } - if ((ardataset->type == dns_rdatatype_cname || - ardataset->type == dns_rdatatype_dname) && - type != ardataset->type && - type != dns_rdatatype_any && - !is_answertarget_allowed(fctx, qname, aname, ardataset, - NULL)) - { - return (DNS_R_SERVFAIL); - } - aname->attributes |= DNS_NAMEATTR_CACHE; - aname->attributes |= DNS_NAMEATTR_ANSWER; - ardataset->attributes |= DNS_RDATASETATTR_ANSWER; - ardataset->attributes |= DNS_RDATASETATTR_CACHE; - ardataset->trust = trust; - chkarg.fctx = fctx; - chkarg.rmessage = message; - (void)dns_rdataset_additionaldata(ardataset, check_related, - &chkarg); - for (sigrdataset = ISC_LIST_HEAD(aname->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { - if (!validinanswer(sigrdataset, fctx)) - return (DNS_R_FORMERR); - if (sigrdataset->type != dns_rdatatype_rrsig || - sigrdataset->covers != type) - continue; - sigrdataset->attributes |= DNS_RDATASETATTR_ANSWERSIG; - sigrdataset->attributes |= DNS_RDATASETATTR_CACHE; - sigrdataset->trust = trust; - break; - } - } else if (cname != NULL) { - if (!validinanswer(crdataset, fctx)) { - return (DNS_R_FORMERR); - } - if (type == dns_rdatatype_rrsig || type == dns_rdatatype_key || - type == dns_rdatatype_nsec) - { - char buf[DNS_RDATATYPE_FORMATSIZE]; - dns_rdatatype_format(type, buf, sizeof(buf)); - log_formerr(fctx, "CNAME response for %s RR", buf); - return (DNS_R_FORMERR); - } - if (!is_answertarget_allowed(fctx, qname, cname, crdataset, - NULL)) - { - return (DNS_R_SERVFAIL); - } - cname->attributes |= DNS_NAMEATTR_CACHE; - cname->attributes |= DNS_NAMEATTR_ANSWER; - cname->attributes |= DNS_NAMEATTR_CHAINING; - crdataset->attributes |= DNS_RDATASETATTR_ANSWER; - crdataset->attributes |= DNS_RDATASETATTR_CACHE; - crdataset->attributes |= DNS_RDATASETATTR_CHAINING; - crdataset->trust = trust; - for (sigrdataset = ISC_LIST_HEAD(cname->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) - { - if (!validinanswer(sigrdataset, fctx)) { - return (DNS_R_FORMERR); - } - if (sigrdataset->type != dns_rdatatype_rrsig || - sigrdataset->covers != dns_rdatatype_cname) - { - continue; - } - sigrdataset->attributes |= DNS_RDATASETATTR_ANSWERSIG; - sigrdataset->attributes |= DNS_RDATASETATTR_CACHE; - sigrdataset->trust = trust; - break; - } - chaining = true; - } else if (dname != NULL) { - if (!validinanswer(drdataset, fctx)) { - return (DNS_R_FORMERR); - } - if (!is_answertarget_allowed(fctx, qname, dname, drdataset, - &chaining)) { - return (DNS_R_SERVFAIL); - } - dname->attributes |= DNS_NAMEATTR_CACHE; - dname->attributes |= DNS_NAMEATTR_ANSWER; - dname->attributes |= DNS_NAMEATTR_CHAINING; - drdataset->attributes |= DNS_RDATASETATTR_ANSWER; - drdataset->attributes |= DNS_RDATASETATTR_CACHE; - drdataset->attributes |= DNS_RDATASETATTR_CHAINING; - drdataset->trust = trust; - for (sigrdataset = ISC_LIST_HEAD(dname->list); - sigrdataset != NULL; - sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) - { - if (!validinanswer(sigrdataset, fctx)) { - return (DNS_R_FORMERR); - } - if (sigrdataset->type != dns_rdatatype_rrsig || - sigrdataset->covers != dns_rdatatype_dname) - { - continue; - } - sigrdataset->attributes |= DNS_RDATASETATTR_ANSWERSIG; - sigrdataset->attributes |= DNS_RDATASETATTR_CACHE; - sigrdataset->trust = trust; - break; - } - } else { - log_formerr(fctx, "reply has no answer"); - return (DNS_R_FORMERR); - } - - /* - * This response is now potentially cacheable. - */ - FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTCACHE); - - /* - * Did chaining end before we got the final answer? - */ - if (chaining) { - return (ISC_R_SUCCESS); - } - - /* - * We didn't end with an incomplete chain, so the rcode should be - * "no error". - */ - if (message->rcode != dns_rcode_noerror) { - log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE " - "indicates error"); - return (DNS_R_FORMERR); - } - - /* - * Examine the authority section (if there is one). - * - * We expect there to be only one owner name for all the rdatasets - * in this section, and we expect that it is not external. - */ - result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - while (!done && result == ISC_R_SUCCESS) { - bool external; - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); - external = !dns_name_issubdomain(name, &fctx->domain); - if (!external) { - /* - * We expect to find NS or SIG NS rdatasets, and - * nothing else. - */ - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (rdataset->type == dns_rdatatype_ns || - (rdataset->type == dns_rdatatype_rrsig && - rdataset->covers == dns_rdatatype_ns)) { - dns_chkarg_t chkarg; - name->attributes |= - DNS_NAMEATTR_CACHE; - rdataset->attributes |= - DNS_RDATASETATTR_CACHE; - if (aa && !chaining) { - rdataset->trust = - dns_trust_authauthority; - } else { - rdataset->trust = - dns_trust_additional; - } - - if (rdataset->type == dns_rdatatype_ns) - { - ns_name = name; - ns_rdataset = rdataset; - } - /* - * Mark any additional data related - * to this rdataset. - */ - chkarg.fctx = fctx; - chkarg.rmessage = message; - (void)dns_rdataset_additionaldata( - rdataset, - check_related, - &chkarg); - done = true; - } - } - } - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - log_ns_ttl(fctx, "answer_response"); - - if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && - !dns_name_equal(ns_name, dns_rootname)) - trim_ns_ttl(fctx, ns_name, ns_rdataset); - - return (result); -} - -static void -fctx_increference(fetchctx_t *fctx) { - REQUIRE(VALID_FCTX(fctx)); - - LOCK(&fctx->res->buckets[fctx->bucketnum].lock); - fctx->references++; - UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); -} - -static bool -fctx_decreference(fetchctx_t *fctx) { - bool bucket_empty = false; - - REQUIRE(VALID_FCTX(fctx)); - - INSIST(fctx->references > 0); - fctx->references--; - if (fctx->references == 0) { - /* - * No one cares about the result of this fetch anymore. - */ - if (fctx->pending == 0 && fctx->nqueries == 0 && - ISC_LIST_EMPTY(fctx->validators) && fctx->shuttingdown) - { - /* - * This fctx is already shutdown; we were just - * waiting for the last reference to go away. - */ - bucket_empty = fctx_unlink(fctx); - fctx_destroy(fctx); - } else { - /* - * Initiate shutdown. - */ - fctx_shutdown(fctx); - } - } - return (bucket_empty); -} - -static void -resume_dslookup(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *fevent; - dns_resolver_t *res; - fetchctx_t *fctx; - isc_result_t result; - bool bucket_empty; - bool locked = false; - unsigned int bucketnum; - dns_rdataset_t nameservers; - dns_fixedname_t fixed; - dns_name_t *domain; - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - fevent = (dns_fetchevent_t *)event; - fctx = event->ev_arg; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - - UNUSED(task); - FCTXTRACE("resume_dslookup"); - - if (fevent->node != NULL) - dns_db_detachnode(fevent->db, &fevent->node); - if (fevent->db != NULL) - dns_db_detach(&fevent->db); - - dns_rdataset_init(&nameservers); - - bucketnum = fctx->bucketnum; - - /* - * Note: fevent->rdataset must be disassociated and - * isc_event_free(&event) be called before resuming - * processing of the 'fctx' to prevent use-after-free. - * 'fevent' is set to NULL so as to not have a dangling - * pointer. - */ - if (fevent->result == ISC_R_CANCELED) { - if (dns_rdataset_isassociated(fevent->rdataset)) { - dns_rdataset_disassociate(fevent->rdataset); - } - fevent = NULL; - isc_event_free(&event); - - dns_resolver_destroyfetch(&fctx->nsfetch); - fctx_done(fctx, ISC_R_CANCELED, __LINE__); - } else if (fevent->result == ISC_R_SUCCESS) { - FCTXTRACE("resuming DS lookup"); - - dns_resolver_destroyfetch(&fctx->nsfetch); - if (dns_rdataset_isassociated(&fctx->nameservers)) { - dns_rdataset_disassociate(&fctx->nameservers); - } - dns_rdataset_clone(fevent->rdataset, &fctx->nameservers); - fctx->ns_ttl = fctx->nameservers.ttl; - fctx->ns_ttl_ok = true; - log_ns_ttl(fctx, "resume_dslookup"); - - if (dns_rdataset_isassociated(fevent->rdataset)) { - dns_rdataset_disassociate(fevent->rdataset); - } - fevent = NULL; - isc_event_free(&event); - - fcount_decr(fctx); - dns_name_free(&fctx->domain, fctx->mctx); - dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto cleanup; - } - result = fcount_incr(fctx, true); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto cleanup; - } - /* - * Try again. - */ - fctx_try(fctx, true, false); - } else { - unsigned int n; - dns_rdataset_t *nsrdataset = NULL; - - /* - * Retrieve state from fctx->nsfetch before we destroy it. - */ - dns_fixedname_init(&fixed); - domain = dns_fixedname_name(&fixed); - dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL); - if (dns_name_equal(&fctx->nsname, domain)) { - if (dns_rdataset_isassociated(fevent->rdataset)) { - dns_rdataset_disassociate(fevent->rdataset); - } - fevent = NULL; - isc_event_free(&event); - - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - dns_resolver_destroyfetch(&fctx->nsfetch); - goto cleanup; - } - if (dns_rdataset_isassociated( - &fctx->nsfetch->private->nameservers)) { - dns_rdataset_clone( - &fctx->nsfetch->private->nameservers, - &nameservers); - nsrdataset = &nameservers; - } else - domain = NULL; - dns_resolver_destroyfetch(&fctx->nsfetch); - n = dns_name_countlabels(&fctx->nsname); - dns_name_getlabelsequence(&fctx->nsname, 1, n - 1, - &fctx->nsname); - - if (dns_rdataset_isassociated(fevent->rdataset)) - dns_rdataset_disassociate(fevent->rdataset); - fevent = NULL; - isc_event_free(&event); - - FCTXTRACE("continuing to look for parent's NS records"); - - result = dns_resolver_createfetch(fctx->res, &fctx->nsname, - dns_rdatatype_ns, domain, - nsrdataset, NULL, - fctx->options, task, - resume_dslookup, fctx, - &fctx->nsrrset, NULL, - &fctx->nsfetch); - /* - * fevent->rdataset (a.k.a. fctx->nsrrset) must not be - * accessed below this point to prevent races with - * another thread concurrently processing the fetch. - */ - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, result, __LINE__); - } else { - LOCK(&res->buckets[bucketnum].lock); - locked = true; - fctx->references++; - } - } - - cleanup: - INSIST(event == NULL); - INSIST(fevent == NULL); - if (dns_rdataset_isassociated(&nameservers)) - dns_rdataset_disassociate(&nameservers); - if (!locked) - LOCK(&res->buckets[bucketnum].lock); - bucket_empty = fctx_decreference(fctx); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) - empty_bucket(res); -} - -static inline void -checknamessection(dns_message_t *message, dns_section_t section) { - isc_result_t result; - dns_name_t *name; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t *rdataset; - - for (result = dns_message_firstname(message, section); - result == ISC_R_SUCCESS; - result = dns_message_nextname(message, section)) - { - name = NULL; - dns_message_currentname(message, section, &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdataset_current(rdataset, &rdata); - if (!dns_rdata_checkowner(name, rdata.rdclass, - rdata.type, - false) || - !dns_rdata_checknames(&rdata, name, NULL)) - { - rdataset->attributes |= - DNS_RDATASETATTR_CHECKNAMES; - } - dns_rdata_reset(&rdata); - } - } - } -} - -static void -checknames(dns_message_t *message) { - - checknamessection(message, DNS_SECTION_ANSWER); - checknamessection(message, DNS_SECTION_AUTHORITY); - checknamessection(message, DNS_SECTION_ADDITIONAL); -} - -/* - * Log server NSID at log level 'level' - */ -static void -log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, - int level, isc_mem_t *mctx) -{ - static const char hex[17] = "0123456789abcdef"; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - uint16_t buflen, i; - unsigned char *p, *nsid; - unsigned char *buf = NULL, *pbuf = NULL; - - /* Allocate buffer for storing hex version of the NSID */ - buflen = (uint16_t)nsid_len * 2 + 1; - buf = isc_mem_get(mctx, buflen); - if (buf == NULL) - goto cleanup; - pbuf = isc_mem_get(mctx, nsid_len + 1); - if (pbuf == NULL) - goto cleanup; - - /* Convert to hex */ - p = buf; - nsid = isc_buffer_current(opt); - for (i = 0; i < nsid_len; i++) { - *p++ = hex[(nsid[i] >> 4) & 0xf]; - *p++ = hex[nsid[i] & 0xf]; - } - *p = '\0'; - - /* Make printable version */ - p = pbuf; - for (i = 0; i < nsid_len; i++) { - if (isprint(nsid[i])) - *p++ = nsid[i]; - else - *p++ = '.'; - } - *p = '\0'; - - isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, - sizeof(addrbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, level, - "received NSID %s (\"%s\") from %s", buf, pbuf, addrbuf); - cleanup: - if (pbuf != NULL) - isc_mem_put(mctx, pbuf, nsid_len + 1); - if (buf != NULL) - isc_mem_put(mctx, buf, buflen); -} - -static bool -iscname(fetchctx_t *fctx, dns_message_t *rmessage) { - isc_result_t result; - - result = dns_message_findname(rmessage, DNS_SECTION_ANSWER, - &fctx->name, dns_rdatatype_cname, 0, - NULL, NULL); - return (result == ISC_R_SUCCESS ? true : false); -} - -static bool -betterreferral(fetchctx_t *fctx, dns_message_t *message) { - isc_result_t result; - dns_name_t *name; - dns_rdataset_t *rdataset; - - for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) { - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); - if (!isstrictsubdomain(name, &fctx->domain)) - continue; - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - if (rdataset->type == dns_rdatatype_ns) - return (true); - } - return (false); -} - -static void -process_opt(resquery_t *query, dns_rdataset_t *opt) { - dns_rdata_t rdata; - isc_buffer_t optbuf; - isc_result_t result; - uint16_t optcode; - uint16_t optlen; - unsigned char *optvalue; - dns_adbaddrinfo_t *addrinfo; - unsigned char cookie[CLIENT_COOKIE_SIZE]; - bool seen_cookie = false; - bool seen_nsid = false; - - result = dns_rdataset_first(opt); - if (result == ISC_R_SUCCESS) { - dns_rdata_init(&rdata); - dns_rdataset_current(opt, &rdata); - isc_buffer_init(&optbuf, rdata.data, rdata.length); - isc_buffer_add(&optbuf, rdata.length); - while (isc_buffer_remaininglength(&optbuf) >= 4) { - optcode = isc_buffer_getuint16(&optbuf); - optlen = isc_buffer_getuint16(&optbuf); - INSIST(optlen <= isc_buffer_remaininglength(&optbuf)); - switch (optcode) { - case DNS_OPT_NSID: - if (!seen_nsid && - query->options & DNS_FETCHOPT_WANTNSID) - log_nsid(&optbuf, optlen, query, - ISC_LOG_DEBUG(3), - query->fctx->res->mctx); - isc_buffer_forward(&optbuf, optlen); - seen_nsid = true; - break; - case DNS_OPT_COOKIE: - /* - * Only process the first cookie option. - */ - if (seen_cookie) { - isc_buffer_forward(&optbuf, optlen); - break; - } - optvalue = isc_buffer_current(&optbuf); - compute_cc(query, cookie, sizeof(cookie)); - INSIST(query->rmessage->cc_bad == 0 && - query->rmessage->cc_ok == 0); - if (optlen >= CLIENT_COOKIE_SIZE && - memcmp(cookie, optvalue, - CLIENT_COOKIE_SIZE) == 0) - { - query->rmessage->cc_ok = 1; - inc_stats(query->fctx->res, - dns_resstatscounter_cookieok); - addrinfo = query->addrinfo; - dns_adb_setcookie(query->fctx->adb, - addrinfo, optvalue, - optlen); - } else - query->rmessage->cc_bad = 1; - isc_buffer_forward(&optbuf, optlen); - inc_stats(query->fctx->res, - dns_resstatscounter_cookiein); - seen_cookie = true; - break; - default: - isc_buffer_forward(&optbuf, optlen); - break; - } - } - INSIST(isc_buffer_remaininglength(&optbuf) == 0U); - } -} - -static void -resquery_response(isc_task_t *task, isc_event_t *event) { - isc_result_t result = ISC_R_SUCCESS; - resquery_t *query = event->ev_arg; - dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; - bool keep_trying, get_nameservers, resend, nextitem; - bool truncated; - dns_message_t *rmessage = NULL; - dns_rdataset_t *opt; - fetchctx_t *fctx; - dns_name_t *fname; - dns_fixedname_t foundname; - isc_stdtime_t now; - isc_time_t tnow, *finish; - dns_adbaddrinfo_t *addrinfo; - unsigned int options; - unsigned int findoptions; - isc_result_t broken_server; - badnstype_t broken_type = badns_response; - bool no_response; - unsigned int bucketnum; - dns_resolver_t *res; - bool bucket_empty; -#ifdef HAVE_DNSTAP - isc_socket_t *sock = NULL; - isc_sockaddr_t localaddr, *la = NULL; - unsigned char zone[DNS_NAME_MAXWIRE]; - dns_dtmsgtype_t dtmsgtype; - dns_compress_t cctx; - isc_region_t zr; - isc_buffer_t zb; -#endif /* HAVE_DNSTAP */ - - REQUIRE(VALID_QUERY(query)); - fctx = query->fctx; - options = query->options; - REQUIRE(VALID_FCTX(fctx)); - REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); - dns_message_attach(query->rmessage, &rmessage); - - QTRACE("response"); - - res = fctx->res; - if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET) - inc_stats(res, dns_resstatscounter_responsev4); - else - inc_stats(res, dns_resstatscounter_responsev6); - - (void)isc_timer_touch(fctx->timer); - - keep_trying = false; - broken_server = ISC_R_SUCCESS; - get_nameservers = false; - resend = false; - nextitem = false; - truncated = false; - finish = NULL; - no_response = false; - - if (res->exiting) { - result = ISC_R_SHUTTINGDOWN; - FCTXTRACE("resolver shutting down"); - goto done; - } - - fctx->timeouts = 0; - fctx->timeout = false; - fctx->addrinfo = query->addrinfo; - - /* - * XXXRTH We should really get the current time just once. We - * need a routine to convert from an isc_time_t to an - * isc_stdtime_t. - */ - TIME_NOW(&tnow); - finish = &tnow; - isc_stdtime_get(&now); - - /* - * Did the dispatcher have a problem? - */ - if (devent->result != ISC_R_SUCCESS) { - if (devent->result == ISC_R_EOF && - (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - /* - * The problem might be that they - * don't understand EDNS0. Turn it - * off and try again. - */ - options |= DNS_FETCHOPT_NOEDNS0; - resend = true; - add_bad_edns(fctx, &query->addrinfo->sockaddr); - } else { - /* - * There's no hope for this query. - */ - keep_trying = true; - - /* - * If this is a network error on an exclusive query - * socket, mark the server as bad so that we won't try - * it for this fetch again. Also adjust finish and - * no_response so that we penalize this address in SRTT - * adjustment later. - */ - if (query->exclusivesocket && - (devent->result == ISC_R_HOSTUNREACH || - devent->result == ISC_R_NETUNREACH || - devent->result == ISC_R_CONNREFUSED || - devent->result == ISC_R_CANCELED)) { - broken_server = devent->result; - broken_type = badns_unreachable; - finish = NULL; - no_response = true; - } - } - FCTXTRACE3("dispatcher failure", devent->result); - goto done; - } - - if (query->tsig != NULL) { - result = dns_message_setquerytsig(rmessage, query->tsig); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("unable to set query tsig", result); - goto done; - } - } - - if (query->tsigkey) { - result = dns_message_settsigkey(rmessage, query->tsigkey); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("unable to set tsig key", result); - goto done; - } - } - - dns_message_setclass(rmessage, res->rdclass); - - if ((options & DNS_FETCHOPT_TCP) == 0) { - if ((options & DNS_FETCHOPT_NOEDNS0) == 0) - dns_adb_setudpsize(fctx->adb, query->addrinfo, - isc_buffer_usedlength(&devent->buffer)); - else - dns_adb_plainresponse(fctx->adb, query->addrinfo); - } - result = dns_message_parse(rmessage, &devent->buffer, 0); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("message failed to parse", result); - switch (result) { - case ISC_R_UNEXPECTEDEND: - if (!rmessage->question_ok || - (rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 || - (options & DNS_FETCHOPT_TCP) != 0) { - /* - * Either the rmessage ended prematurely, - * and/or wasn't marked as being truncated, - * and/or this is a response to a query we - * sent over TCP. In all of these cases, - * something is wrong with the remote - * server and we don't want to retry using - * TCP. - */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) - == 0) { - /* - * The problem might be that they - * don't understand EDNS0. Turn it - * off and try again. - */ - options |= DNS_FETCHOPT_NOEDNS0; - resend = true; - add_bad_edns(fctx, - &query->addrinfo->sockaddr); - inc_stats(res, - dns_resstatscounter_edns0fail); - } else { - broken_server = result; - keep_trying = true; - } - goto done; - } - /* - * We defer retrying via TCP for a bit so we can - * check out this rmessage further. - */ - truncated = true; - break; - case DNS_R_FORMERR: - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - /* - * The problem might be that they - * don't understand EDNS0. Turn it - * off and try again. - */ - options |= DNS_FETCHOPT_NOEDNS0; - resend = true; - add_bad_edns(fctx, &query->addrinfo->sockaddr); - inc_stats(res, dns_resstatscounter_edns0fail); - } else { - broken_server = DNS_R_UNEXPECTEDRCODE; - keep_trying = true; - } - goto done; - default: - /* - * Something bad has happened. - */ - goto done; - } - } - - /* - * Log the incoming packet. - */ - dns_message_logfmtpacket2(rmessage, "received packet from", - &query->addrinfo->sockaddr, - DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_PACKETS, - &dns_master_style_comment, - ISC_LOG_DEBUG(10), res->mctx); - -#ifdef HAVE_DNSTAP - /* - * Log the response via dnstap. - */ - memset(&zr, 0, sizeof(zr)); - result = dns_compress_init(&cctx, -1, res->mctx); - if (result == ISC_R_SUCCESS) { - isc_buffer_init(&zb, zone, sizeof(zone)); - dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE); - result = dns_name_towire(&fctx->domain, &cctx, &zb); - if (result == ISC_R_SUCCESS) - isc_buffer_usedregion(&zb, &zr); - dns_compress_invalidate(&cctx); - } - - if ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0) { - dtmsgtype = DNS_DTTYPE_FR; - } else { - dtmsgtype = DNS_DTTYPE_RR; - } - - if (query->exclusivesocket) { - sock = dns_dispatch_getentrysocket(query->dispentry); - } else { - sock = dns_dispatch_getsocket(query->dispatch); - } - - if (sock != NULL) { - result = isc_socket_getsockname(sock, &localaddr); - if (result == ISC_R_SUCCESS) { - la = &localaddr; - } - } - - dns_dt_send(res->view, dtmsgtype, la, &query->addrinfo->sockaddr, - (query->options & DNS_FETCHOPT_TCP), - &zr, &query->start, NULL, &devent->buffer); -#endif /* HAVE_DNSTAP */ - - if (rmessage->rdclass != res->rdclass) { - resend = true; - FCTXTRACE("bad class"); - goto done; - } - - /* - * Process receive opt record. - */ - opt = dns_message_getopt(rmessage); - if (opt != NULL) - process_opt(query, opt); - - if (rmessage->cc_bad && (options & DNS_FETCHOPT_TCP) == 0) { - /* - * If the COOKIE is bad, assume it is an attack and - * keep listening for a good answer. - */ - nextitem = true; - if (isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&query->addrinfo->sockaddr, - addrbuf, sizeof(addrbuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "bad cookie from %s", addrbuf); - } - goto done; - } - - /* - * Is the question the same as the one we asked? - * NOERROR/NXDOMAIN/YXDOMAIN/REFUSED/SERVFAIL/BADCOOKIE must have - * the same question. - * FORMERR/NOTIMP if they have a question section then it must match. - */ - switch (rmessage->rcode) { - case dns_rcode_notimp: - case dns_rcode_formerr: - if (rmessage->counts[DNS_SECTION_QUESTION] == 0) - break; - /* FALLTHROUGH */ - case dns_rcode_nxrrset: /* Not expected. */ - case dns_rcode_badcookie: - case dns_rcode_noerror: - case dns_rcode_nxdomain: - case dns_rcode_yxdomain: - case dns_rcode_refused: - case dns_rcode_servfail: - default: - result = same_question(fctx, rmessage); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("response did not match question", result); - nextitem = true; - goto done; - } - break; - } - - /* - * If the rmessage is signed, check the signature. If not, this - * returns success anyway. - */ - result = dns_message_checksig(rmessage, res->view); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("signature check failed", result); - if (result == DNS_R_UNEXPECTEDTSIG || - result == DNS_R_EXPECTEDTSIG) { - nextitem = true; - } - goto done; - } - - /* - * The dispatcher should ensure we only get responses with QR set. - */ - INSIST((rmessage->flags & DNS_MESSAGEFLAG_QR) != 0); - /* - * INSIST() that the rmessage comes from the place we sent it to, - * since the dispatch code should ensure this. - * - * INSIST() that the rmessage id is correct (this should also be - * ensured by the dispatch code). - */ - - /* - * If we have had a server cookie and don't get one retry over TCP. - * This may be a misconfigured anycast server or an attempt to send - * a spoofed response. Skip if we have a valid tsig. - */ - if (dns_message_gettsig(rmessage, NULL) == NULL && - !rmessage->cc_ok && !rmessage->cc_bad && - (options & DNS_FETCHOPT_TCP) == 0) - { - unsigned char cookie[COOKIE_BUFFER_SIZE]; - if (dns_adb_getcookie(fctx->adb, query->addrinfo, cookie, - sizeof(cookie)) > CLIENT_COOKIE_SIZE) - { - if (isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&query->addrinfo->sockaddr, - addrbuf, sizeof(addrbuf)); - isc_log_write( - dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "missing expected cookie from %s", - addrbuf); - } - options |= DNS_FETCHOPT_TCP; - resend = true; - goto done; - } - /* - * XXXMPA When support for DNS COOKIE becomes ubiquitous, fall - * back to TCP for all non-COOKIE responses. - */ - } - - /* - * We have an affirmative response to the query and we have - * previously got a response from this server which indicated - * EDNS may not be supported so we can now cache the lack of - * EDNS support. - */ - if (opt == NULL && !EDNSOK(query->addrinfo) && - (rmessage->rcode == dns_rcode_noerror || - rmessage->rcode == dns_rcode_nxdomain || - rmessage->rcode == dns_rcode_refused || - rmessage->rcode == dns_rcode_yxdomain) && - bad_edns(fctx, &query->addrinfo->sockaddr)) { - dns_message_logpacket2(rmessage, - "received packet (bad edns) from", - &query->addrinfo->sockaddr, - DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, - ISC_LOG_DEBUG(3), - res->mctx); - dns_adb_changeflags(fctx->adb, query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); - } else if (opt == NULL && (rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 && - !EDNSOK(query->addrinfo) && - (rmessage->rcode == dns_rcode_noerror || - rmessage->rcode == dns_rcode_nxdomain) && - (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - /* - * We didn't get a OPT record in response to a EDNS query. - * - * Old versions of named incorrectly drop the OPT record - * when there is a signed, truncated response so we check - * that TC is not set. - * - * Record that the server is not talking EDNS. While this - * should be safe to do for any rcode we limit it to NOERROR - * and NXDOMAIN. - */ - dns_message_logpacket2(rmessage, "received packet (no opt) from", - &query->addrinfo->sockaddr, - DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, - ISC_LOG_DEBUG(3), res->mctx); - dns_adb_changeflags(fctx->adb, query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); - } - - /* - * If we get a non error EDNS response record the fact so we - * won't fallback to plain DNS in the future for this server. - */ - if (opt != NULL && !EDNSOK(query->addrinfo) && - (query->options & DNS_FETCHOPT_NOEDNS0) == 0 && - (rmessage->rcode == dns_rcode_noerror || - rmessage->rcode == dns_rcode_nxdomain || - rmessage->rcode == dns_rcode_refused || - rmessage->rcode == dns_rcode_yxdomain)) { - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_EDNSOK, - FCTX_ADDRINFO_EDNSOK); - } - - /* - * Deal with truncated responses by retrying using TCP. - */ - if ((rmessage->flags & DNS_MESSAGEFLAG_TC) != 0) - truncated = true; - - if (truncated) { - inc_stats(res, dns_resstatscounter_truncated); - if ((options & DNS_FETCHOPT_TCP) != 0) { - broken_server = DNS_R_TRUNCATEDTCP; - keep_trying = true; - } else { - options |= DNS_FETCHOPT_TCP; - resend = true; - } - FCTXTRACE3("message truncated", result); - goto done; - } - - /* - * Is it a query response? - */ - if (rmessage->opcode != dns_opcode_query) { - /* XXXRTH Log */ - broken_server = DNS_R_UNEXPECTEDOPCODE; - keep_trying = true; - FCTXTRACE("invalid rmessage opcode"); - goto done; - } - - /* - * Update statistics about erroneous responses. - */ - if (rmessage->rcode != dns_rcode_noerror) { - switch (rmessage->rcode) { - case dns_rcode_nxdomain: - inc_stats(res, dns_resstatscounter_nxdomain); - break; - case dns_rcode_servfail: - inc_stats(res, dns_resstatscounter_servfail); - break; - case dns_rcode_formerr: - inc_stats(res, dns_resstatscounter_formerr); - break; - case dns_rcode_refused: - inc_stats(res, dns_resstatscounter_refused); - break; - case dns_rcode_badvers: - inc_stats(res, dns_resstatscounter_badvers); - break; - case dns_rcode_badcookie: - inc_stats(res, dns_resstatscounter_badcookie); - break; - default: - inc_stats(res, dns_resstatscounter_othererror); - break; - } - } - - /* - * Is the remote server broken, or does it dislike us? - */ - if (rmessage->rcode != dns_rcode_noerror && - rmessage->rcode != dns_rcode_yxdomain && - rmessage->rcode != dns_rcode_nxdomain) { - isc_buffer_t b; - char code[64]; - unsigned char cookie[COOKIE_BUFFER_SIZE]; - - /* - * Some servers do not ignore unknown EDNS options. - */ - if (!NOCOOKIE(query->addrinfo) && - (rmessage->rcode == dns_rcode_formerr || - rmessage->rcode == dns_rcode_notimp || - rmessage->rcode == dns_rcode_refused) && - dns_adb_getcookie(fctx->adb, query->addrinfo, - cookie, sizeof(cookie)) == 0U) { - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_NOCOOKIE, - FCTX_ADDRINFO_NOCOOKIE); - resend = true; - } else if ((rmessage->rcode == dns_rcode_formerr || - rmessage->rcode == dns_rcode_notimp || - (rmessage->rcode == dns_rcode_servfail && - dns_message_getopt(rmessage) == NULL)) && - (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { - /* - * It's very likely they don't like EDNS0. - * If the response code is SERVFAIL, also check if the - * response contains an OPT RR and don't cache the - * failure since it can be returned for various other - * reasons. - * - * XXXRTH We should check if the question - * we're asking requires EDNS0, and - * if so, we should bail out. - */ - options |= DNS_FETCHOPT_NOEDNS0; - resend = true; - /* - * Remember that they may not like EDNS0. - */ - add_bad_edns(fctx, &query->addrinfo->sockaddr); - inc_stats(res, dns_resstatscounter_edns0fail); - } else if (rmessage->rcode == dns_rcode_formerr) { - if (ISFORWARDER(query->addrinfo)) { - /* - * This forwarder doesn't understand us, - * but other forwarders might. Keep trying. - */ - broken_server = DNS_R_REMOTEFORMERR; - keep_trying = true; - } else { - /* - * The server doesn't understand us. Since - * all servers for a zone need similar - * capabilities, we assume that we will get - * FORMERR from all servers, and thus we - * cannot make any more progress with this - * fetch. - */ - log_formerr(fctx, "server sent FORMERR"); - result = DNS_R_FORMERR; - } - } else if (rmessage->rcode == dns_rcode_badvers) { - unsigned int version; - bool setnocookie = false; -#if DNS_EDNS_VERSION > 0 - unsigned int flags, mask; -#endif - - /* - * Some servers return BADVERS to unknown - * EDNS options. This cannot be long term - * strategy. Do not disable COOKIE if we have - * already have received a COOKIE from this - * server. - */ - if (dns_adb_getcookie(fctx->adb, query->addrinfo, - cookie, sizeof(cookie)) == 0U) { - if (!NOCOOKIE(query->addrinfo)) - setnocookie = true; - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_NOCOOKIE, - FCTX_ADDRINFO_NOCOOKIE); - } - - INSIST(opt != NULL); - version = (opt->ttl >> 16) & 0xff; -#if DNS_EDNS_VERSION > 0 - flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) | - DNS_FETCHOPT_EDNSVERSIONSET; - mask = DNS_FETCHOPT_EDNSVERSIONMASK | - DNS_FETCHOPT_EDNSVERSIONSET; -#endif - - /* - * Record that we got a good EDNS response. - */ - if (query->ednsversion > (int)version && - !EDNSOK(query->addrinfo)) { - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_EDNSOK, - FCTX_ADDRINFO_EDNSOK); - } - - /* - * RFC 2671 was not clear that unknown options should - * be ignored. RFC 6891 is clear that that they - * should be ignored. If we are supporting the - * experimental EDNS > 0 then perform strict - * version checking of badvers responses. We won't - * be sending COOKIE etc. in that case. - */ -#if DNS_EDNS_VERSION > 0 - if ((int)version < query->ednsversion) { - dns_adb_changeflags(fctx->adb, query->addrinfo, - flags, mask); - resend = true; - } else { - broken_server = DNS_R_BADVERS; - keep_trying = true; - } -#else - if (version == 0U && setnocookie) { - resend = true; - } else { - broken_server = DNS_R_BADVERS; - keep_trying = true; - } -#endif - } else if (rmessage->rcode == dns_rcode_badcookie && - rmessage->cc_ok) { - /* - * We have recorded the new cookie. - */ - if (BADCOOKIE(query->addrinfo)) - query->options |= DNS_FETCHOPT_TCP; - query->addrinfo->flags |= FCTX_ADDRINFO_BADCOOKIE; - resend = true; - } else { - /* - * XXXRTH log. - */ - broken_server = DNS_R_UNEXPECTEDRCODE; - INSIST(broken_server != ISC_R_SUCCESS); - keep_trying = true; - } - - isc_buffer_init(&b, code, sizeof(code) - 1); - dns_rcode_totext(rmessage->rcode, &b); - code[isc_buffer_usedlength(&b)] = '\0'; - FCTXTRACE2("remote server broken: returned ", code); - goto done; - } - - /* - * Is the server lame? - */ - if (res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) && - is_lame(fctx, rmessage)) { - inc_stats(res, dns_resstatscounter_lame); - log_lame(fctx, query->addrinfo); - result = dns_adb_marklame(fctx->adb, query->addrinfo, - &fctx->name, fctx->type, - now + res->lame_ttl); - if (result != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR, - "could not mark server as lame: %s", - isc_result_totext(result)); - broken_server = DNS_R_LAME; - keep_trying = true; - FCTXTRACE("lame server"); - goto done; - } - - /* - * Enforce delegations only zones like NET and COM. - */ - if (!ISFORWARDER(query->addrinfo) && - dns_view_isdelegationonly(res->view, &fctx->domain) && - !dns_name_equal(&fctx->domain, &fctx->name) && - fix_mustbedelegationornxdomain(rmessage, fctx)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char domainbuf[DNS_NAME_FORMATSIZE]; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - char classbuf[64]; - char typebuf[64]; - - dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); - dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); - dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(res->rdclass, classbuf, - sizeof(classbuf)); - isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, - sizeof(addrbuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "enforced delegation-only for '%s' (%s/%s/%s) " - "from %s", - domainbuf, namebuf, typebuf, classbuf, addrbuf); - } - - if ((res->options & DNS_RESOLVER_CHECKNAMES) != 0) - checknames(rmessage); - - /* - * Clear cache bits. - */ - FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE); - - /* - * Did we get any answers? - */ - if (rmessage->counts[DNS_SECTION_ANSWER] > 0 && - (rmessage->rcode == dns_rcode_noerror || - rmessage->rcode == dns_rcode_yxdomain || - rmessage->rcode == dns_rcode_nxdomain)) { - /* - * [normal case] - * We've got answers. If it has an authoritative answer or an - * answer from a forwarder, we're done. - */ - if ((rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 || - ISFORWARDER(query->addrinfo)) - { - result = answer_response(fctx, rmessage); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("answer_response (AA/fwd)", result); - } else if (iscname(fctx, rmessage) && - fctx->type != dns_rdatatype_any && - fctx->type != dns_rdatatype_cname) - { - /* - * A BIND8 server could return a non-authoritative - * answer when a CNAME is followed. We should treat - * it as a valid answer. - */ - result = answer_response(fctx, rmessage); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("answer_response (!ANY/!CNAME)", - result); - } else if (fctx->type != dns_rdatatype_ns && - !betterreferral(fctx, rmessage)) { - /* - * Lame response !!!. - */ - result = answer_response(fctx, rmessage); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("answer_response (!NS)", result); - } else { - if (fctx->type == dns_rdatatype_ns) { - /* - * A BIND 8 server could incorrectly return a - * non-authoritative answer to an NS query - * instead of a referral. Since this answer - * lacks the SIGs necessary to do DNSSEC - * validation, we must invoke the following - * special kludge to treat it as a referral. - */ - result = noanswer_response(fctx, - rmessage, - NULL, - LOOK_FOR_NS_IN_ANSWER); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("noanswer_response (NS)", - result); - } else { - /* - * Some other servers may still somehow include - * an answer when it should return a referral - * with an empty answer. Check to see if we can - * treat this as a referral by ignoring the - * answer. Further more, there may be an - * implementation that moves A/AAAA glue records - * to the answer section for that type of - * delegation when the query is for that glue - * record. LOOK_FOR_GLUE_IN_ANSWER will handle - * such a corner case. - */ - result = noanswer_response(fctx, - rmessage, - NULL, - LOOK_FOR_GLUE_IN_ANSWER); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("noanswer_response", result); - } - if (result != DNS_R_DELEGATION) { - /* - * At this point, AA is not set, the response - * is not a referral, and the server is not a - * forwarder. It is technically lame and it's - * easier to treat it as such than to figure out - * some more elaborate course of action. - */ - broken_server = DNS_R_LAME; - keep_trying = true; - goto done; - } - goto force_referral; - } - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_FORMERR) - keep_trying = true; - goto done; - } - } else if (rmessage->counts[DNS_SECTION_AUTHORITY] > 0 || - rmessage->rcode == dns_rcode_noerror || - rmessage->rcode == dns_rcode_nxdomain) { - /* - * NXDOMAIN, NXRDATASET, or referral. - */ - result = noanswer_response(fctx, rmessage, NULL, 0); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_CHASEDSSERVERS: - break; - case DNS_R_DELEGATION: - force_referral: - /* - * We don't have the answer, but we know a better - * place to look. - */ - get_nameservers = true; - keep_trying = true; - /* - * We have a new set of name servers, and it - * has not experienced any restarts yet. - */ - fctx->restarts = 0; - - /* - * Update local statistics counters collected for each - * new zone. - */ - fctx->referrals++; - fctx->querysent = 0; - fctx->lamecount = 0; - fctx->quotacount = 0; - fctx->neterr = 0; - fctx->badresp = 0; - fctx->adberr = 0; - - result = ISC_R_SUCCESS; - break; - default: - /* - * Something has gone wrong. - */ - if (result == DNS_R_FORMERR) - keep_trying = true; - FCTXTRACE3("noanswer_response", result); - goto done; - } - } else { - /* - * The server is insane. - */ - /* XXXRTH Log */ - broken_server = DNS_R_UNEXPECTEDRCODE; - keep_trying = true; - FCTXTRACE("broken server: unexpected rcode"); - goto done; - } - - /* - * Follow additional section data chains. - */ - chase_additional(fctx, rmessage); - - /* - * Cache the cacheable parts of the rmessage. This may also cause - * work to be queued to the DNSSEC validator. - */ - if (WANTCACHE(fctx)) { - result = cache_message(fctx, rmessage, query->addrinfo, - now); - if (result != ISC_R_SUCCESS) { - FCTXTRACE3("cache_message complete", result); - goto done; - } - } - - /* - * Ncache the negatively cacheable parts of the rmessage. This may - * also cause work to be queued to the DNSSEC validator. - */ - if (WANTNCACHE(fctx)) { - dns_rdatatype_t covers; - - /* - * Cache DS NXDOMAIN separately to other types. - */ - if (rmessage->rcode == dns_rcode_nxdomain && - fctx->type != dns_rdatatype_ds) - covers = dns_rdatatype_any; - else - covers = fctx->type; - - /* - * Cache any negative cache entries in the rmessage. - */ - result = ncache_message(fctx, rmessage, query->addrinfo, covers, now); - if (result != ISC_R_SUCCESS) - FCTXTRACE3("ncache_message complete", result); - } - - done: - /* - * Remember the query's addrinfo, in case we need to mark the - * server as broken. - */ - addrinfo = query->addrinfo; - - FCTXTRACE4("query canceled in response(); ", - no_response ? "no response" : "responding", - result); - - /* - * Cancel the query. - * - * XXXRTH Don't cancel the query if waiting for validation? - */ - if (!nextitem) - fctx_cancelquery(&query, &devent, finish, - no_response, false); - -#ifdef ENABLE_AFL - if (dns_fuzzing_resolver && (keep_trying || resend)) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto cleanup_rmessage; - } else -#endif - if (keep_trying) { - if (result == DNS_R_FORMERR) - broken_server = DNS_R_FORMERR; - if (broken_server != ISC_R_SUCCESS) { - /* - * Add this server to the list of bad servers for - * this fctx. - */ - add_bad(fctx, rmessage, addrinfo, - broken_server, broken_type); - } - - if (get_nameservers) { - dns_name_t *name; - fname = dns_fixedname_initname(&foundname); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto detach_rmessage; - } - findoptions = 0; - if (dns_rdatatype_atparent(fctx->type)) - findoptions |= DNS_DBFIND_NOEXACT; - if ((options & DNS_FETCHOPT_UNSHARED) == 0) - name = &fctx->name; - else - name = &fctx->domain; - result = dns_view_findzonecut(res->view, - name, fname, - now, findoptions, - true, - &fctx->nameservers, - NULL); - if (result != ISC_R_SUCCESS) { - FCTXTRACE("couldn't find a zonecut"); - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto detach_rmessage; - } - if (!dns_name_issubdomain(fname, &fctx->domain)) { - /* - * The best nameservers are now above our - * QDOMAIN. - */ - FCTXTRACE("nameservers now above QDOMAIN"); - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto detach_rmessage; - } - - fcount_decr(fctx); - dns_name_free(&fctx->domain, fctx->mctx); - dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(fname, fctx->mctx, &fctx->domain); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto detach_rmessage; - } - result = fcount_incr(fctx, true); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); - goto detach_rmessage; - } - fctx->ns_ttl = fctx->nameservers.ttl; - fctx->ns_ttl_ok = true; - fctx_cancelqueries(fctx, true, false); - fctx_cleanupfinds(fctx); - fctx_cleanupaltfinds(fctx); - fctx_cleanupforwaddrs(fctx); - fctx_cleanupaltaddrs(fctx); - } - /* - * Try again. - */ - fctx_try(fctx, !get_nameservers, false); - } else if (resend) { - /* - * Resend (probably with changed options). - */ - FCTXTRACE("resend"); - inc_stats(res, dns_resstatscounter_retry); - bucketnum = fctx->bucketnum; - fctx_increference(fctx); - result = fctx_query(fctx, addrinfo, options); - if (result != ISC_R_SUCCESS) { - fctx_done(fctx, result, __LINE__); - LOCK(&res->buckets[bucketnum].lock); - bucket_empty = fctx_decreference(fctx); - UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) - empty_bucket(res); - } - } else if (nextitem) { - /* - * Wait for next item. - */ - FCTXTRACE("nextitem"); - inc_stats(fctx->res, dns_resstatscounter_nextitem); - INSIST(query->dispentry != NULL); - dns_message_reset(query->rmessage, DNS_MESSAGE_INTENTPARSE); - result = dns_dispatch_getnext(query->dispentry, &devent); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) { - /* - * All has gone well so far, but we are waiting for the - * DNSSEC validator to validate the answer. - */ - FCTXTRACE("wait for validator"); - fctx_cancelqueries(fctx, true, false); - /* - * We must not retransmit while the validator is working; - * it has references to the current rmessage. - */ - result = fctx_stopidletimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - } else if (result == DNS_R_CHASEDSSERVERS) { - unsigned int n; - add_bad(fctx, rmessage, addrinfo, result, broken_type); - fctx_cancelqueries(fctx, true, false); - fctx_cleanupfinds(fctx); - fctx_cleanupforwaddrs(fctx); - - n = dns_name_countlabels(&fctx->name); - dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname); - - FCTXTRACE("suspending DS lookup to find parent's NS records"); - - result = dns_resolver_createfetch(res, &fctx->nsname, - dns_rdatatype_ns, - NULL, NULL, NULL, - fctx->options, task, - resume_dslookup, fctx, - &fctx->nsrrset, NULL, - &fctx->nsfetch); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - else { - fctx_increference(fctx); - result = fctx_stopidletimer(fctx); - if (result != ISC_R_SUCCESS) - fctx_done(fctx, result, __LINE__); - } - } else { - /* - * We're done. - */ - fctx_done(fctx, result, __LINE__); - } -detach_rmessage: - dns_message_detach(&rmessage); -} - -/*** - *** Resolver Methods - ***/ -static void -destroy(dns_resolver_t *res) { - unsigned int i; - alternate_t *a; - - REQUIRE(res->references == 0); - REQUIRE(!res->priming); - REQUIRE(res->primefetch == NULL); - - RTRACE("destroy"); - - INSIST(res->nfctx == 0); - - DESTROYLOCK(&res->spill_lock); - DESTROYLOCK(&res->primelock); - DESTROYLOCK(&res->nlock); - DESTROYLOCK(&res->lock); - for (i = 0; i < res->nbuckets; i++) { - INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs)); - isc_task_shutdown(res->buckets[i].task); - isc_task_detach(&res->buckets[i].task); - DESTROYLOCK(&res->buckets[i].lock); - isc_mem_detach(&res->buckets[i].mctx); - } - isc_mem_put(res->mctx, res->buckets, - res->nbuckets * sizeof(fctxbucket_t)); - for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { - INSIST(ISC_LIST_EMPTY(res->dbuckets[i].list)); - isc_mem_detach(&res->dbuckets[i].mctx); - DESTROYLOCK(&res->dbuckets[i].lock); - } - isc_mem_put(res->mctx, res->dbuckets, - RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); - if (res->dispatches4 != NULL) - dns_dispatchset_destroy(&res->dispatches4); - if (res->dispatches6 != NULL) - dns_dispatchset_destroy(&res->dispatches6); - while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) { - ISC_LIST_UNLINK(res->alternates, a, link); - if (!a->isaddress) - dns_name_free(&a->_u._n.name, res->mctx); - isc_mem_put(res->mctx, a, sizeof(*a)); - } - dns_resolver_reset_algorithms(res); - dns_resolver_reset_ds_digests(res); - dns_badcache_destroy(&res->badcache); - dns_resolver_resetmustbesecure(res); -#if USE_ALGLOCK - isc_rwlock_destroy(&res->alglock); -#endif -#if USE_MBSLOCK - isc_rwlock_destroy(&res->mbslock); -#endif - isc_timer_detach(&res->spillattimer); - res->magic = 0; - isc_mem_put(res->mctx, res, sizeof(*res)); -} - -static void -send_shutdown_events(dns_resolver_t *res) { - isc_event_t *event, *next_event; - isc_task_t *etask; - - /* - * Caller must be holding the resolver lock. - */ - - for (event = ISC_LIST_HEAD(res->whenshutdown); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - ISC_LIST_UNLINK(res->whenshutdown, event, ev_link); - etask = event->ev_sender; - event->ev_sender = res; - isc_task_sendanddetach(&etask, &event); - } -} - -static void -empty_bucket(dns_resolver_t *res) { - RTRACE("empty_bucket"); - - LOCK(&res->lock); - - INSIST(res->activebuckets > 0); - res->activebuckets--; - if (res->activebuckets == 0) - send_shutdown_events(res); - - UNLOCK(&res->lock); -} - -static void -spillattimer_countdown(isc_task_t *task, isc_event_t *event) { - dns_resolver_t *res = event->ev_arg; - isc_result_t result; - unsigned int count; - bool logit = false; - - REQUIRE(VALID_RESOLVER(res)); - - UNUSED(task); - - LOCK(&res->lock); - INSIST(!res->exiting); - LOCK(&res->spill_lock); - if (res->spillat > res->spillatmin) { - res->spillat--; - logit = true; - } - if (res->spillat <= res->spillatmin) { - result = isc_timer_reset(res->spillattimer, - isc_timertype_inactive, NULL, - NULL, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - count = res->spillat; - UNLOCK(&res->spill_lock); - UNLOCK(&res->lock); - if (logit) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, - "clients-per-query decreased to %u", count); - - isc_event_free(&event); -} - -isc_result_t -dns_resolver_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, - unsigned int ntasks, unsigned int ndisp, - isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, - unsigned int options, - dns_dispatchmgr_t *dispatchmgr, - dns_dispatch_t *dispatchv4, - dns_dispatch_t *dispatchv6, - dns_resolver_t **resp) -{ - dns_resolver_t *res; - isc_result_t result = ISC_R_SUCCESS; - unsigned int i, buckets_created = 0, dbuckets_created = 0; - isc_task_t *task = NULL; - char name[16]; - unsigned dispattr; - - /* - * Create a resolver. - */ - - REQUIRE(DNS_VIEW_VALID(view)); - REQUIRE(ntasks > 0); - REQUIRE(ndisp > 0); - REQUIRE(resp != NULL && *resp == NULL); - REQUIRE(dispatchmgr != NULL); - REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL); - - res = isc_mem_get(view->mctx, sizeof(*res)); - if (res == NULL) - return (ISC_R_NOMEMORY); - RTRACE("create"); - res->mctx = view->mctx; - res->rdclass = view->rdclass; - res->socketmgr = socketmgr; - res->timermgr = timermgr; - res->taskmgr = taskmgr; - res->dispatchmgr = dispatchmgr; - res->view = view; - res->options = options; - res->lame_ttl = 0; - ISC_LIST_INIT(res->alternates); - res->udpsize = RECV_BUFFER_SIZE; - res->algorithms = NULL; - res->digests = NULL; - res->badcache = NULL; - result = dns_badcache_init(res->mctx, DNS_RESOLVER_BADCACHESIZE, - &res->badcache); - if (result != ISC_R_SUCCESS) { - goto cleanup_res; - } - res->mustbesecure = NULL; - res->spillatmin = res->spillat = 10; - res->spillatmax = 100; - res->spillattimer = NULL; - res->zspill = 0; - res->zero_no_soa_ttl = false; - res->retryinterval = 30000; - res->nonbackofftries = 3; - res->query_timeout = DEFAULT_QUERY_TIMEOUT; - res->maxdepth = DEFAULT_RECURSION_DEPTH; - res->maxqueries = DEFAULT_MAX_QUERIES; - res->quotaresp[dns_quotatype_zone] = DNS_R_DROP; - res->quotaresp[dns_quotatype_server] = DNS_R_SERVFAIL; - res->nbuckets = ntasks; - if (view->resstats != NULL) - isc_stats_set(view->resstats, ntasks, - dns_resstatscounter_buckets); - res->activebuckets = ntasks; - res->buckets = isc_mem_get(view->mctx, - ntasks * sizeof(fctxbucket_t)); - if (res->buckets == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_badcache; - } - for (i = 0; i < ntasks; i++) { - result = isc_mutex_init(&res->buckets[i].lock); - if (result != ISC_R_SUCCESS) - goto cleanup_buckets; - res->buckets[i].task = NULL; - result = isc_task_create(taskmgr, 0, &res->buckets[i].task); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&res->buckets[i].lock); - goto cleanup_buckets; - } - res->buckets[i].mctx = NULL; - snprintf(name, sizeof(name), "res%u", i); -#ifdef ISC_PLATFORM_USETHREADS - /* - * Use a separate memory context for each bucket to reduce - * contention among multiple threads. Do this only when - * enabling threads because it will be require more memory. - */ - result = isc_mem_create(0, 0, &res->buckets[i].mctx); - if (result != ISC_R_SUCCESS) { - isc_task_detach(&res->buckets[i].task); - DESTROYLOCK(&res->buckets[i].lock); - goto cleanup_buckets; - } - isc_mem_setname(res->buckets[i].mctx, name, NULL); -#else - isc_mem_attach(view->mctx, &res->buckets[i].mctx); -#endif - isc_task_setname(res->buckets[i].task, name, res); - ISC_LIST_INIT(res->buckets[i].fctxs); - res->buckets[i].exiting = false; - buckets_created++; - } - - res->dbuckets = isc_mem_get(view->mctx, - RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); - if (res->dbuckets == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_buckets; - } - for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { - ISC_LIST_INIT(res->dbuckets[i].list); - res->dbuckets[i].mctx = NULL; - isc_mem_attach(view->mctx, &res->dbuckets[i].mctx); - result = isc_mutex_init(&res->dbuckets[i].lock); - if (result != ISC_R_SUCCESS) { - isc_mem_detach(&res->dbuckets[i].mctx); - goto cleanup_dbuckets; - } - dbuckets_created++; - } - - res->dispatches4 = NULL; - if (dispatchv4 != NULL) { - dns_dispatchset_create(view->mctx, socketmgr, taskmgr, - dispatchv4, &res->dispatches4, ndisp); - dispattr = dns_dispatch_getattributes(dispatchv4); - res->exclusivev4 = (dispattr & DNS_DISPATCHATTR_EXCLUSIVE); - } - - res->dispatches6 = NULL; - if (dispatchv6 != NULL) { - dns_dispatchset_create(view->mctx, socketmgr, taskmgr, - dispatchv6, &res->dispatches6, ndisp); - dispattr = dns_dispatch_getattributes(dispatchv6); - res->exclusivev6 = (dispattr & DNS_DISPATCHATTR_EXCLUSIVE); - } - - res->querydscp4 = -1; - res->querydscp6 = -1; - res->references = 1; - res->exiting = false; - res->frozen = false; - ISC_LIST_INIT(res->whenshutdown); - res->priming = false; - res->primefetch = NULL; - res->nfctx = 0; - - result = isc_mutex_init(&res->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_dispatches; - - result = isc_mutex_init(&res->nlock); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - result = isc_mutex_init(&res->primelock); - if (result != ISC_R_SUCCESS) - goto cleanup_nlock; - - result = isc_mutex_init(&res->spill_lock); - if (result != ISC_R_SUCCESS) - goto cleanup_primelock; - - task = NULL; - result = isc_task_create(taskmgr, 0, &task); - if (result != ISC_R_SUCCESS) - goto cleanup_spill_lock; - isc_task_setname(task, "resolver_task", NULL); - - result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, - task, spillattimer_countdown, res, - &res->spillattimer); - isc_task_detach(&task); - if (result != ISC_R_SUCCESS) - goto cleanup_spill_lock; - -#if USE_ALGLOCK - result = isc_rwlock_init(&res->alglock, 0, 0); - if (result != ISC_R_SUCCESS) - goto cleanup_spillattimer; -#endif -#if USE_MBSLOCK - result = isc_rwlock_init(&res->mbslock, 0, 0); - if (result != ISC_R_SUCCESS) -#if USE_ALGLOCK - goto cleanup_alglock; -#else - goto cleanup_spillattimer; -#endif -#endif - - res->magic = RES_MAGIC; - - *resp = res; - - return (ISC_R_SUCCESS); - -#if USE_ALGLOCK && USE_MBSLOCK - cleanup_alglock: - isc_rwlock_destroy(&res->alglock); -#endif - -#if USE_ALGLOCK || USE_MBSLOCK - cleanup_spillattimer: - isc_timer_detach(&res->spillattimer); -#endif - - cleanup_spill_lock: - DESTROYLOCK(&res->spill_lock); - - cleanup_primelock: - DESTROYLOCK(&res->primelock); - - cleanup_nlock: - DESTROYLOCK(&res->nlock); - - cleanup_lock: - DESTROYLOCK(&res->lock); - - cleanup_dispatches: - if (res->dispatches6 != NULL) - dns_dispatchset_destroy(&res->dispatches6); - if (res->dispatches4 != NULL) - dns_dispatchset_destroy(&res->dispatches4); - - cleanup_dbuckets: - for (i = 0; i < dbuckets_created; i++) { - DESTROYLOCK(&res->dbuckets[i].lock); - isc_mem_detach(&res->dbuckets[i].mctx); - } - isc_mem_put(view->mctx, res->dbuckets, - RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); - - cleanup_buckets: - for (i = 0; i < buckets_created; i++) { - isc_mem_detach(&res->buckets[i].mctx); - DESTROYLOCK(&res->buckets[i].lock); - isc_task_shutdown(res->buckets[i].task); - isc_task_detach(&res->buckets[i].task); - } - isc_mem_put(view->mctx, res->buckets, - res->nbuckets * sizeof(fctxbucket_t)); - - cleanup_badcache: - dns_badcache_destroy(&res->badcache); - - cleanup_res: - isc_mem_put(view->mctx, res, sizeof(*res)); - - return (result); -} - -static void -prime_done(isc_task_t *task, isc_event_t *event) { - dns_resolver_t *res; - dns_fetchevent_t *fevent; - dns_fetch_t *fetch; - dns_db_t *db = NULL; - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - fevent = (dns_fetchevent_t *)event; - res = event->ev_arg; - REQUIRE(VALID_RESOLVER(res)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "resolver priming query complete"); - - UNUSED(task); - - LOCK(&res->lock); - - INSIST(res->priming); - res->priming = false; - LOCK(&res->primelock); - fetch = res->primefetch; - res->primefetch = NULL; - UNLOCK(&res->primelock); - - UNLOCK(&res->lock); - - if (fevent->result == ISC_R_SUCCESS && - res->view->cache != NULL && res->view->hints != NULL) { - dns_cache_attachdb(res->view->cache, &db); - dns_root_checkhints(res->view, res->view->hints, db); - dns_db_detach(&db); - } - - if (fevent->node != NULL) - dns_db_detachnode(fevent->db, &fevent->node); - if (fevent->db != NULL) - dns_db_detach(&fevent->db); - if (dns_rdataset_isassociated(fevent->rdataset)) - dns_rdataset_disassociate(fevent->rdataset); - INSIST(fevent->sigrdataset == NULL); - - isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset)); - - isc_event_free(&event); - dns_resolver_destroyfetch(&fetch); -} - -void -dns_resolver_prime(dns_resolver_t *res) { - bool want_priming = false; - dns_rdataset_t *rdataset; - isc_result_t result; - - REQUIRE(VALID_RESOLVER(res)); - REQUIRE(res->frozen); - - RTRACE("dns_resolver_prime"); - - LOCK(&res->lock); - - if (!res->exiting && !res->priming) { - INSIST(res->primefetch == NULL); - res->priming = true; - want_priming = true; - } - - UNLOCK(&res->lock); - - if (want_priming) { - /* - * To avoid any possible recursive locking problems, we - * start the priming fetch like any other fetch, and holding - * no resolver locks. No one else will try to start it - * because we're the ones who set res->priming to true. - * Any other callers of dns_resolver_prime() while we're - * running will see that res->priming is already true and - * do nothing. - */ - RTRACE("priming"); - rdataset = isc_mem_get(res->mctx, sizeof(*rdataset)); - if (rdataset == NULL) { - LOCK(&res->lock); - INSIST(res->priming); - INSIST(res->primefetch == NULL); - res->priming = false; - UNLOCK(&res->lock); - return; - } - dns_rdataset_init(rdataset); - LOCK(&res->primelock); - result = dns_resolver_createfetch(res, dns_rootname, - dns_rdatatype_ns, - NULL, NULL, NULL, - DNS_FETCHOPT_NOFORWARD, - res->buckets[0].task, - prime_done, - res, rdataset, NULL, - &res->primefetch); - UNLOCK(&res->primelock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(res->mctx, rdataset, sizeof(*rdataset)); - LOCK(&res->lock); - INSIST(res->priming); - res->priming = false; - UNLOCK(&res->lock); - } - } -} - -void -dns_resolver_freeze(dns_resolver_t *res) { - /* - * Freeze resolver. - */ - - REQUIRE(VALID_RESOLVER(res)); - - res->frozen = true; -} - -void -dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) { - REQUIRE(VALID_RESOLVER(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - RRTRACE(source, "attach"); - LOCK(&source->lock); - REQUIRE(!source->exiting); - - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); - UNLOCK(&source->lock); - - *targetp = source; -} - -void -dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, - isc_event_t **eventp) -{ - isc_task_t *tclone; - isc_event_t *event; - - REQUIRE(VALID_RESOLVER(res)); - REQUIRE(eventp != NULL); - - event = *eventp; - *eventp = NULL; - - LOCK(&res->lock); - - if (res->exiting && res->activebuckets == 0) { - /* - * We're already shutdown. Send the event. - */ - event->ev_sender = res; - isc_task_send(task, &event); - } else { - tclone = NULL; - isc_task_attach(task, &tclone); - event->ev_sender = tclone; - ISC_LIST_APPEND(res->whenshutdown, event, ev_link); - } - - UNLOCK(&res->lock); -} - -void -dns_resolver_shutdown(dns_resolver_t *res) { - unsigned int i; - fetchctx_t *fctx; - isc_result_t result; - - REQUIRE(VALID_RESOLVER(res)); - - RTRACE("shutdown"); - - LOCK(&res->lock); - - if (!res->exiting) { - RTRACE("exiting"); - res->exiting = true; - - for (i = 0; i < res->nbuckets; i++) { - LOCK(&res->buckets[i].lock); - for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs); - fctx != NULL; - fctx = ISC_LIST_NEXT(fctx, link)) - fctx_shutdown(fctx); - if (res->dispatches4 != NULL && !res->exclusivev4) { - dns_dispatchset_cancelall(res->dispatches4, - res->buckets[i].task); - } - if (res->dispatches6 != NULL && !res->exclusivev6) { - dns_dispatchset_cancelall(res->dispatches6, - res->buckets[i].task); - } - res->buckets[i].exiting = true; - if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { - INSIST(res->activebuckets > 0); - res->activebuckets--; - } - UNLOCK(&res->buckets[i].lock); - } - if (res->activebuckets == 0) - send_shutdown_events(res); - result = isc_timer_reset(res->spillattimer, - isc_timertype_inactive, NULL, - NULL, true); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - UNLOCK(&res->lock); -} - -void -dns_resolver_detach(dns_resolver_t **resp) { - dns_resolver_t *res; - bool need_destroy = false; - - REQUIRE(resp != NULL); - res = *resp; - REQUIRE(VALID_RESOLVER(res)); - - RTRACE("detach"); - - LOCK(&res->lock); - - INSIST(res->references > 0); - res->references--; - if (res->references == 0) { - INSIST(res->exiting && res->activebuckets == 0); - need_destroy = true; - } - - UNLOCK(&res->lock); - - if (need_destroy) - destroy(res); - - *resp = NULL; -} - -static inline bool -fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, - unsigned int options) -{ - /* - * Don't match fetch contexts that are shutting down. - */ - if (fctx->cloned || fctx->state == fetchstate_done || - ISC_LIST_EMPTY(fctx->events)) - return (false); - - if (fctx->type != type || fctx->options != options) - return (false); - return (dns_name_equal(&fctx->name, name)); -} - -static inline void -log_fetch(dns_name_t *name, dns_rdatatype_t type) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - int level = ISC_LOG_DEBUG(1); - - /* - * If there's no chance of logging it, don't render (format) the - * name and RDATA type (further below), and return early. - */ - if (! isc_log_wouldlog(dns_lctx, level)) - return; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, level, - "fetch: %s/%s", namebuf, typebuf); -} - -isc_result_t -dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp) -{ - return (dns_resolver_createfetch3(res, name, type, domain, - nameservers, forwarders, NULL, 0, - options, 0, NULL, task, action, arg, - rdataset, sigrdataset, fetchp)); -} - -isc_result_t -dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - isc_sockaddr_t *client, dns_messageid_t id, - unsigned int options, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp) -{ - return (dns_resolver_createfetch3(res, name, type, domain, - nameservers, forwarders, client, id, - options, 0, NULL, task, action, arg, - rdataset, sigrdataset, fetchp)); -} - -isc_result_t -dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, - dns_rdatatype_t type, - dns_name_t *domain, dns_rdataset_t *nameservers, - dns_forwarders_t *forwarders, - isc_sockaddr_t *client, dns_messageid_t id, - unsigned int options, unsigned int depth, - isc_counter_t *qc, isc_task_t *task, - isc_taskaction_t action, void *arg, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - dns_fetch_t **fetchp) -{ - dns_fetch_t *fetch; - fetchctx_t *fctx = NULL; - isc_result_t result = ISC_R_SUCCESS; - unsigned int bucketnum; - bool new_fctx = false; - isc_event_t *event; - unsigned int count = 0; - unsigned int spillat; - unsigned int spillatmin; - bool dodestroy = false; - - UNUSED(forwarders); - - REQUIRE(VALID_RESOLVER(res)); - REQUIRE(res->frozen); - /* XXXRTH Check for meta type */ - if (domain != NULL) { - REQUIRE(DNS_RDATASET_VALID(nameservers)); - REQUIRE(nameservers->type == dns_rdatatype_ns); - } else - REQUIRE(nameservers == NULL); - REQUIRE(forwarders == NULL); - REQUIRE(!dns_rdataset_isassociated(rdataset)); - REQUIRE(sigrdataset == NULL || - !dns_rdataset_isassociated(sigrdataset)); - REQUIRE(fetchp != NULL && *fetchp == NULL); - - log_fetch(name, type); - - /* - * XXXRTH use a mempool? - */ - fetch = isc_mem_get(res->mctx, sizeof(*fetch)); - if (fetch == NULL) - return (ISC_R_NOMEMORY); - fetch->mctx = NULL; - isc_mem_attach(res->mctx, &fetch->mctx); - - bucketnum = dns_name_fullhash(name, false) % res->nbuckets; - - LOCK(&res->spill_lock); - spillat = res->spillat; - spillatmin = res->spillatmin; - UNLOCK(&res->spill_lock); - LOCK(&res->buckets[bucketnum].lock); - - if (res->buckets[bucketnum].exiting) { - result = ISC_R_SHUTTINGDOWN; - goto unlock; - } - - if ((options & DNS_FETCHOPT_UNSHARED) == 0) { - for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs); - fctx != NULL; - fctx = ISC_LIST_NEXT(fctx, link)) { - if (fctx_match(fctx, name, type, options)) - break; - } - } - - /* - * Is this a duplicate? - */ - if (fctx != NULL && client != NULL) { - dns_fetchevent_t *fevent; - for (fevent = ISC_LIST_HEAD(fctx->events); - fevent != NULL; - fevent = ISC_LIST_NEXT(fevent, ev_link)) { - if (fevent->client != NULL && fevent->id == id && - isc_sockaddr_equal(fevent->client, client)) { - result = DNS_R_DUPLICATE; - goto unlock; - } - count++; - } - } - if (count >= spillatmin && spillatmin != 0) { - INSIST(fctx != NULL); - if (count >= spillat) - fctx->spilled = true; - if (fctx->spilled) { - result = DNS_R_DROP; - goto unlock; - } - } - - if (fctx == NULL) { - result = fctx_create(res, name, type, domain, nameservers, - client, options, bucketnum, depth, qc, - &fctx); - if (result != ISC_R_SUCCESS) - goto unlock; - new_fctx = true; - } else if (fctx->depth > depth) - fctx->depth = depth; - - result = fctx_join(fctx, task, client, id, action, arg, - rdataset, sigrdataset, fetch); - if (new_fctx) { - if (result == ISC_R_SUCCESS) { - /* - * Launch this fctx. - */ - event = &fctx->control_event; - ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, - DNS_EVENT_FETCHCONTROL, - fctx_start, fctx, NULL, - NULL, NULL); - isc_task_send(res->buckets[bucketnum].task, &event); - } else { - /* - * We don't care about the result of fctx_unlink() - * since we know we're not exiting. - */ - (void)fctx_unlink(fctx); - dodestroy = true; - } - } - - unlock: - UNLOCK(&res->buckets[bucketnum].lock); - - if (dodestroy) - fctx_destroy(fctx); - - if (result == ISC_R_SUCCESS) { - FTRACE("created"); - *fetchp = fetch; - } else - isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); - - return (result); -} - -void -dns_resolver_cancelfetch(dns_fetch_t *fetch) { - fetchctx_t *fctx; - dns_resolver_t *res; - dns_fetchevent_t *event, *next_event; - isc_task_t *etask; - - REQUIRE(DNS_FETCH_VALID(fetch)); - fctx = fetch->private; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - - FTRACE("cancelfetch"); - - LOCK(&res->buckets[fctx->bucketnum].lock); - - /* - * Find the completion event for this fetch (as opposed - * to those for other fetches that have joined the same - * fctx) and send it with result = ISC_R_CANCELED. - */ - event = NULL; - if (fctx->state != fetchstate_done) { - for (event = ISC_LIST_HEAD(fctx->events); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - if (event->fetch == fetch) { - ISC_LIST_UNLINK(fctx->events, event, ev_link); - break; - } - } - } - if (event != NULL) { - etask = event->ev_sender; - event->ev_sender = fctx; - event->result = ISC_R_CANCELED; - isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event)); - } - /* - * The fctx continues running even if no fetches remain; - * the answer is still cached. - */ - - UNLOCK(&res->buckets[fctx->bucketnum].lock); -} - -void -dns_resolver_destroyfetch(dns_fetch_t **fetchp) { - dns_fetch_t *fetch; - dns_resolver_t *res; - dns_fetchevent_t *event, *next_event; - fetchctx_t *fctx; - unsigned int bucketnum; - bool bucket_empty; - - REQUIRE(fetchp != NULL); - fetch = *fetchp; - REQUIRE(DNS_FETCH_VALID(fetch)); - fctx = fetch->private; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - - FTRACE("destroyfetch"); - - bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); - - /* - * Sanity check: the caller should have gotten its event before - * trying to destroy the fetch. - */ - event = NULL; - if (fctx->state != fetchstate_done) { - for (event = ISC_LIST_HEAD(fctx->events); - event != NULL; - event = next_event) { - next_event = ISC_LIST_NEXT(event, ev_link); - RUNTIME_CHECK(event->fetch != fetch); - } - } - - bucket_empty = fctx_decreference(fctx); - - UNLOCK(&res->buckets[bucketnum].lock); - - isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); - *fetchp = NULL; - - if (bucket_empty) - empty_bucket(res); -} - -void -dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, - isc_logcategory_t *category, isc_logmodule_t *module, - int level, bool duplicateok) -{ - fetchctx_t *fctx; - dns_resolver_t *res; - char domainbuf[DNS_NAME_FORMATSIZE]; - - REQUIRE(DNS_FETCH_VALID(fetch)); - fctx = fetch->private; - REQUIRE(VALID_FCTX(fctx)); - res = fctx->res; - - LOCK(&res->buckets[fctx->bucketnum].lock); - - INSIST(fctx->exitline >= 0); - if (!fctx->logged || duplicateok) { - dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); - isc_log_write(lctx, category, module, level, - "fetch completed at %s:%d for %s in " - "%" PRIu64 "." - "%06" PRIu64 ": %s/%s " - "[domain:%s,referral:%u,restart:%u,qrysent:%u," - "timeout:%u,lame:%u,quota:%u,neterr:%u," - "badresp:%u,adberr:%u,findfail:%u,valfail:%u]", - __FILE__, fctx->exitline, fctx->info, - fctx->duration / US_PER_SEC, - fctx->duration % US_PER_SEC, - isc_result_totext(fctx->result), - isc_result_totext(fctx->vresult), domainbuf, - fctx->referrals, fctx->restarts, - fctx->querysent, fctx->timeouts, - fctx->lamecount, fctx->quotacount, - fctx->neterr, fctx->badresp, fctx->adberr, - fctx->findfail, fctx->valfail); - fctx->logged = true; - } - - UNLOCK(&res->buckets[fctx->bucketnum].lock); -} - -dns_dispatchmgr_t * -dns_resolver_dispatchmgr(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->dispatchmgr); -} - -dns_dispatch_t * -dns_resolver_dispatchv4(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (dns_dispatchset_get(resolver->dispatches4)); -} - -dns_dispatch_t * -dns_resolver_dispatchv6(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (dns_dispatchset_get(resolver->dispatches6)); -} - -isc_socketmgr_t * -dns_resolver_socketmgr(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->socketmgr); -} - -isc_taskmgr_t * -dns_resolver_taskmgr(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->taskmgr); -} - -uint32_t -dns_resolver_getlamettl(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->lame_ttl); -} - -void -dns_resolver_setlamettl(dns_resolver_t *resolver, uint32_t lame_ttl) { - REQUIRE(VALID_RESOLVER(resolver)); - resolver->lame_ttl = lame_ttl; -} - -unsigned int -dns_resolver_nrunning(dns_resolver_t *resolver) { - unsigned int n; - LOCK(&resolver->nlock); - n = resolver->nfctx; - UNLOCK(&resolver->nlock); - return (n); -} - -isc_result_t -dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, - dns_name_t *name, in_port_t port) { - alternate_t *a; - isc_result_t result; - - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(!resolver->frozen); - REQUIRE((alt == NULL) ^ (name == NULL)); - - a = isc_mem_get(resolver->mctx, sizeof(*a)); - if (a == NULL) - return (ISC_R_NOMEMORY); - if (alt != NULL) { - a->isaddress = true; - a->_u.addr = *alt; - } else { - a->isaddress = false; - a->_u._n.port = port; - dns_name_init(&a->_u._n.name, NULL); - result = dns_name_dup(name, resolver->mctx, &a->_u._n.name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(resolver->mctx, a, sizeof(*a)); - return (result); - } - } - ISC_LINK_INIT(a, link); - ISC_LIST_APPEND(resolver->alternates, a, link); - - return (ISC_R_SUCCESS); -} - -void -dns_resolver_setudpsize(dns_resolver_t *resolver, uint16_t udpsize) { - REQUIRE(VALID_RESOLVER(resolver)); - resolver->udpsize = udpsize; -} - -uint16_t -dns_resolver_getudpsize(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->udpsize); -} - -void -dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) { - if (name != NULL) - dns_badcache_flushname(resolver->badcache, name); - else - dns_badcache_flush(resolver->badcache); -} - -void -dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name) { - dns_badcache_flushtree(resolver->badcache, name); -} - -void -dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, - dns_rdatatype_t type, isc_time_t *expire) -{ -#ifdef ENABLE_AFL - if (!dns_fuzzing_resolver) -#endif - { - (void) dns_badcache_add(resolver->badcache, name, type, - false, 0, expire); - } -} - -bool -dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, - dns_rdatatype_t type, isc_time_t *now) -{ - return (dns_badcache_find(resolver->badcache, name, type, NULL, now)); -} - -void -dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) { - (void) dns_badcache_print(resolver->badcache, "Bad cache", fp); -} - -static void -free_algorithm(void *node, void *arg) { - unsigned char *algorithms = node; - isc_mem_t *mctx = arg; - - isc_mem_put(mctx, algorithms, *algorithms); -} - -void -dns_resolver_reset_algorithms(dns_resolver_t *resolver) { - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - if (resolver->algorithms != NULL) - dns_rbt_destroy(&resolver->algorithms); -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif -} - -isc_result_t -dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, - unsigned int alg) -{ - unsigned int len, mask; - unsigned char *tmp; - unsigned char *algorithms; - isc_result_t result; - dns_rbtnode_t *node = NULL; - - /* - * Whether an algorithm is disabled (or not) is stored in a - * per-name bitfield that is stored as the node data of an - * RBT. - */ - - REQUIRE(VALID_RESOLVER(resolver)); - if (alg > 255) - return (ISC_R_RANGE); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - if (resolver->algorithms == NULL) { - result = dns_rbt_create(resolver->mctx, free_algorithm, - resolver->mctx, &resolver->algorithms); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - len = alg/8 + 2; - mask = 1 << (alg%8); - - result = dns_rbt_addnode(resolver->algorithms, name, &node); - - if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { - algorithms = node->data; - /* - * If algorithms is set, algorithms[0] contains its - * length. - */ - if (algorithms == NULL || len > *algorithms) { - /* - * If no bitfield exists in the node data, or if - * it is not long enough, allocate a new - * bitfield and copy the old (smaller) bitfield - * into it if one exists. - */ - tmp = isc_mem_get(resolver->mctx, len); - if (tmp == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - memset(tmp, 0, len); - if (algorithms != NULL) - memmove(tmp, algorithms, *algorithms); - tmp[len-1] |= mask; - /* 'tmp[0]' should contain the length of 'tmp'. */ - *tmp = len; - node->data = tmp; - /* Free the older bitfield. */ - if (algorithms != NULL) - isc_mem_put(resolver->mctx, algorithms, - *algorithms); - } else - algorithms[len-1] |= mask; - } - result = ISC_R_SUCCESS; - cleanup: -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - return (result); -} - -bool -dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, - unsigned int alg) -{ - unsigned int len, mask; - unsigned char *algorithms; - void *data = NULL; - isc_result_t result; - bool found = false; - - REQUIRE(VALID_RESOLVER(resolver)); - - /* - * DH is unsupported for DNSKEYs, see RFC 4034 sec. A.1. - */ - if ((alg == DST_ALG_DH) || (alg == DST_ALG_INDIRECT)) - return (false); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_read); -#endif - if (resolver->algorithms == NULL) - goto unlock; - result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { - len = alg/8 + 2; - mask = 1 << (alg%8); - algorithms = data; - if (len <= *algorithms && (algorithms[len-1] & mask) != 0) - found = true; - } - unlock: -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); -#endif - if (found) - return (false); - - return (dst_algorithm_supported(alg)); -} - -static void -free_digest(void *node, void *arg) { - unsigned char *digests = node; - isc_mem_t *mctx = arg; - - isc_mem_put(mctx, digests, *digests); -} - -void -dns_resolver_reset_ds_digests(dns_resolver_t *resolver) { - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - if (resolver->digests != NULL) - dns_rbt_destroy(&resolver->digests); -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif -} - -isc_result_t -dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name, - unsigned int digest_type) -{ - unsigned int len, mask; - unsigned char *tmp; - unsigned char *digests; - isc_result_t result; - dns_rbtnode_t *node = NULL; - - /* - * Whether a digest is disabled (or not) is stored in a per-name - * bitfield that is stored as the node data of an RBT. - */ - - REQUIRE(VALID_RESOLVER(resolver)); - if (digest_type > 255) - return (ISC_R_RANGE); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - if (resolver->digests == NULL) { - result = dns_rbt_create(resolver->mctx, free_digest, - resolver->mctx, &resolver->digests); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - len = digest_type/8 + 2; - mask = 1 << (digest_type%8); - - result = dns_rbt_addnode(resolver->digests, name, &node); - - if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { - digests = node->data; - /* If digests is set, digests[0] contains its length. */ - if (digests == NULL || len > *digests) { - /* - * If no bitfield exists in the node data, or if - * it is not long enough, allocate a new - * bitfield and copy the old (smaller) bitfield - * into it if one exists. - */ - tmp = isc_mem_get(resolver->mctx, len); - if (tmp == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - memset(tmp, 0, len); - if (digests != NULL) - memmove(tmp, digests, *digests); - tmp[len-1] |= mask; - /* tmp[0] should contain the length of 'tmp'. */ - *tmp = len; - node->data = tmp; - /* Free the older bitfield. */ - if (digests != NULL) - isc_mem_put(resolver->mctx, digests, - *digests); - } else - digests[len-1] |= mask; - } - result = ISC_R_SUCCESS; - cleanup: -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); -#endif - return (result); -} - -bool -dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name, - unsigned int digest_type) -{ - unsigned int len, mask; - unsigned char *digests; - void *data = NULL; - isc_result_t result; - bool found = false; - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_ALGLOCK - RWLOCK(&resolver->alglock, isc_rwlocktype_read); -#endif - if (resolver->digests == NULL) - goto unlock; - result = dns_rbt_findname(resolver->digests, name, 0, NULL, &data); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { - len = digest_type/8 + 2; - mask = 1 << (digest_type%8); - digests = data; - if (len <= *digests && (digests[len-1] & mask) != 0) - found = true; - } - unlock: -#if USE_ALGLOCK - RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); -#endif - if (found) - return (false); - return (dst_ds_digest_supported(digest_type)); -} - -void -dns_resolver_resetmustbesecure(dns_resolver_t *resolver) { - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_MBSLOCK - RWLOCK(&resolver->mbslock, isc_rwlocktype_write); -#endif - if (resolver->mustbesecure != NULL) - dns_rbt_destroy(&resolver->mustbesecure); -#if USE_MBSLOCK - RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); -#endif -} - -static bool yes = true, no = false; - -isc_result_t -dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, - bool value) -{ - isc_result_t result; - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_MBSLOCK - RWLOCK(&resolver->mbslock, isc_rwlocktype_write); -#endif - if (resolver->mustbesecure == NULL) { - result = dns_rbt_create(resolver->mctx, NULL, NULL, - &resolver->mustbesecure); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - result = dns_rbt_addname(resolver->mustbesecure, name, - value ? &yes : &no); - cleanup: -#if USE_MBSLOCK - RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); -#endif - return (result); -} - -bool -dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) { - void *data = NULL; - bool value = false; - isc_result_t result; - - REQUIRE(VALID_RESOLVER(resolver)); - -#if USE_MBSLOCK - RWLOCK(&resolver->mbslock, isc_rwlocktype_read); -#endif - if (resolver->mustbesecure == NULL) - goto unlock; - result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - value = *(bool*)data; - unlock: -#if USE_MBSLOCK - RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read); -#endif - return (value); -} - -void -dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur, - uint32_t *min, uint32_t *max) -{ - REQUIRE(VALID_RESOLVER(resolver)); - - LOCK(&resolver->spill_lock); - if (cur != NULL) - *cur = resolver->spillat; - if (min != NULL) - *min = resolver->spillatmin; - if (max != NULL) - *max = resolver->spillatmax; - UNLOCK(&resolver->spill_lock); -} - -void -dns_resolver_setclientsperquery(dns_resolver_t *resolver, uint32_t min, - uint32_t max) -{ - REQUIRE(VALID_RESOLVER(resolver)); - - LOCK(&resolver->spill_lock); - resolver->spillatmin = resolver->spillat = min; - resolver->spillatmax = max; - UNLOCK(&resolver->spill_lock); -} - -void -dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients) -{ - REQUIRE(VALID_RESOLVER(resolver)); - - LOCK(&resolver->spill_lock); - resolver->zspill = clients; - UNLOCK(&resolver->spill_lock); -} - - -bool -dns_resolver_getzeronosoattl(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - - return (resolver->zero_no_soa_ttl); -} - -void -dns_resolver_setzeronosoattl(dns_resolver_t *resolver, bool state) { - REQUIRE(VALID_RESOLVER(resolver)); - - resolver->zero_no_soa_ttl = state; -} - -unsigned int -dns_resolver_getoptions(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - - return (resolver->options); -} - -unsigned int -dns_resolver_gettimeout(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - - return (resolver->query_timeout); -} - -void -dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int timeout) { - REQUIRE(VALID_RESOLVER(resolver)); - - if (timeout <= 300) - timeout *= 1000; - - if (timeout == 0) - timeout = DEFAULT_QUERY_TIMEOUT; - if (timeout > MAXIMUM_QUERY_TIMEOUT) - timeout = MAXIMUM_QUERY_TIMEOUT; - if (timeout < MINIMUM_QUERY_TIMEOUT) - timeout = MINIMUM_QUERY_TIMEOUT; - - resolver->query_timeout = timeout; -} - -void -dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp) { - REQUIRE(VALID_RESOLVER(resolver)); - - resolver->querydscp4 = dscp; -} - -isc_dscp_t -dns_resolver_getquerydscp4(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->querydscp4); -} - -void -dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp) { - REQUIRE(VALID_RESOLVER(resolver)); - - resolver->querydscp6 = dscp; -} - -isc_dscp_t -dns_resolver_getquerydscp6(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->querydscp6); -} - -void -dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) { - REQUIRE(VALID_RESOLVER(resolver)); - resolver->maxdepth = maxdepth; -} - -unsigned int -dns_resolver_getmaxdepth(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->maxdepth); -} - -void -dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) { - REQUIRE(VALID_RESOLVER(resolver)); - resolver->maxqueries = queries; -} - -unsigned int -dns_resolver_getmaxqueries(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->maxqueries); -} - -void -dns_resolver_dumpfetches(dns_resolver_t *resolver, - isc_statsformat_t format, FILE *fp) -{ - int i; - - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(fp != NULL); - REQUIRE(format == isc_statsformat_file); - - for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { - fctxcount_t *fc; - LOCK(&resolver->dbuckets[i].lock); - for (fc = ISC_LIST_HEAD(resolver->dbuckets[i].list); - fc != NULL; - fc = ISC_LIST_NEXT(fc, link)) - { - dns_name_print(fc->domain, fp); - fprintf(fp, ": %u active (%u spilled, %u allowed)\n", - fc->count, fc->dropped, fc->allowed); - } - UNLOCK(&resolver->dbuckets[i].lock); - } -} - -void -dns_resolver_setquotaresponse(dns_resolver_t *resolver, - dns_quotatype_t which, isc_result_t resp) -{ - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server); - REQUIRE(resp == DNS_R_DROP || resp == DNS_R_SERVFAIL); - - resolver->quotaresp[which] = resp; -} - -isc_result_t -dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which) -{ - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server); - - return (resolver->quotaresp[which]); -} - -unsigned int -dns_resolver_getretryinterval(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - - return (resolver->retryinterval); -} - -void -dns_resolver_setretryinterval(dns_resolver_t *resolver, unsigned int interval) -{ - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(interval > 0); - - resolver->retryinterval = ISC_MIN(interval, 2000); -} - -unsigned int -dns_resolver_getnonbackofftries(dns_resolver_t *resolver) { - REQUIRE(VALID_RESOLVER(resolver)); - - return (resolver->nonbackofftries); -} - -void -dns_resolver_setnonbackofftries(dns_resolver_t *resolver, unsigned int tries) { - REQUIRE(VALID_RESOLVER(resolver)); - REQUIRE(tries > 0); - - resolver->nonbackofftries = tries; -} diff --git a/lib/dns-pkcs11/result.c b/lib/dns-pkcs11/result.c deleted file mode 100644 index c4324aa..0000000 --- a/lib/dns-pkcs11/result.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -static const char *text[DNS_R_NRESULTS] = { - "label too long", /*%< 0 DNS_R_LABELTOOLONG */ - "bad escape", /*%< 1 DNS_R_BADESCAPE */ - /*! - * Note that DNS_R_BADBITSTRING and DNS_R_BITSTRINGTOOLONG are - * deprecated. - */ - "bad bitstring", /*%< 2 DNS_R_BADBITSTRING */ - "bitstring too long", /*%< 3 DNS_R_BITSTRINGTOOLONG */ - "empty label", /*%< 4 DNS_R_EMPTYLABEL */ - - "bad dotted quad", /*%< 5 DNS_R_BADDOTTEDQUAD */ - "invalid NS owner name (wildcard)", /*%< 6 DNS_R_INVALIDNS */ - "unknown class/type", /*%< 7 DNS_R_UNKNOWN */ - "bad label type", /*%< 8 DNS_R_BADLABELTYPE */ - "bad compression pointer", /*%< 9 DNS_R_BADPOINTER */ - - "too many hops", /*%< 10 DNS_R_TOOMANYHOPS */ - "disallowed (by application policy)", /*%< 11 DNS_R_DISALLOWED */ - "extra input text", /*%< 12 DNS_R_EXTRATOKEN */ - "extra input data", /*%< 13 DNS_R_EXTRADATA */ - "text too long", /*%< 14 DNS_R_TEXTTOOLONG */ - - "not at top of zone", /*%< 15 DNS_R_NOTZONETOP */ - "syntax error", /*%< 16 DNS_R_SYNTAX */ - "bad checksum", /*%< 17 DNS_R_BADCKSUM */ - "bad IPv6 address", /*%< 18 DNS_R_BADAAAA */ - "no owner", /*%< 19 DNS_R_NOOWNER */ - - "no ttl", /*%< 20 DNS_R_NOTTL */ - "bad class", /*%< 21 DNS_R_BADCLASS */ - "name too long", /*%< 22 DNS_R_NAMETOOLONG */ - "partial match", /*%< 23 DNS_R_PARTIALMATCH */ - "new origin", /*%< 24 DNS_R_NEWORIGIN */ - - "unchanged", /*%< 25 DNS_R_UNCHANGED */ - "bad ttl", /*%< 26 DNS_R_BADTTL */ - "more data needed/to be rendered", /*%< 27 DNS_R_NOREDATA */ - "continue", /*%< 28 DNS_R_CONTINUE */ - "delegation", /*%< 29 DNS_R_DELEGATION */ - - "glue", /*%< 30 DNS_R_GLUE */ - "dname", /*%< 31 DNS_R_DNAME */ - "cname", /*%< 32 DNS_R_CNAME */ - "bad database", /*%< 33 DNS_R_BADDB */ - "zonecut", /*%< 34 DNS_R_ZONECUT */ - - "bad zone", /*%< 35 DNS_R_BADZONE */ - "more data", /*%< 36 DNS_R_MOREDATA */ - "up to date", /*%< 37 DNS_R_UPTODATE */ - "tsig verify failure", /*%< 38 DNS_R_TSIGVERIFYFAILURE */ - "tsig indicates error", /*%< 39 DNS_R_TSIGERRORSET */ - - "RRSIG failed to verify", /*%< 40 DNS_R_SIGINVALID */ - "RRSIG has expired", /*%< 41 DNS_R_SIGEXPIRED */ - "RRSIG validity period has not begun", /*%< 42 DNS_R_SIGFUTURE */ - "key is unauthorized to sign data", /*%< 43 DNS_R_KEYUNAUTHORIZED */ - "invalid time", /*%< 44 DNS_R_INVALIDTIME */ - - "expected a TSIG or SIG(0)", /*%< 45 DNS_R_EXPECTEDTSIG */ - "did not expect a TSIG or SIG(0)", /*%< 46 DNS_R_UNEXPECTEDTSIG */ - "TKEY is unacceptable", /*%< 47 DNS_R_INVALIDTKEY */ - "hint", /*%< 48 DNS_R_HINT */ - "drop", /*%< 49 DNS_R_DROP */ - - "zone not loaded", /*%< 50 DNS_R_NOTLOADED */ - "ncache nxdomain", /*%< 51 DNS_R_NCACHENXDOMAIN */ - "ncache nxrrset", /*%< 52 DNS_R_NCACHENXRRSET */ - "wait", /*%< 53 DNS_R_WAIT */ - "not verified yet", /*%< 54 DNS_R_NOTVERIFIEDYET */ - - "no identity", /*%< 55 DNS_R_NOIDENTITY */ - "no journal", /*%< 56 DNS_R_NOJOURNAL */ - "alias", /*%< 57 DNS_R_ALIAS */ - "use TCP", /*%< 58 DNS_R_USETCP */ - "no valid RRSIG", /*%< 59 DNS_R_NOVALIDSIG */ - - "no valid NSEC", /*%< 60 DNS_R_NOVALIDNSEC */ - "insecurity proof failed", /*%< 61 DNS_R_NOTINSECURE */ - "unknown service", /*%< 62 DNS_R_UNKNOWNSERVICE */ - "recoverable error occurred", /*%< 63 DNS_R_RECOVERABLE */ - "unknown opt attribute record", /*%< 64 DNS_R_UNKNOWNOPT */ - - "unexpected message id", /*%< 65 DNS_R_UNEXPECTEDID */ - "seen include file", /*%< 66 DNS_R_SEENINCLUDE */ - "not exact", /*%< 67 DNS_R_NOTEXACT */ - "address blackholed", /*%< 68 DNS_R_BLACKHOLED */ - "bad algorithm", /*%< 69 DNS_R_BADALG */ - - "invalid use of a meta type", /*%< 70 DNS_R_METATYPE */ - "CNAME and other data", /*%< 71 DNS_R_CNAMEANDOTHER */ - "multiple RRs of singleton type", /*%< 72 DNS_R_SINGLETON */ - "hint nxrrset", /*%< 73 DNS_R_HINTNXRRSET */ - "no master file configured", /*%< 74 DNS_R_NOMASTERFILE */ - - "unknown protocol", /*%< 75 DNS_R_UNKNOWNPROTO */ - "clocks are unsynchronized", /*%< 76 DNS_R_CLOCKSKEW */ - "IXFR failed", /*%< 77 DNS_R_BADIXFR */ - "not authoritative", /*%< 78 DNS_R_NOTAUTHORITATIVE */ - "no valid KEY", /*%< 79 DNS_R_NOVALIDKEY */ - - "obsolete", /*%< 80 DNS_R_OBSOLETE */ - "already frozen", /*%< 81 DNS_R_FROZEN */ - "unknown flag", /*%< 82 DNS_R_UNKNOWNFLAG */ - "expected a response", /*%< 83 DNS_R_EXPECTEDRESPONSE */ - "no valid DS", /*%< 84 DNS_R_NOVALIDDS */ - - "NS is an address", /*%< 85 DNS_R_NSISADDRESS */ - "received FORMERR", /*%< 86 DNS_R_REMOTEFORMERR */ - "truncated TCP response", /*%< 87 DNS_R_TRUNCATEDTCP */ - "lame server detected", /*%< 88 DNS_R_LAME */ - "unexpected RCODE", /*%< 89 DNS_R_UNEXPECTEDRCODE */ - - "unexpected OPCODE", /*%< 90 DNS_R_UNEXPECTEDOPCODE */ - "chase DS servers", /*%< 91 DNS_R_CHASEDSSERVERS */ - "empty name", /*%< 92 DNS_R_EMPTYNAME */ - "empty wild", /*%< 93 DNS_R_EMPTYWILD */ - "bad bitmap", /*%< 94 DNS_R_BADBITMAP */ - - "from wildcard", /*%< 95 DNS_R_FROMWILDCARD */ - "bad owner name (check-names)", /*%< 96 DNS_R_BADOWNERNAME */ - "bad name (check-names)", /*%< 97 DNS_R_BADNAME */ - "dynamic zone", /*%< 98 DNS_R_DYNAMIC */ - "unknown command", /*%< 99 DNS_R_UNKNOWNCOMMAND */ - - "must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */ - "covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */ - "MX is an address", /*%< 102 DNS_R_MXISADDRESS */ - "duplicate query", /*%< 103 DNS_R_DUPLICATE */ - "invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */ - - "not master", /*%< 105 DNS_R_NOTMASTER */ - "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ - "expired", /*%< 107 DNS_R_EXPIRED */ - "not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */ - "bad EUI", /*%< 109 DNS_R_BADEUI */ - - "covered by negative trust anchor", /*%< 110 DNS_R_NTACOVERED */ - "bad CDS", /*%< 111 DNS_R_BADCDS */ - "bad CDNSKEY", /*%< 112 DNS_R_BADCDNSKEY */ - "malformed OPT option", /*%< 113 DNS_R_OPTERR */ - "malformed DNSTAP data", /*%< 114 DNS_R_BADDNSTAP */ - - "TSIG in wrong location", /*%< 115 DNS_R_BADTSIG */ - "SIG(0) in wrong location", /*%< 116 DNS_R_BADSIG0 */ - "too many records", /*%< 117 DNS_R_TOOMANYRECORDS */ -}; - -static const char *ids[DNS_R_NRESULTS] = { - "DNS_R_LABELTOOLONG", - "DNS_R_BADESCAPE", - /*! - * Note that DNS_R_BADBITSTRING and DNS_R_BITSTRINGTOOLONG are - * deprecated. - */ - "DNS_R_BADBITSTRING", - "DNS_R_BITSTRINGTOOLONG", - "DNS_R_EMPTYLABEL", - "DNS_R_BADDOTTEDQUAD", - "DNS_R_INVALIDNS", - "DNS_R_UNKNOWN", - "DNS_R_BADLABELTYPE", - "DNS_R_BADPOINTER", - "DNS_R_TOOMANYHOPS", - "DNS_R_DISALLOWED", - "DNS_R_EXTRATOKEN", - "DNS_R_EXTRADATA", - "DNS_R_TEXTTOOLONG", - "DNS_R_NOTZONETOP", - "DNS_R_SYNTAX", - "DNS_R_BADCKSUM", - "DNS_R_BADAAAA", - "DNS_R_NOOWNER", - "DNS_R_NOTTL", - "DNS_R_BADCLASS", - "DNS_R_NAMETOOLONG", - "DNS_R_PARTIALMATCH", - "DNS_R_NEWORIGIN", - "DNS_R_UNCHANGED", - "DNS_R_BADTTL", - "DNS_R_NOREDATA", - "DNS_R_CONTINUE", - "DNS_R_DELEGATION", - "DNS_R_GLUE", - "DNS_R_DNAME", - "DNS_R_CNAME", - "DNS_R_BADDB", - "DNS_R_ZONECUT", - "DNS_R_BADZONE", - "DNS_R_MOREDATA", - "DNS_R_UPTODATE", - "DNS_R_TSIGVERIFYFAILURE", - "DNS_R_TSIGERRORSET", - "DNS_R_SIGINVALID", - "DNS_R_SIGEXPIRED", - "DNS_R_SIGFUTURE", - "DNS_R_KEYUNAUTHORIZED", - "DNS_R_INVALIDTIME", - "DNS_R_EXPECTEDTSIG", - "DNS_R_UNEXPECTEDTSIG", - "DNS_R_INVALIDTKEY", - "DNS_R_HINT", - "DNS_R_DROP", - "DNS_R_NOTLOADED", - "DNS_R_NCACHENXDOMAIN", - "DNS_R_NCACHENXRRSET", - "DNS_R_WAIT", - "DNS_R_NOTVERIFIEDYET", - "DNS_R_NOIDENTITY", - "DNS_R_NOJOURNAL", - "DNS_R_ALIAS", - "DNS_R_USETCP", - "DNS_R_NOVALIDSIG", - "DNS_R_NOVALIDNSEC", - "DNS_R_NOTINSECURE", - "DNS_R_UNKNOWNSERVICE", - "DNS_R_RECOVERABLE", - "DNS_R_UNKNOWNOPT", - "DNS_R_UNEXPECTEDID", - "DNS_R_SEENINCLUDE", - "DNS_R_NOTEXACT", - "DNS_R_BLACKHOLED", - "DNS_R_BADALG", - "DNS_R_METATYPE", - "DNS_R_CNAMEANDOTHER", - "DNS_R_SINGLETON", - "DNS_R_HINTNXRRSET", - "DNS_R_NOMASTERFILE", - "DNS_R_UNKNOWNPROTO", - "DNS_R_CLOCKSKEW", - "DNS_R_BADIXFR", - "DNS_R_NOTAUTHORITATIVE", - "DNS_R_NOVALIDKEY", - "DNS_R_OBSOLETE", - "DNS_R_FROZEN", - "DNS_R_UNKNOWNFLAG", - "DNS_R_EXPECTEDRESPONSE", - "DNS_R_NOVALIDDS", - "DNS_R_NSISADDRESS", - "DNS_R_REMOTEFORMERR", - "DNS_R_TRUNCATEDTCP", - "DNS_R_LAME", - "DNS_R_UNEXPECTEDRCODE", - "DNS_R_UNEXPECTEDOPCODE", - "DNS_R_CHASEDSSERVERS", - "DNS_R_EMPTYNAME", - "DNS_R_EMPTYWILD", - "DNS_R_BADBITMAP", - "DNS_R_FROMWILDCARD", - "DNS_R_BADOWNERNAME", - "DNS_R_BADNAME", - "DNS_R_DYNAMIC", - "DNS_R_UNKNOWNCOMMAND", - "DNS_R_MUSTBESECURE", - "DNS_R_COVERINGNSEC", - "DNS_R_MXISADDRESS", - "DNS_R_DUPLICATE", - "DNS_R_INVALIDNSEC3", - "DNS_R_NOTMASTER", - "DNS_R_BROKENCHAIN", - "DNS_R_EXPIRED", - "DNS_R_NOTDYNAMIC", - "DNS_R_BADEUI", - "DNS_R_NTACOVERED", - "DNS_R_BADCDS", - "DNS_R_BADCDNSKEY", - "DNS_R_OPTERR", - "DNS_R_BADDNSTAP", - "DNS_R_BADTSIG", - "DNS_R_BADSIG0", - "DNS_R_TOOMANYRECORDS", -}; - -static const char *rcode_text[DNS_R_NRCODERESULTS] = { - "NOERROR", /*%< 0 DNS_R_NOERROR */ - "FORMERR", /*%< 1 DNS_R_FORMERR */ - "SERVFAIL", /*%< 2 DNS_R_SERVFAIL */ - "NXDOMAIN", /*%< 3 DNS_R_NXDOMAIN */ - "NOTIMP", /*%< 4 DNS_R_NOTIMP */ - - "REFUSED", /*%< 5 DNS_R_REFUSED */ - "YXDOMAIN", /*%< 6 DNS_R_YXDOMAIN */ - "YXRRSET", /*%< 7 DNS_R_YXRRSET */ - "NXRRSET", /*%< 8 DNS_R_NXRRSET */ - "NOTAUTH", /*%< 9 DNS_R_NOTAUTH */ - - "NOTZONE", /*%< 10 DNS_R_NOTZONE */ - "", /*%< 11 DNS_R_RCODE11 */ - "", /*%< 12 DNS_R_RCODE12 */ - "", /*%< 13 DNS_R_RCODE13 */ - "", /*%< 14 DNS_R_RCODE14 */ - - "", /*%< 15 DNS_R_RCODE15 */ - "BADVERS", /*%< 16 DNS_R_BADVERS */ -}; - -static const char *rcode_ids[DNS_R_NRCODERESULTS] = { - "DNS_R_NOERROR", - "DNS_R_FORMERR", - "DNS_R_SERVFAIL", - "DNS_R_NXDOMAIN", - "DNS_R_NOTIMP", - "DNS_R_REFUSED", - "DNS_R_YXDOMAIN", - "DNS_R_YXRRSET", - "DNS_R_NXRRSET", - "DNS_R_NOTAUTH", - "DNS_R_NOTZONE", - "DNS_R_RCODE11", - "RNS_R_RCODE12", - "DNS_R_RCODE13", - "DNS_R_RCODE14", - "DNS_R_RCODE15", - "DNS_R_BADVERS", -}; - -#define DNS_RESULT_RESULTSET 2 -#define DNS_RESULT_RCODERESULTSET 3 - -static isc_once_t once = ISC_ONCE_INIT; - -static void -initialize_action(void) { - isc_result_t result; - - result = isc_result_register(ISC_RESULTCLASS_DNS, DNS_R_NRESULTS, - text, dns_msgcat, DNS_RESULT_RESULTSET); - if (result == ISC_R_SUCCESS) - result = isc_result_register(ISC_RESULTCLASS_DNSRCODE, - DNS_R_NRCODERESULTS, - rcode_text, dns_msgcat, - DNS_RESULT_RCODERESULTSET); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_result_register() failed: %u", result); - - result = isc_result_registerids(ISC_RESULTCLASS_DNS, DNS_R_NRESULTS, - ids, dns_msgcat, DNS_RESULT_RESULTSET); - if (result == ISC_R_SUCCESS) - result = isc_result_registerids(ISC_RESULTCLASS_DNSRCODE, - DNS_R_NRCODERESULTS, - rcode_ids, dns_msgcat, - DNS_RESULT_RCODERESULTSET); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_result_registerids() failed: %u", result); -} - -static void -initialize(void) { - dns_lib_initmsgcat(); - RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); -} - -const char * -dns_result_totext(isc_result_t result) { - initialize(); - - return (isc_result_totext(result)); -} - -void -dns_result_register(void) { - initialize(); -} - -dns_rcode_t -dns_result_torcode(isc_result_t result) { - dns_rcode_t rcode = dns_rcode_servfail; - - if (DNS_RESULT_ISRCODE(result)) { - /* - * Rcodes can't be bigger than 12 bits, which is why we - * AND with 0xFFF instead of 0xFFFF. - */ - return ((dns_rcode_t)((result) & 0xFFF)); - } - - /* - * Try to supply an appropriate rcode. - */ - switch (result) { - case ISC_R_SUCCESS: - rcode = dns_rcode_noerror; - break; - case ISC_R_BADBASE64: - case ISC_R_RANGE: - case ISC_R_UNEXPECTEDEND: - case DNS_R_BADAAAA: - /* case DNS_R_BADBITSTRING: deprecated */ - case DNS_R_BADCKSUM: - case DNS_R_BADCLASS: - case DNS_R_BADLABELTYPE: - case DNS_R_BADPOINTER: - case DNS_R_BADTTL: - case DNS_R_BADZONE: - /* case DNS_R_BITSTRINGTOOLONG: deprecated */ - case DNS_R_EXTRADATA: - case DNS_R_LABELTOOLONG: - case DNS_R_NOREDATA: - case DNS_R_SYNTAX: - case DNS_R_TEXTTOOLONG: - case DNS_R_TOOMANYHOPS: - case DNS_R_TSIGERRORSET: - case DNS_R_UNKNOWN: - case DNS_R_NAMETOOLONG: - case DNS_R_OPTERR: - rcode = dns_rcode_formerr; - break; - case DNS_R_DISALLOWED: - rcode = dns_rcode_refused; - break; - case DNS_R_TSIGVERIFYFAILURE: - case DNS_R_CLOCKSKEW: - rcode = dns_rcode_notauth; - break; - default: - rcode = dns_rcode_servfail; - } - - return (rcode); -} diff --git a/lib/dns-pkcs11/rootns.c b/lib/dns-pkcs11/rootns.c deleted file mode 100644 index 9653f3b..0000000 --- a/lib/dns-pkcs11/rootns.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char root_ns[] = -";\n" -"; Internet Root Nameservers\n" -";\n" -"$TTL 518400\n" -". 518400 IN NS A.ROOT-SERVERS.NET.\n" -". 518400 IN NS B.ROOT-SERVERS.NET.\n" -". 518400 IN NS C.ROOT-SERVERS.NET.\n" -". 518400 IN NS D.ROOT-SERVERS.NET.\n" -". 518400 IN NS E.ROOT-SERVERS.NET.\n" -". 518400 IN NS F.ROOT-SERVERS.NET.\n" -". 518400 IN NS G.ROOT-SERVERS.NET.\n" -". 518400 IN NS H.ROOT-SERVERS.NET.\n" -". 518400 IN NS I.ROOT-SERVERS.NET.\n" -". 518400 IN NS J.ROOT-SERVERS.NET.\n" -". 518400 IN NS K.ROOT-SERVERS.NET.\n" -". 518400 IN NS L.ROOT-SERVERS.NET.\n" -". 518400 IN NS M.ROOT-SERVERS.NET.\n" -"A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4\n" -"A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n" -"B.ROOT-SERVERS.NET. 3600000 IN A 199.9.14.201\n" -"B.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:200::b\n" -"C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n" -"C.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2::c\n" -"D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n" -"D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d\n" -"E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n" -"E.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:a8::e\n" -"F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n" -"F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2F::F\n" -"G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4\n" -"G.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:12::d0d\n" -"H.ROOT-SERVERS.NET. 3600000 IN A 198.97.190.53\n" -"H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::53\n" -"I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17\n" -"I.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fe::53\n" -"J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30\n" -"J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:C27::2:30\n" -"K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129\n" -"K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7FD::1\n" -"L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42\n" -"L.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:9f::42\n" -"M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33\n" -"M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:DC3::35\n"; - -static isc_result_t -in_rootns(dns_rdataset_t *rootns, dns_name_t *name) { - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_ns_t ns; - - if (!dns_rdataset_isassociated(rootns)) - return (ISC_R_NOTFOUND); - - result = dns_rdataset_first(rootns); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(rootns, &rdata); - result = dns_rdata_tostruct(&rdata, &ns, NULL); - if (result != ISC_R_SUCCESS) - return (result); - if (dns_name_compare(name, &ns.name) == 0) - return (ISC_R_SUCCESS); - result = dns_rdataset_next(rootns); - dns_rdata_reset(&rdata); - } - if (result == ISC_R_NOMORE) - result = ISC_R_NOTFOUND; - return (result); -} - -static isc_result_t -check_node(dns_rdataset_t *rootns, dns_name_t *name, - dns_rdatasetiter_t *rdsiter) { - isc_result_t result; - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - switch (rdataset.type) { - case dns_rdatatype_a: - case dns_rdatatype_aaaa: - result = in_rootns(rootns, name); - if (result != ISC_R_SUCCESS) - goto cleanup; - break; - case dns_rdatatype_ns: - if (dns_name_compare(name, dns_rootname) == 0) - break; - /* FALLTHROUGH */ - default: - result = ISC_R_FAILURE; - goto cleanup; - } - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - cleanup: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - return (result); -} - -static isc_result_t -check_hints(dns_db_t *db) { - isc_result_t result; - dns_rdataset_t rootns; - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL; - isc_stdtime_t now; - dns_fixedname_t fixname; - dns_name_t *name; - dns_rdatasetiter_t *rdsiter = NULL; - - isc_stdtime_get(&now); - - name = dns_fixedname_initname(&fixname); - - dns_rdataset_init(&rootns); - (void)dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0, - now, NULL, name, &rootns, NULL); - result = dns_db_createiterator(db, 0, &dbiter); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_dbiterator_first(dbiter); - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(dbiter, &node, name); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_db_allrdatasets(db, node, NULL, now, &rdsiter); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = check_node(&rootns, name, rdsiter); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(dbiter); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup: - if (dns_rdataset_isassociated(&rootns)) - dns_rdataset_disassociate(&rootns); - if (rdsiter != NULL) - dns_rdatasetiter_destroy(&rdsiter); - if (node != NULL) - dns_db_detachnode(db, &node); - if (dbiter != NULL) - dns_dbiterator_destroy(&dbiter); - return (result); -} - -isc_result_t -dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, - const char *filename, dns_db_t **target) -{ - isc_result_t result, eresult; - isc_buffer_t source; - unsigned int len; - dns_rdatacallbacks_t callbacks; - dns_db_t *db = NULL; - - REQUIRE(target != NULL && *target == NULL); - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - rdclass, 0, NULL, &db); - if (result != ISC_R_SUCCESS) - goto failure; - - len = strlen(root_ns); - isc_buffer_init(&source, root_ns, len); - isc_buffer_add(&source, len); - - dns_rdatacallbacks_init(&callbacks); - result = dns_db_beginload(db, &callbacks); - if (result != ISC_R_SUCCESS) - goto failure; - if (filename != NULL) { - /* - * Load the hints from the specified filename. - */ - result = dns_master_loadfile(filename, &db->origin, - &db->origin, db->rdclass, - DNS_MASTER_HINT, - &callbacks, db->mctx); - } else if (rdclass == dns_rdataclass_in) { - /* - * Default to using the Internet root servers. - */ - result = dns_master_loadbuffer(&source, &db->origin, - &db->origin, db->rdclass, - DNS_MASTER_HINT, - &callbacks, db->mctx); - } else - result = ISC_R_NOTFOUND; - eresult = dns_db_endload(db, &callbacks); - if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) - result = eresult; - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - goto failure; - if (check_hints(db) != ISC_R_SUCCESS) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "extra data in root hints '%s'", - (filename != NULL) ? filename : ""); - *target = db; - return (ISC_R_SUCCESS); - - failure: - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, - ISC_LOG_ERROR, "could not configure root hints from " - "'%s': %s", (filename != NULL) ? filename : "", - isc_result_totext(result)); - - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static void -report(dns_view_t *view, dns_name_t *name, bool missing, - dns_rdata_t *rdata) -{ - const char *viewname = "", *sep = ""; - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char databuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; - isc_buffer_t buffer; - isc_result_t result; - - if (strcmp(view->name, "_bind") != 0 && - strcmp(view->name, "_default") != 0) { - viewname = view->name; - sep = ": view "; - } - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); - isc_buffer_init(&buffer, databuf, sizeof(databuf) - 1); - result = dns_rdata_totext(rdata, NULL, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - databuf[isc_buffer_usedlength(&buffer)] = '\0'; - - if (missing) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: %s/%s (%s) missing from hints", - sep, viewname, namebuf, typebuf, databuf); - else - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: %s/%s (%s) extra record " - "in hints", sep, viewname, namebuf, typebuf, - databuf); -} - -static bool -inrrset(dns_rdataset_t *rrset, dns_rdata_t *rdata) { - isc_result_t result; - dns_rdata_t current = DNS_RDATA_INIT; - - result = dns_rdataset_first(rrset); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(rrset, ¤t); - if (dns_rdata_compare(rdata, ¤t) == 0) - return (true); - dns_rdata_reset(¤t); - result = dns_rdataset_next(rrset); - } - return (false); -} - -/* - * Check that the address RRsets match. - * - * Note we don't complain about missing glue records. - */ - -static void -check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db, - dns_name_t *name, isc_stdtime_t now) -{ - isc_result_t hresult, rresult, result; - dns_rdataset_t hintrrset, rootrrset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_name_t *foundname; - dns_fixedname_t fixed; - - dns_rdataset_init(&hintrrset); - dns_rdataset_init(&rootrrset); - foundname = dns_fixedname_initname(&fixed); - - hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0, - now, NULL, foundname, &hintrrset, NULL); - rresult = dns_db_find(db, name, NULL, dns_rdatatype_a, - DNS_DBFIND_GLUEOK, now, NULL, foundname, - &rootrrset, NULL); - if (hresult == ISC_R_SUCCESS && - (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { - result = dns_rdataset_first(&rootrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rootrrset, &rdata); - if (!inrrset(&hintrrset, &rdata)) - report(view, name, true, &rdata); - result = dns_rdataset_next(&rootrrset); - } - result = dns_rdataset_first(&hintrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&hintrrset, &rdata); - if (!inrrset(&rootrrset, &rdata)) - report(view, name, false, &rdata); - result = dns_rdataset_next(&hintrrset); - } - } - if (hresult == ISC_R_NOTFOUND && - (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { - result = dns_rdataset_first(&rootrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rootrrset, &rdata); - report(view, name, true, &rdata); - result = dns_rdataset_next(&rootrrset); - } - } - if (dns_rdataset_isassociated(&rootrrset)) - dns_rdataset_disassociate(&rootrrset); - if (dns_rdataset_isassociated(&hintrrset)) - dns_rdataset_disassociate(&hintrrset); - - /* - * Check AAAA records. - */ - hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0, - now, NULL, foundname, &hintrrset, NULL); - rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, - DNS_DBFIND_GLUEOK, now, NULL, foundname, - &rootrrset, NULL); - if (hresult == ISC_R_SUCCESS && - (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { - result = dns_rdataset_first(&rootrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rootrrset, &rdata); - if (!inrrset(&hintrrset, &rdata)) - report(view, name, true, &rdata); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rootrrset); - } - result = dns_rdataset_first(&hintrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&hintrrset, &rdata); - if (!inrrset(&rootrrset, &rdata)) - report(view, name, false, &rdata); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&hintrrset); - } - } - if (hresult == ISC_R_NOTFOUND && - (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { - result = dns_rdataset_first(&rootrrset); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rootrrset, &rdata); - report(view, name, true, &rdata); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rootrrset); - } - } - if (dns_rdataset_isassociated(&rootrrset)) - dns_rdataset_disassociate(&rootrrset); - if (dns_rdataset_isassociated(&hintrrset)) - dns_rdataset_disassociate(&hintrrset); -} - -void -dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) { - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_ns_t ns; - dns_rdataset_t hintns, rootns; - const char *viewname = "", *sep = ""; - isc_stdtime_t now; - dns_name_t *name; - dns_fixedname_t fixed; - - REQUIRE(hints != NULL); - REQUIRE(db != NULL); - REQUIRE(view != NULL); - - isc_stdtime_get(&now); - - if (strcmp(view->name, "_bind") != 0 && - strcmp(view->name, "_default") != 0) { - viewname = view->name; - sep = ": view "; - } - - dns_rdataset_init(&hintns); - dns_rdataset_init(&rootns); - name = dns_fixedname_initname(&fixed); - - result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0, - now, NULL, name, &hintns, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: unable to get root NS rrset " - "from hints: %s", sep, viewname, - dns_result_totext(result)); - goto cleanup; - } - - result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0, - now, NULL, name, &rootns, NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: unable to get root NS rrset " - "from cache: %s", sep, viewname, - dns_result_totext(result)); - goto cleanup; - } - - /* - * Look for missing root NS names. - */ - result = dns_rdataset_first(&rootns); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&rootns, &rdata); - result = dns_rdata_tostruct(&rdata, &ns, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = in_rootns(&hintns, &ns.name); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - /* missing from hints */ - dns_name_format(&ns.name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: unable to find root " - "NS '%s' in hints", sep, viewname, - namebuf); - } else - check_address_records(view, hints, db, &ns.name, now); - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rootns); - } - if (result != ISC_R_NOMORE) { - goto cleanup; - } - - /* - * Look for extra root NS names. - */ - result = dns_rdataset_first(&hintns); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&hintns, &rdata); - result = dns_rdata_tostruct(&rdata, &ns, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = in_rootns(&rootns, &ns.name); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - /* extra entry in hints */ - dns_name_format(&ns.name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, - "checkhints%s%s: extra NS '%s' in hints", - sep, viewname, namebuf); - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&hintns); - } - if (result != ISC_R_NOMORE) { - goto cleanup; - } - - cleanup: - if (dns_rdataset_isassociated(&rootns)) - dns_rdataset_disassociate(&rootns); - if (dns_rdataset_isassociated(&hintns)) - dns_rdataset_disassociate(&hintns); -} diff --git a/lib/dns-pkcs11/rpz.c b/lib/dns-pkcs11/rpz.c deleted file mode 100644 index 8cb0781..0000000 --- a/lib/dns-pkcs11/rpz.c +++ /dev/null @@ -1,2472 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * Parallel radix trees for databases of response policy IP addresses - * - * The radix or patricia trees are somewhat specialized to handle response - * policy addresses by representing the two sets of IP addresses and name - * server IP addresses in a single tree. One set of IP addresses is - * for rpz-ip policies or policies triggered by addresses in A or - * AAAA records in responses. - * The second set is for rpz-nsip policies or policies triggered by addresses - * in A or AAAA records for NS records that are authorities for responses. - * - * Each leaf indicates that an IP address is listed in the IP address or the - * name server IP address policy sub-zone (or both) of the corresponding - * response policy zone. The policy data such as a CNAME or an A record - * is kept in the policy zone. After an IP address has been found in a radix - * tree, the node in the policy zone's database is found by converting - * the IP address to a domain name in a canonical form. - * - * - * The response policy zone canonical form of an IPv6 address is one of: - * prefix.W.W.W.W.W.W.W.W - * prefix.WORDS.zz - * prefix.WORDS.zz.WORDS - * prefix.zz.WORDS - * where - * prefix is the prefix length of the IPv6 address between 1 and 128 - * W is a number between 0 and 65535 - * WORDS is one or more numbers W separated with "." - * zz corresponds to :: in the standard IPv6 text representation - * - * The canonical form of IPv4 addresses is: - * prefix.B.B.B.B - * where - * prefix is the prefix length of the address between 1 and 32 - * B is a number between 0 and 255 - * - * Names for IPv4 addresses are distinguished from IPv6 addresses by having - * 5 labels all of which are numbers, and a prefix between 1 and 32. - */ - - -/* - * Use a private definition of IPv6 addresses because s6_addr32 is not - * always defined and our IPv6 addresses are in non-standard byte order - */ -typedef uint32_t dns_rpz_cidr_word_t; -#define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t)*8) -#define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t)*8) -#define DNS_RPZ_CIDR_WORDS (128/DNS_RPZ_CIDR_WORD_BITS) -typedef struct { - dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS]; -} dns_rpz_cidr_key_t; - -#define ADDR_V4MAPPED 0xffff -#define KEY_IS_IPV4(prefix,ip) ((prefix) >= 96 && (ip)->w[0] == 0 && \ - (ip)->w[1] == 0 && (ip)->w[2] == ADDR_V4MAPPED) - -#define DNS_RPZ_WORD_MASK(b) ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \ - : ((dns_rpz_cidr_word_t)(-1) \ - << (DNS_RPZ_CIDR_WORD_BITS - (b)))) - -/* - * Get bit #n from the array of words of an IP address. - */ -#define DNS_RPZ_IP_BIT(ip, n) (1 & ((ip)->w[(n)/DNS_RPZ_CIDR_WORD_BITS] >> \ - (DNS_RPZ_CIDR_WORD_BITS \ - - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS)))) - -/* - * A triplet of arrays of bits flagging the existence of - * client-IP, IP, and NSIP policy triggers. - */ -typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t; -struct dns_rpz_addr_zbits { - dns_rpz_zbits_t client_ip; - dns_rpz_zbits_t ip; - dns_rpz_zbits_t nsip; -}; - -/* - * A CIDR or radix tree node. - */ -struct dns_rpz_cidr_node { - dns_rpz_cidr_node_t *parent; - dns_rpz_cidr_node_t *child[2]; - dns_rpz_cidr_key_t ip; - dns_rpz_prefix_t prefix; - dns_rpz_addr_zbits_t set; - dns_rpz_addr_zbits_t sum; -}; - -/* - * A pair of arrays of bits flagging the existence of - * QNAME and NSDNAME policy triggers. - */ -typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t; -struct dns_rpz_nm_zbits { - dns_rpz_zbits_t qname; - dns_rpz_zbits_t ns; -}; - -/* - * The data in a RBT node has two pairs of bits for policy zones. - * One pair is for the corresponding name of the node such as example.com - * and the other pair is for a wildcard child such as *.example.com. - */ -typedef struct dns_rpz_nm_data dns_rpz_nm_data_t; -struct dns_rpz_nm_data { - dns_rpz_nm_zbits_t set; - dns_rpz_nm_zbits_t wild; -}; - -#if 0 -/* - * Catch a name while debugging. - */ -static void -catch_name(const dns_name_t *src_name, const char *tgt, const char *str) { - dns_fixedname_t tgt_namef; - dns_name_t *tgt_name; - - tgt_name = dns_fixedname_initname(&tgt_namef); - dns_name_fromstring(tgt_name, tgt, DNS_NAME_DOWNCASE, NULL); - if (dns_name_equal(src_name, tgt_name)) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz hit failed: %s %s", str, tgt); - } -} -#endif - -const char * -dns_rpz_type2str(dns_rpz_type_t type) { - switch (type) { - case DNS_RPZ_TYPE_CLIENT_IP: - return ("CLIENT-IP"); - case DNS_RPZ_TYPE_QNAME: - return ("QNAME"); - case DNS_RPZ_TYPE_IP: - return ("IP"); - case DNS_RPZ_TYPE_NSIP: - return ("NSIP"); - case DNS_RPZ_TYPE_NSDNAME: - return ("NSDNAME"); - case DNS_RPZ_TYPE_BAD: - break; - } - FATAL_ERROR(__FILE__, __LINE__, "impossible rpz type %d", type); - return ("impossible"); -} - -dns_rpz_policy_t -dns_rpz_str2policy(const char *str) { - static struct { - const char *str; - dns_rpz_policy_t policy; - } tbl[] = { - {"given", DNS_RPZ_POLICY_GIVEN}, - {"disabled", DNS_RPZ_POLICY_DISABLED}, - {"passthru", DNS_RPZ_POLICY_PASSTHRU}, - {"drop", DNS_RPZ_POLICY_DROP}, - {"tcp-only", DNS_RPZ_POLICY_TCP_ONLY}, - {"nxdomain", DNS_RPZ_POLICY_NXDOMAIN}, - {"nodata", DNS_RPZ_POLICY_NODATA}, - {"cname", DNS_RPZ_POLICY_CNAME}, - {"no-op", DNS_RPZ_POLICY_PASSTHRU}, /* old passthru */ - }; - unsigned int n; - - if (str == NULL) - return (DNS_RPZ_POLICY_ERROR); - for (n = 0; n < sizeof(tbl)/sizeof(tbl[0]); ++n) { - if (!strcasecmp(tbl[n].str, str)) - return (tbl[n].policy); - } - return (DNS_RPZ_POLICY_ERROR); -} - -const char * -dns_rpz_policy2str(dns_rpz_policy_t policy) { - const char *str; - - switch (policy) { - case DNS_RPZ_POLICY_PASSTHRU: - str = "PASSTHRU"; - break; - case DNS_RPZ_POLICY_DROP: - str = "DROP"; - break; - case DNS_RPZ_POLICY_TCP_ONLY: - str = "TCP-ONLY"; - break; - case DNS_RPZ_POLICY_NXDOMAIN: - str = "NXDOMAIN"; - break; - case DNS_RPZ_POLICY_NODATA: - str = "NODATA"; - break; - case DNS_RPZ_POLICY_RECORD: - str = "Local-Data"; - break; - case DNS_RPZ_POLICY_CNAME: - case DNS_RPZ_POLICY_WILDCNAME: - str = "CNAME"; - break; - case DNS_RPZ_POLICY_MISS: - str = "MISS"; - break; - case DNS_RPZ_POLICY_DNS64: - str = "DNS64"; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - return (str); -} - -/* - * Return the bit number of the highest set bit in 'zbit'. - * (for example, 0x01 returns 0, 0xFF returns 7, etc.) - */ -static int -zbit_to_num(dns_rpz_zbits_t zbit) { - dns_rpz_num_t rpz_num; - - REQUIRE(zbit != 0); - rpz_num = 0; -#if DNS_RPZ_MAX_ZONES > 32 - if ((zbit & 0xffffffff00000000L) != 0) { - zbit >>= 32; - rpz_num += 32; - } -#endif - if ((zbit & 0xffff0000) != 0) { - zbit >>= 16; - rpz_num += 16; - } - if ((zbit & 0xff00) != 0) { - zbit >>= 8; - rpz_num += 8; - } - if ((zbit & 0xf0) != 0) { - zbit >>= 4; - rpz_num += 4; - } - if ((zbit & 0xc) != 0) { - zbit >>= 2; - rpz_num += 2; - } - if ((zbit & 2) != 0) - ++rpz_num; - return (rpz_num); -} - -/* - * Make a set of bit masks given one or more bits and their type. - */ -static void -make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits, - dns_rpz_type_t type) -{ - switch (type) { - case DNS_RPZ_TYPE_CLIENT_IP: - tgt_set->client_ip = zbits; - tgt_set->ip = 0; - tgt_set->nsip = 0; - break; - case DNS_RPZ_TYPE_IP: - tgt_set->client_ip = 0; - tgt_set->ip = zbits; - tgt_set->nsip = 0; - break; - case DNS_RPZ_TYPE_NSIP: - tgt_set->client_ip = 0; - tgt_set->ip = 0; - tgt_set->nsip = zbits; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static void -make_nm_set(dns_rpz_nm_zbits_t *tgt_set, - dns_rpz_num_t rpz_num, dns_rpz_type_t type) -{ - switch (type) { - case DNS_RPZ_TYPE_QNAME: - tgt_set->qname = DNS_RPZ_ZBIT(rpz_num); - tgt_set->ns = 0; - break; - case DNS_RPZ_TYPE_NSDNAME: - tgt_set->qname = 0; - tgt_set->ns = DNS_RPZ_ZBIT(rpz_num); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -/* - * Mark a node and all of its parents as having client-IP, IP, or NSIP data - */ -static void -set_sum_pair(dns_rpz_cidr_node_t *cnode) { - dns_rpz_cidr_node_t *child; - dns_rpz_addr_zbits_t sum; - - do { - sum = cnode->set; - - child = cnode->child[0]; - if (child != NULL) { - sum.client_ip |= child->sum.client_ip; - sum.ip |= child->sum.ip; - sum.nsip |= child->sum.nsip; - } - - child = cnode->child[1]; - if (child != NULL) { - sum.client_ip |= child->sum.client_ip; - sum.ip |= child->sum.ip; - sum.nsip |= child->sum.nsip; - } - - if (cnode->sum.client_ip == sum.client_ip && - cnode->sum.ip == sum.ip && - cnode->sum.nsip == sum.nsip) - break; - cnode->sum = sum; - cnode = cnode->parent; - } while (cnode != NULL); -} - -/* Caller must hold rpzs->maint_lock */ -static void -fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) { - dns_rpz_zbits_t mask; - - /* - * qname_wait_recurse and qname_skip_recurse are used to - * implement the "qname-wait-recurse" config option. - * - * When "qname-wait-recurse" is yes, no processing happens - * without recursion. In this case, qname_wait_recurse is true, - * and qname_skip_recurse (a bitfield indicating which policy - * zones can be processed without recursion) is set to all 0's - * by fix_qname_skip_recurse(). - * - * When "qname-wait-recurse" is no, qname_skip_recurse may be - * set to a non-zero value by fix_qname_skip_recurse(). The mask - * has to have bits set for the policy zones for which - * processing may continue without recursion, and bits cleared - * for the rest. - * - * (1) The ARM says: - * - * The "qname-wait-recurse no" option overrides that default - * behavior when recursion cannot change a non-error - * response. The option does not affect QNAME or client-IP - * triggers in policy zones listed after other zones - * containing IP, NSIP and NSDNAME triggers, because those may - * depend on the A, AAAA, and NS records that would be found - * during recursive resolution. - * - * Let's consider the following: - * - * zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | - * rpzs->have.nsdname | - * rpzs->have.nsipv4 | rpzs->have.nsipv6); - * - * zbits_req now contains bits set for zones which require - * recursion. - * - * But going by the description in the ARM, if the first policy - * zone requires recursion, then all zones after that (higher - * order bits) have to wait as well. If the Nth zone requires - * recursion, then (N+1)th zone onwards all need to wait. - * - * So mapping this, examples: - * - * zbits_req = 0b000 mask = 0xffffffff (no zones have to wait for - * recursion) - * zbits_req = 0b001 mask = 0x00000000 (all zones have to wait) - * zbits_req = 0b010 mask = 0x00000001 (the first zone doesn't have to - * wait, second zone onwards need - * to wait) - * zbits_req = 0b011 mask = 0x00000000 (all zones have to wait) - * zbits_req = 0b100 mask = 0x00000011 (the 1st and 2nd zones don't - * have to wait, third zone - * onwards need to wait) - * - * More generally, we have to count the number of trailing 0 - * bits in zbits_req and only these can be processed without - * recursion. All the rest need to wait. - * - * (2) The ARM says that "qname-wait-recurse no" option - * overrides the default behavior when recursion cannot change a - * non-error response. So, in the order of listing of policy - * zones, within the first policy zone where recursion may be - * required, we should first allow CLIENT-IP and QNAME policy - * records to be attempted without recursion. - */ - - /* - * Get a mask covering all policy zones that are not subordinate to - * other policy zones containing triggers that require that the - * qname be resolved before they can be checked. - */ - rpzs->have.client_ip = rpzs->have.client_ipv4 | rpzs->have.client_ipv6; - rpzs->have.ip = rpzs->have.ipv4 | rpzs->have.ipv6; - rpzs->have.nsip = rpzs->have.nsipv4 | rpzs->have.nsipv6; - - if (rpzs->p.qname_wait_recurse) { - mask = 0; - } else { - dns_rpz_zbits_t zbits_req; - dns_rpz_zbits_t zbits_notreq; - dns_rpz_zbits_t mask2; - dns_rpz_zbits_t req_mask; - - /* - * Get the masks of zones with policies that - * do/don't require recursion - */ - - zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | - rpzs->have.nsdname | - rpzs->have.nsipv4 | rpzs->have.nsipv6); - zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname); - - if (zbits_req == 0) { - mask = DNS_RPZ_ALL_ZBITS; - goto set; - } - - /* - * req_mask is a mask covering used bits in - * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111, - * 0b11010101 => 0b11111111). - */ - req_mask = zbits_req; - req_mask |= req_mask >> 1; - req_mask |= req_mask >> 2; - req_mask |= req_mask >> 4; - req_mask |= req_mask >> 8; - req_mask |= req_mask >> 16; -#if DNS_RPZ_MAX_ZONES > 32 - req_mask |= req_mask >> 32; -#endif - - /* - * There's no point in skipping recursion for a later - * zone if it is required in a previous zone. - */ - if ((zbits_notreq & req_mask) == 0) { - mask = 0; - goto set; - } - - /* - * This bit arithmetic creates a mask of zones in which - * it is okay to skip recursion. After the first zone - * that has to wait for recursion, all the others have - * to wait as well, so we want to create a mask in which - * all the trailing zeroes in zbits_req are are 1, and - * more significant bits are 0. (For instance, - * 0x0700 => 0x00ff, 0x0007 => 0x0000) - */ - mask = ~(zbits_req | ((~zbits_req) + 1)); - - /* - * As mentioned in (2) above, the zone corresponding to - * the least significant zero could have its CLIENT-IP - * and QNAME policies checked before recursion, if it - * has any of those policies. So if it does, we - * can set its 0 to 1. - * - * Locate the least significant 0 bit in the mask (for - * instance, 0xff => 0x100)... - */ - mask2 = (mask << 1) & ~mask; - - /* - * Also set the bit for zone 0, because if it's in - * zbits_notreq then it's definitely okay to attempt to - * skip recursion for zone 0... - */ - mask2 |= 1; - - /* Clear any bits *not* in zbits_notreq... */ - mask2 &= zbits_notreq; - - /* And merge the result into the skip-recursion mask */ - mask |= mask2; - } - - set: - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, - DNS_RPZ_DEBUG_QUIET, - "computed RPZ qname_skip_recurse mask=0x%" PRIx64, - (uint64_t) mask); - rpzs->have.qname_skip_recurse = mask; -} - -static void -adj_trigger_cnt(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, - const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, - bool inc) -{ - dns_rpz_trigger_counter_t *cnt = NULL; - dns_rpz_zbits_t *have = NULL; - - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - REQUIRE(tgt_ip != NULL); - if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { - cnt = &rpzs->triggers[rpz_num].client_ipv4; - have = &rpzs->have.client_ipv4; - } else { - cnt = &rpzs->triggers[rpz_num].client_ipv6; - have = &rpzs->have.client_ipv6; - } - break; - case DNS_RPZ_TYPE_QNAME: - cnt = &rpzs->triggers[rpz_num].qname; - have = &rpzs->have.qname; - break; - case DNS_RPZ_TYPE_IP: - REQUIRE(tgt_ip != NULL); - if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { - cnt = &rpzs->triggers[rpz_num].ipv4; - have = &rpzs->have.ipv4; - } else { - cnt = &rpzs->triggers[rpz_num].ipv6; - have = &rpzs->have.ipv6; - } - break; - case DNS_RPZ_TYPE_NSDNAME: - cnt = &rpzs->triggers[rpz_num].nsdname; - have = &rpzs->have.nsdname; - break; - case DNS_RPZ_TYPE_NSIP: - REQUIRE(tgt_ip != NULL); - if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { - cnt = &rpzs->triggers[rpz_num].nsipv4; - have = &rpzs->have.nsipv4; - } else { - cnt = &rpzs->triggers[rpz_num].nsipv6; - have = &rpzs->have.nsipv6; - } - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (inc) { - if (++*cnt == 1U) { - *have |= DNS_RPZ_ZBIT(rpz_num); - fix_qname_skip_recurse(rpzs); - } - } else { - REQUIRE(*cnt != 0U); - if (--*cnt == 0U) { - *have &= ~DNS_RPZ_ZBIT(rpz_num); - fix_qname_skip_recurse(rpzs); - } - } -} - -static dns_rpz_cidr_node_t * -new_node(dns_rpz_zones_t *rpzs, - const dns_rpz_cidr_key_t *ip, dns_rpz_prefix_t prefix, - const dns_rpz_cidr_node_t *child) -{ - dns_rpz_cidr_node_t *node; - int i, words, wlen; - - node = isc_mem_get(rpzs->mctx, sizeof(*node)); - if (node == NULL) - return (NULL); - memset(node, 0, sizeof(*node)); - - if (child != NULL) - node->sum = child->sum; - - node->prefix = prefix; - words = prefix / DNS_RPZ_CIDR_WORD_BITS; - wlen = prefix % DNS_RPZ_CIDR_WORD_BITS; - i = 0; - while (i < words) { - node->ip.w[i] = ip->w[i]; - ++i; - } - if (wlen != 0) { - node->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen); - ++i; - } - while (i < DNS_RPZ_CIDR_WORDS) - node->ip.w[i++] = 0; - - return (node); -} - -static void -badname(int level, dns_name_t *name, const char *str1, const char *str2) { - char namebuf[DNS_NAME_FORMATSIZE]; - - /* - * bin/tests/system/rpz/tests.sh looks for "invalid rpz". - */ - if (level < DNS_RPZ_DEBUG_QUIET && - isc_log_wouldlog(dns_lctx, level)) { - dns_name_format(name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, level, - "invalid rpz IP address \"%s\"%s%s", - namebuf, str1, str2); - } -} - -/* - * Convert an IP address from radix tree binary (host byte order) to - * to its canonical response policy domain name without the origin of the - * policy zone. - * - * Generate a name for an IPv6 address that fits RFC 5952, except that - * our reversed format requires that when the length of the consecutive - * 16-bit 0 fields are equal (e.g., 1.0.0.1.0.0.db8.2001 corresponding - * to 2001:db8:0:0:1:0:0:1), we shorted the last instead of the first - * (e.g., 1.0.0.1.zz.db8.2001 corresponding to 2001:db8::1:0:0:1). - */ -static isc_result_t -ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, - dns_name_t *base_name, dns_name_t *ip_name) -{ -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif - int w[DNS_RPZ_CIDR_WORDS*2]; - char str[1+8+1+INET6_ADDRSTRLEN+1]; - isc_buffer_t buffer; - isc_result_t result; - int best_first, best_len, cur_first, cur_len; - int i, n, len; - - if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { - len = snprintf(str, sizeof(str), "%u.%u.%u.%u.%u", - tgt_prefix - 96U, - tgt_ip->w[3] & 0xffU, - (tgt_ip->w[3]>>8) & 0xffU, - (tgt_ip->w[3]>>16) & 0xffU, - (tgt_ip->w[3]>>24) & 0xffU); - if (len < 0 || (size_t)len >= sizeof(str)) { - return (ISC_R_FAILURE); - } - } else { - len = snprintf(str, sizeof(str), "%d", tgt_prefix); - if (len < 0 || (size_t)len >= sizeof(str)) { - return (ISC_R_FAILURE); - } - for (i = 0; i < DNS_RPZ_CIDR_WORDS; i++) { - w[i*2+1] = ((tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] >> 16) - & 0xffff); - w[i*2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] & 0xffff; - } - /* - * Find the start and length of the first longest sequence - * of zeros in the address. - */ - best_first = -1; - best_len = 0; - cur_first = -1; - cur_len = 0; - for (n = 0; n <=7; ++n) { - if (w[n] != 0) { - cur_len = 0; - cur_first = -1; - } else { - ++cur_len; - if (cur_first < 0) { - cur_first = n; - } else if (cur_len >= best_len) { - best_first = cur_first; - best_len = cur_len; - } - } - } - - for (n = 0; n <= 7; ++n) { - INSIST(len > 0 && (size_t)len < sizeof(str)); - if (n == best_first) { - i = snprintf(str + len, sizeof(str) - len, - ".zz"); - n += best_len - 1; - } else { - i = snprintf(str + len, sizeof(str) - len, - ".%x", w[n]); - } - if (i < 0 || (size_t)i >= (size_t)(sizeof(str) - len)) { - return (ISC_R_FAILURE); - } - len += i; - } - } - - isc_buffer_init(&buffer, str, sizeof(str)); - isc_buffer_add(&buffer, len); - result = dns_name_fromtext(ip_name, &buffer, base_name, 0, NULL); - return (result); -} - -/* - * Determine the type of a name in a response policy zone. - */ -static dns_rpz_type_t -type_from_name(dns_rpz_zone_t *rpz, dns_name_t *name) { - - if (dns_name_issubdomain(name, &rpz->ip)) - return (DNS_RPZ_TYPE_IP); - - if (dns_name_issubdomain(name, &rpz->client_ip)) - return (DNS_RPZ_TYPE_CLIENT_IP); - -#ifdef ENABLE_RPZ_NSIP - if (dns_name_issubdomain(name, &rpz->nsip)) - return (DNS_RPZ_TYPE_NSIP); -#endif - -#ifdef ENABLE_RPZ_NSDNAME - if (dns_name_issubdomain(name, &rpz->nsdname)) - return (DNS_RPZ_TYPE_NSDNAME); -#endif - - return (DNS_RPZ_TYPE_QNAME); -} - -/* - * Convert an IP address from canonical response policy domain name form - * to radix tree binary (host byte order) for adding or deleting IP or NSIP - * data. - */ -static isc_result_t -name2ipkey(int log_level, - const dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, dns_name_t *src_name, - dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t *tgt_prefix, - dns_rpz_addr_zbits_t *new_set) -{ - dns_rpz_zone_t *rpz; - char ip_str[DNS_NAME_FORMATSIZE]; - char ip2_str[DNS_NAME_FORMATSIZE]; - dns_offsets_t ip_name_offsets; - dns_fixedname_t ip_name2f; - dns_name_t ip_name, *ip_name2; - const char *prefix_str, *cp, *end; - char *cp2; - int ip_labels; - dns_rpz_prefix_t prefix; - unsigned long prefix_num, l; - isc_result_t result; - int i; - - REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); - rpz = rpzs->zones[rpz_num]; - REQUIRE(rpz != NULL); - - make_addr_set(new_set, DNS_RPZ_ZBIT(rpz_num), rpz_type); - - ip_labels = dns_name_countlabels(src_name); - if (rpz_type == DNS_RPZ_TYPE_QNAME) - ip_labels -= dns_name_countlabels(&rpz->origin); - else - ip_labels -= dns_name_countlabels(&rpz->nsdname); - if (ip_labels < 2) { - badname(log_level, src_name, "; too short", ""); - return (ISC_R_FAILURE); - } - dns_name_init(&ip_name, ip_name_offsets); - dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name); - - /* - * Get text for the IP address - */ - dns_name_format(&ip_name, ip_str, sizeof(ip_str)); - end = &ip_str[strlen(ip_str)+1]; - prefix_str = ip_str; - - prefix_num = strtoul(prefix_str, &cp2, 10); - if (*cp2 != '.') { - badname(log_level, src_name, - "; invalid leading prefix length", ""); - return (ISC_R_FAILURE); - } - - if (prefix_num < 1U || prefix_num > 128U) { - badname(log_level, src_name, - "; invalid prefix length of ", prefix_str); - return (ISC_R_FAILURE); - } - cp = cp2+1; - - if (--ip_labels == 4 && !strchr(cp, 'z')) { - /* - * Convert an IPv4 address - * from the form "prefix.z.y.x.w" - */ - if (prefix_num > 32U) { - badname(log_level, src_name, - "; invalid IPv4 prefix length of ", prefix_str); - return (ISC_R_FAILURE); - } - prefix_num += 96; - *tgt_prefix = (dns_rpz_prefix_t)prefix_num; - tgt_ip->w[0] = 0; - tgt_ip->w[1] = 0; - tgt_ip->w[2] = ADDR_V4MAPPED; - tgt_ip->w[3] = 0; - for (i = 0; i < 32; i += 8) { - l = strtoul(cp, &cp2, 10); - if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { - if (*cp2 == '.') - *cp2 = '\0'; - badname(log_level, src_name, - "; invalid IPv4 octet ", cp); - return (ISC_R_FAILURE); - } - tgt_ip->w[3] |= l << i; - cp = cp2 + 1; - } - } else { - /* - * Convert a text IPv6 address. - */ - *tgt_prefix = (dns_rpz_prefix_t)prefix_num; - for (i = 0; - ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2; - ip_labels--) { - if (cp[0] == 'z' && cp[1] == 'z' && - (cp[2] == '.' || cp[2] == '\0') && - i <= 6) { - do { - if ((i & 1) == 0) - tgt_ip->w[3-i/2] = 0; - ++i; - } while (ip_labels + i <= 8); - cp += 3; - } else { - l = strtoul(cp, &cp2, 16); - if (l > 0xffffu || - (*cp2 != '.' && *cp2 != '\0')) { - if (*cp2 == '.') - *cp2 = '\0'; - badname(log_level, src_name, - "; invalid IPv6 word ", cp); - return (ISC_R_FAILURE); - } - if ((i & 1) == 0) - tgt_ip->w[3-i/2] = l; - else - tgt_ip->w[3-i/2] |= l << 16; - i++; - cp = cp2 + 1; - } - } - } - if (cp != end) { - badname(log_level, src_name, "", ""); - return (ISC_R_FAILURE); - } - - /* - * Check for 1s after the prefix length. - */ - prefix = (dns_rpz_prefix_t)prefix_num; - while (prefix < DNS_RPZ_CIDR_KEY_BITS) { - dns_rpz_cidr_word_t aword; - - i = prefix % DNS_RPZ_CIDR_WORD_BITS; - aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS]; - if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { - badname(log_level, src_name, - "; too small prefix length of ", prefix_str); - return (ISC_R_FAILURE); - } - prefix -= i; - prefix += DNS_RPZ_CIDR_WORD_BITS; - } - - /* - * Complain about bad names but be generous and accept them. - */ - if (log_level < DNS_RPZ_DEBUG_QUIET && - isc_log_wouldlog(dns_lctx, log_level)) { - /* - * Convert the address back to a canonical domain name - * to ensure that the original name is in canonical form. - */ - ip_name2 = dns_fixedname_initname(&ip_name2f); - result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, - NULL, ip_name2); - if (result != ISC_R_SUCCESS || - !dns_name_equal(&ip_name, ip_name2)) { - dns_name_format(ip_name2, ip2_str, sizeof(ip2_str)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, log_level, - "rpz IP address \"%s\"" - " is not the canonical \"%s\"", - ip_str, ip2_str); - } - } - - return (ISC_R_SUCCESS); -} - -/* - * Get trigger name and data bits for adding or deleting summary NSDNAME - * or QNAME data. - */ -static void -name2data(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, const dns_name_t *src_name, - dns_name_t *trig_name, dns_rpz_nm_data_t *new_data) -{ - dns_rpz_zone_t *rpz; - dns_offsets_t tmp_name_offsets; - dns_name_t tmp_name; - unsigned int prefix_len, n; - - REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); - rpz = rpzs->zones[rpz_num]; - REQUIRE(rpz != NULL); - - /* - * Handle wildcards by putting only the parent into the - * summary RBT. The summary database only causes a check of the - * real policy zone where wildcards will be handled. - */ - if (dns_name_iswildcard(src_name)) { - prefix_len = 1; - memset(&new_data->set, 0, sizeof(new_data->set)); - make_nm_set(&new_data->wild, rpz_num, rpz_type); - } else { - prefix_len = 0; - make_nm_set(&new_data->set, rpz_num, rpz_type); - memset(&new_data->wild, 0, sizeof(new_data->wild)); - } - - dns_name_init(&tmp_name, tmp_name_offsets); - n = dns_name_countlabels(src_name); - n -= prefix_len; - if (rpz_type == DNS_RPZ_TYPE_QNAME) - n -= dns_name_countlabels(&rpz->origin); - else - n -= dns_name_countlabels(&rpz->nsdname); - dns_name_getlabelsequence(src_name, prefix_len, n, &tmp_name); - (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL); -} - -#ifndef HAVE_BUILTIN_CLZ -/** - * \brief Count Leading Zeros: Find the location of the left-most set - * bit. - */ -static inline unsigned int -clz(dns_rpz_cidr_word_t w) { - unsigned int bit; - - bit = DNS_RPZ_CIDR_WORD_BITS-1; - - if ((w & 0xffff0000) != 0) { - w >>= 16; - bit -= 16; - } - - if ((w & 0xff00) != 0) { - w >>= 8; - bit -= 8; - } - - if ((w & 0xf0) != 0) { - w >>= 4; - bit -= 4; - } - - if ((w & 0xc) != 0) { - w >>= 2; - bit -= 2; - } - - if ((w & 2) != 0) - --bit; - - return (bit); -} -#endif - -/* - * Find the first differing bit in two keys (IP addresses). - */ -static int -diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1, - const dns_rpz_cidr_key_t *key2, dns_rpz_prefix_t prefix2) -{ - dns_rpz_cidr_word_t delta; - dns_rpz_prefix_t maxbit, bit; - int i; - - bit = 0; - maxbit = ISC_MIN(prefix1, prefix2); - - /* - * find the first differing words - */ - for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) { - delta = key1->w[i] ^ key2->w[i]; - if (ISC_UNLIKELY(delta != 0)) { -#ifdef HAVE_BUILTIN_CLZ - bit += __builtin_clz(delta); -#else - bit += clz(delta); -#endif - break; - } - } - return (ISC_MIN(bit, maxbit)); -} - -/* - * Given a hit while searching the radix trees, - * clear all bits for higher numbered zones. - */ -static inline dns_rpz_zbits_t -trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) { - dns_rpz_zbits_t x; - - /* - * Isolate the first or smallest numbered hit bit. - * Make a mask of that bit and all smaller numbered bits. - */ - x = zbits & found; - x &= (~x + 1); - x = (x << 1) - 1; - zbits &= x; - return (zbits); -} - -/* - * Search a radix tree for an IP address for ordinary lookup - * or for a CIDR block adding or deleting an entry - * - * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND, - * and *found=longest match node - * or with create==true, ISC_R_EXISTS or ISC_R_NOMEMORY - */ -static isc_result_t -search(dns_rpz_zones_t *rpzs, - const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, - const dns_rpz_addr_zbits_t *tgt_set, bool create, - dns_rpz_cidr_node_t **found) -{ - dns_rpz_cidr_node_t *cur, *parent, *child, *new_parent, *sibling; - dns_rpz_addr_zbits_t set; - int cur_num, child_num; - dns_rpz_prefix_t dbit; - isc_result_t find_result; - - set = *tgt_set; - find_result = ISC_R_NOTFOUND; - *found = NULL; - cur = rpzs->cidr; - parent = NULL; - cur_num = 0; - for (;;) { - if (cur == NULL) { - /* - * No child so we cannot go down. - * Quit with whatever we already found - * or add the target as a child of the current parent. - */ - if (!create) - return (find_result); - child = new_node(rpzs, tgt_ip, tgt_prefix, NULL); - if (child == NULL) - return (ISC_R_NOMEMORY); - if (parent == NULL) - rpzs->cidr = child; - else - parent->child[cur_num] = child; - child->parent = parent; - child->set.client_ip |= tgt_set->client_ip; - child->set.ip |= tgt_set->ip; - child->set.nsip |= tgt_set->nsip; - set_sum_pair(child); - *found = child; - return (ISC_R_SUCCESS); - } - - if ((cur->sum.client_ip & set.client_ip) == 0 && - (cur->sum.ip & set.ip) == 0 && - (cur->sum.nsip & set.nsip) == 0) { - /* - * This node has no relevant data - * and is in none of the target trees. - * Pretend it does not exist if we are not adding. - * - * If we are adding, continue down to eventually add - * a node and mark/put this node in the correct tree. - */ - if (!create) - return (find_result); - } - - dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix); - /* - * dbit <= tgt_prefix and dbit <= cur->prefix always. - * We are finished searching if we matched all of the target. - */ - if (dbit == tgt_prefix) { - if (tgt_prefix == cur->prefix) { - /* - * The node's key matches the target exactly. - */ - if ((cur->set.client_ip & set.client_ip) != 0 || - (cur->set.ip & set.ip) != 0 || - (cur->set.nsip & set.nsip) != 0) { - /* - * It is the answer if it has data. - */ - *found = cur; - if (create) { - find_result = ISC_R_EXISTS; - } else { - find_result = ISC_R_SUCCESS; - } - } else if (create) { - /* - * The node lacked relevant data, - * but will have it now. - */ - cur->set.client_ip |= tgt_set->client_ip; - cur->set.ip |= tgt_set->ip; - cur->set.nsip |= tgt_set->nsip; - set_sum_pair(cur); - *found = cur; - find_result = ISC_R_SUCCESS; - } - return (find_result); - } - - /* - * We know tgt_prefix < cur->prefix which means that - * the target is shorter than the current node. - * Add the target as the current node's parent. - */ - if (!create) - return (find_result); - - new_parent = new_node(rpzs, tgt_ip, tgt_prefix, cur); - if (new_parent == NULL) - return (ISC_R_NOMEMORY); - new_parent->parent = parent; - if (parent == NULL) - rpzs->cidr = new_parent; - else - parent->child[cur_num] = new_parent; - child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix); - new_parent->child[child_num] = cur; - cur->parent = new_parent; - new_parent->set = *tgt_set; - set_sum_pair(new_parent); - *found = new_parent; - return (ISC_R_SUCCESS); - } - - if (dbit == cur->prefix) { - if ((cur->set.client_ip & set.client_ip) != 0 || - (cur->set.ip & set.ip) != 0 || - (cur->set.nsip & set.nsip) != 0) { - /* - * We have a partial match between of all of the - * current node but only part of the target. - * Continue searching for other hits in the - * same or lower numbered trees. - */ - find_result = DNS_R_PARTIALMATCH; - *found = cur; - set.client_ip = trim_zbits(set.client_ip, - cur->set.client_ip); - set.ip = trim_zbits(set.ip, - cur->set.ip); - set.nsip = trim_zbits(set.nsip, - cur->set.nsip); - } - parent = cur; - cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); - cur = cur->child[cur_num]; - continue; - } - - - /* - * dbit < tgt_prefix and dbit < cur->prefix, - * so we failed to match both the target and the current node. - * Insert a fork of a parent above the current node and - * add the target as a sibling of the current node - */ - if (!create) - return (find_result); - - sibling = new_node(rpzs, tgt_ip, tgt_prefix, NULL); - if (sibling == NULL) - return (ISC_R_NOMEMORY); - new_parent = new_node(rpzs, tgt_ip, dbit, cur); - if (new_parent == NULL) { - isc_mem_put(rpzs->mctx, sibling, sizeof(*sibling)); - return (ISC_R_NOMEMORY); - } - new_parent->parent = parent; - if (parent == NULL) - rpzs->cidr = new_parent; - else - parent->child[cur_num] = new_parent; - child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); - new_parent->child[child_num] = sibling; - new_parent->child[1-child_num] = cur; - cur->parent = new_parent; - sibling->parent = new_parent; - sibling->set = *tgt_set; - set_sum_pair(sibling); - *found = sibling; - return (ISC_R_SUCCESS); - } -} - -/* - * Add an IP address to the radix tree. - */ -static isc_result_t -add_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, dns_name_t *src_name) -{ - dns_rpz_cidr_key_t tgt_ip; - dns_rpz_prefix_t tgt_prefix; - dns_rpz_addr_zbits_t set; - dns_rpz_cidr_node_t *found; - isc_result_t result; - - result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpzs, rpz_num, rpz_type, - src_name, &tgt_ip, &tgt_prefix, &set); - /* - * Log complaints about bad owner names but let the zone load. - */ - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - result = search(rpzs, &tgt_ip, tgt_prefix, &set, true, &found); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - - /* - * Do not worry if the radix tree already exists, - * because diff_apply() likes to add nodes before deleting. - */ - if (result == ISC_R_EXISTS) - return (ISC_R_SUCCESS); - - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". - */ - dns_name_format(src_name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz add_cidr(%s) failed: %s", - namebuf, isc_result_totext(result)); - return (result); - } - - adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, true); - return (result); -} - -static isc_result_t -add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name, - const dns_rpz_nm_data_t *new_data) -{ - dns_rbtnode_t *nmnode; - dns_rpz_nm_data_t *nm_data; - isc_result_t result; - - nmnode = NULL; - result = dns_rbt_addnode(rpzs->rbt, trig_name, &nmnode); - switch (result) { - case ISC_R_SUCCESS: - case ISC_R_EXISTS: - nm_data = nmnode->data; - if (nm_data == NULL) { - nm_data = isc_mem_get(rpzs->mctx, sizeof(*nm_data)); - if (nm_data == NULL) - return (ISC_R_NOMEMORY); - *nm_data = *new_data; - nmnode->data = nm_data; - return (ISC_R_SUCCESS); - } - break; - default: - return (result); - } - - /* - * Do not count bits that are already present - */ - if ((nm_data->set.qname & new_data->set.qname) != 0 || - (nm_data->set.ns & new_data->set.ns) != 0 || - (nm_data->wild.qname & new_data->wild.qname) != 0 || - (nm_data->wild.ns & new_data->wild.ns) != 0) - return (ISC_R_EXISTS); - - nm_data->set.qname |= new_data->set.qname; - nm_data->set.ns |= new_data->set.ns; - nm_data->wild.qname |= new_data->wild.qname; - nm_data->wild.ns |= new_data->wild.ns; - return (ISC_R_SUCCESS); -} - -static isc_result_t -add_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, dns_name_t *src_name) -{ - dns_rpz_nm_data_t new_data; - dns_fixedname_t trig_namef; - dns_name_t *trig_name; - isc_result_t result; - - /* - * We need a summary database of names even with 1 policy zone, - * because wildcard triggers are handled differently. - */ - - trig_name = dns_fixedname_initname(&trig_namef); - name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &new_data); - - result = add_nm(rpzs, trig_name, &new_data); - - /* - * Do not worry if the node already exists, - * because diff_apply() likes to add nodes before deleting. - */ - if (result == ISC_R_EXISTS) - return (ISC_R_SUCCESS); - if (result == ISC_R_SUCCESS) - adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, true); - return (result); -} - -/* - * Callback to free the data for a node in the summary RBT database. - */ -static void -rpz_node_deleter(void *nm_data, void *mctx) { - isc_mem_put(mctx, nm_data, sizeof(dns_rpz_nm_data_t)); -} - -/* - * Get ready for a new set of policy zones for a view. - */ -isc_result_t -dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, isc_mem_t *mctx) { - dns_rpz_zones_t *new; - isc_result_t result; - - REQUIRE(rpzsp != NULL && *rpzsp == NULL); - - *rpzsp = NULL; - - new = isc_mem_get(mctx, sizeof(*new)); - if (new == NULL) - return (ISC_R_NOMEMORY); - memset(new, 0, sizeof(*new)); - - result = isc_rwlock_init(&new->search_lock, 0, 0); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, new, sizeof(*new)); - return (result); - } - - result = isc_mutex_init(&new->maint_lock); - if (result != ISC_R_SUCCESS) { - isc_rwlock_destroy(&new->search_lock); - isc_mem_put(mctx, new, sizeof(*new)); - return (result); - } - - result = isc_refcount_init(&new->refs, 1); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&new->maint_lock); - isc_rwlock_destroy(&new->search_lock); - isc_mem_put(mctx, new, sizeof(*new)); - return (result); - } - - result = dns_rbt_create(mctx, rpz_node_deleter, mctx, &new->rbt); - if (result != ISC_R_SUCCESS) { - isc_refcount_decrement(&new->refs, NULL); - isc_refcount_destroy(&new->refs); - DESTROYLOCK(&new->maint_lock); - isc_rwlock_destroy(&new->search_lock); - isc_mem_put(mctx, new, sizeof(*new)); - return (result); - } - - isc_mem_attach(mctx, &new->mctx); - - *rpzsp = new; - return (ISC_R_SUCCESS); -} - -/* - * Free the radix tree of a response policy database. - */ -static void -cidr_free(dns_rpz_zones_t *rpzs) { - dns_rpz_cidr_node_t *cur, *child, *parent; - - cur = rpzs->cidr; - while (cur != NULL) { - /* Depth first. */ - child = cur->child[0]; - if (child != NULL) { - cur = child; - continue; - } - child = cur->child[1]; - if (child != NULL) { - cur = child; - continue; - } - - /* Delete this leaf and go up. */ - parent = cur->parent; - if (parent == NULL) - rpzs->cidr = NULL; - else - parent->child[parent->child[1] == cur] = NULL; - isc_mem_put(rpzs->mctx, cur, sizeof(*cur)); - cur = parent; - } -} - -/* - * Discard a response policy zone blob - * before discarding the overall rpz structure. - */ -static void -rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) { - dns_rpz_zone_t *rpz; - unsigned int refs; - - rpz = *rpzp; - *rpzp = NULL; - isc_refcount_decrement(&rpz->refs, &refs); - if (refs != 0) - return; - isc_refcount_destroy(&rpz->refs); - - if (dns_name_dynamic(&rpz->origin)) - dns_name_free(&rpz->origin, rpzs->mctx); - if (dns_name_dynamic(&rpz->client_ip)) - dns_name_free(&rpz->client_ip, rpzs->mctx); - if (dns_name_dynamic(&rpz->ip)) - dns_name_free(&rpz->ip, rpzs->mctx); - if (dns_name_dynamic(&rpz->nsdname)) - dns_name_free(&rpz->nsdname, rpzs->mctx); - if (dns_name_dynamic(&rpz->nsip)) - dns_name_free(&rpz->nsip, rpzs->mctx); - if (dns_name_dynamic(&rpz->passthru)) - dns_name_free(&rpz->passthru, rpzs->mctx); - if (dns_name_dynamic(&rpz->drop)) - dns_name_free(&rpz->drop, rpzs->mctx); - if (dns_name_dynamic(&rpz->tcp_only)) - dns_name_free(&rpz->tcp_only, rpzs->mctx); - if (dns_name_dynamic(&rpz->cname)) - dns_name_free(&rpz->cname, rpzs->mctx); - - isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz)); -} - -void -dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) { - REQUIRE(rpzsp != NULL && *rpzsp == NULL); - isc_refcount_increment(&rpzs->refs, NULL); - *rpzsp = rpzs; -} - -/* - * Forget a view's policy zones. - */ -void -dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) { - dns_rpz_zones_t *rpzs; - dns_rpz_zone_t *rpz; - dns_rpz_num_t rpz_num; - unsigned int refs; - - REQUIRE(rpzsp != NULL); - rpzs = *rpzsp; - REQUIRE(rpzs != NULL); - - *rpzsp = NULL; - isc_refcount_decrement(&rpzs->refs, &refs); - if (refs > 0) - return; - - /* - * Forget the last of view's rpz machinery after the last - * reference. - */ - for (rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num) { - rpz = rpzs->zones[rpz_num]; - rpzs->zones[rpz_num] = NULL; - if (rpz != NULL) - rpz_detach(&rpz, rpzs); - } - - cidr_free(rpzs); - dns_rbt_destroy(&rpzs->rbt); - DESTROYLOCK(&rpzs->maint_lock); - isc_rwlock_destroy(&rpzs->search_lock); - isc_refcount_destroy(&rpzs->refs); - isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs)); -} - -/* - * Create empty summary database to load one zone. - * The RBTDB write tree lock must be held. - */ -isc_result_t -dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, - dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) -{ - dns_rpz_zones_t *load_rpzs; - dns_rpz_zone_t *rpz; - dns_rpz_zbits_t tgt; - isc_result_t result; - - REQUIRE(rpz_num < rpzs->p.num_zones); - rpz = rpzs->zones[rpz_num]; - REQUIRE(rpz != NULL); - - /* - * When reloading a zone, there are usually records among the summary - * data for the zone. Some of those records might be deleted by the - * reloaded zone data. To deal with that case: - * reload the new zone data into a new blank summary database - * if the reload fails, discard the new summary database - * if the new zone data is acceptable, copy the records for the - * other zones into the new summary CIDR and RBT databases - * and replace the old summary databases with the new, and - * correct the triggers and have values for the updated - * zone. - * - * At the first attempt to load a zone, there is no summary data - * for the zone and so no records that need to be deleted. - * This is also the most common case of policy zone loading. - * Most policy zone maintenance should be by incremental changes - * and so by the addition and deletion of individual records. - * Detect that case and load records the first time into the - * operational summary database - */ - tgt = DNS_RPZ_ZBIT(rpz_num); - LOCK(&rpzs->maint_lock); - RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); - if ((rpzs->load_begun & tgt) == 0) { - /* - * There is no existing version of the target zone. - */ - rpzs->load_begun |= tgt; - dns_rpz_attach_rpzs(rpzs, load_rpzsp); - } else { - /* - * Setup the new RPZ struct with empty summary trees. - */ - result = dns_rpz_new_zones(load_rpzsp, rpzs->mctx); - if (result != ISC_R_SUCCESS) - return (result); - load_rpzs = *load_rpzsp; - /* - * Initialize some members so that dns_rpz_add() works. - */ - load_rpzs->p.num_zones = rpzs->p.num_zones; - memset(&load_rpzs->triggers, 0, sizeof(load_rpzs->triggers)); - load_rpzs->zones[rpz_num] = rpz; - isc_refcount_increment(&rpz->refs, NULL); - } - - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); - UNLOCK(&rpzs->maint_lock); - - return (ISC_R_SUCCESS); -} - -/* - * This function updates "have" bits and also the qname_skip_recurse - * mask. It must be called when holding a write lock on rpzs->search_lock. - */ -static void -fix_triggers(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { - dns_rpz_num_t n; - dns_rpz_triggers_t old_totals; - dns_rpz_zbits_t zbit; - char namebuf[DNS_NAME_FORMATSIZE]; - - /* - * rpzs->total_triggers is only used to log a message below. - */ - - memmove(&old_totals, &rpzs->total_triggers, sizeof(old_totals)); - memset(&rpzs->total_triggers, 0, sizeof(rpzs->total_triggers)); - -#define SET_TRIG(n, zbit, type) \ - if (rpzs->triggers[n].type == 0U) { \ - rpzs->have.type &= ~zbit; \ - } else { \ - rpzs->total_triggers.type += rpzs->triggers[n].type; \ - rpzs->have.type |= zbit; \ - } - - for (n = 0; n < rpzs->p.num_zones; ++n) { - zbit = DNS_RPZ_ZBIT(n); - SET_TRIG(n, zbit, client_ipv4); - SET_TRIG(n, zbit, client_ipv6); - SET_TRIG(n, zbit, qname); - SET_TRIG(n, zbit, ipv4); - SET_TRIG(n, zbit, ipv6); - SET_TRIG(n, zbit, nsdname); - SET_TRIG(n, zbit, nsipv4); - SET_TRIG(n, zbit, nsipv6); - } - -#undef SET_TRIG - - fix_qname_skip_recurse(rpzs); - - dns_name_format(&rpzs->zones[rpz_num]->origin, - namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_INFO_LEVEL, - "(re)loading policy zone '%s' changed from" - " %lu to %lu qname, %lu to %lu nsdname," - " %lu to %lu IP, %lu to %lu NSIP," - " %lu to %lu CLIENTIP entries", - namebuf, - (unsigned long) old_totals.qname, - (unsigned long) rpzs->total_triggers.qname, - (unsigned long) old_totals.nsdname, - (unsigned long) rpzs->total_triggers.nsdname, - (unsigned long) old_totals.ipv4 + old_totals.ipv6, - (unsigned long) (rpzs->total_triggers.ipv4 + - rpzs->total_triggers.ipv6), - (unsigned long) old_totals.nsipv4 + old_totals.nsipv6, - (unsigned long) (rpzs->total_triggers.nsipv4 + - rpzs->total_triggers.nsipv6), - (unsigned long) old_totals.client_ipv4 + - old_totals.client_ipv6, - (unsigned long) (rpzs->total_triggers.client_ipv4 + - rpzs->total_triggers.client_ipv6)); -} - -/* - * Finish loading one zone. This function is called during a commit when - * a RPZ zone loading is complete. The RBTDB write tree lock must be - * held. - * - * Here, rpzs is a pointer to the view's common rpzs - * structure. *load_rpzsp is a rpzs structure that is local to the - * RBTDB, which is used during a single zone's load. - * - * During the zone load, i.e., between dns_rpz_beginload() and - * dns_rpz_ready(), only the zone that is being loaded updates - * *load_rpzsp. These updates in the summary databases inside load_rpzsp - * are made only for the rpz_num (and corresponding bit) of that - * zone. Nothing else reads or writes *load_rpzsp. The view's common - * rpzs is used during this time for queries. - * - * When zone loading is complete and we arrive here, the parts of the - * summary databases (CIDR and nsdname+qname RBT trees) from the view's - * common rpzs struct have to be merged into the summary databases of - * *load_rpzsp, as the summary databases of the view's common rpzs - * struct may have changed during the time the zone was being loaded. - * - * The function below carries out the merge. During the merge, it holds - * the maint_lock of the view's common rpzs struct so that it is not - * updated while the merging is taking place. - * - * After the merging is carried out, *load_rpzsp contains the most - * current state of the rpzs structure, i.e., the summary trees contain - * data for the new zone that was just loaded, as well as all other - * zones. - * - * Pointers to the summary databases of *load_rpzsp (CIDR and - * nsdname+qname RBT trees) are then swapped into the view's common rpz - * struct, so that the query path can continue using it. During the - * swap, the search_lock of the view's common rpz struct is acquired so - * that queries are paused while this swap occurs. - * - * The trigger counts for the new zone are also copied into the view's - * common rpz struct, and some other summary counts and masks are - * updated. - */ -isc_result_t -dns_rpz_ready(dns_rpz_zones_t *rpzs, - dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num) -{ - dns_rpz_zones_t *load_rpzs; - const dns_rpz_cidr_node_t *cnode, *next_cnode, *parent_cnode; - dns_rpz_cidr_node_t *found; - dns_rpz_zbits_t new_bit; - dns_rpz_addr_zbits_t new_ip; - dns_rbt_t *rbt; - dns_rbtnodechain_t chain; - dns_rbtnode_t *nmnode; - dns_rpz_nm_data_t *nm_data, new_data; - dns_fixedname_t labelf, originf, namef; - dns_name_t *label, *origin, *name; - isc_result_t result; - - INSIST(rpzs != NULL); - LOCK(&rpzs->maint_lock); - load_rpzs = *load_rpzsp; - INSIST(load_rpzs != NULL); - - if (load_rpzs == rpzs) { - /* - * This is a successful initial zone loading, perhaps - * for a new instance of a view. - */ - RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); - fix_triggers(rpzs, rpz_num); - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); - UNLOCK(&rpzs->maint_lock); - dns_rpz_detach_rpzs(load_rpzsp); - return (ISC_R_SUCCESS); - } - - LOCK(&load_rpzs->maint_lock); - RWLOCK(&load_rpzs->search_lock, isc_rwlocktype_write); - - /* - * Unless there is only one policy zone, copy the other policy zones - * from the old policy structure to the new summary databases. - */ - if (rpzs->p.num_zones > 1) { - new_bit = ~DNS_RPZ_ZBIT(rpz_num); - - /* - * Copy to the radix tree. - */ - for (cnode = rpzs->cidr; cnode != NULL; cnode = next_cnode) { - new_ip.ip = cnode->set.ip & new_bit; - new_ip.client_ip = cnode->set.client_ip & new_bit; - new_ip.nsip = cnode->set.nsip & new_bit; - if (new_ip.client_ip != 0 || - new_ip.ip != 0 || - new_ip.nsip != 0) { - result = search(load_rpzs, - &cnode->ip, cnode->prefix, - &new_ip, true, &found); - if (result == ISC_R_NOMEMORY) - goto unlock_and_detach; - INSIST(result == ISC_R_SUCCESS); - } - /* - * Do down and to the left as far as possible. - */ - next_cnode = cnode->child[0]; - if (next_cnode != NULL) - continue; - /* - * Go up until we find a branch to the right where - * we previously took the branch to the left. - */ - for (;;) { - parent_cnode = cnode->parent; - if (parent_cnode == NULL) - break; - if (parent_cnode->child[0] == cnode) { - next_cnode = parent_cnode->child[1]; - if (next_cnode != NULL) - break; - } - cnode = parent_cnode; - } - } - - /* - * Copy to the summary RBT. - */ - dns_fixedname_init(&namef); - name = dns_fixedname_name(&namef); - dns_fixedname_init(&labelf); - label = dns_fixedname_name(&labelf); - dns_fixedname_init(&originf); - origin = dns_fixedname_name(&originf); - dns_rbtnodechain_init(&chain, NULL); - result = dns_rbtnodechain_first(&chain, rpzs->rbt, NULL, NULL); - while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { - result = dns_rbtnodechain_current(&chain, label, origin, - &nmnode); - INSIST(result == ISC_R_SUCCESS); - nm_data = nmnode->data; - if (nm_data != NULL) { - new_data.set.qname = (nm_data->set.qname & - new_bit); - new_data.set.ns = nm_data->set.ns & new_bit; - new_data.wild.qname = (nm_data->wild.qname & - new_bit); - new_data.wild.ns = nm_data->wild.ns & new_bit; - if (new_data.set.qname != 0 || - new_data.set.ns != 0 || - new_data.wild.qname != 0 || - new_data.wild.ns != 0) { - result = dns_name_concatenate(label, - origin, name, NULL); - INSIST(result == ISC_R_SUCCESS); - result = add_nm(load_rpzs, name, - &new_data); - if (result != ISC_R_SUCCESS) - goto unlock_and_detach; - } - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - } - if (result != ISC_R_NOMORE && result != ISC_R_NOTFOUND) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "dns_rpz_ready(): unexpected %s", - isc_result_totext(result)); - goto unlock_and_detach; - } - } - - /* - * Exchange the summary databases. - */ - RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); - - rpzs->triggers[rpz_num] = load_rpzs->triggers[rpz_num]; - fix_triggers(rpzs, rpz_num); - - found = rpzs->cidr; - rpzs->cidr = load_rpzs->cidr; - load_rpzs->cidr = found; - - rbt = rpzs->rbt; - rpzs->rbt = load_rpzs->rbt; - load_rpzs->rbt = rbt; - - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); - - result = ISC_R_SUCCESS; - - unlock_and_detach: - UNLOCK(&rpzs->maint_lock); - RWUNLOCK(&load_rpzs->search_lock, isc_rwlocktype_write); - UNLOCK(&load_rpzs->maint_lock); - dns_rpz_detach_rpzs(load_rpzsp); - return (result); -} - -/* - * Add an IP address to the radix tree or a name to the summary database. - */ -isc_result_t -dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *src_name) -{ - dns_rpz_zone_t *rpz; - dns_rpz_type_t rpz_type; - isc_result_t result = ISC_R_FAILURE; - - REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); - rpz = rpzs->zones[rpz_num]; - REQUIRE(rpz != NULL); - - rpz_type = type_from_name(rpz, src_name); - - LOCK(&rpzs->maint_lock); - RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); - - switch (rpz_type) { - case DNS_RPZ_TYPE_QNAME: - case DNS_RPZ_TYPE_NSDNAME: - result = add_name(rpzs, rpz_num, rpz_type, src_name); - break; - case DNS_RPZ_TYPE_CLIENT_IP: - case DNS_RPZ_TYPE_IP: - case DNS_RPZ_TYPE_NSIP: - result = add_cidr(rpzs, rpz_num, rpz_type, src_name); - break; - case DNS_RPZ_TYPE_BAD: - break; - } - - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); - UNLOCK(&rpzs->maint_lock); - return (result); -} - -/* - * Remove an IP address from the radix tree. - */ -static void -del_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, dns_name_t *src_name) -{ - isc_result_t result; - dns_rpz_cidr_key_t tgt_ip; - dns_rpz_prefix_t tgt_prefix; - dns_rpz_addr_zbits_t tgt_set; - dns_rpz_cidr_node_t *tgt, *parent, *child; - - /* - * Do not worry about invalid rpz IP address names. If we - * are here, then something relevant was added and so was - * valid. Invalid names here are usually internal RBTDB nodes. - */ - result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpzs, rpz_num, rpz_type, - src_name, &tgt_ip, &tgt_prefix, &tgt_set); - if (result != ISC_R_SUCCESS) - return; - - result = search(rpzs, &tgt_ip, tgt_prefix, &tgt_set, false, &tgt); - if (result != ISC_R_SUCCESS) { - INSIST(result == ISC_R_NOTFOUND || - result == DNS_R_PARTIALMATCH); - /* - * Do not worry about missing summary RBT nodes that probably - * correspond to RBTDB nodes that were implicit RBT nodes - * that were later added for (often empty) wildcards - * and then to the RBTDB deferred cleanup list. - */ - return; - } - - /* - * Mark the node and its parents to reflect the deleted IP address. - * Do not count bits that are already clear for internal RBTDB nodes. - */ - tgt_set.client_ip &= tgt->set.client_ip; - tgt_set.ip &= tgt->set.ip; - tgt_set.nsip &= tgt->set.nsip; - tgt->set.client_ip &= ~tgt_set.client_ip; - tgt->set.ip &= ~tgt_set.ip; - tgt->set.nsip &= ~tgt_set.nsip; - set_sum_pair(tgt); - - adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, false); - - /* - * We might need to delete 2 nodes. - */ - do { - /* - * The node is now useless if it has no data of its own - * and 0 or 1 children. We are finished if it is not useless. - */ - if ((child = tgt->child[0]) != NULL) { - if (tgt->child[1] != NULL) - break; - } else { - child = tgt->child[1]; - } - if (tgt->set.client_ip != 0 || - tgt->set.ip != 0 || - tgt->set.nsip != 0) - break; - - /* - * Replace the pointer to this node in the parent with - * the remaining child or NULL. - */ - parent = tgt->parent; - if (parent == NULL) { - rpzs->cidr = child; - } else { - parent->child[parent->child[1] == tgt] = child; - } - /* - * If the child exists fix up its parent pointer. - */ - if (child != NULL) - child->parent = parent; - isc_mem_put(rpzs->mctx, tgt, sizeof(*tgt)); - - tgt = parent; - } while (tgt != NULL); -} - -static void -del_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_rpz_type_t rpz_type, dns_name_t *src_name) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - dns_fixedname_t trig_namef; - dns_name_t *trig_name; - dns_rbtnode_t *nmnode; - dns_rpz_nm_data_t *nm_data, del_data; - isc_result_t result; - bool exists; - - /* - * We need a summary database of names even with 1 policy zone, - * because wildcard triggers are handled differently. - */ - - trig_name = dns_fixedname_initname(&trig_namef); - name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &del_data); - - nmnode = NULL; - result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, 0, - NULL, NULL); - if (result != ISC_R_SUCCESS) { - /* - * Do not worry about missing summary RBT nodes that probably - * correspond to RBTDB nodes that were implicit RBT nodes - * that were later added for (often empty) wildcards - * and then to the RBTDB deferred cleanup list. - */ - if (result == ISC_R_NOTFOUND || - result == DNS_R_PARTIALMATCH) - return; - dns_name_format(src_name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz del_name(%s) node search failed: %s", - namebuf, isc_result_totext(result)); - return; - } - - nm_data = nmnode->data; - INSIST(nm_data != NULL); - - /* - * Do not count bits that next existed for RBT nodes that would we - * would not have found in a summary for a single RBTDB tree. - */ - del_data.set.qname &= nm_data->set.qname; - del_data.set.ns &= nm_data->set.ns; - del_data.wild.qname &= nm_data->wild.qname; - del_data.wild.ns &= nm_data->wild.ns; - - exists = (del_data.set.qname != 0 || - del_data.set.ns != 0 || - del_data.wild.qname != 0 || - del_data.wild.ns != 0); - - nm_data->set.qname &= ~del_data.set.qname; - nm_data->set.ns &= ~del_data.set.ns; - nm_data->wild.qname &= ~del_data.wild.qname; - nm_data->wild.ns &= ~del_data.wild.ns; - - if (nm_data->set.qname == 0 && nm_data->set.ns == 0 && - nm_data->wild.qname == 0 && nm_data->wild.ns == 0) { - result = dns_rbt_deletenode(rpzs->rbt, nmnode, false); - if (result != ISC_R_SUCCESS) { - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". - */ - dns_name_format(src_name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz del_name(%s) node delete failed: %s", - namebuf, isc_result_totext(result)); - } - } - - if (exists) - adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, false); -} - -/* - * Remove an IP address from the radix tree or a name from the summary database. - */ -void -dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, - dns_name_t *src_name) { - dns_rpz_zone_t *rpz; - dns_rpz_type_t rpz_type; - - REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); - rpz = rpzs->zones[rpz_num]; - REQUIRE(rpz != NULL); - - rpz_type = type_from_name(rpz, src_name); - - LOCK(&rpzs->maint_lock); - RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); - - switch (rpz_type) { - case DNS_RPZ_TYPE_QNAME: - case DNS_RPZ_TYPE_NSDNAME: - del_name(rpzs, rpz_num, rpz_type, src_name); - break; - case DNS_RPZ_TYPE_CLIENT_IP: - case DNS_RPZ_TYPE_IP: - case DNS_RPZ_TYPE_NSIP: - del_cidr(rpzs, rpz_num, rpz_type, src_name); - break; - case DNS_RPZ_TYPE_BAD: - break; - } - - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); - UNLOCK(&rpzs->maint_lock); -} - -/* - * Search the summary radix tree to get a relative owner name in a - * policy zone relevant to a triggering IP address. - * rpz_type and zbits limit the search for IP address netaddr - * return the policy zone's number or DNS_RPZ_INVALID_NUM - * ip_name is the relative owner name found and - * *prefixp is its prefix length. - */ -dns_rpz_num_t -dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, - dns_name_t *ip_name, dns_rpz_prefix_t *prefixp) -{ - dns_rpz_cidr_key_t tgt_ip; - dns_rpz_addr_zbits_t tgt_set; - dns_rpz_cidr_node_t *found; - isc_result_t result; - dns_rpz_num_t rpz_num = 0; - dns_rpz_have_t have; - int i; - - LOCK(&rpzs->maint_lock); - have = rpzs->have; - UNLOCK(&rpzs->maint_lock); - - /* - * Convert IP address to CIDR tree key. - */ - if (netaddr->family == AF_INET) { - tgt_ip.w[0] = 0; - tgt_ip.w[1] = 0; - tgt_ip.w[2] = ADDR_V4MAPPED; - tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr); - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - zbits &= have.client_ipv4; - break; - case DNS_RPZ_TYPE_IP: - zbits &= have.ipv4; - break; - case DNS_RPZ_TYPE_NSIP: - zbits &= have.nsipv4; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else if (netaddr->family == AF_INET6) { - dns_rpz_cidr_key_t src_ip6; - - /* - * Given the int aligned struct in_addr member of netaddr->type - * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *, - * but some people object. - */ - memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w)); - for (i = 0; i < 4; i++) { - tgt_ip.w[i] = ntohl(src_ip6.w[i]); - } - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - zbits &= have.client_ipv6; - break; - case DNS_RPZ_TYPE_IP: - zbits &= have.ipv6; - break; - case DNS_RPZ_TYPE_NSIP: - zbits &= have.nsipv6; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - } else { - return (DNS_RPZ_INVALID_NUM); - } - - if (zbits == 0) - return (DNS_RPZ_INVALID_NUM); - make_addr_set(&tgt_set, zbits, rpz_type); - - RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); - result = search(rpzs, &tgt_ip, 128, &tgt_set, false, &found); - if (result == ISC_R_NOTFOUND) { - /* - * There are no eligible zones for this IP address. - */ - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - return (DNS_RPZ_INVALID_NUM); - } - - /* - * Construct the trigger name for the longest matching trigger - * in the first eligible zone with a match. - */ - *prefixp = found->prefix; - switch (rpz_type) { - case DNS_RPZ_TYPE_CLIENT_IP: - rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip); - break; - case DNS_RPZ_TYPE_IP: - rpz_num = zbit_to_num(found->set.ip & tgt_set.ip); - break; - case DNS_RPZ_TYPE_NSIP: - rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name); - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - if (result != ISC_R_SUCCESS) { - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". - */ - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "rpz ip2name() failed: %s", - isc_result_totext(result)); - return (DNS_RPZ_INVALID_NUM); - } - return (rpz_num); -} - -/* - * Search the summary radix tree for policy zones with triggers matching - * a name. - */ -dns_rpz_zbits_t -dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, - dns_rpz_zbits_t zbits, dns_name_t *trig_name) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - dns_rbtnode_t *nmnode; - const dns_rpz_nm_data_t *nm_data; - dns_rpz_zbits_t found_zbits; - dns_rbtnodechain_t chain; - isc_result_t result; - int i; - - if (zbits == 0) { - return (0); - } - - found_zbits = 0; - - dns_rbtnodechain_init(&chain, NULL); - - RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); - - nmnode = NULL; - result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, - &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); - switch (result) { - case ISC_R_SUCCESS: - nm_data = nmnode->data; - if (nm_data != NULL) { - if (rpz_type == DNS_RPZ_TYPE_QNAME) { - found_zbits = nm_data->set.qname; - } else { - found_zbits = nm_data->set.ns; - } - } - /* FALLTHROUGH */ - - case DNS_R_PARTIALMATCH: - i = chain.level_matches; - nmnode = chain.levels[chain.level_matches]; - - /* Whenever an exact match is found by dns_rbt_findnode(), - * the highest level node in the chain will not be put into - * chain->levels[] array, but instead the chain->end - * pointer will be adjusted to point to that node. - * - * Suppose we have the following entries in a rpz zone: - * example.com CNAME rpz-passthru. - * *.example.com CNAME rpz-passthru. - * - * A query for www.example.com would result in the - * following chain object returned by dns_rbt_findnode(): - * chain->level_count = 2 - * chain->level_matches = 2 - * chain->levels[0] = . - * chain->levels[1] = example.com - * chain->levels[2] = NULL - * chain->end = www - * - * Since exact matches only care for testing rpz set bits, - * we need to test for rpz wild bits through iterating the - * nodechain, and that includes testing the rpz wild bits in the - * highest level node found. In the case of an exact match, - * chain->levels[chain->level_matches] will be NULL, to address - * that we must use chain->end as the start - * point, then iterate over the remaining levels in the chain. - */ - if (nmnode == NULL) { - --i; - nmnode = chain.end; - } - - while (nmnode != NULL) { - nm_data = nmnode->data; - if (nm_data != NULL) { - if (rpz_type == DNS_RPZ_TYPE_QNAME) { - found_zbits |= nm_data->wild.qname; - } else { - found_zbits |= nm_data->wild.ns; - } - } - - if (i >= 0) { - nmnode = chain.levels[i]; - --i; - } else { - break; - } - } - break; - - case ISC_R_NOTFOUND: - break; - - default: - /* - * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". - */ - dns_name_format(trig_name, namebuf, sizeof(namebuf)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, - DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, - "dns_rpz_find_name(%s) failed: %s", - namebuf, isc_result_totext(result)); - break; - } - - RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); - - dns_rbtnodechain_invalidate(&chain); - - return (zbits & found_zbits); -} - -/* - * Translate CNAME rdata to a QNAME response policy action. - */ -dns_rpz_policy_t -dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, - dns_name_t *selfname) -{ - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_cname_t cname; - isc_result_t result; - - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - INSIST(result == ISC_R_SUCCESS); - dns_rdata_reset(&rdata); - - /* - * CNAME . means NXDOMAIN - */ - if (dns_name_equal(&cname.cname, dns_rootname)) - return (DNS_RPZ_POLICY_NXDOMAIN); - - if (dns_name_iswildcard(&cname.cname)) { - /* - * CNAME *. means NODATA - */ - if (dns_name_countlabels(&cname.cname) == 2) - return (DNS_RPZ_POLICY_NODATA); - - /* - * A qname of www.evil.com and a policy of - * *.evil.com CNAME *.garden.net - * gives a result of - * evil.com CNAME evil.com.garden.net - */ - if (dns_name_countlabels(&cname.cname) > 2) - return (DNS_RPZ_POLICY_WILDCNAME); - } - - /* - * CNAME rpz-tcp-only. means "send truncated UDP responses." - */ - if (dns_name_equal(&cname.cname, &rpz->tcp_only)) - return (DNS_RPZ_POLICY_TCP_ONLY); - - /* - * CNAME rpz-drop. means "do not respond." - */ - if (dns_name_equal(&cname.cname, &rpz->drop)) - return (DNS_RPZ_POLICY_DROP); - - /* - * CNAME rpz-passthru. means "do not rewrite." - */ - if (dns_name_equal(&cname.cname, &rpz->passthru)) - return (DNS_RPZ_POLICY_PASSTHRU); - - /* - * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU - */ - if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) - return (DNS_RPZ_POLICY_PASSTHRU); - - /* - * Any other rdata gives a response consisting of the rdata. - */ - return (DNS_RPZ_POLICY_RECORD); -} diff --git a/lib/dns-pkcs11/rriterator.c b/lib/dns-pkcs11/rriterator.c deleted file mode 100644 index fb4eb34..0000000 --- a/lib/dns-pkcs11/rriterator.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -/*** - *** Imports - ***/ - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/*** - *** RRiterator methods - ***/ - -isc_result_t -dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver, - isc_stdtime_t now) -{ - isc_result_t result; - it->magic = RRITERATOR_MAGIC; - it->db = db; - it->dbit = NULL; - it->ver = ver; - it->now = now; - it->node = NULL; - result = dns_db_createiterator(it->db, 0, &it->dbit); - if (result != ISC_R_SUCCESS) - return (result); - it->rdatasetit = NULL; - dns_rdata_init(&it->rdata); - dns_rdataset_init(&it->rdataset); - dns_fixedname_init(&it->fixedname); - INSIST(! dns_rdataset_isassociated(&it->rdataset)); - it->result = ISC_R_SUCCESS; - return (it->result); -} - -isc_result_t -dns_rriterator_first(dns_rriterator_t *it) { - REQUIRE(VALID_RRITERATOR(it)); - /* Reset state */ - if (dns_rdataset_isassociated(&it->rdataset)) - dns_rdataset_disassociate(&it->rdataset); - if (it->rdatasetit != NULL) - dns_rdatasetiter_destroy(&it->rdatasetit); - if (it->node != NULL) - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_first(it->dbit); - - /* - * The top node may be empty when out of zone glue exists. - * Walk the tree to find the first node with data. - */ - while (it->result == ISC_R_SUCCESS) { - it->result = dns_dbiterator_current(it->dbit, &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_db_allrdatasets(it->db, it->node, it->ver, - it->now, &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_rdatasetiter_first(it->rdatasetit); - if (it->result != ISC_R_SUCCESS) { - /* - * This node is empty. Try next node. - */ - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - continue; - } - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - dns_rdataset_getownercase(&it->rdataset, - dns_fixedname_name(&it->fixedname)); - it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; - it->result = dns_rdataset_first(&it->rdataset); - return (it->result); - } - return (it->result); -} - -isc_result_t -dns_rriterator_nextrrset(dns_rriterator_t *it) { - REQUIRE(VALID_RRITERATOR(it)); - if (dns_rdataset_isassociated(&it->rdataset)) - dns_rdataset_disassociate(&it->rdataset); - it->result = dns_rdatasetiter_next(it->rdatasetit); - /* - * The while loop body is executed more than once - * only when an empty dbnode needs to be skipped. - */ - while (it->result == ISC_R_NOMORE) { - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - if (it->result == ISC_R_NOMORE) { - /* We are at the end of the entire database. */ - return (it->result); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_dbiterator_current(it->dbit, &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_db_allrdatasets(it->db, it->node, it->ver, - it->now, &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_rdatasetiter_first(it->rdatasetit); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - dns_rdataset_getownercase(&it->rdataset, - dns_fixedname_name(&it->fixedname)); - it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; - it->result = dns_rdataset_first(&it->rdataset); - return (it->result); -} - -isc_result_t -dns_rriterator_next(dns_rriterator_t *it) { - REQUIRE(VALID_RRITERATOR(it)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - INSIST(it->dbit != NULL); - INSIST(it->node != NULL); - INSIST(it->rdatasetit != NULL); - - it->result = dns_rdataset_next(&it->rdataset); - if (it->result == ISC_R_NOMORE) - return (dns_rriterator_nextrrset(it)); - return (it->result); -} - -void -dns_rriterator_pause(dns_rriterator_t *it) { - REQUIRE(VALID_RRITERATOR(it)); - RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS); -} - -void -dns_rriterator_destroy(dns_rriterator_t *it) { - REQUIRE(VALID_RRITERATOR(it)); - if (dns_rdataset_isassociated(&it->rdataset)) - dns_rdataset_disassociate(&it->rdataset); - if (it->rdatasetit != NULL) - dns_rdatasetiter_destroy(&it->rdatasetit); - if (it->node != NULL) - dns_db_detachnode(it->db, &it->node); - dns_dbiterator_destroy(&it->dbit); -} - -void -dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, - uint32_t *ttl, dns_rdataset_t **rdataset, - dns_rdata_t **rdata) -{ - REQUIRE(name != NULL && *name == NULL); - REQUIRE(VALID_RRITERATOR(it)); - REQUIRE(it->result == ISC_R_SUCCESS); - REQUIRE(rdataset == NULL || *rdataset == NULL); - REQUIRE(rdata == NULL || *rdata == NULL); - - *name = dns_fixedname_name(&it->fixedname); - *ttl = it->rdataset.ttl; - - dns_rdata_reset(&it->rdata); - dns_rdataset_current(&it->rdataset, &it->rdata); - - if (rdataset != NULL) - *rdataset = &it->rdataset; - - if (rdata != NULL) - *rdata = &it->rdata; -} diff --git a/lib/dns-pkcs11/rrl.c b/lib/dns-pkcs11/rrl.c deleted file mode 100644 index 98fc83a..0000000 --- a/lib/dns-pkcs11/rrl.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -/* - * Rate limit DNS responses. - */ - -/* #define ISC_LIST_CHECKINIT */ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static void -log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, bool early, - char *log_buf, unsigned int log_buf_len); - -/* - * Get a modulus for a hash function that is tolerably likely to be - * relatively prime to most inputs. Of course, we get a prime for for initial - * values not larger than the square of the last prime. We often get a prime - * after that. - * This works well in practice for hash tables up to at least 100 - * times the square of the last prime and better than a multiplicative hash. - */ -static int -hash_divisor(unsigned int initial) { - static uint16_t primes[] = { - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, - 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, -#if 0 - 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, - 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, - 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, - 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, - 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, - 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, - 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, - 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, - 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009, -#endif - }; - int divisions, tries; - unsigned int result; - uint16_t *pp, p; - - result = initial; - - if (primes[sizeof(primes)/sizeof(primes[0])-1] >= result) { - pp = primes; - while (*pp < result) - ++pp; - return (*pp); - } - - if ((result & 1) == 0) - ++result; - - divisions = 0; - tries = 1; - pp = primes; - do { - p = *pp++; - ++divisions; - if ((result % p) == 0) { - ++tries; - result += 2; - pp = primes; - } - } while (pp < &primes[sizeof(primes) / sizeof(primes[0])]); - - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3, - "%d hash_divisor() divisions in %d tries" - " to get %d from %d", - divisions, tries, result, initial); - - return (result); -} - -/* - * Convert a timestamp to a number of seconds in the past. - */ -static inline int -delta_rrl_time(isc_stdtime_t ts, isc_stdtime_t now) { - int delta; - - delta = now - ts; - if (delta >= 0) - return (delta); - - /* - * The timestamp is in the future. That future might result from - * re-ordered requests, because we use timestamps on requests - * instead of consulting a clock. Timestamps in the distant future are - * assumed to result from clock changes. When the clock changes to - * the past, make existing timestamps appear to be in the past. - */ - if (delta < -DNS_RRL_MAX_TIME_TRAVEL) - return (DNS_RRL_FOREVER); - return (0); -} - -static inline int -get_age(const dns_rrl_t *rrl, const dns_rrl_entry_t *e, isc_stdtime_t now) { - if (!e->ts_valid) - return (DNS_RRL_FOREVER); - return (delta_rrl_time(e->ts + rrl->ts_bases[e->ts_gen], now)); -} - -static inline void -set_age(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_stdtime_t now) { - dns_rrl_entry_t *e_old; - unsigned int ts_gen; - int i, ts; - - ts_gen = rrl->ts_gen; - ts = now - rrl->ts_bases[ts_gen]; - if (ts < 0) { - if (ts < -DNS_RRL_MAX_TIME_TRAVEL) - ts = DNS_RRL_FOREVER; - else - ts = 0; - } - - /* - * Make a new timestamp base if the current base is too old. - * All entries older than DNS_RRL_MAX_WINDOW seconds are ancient, - * useless history. Their timestamps can be treated as if they are - * all the same. - * We only do arithmetic on more recent timestamps, so bases for - * older timestamps can be recycled provided the old timestamps are - * marked as ancient history. - * This loop is almost always very short because most entries are - * recycled after one second and any entries that need to be marked - * are older than (DNS_RRL_TS_BASES)*DNS_RRL_MAX_TS seconds. - */ - if (ts >= DNS_RRL_MAX_TS) { - ts_gen = (ts_gen + 1) % DNS_RRL_TS_BASES; - for (e_old = ISC_LIST_TAIL(rrl->lru), i = 0; - e_old != NULL && (e_old->ts_gen == ts_gen || - !ISC_LINK_LINKED(e_old, hlink)); - e_old = ISC_LIST_PREV(e_old, lru), ++i) - { - e_old->ts_valid = false; - } - if (i != 0) - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, - "rrl new time base scanned %d entries" - " at %d for %d %d %d %d", - i, now, rrl->ts_bases[ts_gen], - rrl->ts_bases[(ts_gen + 1) % - DNS_RRL_TS_BASES], - rrl->ts_bases[(ts_gen + 2) % - DNS_RRL_TS_BASES], - rrl->ts_bases[(ts_gen + 3) % - DNS_RRL_TS_BASES]); - rrl->ts_gen = ts_gen; - rrl->ts_bases[ts_gen] = now; - ts = 0; - } - - e->ts_gen = ts_gen; - e->ts = ts; - e->ts_valid = true; -} - -static isc_result_t -expand_entries(dns_rrl_t *rrl, int newsize) { - unsigned int bsize; - dns_rrl_block_t *b; - dns_rrl_entry_t *e; - double rate; - int i; - - if (rrl->num_entries + newsize >= rrl->max_entries && - rrl->max_entries != 0) - { - newsize = rrl->max_entries - rrl->num_entries; - if (newsize <= 0) - return (ISC_R_SUCCESS); - } - - /* - * Log expansions so that the user can tune max-table-size - * and min-table-size. - */ - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) && - rrl->hash != NULL) { - rate = rrl->probes; - if (rrl->searches != 0) - rate /= rrl->searches; - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, - "increase from %d to %d RRL entries with" - " %d bins; average search length %.1f", - rrl->num_entries, rrl->num_entries+newsize, - rrl->hash->length, rate); - } - - bsize = sizeof(dns_rrl_block_t) + (newsize-1)*sizeof(dns_rrl_entry_t); - b = isc_mem_get(rrl->mctx, bsize); - if (b == NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL, - "isc_mem_get(%d) failed for RRL entries", - bsize); - return (ISC_R_NOMEMORY); - } - memset(b, 0, bsize); - b->size = bsize; - - e = b->entries; - for (i = 0; i < newsize; ++i, ++e) { - ISC_LINK_INIT(e, hlink); - ISC_LIST_INITANDAPPEND(rrl->lru, e, lru); - } - rrl->num_entries += newsize; - ISC_LIST_INITANDAPPEND(rrl->blocks, b, link); - - return (ISC_R_SUCCESS); -} - -static inline dns_rrl_bin_t * -get_bin(dns_rrl_hash_t *hash, unsigned int hval) { - INSIST(hash != NULL); - return (&hash->bins[hval % hash->length]); -} - -static void -free_old_hash(dns_rrl_t *rrl) { - dns_rrl_hash_t *old_hash; - dns_rrl_bin_t *old_bin; - dns_rrl_entry_t *e, *e_next; - - old_hash = rrl->old_hash; - for (old_bin = &old_hash->bins[0]; - old_bin < &old_hash->bins[old_hash->length]; - ++old_bin) - { - for (e = ISC_LIST_HEAD(*old_bin); e != NULL; e = e_next) { - e_next = ISC_LIST_NEXT(e, hlink); - ISC_LINK_INIT(e, hlink); - } - } - - isc_mem_put(rrl->mctx, old_hash, - sizeof(*old_hash) - + (old_hash->length - 1) * sizeof(old_hash->bins[0])); - rrl->old_hash = NULL; -} - -static isc_result_t -expand_rrl_hash(dns_rrl_t *rrl, isc_stdtime_t now) { - dns_rrl_hash_t *hash; - int old_bins, new_bins, hsize; - double rate; - - if (rrl->old_hash != NULL) - free_old_hash(rrl); - - /* - * Most searches fail and so go to the end of the chain. - * Use a small hash table load factor. - */ - old_bins = (rrl->hash == NULL) ? 0 : rrl->hash->length; - new_bins = old_bins/8 + old_bins; - if (new_bins < rrl->num_entries) - new_bins = rrl->num_entries; - new_bins = hash_divisor(new_bins); - - hsize = sizeof(dns_rrl_hash_t) + (new_bins-1)*sizeof(hash->bins[0]); - hash = isc_mem_get(rrl->mctx, hsize); - if (hash == NULL) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL, - "isc_mem_get(%d) failed for" - " RRL hash table", - hsize); - return (ISC_R_NOMEMORY); - } - memset(hash, 0, hsize); - hash->length = new_bins; - rrl->hash_gen ^= 1; - hash->gen = rrl->hash_gen; - - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) && old_bins != 0) { - rate = rrl->probes; - if (rrl->searches != 0) - rate /= rrl->searches; - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, - "increase from %d to %d RRL bins for" - " %d entries; average search length %.1f", - old_bins, new_bins, rrl->num_entries, rate); - } - - rrl->old_hash = rrl->hash; - if (rrl->old_hash != NULL) - rrl->old_hash->check_time = now; - rrl->hash = hash; - - return (ISC_R_SUCCESS); -} - -static void -ref_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, int probes, isc_stdtime_t now) { - /* - * Make the entry most recently used. - */ - if (ISC_LIST_HEAD(rrl->lru) != e) { - if (e == rrl->last_logged) - rrl->last_logged = ISC_LIST_PREV(e, lru); - ISC_LIST_UNLINK(rrl->lru, e, lru); - ISC_LIST_PREPEND(rrl->lru, e, lru); - } - - /* - * Expand the hash table if it is time and necessary. - * This will leave the newly referenced entry in a chain in the - * old hash table. It will migrate to the new hash table the next - * time it is used or be cut loose when the old hash table is destroyed. - */ - rrl->probes += probes; - ++rrl->searches; - if (rrl->searches > 100 && - delta_rrl_time(rrl->hash->check_time, now) > 1) { - if (rrl->probes/rrl->searches > 2) - expand_rrl_hash(rrl, now); - rrl->hash->check_time = now; - rrl->probes = 0; - rrl->searches = 0; - } -} - -static inline bool -key_cmp(const dns_rrl_key_t *a, const dns_rrl_key_t *b) { - if (memcmp(a, b, sizeof(dns_rrl_key_t)) == 0) - return (true); - return (false); -} - -static inline uint32_t -hash_key(const dns_rrl_key_t *key) { - uint32_t hval; - int i; - - hval = key->w[0]; - for (i = sizeof(key->w) / sizeof(key->w[0]) - 1; i >= 0; --i) { - hval = key->w[i] + (hval<<1); - } - return (hval); -} - -/* - * Construct the hash table key. - * Use a hash of the DNS query name to save space in the database. - * Collisions result in legitimate rate limiting responses for one - * query name also limiting responses for other names to the - * same client. This is rare and benign enough given the large - * space costs compared to keeping the entire name in the database - * entry or the time costs of dynamic allocation. - */ -static void -make_key(const dns_rrl_t *rrl, dns_rrl_key_t *key, - const isc_sockaddr_t *client_addr, - dns_rdatatype_t qtype, dns_name_t *qname, dns_rdataclass_t qclass, - dns_rrl_rtype_t rtype) -{ - dns_name_t base; - dns_offsets_t base_offsets; - int labels, i; - - memset(key, 0, sizeof(*key)); - - key->s.rtype = rtype; - if (rtype == DNS_RRL_RTYPE_QUERY) { - key->s.qtype = qtype; - key->s.qclass = qclass & 0xff; - } else if (rtype == DNS_RRL_RTYPE_REFERRAL || - rtype == DNS_RRL_RTYPE_NODATA) { - /* - * Because there is no qtype in the empty answer sections of - * referral and NODATA responses, count them as the same. - */ - key->s.qclass = qclass & 0xff; - } - - if (qname != NULL && qname->labels != 0) { - /* - * Ignore the first label of wildcards. - */ - if ((qname->attributes & DNS_NAMEATTR_WILDCARD) != 0 && - (labels = dns_name_countlabels(qname)) > 1) - { - dns_name_init(&base, base_offsets); - dns_name_getlabelsequence(qname, 1, labels-1, &base); - key->s.qname_hash = - dns_name_fullhash(&base, false); - } else { - key->s.qname_hash = - dns_name_fullhash(qname, false); - } - } - - switch (client_addr->type.sa.sa_family) { - case AF_INET: - key->s.ip[0] = (client_addr->type.sin.sin_addr.s_addr & - rrl->ipv4_mask); - break; - case AF_INET6: - key->s.ipv6 = true; - memmove(key->s.ip, &client_addr->type.sin6.sin6_addr, - sizeof(key->s.ip)); - for (i = 0; i < DNS_RRL_MAX_PREFIX/32; ++i) - key->s.ip[i] &= rrl->ipv6_mask[i]; - break; - } -} - -static inline dns_rrl_rate_t * -get_rate(dns_rrl_t *rrl, dns_rrl_rtype_t rtype) { - switch (rtype) { - case DNS_RRL_RTYPE_QUERY: - return (&rrl->responses_per_second); - case DNS_RRL_RTYPE_REFERRAL: - return (&rrl->referrals_per_second); - case DNS_RRL_RTYPE_NODATA: - return (&rrl->nodata_per_second); - case DNS_RRL_RTYPE_NXDOMAIN: - return (&rrl->nxdomains_per_second); - case DNS_RRL_RTYPE_ERROR: - return (&rrl->errors_per_second); - case DNS_RRL_RTYPE_ALL: - return (&rrl->all_per_second); - default: - INSIST(0); - ISC_UNREACHABLE(); - } -} - -static int -response_balance(dns_rrl_t *rrl, const dns_rrl_entry_t *e, int age) { - dns_rrl_rate_t *ratep; - int balance, rate; - - if (e->key.s.rtype == DNS_RRL_RTYPE_TCP) { - rate = 1; - } else { - ratep = get_rate(rrl, e->key.s.rtype); - rate = ratep->scaled; - } - - balance = e->responses + age * rate; - if (balance > rate) - balance = rate; - return (balance); -} - -/* - * Search for an entry for a response and optionally create it. - */ -static dns_rrl_entry_t * -get_entry(dns_rrl_t *rrl, const isc_sockaddr_t *client_addr, - dns_rdataclass_t qclass, dns_rdatatype_t qtype, dns_name_t *qname, - dns_rrl_rtype_t rtype, isc_stdtime_t now, bool create, - char *log_buf, unsigned int log_buf_len) -{ - dns_rrl_key_t key; - uint32_t hval; - dns_rrl_entry_t *e; - dns_rrl_hash_t *hash; - dns_rrl_bin_t *new_bin, *old_bin; - int probes, age; - - make_key(rrl, &key, client_addr, qtype, qname, qclass, rtype); - hval = hash_key(&key); - - /* - * Look for the entry in the current hash table. - */ - new_bin = get_bin(rrl->hash, hval); - probes = 1; - e = ISC_LIST_HEAD(*new_bin); - while (e != NULL) { - if (key_cmp(&e->key, &key)) { - ref_entry(rrl, e, probes, now); - return (e); - } - ++probes; - e = ISC_LIST_NEXT(e, hlink); - } - - /* - * Look in the old hash table. - */ - if (rrl->old_hash != NULL) { - old_bin = get_bin(rrl->old_hash, hval); - e = ISC_LIST_HEAD(*old_bin); - while (e != NULL) { - if (key_cmp(&e->key, &key)) { - ISC_LIST_UNLINK(*old_bin, e, hlink); - ISC_LIST_PREPEND(*new_bin, e, hlink); - e->hash_gen = rrl->hash_gen; - ref_entry(rrl, e, probes, now); - return (e); - } - e = ISC_LIST_NEXT(e, hlink); - } - - /* - * Discard previous hash table when all of its entries are old. - */ - age = delta_rrl_time(rrl->old_hash->check_time, now); - if (age > rrl->window) - free_old_hash(rrl); - } - - if (!create) - return (NULL); - - /* - * The entry does not exist, so create it by finding a free entry. - * Keep currently penalized and logged entries. - * Try to make more entries if none are idle. - * Steal the oldest entry if we cannot create more. - */ - for (e = ISC_LIST_TAIL(rrl->lru); - e != NULL; - e = ISC_LIST_PREV(e, lru)) - { - if (!ISC_LINK_LINKED(e, hlink)) - break; - age = get_age(rrl, e, now); - if (age <= 1) { - e = NULL; - break; - } - if (!e->logged && response_balance(rrl, e, age) > 0) - break; - } - if (e == NULL) { - expand_entries(rrl, ISC_MIN((rrl->num_entries+1)/2, 1000)); - e = ISC_LIST_TAIL(rrl->lru); - } - if (e->logged) - log_end(rrl, e, true, log_buf, log_buf_len); - if (ISC_LINK_LINKED(e, hlink)) { - if (e->hash_gen == rrl->hash_gen) - hash = rrl->hash; - else - hash = rrl->old_hash; - old_bin = get_bin(hash, hash_key(&e->key)); - ISC_LIST_UNLINK(*old_bin, e, hlink); - } - ISC_LIST_PREPEND(*new_bin, e, hlink); - e->hash_gen = rrl->hash_gen; - e->key = key; - e->ts_valid = false; - ref_entry(rrl, e, probes, now); - return (e); -} - -static void -debit_log(const dns_rrl_entry_t *e, int age, const char *action) { - char buf[sizeof("age=1234567890")]; - const char *age_str; - - if (age == DNS_RRL_FOREVER) { - age_str = ""; - } else { - snprintf(buf, sizeof(buf), "age=%d", age); - age_str = buf; - } - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3, - "rrl %08x %6s responses=%-3d %s", - hash_key(&e->key), age_str, e->responses, action); -} - -static inline dns_rrl_result_t -debit_rrl_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, double qps, double scale, - const isc_sockaddr_t *client_addr, isc_stdtime_t now, - char *log_buf, unsigned int log_buf_len) -{ - int rate, new_rate, slip, new_slip, age, log_secs, min; - dns_rrl_rate_t *ratep; - dns_rrl_entry_t const *credit_e; - - /* - * Pick the rate counter. - * Optionally adjust the rate by the estimated query/second rate. - */ - ratep = get_rate(rrl, e->key.s.rtype); - rate = ratep->r; - if (rate == 0) - return (DNS_RRL_RESULT_OK); - - if (scale < 1.0) { - /* - * The limit for clients that have used TCP is not scaled. - */ - credit_e = get_entry(rrl, client_addr, - 0, dns_rdatatype_none, NULL, - DNS_RRL_RTYPE_TCP, now, false, - log_buf, log_buf_len); - if (credit_e != NULL) { - age = get_age(rrl, e, now); - if (age < rrl->window) - scale = 1.0; - } - } - if (scale < 1.0) { - new_rate = (int) (rate * scale); - if (new_rate < 1) - new_rate = 1; - if (ratep->scaled != new_rate) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, - DNS_RRL_LOG_DEBUG1, - "%d qps scaled %s by %.2f" - " from %d to %d", - (int)qps, ratep->str, scale, - rate, new_rate); - rate = new_rate; - ratep->scaled = rate; - } - } - - min = -rrl->window * rate; - - /* - * Treat time jumps into the recent past as no time. - * Treat entries older than the window as if they were just created - * Credit other entries. - */ - age = get_age(rrl, e, now); - if (age > 0) { - /* - * Credit tokens earned during elapsed time. - */ - if (age > rrl->window) { - e->responses = rate; - e->slip_cnt = 0; - } else { - e->responses += rate*age; - if (e->responses > rate) { - e->responses = rate; - e->slip_cnt = 0; - } - } - /* - * Find the seconds since last log message without overflowing - * small counter. This counter is reset when an entry is - * created. It is not necessarily reset when some requests - * are answered provided other requests continue to be dropped - * or slipped. This can happen when the request rate is just - * at the limit. - */ - if (e->logged) { - log_secs = e->log_secs; - log_secs += age; - if (log_secs > DNS_RRL_MAX_LOG_SECS || log_secs < 0) - log_secs = DNS_RRL_MAX_LOG_SECS; - e->log_secs = log_secs; - } - } - set_age(rrl, e, now); - - /* - * Debit the entry for this response. - */ - if (--e->responses >= 0) { - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) - debit_log(e, age, ""); - return (DNS_RRL_RESULT_OK); - } - - if (e->responses < min) - e->responses = min; - - /* - * Drop this response unless it should slip or leak. - */ - slip = rrl->slip.r; - if (slip > 2 && scale < 1.0) { - new_slip = (int) (slip * scale); - if (new_slip < 2) - new_slip = 2; - if (rrl->slip.scaled != new_slip) { - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, - DNS_RRL_LOG_DEBUG1, - "%d qps scaled slip" - " by %.2f from %d to %d", - (int)qps, scale, - slip, new_slip); - slip = new_slip; - rrl->slip.scaled = slip; - } - } - if (slip != 0 && e->key.s.rtype != DNS_RRL_RTYPE_ALL) { - if (e->slip_cnt++ == 0) { - if ((int) e->slip_cnt >= slip) - e->slip_cnt = 0; - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) - debit_log(e, age, "slip"); - return (DNS_RRL_RESULT_SLIP); - } else if ((int) e->slip_cnt >= slip) { - e->slip_cnt = 0; - } - } - - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) - debit_log(e, age, "drop"); - return (DNS_RRL_RESULT_DROP); -} - -static inline dns_rrl_qname_buf_t * -get_qname(dns_rrl_t *rrl, const dns_rrl_entry_t *e) { - dns_rrl_qname_buf_t *qbuf; - - qbuf = rrl->qnames[e->log_qname]; - if (qbuf == NULL || qbuf->e != e) - return (NULL); - return (qbuf); -} - -static inline void -free_qname(dns_rrl_t *rrl, dns_rrl_entry_t *e) { - dns_rrl_qname_buf_t *qbuf; - - qbuf = get_qname(rrl, e); - if (qbuf != NULL) { - qbuf->e = NULL; - ISC_LIST_APPEND(rrl->qname_free, qbuf, link); - } -} - -static void -add_log_str(isc_buffer_t *lb, const char *str, unsigned int str_len) { - isc_region_t region; - - isc_buffer_availableregion(lb, ®ion); - if (str_len >= region.length) { - if (region.length == 0U) - return; - str_len = region.length; - } - memmove(region.base, str, str_len); - isc_buffer_add(lb, str_len); -} - -#define ADD_LOG_CSTR(eb, s) add_log_str(eb, s, sizeof(s)-1) - -/* - * Build strings for the logs - */ -static void -make_log_buf(dns_rrl_t *rrl, dns_rrl_entry_t *e, - const char *str1, const char *str2, bool plural, - dns_name_t *qname, bool save_qname, - dns_rrl_result_t rrl_result, isc_result_t resp_result, - char *log_buf, unsigned int log_buf_len) -{ - isc_buffer_t lb; - dns_rrl_qname_buf_t *qbuf; - isc_netaddr_t cidr; - char strbuf[ISC_MAX(sizeof("/123"), sizeof(" (12345678)"))]; - const char *rstr; - isc_result_t msg_result; - - if (log_buf_len <= 1) { - if (log_buf_len == 1) - log_buf[0] = '\0'; - return; - } - isc_buffer_init(&lb, log_buf, log_buf_len-1); - - if (str1 != NULL) - add_log_str(&lb, str1, strlen(str1)); - if (str2 != NULL) - add_log_str(&lb, str2, strlen(str2)); - - switch (rrl_result) { - case DNS_RRL_RESULT_OK: - break; - case DNS_RRL_RESULT_DROP: - ADD_LOG_CSTR(&lb, "drop "); - break; - case DNS_RRL_RESULT_SLIP: - ADD_LOG_CSTR(&lb, "slip "); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - switch (e->key.s.rtype) { - case DNS_RRL_RTYPE_QUERY: - break; - case DNS_RRL_RTYPE_REFERRAL: - ADD_LOG_CSTR(&lb, "referral "); - break; - case DNS_RRL_RTYPE_NODATA: - ADD_LOG_CSTR(&lb, "NODATA "); - break; - case DNS_RRL_RTYPE_NXDOMAIN: - ADD_LOG_CSTR(&lb, "NXDOMAIN "); - break; - case DNS_RRL_RTYPE_ERROR: - if (resp_result == ISC_R_SUCCESS) { - ADD_LOG_CSTR(&lb, "error "); - } else { - rstr = isc_result_totext(resp_result); - add_log_str(&lb, rstr, strlen(rstr)); - ADD_LOG_CSTR(&lb, " error "); - } - break; - case DNS_RRL_RTYPE_ALL: - ADD_LOG_CSTR(&lb, "all "); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - - if (plural) - ADD_LOG_CSTR(&lb, "responses to "); - else - ADD_LOG_CSTR(&lb, "response to "); - - memset(&cidr, 0, sizeof(cidr)); - if (e->key.s.ipv6) { - snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv6_prefixlen); - cidr.family = AF_INET6; - memset(&cidr.type.in6, 0, sizeof(cidr.type.in6)); - memmove(&cidr.type.in6, e->key.s.ip, sizeof(e->key.s.ip)); - } else { - snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv4_prefixlen); - cidr.family = AF_INET; - cidr.type.in.s_addr = e->key.s.ip[0]; - } - msg_result = isc_netaddr_totext(&cidr, &lb); - if (msg_result != ISC_R_SUCCESS) - ADD_LOG_CSTR(&lb, "?"); - add_log_str(&lb, strbuf, strlen(strbuf)); - - if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY || - e->key.s.rtype == DNS_RRL_RTYPE_REFERRAL || - e->key.s.rtype == DNS_RRL_RTYPE_NODATA || - e->key.s.rtype == DNS_RRL_RTYPE_NXDOMAIN) { - qbuf = get_qname(rrl, e); - if (save_qname && qbuf == NULL && - qname != NULL && dns_name_isabsolute(qname)) { - /* - * Capture the qname for the "stop limiting" message. - */ - qbuf = ISC_LIST_TAIL(rrl->qname_free); - if (qbuf != NULL) { - ISC_LIST_UNLINK(rrl->qname_free, qbuf, link); - } else if (rrl->num_qnames < DNS_RRL_QNAMES) { - qbuf = isc_mem_get(rrl->mctx, sizeof(*qbuf)); - if (qbuf != NULL) { - memset(qbuf, 0, sizeof(*qbuf)); - ISC_LINK_INIT(qbuf, link); - qbuf->index = rrl->num_qnames; - rrl->qnames[rrl->num_qnames++] = qbuf; - } else { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, - DNS_RRL_LOG_FAIL, - "isc_mem_get(%d)" - " failed for RRL qname", - (int)sizeof(*qbuf)); - } - } - if (qbuf != NULL) { - e->log_qname = qbuf->index; - qbuf->e = e; - dns_fixedname_init(&qbuf->qname); - dns_name_copy(qname, - dns_fixedname_name(&qbuf->qname), - NULL); - } - } - if (qbuf != NULL) - qname = dns_fixedname_name(&qbuf->qname); - if (qname != NULL) { - ADD_LOG_CSTR(&lb, " for "); - (void)dns_name_totext(qname, true, &lb); - } else { - ADD_LOG_CSTR(&lb, " for (?)"); - } - if (e->key.s.rtype != DNS_RRL_RTYPE_NXDOMAIN) { - ADD_LOG_CSTR(&lb, " "); - (void)dns_rdataclass_totext(e->key.s.qclass, &lb); - if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY) { - ADD_LOG_CSTR(&lb, " "); - (void)dns_rdatatype_totext(e->key.s.qtype, &lb); - } - } - snprintf(strbuf, sizeof(strbuf), " (%08x)", - e->key.s.qname_hash); - add_log_str(&lb, strbuf, strlen(strbuf)); - } - - /* - * We saved room for '\0'. - */ - log_buf[isc_buffer_usedlength(&lb)] = '\0'; -} - -static void -log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, bool early, - char *log_buf, unsigned int log_buf_len) -{ - if (e->logged) { - make_log_buf(rrl, e, - early ? "*" : NULL, - rrl->log_only ? "would stop limiting " - : "stop limiting ", - true, NULL, false, - DNS_RRL_RESULT_OK, ISC_R_SUCCESS, - log_buf, log_buf_len); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, - "%s", log_buf); - free_qname(rrl, e); - e->logged = false; - --rrl->num_logged; - } -} - -/* - * Log messages for streams that have stopped being rate limited. - */ -static void -log_stops(dns_rrl_t *rrl, isc_stdtime_t now, int limit, - char *log_buf, unsigned int log_buf_len) -{ - dns_rrl_entry_t *e; - int age; - - for (e = rrl->last_logged; e != NULL; e = ISC_LIST_PREV(e, lru)) { - if (!e->logged) - continue; - if (now != 0) { - age = get_age(rrl, e, now); - if (age < DNS_RRL_STOP_LOG_SECS || - response_balance(rrl, e, age) < 0) - break; - } - - log_end(rrl, e, now == 0, log_buf, log_buf_len); - if (rrl->num_logged <= 0) - break; - - /* - * Too many messages could stall real work. - */ - if (--limit < 0) { - rrl->last_logged = ISC_LIST_PREV(e, lru); - return; - } - } - if (e == NULL) { - INSIST(rrl->num_logged == 0); - rrl->log_stops_time = now; - } - rrl->last_logged = e; -} - -/* - * Main rate limit interface. - */ -dns_rrl_result_t -dns_rrl(dns_view_t *view, - const isc_sockaddr_t *client_addr, bool is_tcp, - dns_rdataclass_t qclass, dns_rdatatype_t qtype, - dns_name_t *qname, isc_result_t resp_result, isc_stdtime_t now, - bool wouldlog, char *log_buf, unsigned int log_buf_len) -{ - dns_rrl_t *rrl; - dns_rrl_rtype_t rtype; - dns_rrl_entry_t *e; - isc_netaddr_t netclient; - int secs; - double qps, scale; - int exempt_match; - isc_result_t result; - dns_rrl_result_t rrl_result; - - INSIST(log_buf != NULL && log_buf_len > 0); - - rrl = view->rrl; - if (rrl->exempt != NULL) { - isc_netaddr_fromsockaddr(&netclient, client_addr); - result = dns_acl_match(&netclient, NULL, rrl->exempt, - &view->aclenv, &exempt_match, NULL); - if (result == ISC_R_SUCCESS && exempt_match > 0) - return (DNS_RRL_RESULT_OK); - } - - LOCK(&rrl->lock); - - /* - * Estimate total query per second rate when scaling by qps. - */ - if (rrl->qps_scale == 0) { - qps = 0.0; - scale = 1.0; - } else { - ++rrl->qps_responses; - secs = delta_rrl_time(rrl->qps_time, now); - if (secs <= 0) { - qps = rrl->qps; - } else { - qps = (1.0*rrl->qps_responses) / secs; - if (secs >= rrl->window) { - if (isc_log_wouldlog(dns_lctx, - DNS_RRL_LOG_DEBUG3)) - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, - DNS_RRL_LOG_DEBUG3, - "%d responses/%d seconds" - " = %d qps", - rrl->qps_responses, secs, - (int)qps); - rrl->qps = qps; - rrl->qps_responses = 0; - rrl->qps_time = now; - } else if (qps < rrl->qps) { - qps = rrl->qps; - } - } - scale = rrl->qps_scale / qps; - } - - /* - * Do maintenance once per second. - */ - if (rrl->num_logged > 0 && rrl->log_stops_time != now) - log_stops(rrl, now, 8, log_buf, log_buf_len); - - /* - * Notice TCP responses when scaling limits by qps. - * Do not try to rate limit TCP responses. - */ - if (is_tcp) { - if (scale < 1.0) { - e = get_entry(rrl, client_addr, - 0, dns_rdatatype_none, NULL, - DNS_RRL_RTYPE_TCP, now, true, - log_buf, log_buf_len); - if (e != NULL) { - e->responses = -(rrl->window+1); - set_age(rrl, e, now); - } - } - UNLOCK(&rrl->lock); - return (ISC_R_SUCCESS); - } - - /* - * Find the right kind of entry, creating it if necessary. - * If that is impossible, then nothing more can be done - */ - switch (resp_result) { - case ISC_R_SUCCESS: - rtype = DNS_RRL_RTYPE_QUERY; - break; - case DNS_R_DELEGATION: - rtype = DNS_RRL_RTYPE_REFERRAL; - break; - case DNS_R_NXRRSET: - rtype = DNS_RRL_RTYPE_NODATA; - break; - case DNS_R_NXDOMAIN: - rtype = DNS_RRL_RTYPE_NXDOMAIN; - break; - default: - rtype = DNS_RRL_RTYPE_ERROR; - break; - } - e = get_entry(rrl, client_addr, qclass, qtype, qname, rtype, - now, true, log_buf, log_buf_len); - if (e == NULL) { - UNLOCK(&rrl->lock); - return (DNS_RRL_RESULT_OK); - } - - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) { - /* - * Do not worry about speed or releasing the lock. - * This message appears before messages from debit_rrl_entry(). - */ - make_log_buf(rrl, e, "consider limiting ", NULL, false, - qname, false, DNS_RRL_RESULT_OK, resp_result, - log_buf, log_buf_len); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, - "%s", log_buf); - } - - rrl_result = debit_rrl_entry(rrl, e, qps, scale, client_addr, now, - log_buf, log_buf_len); - - if (rrl->all_per_second.r != 0) { - /* - * We must debit the all-per-second token bucket if we have - * an all-per-second limit for the IP address. - * The all-per-second limit determines the log message - * when both limits are hit. - * The response limiting must continue if the - * all-per-second limiting lapses. - */ - dns_rrl_entry_t *e_all; - dns_rrl_result_t rrl_all_result; - - e_all = get_entry(rrl, client_addr, - 0, dns_rdatatype_none, NULL, - DNS_RRL_RTYPE_ALL, now, true, - log_buf, log_buf_len); - if (e_all == NULL) { - UNLOCK(&rrl->lock); - return (DNS_RRL_RESULT_OK); - } - rrl_all_result = debit_rrl_entry(rrl, e_all, qps, scale, - client_addr, now, - log_buf, log_buf_len); - if (rrl_all_result != DNS_RRL_RESULT_OK) { - e = e_all; - rrl_result = rrl_all_result; - if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) { - make_log_buf(rrl, e, - "prefer all-per-second limiting ", - NULL, true, qname, false, - DNS_RRL_RESULT_OK, resp_result, - log_buf, log_buf_len); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, - DNS_RRL_LOG_DEBUG1, - "%s", log_buf); - } - } - } - - if (rrl_result == DNS_RRL_RESULT_OK) { - UNLOCK(&rrl->lock); - return (DNS_RRL_RESULT_OK); - } - - /* - * Log occasionally in the rate-limit category. - */ - if ((!e->logged || e->log_secs >= DNS_RRL_MAX_LOG_SECS) && - isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP)) { - make_log_buf(rrl, e, rrl->log_only ? "would " : NULL, - e->logged ? "continue limiting " : "limit ", - true, qname, true, - DNS_RRL_RESULT_OK, resp_result, - log_buf, log_buf_len); - if (!e->logged) { - e->logged = true; - if (++rrl->num_logged <= 1) - rrl->last_logged = e; - } - e->log_secs = 0; - - /* - * Avoid holding the lock. - */ - if (!wouldlog) { - UNLOCK(&rrl->lock); - e = NULL; - } - isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, - DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, - "%s", log_buf); - } - - /* - * Make a log message for the caller. - */ - if (wouldlog) - make_log_buf(rrl, e, - rrl->log_only ? "would rate limit " : "rate limit ", - NULL, false, qname, false, - rrl_result, resp_result, log_buf, log_buf_len); - - if (e != NULL) { - /* - * Do not save the qname unless we might need it for - * the ending log message. - */ - if (!e->logged) - free_qname(rrl, e); - UNLOCK(&rrl->lock); - } - - return (rrl_result); -} - -void -dns_rrl_view_destroy(dns_view_t *view) { - dns_rrl_t *rrl; - dns_rrl_block_t *b; - dns_rrl_hash_t *h; - char log_buf[DNS_RRL_LOG_BUF_LEN]; - int i; - - rrl = view->rrl; - if (rrl == NULL) - return; - view->rrl = NULL; - - /* - * Assume the caller takes care of locking the view and anything else. - */ - - if (rrl->num_logged > 0) - log_stops(rrl, 0, INT32_MAX, log_buf, sizeof(log_buf)); - - for (i = 0; i < DNS_RRL_QNAMES; ++i) { - if (rrl->qnames[i] == NULL) - break; - isc_mem_put(rrl->mctx, rrl->qnames[i], sizeof(*rrl->qnames[i])); - } - - if (rrl->exempt != NULL) - dns_acl_detach(&rrl->exempt); - - DESTROYLOCK(&rrl->lock); - - while (!ISC_LIST_EMPTY(rrl->blocks)) { - b = ISC_LIST_HEAD(rrl->blocks); - ISC_LIST_UNLINK(rrl->blocks, b, link); - isc_mem_put(rrl->mctx, b, b->size); - } - - h = rrl->hash; - if (h != NULL) - isc_mem_put(rrl->mctx, h, - sizeof(*h) + (h->length - 1) * sizeof(h->bins[0])); - - h = rrl->old_hash; - if (h != NULL) - isc_mem_put(rrl->mctx, h, - sizeof(*h) + (h->length - 1) * sizeof(h->bins[0])); - - isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl)); -} - -isc_result_t -dns_rrl_init(dns_rrl_t **rrlp, dns_view_t *view, int min_entries) { - dns_rrl_t *rrl; - isc_result_t result; - - *rrlp = NULL; - - rrl = isc_mem_get(view->mctx, sizeof(*rrl)); - if (rrl == NULL) - return (ISC_R_NOMEMORY); - memset(rrl, 0, sizeof(*rrl)); - isc_mem_attach(view->mctx, &rrl->mctx); - result = isc_mutex_init(&rrl->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl)); - return (result); - } - isc_stdtime_get(&rrl->ts_bases[0]); - - view->rrl = rrl; - - result = expand_entries(rrl, min_entries); - if (result != ISC_R_SUCCESS) { - dns_rrl_view_destroy(view); - return (result); - } - result = expand_rrl_hash(rrl, 0); - if (result != ISC_R_SUCCESS) { - dns_rrl_view_destroy(view); - return (result); - } - - *rrlp = rrl; - return (ISC_R_SUCCESS); -} diff --git a/lib/dns-pkcs11/sdb.c b/lib/dns-pkcs11/sdb.c deleted file mode 100644 index 09cf932..0000000 --- a/lib/dns-pkcs11/sdb.c +++ /dev/null @@ -1,1673 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rdatalist_p.h" - -struct dns_sdbimplementation { - const dns_sdbmethods_t *methods; - void *driverdata; - unsigned int flags; - isc_mem_t *mctx; - isc_mutex_t driverlock; - dns_dbimplementation_t *dbimp; -}; - -struct dns_sdb { - /* Unlocked */ - dns_db_t common; - char *zone; - dns_sdbimplementation_t *implementation; - void *dbdata; - isc_mutex_t lock; - /* Locked */ - unsigned int references; -}; - -struct dns_sdblookup { - /* Unlocked */ - unsigned int magic; - dns_sdb_t *sdb; - ISC_LIST(dns_rdatalist_t) lists; - ISC_LIST(isc_buffer_t) buffers; - dns_name_t *name; - ISC_LINK(dns_sdblookup_t) link; - isc_mutex_t lock; - dns_rdatacallbacks_t callbacks; - /* Locked */ - unsigned int references; -}; - -typedef struct dns_sdblookup dns_sdbnode_t; - -struct dns_sdballnodes { - dns_dbiterator_t common; - ISC_LIST(dns_sdbnode_t) nodelist; - dns_sdbnode_t *current; - dns_sdbnode_t *origin; -}; - -typedef dns_sdballnodes_t sdb_dbiterator_t; - -typedef struct sdb_rdatasetiter { - dns_rdatasetiter_t common; - dns_rdatalist_t *current; -} sdb_rdatasetiter_t; - -#define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-') - -/*% - * Note that "impmagic" is not the first four bytes of the struct, so - * ISC_MAGIC_VALID cannot be used. - */ -#define VALID_SDB(sdb) ((sdb) != NULL && \ - (sdb)->common.impmagic == SDB_MAGIC) - -#define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L') -#define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC) -#define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn) - -/* These values are taken from RFC1537 */ -#define SDB_DEFAULT_REFRESH 28800U /* 8 hours */ -#define SDB_DEFAULT_RETRY 7200U /* 2 hours */ -#define SDB_DEFAULT_EXPIRE 604800U /* 7 days */ -#define SDB_DEFAULT_MINIMUM 86400U /* 1 day */ - -/* This is a reasonable value */ -#define SDB_DEFAULT_TTL (60 * 60 * 24) - -#ifdef __COVERITY__ -#define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock) -#define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock) -#else -#define MAYBE_LOCK(sdb) \ - do { \ - unsigned int flags = sdb->implementation->flags; \ - if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ - LOCK(&sdb->implementation->driverlock); \ - } while (0) - -#define MAYBE_UNLOCK(sdb) \ - do { \ - unsigned int flags = sdb->implementation->flags; \ - if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ - UNLOCK(&sdb->implementation->driverlock); \ - } while (0) -#endif - -static int dummy; - -static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, - dns_dbtype_t type, dns_rdataclass_t rdclass, - unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp); - -static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset); - -static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep); - -static void destroynode(dns_sdbnode_t *node); - -static void detachnode(dns_db_t *db, dns_dbnode_t **targetp); - - -static void list_tordataset(dns_rdatalist_t *rdatalist, - dns_db_t *db, dns_dbnode_t *node, - dns_rdataset_t *rdataset); - -static void dbiterator_destroy(dns_dbiterator_t **iteratorp); -static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, - dns_name_t *name); -static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, - dns_dbnode_t **nodep, - dns_name_t *name); -static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, - dns_name_t *name); - -static dns_dbiteratormethods_t dbiterator_methods = { - dbiterator_destroy, - dbiterator_first, - dbiterator_last, - dbiterator_seek, - dbiterator_prev, - dbiterator_next, - dbiterator_current, - dbiterator_pause, - dbiterator_origin -}; - -static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); -static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); -static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); -static void rdatasetiter_current(dns_rdatasetiter_t *iterator, - dns_rdataset_t *rdataset); - -static dns_rdatasetitermethods_t rdatasetiter_methods = { - rdatasetiter_destroy, - rdatasetiter_first, - rdatasetiter_next, - rdatasetiter_current -}; - -/* - * Functions used by implementors of simple databases - */ -isc_result_t -dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, - void *driverdata, unsigned int flags, isc_mem_t *mctx, - dns_sdbimplementation_t **sdbimp) -{ - dns_sdbimplementation_t *imp; - isc_result_t result; - - REQUIRE(drivername != NULL); - REQUIRE(methods != NULL); - REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL); - REQUIRE(mctx != NULL); - REQUIRE(sdbimp != NULL && *sdbimp == NULL); - REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_THREADSAFE| - DNS_SDBFLAG_DNS64)) == 0); - - imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); - if (imp == NULL) - return (ISC_R_NOMEMORY); - imp->methods = methods; - imp->driverdata = driverdata; - imp->flags = flags; - imp->mctx = NULL; - isc_mem_attach(mctx, &imp->mctx); - result = isc_mutex_init(&imp->driverlock); - if (result != ISC_R_SUCCESS) - goto cleanup_mctx; - - imp->dbimp = NULL; - result = dns_db_register(drivername, dns_sdb_create, imp, mctx, - &imp->dbimp); - if (result != ISC_R_SUCCESS) - goto cleanup_mutex; - *sdbimp = imp; - - return (ISC_R_SUCCESS); - - cleanup_mutex: - DESTROYLOCK(&imp->driverlock); - cleanup_mctx: - isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); - return (result); -} - -void -dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { - dns_sdbimplementation_t *imp; - isc_mem_t *mctx; - - REQUIRE(sdbimp != NULL && *sdbimp != NULL); - - imp = *sdbimp; - dns_db_unregister(&imp->dbimp); - DESTROYLOCK(&imp->driverlock); - - mctx = imp->mctx; - isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); - isc_mem_detach(&mctx); - - *sdbimp = NULL; -} - -static inline unsigned int -initial_size(unsigned int len) { - unsigned int size; - - for (size = 1024; size < (64 * 1024); size *= 2) - if (len < size) - return (size); - return (65535); -} - -isc_result_t -dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, - dns_ttl_t ttl, const unsigned char *rdatap, - unsigned int rdlen) -{ - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_buffer_t *rdatabuf = NULL; - isc_result_t result; - isc_mem_t *mctx; - isc_region_t region; - - mctx = lookup->sdb->common.mctx; - - rdatalist = ISC_LIST_HEAD(lookup->lists); - while (rdatalist != NULL) { - if (rdatalist->type == typeval) - break; - rdatalist = ISC_LIST_NEXT(rdatalist, link); - } - - if (rdatalist == NULL) { - rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); - if (rdatalist == NULL) - return (ISC_R_NOMEMORY); - dns_rdatalist_init(rdatalist); - rdatalist->rdclass = lookup->sdb->common.rdclass; - rdatalist->type = typeval; - rdatalist->ttl = ttl; - ISC_LIST_APPEND(lookup->lists, rdatalist, link); - } else - if (rdatalist->ttl != ttl) - return (DNS_R_BADTTL); - - rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - - result = isc_buffer_allocate(mctx, &rdatabuf, rdlen); - if (result != ISC_R_SUCCESS) - goto failure; - DE_CONST(rdatap, region.base); - region.length = rdlen; - isc_buffer_copyregion(rdatabuf, ®ion); - isc_buffer_usedregion(rdatabuf, ®ion); - dns_rdata_init(rdata); - dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type, - ®ion); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); - rdata = NULL; - - failure: - if (rdata != NULL) - isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); - return (result); -} - -isc_result_t -dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, - const char *data) -{ - unsigned int datalen; - dns_rdatatype_t typeval; - isc_textregion_t r; - isc_lex_t *lex = NULL; - isc_result_t result; - unsigned char *p = NULL; - unsigned int size = 0; /* Init to suppress compiler warning */ - isc_mem_t *mctx; - dns_sdbimplementation_t *imp; - dns_name_t *origin; - isc_buffer_t b; - isc_buffer_t rb; - - REQUIRE(VALID_SDBLOOKUP(lookup)); - REQUIRE(type != NULL); - REQUIRE(data != NULL); - - mctx = lookup->sdb->common.mctx; - - DE_CONST(type, r.base); - r.length = strlen(type); - result = dns_rdatatype_fromtext(&typeval, &r); - if (result != ISC_R_SUCCESS) - return (result); - - imp = lookup->sdb->implementation; - if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) - origin = &lookup->sdb->common.origin; - else - origin = dns_rootname; - - result = isc_lex_create(mctx, 64, &lex); - if (result != ISC_R_SUCCESS) - goto failure; - - datalen = strlen(data); - size = initial_size(datalen); - do { - isc_buffer_constinit(&b, data, datalen); - isc_buffer_add(&b, datalen); - result = isc_lex_openbuffer(lex, &b); - if (result != ISC_R_SUCCESS) - goto failure; - - if (size >= 65535) - size = 65535; - p = isc_mem_get(mctx, size); - if (p == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&rb, p, size); - result = dns_rdata_fromtext(NULL, - lookup->sdb->common.rdclass, - typeval, lex, - origin, 0, - mctx, &rb, - &lookup->callbacks); - if (result != ISC_R_NOSPACE) - break; - - /* - * Is the RR too big? - */ - if (size >= 65535) - break; - isc_mem_put(mctx, p, size); - p = NULL; - size *= 2; - } while (result == ISC_R_NOSPACE); - - if (result != ISC_R_SUCCESS) - goto failure; - - result = dns_sdb_putrdata(lookup, typeval, ttl, - isc_buffer_base(&rb), - isc_buffer_usedlength(&rb)); - failure: - if (p != NULL) - isc_mem_put(mctx, p, size); - if (lex != NULL) - isc_lex_destroy(&lex); - - return (result); -} - -static isc_result_t -getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { - dns_name_t *newname, *origin; - dns_fixedname_t fnewname; - dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db; - dns_sdbimplementation_t *imp = sdb->implementation; - dns_sdbnode_t *sdbnode; - isc_mem_t *mctx = sdb->common.mctx; - isc_buffer_t b; - isc_result_t result; - - newname = dns_fixedname_initname(&fnewname); - - if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) - origin = &sdb->common.origin; - else - origin = dns_rootname; - isc_buffer_constinit(&b, name, strlen(name)); - isc_buffer_add(&b, strlen(name)); - - result = dns_name_fromtext(newname, &b, origin, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - if (allnodes->common.relative_names) { - /* All names are relative to the root */ - unsigned int nlabels = dns_name_countlabels(newname); - dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); - } - - sdbnode = ISC_LIST_HEAD(allnodes->nodelist); - if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) { - sdbnode = NULL; - result = createnode(sdb, &sdbnode); - if (result != ISC_R_SUCCESS) - return (result); - sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t)); - if (sdbnode->name == NULL) { - destroynode(sdbnode); - return (ISC_R_NOMEMORY); - } - dns_name_init(sdbnode->name, NULL); - result = dns_name_dup(newname, mctx, sdbnode->name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t)); - destroynode(sdbnode); - return (result); - } - ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link); - if (allnodes->origin == NULL && - dns_name_equal(newname, &sdb->common.origin)) - allnodes->origin = sdbnode; - } - *nodep = sdbnode; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, - const char *type, dns_ttl_t ttl, const char *data) -{ - isc_result_t result; - dns_sdbnode_t *sdbnode = NULL; - result = getnode(allnodes, name, &sdbnode); - if (result != ISC_R_SUCCESS) - return (result); - return (dns_sdb_putrr(sdbnode, type, ttl, data)); -} - -isc_result_t -dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, - dns_rdatatype_t type, dns_ttl_t ttl, - const void *rdata, unsigned int rdlen) -{ - isc_result_t result; - dns_sdbnode_t *sdbnode = NULL; - result = getnode(allnodes, name, &sdbnode); - if (result != ISC_R_SUCCESS) - return (result); - return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen)); -} - -isc_result_t -dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, - uint32_t serial) -{ - char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; - int n; - - REQUIRE(mname != NULL); - REQUIRE(rname != NULL); - - n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u", - mname, rname, serial, - SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY, - SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM); - if (n >= (int)sizeof(str) || n < 0) - return (ISC_R_NOSPACE); - return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str)); -} - -/* - * DB routines - */ - -static void -attach(dns_db_t *source, dns_db_t **targetp) { - dns_sdb_t *sdb = (dns_sdb_t *) source; - - REQUIRE(VALID_SDB(sdb)); - - LOCK(&sdb->lock); - REQUIRE(sdb->references > 0); - sdb->references++; - UNLOCK(&sdb->lock); - - *targetp = source; -} - -static void -destroy(dns_sdb_t *sdb) { - isc_mem_t *mctx; - dns_sdbimplementation_t *imp = sdb->implementation; - - mctx = sdb->common.mctx; - - if (imp->methods->destroy != NULL) { - MAYBE_LOCK(sdb); - imp->methods->destroy(sdb->zone, imp->driverdata, - &sdb->dbdata); - MAYBE_UNLOCK(sdb); - } - - isc_mem_free(mctx, sdb->zone); - DESTROYLOCK(&sdb->lock); - - sdb->common.magic = 0; - sdb->common.impmagic = 0; - - dns_name_free(&sdb->common.origin, mctx); - - isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); - isc_mem_detach(&mctx); -} - -static void -detach(dns_db_t **dbp) { - dns_sdb_t *sdb = (dns_sdb_t *)(*dbp); - bool need_destroy = false; - - REQUIRE(VALID_SDB(sdb)); - LOCK(&sdb->lock); - REQUIRE(sdb->references > 0); - sdb->references--; - if (sdb->references == 0) - need_destroy = true; - UNLOCK(&sdb->lock); - - if (need_destroy) - destroy(sdb); - - *dbp = NULL; -} - -static isc_result_t -beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - UNUSED(db); - UNUSED(callbacks); - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - UNUSED(db); - UNUSED(callbacks); - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat) { - UNUSED(db); - UNUSED(version); - UNUSED(filename); - UNUSED(masterformat); - return (ISC_R_NOTIMPLEMENTED); -} - -static void -currentversion(dns_db_t *db, dns_dbversion_t **versionp) { - REQUIRE(versionp != NULL && *versionp == NULL); - - UNUSED(db); - - *versionp = (void *) &dummy; - return; -} - -static isc_result_t -newversion(dns_db_t *db, dns_dbversion_t **versionp) { - UNUSED(db); - UNUSED(versionp); - - return (ISC_R_NOTIMPLEMENTED); -} - -static void -attachversion(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp) -{ - REQUIRE(source != NULL && source == (void *) &dummy); - REQUIRE(targetp != NULL && *targetp == NULL); - - UNUSED(db); - *targetp = source; - return; -} - -static void -closeversion(dns_db_t *db, dns_dbversion_t **versionp, bool commit) { - REQUIRE(versionp != NULL && *versionp == (void *) &dummy); - REQUIRE(commit == false); - - UNUSED(db); - UNUSED(commit); - - *versionp = NULL; -} - -static isc_result_t -createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) { - dns_sdbnode_t *node; - isc_result_t result; - - node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t)); - if (node == NULL) - return (ISC_R_NOMEMORY); - - node->sdb = NULL; - attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb); - ISC_LIST_INIT(node->lists); - ISC_LIST_INIT(node->buffers); - ISC_LINK_INIT(node, link); - node->name = NULL; - result = isc_mutex_init(&node->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t)); - return (result); - } - dns_rdatacallbacks_init(&node->callbacks); - node->references = 1; - node->magic = SDBLOOKUP_MAGIC; - - *nodep = node; - return (ISC_R_SUCCESS); -} - -static void -destroynode(dns_sdbnode_t *node) { - dns_rdatalist_t *list; - dns_rdata_t *rdata; - isc_buffer_t *b; - dns_sdb_t *sdb; - isc_mem_t *mctx; - - sdb = node->sdb; - mctx = sdb->common.mctx; - - while (!ISC_LIST_EMPTY(node->lists)) { - list = ISC_LIST_HEAD(node->lists); - while (!ISC_LIST_EMPTY(list->rdata)) { - rdata = ISC_LIST_HEAD(list->rdata); - ISC_LIST_UNLINK(list->rdata, rdata, link); - isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); - } - ISC_LIST_UNLINK(node->lists, list, link); - isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); - } - - while (!ISC_LIST_EMPTY(node->buffers)) { - b = ISC_LIST_HEAD(node->buffers); - ISC_LIST_UNLINK(node->buffers, b, link); - isc_buffer_free(&b); - } - - if (node->name != NULL) { - dns_name_free(node->name, mctx); - isc_mem_put(mctx, node->name, sizeof(dns_name_t)); - } - DESTROYLOCK(&node->lock); - node->magic = 0; - isc_mem_put(mctx, node, sizeof(dns_sdbnode_t)); - detach((dns_db_t **) (void *)&sdb); -} - -static isc_result_t -getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { - dns_sdb_t *sdb = (dns_sdb_t *)db; - dns_sdbnode_t *node = NULL; - isc_result_t result; - isc_buffer_t b; - char namestr[DNS_NAME_MAXTEXT + 1]; - dns_sdbimplementation_t *imp; - dns_name_t relname; - dns_name_t *name; - - REQUIRE(VALID_SDB(sdb)); - REQUIRE(nodep != NULL && *nodep == NULL); - - imp = sdb->implementation; - name = &sdb->common.origin; - - if (imp->methods->lookup2 != NULL) { - if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { - dns_name_init(&relname, NULL); - name = &relname; - } - } else { - isc_buffer_init(&b, namestr, sizeof(namestr)); - if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { - - dns_name_init(&relname, NULL); - result = dns_name_totext(&relname, true, &b); - if (result != ISC_R_SUCCESS) { - return (result); - } - } else { - result = dns_name_totext(name, true, &b); - if (result != ISC_R_SUCCESS) { - return (result); - } - } - isc_buffer_putuint8(&b, 0); - } - - result = createnode(sdb, &node); - if (result != ISC_R_SUCCESS) { - return (result); - } - - MAYBE_LOCK(sdb); - if (imp->methods->lookup2 != NULL) { - result = imp->methods->lookup2(&sdb->common.origin, name, - sdb->dbdata, node, NULL, NULL); - } else { - result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, - node, NULL, NULL); - } - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS && - !(result == ISC_R_NOTFOUND && - imp->methods->authority != NULL)) - { - destroynode(node); - return (result); - } - - if (imp->methods->authority != NULL) { - MAYBE_LOCK(sdb); - result = imp->methods->authority(sdb->zone, sdb->dbdata, node); - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS) { - destroynode(node); - return (result); - } - } - - *nodep = node; - return (ISC_R_SUCCESS); -} - -static isc_result_t -findnodeext(dns_db_t *db, dns_name_t *name, bool create, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_dbnode_t **nodep) -{ - dns_sdb_t *sdb = (dns_sdb_t *)db; - dns_sdbnode_t *node = NULL; - isc_result_t result; - isc_buffer_t b; - char namestr[DNS_NAME_MAXTEXT + 1]; - bool isorigin; - dns_sdbimplementation_t *imp; - dns_name_t relname; - unsigned int labels; - - REQUIRE(VALID_SDB(sdb)); - REQUIRE(create == false); - REQUIRE(nodep != NULL && *nodep == NULL); - - UNUSED(name); - UNUSED(create); - - imp = sdb->implementation; - - isorigin = dns_name_equal(name, &sdb->common.origin); - - if (imp->methods->lookup2 != NULL) { - if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { - labels = dns_name_countlabels(name) - - dns_name_countlabels(&db->origin); - dns_name_init(&relname, NULL); - dns_name_getlabelsequence(name, 0, labels, &relname); - name = &relname; - } - } else { - isc_buffer_init(&b, namestr, sizeof(namestr)); - if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { - - labels = dns_name_countlabels(name) - - dns_name_countlabels(&db->origin); - dns_name_init(&relname, NULL); - dns_name_getlabelsequence(name, 0, labels, &relname); - result = dns_name_totext(&relname, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - } else { - result = dns_name_totext(name, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - } - isc_buffer_putuint8(&b, 0); - } - - result = createnode(sdb, &node); - if (result != ISC_R_SUCCESS) - return (result); - - MAYBE_LOCK(sdb); - if (imp->methods->lookup2 != NULL) - result = imp->methods->lookup2(&sdb->common.origin, name, - sdb->dbdata, node, methods, - clientinfo); - else - result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, - node, methods, clientinfo); - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS && - !(result == ISC_R_NOTFOUND && - isorigin && imp->methods->authority != NULL)) - { - destroynode(node); - return (result); - } - - if (isorigin && imp->methods->authority != NULL) { - MAYBE_LOCK(sdb); - result = imp->methods->authority(sdb->zone, sdb->dbdata, node); - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS) { - destroynode(node); - return (result); - } - } - - *nodep = node; - return (ISC_R_SUCCESS); -} - -static isc_result_t -findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_sdb_t *sdb = (dns_sdb_t *)db; - dns_dbnode_t *node = NULL; - dns_fixedname_t fname; - dns_rdataset_t xrdataset; - dns_name_t *xname; - unsigned int nlabels, olabels; - isc_result_t result; - unsigned int i; - unsigned int flags; - - REQUIRE(VALID_SDB(sdb)); - REQUIRE(nodep == NULL || *nodep == NULL); - REQUIRE(version == NULL || version == (void *) &dummy); - - UNUSED(options); - - if (!dns_name_issubdomain(name, &db->origin)) - return (DNS_R_NXDOMAIN); - - olabels = dns_name_countlabels(&db->origin); - nlabels = dns_name_countlabels(name); - - xname = dns_fixedname_initname(&fname); - - if (rdataset == NULL) { - dns_rdataset_init(&xrdataset); - rdataset = &xrdataset; - } - - result = DNS_R_NXDOMAIN; - flags = sdb->implementation->flags; - i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels; - for (; i <= nlabels; i++) { - /* - * Look up the next label. - */ - dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = findnodeext(db, xname, false, methods, - clientinfo, &node); - if (result == ISC_R_NOTFOUND) { - /* - * No data at zone apex? - */ - if (i == olabels) - return (DNS_R_BADDB); - result = DNS_R_NXDOMAIN; - continue; - } - if (result != ISC_R_SUCCESS) - return (result); - - /* - * DNS64 zone's don't have DNAME or NS records. - */ - if ((flags & DNS_SDBFLAG_DNS64) != 0) - goto skip; - - /* - * DNS64 zone's don't have DNAME or NS records. - */ - if ((flags & DNS_SDBFLAG_DNS64) != 0) - goto skip; - - /* - * Look for a DNAME at the current label, unless this is - * the qname. - */ - if (i < nlabels) { - result = findrdataset(db, node, version, - dns_rdatatype_dname, - 0, now, rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - result = DNS_R_DNAME; - break; - } - } - - /* - * Look for an NS at the current label, unless this is the - * origin or glue is ok. - */ - if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { - result = findrdataset(db, node, version, - dns_rdatatype_ns, - 0, now, rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (i == nlabels && type == dns_rdatatype_any) - { - result = DNS_R_ZONECUT; - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated - (sigrdataset)) { - dns_rdataset_disassociate - (sigrdataset); - } - } else - result = DNS_R_DELEGATION; - break; - } - } - - /* - * If the current name is not the qname, add another label - * and try again. - */ - if (i < nlabels) { - destroynode(node); - node = NULL; - continue; - } - - skip: - /* - * If we're looking for ANY, we're done. - */ - if (type == dns_rdatatype_any) { - result = ISC_R_SUCCESS; - break; - } - - /* - * Look for the qtype. - */ - result = findrdataset(db, node, version, type, - 0, now, rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) - break; - - /* - * Look for a CNAME - */ - if (type != dns_rdatatype_cname) { - result = findrdataset(db, node, version, - dns_rdatatype_cname, - 0, now, rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - result = DNS_R_CNAME; - break; - } - } - - result = DNS_R_NXRRSET; - break; - } - - if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (foundname != NULL) { - isc_result_t xresult; - - xresult = dns_name_copy(xname, foundname, NULL); - if (xresult != ISC_R_SUCCESS) { - if (node != NULL) - destroynode(node); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - return (DNS_R_BADDB); - } - } - - if (nodep != NULL) - *nodep = node; - else if (node != NULL) - detachnode(db, &node); - - return (result); -} - -static isc_result_t -findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - UNUSED(db); - UNUSED(name); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - return (ISC_R_NOTIMPLEMENTED); -} - -static void -attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { - dns_sdb_t *sdb = (dns_sdb_t *)db; - dns_sdbnode_t *node = (dns_sdbnode_t *)source; - - REQUIRE(VALID_SDB(sdb)); - - UNUSED(sdb); - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references++; - INSIST(node->references != 0); /* Catch overflow. */ - UNLOCK(&node->lock); - - *targetp = source; -} - -static void -detachnode(dns_db_t *db, dns_dbnode_t **targetp) { - dns_sdb_t *sdb = (dns_sdb_t *)db; - dns_sdbnode_t *node; - bool need_destroy = false; - - REQUIRE(VALID_SDB(sdb)); - REQUIRE(targetp != NULL && *targetp != NULL); - - UNUSED(sdb); - - node = (dns_sdbnode_t *)(*targetp); - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - need_destroy = true; - UNLOCK(&node->lock); - - if (need_destroy) - destroynode(node); - - *targetp = NULL; -} - -static isc_result_t -expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { - UNUSED(db); - UNUSED(node); - UNUSED(now); - INSIST(0); - ISC_UNREACHABLE(); -} - -static void -printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { - UNUSED(db); - UNUSED(node); - UNUSED(out); - return; -} - -static isc_result_t -createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) -{ - dns_sdb_t *sdb = (dns_sdb_t *)db; - sdb_dbiterator_t *sdbiter; - dns_sdbimplementation_t *imp; - isc_result_t result; - - REQUIRE(VALID_SDB(sdb)); - - imp = sdb->implementation; - - if (imp->methods->allnodes == NULL) - return (ISC_R_NOTIMPLEMENTED); - - if ((options & DNS_DB_NSEC3ONLY) != 0 || - (options & DNS_DB_NONSEC3) != 0) - return (ISC_R_NOTIMPLEMENTED); - - sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t)); - if (sdbiter == NULL) - return (ISC_R_NOMEMORY); - - sdbiter->common.methods = &dbiterator_methods; - sdbiter->common.db = NULL; - dns_db_attach(db, &sdbiter->common.db); - sdbiter->common.relative_names = ((options & DNS_DB_RELATIVENAMES) != 0); - sdbiter->common.magic = DNS_DBITERATOR_MAGIC; - ISC_LIST_INIT(sdbiter->nodelist); - sdbiter->current = NULL; - sdbiter->origin = NULL; - - MAYBE_LOCK(sdb); - result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS) { - dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter); - return (result); - } - - if (sdbiter->origin != NULL) { - ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link); - ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link); - } - - *iteratorp = (dns_dbiterator_t *)sdbiter; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - dns_rdatalist_t *list; - dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node; - - REQUIRE(VALID_SDBNODE(sdbnode)); - - UNUSED(db); - UNUSED(version); - UNUSED(covers); - UNUSED(now); - UNUSED(sigrdataset); - - if (type == dns_rdatatype_rrsig) - return (ISC_R_NOTIMPLEMENTED); - - list = ISC_LIST_HEAD(sdbnode->lists); - while (list != NULL) { - if (list->type == type) - break; - list = ISC_LIST_NEXT(list, link); - } - if (list == NULL) - return (ISC_R_NOTFOUND); - - list_tordataset(list, db, node, rdataset); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) -{ - sdb_rdatasetiter_t *iterator; - - REQUIRE(version == NULL || version == &dummy); - - UNUSED(version); - UNUSED(now); - - iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t)); - if (iterator == NULL) - return (ISC_R_NOMEMORY); - - iterator->common.magic = DNS_RDATASETITER_MAGIC; - iterator->common.methods = &rdatasetiter_methods; - iterator->common.db = db; - iterator->common.node = NULL; - attachnode(db, node, &iterator->common.node); - iterator->common.version = version; - iterator->common.now = now; - - *iteratorp = (dns_rdatasetiter_t *)iterator; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset) -{ - UNUSED(db); - UNUSED(node); - UNUSED(version); - UNUSED(now); - UNUSED(rdataset); - UNUSED(options); - UNUSED(addedrdataset); - - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *newrdataset) -{ - UNUSED(db); - UNUSED(node); - UNUSED(version); - UNUSED(rdataset); - UNUSED(options); - UNUSED(newrdataset); - - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers) -{ - UNUSED(db); - UNUSED(node); - UNUSED(version); - UNUSED(type); - UNUSED(covers); - - return (ISC_R_NOTIMPLEMENTED); -} - -static bool -issecure(dns_db_t *db) { - UNUSED(db); - - return (false); -} - -static unsigned int -nodecount(dns_db_t *db) { - UNUSED(db); - - return (0); -} - -static bool -ispersistent(dns_db_t *db) { - UNUSED(db); - return (true); -} - -static void -overmem(dns_db_t *db, bool over) { - UNUSED(db); - UNUSED(over); -} - -static void -settask(dns_db_t *db, isc_task_t *task) { - UNUSED(db); - UNUSED(task); -} - - -static dns_dbmethods_t sdb_methods = { - attach, - detach, - beginload, - endload, - NULL, - dump, - currentversion, - newversion, - attachversion, - closeversion, - NULL, - NULL, - findzonecut, - attachnode, - detachnode, - expirenode, - printnode, - createiterator, - findrdataset, - allrdatasets, - addrdataset, - subtractrdataset, - deleterdataset, - issecure, - nodecount, - ispersistent, - overmem, - settask, - getoriginnode, /* getoriginnode */ - NULL, /* transfernode */ - NULL, /* getnsec3parameters */ - NULL, /* findnsec3node */ - NULL, /* setsigningtime */ - NULL, /* getsigningtime */ - NULL, /* resigned */ - NULL, /* isdnssec */ - NULL, /* getrrsetstats */ - NULL, /* rpz_attach */ - NULL, /* rpz_ready */ - findnodeext, - findext, - NULL, /* setcachestats */ - NULL, /* hashsize */ - NULL, /* nodefullname */ - NULL, /* getsize */ - NULL, /* setservestalettl */ - NULL /* getservestalettl */ -}; - -static isc_result_t -dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) -{ - dns_sdb_t *sdb; - isc_result_t result; - char zonestr[DNS_NAME_MAXTEXT + 1]; - isc_buffer_t b; - dns_sdbimplementation_t *imp; - - REQUIRE(driverarg != NULL); - - imp = driverarg; - - if (type != dns_dbtype_zone) - return (ISC_R_NOTIMPLEMENTED); - - sdb = isc_mem_get(mctx, sizeof(dns_sdb_t)); - if (sdb == NULL) - return (ISC_R_NOMEMORY); - memset(sdb, 0, sizeof(dns_sdb_t)); - - dns_name_init(&sdb->common.origin, NULL); - sdb->common.attributes = 0; - sdb->common.methods = &sdb_methods; - sdb->common.rdclass = rdclass; - sdb->common.mctx = NULL; - sdb->implementation = imp; - - isc_mem_attach(mctx, &sdb->common.mctx); - - result = isc_mutex_init(&sdb->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mctx; - - result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - - isc_buffer_init(&b, zonestr, sizeof(zonestr)); - result = dns_name_totext(origin, true, &b); - if (result != ISC_R_SUCCESS) - goto cleanup_origin; - isc_buffer_putuint8(&b, 0); - - sdb->zone = isc_mem_strdup(mctx, zonestr); - if (sdb->zone == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_origin; - } - - sdb->dbdata = NULL; - if (imp->methods->create != NULL) { - MAYBE_LOCK(sdb); - result = imp->methods->create(sdb->zone, argc, argv, - imp->driverdata, &sdb->dbdata); - MAYBE_UNLOCK(sdb); - if (result != ISC_R_SUCCESS) - goto cleanup_zonestr; - } - - sdb->references = 1; - - sdb->common.magic = DNS_DB_MAGIC; - sdb->common.impmagic = SDB_MAGIC; - - *dbp = (dns_db_t *)sdb; - - return (ISC_R_SUCCESS); - - cleanup_zonestr: - isc_mem_free(mctx, sdb->zone); - cleanup_origin: - dns_name_free(&sdb->common.origin, mctx); - cleanup_lock: - (void)isc_mutex_destroy(&sdb->lock); - cleanup_mctx: - isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); - isc_mem_detach(&mctx); - - return (result); -} - - -/* - * Rdataset Methods - */ - -static void -disassociate(dns_rdataset_t *rdataset) { - dns_dbnode_t *node = rdataset->private5; - dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; - dns_db_t *db = (dns_db_t *) sdbnode->sdb; - - detachnode(db, &node); - isc__rdatalist_disassociate(rdataset); -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - dns_dbnode_t *node = source->private5; - dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; - dns_db_t *db = (dns_db_t *) sdbnode->sdb; - dns_dbnode_t *tempdb = NULL; - - isc__rdatalist_clone(source, target); - attachnode(db, node, &tempdb); - source->private5 = tempdb; -} - -static dns_rdatasetmethods_t sdb_rdataset_methods = { - disassociate, - isc__rdatalist_first, - isc__rdatalist_next, - isc__rdatalist_current, - rdataset_clone, - isc__rdatalist_count, - isc__rdatalist_addnoqname, - isc__rdatalist_getnoqname, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -static void -list_tordataset(dns_rdatalist_t *rdatalist, - dns_db_t *db, dns_dbnode_t *node, - dns_rdataset_t *rdataset) -{ - /* - * The sdb rdataset is an rdatalist with some additions. - * - private1 & private2 are used by the rdatalist. - * - private3 & private 4 are unused. - * - private5 is the node. - */ - - /* This should never fail. */ - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == - ISC_R_SUCCESS); - - rdataset->methods = &sdb_rdataset_methods; - dns_db_attachnode(db, node, &rdataset->private5); -} - -/* - * Database Iterator Methods - */ -static void -dbiterator_destroy(dns_dbiterator_t **iteratorp) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp); - dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db; - - while (!ISC_LIST_EMPTY(sdbiter->nodelist)) { - dns_sdbnode_t *node; - node = ISC_LIST_HEAD(sdbiter->nodelist); - ISC_LIST_UNLINK(sdbiter->nodelist, node, link); - destroynode(node); - } - - dns_db_detach(&sdbiter->common.db); - isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t)); - - *iteratorp = NULL; -} - -static isc_result_t -dbiterator_first(dns_dbiterator_t *iterator) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); - if (sdbiter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_last(dns_dbiterator_t *iterator) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist); - if (sdbiter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); - while (sdbiter->current != NULL) { - if (dns_name_equal(sdbiter->current->name, name)) - return (ISC_R_SUCCESS); - sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); - } - return (ISC_R_NOTFOUND); -} - -static isc_result_t -dbiterator_prev(dns_dbiterator_t *iterator) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - sdbiter->current = ISC_LIST_PREV(sdbiter->current, link); - if (sdbiter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_next(dns_dbiterator_t *iterator) { - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); - if (sdbiter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, - dns_name_t *name) -{ - sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; - - attachnode(iterator->db, sdbiter->current, nodep); - if (name != NULL) - return (dns_name_copy(sdbiter->current->name, name, NULL)); - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_pause(dns_dbiterator_t *iterator) { - UNUSED(iterator); - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { - UNUSED(iterator); - return (dns_name_copy(dns_rootname, name, NULL)); -} - -/* - * Rdataset Iterator Methods - */ - -static void -rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { - sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp); - detachnode(sdbiterator->common.db, &sdbiterator->common.node); - isc_mem_put(sdbiterator->common.db->mctx, sdbiterator, - sizeof(sdb_rdatasetiter_t)); - *iteratorp = NULL; -} - -static isc_result_t -rdatasetiter_first(dns_rdatasetiter_t *iterator) { - sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; - dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node; - - if (ISC_LIST_EMPTY(sdbnode->lists)) - return (ISC_R_NOMORE); - sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists); - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdatasetiter_next(dns_rdatasetiter_t *iterator) { - sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; - - sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link); - if (sdbiterator->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static void -rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { - sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; - - list_tordataset(sdbiterator->current, iterator->db, iterator->node, - rdataset); -} diff --git a/lib/dns-pkcs11/sdlz.c b/lib/dns-pkcs11/sdlz.c deleted file mode 100644 index 9218fed..0000000 --- a/lib/dns-pkcs11/sdlz.c +++ /dev/null @@ -1,2182 +0,0 @@ -/* - * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/* - * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. - * - * 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 STICHTING NLNET - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * STICHTING NLNET 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. - * - * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was - * conceived and contributed by Rob Butler. - * - * 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 ROB BUTLER - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * ROB BUTLER 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. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rdatalist_p.h" - -/* - * Private Types - */ - -struct dns_sdlzimplementation { - const dns_sdlzmethods_t *methods; - isc_mem_t *mctx; - void *driverarg; - unsigned int flags; - isc_mutex_t driverlock; - dns_dlzimplementation_t *dlz_imp; -}; - -struct dns_sdlz_db { - /* Unlocked */ - dns_db_t common; - void *dbdata; - dns_sdlzimplementation_t *dlzimp; - isc_mutex_t refcnt_lock; - /* Locked */ - unsigned int references; - dns_dbversion_t *future_version; - int dummy_version; -}; - -struct dns_sdlzlookup { - /* Unlocked */ - unsigned int magic; - dns_sdlz_db_t *sdlz; - ISC_LIST(dns_rdatalist_t) lists; - ISC_LIST(isc_buffer_t) buffers; - dns_name_t *name; - ISC_LINK(dns_sdlzlookup_t) link; - isc_mutex_t lock; - dns_rdatacallbacks_t callbacks; - /* Locked */ - unsigned int references; -}; - -typedef struct dns_sdlzlookup dns_sdlznode_t; - -struct dns_sdlzallnodes { - dns_dbiterator_t common; - ISC_LIST(dns_sdlznode_t) nodelist; - dns_sdlznode_t *current; - dns_sdlznode_t *origin; -}; - -typedef dns_sdlzallnodes_t sdlz_dbiterator_t; - -typedef struct sdlz_rdatasetiter { - dns_rdatasetiter_t common; - dns_rdatalist_t *current; -} sdlz_rdatasetiter_t; - - -#define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S') - -/* - * Note that "impmagic" is not the first four bytes of the struct, so - * ISC_MAGIC_VALID cannot be used. - */ - -#define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \ - (sdlzdb)->common.impmagic == SDLZDB_MAGIC) - -#define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L') -#define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC) -#define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn) - -/* These values are taken from RFC 1537 */ -#define SDLZ_DEFAULT_REFRESH 28800U /* 8 hours */ -#define SDLZ_DEFAULT_RETRY 7200U /* 2 hours */ -#define SDLZ_DEFAULT_EXPIRE 604800U /* 7 days */ -#define SDLZ_DEFAULT_MINIMUM 86400U /* 1 day */ - -/* This is a reasonable value */ -#define SDLZ_DEFAULT_TTL (60 * 60 * 24) - -#ifdef __COVERITY__ -#define MAYBE_LOCK(imp) LOCK(&imp->driverlock) -#define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock) -#else -#define MAYBE_LOCK(imp) \ - do { \ - unsigned int flags = imp->flags; \ - if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ - LOCK(&imp->driverlock); \ - } while (0) - -#define MAYBE_UNLOCK(imp) \ - do { \ - unsigned int flags = imp->flags; \ - if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ - UNLOCK(&imp->driverlock); \ - } while (0) -#endif - -/* - * Forward references. - */ -static isc_result_t getnodedata(dns_db_t *db, dns_name_t *name, - bool create, unsigned int options, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_dbnode_t **nodep); - -static void list_tordataset(dns_rdatalist_t *rdatalist, - dns_db_t *db, dns_dbnode_t *node, - dns_rdataset_t *rdataset); - -static void detachnode(dns_db_t *db, dns_dbnode_t **targetp); - -static void dbiterator_destroy(dns_dbiterator_t **iteratorp); -static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, - dns_name_t *name); -static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, - dns_dbnode_t **nodep, - dns_name_t *name); -static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); -static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, - dns_name_t *name); - -static dns_dbiteratormethods_t dbiterator_methods = { - dbiterator_destroy, - dbiterator_first, - dbiterator_last, - dbiterator_seek, - dbiterator_prev, - dbiterator_next, - dbiterator_current, - dbiterator_pause, - dbiterator_origin -}; - -/* - * Utility functions - */ - -/* - * Log a message at the given level - */ -static void -sdlz_log(int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, - DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), - fmt, ap); - va_end(ap); -} - -/*% Converts the input string to lowercase, in place. */ -static void -dns_sdlz_tolower(char *str) { - unsigned int len = strlen(str); - unsigned int i; - - for (i = 0; i < len; i++) { - if (str[i] >= 'A' && str[i] <= 'Z') - str[i] += 32; - } -} - -static inline unsigned int -initial_size(const char *data) { - unsigned int len = (strlen(data) / 64) + 1; - return (len * 64 + 64); -} - -/* - * Rdataset Iterator Methods. These methods were "borrowed" from the SDB - * driver interface. See the SDB driver interface documentation for more info. - */ - -static void -rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { - sdlz_rdatasetiter_t *sdlziterator = - (sdlz_rdatasetiter_t *)(*iteratorp); - - detachnode(sdlziterator->common.db, &sdlziterator->common.node); - isc_mem_put(sdlziterator->common.db->mctx, sdlziterator, - sizeof(sdlz_rdatasetiter_t)); - *iteratorp = NULL; -} - -static isc_result_t -rdatasetiter_first(dns_rdatasetiter_t *iterator) { - sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; - dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node; - - if (ISC_LIST_EMPTY(sdlznode->lists)) - return (ISC_R_NOMORE); - sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists); - return (ISC_R_SUCCESS); -} - -static isc_result_t -rdatasetiter_next(dns_rdatasetiter_t *iterator) { - sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; - - sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link); - if (sdlziterator->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static void -rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { - sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; - - list_tordataset(sdlziterator->current, iterator->db, iterator->node, - rdataset); -} - -static dns_rdatasetitermethods_t rdatasetiter_methods = { - rdatasetiter_destroy, - rdatasetiter_first, - rdatasetiter_next, - rdatasetiter_current -}; - -/* - * DB routines. These methods were "borrowed" from the SDB driver interface. - * See the SDB driver interface documentation for more info. - */ - -static void -attach(dns_db_t *source, dns_db_t **targetp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source; - - REQUIRE(VALID_SDLZDB(sdlz)); - - LOCK(&sdlz->refcnt_lock); - REQUIRE(sdlz->references > 0); - sdlz->references++; - UNLOCK(&sdlz->refcnt_lock); - - *targetp = source; -} - -static void -destroy(dns_sdlz_db_t *sdlz) { - isc_mem_t *mctx; - mctx = sdlz->common.mctx; - - sdlz->common.magic = 0; - sdlz->common.impmagic = 0; - - (void)isc_mutex_destroy(&sdlz->refcnt_lock); - - dns_name_free(&sdlz->common.origin, mctx); - - isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t)); - isc_mem_detach(&mctx); -} - -static void -detach(dns_db_t **dbp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp); - bool need_destroy = false; - - REQUIRE(VALID_SDLZDB(sdlz)); - LOCK(&sdlz->refcnt_lock); - REQUIRE(sdlz->references > 0); - sdlz->references--; - if (sdlz->references == 0) - need_destroy = true; - UNLOCK(&sdlz->refcnt_lock); - - if (need_destroy) - destroy(sdlz); - - *dbp = NULL; -} - -static isc_result_t -beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - UNUSED(db); - UNUSED(callbacks); - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { - UNUSED(db); - UNUSED(callbacks); - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat) -{ - UNUSED(db); - UNUSED(version); - UNUSED(filename); - UNUSED(masterformat); - return (ISC_R_NOTIMPLEMENTED); -} - -static void -currentversion(dns_db_t *db, dns_dbversion_t **versionp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(versionp != NULL && *versionp == NULL); - - *versionp = (void *) &sdlz->dummy_version; - return; -} - -static isc_result_t -newversion(dns_db_t *db, dns_dbversion_t **versionp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - char origin[DNS_NAME_MAXTEXT + 1]; - isc_result_t result; - - REQUIRE(VALID_SDLZDB(sdlz)); - - if (sdlz->dlzimp->methods->newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - dns_name_format(&sdlz->common.origin, origin, sizeof(origin)); - - result = sdlz->dlzimp->methods->newversion(origin, - sdlz->dlzimp->driverarg, - sdlz->dbdata, versionp); - if (result != ISC_R_SUCCESS) { - sdlz_log(ISC_LOG_ERROR, - "sdlz newversion on origin %s failed : %s", - origin, isc_result_totext(result)); - return (result); - } - - sdlz->future_version = *versionp; - return (ISC_R_SUCCESS); -} - -static void -attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version); - - *targetp = source; -} - -static void -closeversion(dns_db_t *db, dns_dbversion_t **versionp, bool commit) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - char origin[DNS_NAME_MAXTEXT + 1]; - - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(versionp != NULL); - - if (*versionp == (void *)&sdlz->dummy_version) { - *versionp = NULL; - return; - } - - REQUIRE(*versionp == sdlz->future_version); - REQUIRE(sdlz->dlzimp->methods->closeversion != NULL); - - dns_name_format(&sdlz->common.origin, origin, sizeof(origin)); - - sdlz->dlzimp->methods->closeversion(origin, commit, - sdlz->dlzimp->driverarg, - sdlz->dbdata, versionp); - if (*versionp != NULL) - sdlz_log(ISC_LOG_ERROR, - "sdlz closeversion on origin %s failed", origin); - - sdlz->future_version = NULL; -} - -static isc_result_t -createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) { - dns_sdlznode_t *node; - isc_result_t result; - - node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t)); - if (node == NULL) - return (ISC_R_NOMEMORY); - - node->sdlz = NULL; - attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz); - ISC_LIST_INIT(node->lists); - ISC_LIST_INIT(node->buffers); - ISC_LINK_INIT(node, link); - node->name = NULL; - result = isc_mutex_init(&node->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t)); - return (ISC_R_UNEXPECTED); - } - dns_rdatacallbacks_init(&node->callbacks); - node->references = 1; - node->magic = SDLZLOOKUP_MAGIC; - - *nodep = node; - return (ISC_R_SUCCESS); -} - -static void -destroynode(dns_sdlznode_t *node) { - dns_rdatalist_t *list; - dns_rdata_t *rdata; - isc_buffer_t *b; - dns_sdlz_db_t *sdlz; - dns_db_t *db; - isc_mem_t *mctx; - - sdlz = node->sdlz; - mctx = sdlz->common.mctx; - - while (!ISC_LIST_EMPTY(node->lists)) { - list = ISC_LIST_HEAD(node->lists); - while (!ISC_LIST_EMPTY(list->rdata)) { - rdata = ISC_LIST_HEAD(list->rdata); - ISC_LIST_UNLINK(list->rdata, rdata, link); - isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); - } - ISC_LIST_UNLINK(node->lists, list, link); - isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); - } - - while (!ISC_LIST_EMPTY(node->buffers)) { - b = ISC_LIST_HEAD(node->buffers); - ISC_LIST_UNLINK(node->buffers, b, link); - isc_buffer_free(&b); - } - - if (node->name != NULL) { - dns_name_free(node->name, mctx); - isc_mem_put(mctx, node->name, sizeof(dns_name_t)); - } - DESTROYLOCK(&node->lock); - node->magic = 0; - isc_mem_put(mctx, node, sizeof(dns_sdlznode_t)); - db = &sdlz->common; - detach(&db); -} - -static isc_result_t -getnodedata(dns_db_t *db, dns_name_t *name, bool create, - unsigned int options, dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - dns_sdlznode_t *node = NULL; - isc_result_t result; - isc_buffer_t b; - char namestr[DNS_NAME_MAXTEXT + 1]; - isc_buffer_t b2; - char zonestr[DNS_NAME_MAXTEXT + 1]; - bool isorigin; - dns_sdlzauthorityfunc_t authority; - - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(nodep != NULL && *nodep == NULL); - - if (sdlz->dlzimp->methods->newversion == NULL) { - REQUIRE(create == false); - } - - isc_buffer_init(&b, namestr, sizeof(namestr)); - if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) { - dns_name_t relname; - unsigned int labels; - - labels = dns_name_countlabels(name) - - dns_name_countlabels(&sdlz->common.origin); - dns_name_init(&relname, NULL); - dns_name_getlabelsequence(name, 0, labels, &relname); - result = dns_name_totext(&relname, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - } else { - result = dns_name_totext(name, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - } - isc_buffer_putuint8(&b, 0); - - isc_buffer_init(&b2, zonestr, sizeof(zonestr)); - result = dns_name_totext(&sdlz->common.origin, true, &b2); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_putuint8(&b2, 0); - - result = createnode(sdlz, &node); - if (result != ISC_R_SUCCESS) - return (result); - - isorigin = dns_name_equal(name, &sdlz->common.origin); - - /* make sure strings are always lowercase */ - dns_sdlz_tolower(zonestr); - dns_sdlz_tolower(namestr); - - MAYBE_LOCK(sdlz->dlzimp); - - /* try to lookup the host (namestr) */ - result = sdlz->dlzimp->methods->lookup(zonestr, namestr, - sdlz->dlzimp->driverarg, - sdlz->dbdata, node, - methods, clientinfo); - - /* - * If the name was not found and DNS_DBFIND_NOWILD is not - * set, then we try to find a wildcard entry. - * - * If DNS_DBFIND_NOZONECUT is set and there are multiple - * levels between the host and the zone origin, we also look - * for wildcards at each level. - */ - if (result == ISC_R_NOTFOUND && !create && - (options & DNS_DBFIND_NOWILD) == 0) - { - unsigned int i, dlabels, nlabels; - - nlabels = dns_name_countlabels(name); - dlabels = nlabels - dns_name_countlabels(&sdlz->common.origin); - for (i = 0; i < dlabels; i++) { - char wildstr[DNS_NAME_MAXTEXT + 1]; - dns_fixedname_t fixed; - dns_name_t *wild; - - dns_fixedname_init(&fixed); - if (i == dlabels - 1) { - wild = dns_wildcardname; - } else { - dns_name_t *fname; - fname = dns_fixedname_name(&fixed); - dns_name_getlabelsequence(name, i + 1, - dlabels - i - 1, - fname); - result = dns_name_concatenate(dns_wildcardname, - fname, fname, - NULL); - if (result != ISC_R_SUCCESS) { - MAYBE_UNLOCK(sdlz->dlzimp); - return (result); - } - wild = fname; - } - - isc_buffer_init(&b, wildstr, sizeof(wildstr)); - result = dns_name_totext(wild, true, &b); - if (result != ISC_R_SUCCESS) { - MAYBE_UNLOCK(sdlz->dlzimp); - return (result); - } - isc_buffer_putuint8(&b, 0); - - result = sdlz->dlzimp->methods->lookup(zonestr, wildstr, - sdlz->dlzimp->driverarg, - sdlz->dbdata, node, - methods, clientinfo); - if (result == ISC_R_SUCCESS) - break; - } - } - - MAYBE_UNLOCK(sdlz->dlzimp); - - if (result == ISC_R_NOTFOUND && (isorigin || create)) - result = ISC_R_SUCCESS; - - if (result != ISC_R_SUCCESS) { - destroynode(node); - return (result); - } - - if (isorigin && sdlz->dlzimp->methods->authority != NULL) { - MAYBE_LOCK(sdlz->dlzimp); - authority = sdlz->dlzimp->methods->authority; - result = (*authority)(zonestr, sdlz->dlzimp->driverarg, - sdlz->dbdata, node); - MAYBE_UNLOCK(sdlz->dlzimp); - if (result != ISC_R_SUCCESS && - result != ISC_R_NOTIMPLEMENTED) - { - destroynode(node); - return (result); - } - } - - if (node->name == NULL) { - node->name = isc_mem_get(sdlz->common.mctx, - sizeof(dns_name_t)); - if (node->name == NULL) { - destroynode(node); - return (ISC_R_NOMEMORY); - } - dns_name_init(node->name, NULL); - result = dns_name_dup(name, sdlz->common.mctx, node->name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(sdlz->common.mctx, node->name, - sizeof(dns_name_t)); - destroynode(node); - return (result); - } - } - - *nodep = node; - return (ISC_R_SUCCESS); -} - -static isc_result_t -findnodeext(dns_db_t *db, dns_name_t *name, bool create, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_dbnode_t **nodep) -{ - return (getnodedata(db, name, create, 0, methods, clientinfo, nodep)); -} - -static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, bool create, - dns_dbnode_t **nodep) -{ - return (getnodedata(db, name, create, 0, NULL, NULL, nodep)); -} - -static isc_result_t -findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - UNUSED(db); - UNUSED(name); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - return (ISC_R_NOTIMPLEMENTED); -} - -static void -attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - dns_sdlznode_t *node = (dns_sdlznode_t *)source; - - REQUIRE(VALID_SDLZDB(sdlz)); - - UNUSED(sdlz); - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references++; - INSIST(node->references != 0); /* Catch overflow. */ - UNLOCK(&node->lock); - - *targetp = source; -} - -static void -detachnode(dns_db_t *db, dns_dbnode_t **targetp) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - dns_sdlznode_t *node; - bool need_destroy = false; - - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(targetp != NULL && *targetp != NULL); - - UNUSED(sdlz); - - node = (dns_sdlznode_t *)(*targetp); - - LOCK(&node->lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - need_destroy = true; - UNLOCK(&node->lock); - - if (need_destroy) - destroynode(node); - - *targetp = NULL; -} - -static isc_result_t -expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { - UNUSED(db); - UNUSED(node); - UNUSED(now); - INSIST(0); - ISC_UNREACHABLE(); -} - -static void -printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { - UNUSED(db); - UNUSED(node); - UNUSED(out); - return; -} - -static isc_result_t -createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - sdlz_dbiterator_t *sdlziter; - isc_result_t result; - isc_buffer_t b; - char zonestr[DNS_NAME_MAXTEXT + 1]; - - REQUIRE(VALID_SDLZDB(sdlz)); - - if (sdlz->dlzimp->methods->allnodes == NULL) - return (ISC_R_NOTIMPLEMENTED); - - if ((options & DNS_DB_NSEC3ONLY) != 0 || - (options & DNS_DB_NONSEC3) != 0) - return (ISC_R_NOTIMPLEMENTED); - - isc_buffer_init(&b, zonestr, sizeof(zonestr)); - result = dns_name_totext(&sdlz->common.origin, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_putuint8(&b, 0); - - sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t)); - if (sdlziter == NULL) - return (ISC_R_NOMEMORY); - - sdlziter->common.methods = &dbiterator_methods; - sdlziter->common.db = NULL; - dns_db_attach(db, &sdlziter->common.db); - sdlziter->common.relative_names = - ((options & DNS_DB_RELATIVENAMES) != 0); - sdlziter->common.magic = DNS_DBITERATOR_MAGIC; - ISC_LIST_INIT(sdlziter->nodelist); - sdlziter->current = NULL; - sdlziter->origin = NULL; - - /* make sure strings are always lowercase */ - dns_sdlz_tolower(zonestr); - - MAYBE_LOCK(sdlz->dlzimp); - result = sdlz->dlzimp->methods->allnodes(zonestr, - sdlz->dlzimp->driverarg, - sdlz->dbdata, sdlziter); - MAYBE_UNLOCK(sdlz->dlzimp); - if (result != ISC_R_SUCCESS) { - dns_dbiterator_t *iter = &sdlziter->common; - dbiterator_destroy(&iter); - return (result); - } - - if (sdlziter->origin != NULL) { - ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link); - ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link); - } - - *iteratorp = (dns_dbiterator_t *)sdlziter; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - dns_rdatalist_t *list; - dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node; - - REQUIRE(VALID_SDLZNODE(node)); - - UNUSED(db); - UNUSED(version); - UNUSED(covers); - UNUSED(now); - UNUSED(sigrdataset); - - if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig) - return (ISC_R_NOTIMPLEMENTED); - - list = ISC_LIST_HEAD(sdlznode->lists); - while (list != NULL) { - if (list->type == type) - break; - list = ISC_LIST_NEXT(list, link); - } - if (list == NULL) - return (ISC_R_NOTFOUND); - - list_tordataset(list, db, node, rdataset); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - dns_dbnode_t *node = NULL; - dns_fixedname_t fname; - dns_rdataset_t xrdataset; - dns_name_t *xname; - unsigned int nlabels, olabels; - isc_result_t result; - unsigned int i; - - REQUIRE(VALID_SDLZDB(sdlz)); - REQUIRE(nodep == NULL || *nodep == NULL); - REQUIRE(version == NULL || - version == (void*)&sdlz->dummy_version || - version == sdlz->future_version); - - UNUSED(sdlz); - - if (!dns_name_issubdomain(name, &db->origin)) - return (DNS_R_NXDOMAIN); - - olabels = dns_name_countlabels(&db->origin); - nlabels = dns_name_countlabels(name); - - xname = dns_fixedname_initname(&fname); - - if (rdataset == NULL) { - dns_rdataset_init(&xrdataset); - rdataset = &xrdataset; - } - - result = DNS_R_NXDOMAIN; - - /* - * If we're not walking down searching for zone - * cuts, we can cut straight to the chase - */ - if ((options & DNS_DBFIND_NOZONECUT) != 0) { - i = nlabels; - goto search; - } - - for (i = olabels; i <= nlabels; i++) { - search: - /* - * Look up the next label. - */ - dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = getnodedata(db, xname, false, options, - methods, clientinfo, &node); - if (result == ISC_R_NOTFOUND) { - result = DNS_R_NXDOMAIN; - continue; - } else if (result != ISC_R_SUCCESS) - break; - - /* - * Look for a DNAME at the current label, unless this is - * the qname. - */ - if (i < nlabels) { - result = findrdataset(db, node, version, - dns_rdatatype_dname, 0, now, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - result = DNS_R_DNAME; - break; - } - } - - /* - * Look for an NS at the current label, unless this is the - * origin, glue is ok, or there are known to be no zone cuts. - */ - if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0 && - (options & DNS_DBFIND_NOZONECUT) == 0) - { - result = findrdataset(db, node, version, - dns_rdatatype_ns, 0, now, - rdataset, sigrdataset); - - if (result == ISC_R_SUCCESS && - i == nlabels && type == dns_rdatatype_any) - { - result = DNS_R_ZONECUT; - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - break; - } else if (result == ISC_R_SUCCESS) { - result = DNS_R_DELEGATION; - break; - } - } - - /* - * If the current name is not the qname, add another label - * and try again. - */ - if (i < nlabels) { - destroynode(node); - node = NULL; - continue; - } - - /* - * If we're looking for ANY, we're done. - */ - if (type == dns_rdatatype_any) { - result = ISC_R_SUCCESS; - break; - } - - /* - * Look for the qtype. - */ - result = findrdataset(db, node, version, type, 0, now, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) - break; - - /* - * Look for a CNAME - */ - if (type != dns_rdatatype_cname) { - result = findrdataset(db, node, version, - dns_rdatatype_cname, 0, now, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - result = DNS_R_CNAME; - break; - } - } - - result = DNS_R_NXRRSET; - break; - } - - if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - - if (foundname != NULL) { - isc_result_t xresult; - - xresult = dns_name_copy(xname, foundname, NULL); - if (xresult != ISC_R_SUCCESS) { - if (node != NULL) - destroynode(node); - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - return (DNS_R_BADDB); - } - } - - if (nodep != NULL) - *nodep = node; - else if (node != NULL) - detachnode(db, &node); - - return (result); -} - -static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - return (findext(db, name, version, type, options, now, nodep, - foundname, NULL, NULL, rdataset, sigrdataset)); -} - -static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db; - sdlz_rdatasetiter_t *iterator; - - REQUIRE(VALID_SDLZDB(sdlz)); - - REQUIRE(version == NULL || - version == (void*)&sdlz->dummy_version || - version == sdlz->future_version); - - UNUSED(version); - UNUSED(now); - - iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t)); - if (iterator == NULL) - return (ISC_R_NOMEMORY); - - iterator->common.magic = DNS_RDATASETITER_MAGIC; - iterator->common.methods = &rdatasetiter_methods; - iterator->common.db = db; - iterator->common.node = NULL; - attachnode(db, node, &iterator->common.node); - iterator->common.version = version; - iterator->common.now = now; - - *iteratorp = (dns_rdatasetiter_t *)iterator; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdataset_t *rdataset, unsigned int options, - dns_sdlzmodrdataset_t mod_function) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - dns_master_style_t *style = NULL; - isc_result_t result; - isc_buffer_t *buffer = NULL; - isc_mem_t *mctx; - dns_sdlznode_t *sdlznode; - char *rdatastr = NULL; - char name[DNS_NAME_MAXTEXT + 1]; - - REQUIRE(VALID_SDLZDB(sdlz)); - - if (mod_function == NULL) - return (ISC_R_NOTIMPLEMENTED); - - sdlznode = (dns_sdlznode_t *)node; - - UNUSED(options); - - dns_name_format(sdlznode->name, name, sizeof(name)); - - mctx = sdlz->common.mctx; - - result = isc_buffer_allocate(mctx, &buffer, 1024); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_master_rdatasettotext(sdlznode->name, rdataset, - style, buffer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (isc_buffer_usedlength(buffer) < 1) { - result = ISC_R_BADADDRESSFORM; - goto cleanup; - } - - rdatastr = isc_buffer_base(buffer); - if (rdatastr == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - rdatastr[isc_buffer_usedlength(buffer) - 1] = 0; - - MAYBE_LOCK(sdlz->dlzimp); - result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg, - sdlz->dbdata, version); - MAYBE_UNLOCK(sdlz->dlzimp); - -cleanup: - isc_buffer_free(&buffer); - if (style != NULL) - dns_master_styledestroy(&style, mctx); - - return (result); -} - -static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - isc_result_t result; - - UNUSED(now); - UNUSED(addedrdataset); - REQUIRE(VALID_SDLZDB(sdlz)); - - if (sdlz->dlzimp->methods->addrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - result = modrdataset(db, node, version, rdataset, options, - sdlz->dlzimp->methods->addrdataset); - return (result); -} - - -static isc_result_t -subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *newrdataset) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - isc_result_t result; - - UNUSED(newrdataset); - REQUIRE(VALID_SDLZDB(sdlz)); - - if (sdlz->dlzimp->methods->subtractrdataset == NULL) { - return (ISC_R_NOTIMPLEMENTED); - } - - result = modrdataset(db, node, version, rdataset, options, - sdlz->dlzimp->methods->subtractrdataset); - return (result); -} - -static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers) -{ - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - char name[DNS_NAME_MAXTEXT + 1]; - char b_type[DNS_RDATATYPE_FORMATSIZE]; - dns_sdlznode_t *sdlznode; - isc_result_t result; - - UNUSED(covers); - - REQUIRE(VALID_SDLZDB(sdlz)); - - if (sdlz->dlzimp->methods->delrdataset == NULL) - return (ISC_R_NOTIMPLEMENTED); - - sdlznode = (dns_sdlznode_t *)node; - dns_name_format(sdlznode->name, name, sizeof(name)); - dns_rdatatype_format(type, b_type, sizeof(b_type)); - - MAYBE_LOCK(sdlz->dlzimp); - result = sdlz->dlzimp->methods->delrdataset(name, b_type, - sdlz->dlzimp->driverarg, - sdlz->dbdata, version); - MAYBE_UNLOCK(sdlz->dlzimp); - - return (result); -} - -static bool -issecure(dns_db_t *db) { - UNUSED(db); - - return (false); -} - -static unsigned int -nodecount(dns_db_t *db) { - UNUSED(db); - - return (0); -} - -static bool -ispersistent(dns_db_t *db) { - UNUSED(db); - return (true); -} - -static void -overmem(dns_db_t *db, bool over) { - UNUSED(db); - UNUSED(over); -} - -static void -settask(dns_db_t *db, isc_task_t *task) { - UNUSED(db); - UNUSED(task); -} - -/* - * getoriginnode() is used by the update code to find the - * dns_rdatatype_dnskey record for a zone - */ -static isc_result_t -getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; - isc_result_t result; - - REQUIRE(VALID_SDLZDB(sdlz)); - if (sdlz->dlzimp->methods->newversion == NULL) - return (ISC_R_NOTIMPLEMENTED); - - result = getnodedata(db, &sdlz->common.origin, false, - 0, NULL, NULL, nodep); - if (result != ISC_R_SUCCESS) - sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s", - isc_result_totext(result)); - return (result); -} - -static dns_dbmethods_t sdlzdb_methods = { - attach, - detach, - beginload, - endload, - NULL, - dump, - currentversion, - newversion, - attachversion, - closeversion, - findnode, - find, - findzonecut, - attachnode, - detachnode, - expirenode, - printnode, - createiterator, - findrdataset, - allrdatasets, - addrdataset, - subtractrdataset, - deleterdataset, - issecure, - nodecount, - ispersistent, - overmem, - settask, - getoriginnode, - NULL, /* transfernode */ - NULL, /* getnsec3parameters */ - NULL, /* findnsec3node */ - NULL, /* setsigningtime */ - NULL, /* getsigningtime */ - NULL, /* resigned */ - NULL, /* isdnssec */ - NULL, /* getrrsetstats */ - NULL, /* rpz_attach */ - NULL, /* rpz_ready */ - findnodeext, - findext, - NULL, /* setcachestats */ - NULL, /* hashsize */ - NULL, /* nodefullname */ - NULL, /* getsize */ - NULL, /* setservestalettl */ - NULL /* getservestalettl */ -}; - -/* - * Database Iterator Methods. These methods were "borrowed" from the SDB - * driver interface. See the SDB driver interface documentation for more info. - */ - -static void -dbiterator_destroy(dns_dbiterator_t **iteratorp) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp); - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db; - - while (!ISC_LIST_EMPTY(sdlziter->nodelist)) { - dns_sdlznode_t *node; - node = ISC_LIST_HEAD(sdlziter->nodelist); - ISC_LIST_UNLINK(sdlziter->nodelist, node, link); - destroynode(node); - } - - dns_db_detach(&sdlziter->common.db); - isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t)); - - *iteratorp = NULL; -} - -static isc_result_t -dbiterator_first(dns_dbiterator_t *iterator) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); - if (sdlziter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_last(dns_dbiterator_t *iterator) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist); - if (sdlziter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); - while (sdlziter->current != NULL) { - if (dns_name_equal(sdlziter->current->name, name)) - return (ISC_R_SUCCESS); - sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); - } - return (ISC_R_NOTFOUND); -} - -static isc_result_t -dbiterator_prev(dns_dbiterator_t *iterator) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - sdlziter->current = ISC_LIST_PREV(sdlziter->current, link); - if (sdlziter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_next(dns_dbiterator_t *iterator) { - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); - if (sdlziter->current == NULL) - return (ISC_R_NOMORE); - else - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, - dns_name_t *name) -{ - sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; - - attachnode(iterator->db, sdlziter->current, nodep); - if (name != NULL) - return (dns_name_copy(sdlziter->current->name, name, NULL)); - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_pause(dns_dbiterator_t *iterator) { - UNUSED(iterator); - return (ISC_R_SUCCESS); -} - -static isc_result_t -dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { - UNUSED(iterator); - return (dns_name_copy(dns_rootname, name, NULL)); -} - -/* - * Rdataset Methods. These methods were "borrowed" from the SDB driver - * interface. See the SDB driver interface documentation for more info. - */ - -static void -disassociate(dns_rdataset_t *rdataset) { - dns_dbnode_t *node = rdataset->private5; - dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; - dns_db_t *db = (dns_db_t *) sdlznode->sdlz; - - detachnode(db, &node); - isc__rdatalist_disassociate(rdataset); -} - -static void -rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { - dns_dbnode_t *node = source->private5; - dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; - dns_db_t *db = (dns_db_t *) sdlznode->sdlz; - dns_dbnode_t *tempdb = NULL; - - isc__rdatalist_clone(source, target); - attachnode(db, node, &tempdb); - source->private5 = tempdb; -} - -static dns_rdatasetmethods_t rdataset_methods = { - disassociate, - isc__rdatalist_first, - isc__rdatalist_next, - isc__rdatalist_current, - rdataset_clone, - isc__rdatalist_count, - isc__rdatalist_addnoqname, - isc__rdatalist_getnoqname, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -static void -list_tordataset(dns_rdatalist_t *rdatalist, - dns_db_t *db, dns_dbnode_t *node, - dns_rdataset_t *rdataset) -{ - /* - * The sdlz rdataset is an rdatalist with some additions. - * - private1 & private2 are used by the rdatalist. - * - private3 & private 4 are unused. - * - private5 is the node. - */ - - /* This should never fail. */ - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == - ISC_R_SUCCESS); - - rdataset->methods = &rdataset_methods; - dns_db_attachnode(db, node, &rdataset->private5); -} - -/* - * SDLZ core methods. This is the core of the new DLZ functionality. - */ - -/*% - * Build a 'bind' database driver structure to be returned by - * either the find zone or the allow zone transfer method. - * This method is only available in this source file, it is - * not made available anywhere else. - */ - -static isc_result_t -dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata, - dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp) -{ - isc_result_t result; - dns_sdlz_db_t *sdlzdb; - dns_sdlzimplementation_t *imp; - - /* check that things are as we expect */ - REQUIRE(dbp != NULL && *dbp == NULL); - REQUIRE(name != NULL); - - imp = (dns_sdlzimplementation_t *) driverarg; - - /* allocate and zero memory for driver structure */ - sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t)); - if (sdlzdb == NULL) - return (ISC_R_NOMEMORY); - memset(sdlzdb, 0, sizeof(dns_sdlz_db_t)); - - /* initialize and set origin */ - dns_name_init(&sdlzdb->common.origin, NULL); - result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin); - if (result != ISC_R_SUCCESS) - goto mem_cleanup; - - /* initialize the reference count mutex */ - result = isc_mutex_init(&sdlzdb->refcnt_lock); - if (result != ISC_R_SUCCESS) - goto name_cleanup; - - /* set the rest of the database structure attributes */ - sdlzdb->dlzimp = imp; - sdlzdb->common.methods = &sdlzdb_methods; - sdlzdb->common.attributes = 0; - sdlzdb->common.rdclass = rdclass; - sdlzdb->common.mctx = NULL; - sdlzdb->dbdata = dbdata; - sdlzdb->references = 1; - - /* attach to the memory context */ - isc_mem_attach(mctx, &sdlzdb->common.mctx); - - /* mark structure as valid */ - sdlzdb->common.magic = DNS_DB_MAGIC; - sdlzdb->common.impmagic = SDLZDB_MAGIC; - *dbp = (dns_db_t *) sdlzdb; - - return (result); - - /* - * reference count mutex could not be initialized, clean up - * name memory - */ - name_cleanup: - dns_name_free(&sdlzdb->common.origin, mctx); - mem_cleanup: - isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t)); - return (result); -} - -static isc_result_t -dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_name_t *name, - isc_sockaddr_t *clientaddr, dns_db_t **dbp) -{ - isc_buffer_t b; - isc_buffer_t b2; - char namestr[DNS_NAME_MAXTEXT + 1]; - char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") - + 1]; - isc_netaddr_t netaddr; - isc_result_t result; - dns_sdlzimplementation_t *imp; - - /* - * Perform checks to make sure data is as we expect it to be. - */ - REQUIRE(driverarg != NULL); - REQUIRE(name != NULL); - REQUIRE(clientaddr != NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - imp = (dns_sdlzimplementation_t *) driverarg; - - /* Convert DNS name to ascii text */ - isc_buffer_init(&b, namestr, sizeof(namestr)); - result = dns_name_totext(name, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_putuint8(&b, 0); - - /* convert client address to ascii text */ - isc_buffer_init(&b2, clientstr, sizeof(clientstr)); - isc_netaddr_fromsockaddr(&netaddr, clientaddr); - result = isc_netaddr_totext(&netaddr, &b2); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_putuint8(&b2, 0); - - /* make sure strings are always lowercase */ - dns_sdlz_tolower(namestr); - dns_sdlz_tolower(clientstr); - - /* Call SDLZ driver's find zone method */ - if (imp->methods->allowzonexfr != NULL) { - MAYBE_LOCK(imp); - result = imp->methods->allowzonexfr(imp->driverarg, dbdata, - namestr, clientstr); - MAYBE_UNLOCK(imp); - /* - * if zone is supported and transfers allowed build a 'bind' - * database driver - */ - if (result == ISC_R_SUCCESS) - result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, - name, rdclass, dbp); - return (result); - } - - return (ISC_R_NOTIMPLEMENTED); -} - -static isc_result_t -dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc, - char *argv[], void *driverarg, void **dbdata) -{ - dns_sdlzimplementation_t *imp; - isc_result_t result = ISC_R_NOTFOUND; - - /* Write debugging message to log */ - sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver."); - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(driverarg != NULL); - REQUIRE(dlzname != NULL); - REQUIRE(dbdata != NULL); - UNUSED(mctx); - - imp = driverarg; - - /* If the create method exists, call it. */ - if (imp->methods->create != NULL) { - MAYBE_LOCK(imp); - result = imp->methods->create(dlzname, argc, argv, - imp->driverarg, dbdata); - MAYBE_UNLOCK(imp); - } - - /* Write debugging message to log */ - if (result == ISC_R_SUCCESS) { - sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully."); - } else { - sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load."); - } - - return (result); -} - -static void -dns_sdlzdestroy(void *driverdata, void **dbdata) { - dns_sdlzimplementation_t *imp; - - /* Write debugging message to log */ - sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver."); - - imp = driverdata; - - /* If the destroy method exists, call it. */ - if (imp->methods->destroy != NULL) { - MAYBE_LOCK(imp); - imp->methods->destroy(imp->driverarg, dbdata); - MAYBE_UNLOCK(imp); - } -} - -static isc_result_t -dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx, - dns_rdataclass_t rdclass, dns_name_t *name, - dns_clientinfomethods_t *methods, - dns_clientinfo_t *clientinfo, - dns_db_t **dbp) -{ - isc_buffer_t b; - char namestr[DNS_NAME_MAXTEXT + 1]; - isc_result_t result; - dns_sdlzimplementation_t *imp; - - /* - * Perform checks to make sure data is as we expect it to be. - */ - REQUIRE(driverarg != NULL); - REQUIRE(name != NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - imp = (dns_sdlzimplementation_t *) driverarg; - - /* Convert DNS name to ascii text */ - isc_buffer_init(&b, namestr, sizeof(namestr)); - result = dns_name_totext(name, true, &b); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_putuint8(&b, 0); - - /* make sure strings are always lowercase */ - dns_sdlz_tolower(namestr); - - /* Call SDLZ driver's find zone method */ - MAYBE_LOCK(imp); - result = imp->methods->findzone(imp->driverarg, dbdata, namestr, - methods, clientinfo); - MAYBE_UNLOCK(imp); - - /* - * if zone is supported build a 'bind' database driver - * structure to return - */ - if (result == ISC_R_SUCCESS) - result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, - rdclass, dbp); - - return (result); -} - - -static isc_result_t -dns_sdlzconfigure(void *driverarg, void *dbdata, - dns_view_t *view, dns_dlzdb_t *dlzdb) -{ - isc_result_t result; - dns_sdlzimplementation_t *imp; - - REQUIRE(driverarg != NULL); - - imp = (dns_sdlzimplementation_t *) driverarg; - - /* Call SDLZ driver's configure method */ - if (imp->methods->configure != NULL) { - MAYBE_LOCK(imp); - result = imp->methods->configure(view, dlzdb, - imp->driverarg, dbdata); - MAYBE_UNLOCK(imp); - } else { - result = ISC_R_SUCCESS; - } - - return (result); -} - -static bool -dns_sdlzssumatch(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, - dns_rdatatype_t type, const dst_key_t *key, void *driverarg, - void *dbdata) -{ - dns_sdlzimplementation_t *imp; - char b_signer[DNS_NAME_FORMATSIZE]; - char b_name[DNS_NAME_FORMATSIZE]; - char b_addr[ISC_NETADDR_FORMATSIZE]; - char b_type[DNS_RDATATYPE_FORMATSIZE]; - char b_key[DST_KEY_FORMATSIZE]; - isc_buffer_t *tkey_token = NULL; - isc_region_t token_region = { NULL, 0 }; - uint32_t token_len = 0; - bool ret; - - REQUIRE(driverarg != NULL); - - imp = (dns_sdlzimplementation_t *) driverarg; - if (imp->methods->ssumatch == NULL) - return (false); - - /* - * Format the request elements. sdlz operates on strings, not - * structures - */ - if (signer != NULL) - dns_name_format(signer, b_signer, sizeof(b_signer)); - else - b_signer[0] = 0; - - dns_name_format(name, b_name, sizeof(b_name)); - - if (tcpaddr != NULL) - isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr)); - else - b_addr[0] = 0; - - dns_rdatatype_format(type, b_type, sizeof(b_type)); - - if (key != NULL) { - dst_key_format(key, b_key, sizeof(b_key)); - tkey_token = dst_key_tkeytoken(key); - } else - b_key[0] = 0; - - if (tkey_token != NULL) { - isc_buffer_region(tkey_token, &token_region); - token_len = token_region.length; - } - - MAYBE_LOCK(imp); - ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key, - token_len, - token_len != 0 ? token_region.base : NULL, - imp->driverarg, dbdata); - MAYBE_UNLOCK(imp); - return (ret); -} - -static dns_dlzmethods_t sdlzmethods = { - dns_sdlzcreate, - dns_sdlzdestroy, - dns_sdlzfindzone, - dns_sdlzallowzonexfr, - dns_sdlzconfigure, - dns_sdlzssumatch -}; - -/* - * Public functions. - */ - -isc_result_t -dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, - const char *data) -{ - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - dns_rdatatype_t typeval; - isc_consttextregion_t r; - isc_buffer_t b; - isc_buffer_t *rdatabuf = NULL; - isc_lex_t *lex; - isc_result_t result; - unsigned int size; - isc_mem_t *mctx; - dns_name_t *origin; - - REQUIRE(VALID_SDLZLOOKUP(lookup)); - REQUIRE(type != NULL); - REQUIRE(data != NULL); - - mctx = lookup->sdlz->common.mctx; - - r.base = type; - r.length = strlen(type); - result = dns_rdatatype_fromtext(&typeval, (void *) &r); - if (result != ISC_R_SUCCESS) - return (result); - - rdatalist = ISC_LIST_HEAD(lookup->lists); - while (rdatalist != NULL) { - if (rdatalist->type == typeval) - break; - rdatalist = ISC_LIST_NEXT(rdatalist, link); - } - - if (rdatalist == NULL) { - rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); - if (rdatalist == NULL) - return (ISC_R_NOMEMORY); - dns_rdatalist_init(rdatalist); - rdatalist->rdclass = lookup->sdlz->common.rdclass; - rdatalist->type = typeval; - rdatalist->ttl = ttl; - ISC_LIST_APPEND(lookup->lists, rdatalist, link); - } else - if (rdatalist->ttl > ttl) { - /* - * BIND9 doesn't enforce all RRs in an RRset - * having the same TTL, as per RFC 2136, - * section 7.12. If a DLZ backend has - * different TTLs, then the best - * we can do is return the lowest. - */ - rdatalist->ttl = ttl; - } - - rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); - if (rdata == NULL) - return (ISC_R_NOMEMORY); - dns_rdata_init(rdata); - - if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) - origin = &lookup->sdlz->common.origin; - else - origin = dns_rootname; - - lex = NULL; - result = isc_lex_create(mctx, 64, &lex); - if (result != ISC_R_SUCCESS) - goto failure; - - size = initial_size(data); - do { - isc_buffer_constinit(&b, data, strlen(data)); - isc_buffer_add(&b, strlen(data)); - - result = isc_lex_openbuffer(lex, &b); - if (result != ISC_R_SUCCESS) - goto failure; - - rdatabuf = NULL; - result = isc_buffer_allocate(mctx, &rdatabuf, size); - if (result != ISC_R_SUCCESS) - goto failure; - - result = dns_rdata_fromtext(rdata, rdatalist->rdclass, - rdatalist->type, lex, - origin, false, - mctx, rdatabuf, - &lookup->callbacks); - if (result != ISC_R_SUCCESS) - isc_buffer_free(&rdatabuf); - if (size >= 65535) - break; - size *= 2; - if (size >= 65535) - size = 65535; - } while (result == ISC_R_NOSPACE); - - if (result != ISC_R_SUCCESS) - goto failure; - - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); - - if (lex != NULL) - isc_lex_destroy(&lex); - - return (ISC_R_SUCCESS); - - failure: - if (rdatabuf != NULL) - isc_buffer_free(&rdatabuf); - if (lex != NULL) - isc_lex_destroy(&lex); - isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); - - return (result); -} - -isc_result_t -dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, - const char *type, dns_ttl_t ttl, const char *data) -{ - dns_name_t *newname, *origin; - dns_fixedname_t fnewname; - dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db; - dns_sdlznode_t *sdlznode; - isc_mem_t *mctx = sdlz->common.mctx; - isc_buffer_t b; - isc_result_t result; - - newname = dns_fixedname_initname(&fnewname); - - if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) - origin = &sdlz->common.origin; - else - origin = dns_rootname; - isc_buffer_constinit(&b, name, strlen(name)); - isc_buffer_add(&b, strlen(name)); - - result = dns_name_fromtext(newname, &b, origin, 0, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - if (allnodes->common.relative_names) { - /* All names are relative to the root */ - unsigned int nlabels = dns_name_countlabels(newname); - dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); - } - - sdlznode = ISC_LIST_HEAD(allnodes->nodelist); - if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) { - sdlznode = NULL; - result = createnode(sdlz, &sdlznode); - if (result != ISC_R_SUCCESS) - return (result); - sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t)); - if (sdlznode->name == NULL) { - destroynode(sdlznode); - return (ISC_R_NOMEMORY); - } - dns_name_init(sdlznode->name, NULL); - result = dns_name_dup(newname, mctx, sdlznode->name); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t)); - destroynode(sdlznode); - return (result); - } - ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link); - if (allnodes->origin == NULL && - dns_name_equal(newname, &sdlz->common.origin)) - allnodes->origin = sdlznode; - } - return (dns_sdlz_putrr(sdlznode, type, ttl, data)); - -} - -isc_result_t -dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, - uint32_t serial) -{ - char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; - int n; - - REQUIRE(mname != NULL); - REQUIRE(rname != NULL); - - n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u", - mname, rname, serial, - SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY, - SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM); - if (n >= (int)sizeof(str) || n < 0) - return (ISC_R_NOSPACE); - return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str)); -} - -isc_result_t -dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, - void *driverarg, unsigned int flags, isc_mem_t *mctx, - dns_sdlzimplementation_t **sdlzimp) -{ - - dns_sdlzimplementation_t *imp; - isc_result_t result; - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(drivername != NULL); - REQUIRE(methods != NULL); - REQUIRE(methods->findzone != NULL); - REQUIRE(methods->lookup != NULL); - REQUIRE(mctx != NULL); - REQUIRE(sdlzimp != NULL && *sdlzimp == NULL); - REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER | - DNS_SDLZFLAG_RELATIVERDATA | - DNS_SDLZFLAG_THREADSAFE)) == 0); - - /* Write debugging message to log */ - sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername); - - /* - * Allocate memory for a sdlz_implementation object. Error if - * we cannot. - */ - imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t)); - if (imp == NULL) - return (ISC_R_NOMEMORY); - - /* Make sure memory region is set to all 0's */ - memset(imp, 0, sizeof(dns_sdlzimplementation_t)); - - /* Store the data passed into this method */ - imp->methods = methods; - imp->driverarg = driverarg; - imp->flags = flags; - imp->mctx = NULL; - - /* attach the new sdlz_implementation object to a memory context */ - isc_mem_attach(mctx, &imp->mctx); - - /* - * initialize the driver lock, error if we cannot - * (used if a driver does not support multiple threads) - */ - result = isc_mutex_init(&imp->driverlock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - goto cleanup_mctx; - } - - imp->dlz_imp = NULL; - - /* - * register the DLZ driver. Pass in our "extra" sdlz information as - * a driverarg. (that's why we stored the passed in driver arg in our - * sdlz_implementation structure) Also, store the dlz_implementation - * structure in our sdlz_implementation. - */ - result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx, - &imp->dlz_imp); - - /* if registration fails, cleanup and get outta here. */ - if (result != ISC_R_SUCCESS) - goto cleanup_mutex; - - *sdlzimp = imp; - - return (ISC_R_SUCCESS); - - cleanup_mutex: - /* destroy the driver lock, we don't need it anymore */ - DESTROYLOCK(&imp->driverlock); - - cleanup_mctx: - /* - * return the memory back to the available memory pool and - * remove it from the memory context. - */ - isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); - isc_mem_detach(&mctx); - return (result); -} - -void -dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) { - dns_sdlzimplementation_t *imp; - isc_mem_t *mctx; - - /* Write debugging message to log */ - sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver."); - - /* - * Performs checks to make sure data is as we expect it to be. - */ - REQUIRE(sdlzimp != NULL && *sdlzimp != NULL); - - imp = *sdlzimp; - - /* Unregister the DLZ driver implementation */ - dns_dlzunregister(&imp->dlz_imp); - - /* destroy the driver lock, we don't need it anymore */ - DESTROYLOCK(&imp->driverlock); - - mctx = imp->mctx; - - /* - * return the memory back to the available memory pool and - * remove it from the memory context. - */ - isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); - isc_mem_detach(&mctx); - - *sdlzimp = NULL; -} - - -isc_result_t -dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass, - dns_name_t *name, dns_db_t **dbp) -{ - isc_result_t result; - - result = dns_sdlzcreateDBP(dlzdatabase->mctx, - dlzdatabase->implementation->driverarg, - dlzdatabase->dbdata, name, rdclass, dbp); - return (result); -} diff --git a/lib/dns-pkcs11/soa.c b/lib/dns-pkcs11/soa.c deleted file mode 100644 index 99f85a8..0000000 --- a/lib/dns-pkcs11/soa.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -static inline uint32_t -decode_uint32(unsigned char *p) { - return ((p[0] << 24) + - (p[1] << 16) + - (p[2] << 8) + - (p[3] << 0)); -} - -static inline void -encode_uint32(uint32_t val, unsigned char *p) { - p[0] = (uint8_t)(val >> 24); - p[1] = (uint8_t)(val >> 16); - p[2] = (uint8_t)(val >> 8); - p[3] = (uint8_t)(val >> 0); -} - -static uint32_t -soa_get(dns_rdata_t *rdata, int offset) { - INSIST(rdata->type == dns_rdatatype_soa); - /* - * Locate the field within the SOA RDATA based - * on its position relative to the end of the data. - * - * This is a bit of a kludge, but the alternative approach of - * using dns_rdata_tostruct() and dns_rdata_fromstruct() would - * involve a lot of unnecessary work (like building domain - * names and allocating temporary memory) when all we really - * want to do is to get 32 bits of fixed-sized data. - */ - INSIST(rdata->length >= 20); - INSIST(offset >= 0 && offset <= 16); - return (decode_uint32(rdata->data + rdata->length - 20 + offset)); -} - -isc_result_t -dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact, - dns_rdataclass_t rdclass, - uint32_t serial, uint32_t refresh, - uint32_t retry, uint32_t expire, - uint32_t minimum, unsigned char *buffer, - dns_rdata_t *rdata) { - dns_rdata_soa_t soa; - isc_buffer_t rdatabuf; - - REQUIRE(origin != NULL); - REQUIRE(contact != NULL); - - memset(buffer, 0, DNS_SOA_BUFFERSIZE); - isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE); - - soa.common.rdtype = dns_rdatatype_soa; - soa.common.rdclass = rdclass; - soa.mctx = NULL; - soa.serial = serial; - soa.refresh = refresh; - soa.retry = retry; - soa.expire = expire; - soa.minimum = minimum; - dns_name_init(&soa.origin, NULL); - dns_name_clone(origin, &soa.origin); - dns_name_init(&soa.contact, NULL); - dns_name_clone(contact, &soa.contact); - - return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_soa, - &soa, &rdatabuf)); -} - -uint32_t -dns_soa_getserial(dns_rdata_t *rdata) { - return soa_get(rdata, 0); -} -uint32_t -dns_soa_getrefresh(dns_rdata_t *rdata) { - return soa_get(rdata, 4); -} -uint32_t -dns_soa_getretry(dns_rdata_t *rdata) { - return soa_get(rdata, 8); -} -uint32_t -dns_soa_getexpire(dns_rdata_t *rdata) { - return soa_get(rdata, 12); -} -uint32_t -dns_soa_getminimum(dns_rdata_t *rdata) { - return soa_get(rdata, 16); -} - -static void -soa_set(dns_rdata_t *rdata, uint32_t val, int offset) { - INSIST(rdata->type == dns_rdatatype_soa); - INSIST(rdata->length >= 20); - INSIST(offset >= 0 && offset <= 16); - encode_uint32(val, rdata->data + rdata->length - 20 + offset); -} - -void -dns_soa_setserial(uint32_t val, dns_rdata_t *rdata) { - soa_set(rdata, val, 0); -} -void -dns_soa_setrefresh(uint32_t val, dns_rdata_t *rdata) { - soa_set(rdata, val, 4); -} -void -dns_soa_setretry(uint32_t val, dns_rdata_t *rdata) { - soa_set(rdata, val, 8); -} -void -dns_soa_setexpire(uint32_t val, dns_rdata_t *rdata) { - soa_set(rdata, val, 12); -} -void -dns_soa_setminimum(uint32_t val, dns_rdata_t *rdata) { - soa_set(rdata, val, 16); -} diff --git a/lib/dns-pkcs11/spnego.asn1 b/lib/dns-pkcs11/spnego.asn1 deleted file mode 100644 index abf9b76..0000000 --- a/lib/dns-pkcs11/spnego.asn1 +++ /dev/null @@ -1,50 +0,0 @@ --- Copyright (C) The Internet Society 2005. This version of --- this module is part of RFC 4178; see the RFC itself for --- full legal notices. - --- (The above copyright notice is per RFC 3978 5.6 (a), q.v.) - --- This is the SPNEGO ASN.1 module from RFC 4178, tweaked --- to get the Heimdal ASN.1 compiler to accept it. - -SPNEGOASNOneSpec DEFINITIONS ::= BEGIN - -MechType ::= OBJECT IDENTIFIER - -MechTypeList ::= SEQUENCE OF MechType - -ContextFlags ::= BIT STRING { - delegFlag (0), - mutualFlag (1), - replayFlag (2), - sequenceFlag (3), - anonFlag (4), - confFlag (5), - integFlag (6) -} - -NegTokenInit ::= SEQUENCE { - mechTypes [0] MechTypeList, - reqFlags [1] ContextFlags OPTIONAL, - mechToken [2] OCTET STRING OPTIONAL, - mechListMIC [3] OCTET STRING OPTIONAL -} - -NegTokenResp ::= SEQUENCE { - negState [0] ENUMERATED { - accept-completed (0), - accept-incomplete (1), - reject (2), - request-mic (3) - } OPTIONAL, - supportedMech [1] MechType OPTIONAL, - responseToken [2] OCTET STRING OPTIONAL, - mechListMIC [3] OCTET STRING OPTIONAL -} - -NegotiationToken ::= CHOICE { - negTokenInit [0] NegTokenInit, - negTokenResp [1] NegTokenResp -} - -END diff --git a/lib/dns-pkcs11/spnego.c b/lib/dns-pkcs11/spnego.c deleted file mode 100644 index dea108b..0000000 --- a/lib/dns-pkcs11/spnego.c +++ /dev/null @@ -1,1825 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file - * \brief - * Portable SPNEGO implementation. - * - * This is part of a portable implementation of the SPNEGO protocol - * (RFCs 2478 and 4178). This implementation uses the RFC 4178 ASN.1 - * module but is not a full implementation of the RFC 4178 protocol; - * at the moment, we only support GSS-TSIG with Kerberos - * authentication, so we only need enough of the SPNEGO protocol to - * support that. - * - * The files that make up this portable SPNEGO implementation are: - * \li spnego.c (this file) - * \li spnego.h (API SPNEGO exports to the rest of lib/dns) - * \li spnego.asn1 (SPNEGO ASN.1 module) - * \li spnego_asn1.c (routines generated from spngo.asn1) - * \li spnego_asn1.pl (perl script to generate spnego_asn1.c) - * - * Everything but the functions exported in spnego.h is static, to - * avoid possible conflicts with other libraries (particularly Heimdal, - * since much of this code comes from Heimdal by way of mod_auth_kerb). - * - * spnego_asn1.c is shipped as part of lib/dns because generating it - * requires both Perl and the Heimdal ASN.1 compiler. See - * spnego_asn1.pl for further details. We've tried to eliminate all - * compiler warnings from the generated code, but you may see a few - * when using a compiler version we haven't tested yet. - */ - -/* - * Portions of this code were derived from mod_auth_kerb and Heimdal. - * These packages are available from: - * - * http://modauthkerb.sourceforge.net/ - * http://www.pdc.kth.se/heimdal/ - * - * and were released under the following licenses: - * - * ---------------------------------------------------------------- - * - * Copyright (c) 2004 Masarykova universita - * (Masaryk University, Brno, Czech Republic) - * 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. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * ---------------------------------------------------------------- - * - * Copyright (c) 1997 - 2003 Kungliga Tekniska H�gskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -/* - * XXXSRA We should omit this file entirely in Makefile.in via autoconf, - * but this will keep it from generating errors until that's written. - */ - -#ifdef GSSAPI - -/* - * XXXSRA Some of the following files are almost certainly unnecessary, - * but using this list (borrowed from gssapictx.c) gets rid of some - * whacky compilation errors when building with MSVC and should be - * harmless in any case. - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dst_internal.h" - -/* - * The API we export - */ -#include "spnego.h" - -/* asn1_err.h */ -/* Generated from ../../../lib/asn1/asn1_err.et */ - -#ifndef ERROR_TABLE_BASE_asn1 -/* these may be brought in already via gssapi_krb5.h */ -typedef enum asn1_error_number { - ASN1_BAD_TIMEFORMAT = 1859794432, - ASN1_MISSING_FIELD = 1859794433, - ASN1_MISPLACED_FIELD = 1859794434, - ASN1_TYPE_MISMATCH = 1859794435, - ASN1_OVERFLOW = 1859794436, - ASN1_OVERRUN = 1859794437, - ASN1_BAD_ID = 1859794438, - ASN1_BAD_LENGTH = 1859794439, - ASN1_BAD_FORMAT = 1859794440, - ASN1_PARSE_ERROR = 1859794441 -} asn1_error_number; - -#define ERROR_TABLE_BASE_asn1 1859794432 -#endif - -#define __asn1_common_definitions__ - -typedef struct octet_string { - size_t length; - void *data; -} octet_string; - -typedef char *general_string; - -typedef char *utf8_string; - -typedef struct oid { - size_t length; - unsigned *components; -} oid; - -/* der.h */ - -typedef enum { - ASN1_C_UNIV = 0, ASN1_C_APPL = 1, - ASN1_C_CONTEXT = 2, ASN1_C_PRIVATE = 3 -} Der_class; - -typedef enum { - PRIM = 0, CONS = 1 -} Der_type; - -/* Universal tags */ - -enum { - UT_Boolean = 1, - UT_Integer = 2, - UT_BitString = 3, - UT_OctetString = 4, - UT_Null = 5, - UT_OID = 6, - UT_Enumerated = 10, - UT_Sequence = 16, - UT_Set = 17, - UT_PrintableString = 19, - UT_IA5String = 22, - UT_UTCTime = 23, - UT_GeneralizedTime = 24, - UT_VisibleString = 26, - UT_GeneralString = 27 -}; - -#define ASN1_INDEFINITE 0xdce0deed - -static int -der_get_length(const unsigned char *p, size_t len, - size_t * val, size_t * size); - -static int -der_get_octet_string(const unsigned char *p, size_t len, - octet_string * data, size_t * size); -static int -der_get_oid(const unsigned char *p, size_t len, - oid * data, size_t * size); -static int -der_get_tag(const unsigned char *p, size_t len, - Der_class * xclass, Der_type * type, - int *tag, size_t * size); - -static int -der_match_tag(const unsigned char *p, size_t len, - Der_class xclass, Der_type type, - int tag, size_t * size); -static int -der_match_tag_and_length(const unsigned char *p, size_t len, - Der_class xclass, Der_type type, int tag, - size_t * length_ret, size_t * size); - -static int -decode_oid(const unsigned char *p, size_t len, - oid * k, size_t * size); - -static int -decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size); - -static int -decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *); - -static int -der_put_int(unsigned char *p, size_t len, int val, size_t *); - -static int -der_put_length(unsigned char *p, size_t len, size_t val, size_t *); - -static int -der_put_octet_string(unsigned char *p, size_t len, - const octet_string * data, size_t *); -static int -der_put_oid(unsigned char *p, size_t len, - const oid * data, size_t * size); -static int -der_put_tag(unsigned char *p, size_t len, Der_class xclass, Der_type type, - int tag, size_t *); -static int -der_put_length_and_tag(unsigned char *, size_t, size_t, - Der_class, Der_type, int, size_t *); - -static int -encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *); - -static int -encode_octet_string(unsigned char *p, size_t len, - const octet_string * k, size_t *); -static int -encode_oid(unsigned char *p, size_t len, - const oid * k, size_t *); - -static void -free_octet_string(octet_string * k); - -static void -free_oid (oid * k); - -static size_t -length_len(size_t len); - -static int -fix_dce(size_t reallen, size_t * len); - -/* - * Include stuff generated by the ASN.1 compiler. - */ - -#include "spnego_asn1.c" - -/* - * Force the oid arrays to be uint64_t aligned to silence warnings - * about the arrays not being properly aligned for (void *). - */ -typedef union { unsigned char b[8]; uint64_t _align; } aligned8; -typedef union { unsigned char b[16]; uint64_t _align[2]; } aligned16; - -static aligned16 gss_krb5_mech_oid_bytes = { - { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 } -}; - -static gss_OID_desc gss_krb5_mech_oid_desc = { - 9, gss_krb5_mech_oid_bytes.b -}; - -static gss_OID GSS_KRB5_MECH = &gss_krb5_mech_oid_desc; - -static aligned16 gss_mskrb5_mech_oid_bytes = { - { 0x2a, 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02 } -}; - -static gss_OID_desc gss_mskrb5_mech_oid_desc = { - 9, gss_mskrb5_mech_oid_bytes.b -}; - -static gss_OID GSS_MSKRB5_MECH = &gss_mskrb5_mech_oid_desc; - -static aligned8 gss_spnego_mech_oid_bytes = { - { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 } -}; - -static gss_OID_desc gss_spnego_mech_oid_desc = { - 6, gss_spnego_mech_oid_bytes.b -}; - -static gss_OID GSS_SPNEGO_MECH = &gss_spnego_mech_oid_desc; - -/* spnegokrb5_locl.h */ - -static OM_uint32 -gssapi_spnego_encapsulate(OM_uint32 *, - unsigned char *, - size_t, - gss_buffer_t, - const gss_OID); - -static OM_uint32 -gssapi_spnego_decapsulate(OM_uint32 *, - gss_buffer_t, - unsigned char **, - size_t *, - const gss_OID); - -/* mod_auth_kerb.c */ - -static int -cmp_gss_type(gss_buffer_t token, gss_OID gssoid) -{ - unsigned char *p; - size_t len; - - if (token->length == 0U) - return (GSS_S_DEFECTIVE_TOKEN); - - p = token->value; - if (*p++ != 0x60) - return (GSS_S_DEFECTIVE_TOKEN); - len = *p++; - if (len & 0x80) { - if ((len & 0x7f) > 4U) - return (GSS_S_DEFECTIVE_TOKEN); - p += len & 0x7f; - } - if (*p++ != 0x06) - return (GSS_S_DEFECTIVE_TOKEN); - - if (((OM_uint32) *p++) != gssoid->length) - return (GSS_S_DEFECTIVE_TOKEN); - - return (isc_safe_memcompare(p, gssoid->elements, gssoid->length)); -} - -/* accept_sec_context.c */ -/* - * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly - * based on Heimdal code) - */ - -static OM_uint32 -code_NegTokenArg(OM_uint32 * minor_status, - const NegTokenResp * resp, - unsigned char **outbuf, - size_t * outbuf_size) -{ - OM_uint32 ret; - u_char *buf; - size_t buf_size, buf_len = 0; - - buf_size = 1024; - buf = malloc(buf_size); - if (buf == NULL) { - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - do { - ret = encode_NegTokenResp(buf + buf_size - 1, - buf_size, - resp, &buf_len); - if (ret == 0) { - size_t tmp; - - ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, - buf_size - buf_len, - buf_len, - ASN1_C_CONTEXT, - CONS, - 1, - &tmp); - if (ret == 0) - buf_len += tmp; - } - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc(buf, buf_size); - if (tmp == NULL) { - *minor_status = ENOMEM; - free(buf); - return (GSS_S_FAILURE); - } - buf = tmp; - } else { - *minor_status = ret; - free(buf); - return (GSS_S_FAILURE); - } - } - } while (ret == ASN1_OVERFLOW); - - *outbuf = malloc(buf_len); - if (*outbuf == NULL) { - *minor_status = ENOMEM; - free(buf); - return (GSS_S_FAILURE); - } - memmove(*outbuf, buf + buf_size - buf_len, buf_len); - *outbuf_size = buf_len; - - free(buf); - - return (GSS_S_COMPLETE); -} - -static OM_uint32 -send_reject(OM_uint32 * minor_status, - gss_buffer_t output_token) -{ - NegTokenResp resp; - OM_uint32 ret; - - resp.negState = malloc(sizeof(*resp.negState)); - if (resp.negState == NULL) { - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - *(resp.negState) = reject; - - resp.supportedMech = NULL; - resp.responseToken = NULL; - resp.mechListMIC = NULL; - - ret = code_NegTokenArg(minor_status, &resp, - (unsigned char **)&output_token->value, - &output_token->length); - free_NegTokenResp(&resp); - if (ret) - return (ret); - - return (GSS_S_BAD_MECH); -} - -static OM_uint32 -send_accept(OM_uint32 * minor_status, - gss_buffer_t output_token, - gss_buffer_t mech_token, - const gss_OID pref) -{ - NegTokenResp resp; - OM_uint32 ret; - - memset(&resp, 0, sizeof(resp)); - resp.negState = malloc(sizeof(*resp.negState)); - if (resp.negState == NULL) { - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - *(resp.negState) = accept_completed; - - resp.supportedMech = malloc(sizeof(*resp.supportedMech)); - if (resp.supportedMech == NULL) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - ret = der_get_oid(pref->elements, - pref->length, - resp.supportedMech, - NULL); - if (ret) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - if (mech_token != NULL && mech_token->length != 0U) { - resp.responseToken = malloc(sizeof(*resp.responseToken)); - if (resp.responseToken == NULL) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - resp.responseToken->length = mech_token->length; - resp.responseToken->data = mech_token->value; - } - - ret = code_NegTokenArg(minor_status, &resp, - (unsigned char **)&output_token->value, - &output_token->length); - if (resp.responseToken != NULL) { - free(resp.responseToken); - resp.responseToken = NULL; - } - free_NegTokenResp(&resp); - if (ret) - return (ret); - - return (GSS_S_COMPLETE); -} - -OM_uint32 -gss_accept_sec_context_spnego(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t *src_name, - gss_OID *mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec, - gss_cred_id_t *delegated_cred_handle) -{ - NegTokenInit init_token; - OM_uint32 major_status = GSS_S_COMPLETE; - OM_uint32 minor_status2; - gss_buffer_desc ibuf, obuf; - gss_buffer_t ot = NULL; - gss_OID pref = GSS_KRB5_MECH; - unsigned char *buf; - size_t buf_size; - size_t len, taglen, ni_len; - int found = 0; - int ret; - unsigned i; - - /* - * Before doing anything else, see whether this is a SPNEGO - * PDU. If not, dispatch to the GSSAPI library and get out. - */ - - if (cmp_gss_type(input_token_buffer, GSS_SPNEGO_MECH)) - return (gss_accept_sec_context(minor_status, - context_handle, - acceptor_cred_handle, - input_token_buffer, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle)); - - /* - * If we get here, it's SPNEGO. - */ - - memset(&init_token, 0, sizeof(init_token)); - - ret = gssapi_spnego_decapsulate(minor_status, input_token_buffer, - &buf, &buf_size, GSS_SPNEGO_MECH); - if (ret) - return (ret); - - ret = der_match_tag_and_length(buf, buf_size, ASN1_C_CONTEXT, CONS, - 0, &len, &taglen); - if (ret) - return (ret); - - ret = decode_NegTokenInit(buf + taglen, len, &init_token, &ni_len); - if (ret) { - *minor_status = EINVAL; /* XXX */ - return (GSS_S_DEFECTIVE_TOKEN); - } - - for (i = 0; !found && i < init_token.mechTypes.len; ++i) { - unsigned char mechbuf[17]; - size_t mech_len; - - ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1, - sizeof(mechbuf), - &init_token.mechTypes.val[i], - &mech_len); - if (ret) { - free_NegTokenInit(&init_token); - return (GSS_S_DEFECTIVE_TOKEN); - } - if (mech_len == GSS_KRB5_MECH->length && - isc_safe_memequal(GSS_KRB5_MECH->elements, - mechbuf + sizeof(mechbuf) - mech_len, - mech_len)) - { - found = 1; - break; - } - if (mech_len == GSS_MSKRB5_MECH->length && - isc_safe_memequal(GSS_MSKRB5_MECH->elements, - mechbuf + sizeof(mechbuf) - mech_len, - mech_len)) - { - found = 1; - if (i == 0) - pref = GSS_MSKRB5_MECH; - break; - } - } - - if (!found) { - free_NegTokenInit(&init_token); - return (send_reject(minor_status, output_token)); - } - - if (i == 0 && init_token.mechToken != NULL) { - ibuf.length = init_token.mechToken->length; - ibuf.value = init_token.mechToken->data; - - major_status = gss_accept_sec_context(minor_status, - context_handle, - acceptor_cred_handle, - &ibuf, - input_chan_bindings, - src_name, - mech_type, - &obuf, - ret_flags, - time_rec, - delegated_cred_handle); - if (GSS_ERROR(major_status)) { - free_NegTokenInit(&init_token); - send_reject(&minor_status2, output_token); - return (major_status); - } - ot = &obuf; - } - ret = send_accept(&minor_status2, output_token, ot, pref); - free_NegTokenInit(&init_token); - if (ot != NULL && ot->length != 0U) - gss_release_buffer(&minor_status2, ot); - - return (ret != GSS_S_COMPLETE ? (OM_uint32) ret : major_status); -} - -/* decapsulate.c */ - -static OM_uint32 -gssapi_verify_mech_header(u_char ** str, - size_t total_len, - const gss_OID mech) -{ - size_t len, len_len, mech_len, foo; - int e; - u_char *p = *str; - - if (total_len < 1U) - return (GSS_S_DEFECTIVE_TOKEN); - if (*p++ != 0x60) - return (GSS_S_DEFECTIVE_TOKEN); - e = der_get_length(p, total_len - 1, &len, &len_len); - if (e || 1 + len_len + len != total_len) - return (GSS_S_DEFECTIVE_TOKEN); - p += len_len; - if (*p++ != 0x06) - return (GSS_S_DEFECTIVE_TOKEN); - e = der_get_length(p, total_len - 1 - len_len - 1, - &mech_len, &foo); - if (e) - return (GSS_S_DEFECTIVE_TOKEN); - p += foo; - if (mech_len != mech->length) - return (GSS_S_BAD_MECH); - if (!isc_safe_memequal(p, mech->elements, mech->length)) - return (GSS_S_BAD_MECH); - p += mech_len; - *str = p; - return (GSS_S_COMPLETE); -} - -/* - * Remove the GSS-API wrapping from `in_token' giving `buf and buf_size' Does - * not copy data, so just free `in_token'. - */ - -static OM_uint32 -gssapi_spnego_decapsulate(OM_uint32 *minor_status, - gss_buffer_t input_token_buffer, - unsigned char **buf, - size_t *buf_len, - const gss_OID mech) -{ - u_char *p; - OM_uint32 ret; - - p = input_token_buffer->value; - ret = gssapi_verify_mech_header(&p, - input_token_buffer->length, - mech); - if (ret) { - *minor_status = ret; - return (GSS_S_FAILURE); - } - *buf_len = input_token_buffer->length - - (p - (u_char *) input_token_buffer->value); - *buf = p; - return (GSS_S_COMPLETE); -} - -/* der_free.c */ - -static void -free_octet_string(octet_string *k) -{ - free(k->data); - k->data = NULL; -} - -static void -free_oid(oid *k) -{ - free(k->components); - k->components = NULL; -} - -/* der_get.c */ - -/* - * All decoding functions take a pointer `p' to first position in which to - * read, from the left, `len' which means the maximum number of characters we - * are able to read, `ret' were the value will be returned and `size' where - * the number of used bytes is stored. Either 0 or an error code is returned. - */ - -static int -der_get_unsigned(const unsigned char *p, size_t len, - unsigned *ret, size_t *size) -{ - unsigned val = 0; - size_t oldlen = len; - - while (len--) - val = val * 256 + *p++; - *ret = val; - if (size) - *size = oldlen; - return (0); -} - -static int -der_get_int(const unsigned char *p, size_t len, - int *ret, size_t *size) -{ - int val = 0; - size_t oldlen = len; - - if (len > 0U) { - val = (signed char)*p++; - while (--len) - val = val * 256 + *p++; - } - *ret = val; - if (size) - *size = oldlen; - return (0); -} - -static int -der_get_length(const unsigned char *p, size_t len, - size_t *val, size_t *size) -{ - size_t v; - - if (len <= 0U) - return (ASN1_OVERRUN); - --len; - v = *p++; - if (v < 128U) { - *val = v; - if (size) - *size = 1; - } else { - int e; - size_t l; - unsigned tmp; - - if (v == 0x80U) { - *val = ASN1_INDEFINITE; - if (size) - *size = 1; - return (0); - } - v &= 0x7F; - if (len < v) - return (ASN1_OVERRUN); - e = der_get_unsigned(p, v, &tmp, &l); - if (e) - return (e); - *val = tmp; - if (size) - *size = l + 1; - } - return (0); -} - -static int -der_get_octet_string(const unsigned char *p, size_t len, - octet_string *data, size_t *size) -{ - data->length = len; - if (len != 0U) { - data->data = malloc(len); - if (data->data == NULL) - return (ENOMEM); - memmove(data->data, p, len); - } else - data->data = NULL; - if (size) - *size = len; - return (0); -} - -static int -der_get_oid(const unsigned char *p, size_t len, oid *data, size_t *size) { - int n; - size_t oldlen = len; - - data->components = NULL; - data->length = 0; - if (len < 1U) { - return (ASN1_OVERRUN); - } - - data->components = malloc(len * sizeof(*data->components)); - if (data->components == NULL) { - return (ENOMEM); - } - data->components[0] = (*p) / 40; - data->components[1] = (*p) % 40; - --len; - ++p; - for (n = 2; len > 0U; ++n) { - unsigned u = 0; - - do { - --len; - u = u * 128 + (*p++ % 128); - } while (len > 0U && p[-1] & 0x80); - data->components[n] = u; - } - if (p[-1] & 0x80) { - free_oid(data); - return (ASN1_OVERRUN); - } - data->length = n; - if (size) { - *size = oldlen; - } - return (0); -} - -static int -der_get_tag(const unsigned char *p, size_t len, - Der_class *xclass, Der_type *type, - int *tag, size_t *size) -{ - if (len < 1U) - return (ASN1_OVERRUN); - *xclass = (Der_class) (((*p) >> 6) & 0x03); - *type = (Der_type) (((*p) >> 5) & 0x01); - *tag = (*p) & 0x1F; - if (size) - *size = 1; - return (0); -} - -static int -der_match_tag(const unsigned char *p, size_t len, - Der_class xclass, Der_type type, - int tag, size_t *size) -{ - size_t l; - Der_class thisclass; - Der_type thistype; - int thistag; - int e; - - e = der_get_tag(p, len, &thisclass, &thistype, &thistag, &l); - if (e) - return (e); - if (xclass != thisclass || type != thistype) - return (ASN1_BAD_ID); - if (tag > thistag) - return (ASN1_MISPLACED_FIELD); - if (tag < thistag) - return (ASN1_MISSING_FIELD); - if (size) - *size = l; - return (0); -} - -static int -der_match_tag_and_length(const unsigned char *p, size_t len, - Der_class xclass, Der_type type, int tag, - size_t *length_ret, size_t *size) -{ - size_t l, ret = 0; - int e; - - e = der_match_tag(p, len, xclass, type, tag, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, length_ret, &l); - if (e) - return (e); - /* p += l; */ - len -= l; - POST(len); - ret += l; - if (size) - *size = ret; - return (0); -} - -static int -decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size) -{ - size_t ret = 0; - size_t l, reallen; - int e; - - e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &reallen, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - e = der_get_int(p, reallen, num, &l); - if (e) - return (e); - p += l; - len -= l; - POST(p); POST(len); - ret += l; - if (size) - *size = ret; - return (0); -} - -static int -decode_octet_string(const unsigned char *p, size_t len, - octet_string *k, size_t *size) -{ - size_t ret = 0; - size_t l; - int e; - size_t slen; - - k->data = NULL; - k->length = 0; - - e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - - e = der_get_length(p, len, &slen, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - if (len < slen) - return (ASN1_OVERRUN); - - e = der_get_octet_string(p, slen, k, &l); - if (e) - return (e); - p += l; - len -= l; - POST(p); POST(len); - ret += l; - if (size) - *size = ret; - return (0); -} - -static int -decode_oid(const unsigned char *p, size_t len, - oid *k, size_t *size) -{ - size_t ret = 0; - size_t l; - int e; - size_t slen; - - e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OID, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - - e = der_get_length(p, len, &slen, &l); - if (e) - return (e); - p += l; - len -= l; - ret += l; - if (len < slen) - return (ASN1_OVERRUN); - - e = der_get_oid(p, slen, k, &l); - if (e) - return (e); - p += l; - len -= l; - POST(p); POST(len); - ret += l; - if (size) - *size = ret; - return (0); -} - -static int -fix_dce(size_t reallen, size_t *len) -{ - if (reallen == ASN1_INDEFINITE) - return (1); - if (*len < reallen) - return (-1); - *len = reallen; - return (0); -} - -/* der_length.c */ - -static size_t -len_unsigned(unsigned val) -{ - size_t ret = 0; - - do { - ++ret; - val /= 256; - } while (val); - return (ret); -} - -static size_t -length_len(size_t len) -{ - if (len < 128U) - return (1); - else - return (len_unsigned((unsigned int)len) + 1); -} - - -/* der_put.c */ - -/* - * All encoding functions take a pointer `p' to first position in which to - * write, from the right, `len' which means the maximum number of characters - * we are able to write. The function returns the number of characters - * written in `size' (if non-NULL). The return value is 0 or an error. - */ - -static int -der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t *size) -{ - unsigned char *base = p; - - if (val) { - while (len > 0U && val) { - *p-- = val % 256; - val /= 256; - --len; - } - if (val != 0) - return (ASN1_OVERFLOW); - else { - *size = base - p; - return (0); - } - } else if (len < 1U) - return (ASN1_OVERFLOW); - else { - *p = 0; - *size = 1; - return (0); - } -} - -static int -der_put_int(unsigned char *p, size_t len, int val, size_t *size) -{ - unsigned char *base = p; - - if (val >= 0) { - do { - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = val % 256; - len--; - val /= 256; - } while (val); - if (p[1] >= 128) { - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = 0; - len--; - POST(len); - } - } else { - val = ~val; - do { - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = ~(val % 256); - len--; - val /= 256; - } while (val); - if (p[1] < 128) { - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = 0xff; - len--; - POST(len); - } - } - *size = base - p; - return (0); -} - -static int -der_put_length(unsigned char *p, size_t len, size_t val, size_t *size) -{ - if (len < 1U) - return (ASN1_OVERFLOW); - if (val < 128U) { - *p = (unsigned char)val; - *size = 1; - return (0); - } else { - size_t l; - int e; - - e = der_put_unsigned(p, len - 1, (unsigned int)val, &l); - if (e) - return (e); - p -= l; - *p = 0x80 | (unsigned char)l; - *size = l + 1; - return (0); - } -} - -static int -der_put_octet_string(unsigned char *p, size_t len, - const octet_string *data, size_t *size) -{ - if (len < data->length) - return (ASN1_OVERFLOW); - p -= data->length; - len -= data->length; - POST(len); - memmove(p + 1, data->data, data->length); - *size = data->length; - return (0); -} - -static int -der_put_oid(unsigned char *p, size_t len, - const oid *data, size_t *size) -{ - unsigned char *base = p; - size_t n; - - for (n = data->length; n >= 3u; --n) { - unsigned u = data->components[n - 1]; - - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = u % 128; - u /= 128; - --len; - while (u > 0) { - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = 128 + u % 128; - u /= 128; - --len; - } - } - if (len < 1U) - return (ASN1_OVERFLOW); - *p-- = 40 * data->components[0] + data->components[1]; - *size = base - p; - return (0); -} - -static int -der_put_tag(unsigned char *p, size_t len, Der_class xclass, Der_type type, - int tag, size_t *size) -{ - if (len < 1U) - return (ASN1_OVERFLOW); - *p = (xclass << 6) | (type << 5) | tag; /* XXX */ - *size = 1; - return (0); -} - -static int -der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val, - Der_class xclass, Der_type type, int tag, size_t *size) -{ - size_t ret = 0; - size_t l; - int e; - - e = der_put_length(p, len, len_val, &l); - if (e) - return (e); - p -= l; - len -= l; - ret += l; - e = der_put_tag(p, len, xclass, type, tag, &l); - if (e) - return (e); - p -= l; - len -= l; - POST(p); POST(len); - ret += l; - *size = ret; - return (0); -} - -static int -encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size) -{ - unsigned num = *(const unsigned *)data; - size_t ret = 0; - size_t l; - int e; - - e = der_put_int(p, len, num, &l); - if (e) - return (e); - p -= l; - len -= l; - ret += l; - e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l); - if (e) - return (e); - p -= l; - len -= l; - POST(p); POST(len); - ret += l; - *size = ret; - return (0); -} - -static int -encode_octet_string(unsigned char *p, size_t len, - const octet_string *k, size_t *size) -{ - size_t ret = 0; - size_t l; - int e; - - e = der_put_octet_string(p, len, k, &l); - if (e) - return (e); - p -= l; - len -= l; - ret += l; - e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l); - if (e) - return (e); - p -= l; - len -= l; - POST(p); POST(len); - ret += l; - *size = ret; - return (0); -} - -static int -encode_oid(unsigned char *p, size_t len, - const oid *k, size_t *size) -{ - size_t ret = 0; - size_t l; - int e; - - e = der_put_oid(p, len, k, &l); - if (e) - return (e); - p -= l; - len -= l; - ret += l; - e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l); - if (e) - return (e); - p -= l; - len -= l; - POST(p); POST(len); - ret += l; - *size = ret; - return (0); -} - - -/* encapsulate.c */ - -static void -gssapi_encap_length(size_t data_len, - size_t *len, - size_t *total_len, - const gss_OID mech) -{ - size_t len_len; - - *len = 1 + 1 + mech->length + data_len; - - len_len = length_len(*len); - - *total_len = 1 + len_len + *len; -} - -static u_char * -gssapi_mech_make_header(u_char *p, - size_t len, - const gss_OID mech) -{ - int e; - size_t len_len, foo; - - *p++ = 0x60; - len_len = length_len(len); - e = der_put_length(p + len_len - 1, len_len, len, &foo); - if (e || foo != len_len) - return (NULL); - p += len_len; - *p++ = 0x06; - *p++ = mech->length; - memmove(p, mech->elements, mech->length); - p += mech->length; - return (p); -} - -/* - * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings. - */ - -static OM_uint32 -gssapi_spnego_encapsulate(OM_uint32 * minor_status, - unsigned char *buf, - size_t buf_size, - gss_buffer_t output_token, - const gss_OID mech) -{ - size_t len, outer_len; - u_char *p; - - gssapi_encap_length(buf_size, &len, &outer_len, mech); - - output_token->length = outer_len; - output_token->value = malloc(outer_len); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - p = gssapi_mech_make_header(output_token->value, len, mech); - if (p == NULL) { - if (output_token->length != 0U) - gss_release_buffer(minor_status, output_token); - return (GSS_S_FAILURE); - } - memmove(p, buf, buf_size); - return (GSS_S_COMPLETE); -} - -/* init_sec_context.c */ -/* - * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly - * based on Heimdal code) - */ - -static int -add_mech(MechTypeList * mech_list, gss_OID mech) -{ - MechType *tmp; - int ret; - - tmp = realloc(mech_list->val, (mech_list->len + 1) * sizeof(*tmp)); - if (tmp == NULL) - return (ENOMEM); - mech_list->val = tmp; - - ret = der_get_oid(mech->elements, mech->length, - &mech_list->val[mech_list->len], NULL); - if (ret) - return (ret); - - mech_list->len++; - return (0); -} - -/* - * return the length of the mechanism in token or -1 - * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN - */ - -static ssize_t -gssapi_krb5_get_mech(const u_char *ptr, - size_t total_len, - const u_char **mech_ret) -{ - size_t len, len_len, mech_len, foo; - const u_char *p = ptr; - int e; - - if (total_len < 1U) - return (-1); - if (*p++ != 0x60) - return (-1); - e = der_get_length (p, total_len - 1, &len, &len_len); - if (e || 1 + len_len + len != total_len) - return (-1); - p += len_len; - if (*p++ != 0x06) - return (-1); - e = der_get_length (p, total_len - 1 - len_len - 1, - &mech_len, &foo); - if (e) - return (-1); - p += foo; - *mech_ret = p; - return (mech_len); -} - -static OM_uint32 -spnego_initial(OM_uint32 *minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t *context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec) -{ - NegTokenInit token_init; - OM_uint32 major_status, minor_status2; - gss_buffer_desc krb5_output_token = GSS_C_EMPTY_BUFFER; - unsigned char *buf = NULL; - size_t buf_size; - size_t len = 0; - int ret; - - (void)mech_type; - - memset(&token_init, 0, sizeof(token_init)); - - ret = add_mech(&token_init.mechTypes, GSS_KRB5_MECH); - if (ret) { - *minor_status = ret; - ret = GSS_S_FAILURE; - goto end; - } - - major_status = gss_init_sec_context(minor_status, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECH, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - &krb5_output_token, - ret_flags, - time_rec); - if (GSS_ERROR(major_status)) { - ret = major_status; - goto end; - } - if (krb5_output_token.length > 0U) { - token_init.mechToken = malloc(sizeof(*token_init.mechToken)); - if (token_init.mechToken == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - goto end; - } - token_init.mechToken->data = krb5_output_token.value; - token_init.mechToken->length = krb5_output_token.length; - } - /* - * The MS implementation of SPNEGO seems to not like the mechListMIC - * field, so we omit it (it's optional anyway) - */ - - buf_size = 1024; - buf = malloc(buf_size); - if (buf == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - goto end; - } - - do { - ret = encode_NegTokenInit(buf + buf_size - 1, - buf_size, - &token_init, &len); - if (ret == 0) { - size_t tmp; - - ret = der_put_length_and_tag(buf + buf_size - len - 1, - buf_size - len, - len, - ASN1_C_CONTEXT, - CONS, - 0, - &tmp); - if (ret == 0) - len += tmp; - } - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc(buf, buf_size); - if (tmp == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - goto end; - } - buf = tmp; - } else { - *minor_status = ret; - ret = GSS_S_FAILURE; - goto end; - } - } - } while (ret == ASN1_OVERFLOW); - - ret = gssapi_spnego_encapsulate(minor_status, - buf + buf_size - len, len, - output_token, GSS_SPNEGO_MECH); - if (ret == GSS_S_COMPLETE) - ret = major_status; - -end: - if (token_init.mechToken != NULL) { - free(token_init.mechToken); - token_init.mechToken = NULL; - } - free_NegTokenInit(&token_init); - if (krb5_output_token.length != 0U) - gss_release_buffer(&minor_status2, &krb5_output_token); - if (buf) - free(buf); - - return (ret); -} - -static OM_uint32 -spnego_reply(OM_uint32 *minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t *context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec) -{ - OM_uint32 ret; - NegTokenResp resp; - unsigned char *buf; - size_t buf_size; - u_char oidbuf[17]; - size_t oidlen; - gss_buffer_desc sub_token; - ssize_t mech_len; - const u_char *p; - size_t len, taglen; - - (void)mech_type; - - output_token->length = 0; - output_token->value = NULL; - - /* - * SPNEGO doesn't include gss wrapping on SubsequentContextToken - * like the Kerberos 5 mech does. But lets check for it anyway. - */ - - mech_len = gssapi_krb5_get_mech(input_token->value, - input_token->length, - &p); - - if (mech_len < 0) { - buf = input_token->value; - buf_size = input_token->length; - } else if ((size_t)mech_len == GSS_KRB5_MECH->length && - isc_safe_memequal(GSS_KRB5_MECH->elements, p, mech_len)) - return (gss_init_sec_context(minor_status, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECH, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec)); - else if ((size_t)mech_len == GSS_SPNEGO_MECH->length && - isc_safe_memequal(GSS_SPNEGO_MECH->elements, p, mech_len)) { - ret = gssapi_spnego_decapsulate(minor_status, - input_token, - &buf, - &buf_size, - GSS_SPNEGO_MECH); - if (ret) - return (ret); - } else - return (GSS_S_BAD_MECH); - - ret = der_match_tag_and_length(buf, buf_size, - ASN1_C_CONTEXT, CONS, 1, &len, &taglen); - if (ret) - return (ret); - - if(len > buf_size - taglen) - return (ASN1_OVERRUN); - - ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL); - if (ret) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - - if (resp.negState == NULL || - *(resp.negState) == reject || - resp.supportedMech == NULL) { - free_NegTokenResp(&resp); - return (GSS_S_BAD_MECH); - } - - ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1, - sizeof(oidbuf), - resp.supportedMech, - &oidlen); - if (ret || oidlen != GSS_KRB5_MECH->length || - !isc_safe_memequal(oidbuf + sizeof(oidbuf) - oidlen, - GSS_KRB5_MECH->elements, oidlen)) - { - free_NegTokenResp(&resp); - return GSS_S_BAD_MECH; - } - - if (resp.responseToken != NULL) { - sub_token.length = resp.responseToken->length; - sub_token.value = resp.responseToken->data; - } else { - sub_token.length = 0; - sub_token.value = NULL; - } - - ret = gss_init_sec_context(minor_status, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECH, - req_flags, - time_req, - input_chan_bindings, - &sub_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - if (ret) { - free_NegTokenResp(&resp); - return (ret); - } - - /* - * XXXSRA I don't think this limited implementation ever needs - * to check the MIC -- our preferred mechanism (Kerberos) - * authenticates its own messages and is the only mechanism - * we'll accept, so if the mechanism negotiation completes - * successfully, we don't need the MIC. See RFC 4178. - */ - - free_NegTokenResp(&resp); - return (ret); -} - - - -OM_uint32 -gss_init_sec_context_spnego(OM_uint32 *minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t *context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec) -{ - /* Dirty trick to suppress compiler warnings */ - - /* Figure out whether we're starting over or processing a reply */ - - if (input_token == GSS_C_NO_BUFFER || input_token->length == 0U) - return (spnego_initial(minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec)); - else - return (spnego_reply(minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec)); -} - -#endif /* GSSAPI */ diff --git a/lib/dns-pkcs11/spnego.h b/lib/dns-pkcs11/spnego.h deleted file mode 100644 index 9c99835..0000000 --- a/lib/dns-pkcs11/spnego.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file - * \brief - * Entry points into portable SPNEGO implementation. - * See spnego.c for information on the SPNEGO implementation itself. - */ - -#ifndef _SPNEGO_H_ -#define _SPNEGO_H_ - -/*% - * Wrapper for GSSAPI gss_init_sec_context(), using portable SPNEGO - * implementation instead of the one that's part of the GSSAPI - * library. Takes arguments identical to the standard GSSAPI - * function, uses standard gss_init_sec_context() to handle - * everything inside the SPNEGO wrapper. - */ -OM_uint32 -gss_init_sec_context_spnego(OM_uint32 *, - const gss_cred_id_t, - gss_ctx_id_t *, - const gss_name_t, - const gss_OID, - OM_uint32, - OM_uint32, - const gss_channel_bindings_t, - const gss_buffer_t, - gss_OID *, - gss_buffer_t, - OM_uint32 *, - OM_uint32 *); - -/*% - * Wrapper for GSSAPI gss_accept_sec_context(), using portable SPNEGO - * implementation instead of the one that's part of the GSSAPI - * library. Takes arguments identical to the standard GSSAPI - * function. Checks the OID of the input token to see if it's SPNEGO; - * if so, processes it, otherwise hands the call off to the standard - * gss_accept_sec_context() function. - */ -OM_uint32 gss_accept_sec_context_spnego(OM_uint32 *, - gss_ctx_id_t *, - const gss_cred_id_t, - const gss_buffer_t, - const gss_channel_bindings_t, - gss_name_t *, - gss_OID *, - gss_buffer_t, - OM_uint32 *, - OM_uint32 *, - gss_cred_id_t *); - - -#endif diff --git a/lib/dns-pkcs11/spnego_asn1.c b/lib/dns-pkcs11/spnego_asn1.c deleted file mode 100644 index 24f0cfb..0000000 --- a/lib/dns-pkcs11/spnego_asn1.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file - * \brief Method routines generated from SPNEGO ASN.1 module. - * See spnego_asn1.pl for details. Do not edit. - */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - -#ifndef __asn1_h__ -#define __asn1_h__ - - -#ifndef __asn1_common_definitions__ -#define __asn1_common_definitions__ - -typedef struct octet_string { - size_t length; - void *data; -} octet_string; - -typedef char *general_string; - -typedef char *utf8_string; - -typedef struct oid { - size_t length; - unsigned *components; -} oid; - -#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \ - do { \ - (BL) = length_##T((S)); \ - (B) = malloc((BL)); \ - if((B) == NULL) { \ - (R) = ENOMEM; \ - } else { \ - (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ - (S), (L)); \ - if((R) != 0) { \ - free((B)); \ - (B) = NULL; \ - } \ - } \ - } while (0) - -#endif - -/* - * MechType ::= OBJECT IDENTIFIER - */ - -typedef oid MechType; - -static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *); -static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *); -static void free_MechType(MechType *); -/* unused declaration: length_MechType */ -/* unused declaration: copy_MechType */ - - -/* - * MechTypeList ::= SEQUENCE OF MechType - */ - -typedef struct MechTypeList { - unsigned int len; - MechType *val; -} MechTypeList; - -static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *); -static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *); -static void free_MechTypeList(MechTypeList *); -/* unused declaration: length_MechTypeList */ -/* unused declaration: copy_MechTypeList */ - - -/* - * ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2), - * sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) } - */ - -typedef struct ContextFlags { - unsigned int delegFlag:1; - unsigned int mutualFlag:1; - unsigned int replayFlag:1; - unsigned int sequenceFlag:1; - unsigned int anonFlag:1; - unsigned int confFlag:1; - unsigned int integFlag:1; -} ContextFlags; - - -static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *); -static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *); -static void free_ContextFlags(ContextFlags *); -/* unused declaration: length_ContextFlags */ -/* unused declaration: copy_ContextFlags */ -/* unused declaration: ContextFlags2int */ -/* unused declaration: int2ContextFlags */ -/* unused declaration: asn1_ContextFlags_units */ - -/* - * NegTokenInit ::= SEQUENCE { mechTypes[0] MechTypeList, reqFlags[1] - * ContextFlags OPTIONAL, mechToken[2] OCTET STRING OPTIONAL, - * mechListMIC[3] OCTET STRING OPTIONAL } - */ - -typedef struct NegTokenInit { - MechTypeList mechTypes; - ContextFlags *reqFlags; - octet_string *mechToken; - octet_string *mechListMIC; -} NegTokenInit; - -static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *); -static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *); -static void free_NegTokenInit(NegTokenInit *); -/* unused declaration: length_NegTokenInit */ -/* unused declaration: copy_NegTokenInit */ - - -/* - * NegTokenResp ::= SEQUENCE { negState[0] ENUMERATED { - * accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) } - * OPTIONAL, supportedMech[1] MechType OPTIONAL, responseToken[2] OCTET - * STRING OPTIONAL, mechListMIC[3] OCTET STRING OPTIONAL } - */ - -typedef struct NegTokenResp { - enum { - accept_completed = 0, - accept_incomplete = 1, - reject = 2, - request_mic = 3 - } *negState; - - MechType *supportedMech; - octet_string *responseToken; - octet_string *mechListMIC; -} NegTokenResp; - -static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *); -static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *); -static void free_NegTokenResp(NegTokenResp *); -/* unused declaration: length_NegTokenResp */ -/* unused declaration: copy_NegTokenResp */ - - - - -#endif /* __asn1_h__ */ -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -#define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret) - -static int -encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int e; - - e = encode_oid(p, len, data, &l); - BACK; - *size = ret; - return 0; -} - -#define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret) - -static int -decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int e; - - memset(data, 0, sizeof(*data)); - e = decode_oid(p, len, data, &l); - FORW; - if (size) - *size = ret; - return 0; -fail: - free_MechType(data); - return e; -} - -static void -free_MechType(MechType * data) -{ - free_oid(data); -} - -/* unused function: length_MechType */ - - -/* unused function: copy_MechType */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -static int -encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int i, e; - - for (i = (data)->len - 1; i >= 0; --i) { - size_t oldret = ret; - ret = 0; - e = encode_MechType(p, len, &(data)->val[i], &l); - BACK; - ret += oldret; - } - e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); - BACK; - *size = ret; - return 0; -} - -static int -decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size) -{ - size_t ret = 0, reallen; - size_t l; - int e; - - memset(data, 0, sizeof(*data)); - reallen = 0; - e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); - FORW; - if (len < reallen) - return ASN1_OVERRUN; - len = reallen; - { - size_t origlen = len; - size_t oldret = ret; - ret = 0; - (data)->len = 0; - (data)->val = NULL; - while (ret < origlen) { - void *old = (data)->val; - (data)->len++; - (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len); - if ((data)->val == NULL) { - (data)->val = old; - (data)->len--; - return ENOMEM; - } - e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l); - FORW; - len = origlen - ret; - } - ret += oldret; - } - if (size) - *size = ret; - return 0; -fail: - free_MechTypeList(data); - return e; -} - -static void -free_MechTypeList(MechTypeList * data) -{ - while ((data)->len) { - free_MechType(&(data)->val[(data)->len - 1]); - (data)->len--; - } - free((data)->val); - (data)->val = NULL; -} - -/* unused function: length_MechTypeList */ - - -/* unused function: copy_MechTypeList */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -static int -encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int e; - - { - unsigned char c = 0; - *p-- = c; - len--; - ret++; - c = 0; - *p-- = c; - len--; - ret++; - c = 0; - *p-- = c; - len--; - ret++; - c = 0; - if (data->integFlag) - c |= 1 << 1; - if (data->confFlag) - c |= 1 << 2; - if (data->anonFlag) - c |= 1 << 3; - if (data->sequenceFlag) - c |= 1 << 4; - if (data->replayFlag) - c |= 1 << 5; - if (data->mutualFlag) - c |= 1 << 6; - if (data->delegFlag) - c |= 1 << 7; - *p-- = c; - *p-- = 0; - len -= 2; - ret += 2; - } - - e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l); - BACK; - *size = ret; - return 0; -} - -static int -decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size) -{ - size_t ret = 0, reallen; - size_t l; - int e; - - memset(data, 0, sizeof(*data)); - reallen = 0; - e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l); - FORW; - if (len < reallen) - return ASN1_OVERRUN; - p++; - len--; - POST(len); - reallen--; - ret++; - data->delegFlag = (*p >> 7) & 1; - data->mutualFlag = (*p >> 6) & 1; - data->replayFlag = (*p >> 5) & 1; - data->sequenceFlag = (*p >> 4) & 1; - data->anonFlag = (*p >> 3) & 1; - data->confFlag = (*p >> 2) & 1; - data->integFlag = (*p >> 1) & 1; - ret += reallen; - if (size) - *size = ret; - return 0; -fail: - free_ContextFlags(data); - return e; -} - -static void -free_ContextFlags(ContextFlags * data) -{ - (void)data; -} - -/* unused function: length_ContextFlags */ - - -/* unused function: copy_ContextFlags */ - - -/* unused function: ContextFlags2int */ - - -/* unused function: int2ContextFlags */ - - -/* unused variable: ContextFlags_units */ - -/* unused function: asn1_ContextFlags_units */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -static int -encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int e; - - if ((data)->mechListMIC) { - size_t oldret = ret; - ret = 0; - e = encode_octet_string(p, len, (data)->mechListMIC, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); - BACK; - ret += oldret; - } - if ((data)->mechToken) { - size_t oldret = ret; - ret = 0; - e = encode_octet_string(p, len, (data)->mechToken, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); - BACK; - ret += oldret; - } - if ((data)->reqFlags) { - size_t oldret = ret; - ret = 0; - e = encode_ContextFlags(p, len, (data)->reqFlags, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); - BACK; - ret += oldret; - } { - size_t oldret = ret; - ret = 0; - e = encode_MechTypeList(p, len, &(data)->mechTypes, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); - BACK; - ret += oldret; - } - e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); - BACK; - *size = ret; - return 0; -} - -static int -decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size) -{ - size_t ret = 0, reallen; - size_t l; - int e; - - memset(data, 0, sizeof(*data)); - reallen = 0; - e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); - FORW; - { - int dce_fix; - if ((dce_fix = fix_dce(reallen, &len)) < 0) { - e = ASN1_BAD_FORMAT; - goto fail; - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); - FORW; - { - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) { - e = ASN1_BAD_FORMAT; - goto fail; - } - e = decode_MechTypeList(p, len, &(data)->mechTypes, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); - if (e) - (data)->reqFlags = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) { - e = ASN1_BAD_FORMAT; - goto fail; - } - (data)->reqFlags = malloc(sizeof(*(data)->reqFlags)); - if ((data)->reqFlags == NULL) { - e = ENOMEM; - goto fail; - } - e = decode_ContextFlags(p, len, (data)->reqFlags, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); - if (e) - (data)->mechToken = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) { - e = ASN1_BAD_FORMAT; - goto fail; - } - (data)->mechToken = malloc(sizeof(*(data)->mechToken)); - if ((data)->mechToken == NULL) { - e = ENOMEM; - goto fail; - } - e = decode_octet_string(p, len, (data)->mechToken, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); - if (e) - (data)->mechListMIC = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) { - e = ASN1_BAD_FORMAT; - goto fail; - } - (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); - if ((data)->mechListMIC == NULL) { - e = ENOMEM; - goto fail; - } - e = decode_octet_string(p, len, (data)->mechListMIC, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - if (dce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } - } - if (size) - *size = ret; - return 0; -fail: - free_NegTokenInit(data); - return e; -} - -static void -free_NegTokenInit(NegTokenInit * data) -{ - free_MechTypeList(&(data)->mechTypes); - if ((data)->reqFlags) { - free_ContextFlags((data)->reqFlags); - free((data)->reqFlags); - (data)->reqFlags = NULL; - } - if ((data)->mechToken) { - free_octet_string((data)->mechToken); - free((data)->mechToken); - (data)->mechToken = NULL; - } - if ((data)->mechListMIC) { - free_octet_string((data)->mechListMIC); - free((data)->mechListMIC); - (data)->mechListMIC = NULL; - } -} - -/* unused function: length_NegTokenInit */ - - -/* unused function: copy_NegTokenInit */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -static int -encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size) -{ - size_t ret = 0; - size_t l; - int e; - - if ((data)->mechListMIC) { - size_t oldret = ret; - ret = 0; - e = encode_octet_string(p, len, (data)->mechListMIC, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); - BACK; - ret += oldret; - } - if ((data)->responseToken) { - size_t oldret = ret; - ret = 0; - e = encode_octet_string(p, len, (data)->responseToken, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); - BACK; - ret += oldret; - } - if ((data)->supportedMech) { - size_t oldret = ret; - ret = 0; - e = encode_MechType(p, len, (data)->supportedMech, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); - BACK; - ret += oldret; - } - if ((data)->negState) { - size_t oldret = ret; - ret = 0; - e = encode_enumerated(p, len, (data)->negState, &l); - BACK; - e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); - BACK; - ret += oldret; - } - e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); - BACK; - *size = ret; - return 0; -} - -static int -decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size) -{ - size_t ret = 0, reallen; - size_t l; - int e; - - memset(data, 0, sizeof(*data)); - reallen = 0; - e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); - FORW; - { - int dce_fix; - if ((dce_fix = fix_dce(reallen, &len)) < 0) - return ASN1_BAD_FORMAT; - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); - if (e) - (data)->negState = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) - return ASN1_BAD_FORMAT; - (data)->negState = malloc(sizeof(*(data)->negState)); - if ((data)->negState == NULL) - return ENOMEM; - e = decode_enumerated(p, len, (data)->negState, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); - if (e) - (data)->supportedMech = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) - return ASN1_BAD_FORMAT; - (data)->supportedMech = malloc(sizeof(*(data)->supportedMech)); - if ((data)->supportedMech == NULL) - return ENOMEM; - e = decode_MechType(p, len, (data)->supportedMech, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); - if (e) - (data)->responseToken = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) - return ASN1_BAD_FORMAT; - (data)->responseToken = malloc(sizeof(*(data)->responseToken)); - if ((data)->responseToken == NULL) - return ENOMEM; - e = decode_octet_string(p, len, (data)->responseToken, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - { - size_t newlen, oldlen; - - e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); - if (e) - (data)->mechListMIC = NULL; - else { - p += l; - len -= l; - ret += l; - e = der_get_length(p, len, &newlen, &l); - FORW; - { - int mydce_fix; - oldlen = len; - if ((mydce_fix = fix_dce(newlen, &len)) < 0) - return ASN1_BAD_FORMAT; - (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); - if ((data)->mechListMIC == NULL) - return ENOMEM; - e = decode_octet_string(p, len, (data)->mechListMIC, &l); - FORW; - if (mydce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } else - len = oldlen - newlen; - } - } - } - if (dce_fix) { - e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); - FORW; - } - } - if (size) - *size = ret; - return 0; -fail: - free_NegTokenResp(data); - return e; -} - -static void -free_NegTokenResp(NegTokenResp * data) -{ - if ((data)->negState) { - free((data)->negState); - (data)->negState = NULL; - } - if ((data)->supportedMech) { - free_MechType((data)->supportedMech); - free((data)->supportedMech); - (data)->supportedMech = NULL; - } - if ((data)->responseToken) { - free_octet_string((data)->responseToken); - free((data)->responseToken); - (data)->responseToken = NULL; - } - if ((data)->mechListMIC) { - free_octet_string((data)->mechListMIC); - free((data)->mechListMIC); - (data)->mechListMIC = NULL; - } -} - -/* unused function: length_NegTokenResp */ - - -/* unused function: copy_NegTokenResp */ - -/* Generated from spnego.asn1 */ -/* Do not edit */ - - -/* CHOICE */ -/* unused variable: asn1_NegotiationToken_dummy_holder */ diff --git a/lib/dns-pkcs11/spnego_asn1.pl b/lib/dns-pkcs11/spnego_asn1.pl deleted file mode 100644 index b4b6da3..0000000 --- a/lib/dns-pkcs11/spnego_asn1.pl +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bin/perl -w -# -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -# Our SPNEGO implementation uses some functions generated by the -# Heimdal ASN.1 compiler, which this script then whacks a bit to make -# them work properly in this stripped down implementation. We don't -# want to require our users to have a copy of the compiler, so we ship -# the output of this script, but we need to keep the script around in -# any case to cope with future changes to the SPNEGO ASN.1 code, so we -# might as well supply the script for users who want it. - -# Overall plan: run the ASN.1 compiler, run each of its output files -# through indent, fix up symbols and whack everything to be static. -# We use indent for two reasons: (1) to whack the Heimdal compiler's -# output into something closer to ISC's coding standard, and (2) to -# make it easier for this script to parse the result. - -# Output from this script is C code which we expect to be #included -# into another C file, which is why everything generated by this -# script is marked "static". The intent is to minimize the number of -# extern symbols exported by the SPNEGO implementation, to avoid -# potential conflicts with the GSSAPI libraries. - -### - -# Filename of the ASN.1 specification. Hardcoded for the moment -# since this script is intended for compiling exactly one module. - -my $asn1_source = $ENV{ASN1_SOURCE} || "spnego.asn1"; - -# Heimdal ASN.1 compiler. This script was written using the version -# from Heimdal 0.7.1. To build this, download a copy of -# heimdal-0.7.1.tar.gz, configure and build with the default options, -# then look for the compiler in heimdal-0.7.1/lib/asn1/asn1_compile. - -my $asn1_compile = $ENV{ASN1_COMPILE} || "asn1_compile"; - -# BSD indent program. This script was written using the version of -# indent that comes with FreeBSD 4.11-STABLE. The GNU project, as -# usual, couldn't resist the temptation to monkey with indent's -# command line syntax, so this probably won't work with GNU indent. - -my $indent = $ENV{INDENT} || "indent"; - -### - -# Step 1: run the compiler. Input is the ASN.1 file. Outputs are a -# header file (name specified on command line without the .h suffix), -# a file called "asn1_files" listing the names of the other output -# files, and a set of files containing C code generated by the -# compiler for each data type that the compiler found. - -if (! -r $asn1_source || system($asn1_compile, $asn1_source, "asn1")) { - die("Couldn't compile ASN.1 source file $asn1_source\n"); -} - -my @files = ("asn1.h"); - -open(F, "asn1_files") - or die("Couldn't open asn1_files: $!\n"); -push(@files, split) - while (); -close(F); - -unlink("asn1_files"); - -### - -# Step 2: generate header block. - -print(q~/* - * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC") - * - * 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. - */ - -/*! \file - * \brief Method routines generated from SPNEGO ASN.1 module. - * See spnego_asn1.pl for details. Do not edit. - */ - -~); - -### - -# Step 3: read and process each generated file, then delete it. - -my $output; - -for my $file (@files) { - - my $is_static = 0; - - system($indent, "-di1", "-ldi1", $file) == 0 - or die("Couldn't indent $file"); - - unlink("$file.BAK"); - - open(F, $file) - or die("Couldn't open $file: $!"); - - while () { - - # Symbol name fixups - - s/heim_general_string/general_string/g; - s/heim_octet_string/octet_string/g; - s/heim_oid/oid/g; - s/heim_utf8_string/utf8_string/g; - - # Convert all externs to statics - - if (/^static/) { - $is_static = 1; - } - - if (!/^typedef/ && - !$is_static && - /^[A-Za-z_][0-9A-Za-z_]*[ \t]*($|[^:0-9A-Za-z_])/) { - $_ = "static " . $_; - $is_static = 1; - } - - if (/[{};]/) { - $is_static = 0; - } - - # Suppress file inclusion, pass anything else through - - if (!/#include/) { - $output .= $_; - } - } - - close(F); - unlink($file); -} - -# Step 4: Delete unused stuff to avoid code bloat and compiler warnings. - -my @unused_functions = qw(ContextFlags2int - int2ContextFlags - asn1_ContextFlags_units - length_NegTokenInit - copy_NegTokenInit - length_NegTokenResp - copy_NegTokenResp - length_MechTypeList - length_MechType - copy_MechTypeList - length_ContextFlags - copy_ContextFlags - copy_MechType); - -$output =~ s<^static [^\n]+\n$_\(.+?^}>ms - foreach (@unused_functions); - -$output =~ s<^static .+$_\(.*\);$>m - foreach (@unused_functions); - -$output =~ s<^static struct units ContextFlags_units\[\].+?^};> - ms; - -$output =~ s<^static int asn1_NegotiationToken_dummy_holder = 1;> - ms; - -$output =~ s<^static void\nfree_ContextFlags\(ContextFlags \* data\)\n{\n> - <$&\t(void)data;\n>ms; - -# Step 5: Write the result. - -print($output); - diff --git a/lib/dns-pkcs11/ssu.c b/lib/dns-pkcs11/ssu.c deleted file mode 100644 index 700bb65..0000000 --- a/lib/dns-pkcs11/ssu.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T') -#define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC) - -#define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R') -#define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC) - -struct dns_ssurule { - unsigned int magic; - bool grant; /*%< is this a grant or a deny? */ - unsigned int matchtype; /*%< which type of pattern match? */ - dns_name_t *identity; /*%< the identity to match */ - dns_name_t *name; /*%< the name being updated */ - unsigned int ntypes; /*%< number of data types covered */ - dns_rdatatype_t *types; /*%< the data types. Can include ANY, */ - /*%< defaults to all but SIG,SOA,NS if NULL */ - ISC_LINK(dns_ssurule_t) link; -}; - -struct dns_ssutable { - unsigned int magic; - isc_mem_t *mctx; - unsigned int references; - isc_mutex_t lock; - dns_dlzdb_t *dlzdatabase; - ISC_LIST(dns_ssurule_t) rules; -}; - -isc_result_t -dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) { - isc_result_t result; - dns_ssutable_t *table; - - REQUIRE(tablep != NULL && *tablep == NULL); - REQUIRE(mctx != NULL); - - table = isc_mem_get(mctx, sizeof(dns_ssutable_t)); - if (table == NULL) - return (ISC_R_NOMEMORY); - result = isc_mutex_init(&table->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, table, sizeof(dns_ssutable_t)); - return (result); - } - table->references = 1; - table->mctx = NULL; - isc_mem_attach(mctx, &table->mctx); - ISC_LIST_INIT(table->rules); - table->magic = SSUTABLEMAGIC; - *tablep = table; - return (ISC_R_SUCCESS); -} - -static inline void -destroy(dns_ssutable_t *table) { - isc_mem_t *mctx; - - REQUIRE(VALID_SSUTABLE(table)); - - mctx = table->mctx; - while (!ISC_LIST_EMPTY(table->rules)) { - dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules); - if (rule->identity != NULL) { - dns_name_free(rule->identity, mctx); - isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); - } - if (rule->name != NULL) { - dns_name_free(rule->name, mctx); - isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); - } - if (rule->types != NULL) - isc_mem_put(mctx, rule->types, - rule->ntypes * sizeof(dns_rdatatype_t)); - ISC_LIST_UNLINK(table->rules, rule, link); - rule->magic = 0; - isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); - } - DESTROYLOCK(&table->lock); - table->magic = 0; - isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t)); -} - -void -dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) { - REQUIRE(VALID_SSUTABLE(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); - - UNLOCK(&source->lock); - - *targetp = source; -} - -void -dns_ssutable_detach(dns_ssutable_t **tablep) { - dns_ssutable_t *table; - bool done = false; - - REQUIRE(tablep != NULL); - table = *tablep; - REQUIRE(VALID_SSUTABLE(table)); - - LOCK(&table->lock); - - INSIST(table->references > 0); - if (--table->references == 0) - done = true; - UNLOCK(&table->lock); - - *tablep = NULL; - - if (done) - destroy(table); -} - -isc_result_t -dns_ssutable_addrule(dns_ssutable_t *table, bool grant, - dns_name_t *identity, unsigned int matchtype, - dns_name_t *name, unsigned int ntypes, - dns_rdatatype_t *types) -{ - dns_ssurule_t *rule; - isc_mem_t *mctx; - isc_result_t result; - - REQUIRE(VALID_SSUTABLE(table)); - REQUIRE(dns_name_isabsolute(identity)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX); - if (matchtype == DNS_SSUMATCHTYPE_WILDCARD) - REQUIRE(dns_name_iswildcard(name)); - if (ntypes > 0) - REQUIRE(types != NULL); - - mctx = table->mctx; - rule = isc_mem_get(mctx, sizeof(dns_ssurule_t)); - if (rule == NULL) - return (ISC_R_NOMEMORY); - - rule->identity = NULL; - rule->name = NULL; - rule->types = NULL; - - rule->grant = grant; - - rule->identity = isc_mem_get(mctx, sizeof(dns_name_t)); - if (rule->identity == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(rule->identity, NULL); - result = dns_name_dup(identity, mctx, rule->identity); - if (result != ISC_R_SUCCESS) - goto failure; - - rule->name = isc_mem_get(mctx, sizeof(dns_name_t)); - if (rule->name == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(rule->name, NULL); - result = dns_name_dup(name, mctx, rule->name); - if (result != ISC_R_SUCCESS) - goto failure; - - rule->matchtype = matchtype; - - rule->ntypes = ntypes; - if (ntypes > 0) { - rule->types = isc_mem_get(mctx, - ntypes * sizeof(dns_rdatatype_t)); - if (rule->types == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); - } else - rule->types = NULL; - - rule->magic = SSURULEMAGIC; - ISC_LIST_INITANDAPPEND(table->rules, rule, link); - - return (ISC_R_SUCCESS); - - failure: - if (rule->identity != NULL) { - if (dns_name_dynamic(rule->identity)) - dns_name_free(rule->identity, mctx); - isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); - } - if (rule->name != NULL) { - if (dns_name_dynamic(rule->name)) - dns_name_free(rule->name, mctx); - isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); - } - if (rule->types != NULL) - isc_mem_put(mctx, rule->types, - ntypes * sizeof(dns_rdatatype_t)); - isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); - - return (result); -} - -static inline bool -isusertype(dns_rdatatype_t type) { - return (type != dns_rdatatype_ns && - type != dns_rdatatype_soa && - type != dns_rdatatype_rrsig); -} - -static void -reverse_from_address(dns_name_t *tcpself, isc_netaddr_t *tcpaddr) { - char buf[16 * 4 + sizeof("IP6.ARPA.")]; - isc_result_t result; - unsigned char *ap; - isc_buffer_t b; - unsigned long l; - - switch (tcpaddr->family) { - case AF_INET: - l = ntohl(tcpaddr->type.in.s_addr); - result = isc_string_printf(buf, sizeof(buf), - "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.", - (l >> 0) & 0xff, (l >> 8) & 0xff, - (l >> 16) & 0xff, (l >> 24) & 0xff); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - break; - case AF_INET6: - ap = tcpaddr->type.in6.s6_addr; - result = isc_string_printf(buf, sizeof(buf), - "%x.%x.%x.%x.%x.%x.%x.%x." - "%x.%x.%x.%x.%x.%x.%x.%x." - "%x.%x.%x.%x.%x.%x.%x.%x." - "%x.%x.%x.%x.%x.%x.%x.%x." - "IP6.ARPA.", - ap[15] & 0x0f, (ap[15] >> 4) & 0x0f, - ap[14] & 0x0f, (ap[14] >> 4) & 0x0f, - ap[13] & 0x0f, (ap[13] >> 4) & 0x0f, - ap[12] & 0x0f, (ap[12] >> 4) & 0x0f, - ap[11] & 0x0f, (ap[11] >> 4) & 0x0f, - ap[10] & 0x0f, (ap[10] >> 4) & 0x0f, - ap[9] & 0x0f, (ap[9] >> 4) & 0x0f, - ap[8] & 0x0f, (ap[8] >> 4) & 0x0f, - ap[7] & 0x0f, (ap[7] >> 4) & 0x0f, - ap[6] & 0x0f, (ap[6] >> 4) & 0x0f, - ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, - ap[4] & 0x0f, (ap[4] >> 4) & 0x0f, - ap[3] & 0x0f, (ap[3] >> 4) & 0x0f, - ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, - ap[1] & 0x0f, (ap[1] >> 4) & 0x0f, - ap[0] & 0x0f, (ap[0] >> 4) & 0x0f); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_buffer_init(&b, buf, strlen(buf)); - isc_buffer_add(&b, strlen(buf)); - result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); -} - -static void -stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) { - char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")]; - isc_result_t result; - unsigned char *ap; - isc_buffer_t b; - unsigned long l; - - switch(tcpaddr->family) { - case AF_INET: - l = ntohl(tcpaddr->type.in.s_addr); - result = isc_string_printf(buf, sizeof(buf), - "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx" - "2.0.0.2.IP6.ARPA.", - l & 0xf, (l >> 4) & 0xf, - (l >> 8) & 0xf, (l >> 12) & 0xf, - (l >> 16) & 0xf, (l >> 20) & 0xf, - (l >> 24) & 0xf, (l >> 28) & 0xf); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - break; - case AF_INET6: - ap = tcpaddr->type.in6.s6_addr; - result = isc_string_printf(buf, sizeof(buf), - "%x.%x.%x.%x.%x.%x.%x.%x." - "%x.%x.%x.%x.IP6.ARPA.", - ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, - ap[4] & 0x0f, (ap[4] >> 4) & 0x0f, - ap[3] & 0x0f, (ap[3] >> 4) & 0x0f, - ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, - ap[1] & 0x0f, (ap[1] >> 4) & 0x0f, - ap[0] & 0x0f, (ap[0] >> 4) & 0x0f); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - isc_buffer_init(&b, buf, strlen(buf)); - isc_buffer_add(&b, strlen(buf)); - result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); -} - -bool -dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *addr, - dns_rdatatype_t type, const dst_key_t *key) -{ - return (dns_ssutable_checkrules2 - (table, signer, name, addr, - addr == NULL ? false : true, - NULL, type, key)); -} - -bool -dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer, - dns_name_t *name, isc_netaddr_t *addr, - bool tcp, const dns_aclenv_t *env, - dns_rdatatype_t type, const dst_key_t *key) -{ - dns_ssurule_t *rule; - unsigned int i; - dns_fixedname_t fixed; - dns_name_t *wildcard; - dns_name_t *tcpself; - dns_name_t *stfself; - isc_result_t result; - int match; - - REQUIRE(VALID_SSUTABLE(table)); - REQUIRE(signer == NULL || dns_name_isabsolute(signer)); - REQUIRE(dns_name_isabsolute(name)); - REQUIRE(addr == NULL || env != NULL); - - if (signer == NULL && addr == NULL) - return (false); - - for (rule = ISC_LIST_HEAD(table->rules); - rule != NULL; - rule = ISC_LIST_NEXT(rule, link)) - { - switch (rule->matchtype) { - case DNS_SSUMATCHTYPE_NAME: - case DNS_SSUMATCHTYPE_LOCAL: - case DNS_SSUMATCHTYPE_SUBDOMAIN: - case DNS_SSUMATCHTYPE_WILDCARD: - case DNS_SSUMATCHTYPE_SELF: - case DNS_SSUMATCHTYPE_SELFSUB: - case DNS_SSUMATCHTYPE_SELFWILD: - if (signer == NULL) - continue; - if (dns_name_iswildcard(rule->identity)) { - if (!dns_name_matcheswildcard(signer, - rule->identity)) - continue; - } else { - if (!dns_name_equal(signer, rule->identity)) - continue; - } - break; - case dns_ssumatchtype_selfkrb5: - case dns_ssumatchtype_selfms: - case dns_ssumatchtype_selfsubkrb5: - case dns_ssumatchtype_selfsubms: - case dns_ssumatchtype_subdomainkrb5: - case dns_ssumatchtype_subdomainms: - if (signer == NULL) - continue; - break; - case DNS_SSUMATCHTYPE_TCPSELF: - case DNS_SSUMATCHTYPE_6TO4SELF: - if (!tcp || addr == NULL) - continue; - break; - } - - switch (rule->matchtype) { - case DNS_SSUMATCHTYPE_NAME: - if (!dns_name_equal(name, rule->name)) - continue; - break; - case DNS_SSUMATCHTYPE_SUBDOMAIN: - if (!dns_name_issubdomain(name, rule->name)) - continue; - break; - case DNS_SSUMATCHTYPE_LOCAL: - if (addr == NULL) { - continue; - } - if (!dns_name_issubdomain(name, rule->name)) { - continue; - } - dns_acl_match(addr, NULL, env->localhost, - NULL, &match, NULL); - if (match == 0) { - if (signer != NULL) { - isc_log_write(dns_lctx, - DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_SSU, - ISC_LOG_WARNING, - "update-policy local: " - "match on session " - "key not from " - "localhost"); - } - continue; - } - break; - case DNS_SSUMATCHTYPE_WILDCARD: - if (!dns_name_matcheswildcard(name, rule->name)) - continue; - break; - case DNS_SSUMATCHTYPE_SELF: - if (!dns_name_equal(signer, name)) - continue; - break; - case DNS_SSUMATCHTYPE_SELFSUB: - if (!dns_name_issubdomain(name, signer)) - continue; - break; - case DNS_SSUMATCHTYPE_SELFWILD: - wildcard = dns_fixedname_initname(&fixed); - result = dns_name_concatenate(dns_wildcardname, signer, - wildcard, NULL); - if (result != ISC_R_SUCCESS) - continue; - if (!dns_name_matcheswildcard(name, wildcard)) - continue; - break; - case dns_ssumatchtype_selfkrb5: - if (dst_gssapi_identitymatchesrealmkrb5(signer, name, - rule->identity, - false)) - { - break; - } - continue; - case dns_ssumatchtype_selfms: - if (dst_gssapi_identitymatchesrealmms(signer, name, - rule->identity, - false)) - { - break; - } - continue; - case dns_ssumatchtype_selfsubkrb5: - if (dst_gssapi_identitymatchesrealmkrb5(signer, name, - rule->identity, - true)) - { - break; - } - continue; - case dns_ssumatchtype_selfsubms: - if (dst_gssapi_identitymatchesrealmms(signer, name, - rule->identity, - true)) - break; - continue; - case dns_ssumatchtype_subdomainkrb5: - if (!dns_name_issubdomain(name, rule->name)) - continue; - if (dst_gssapi_identitymatchesrealmkrb5(signer, NULL, - rule->identity, - false)) - { - break; - } - continue; - case dns_ssumatchtype_subdomainms: - if (!dns_name_issubdomain(name, rule->name)) - continue; - if (dst_gssapi_identitymatchesrealmms(signer, NULL, - rule->identity, - false)) - { - break; - } - continue; - case DNS_SSUMATCHTYPE_TCPSELF: - tcpself = dns_fixedname_initname(&fixed); - reverse_from_address(tcpself, addr); - if (dns_name_iswildcard(rule->identity)) { - if (!dns_name_matcheswildcard(tcpself, - rule->identity)) - continue; - } else { - if (!dns_name_equal(tcpself, rule->identity)) - continue; - } - if (!dns_name_equal(tcpself, name)) - continue; - break; - case DNS_SSUMATCHTYPE_6TO4SELF: - stfself = dns_fixedname_initname(&fixed); - stf_from_address(stfself, addr); - if (dns_name_iswildcard(rule->identity)) { - if (!dns_name_matcheswildcard(stfself, - rule->identity)) - continue; - } else { - if (!dns_name_equal(stfself, rule->identity)) - continue; - } - if (!dns_name_equal(stfself, name)) - continue; - break; - case DNS_SSUMATCHTYPE_EXTERNAL: - if (!dns_ssu_external_match(rule->identity, signer, - name, addr, type, key, - table->mctx)) - continue; - break; - case DNS_SSUMATCHTYPE_DLZ: - if (!dns_dlz_ssumatch(table->dlzdatabase, signer, - name, addr, type, key)) - continue; - break; - } - - if (rule->ntypes == 0) { - /* - * If this is a DLZ rule, then the DLZ ssu - * checks will have already checked - * the type. - */ - if (rule->matchtype != DNS_SSUMATCHTYPE_DLZ && - !isusertype(type)) - continue; - } else { - for (i = 0; i < rule->ntypes; i++) { - if (rule->types[i] == dns_rdatatype_any || - rule->types[i] == type) - break; - } - if (i == rule->ntypes) - continue; - } - return (rule->grant); - } - - return (false); -} - -bool -dns_ssurule_isgrant(const dns_ssurule_t *rule) { - REQUIRE(VALID_SSURULE(rule)); - return (rule->grant); -} - -dns_name_t * -dns_ssurule_identity(const dns_ssurule_t *rule) { - REQUIRE(VALID_SSURULE(rule)); - return (rule->identity); -} - -unsigned int -dns_ssurule_matchtype(const dns_ssurule_t *rule) { - REQUIRE(VALID_SSURULE(rule)); - return (rule->matchtype); -} - -dns_name_t * -dns_ssurule_name(const dns_ssurule_t *rule) { - REQUIRE(VALID_SSURULE(rule)); - return (rule->name); -} - -unsigned int -dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) { - REQUIRE(VALID_SSURULE(rule)); - REQUIRE(types != NULL && *types != NULL); - *types = rule->types; - return (rule->ntypes); -} - -isc_result_t -dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) { - REQUIRE(VALID_SSUTABLE(table)); - REQUIRE(rule != NULL && *rule == NULL); - *rule = ISC_LIST_HEAD(table->rules); - return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE); -} - -isc_result_t -dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) { - REQUIRE(VALID_SSURULE(rule)); - REQUIRE(nextrule != NULL && *nextrule == NULL); - *nextrule = ISC_LIST_NEXT(rule, link); - return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE); -} - -/* - * Create a specialised SSU table that points at an external DLZ database - */ -isc_result_t -dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, - dns_dlzdb_t *dlzdatabase) -{ - isc_result_t result; - dns_ssurule_t *rule; - dns_ssutable_t *table = NULL; - - REQUIRE(tablep != NULL && *tablep == NULL); - - result = dns_ssutable_create(mctx, &table); - if (result != ISC_R_SUCCESS) - return (result); - - table->dlzdatabase = dlzdatabase; - - rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t)); - if (rule == NULL) { - dns_ssutable_detach(&table); - return (ISC_R_NOMEMORY); - } - - rule->identity = NULL; - rule->name = NULL; - rule->types = NULL; - rule->grant = true; - rule->matchtype = DNS_SSUMATCHTYPE_DLZ; - rule->ntypes = 0; - rule->types = NULL; - rule->magic = SSURULEMAGIC; - - ISC_LIST_INITANDAPPEND(table->rules, rule, link); - *tablep = table; - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype) { - - REQUIRE(str != NULL); - REQUIRE(mtype != NULL); - - if (strcasecmp(str, "name") == 0) { - *mtype = dns_ssumatchtype_name; - } else if (strcasecmp(str, "subdomain") == 0) { - *mtype = dns_ssumatchtype_subdomain; - } else if (strcasecmp(str, "wildcard") == 0) { - *mtype = dns_ssumatchtype_wildcard; - } else if (strcasecmp(str, "self") == 0) { - *mtype = dns_ssumatchtype_self; - } else if (strcasecmp(str, "selfsub") == 0) { - *mtype = dns_ssumatchtype_selfsub; - } else if (strcasecmp(str, "selfwild") == 0) { - *mtype = dns_ssumatchtype_selfwild; - } else if (strcasecmp(str, "ms-self") == 0) { - *mtype = dns_ssumatchtype_selfms; - } else if (strcasecmp(str, "ms-selfsub") == 0) { - *mtype = dns_ssumatchtype_selfsubms; - } else if (strcasecmp(str, "krb5-self") == 0) { - *mtype = dns_ssumatchtype_selfkrb5; - } else if (strcasecmp(str, "krb5-selfsub") == 0) { - *mtype = dns_ssumatchtype_selfsubkrb5; - } else if (strcasecmp(str, "ms-subdomain") == 0) { - *mtype = dns_ssumatchtype_subdomainms; - } else if (strcasecmp(str, "krb5-subdomain") == 0) { - *mtype = dns_ssumatchtype_subdomainkrb5; - } else if (strcasecmp(str, "tcp-self") == 0) { - *mtype = dns_ssumatchtype_tcpself; - } else if (strcasecmp(str, "6to4-self") == 0) { - *mtype = dns_ssumatchtype_6to4self; - } else if (strcasecmp(str, "zonesub") == 0) { - *mtype = dns_ssumatchtype_subdomain; - } else if (strcasecmp(str, "external") == 0) { - *mtype = dns_ssumatchtype_external; - } else { - return (ISC_R_NOTFOUND); - } - return (ISC_R_SUCCESS); -} diff --git a/lib/dns-pkcs11/ssu_external.c b/lib/dns-pkcs11/ssu_external.c deleted file mode 100644 index 10d679d..0000000 --- a/lib/dns-pkcs11/ssu_external.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/* - * This implements external update-policy rules. This allows permission - * to update a zone to be checked by consulting an external daemon (e.g., - * kerberos). - */ - -#include - -#include -#include -#include -#include - -#ifdef ISC_PLATFORM_HAVESYSUNH -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - - -static void -ssu_e_log(int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_SECURITY, - DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(level), fmt, ap); - va_end(ap); -} - - -/* - * Connect to a UNIX domain socket. - */ -static int -ux_socket_connect(const char *path) { - int fd = -1; -#ifdef ISC_PLATFORM_HAVESYSUNH - struct sockaddr_un addr; - - REQUIRE(path != NULL); - - if (strlen(path) > sizeof(addr.sun_path)) { - ssu_e_log(3, "ssu_external: socket path '%s' " - "longer than system maximum %u", - path, sizeof(addr.sun_path)); - return (-1); - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) { - char strbuf[ISC_STRERRORSIZE]; - isc__strerror(errno, strbuf, sizeof(strbuf)); - ssu_e_log(3, "ssu_external: unable to create socket - %s", - strbuf); - return (-1); - } - - if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - char strbuf[ISC_STRERRORSIZE]; - isc__strerror(errno, strbuf, sizeof(strbuf)); - ssu_e_log(3, "ssu_external: unable to connect to " - "socket '%s' - %s", - path, strbuf); - close(fd); - return (-1); - } -#endif - return (fd); -} - -/* Change this version if you update the format of the request */ -#define SSU_EXTERNAL_VERSION 1 - -/* - * Perform an update-policy rule check against an external application - * over a socket. - * - * This currently only supports local: for unix domain datagram sockets. - * - * Note that by using a datagram socket and creating a new socket each - * time we avoid the need for locking and allow for parallel access to - * the authorization server. - */ -bool -dns_ssu_external_match(dns_name_t *identity, - dns_name_t *signer, dns_name_t *name, - isc_netaddr_t *tcpaddr, dns_rdatatype_t type, - const dst_key_t *key, isc_mem_t *mctx) -{ - char b_identity[DNS_NAME_FORMATSIZE]; - char b_signer[DNS_NAME_FORMATSIZE]; - char b_name[DNS_NAME_FORMATSIZE]; - char b_addr[ISC_NETADDR_FORMATSIZE]; - char b_type[DNS_RDATATYPE_FORMATSIZE]; - char b_key[DST_KEY_FORMATSIZE]; - isc_buffer_t *tkey_token = NULL; - int fd; - const char *sock_path; - unsigned int req_len; - isc_region_t token_region = {NULL, 0}; - unsigned char *data; - isc_buffer_t buf; - uint32_t token_len = 0; - uint32_t reply; - ssize_t ret; - - /* The identity contains local:/path/to/socket */ - dns_name_format(identity, b_identity, sizeof(b_identity)); - - /* For now only local: is supported */ - if (strncmp(b_identity, "local:", 6) != 0) { - ssu_e_log(3, "ssu_external: invalid socket path '%s'", - b_identity); - return (false); - } - sock_path = &b_identity[6]; - - fd = ux_socket_connect(sock_path); - if (fd == -1) - return (false); - - if (key != NULL) { - dst_key_format(key, b_key, sizeof(b_key)); - tkey_token = dst_key_tkeytoken(key); - } else - b_key[0] = 0; - - if (tkey_token != NULL) { - isc_buffer_region(tkey_token, &token_region); - token_len = token_region.length; - } - - /* Format the request elements */ - if (signer != NULL) - dns_name_format(signer, b_signer, sizeof(b_signer)); - else - b_signer[0] = 0; - - dns_name_format(name, b_name, sizeof(b_name)); - - if (tcpaddr != NULL) - isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr)); - else - b_addr[0] = 0; - - dns_rdatatype_format(type, b_type, sizeof(b_type)); - - /* Work out how big the request will be */ - req_len = sizeof(uint32_t) + /* Format version */ - sizeof(uint32_t) + /* Length */ - strlen(b_signer) + 1 + /* Signer */ - strlen(b_name) + 1 + /* Name */ - strlen(b_addr) + 1 + /* Address */ - strlen(b_type) + 1 + /* Type */ - strlen(b_key) + 1 + /* Key */ - sizeof(uint32_t) + /* tkey_token length */ - token_len; /* tkey_token */ - - - /* format the buffer */ - data = isc_mem_allocate(mctx, req_len); - if (data == NULL) { - close(fd); - return (false); - } - - isc_buffer_init(&buf, data, req_len); - isc_buffer_putuint32(&buf, SSU_EXTERNAL_VERSION); - isc_buffer_putuint32(&buf, req_len); - - /* Strings must be null-terminated */ - isc_buffer_putstr(&buf, b_signer); - isc_buffer_putuint8(&buf, 0); - isc_buffer_putstr(&buf, b_name); - isc_buffer_putuint8(&buf, 0); - isc_buffer_putstr(&buf, b_addr); - isc_buffer_putuint8(&buf, 0); - isc_buffer_putstr(&buf, b_type); - isc_buffer_putuint8(&buf, 0); - isc_buffer_putstr(&buf, b_key); - isc_buffer_putuint8(&buf, 0); - - isc_buffer_putuint32(&buf, token_len); - if (tkey_token && token_len != 0) - isc_buffer_putmem(&buf, token_region.base, token_len); - - ENSURE(isc_buffer_availablelength(&buf) == 0); - - /* Send the request */ - ret = write(fd, data, req_len); - isc_mem_free(mctx, data); - if (ret != (ssize_t) req_len) { - char strbuf[ISC_STRERRORSIZE]; - isc__strerror(errno, strbuf, sizeof(strbuf)); - ssu_e_log(3, "ssu_external: unable to send request - %s", - strbuf); - close(fd); - return (false); - } - - /* Receive the reply */ - ret = read(fd, &reply, sizeof(uint32_t)); - if (ret != (ssize_t) sizeof(uint32_t)) { - char strbuf[ISC_STRERRORSIZE]; - isc__strerror(errno, strbuf, sizeof(strbuf)); - ssu_e_log(3, "ssu_external: unable to receive reply - %s", - strbuf); - close(fd); - return (false); - } - - close(fd); - - reply = ntohl(reply); - - if (reply == 0) { - ssu_e_log(3, "ssu_external: denied external auth for '%s'", - b_name); - return (false); - } else if (reply == 1) { - ssu_e_log(3, "ssu_external: allowed external auth for '%s'", - b_name); - return (true); - } - - ssu_e_log(3, "ssu_external: invalid reply 0x%08x", reply); - - return (false); -} diff --git a/lib/dns-pkcs11/stats.c b/lib/dns-pkcs11/stats.c deleted file mode 100644 index 1473371..0000000 --- a/lib/dns-pkcs11/stats.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't') -#define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC) - -/*% - * Statistics types. - */ -typedef enum { - dns_statstype_general = 0, - dns_statstype_rdtype = 1, - dns_statstype_rdataset = 2, - dns_statstype_opcode = 3, - dns_statstype_rcode = 4 -} dns_statstype_t; - -/*% - * It doesn't make sense to have 2^16 counters for all possible types since - * most of them won't be used. We have counters for the first 256 types and - * those explicitly supported in the rdata implementation. - * XXXJT: this introduces tight coupling with the rdata implementation. - * Ideally, we should have rdata handle this type of details. - */ -/* - * types, !types, nxdomain, stale types, stale !types, stale nxdomain - */ -enum { - /* For 0-255, we use the rdtype value as counter indices */ - rdtypecounter_dlv = 256, /* for dns_rdatatype_dlv */ - rdtypecounter_others = 257, /* anything else */ - rdtypecounter_max = 258, - /* The following are used for rdataset */ - rdtypenxcounter_max = rdtypecounter_max * 2, - rdtypecounter_nxdomain = rdtypenxcounter_max, - /* stale counters offset */ - rdtypecounter_stale = rdtypecounter_nxdomain + 1, - rdatasettypecounter_max = rdtypecounter_stale * 2 -}; - -struct dns_stats { - /*% Unlocked */ - unsigned int magic; - dns_statstype_t type; - isc_mem_t *mctx; - isc_mutex_t lock; - isc_stats_t *counters; - - /*% Locked by lock */ - unsigned int references; -}; - -typedef struct rdatadumparg { - dns_rdatatypestats_dumper_t fn; - void *arg; -} rdatadumparg_t; - -typedef struct opcodedumparg { - dns_opcodestats_dumper_t fn; - void *arg; -} opcodedumparg_t; - -typedef struct rcodedumparg { - dns_rcodestats_dumper_t fn; - void *arg; -} rcodedumparg_t; - -void -dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) { - REQUIRE(DNS_STATS_VALID(stats)); - REQUIRE(statsp != NULL && *statsp == NULL); - - LOCK(&stats->lock); - stats->references++; - UNLOCK(&stats->lock); - - *statsp = stats; -} - -void -dns_stats_detach(dns_stats_t **statsp) { - dns_stats_t *stats; - - REQUIRE(statsp != NULL && DNS_STATS_VALID(*statsp)); - - stats = *statsp; - *statsp = NULL; - - LOCK(&stats->lock); - stats->references--; - UNLOCK(&stats->lock); - - if (stats->references == 0) { - isc_stats_detach(&stats->counters); - DESTROYLOCK(&stats->lock); - isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats)); - } -} - -/*% - * Create methods - */ -static isc_result_t -create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters, - dns_stats_t **statsp) -{ - dns_stats_t *stats; - isc_result_t result; - - stats = isc_mem_get(mctx, sizeof(*stats)); - if (stats == NULL) - return (ISC_R_NOMEMORY); - - stats->counters = NULL; - stats->references = 1; - - result = isc_mutex_init(&stats->lock); - if (result != ISC_R_SUCCESS) - goto clean_stats; - - result = isc_stats_create(mctx, &stats->counters, ncounters); - if (result != ISC_R_SUCCESS) - goto clean_mutex; - - stats->magic = DNS_STATS_MAGIC; - stats->type = type; - stats->mctx = NULL; - isc_mem_attach(mctx, &stats->mctx); - *statsp = stats; - - return (ISC_R_SUCCESS); - - clean_mutex: - DESTROYLOCK(&stats->lock); - clean_stats: - isc_mem_put(mctx, stats, sizeof(*stats)); - - return (result); -} - -isc_result_t -dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters) { - REQUIRE(statsp != NULL && *statsp == NULL); - - return (create_stats(mctx, dns_statstype_general, ncounters, statsp)); -} - -isc_result_t -dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp) { - REQUIRE(statsp != NULL && *statsp == NULL); - - return (create_stats(mctx, dns_statstype_rdtype, rdtypecounter_max, - statsp)); -} - -isc_result_t -dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp) { - REQUIRE(statsp != NULL && *statsp == NULL); - - return (create_stats(mctx, dns_statstype_rdataset, - rdatasettypecounter_max, statsp)); -} - -isc_result_t -dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) { - REQUIRE(statsp != NULL && *statsp == NULL); - - return (create_stats(mctx, dns_statstype_opcode, 16, statsp)); -} - -isc_result_t -dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) { - REQUIRE(statsp != NULL && *statsp == NULL); - - return (create_stats(mctx, dns_statstype_rcode, - dns_rcode_badcookie + 1, statsp)); -} - -/*% - * Increment/Decrement methods - */ -void -dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter) { - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general); - - isc_stats_increment(stats->counters, counter); -} - -void -dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type) { - int counter; - - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype); - - if (type == dns_rdatatype_dlv) - counter = rdtypecounter_dlv; - else if (type > dns_rdatatype_any) - counter = rdtypecounter_others; - else - counter = (int)type; - - isc_stats_increment(stats->counters, (isc_statscounter_t)counter); -} - -static inline void -update_rdatasetstats(dns_stats_t *stats, dns_rdatastatstype_t rrsettype, - bool increment) -{ - int counter; - dns_rdatatype_t rdtype; - - if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & - DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) { - counter = rdtypecounter_nxdomain; - } else { - rdtype = DNS_RDATASTATSTYPE_BASE(rrsettype); - if (rdtype == dns_rdatatype_dlv) - counter = (int)rdtypecounter_dlv; - else if (rdtype > dns_rdatatype_any) - counter = (int)rdtypecounter_others; - else - counter = (int)rdtype; - - if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & - DNS_RDATASTATSTYPE_ATTR_NXRRSET) != 0) - counter += rdtypecounter_max; - } - - if (increment) { - if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & - DNS_RDATASTATSTYPE_ATTR_STALE) != 0) { - isc_stats_decrement(stats->counters, counter); - counter += rdtypecounter_stale; - } - isc_stats_increment(stats->counters, counter); - } else { - if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & - DNS_RDATASTATSTYPE_ATTR_STALE) != 0) - counter += rdtypecounter_stale; - isc_stats_decrement(stats->counters, counter); - } -} - -void -dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype) -{ - REQUIRE(DNS_STATS_VALID(stats) && - stats->type == dns_statstype_rdataset); - - update_rdatasetstats(stats, rrsettype, true); -} - -void -dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype) -{ - REQUIRE(DNS_STATS_VALID(stats) && - stats->type == dns_statstype_rdataset); - - update_rdatasetstats(stats, rrsettype, false); -} - -void -dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) { - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode); - - isc_stats_increment(stats->counters, (isc_statscounter_t)code); -} - -void -dns_rcodestats_increment(dns_stats_t *stats, dns_rcode_t code) { - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rcode); - - if (code <= dns_rcode_badcookie) - isc_stats_increment(stats->counters, (isc_statscounter_t)code); -} - -/*% - * Dump methods - */ -void -dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn, - void *arg, unsigned int options) -{ - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general); - - isc_stats_dump(stats->counters, (isc_stats_dumper_t)dump_fn, - arg, options); -} - -static void -dump_rdentry(int rdcounter, uint64_t value, dns_rdatastatstype_t attributes, - dns_rdatatypestats_dumper_t dump_fn, void * arg) -{ - dns_rdatatype_t rdtype = dns_rdatatype_none; /* sentinel */ - dns_rdatastatstype_t type; - - if (rdcounter == rdtypecounter_others) - attributes |= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE; - else { - if (rdcounter == rdtypecounter_dlv) - rdtype = dns_rdatatype_dlv; - else - rdtype = (dns_rdatatype_t)rdcounter; - } - type = DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t)rdtype, - attributes); - dump_fn(type, value, arg); -} - -static void -rdatatype_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) { - rdatadumparg_t *rdatadumparg = arg; - - dump_rdentry(counter, value, 0, rdatadumparg->fn, rdatadumparg->arg); -} - -void -dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, - void *arg0, unsigned int options) -{ - rdatadumparg_t arg; - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype); - - arg.fn = dump_fn; - arg.arg = arg0; - isc_stats_dump(stats->counters, rdatatype_dumpcb, &arg, options); -} - -static void -rdataset_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) { - rdatadumparg_t *rdatadumparg = arg; - unsigned int attributes; - - if (counter < rdtypecounter_max) { - dump_rdentry(counter, value, 0, rdatadumparg->fn, - rdatadumparg->arg); - } else if (counter < rdtypecounter_nxdomain) { - counter -= rdtypecounter_max; - attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; - dump_rdentry(counter, value, attributes, rdatadumparg->fn, - rdatadumparg->arg); - } else if (counter == rdtypecounter_nxdomain) { - dump_rdentry(0, value, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN, - rdatadumparg->fn, rdatadumparg->arg); - } else if (counter < rdtypecounter_stale + rdtypecounter_max) { - counter -= rdtypecounter_stale; - attributes = DNS_RDATASTATSTYPE_ATTR_STALE; - dump_rdentry(counter, value, attributes, rdatadumparg->fn, - rdatadumparg->arg); - } else if (counter < rdtypecounter_stale + rdtypecounter_nxdomain) { - counter -= rdtypecounter_stale + rdtypecounter_max; - attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET | - DNS_RDATASTATSTYPE_ATTR_STALE; - dump_rdentry(counter, value, attributes, rdatadumparg->fn, - rdatadumparg->arg); - } else { - attributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN | - DNS_RDATASTATSTYPE_ATTR_STALE; - dump_rdentry(0, value, attributes, rdatadumparg->fn, - rdatadumparg->arg); - } -} - -void -dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, - void *arg0, unsigned int options) -{ - rdatadumparg_t arg; - - REQUIRE(DNS_STATS_VALID(stats) && - stats->type == dns_statstype_rdataset); - - arg.fn = dump_fn; - arg.arg = arg0; - isc_stats_dump(stats->counters, rdataset_dumpcb, &arg, options); -} - -static void -opcode_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) { - opcodedumparg_t *opcodearg = arg; - - opcodearg->fn((dns_opcode_t)counter, value, opcodearg->arg); -} - -static void -rcode_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) { - rcodedumparg_t *rcodearg = arg; - - rcodearg->fn((dns_rcode_t)counter, value, rcodearg->arg); -} - -void -dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn, - void *arg0, unsigned int options) -{ - opcodedumparg_t arg; - - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode); - - arg.fn = dump_fn; - arg.arg = arg0; - isc_stats_dump(stats->counters, opcode_dumpcb, &arg, options); -} - -void -dns_rcodestats_dump(dns_stats_t *stats, dns_rcodestats_dumper_t dump_fn, - void *arg0, unsigned int options) -{ - rcodedumparg_t arg; - - REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rcode); - - arg.fn = dump_fn; - arg.arg = arg0; - isc_stats_dump(stats->counters, rcode_dumpcb, &arg, options); -} - -/*** - *** Obsolete variables and functions follow: - ***/ -LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] = - { - "success", - "referral", - "nxrrset", - "nxdomain", - "recursion", - "failure", - "duplicate", - "dropped" - }; - -isc_result_t -dns_stats_alloccounters(isc_mem_t *mctx, uint64_t **ctrp) { - int i; - uint64_t *p = - isc_mem_get(mctx, DNS_STATS_NCOUNTERS * sizeof(uint64_t)); - if (p == NULL) - return (ISC_R_NOMEMORY); - for (i = 0; i < DNS_STATS_NCOUNTERS; i++) - p[i] = 0; - *ctrp = p; - return (ISC_R_SUCCESS); -} - -void -dns_stats_freecounters(isc_mem_t *mctx, uint64_t **ctrp) { - isc_mem_put(mctx, *ctrp, DNS_STATS_NCOUNTERS * sizeof(uint64_t)); - *ctrp = NULL; -} diff --git a/lib/dns-pkcs11/tcpmsg.c b/lib/dns-pkcs11/tcpmsg.c deleted file mode 100644 index ac20ff2..0000000 --- a/lib/dns-pkcs11/tcpmsg.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef TCPMSG_DEBUG -#include /* Required for printf. */ -#define XDEBUG(x) printf x -#else -#define XDEBUG(x) -#endif - -#define TCPMSG_MAGIC ISC_MAGIC('T', 'C', 'P', 'm') -#define VALID_TCPMSG(foo) ISC_MAGIC_VALID(foo, TCPMSG_MAGIC) - -static void recv_length(isc_task_t *, isc_event_t *); -static void recv_message(isc_task_t *, isc_event_t *); - - -static void -recv_length(isc_task_t *task, isc_event_t *ev_in) { - isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; - isc_event_t *dev; - dns_tcpmsg_t *tcpmsg = ev_in->ev_arg; - isc_region_t region; - isc_result_t result; - - INSIST(VALID_TCPMSG(tcpmsg)); - - dev = &tcpmsg->event; - /* cppcheck-suppress nullPointerRedundantCheck */ - tcpmsg->address = ev->address; - /* cppcheck-suppress nullPointerRedundantCheck */ - - if (ev->result != ISC_R_SUCCESS) { - tcpmsg->result = ev->result; - goto send_and_free; - } - - /* - * Success. - */ - tcpmsg->size = ntohs(tcpmsg->size); - if (tcpmsg->size == 0) { - tcpmsg->result = ISC_R_UNEXPECTEDEND; - goto send_and_free; - } - if (tcpmsg->size > tcpmsg->maxsize) { - tcpmsg->result = ISC_R_RANGE; - goto send_and_free; - } - - region.base = isc_mem_get(tcpmsg->mctx, tcpmsg->size); - region.length = tcpmsg->size; - if (region.base == NULL) { - tcpmsg->result = ISC_R_NOMEMORY; - goto send_and_free; - } - XDEBUG(("Allocated %d bytes\n", tcpmsg->size)); - - isc_buffer_init(&tcpmsg->buffer, region.base, region.length); - result = isc_socket_recv(tcpmsg->sock, ®ion, 0, - task, recv_message, tcpmsg); - if (result != ISC_R_SUCCESS) { - tcpmsg->result = result; - goto send_and_free; - } - - isc_event_free(&ev_in); - return; - - send_and_free: - isc_task_send(tcpmsg->task, &dev); - tcpmsg->task = NULL; - isc_event_free(&ev_in); - return; -} - -static void -recv_message(isc_task_t *task, isc_event_t *ev_in) { - isc_socketevent_t *ev;; - isc_event_t *dev; - dns_tcpmsg_t *tcpmsg; - - REQUIRE(VALID_TCPMSG(ev_in->ev_arg)); - - ev = (isc_socketevent_t *)ev_in; - tcpmsg = ev_in->ev_arg; - - (void)task; - - dev = &tcpmsg->event; - tcpmsg->address = ev->address; - - if (ev->result != ISC_R_SUCCESS) { - tcpmsg->result = ev->result; - goto send_and_free; - } - - tcpmsg->result = ISC_R_SUCCESS; - isc_buffer_add(&tcpmsg->buffer, ev->n); - - XDEBUG(("Received %u bytes (of %d)\n", ev->n, tcpmsg->size)); - - send_and_free: - isc_task_send(tcpmsg->task, &dev); - tcpmsg->task = NULL; - isc_event_free(&ev_in); -} - -void -dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg) { - REQUIRE(mctx != NULL); - REQUIRE(sock != NULL); - REQUIRE(tcpmsg != NULL); - - tcpmsg->magic = TCPMSG_MAGIC; - tcpmsg->size = 0; - tcpmsg->buffer.base = NULL; - tcpmsg->buffer.length = 0; - tcpmsg->maxsize = 65535; /* Largest message possible. */ - tcpmsg->mctx = mctx; - tcpmsg->sock = sock; - tcpmsg->task = NULL; /* None yet. */ - tcpmsg->result = ISC_R_UNEXPECTED; /* None yet. */ - /* - * Should probably initialize the event here, but it can wait. - */ -} - - -void -dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize) { - REQUIRE(VALID_TCPMSG(tcpmsg)); - REQUIRE(maxsize < 65536); - - tcpmsg->maxsize = maxsize; -} - - -isc_result_t -dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, - isc_task_t *task, isc_taskaction_t action, void *arg) -{ - isc_result_t result; - isc_region_t region; - - REQUIRE(VALID_TCPMSG(tcpmsg)); - REQUIRE(task != NULL); - REQUIRE(tcpmsg->task == NULL); /* not currently in use */ - - if (tcpmsg->buffer.base != NULL) { - isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, - tcpmsg->buffer.length); - tcpmsg->buffer.base = NULL; - tcpmsg->buffer.length = 0; - } - - tcpmsg->task = task; - tcpmsg->action = action; - tcpmsg->arg = arg; - tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */ - - ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0, - DNS_EVENT_TCPMSG, action, arg, tcpmsg, - NULL, NULL); - - region.base = (unsigned char *)&tcpmsg->size; - region.length = 2; /* uint16_t */ - result = isc_socket_recv(tcpmsg->sock, ®ion, 0, - tcpmsg->task, recv_length, tcpmsg); - - if (result != ISC_R_SUCCESS) - tcpmsg->task = NULL; - - return (result); -} - -void -dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg) { - REQUIRE(VALID_TCPMSG(tcpmsg)); - - isc_socket_cancel(tcpmsg->sock, NULL, ISC_SOCKCANCEL_RECV); -} - -void -dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer) { - REQUIRE(VALID_TCPMSG(tcpmsg)); - REQUIRE(buffer != NULL); - - *buffer = tcpmsg->buffer; - tcpmsg->buffer.base = NULL; - tcpmsg->buffer.length = 0; -} - -#if 0 -void -dns_tcpmsg_freebuffer(dns_tcpmsg_t *tcpmsg) { - REQUIRE(VALID_TCPMSG(tcpmsg)); - - if (tcpmsg->buffer.base == NULL) - return; - - isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length); - tcpmsg->buffer.base = NULL; - tcpmsg->buffer.length = 0; -} -#endif - -void -dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg) { - REQUIRE(VALID_TCPMSG(tcpmsg)); - - tcpmsg->magic = 0; - - if (tcpmsg->buffer.base != NULL) { - isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, - tcpmsg->buffer.length); - tcpmsg->buffer.base = NULL; - tcpmsg->buffer.length = 0; - } -} diff --git a/lib/dns-pkcs11/tests/Kdh.+002+18602.key b/lib/dns-pkcs11/tests/Kdh.+002+18602.key deleted file mode 100644 index 09b4cf5..0000000 --- a/lib/dns-pkcs11/tests/Kdh.+002+18602.key +++ /dev/null @@ -1 +0,0 @@ -dh. IN KEY 0 2 2 AAEBAAAAYIHI/wjtOagNga9GILSoS02IVelgLilPE/TfhtvShsiDAXqb IfxQcj2JkuOnNLs5ttb2WZXWl5/jsSjIxHMwMF2XY4gwt/lwHBf/vgYH r7aIxnKXov1jk9rymTLHGKIOtg== diff --git a/lib/dns-pkcs11/tests/Krsa.+005+29235.key b/lib/dns-pkcs11/tests/Krsa.+005+29235.key deleted file mode 100644 index e2d81e7..0000000 --- a/lib/dns-pkcs11/tests/Krsa.+005+29235.key +++ /dev/null @@ -1,5 +0,0 @@ -; This is a zone-signing key, keyid 29235, for rsa. -; Created: 20160819191802 (Fri Aug 19 21:18:02 2016) -; Publish: 20160819191802 (Fri Aug 19 21:18:02 2016) -; Activate: 20160819191802 (Fri Aug 19 21:18:02 2016) -rsa. IN DNSKEY 256 3 5 AwEAAdLT1R3qiqCqll3Xzh2qFMvehQ9FODsPftw5U4UjB3QwnJ/3+dph 9kZBBeaJagUBVYzoArk6XNydpp3HhSCFDcIiepL6r8XAifW3SqI1KCne OD38kSCl/Qm9P0+3CFWokGVubsSQ+3dpQZxqx5bzOXthbuzAr6X+gDUE LAyHtCQNmJ+4ktdCoj3DNYW0z/xLvrcB2Lns7H+/qWnGPL4f3hr7Vbak Oeay+4J4KGdY2LFxJUVts6QrgAA8gz4mV9YIJFP+C4B3b/Z7qgqZRxmT 0pic+fJC5+sq0l8KwavPn0n+HqVuJNvppVKMdTbsmmuk69RFGMjbFkP7 tnCiqC9Zi6s= diff --git a/lib/dns-pkcs11/tests/Kyuafile b/lib/dns-pkcs11/tests/Kyuafile deleted file mode 100644 index f3c0e38..0000000 --- a/lib/dns-pkcs11/tests/Kyuafile +++ /dev/null @@ -1,35 +0,0 @@ -syntax(2) -test_suite('bind9') - -tap_test_program{name='acl_test'} -tap_test_program{name='db_test'} -tap_test_program{name='dbdiff_test'} -tap_test_program{name='dbiterator_test'} -tap_test_program{name='dbversion_test'} -tap_test_program{name='dh_test'} -tap_test_program{name='dispatch_test'} -tap_test_program{name='dnstap_test'} -tap_test_program{name='dst_test'} -tap_test_program{name='dstrandom_test'} -tap_test_program{name='geoip_test'} -tap_test_program{name='gost_test'} -tap_test_program{name='keytable_test'} -tap_test_program{name='master_test'} -tap_test_program{name='name_test'} -tap_test_program{name='nsec3_test'} -tap_test_program{name='peer_test'} -tap_test_program{name='private_test'} -tap_test_program{name='rbt_serialize_test'} -tap_test_program{name='rbt_test'} -tap_test_program{name='rdata_test'} -tap_test_program{name='rdataset_test'} -tap_test_program{name='rdatasetstats_test'} -tap_test_program{name='resolver_test'} -tap_test_program{name='result_test'} -tap_test_program{name='rsa_test'} -tap_test_program{name='sigs_test'} -tap_test_program{name='time_test'} -tap_test_program{name='tsig_test'} -tap_test_program{name='update_test'} -tap_test_program{name='zonemgr_test'} -tap_test_program{name='zt_test'} diff --git a/lib/dns-pkcs11/tests/Makefile.in b/lib/dns-pkcs11/tests/Makefile.in deleted file mode 100644 index 0c184df..0000000 --- a/lib/dns-pkcs11/tests/Makefile.in +++ /dev/null @@ -1,276 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -VERSION=@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} \ - @DST_OPENSSL_INC@ ${MAXMINDDB_CFLAGS} -CDEFINES = @CRYPTO_PK11@ -DTESTS="\"${top_builddir}/lib/dns-pkcs11/tests/\"" - -ISCLIBS = ../../isc-pkcs11/libisc-pkcs11.@A@ -ISCDEPLIBS = ../../isc-pkcs11/libisc-pkcs11.@A@ -DNSLIBS = ../libdns-pkcs11.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@ -DNSDEPLIBS = ../libdns-pkcs11.@A@ - -LIBS = @LIBS@ @CMOCKA_LIBS@ -CFLAGS = @CFLAGS@ @CMOCKA_CFLAGS@ - -OBJS = dnstest.@O@ -SRCS = acl_test.c \ - db_test.c \ - dbdiff_test.c \ - dbiterator_test.c \ - dh_test.c \ - dispatch_test.c \ - dnstap_test.c \ - dst_test.c \ - dnstest.c \ - dstrandom_test.c \ - geoip_test.c \ - gost_test.c \ - keytable_test.c \ - master_test.c \ - name_test.c \ - nsec3_test.c \ - peer_test.c \ - private_test.c \ - rbt_test.c \ - rbt_serialize_test.c \ - rdata_test.c \ - rdataset_test.c \ - rdatasetstats_test.c \ - resolver_test.c \ - result_test.c \ - rsa_test.c \ - sigs_test.c \ - time_test.c \ - tsig_test.c \ - update_test.c \ - zonemgr_test.c \ - zt_test.c - -SUBDIRS = -TARGETS = acl_test@EXEEXT@ \ - db_test@EXEEXT@ \ - dbdiff_test@EXEEXT@ \ - dbiterator_test@EXEEXT@ \ - dbversion_test@EXEEXT@ \ - dh_test@EXEEXT@ \ - dispatch_test@EXEEXT@ \ - dnstap_test@EXEEXT@ \ - dstrandom_test@EXEEXT@ \ - dst_test@EXEEXT@ \ - geoip_test@EXEEXT@ \ - gost_test@EXEEXT@ \ - keytable_test@EXEEXT@ \ - master_test@EXEEXT@ \ - name_test@EXEEXT@ \ - nsec3_test@EXEEXT@ \ - peer_test@EXEEXT@ \ - private_test@EXEEXT@ \ - rbt_test@EXEEXT@ \ - rbt_serialize_test@EXEEXT@ \ - rdata_test@EXEEXT@ \ - rdataset_test@EXEEXT@ \ - rdatasetstats_test@EXEEXT@ \ - resolver_test@EXEEXT@ \ - result_test@EXEEXT@ \ - rsa_test@EXEEXT@ \ - sigs_test@EXEEXT@ \ - time_test@EXEEXT@ \ - tsig_test@EXEEXT@ \ - update_test@EXEEXT@ \ - zonemgr_test@EXEEXT@ \ - zt_test@EXEEXT@ - -@BIND9_MAKE_RULES@ - -acl_test@EXEEXT@: acl_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ acl_test.@O@ dnstest.@O@ ${DNSLIBS} \ - ${ISCLIBS} ${LIBS} - -db_test@EXEEXT@: db_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ db_test.@O@ dnstest.@O@ ${DNSLIBS} \ - ${ISCLIBS} ${LIBS} - -dbdiff_test@EXEEXT@: dbdiff_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dbdiff_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dbiterator_test@EXEEXT@: dbiterator_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dbiterator_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dbversion_test@EXEEXT@: dbversion_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dbversion_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dh_test@EXEEXT@: dh_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dh_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dispatch_test@EXEEXT@: dispatch_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dispatch_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dnstap_test@EXEEXT@: dnstap_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dnstap_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dst_test@EXEEXT@: dst_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ dst_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -geoip_test@EXEEXT@: geoip_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ geoip_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -gost_test@EXEEXT@: gost_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ gost_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -keytable_test@EXEEXT@: keytable_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ keytable_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -master_test@EXEEXT@: master_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - test -d testdata || mkdir testdata - test -d testdata/master || mkdir testdata/master - ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master12.data.in \ - > testdata/master/master12.data - ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master13.data.in \ - > testdata/master/master13.data - ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master14.data.in \ - > testdata/master/master14.data - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ master_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -name_test@EXEEXT@: name_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ name_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -nsec3_test@EXEEXT@: nsec3_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ nsec3_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -peer_test@EXEEXT@: peer_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ peer_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -private_test@EXEEXT@: private_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ private_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rbt_serialize_test@EXEEXT@: rbt_serialize_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rbt_serialize_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rbt_test@EXEEXT@: rbt_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rbt_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rdata_test@EXEEXT@: rdata_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rdata_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rdataset_test@EXEEXT@: rdataset_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rdataset_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rdatasetstats_test@EXEEXT@: rdatasetstats_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rdatasetstats_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -resolver_test@EXEEXT@: resolver_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ resolver_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -result_test@EXEEXT@: result_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ result_test.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -rsa_test@EXEEXT@: rsa_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ rsa_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -sigs_test@EXEEXT@: sigs_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ sigs_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -time_test@EXEEXT@: time_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ time_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -tsig_test@EXEEXT@: tsig_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ tsig_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -update_test@EXEEXT@: update_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ update_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -zonemgr_test@EXEEXT@: zonemgr_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ zonemgr_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -zt_test@EXEEXT@: zt_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \ - ${LDFLAGS} -o $@ zt_test.@O@ dnstest.@O@ \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -dstrandom_test@EXEEXT@: dstrandom_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dstrandom_test.@O@ ${DNSLIBS} \ - ${ISCLIBS} ${ISCPK11LIBS} ${LIBS} - -unit:: - sh ${top_builddir}/unit/unittest.sh - -clean distclean:: - rm -f ${TARGETS} - rm -f atf.out - rm -f testdata/master/master12.data testdata/master/master13.data \ - testdata/master/master14.data - rm -f zone.bin diff --git a/lib/dns-pkcs11/tests/acl_test.c b/lib/dns-pkcs11/tests/acl_test.c deleted file mode 100644 index b898ca1..0000000 --- a/lib/dns-pkcs11/tests/acl_test.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -#define BUFLEN 255 -#define BIGBUFLEN (70 * 1024) -#define TEST_ORIGIN "test" - -/* test that dns_acl_isinsecure works */ -static void -dns_acl_isinsecure_test(void **state) { - isc_result_t result; - unsigned int pass; - struct { - bool first; - bool second; - } ecs[] = { - { false, false }, - { true, true }, - { true, false }, - { false, true } - }; - - dns_acl_t *any = NULL; - dns_acl_t *none = NULL; - dns_acl_t *notnone = NULL; - dns_acl_t *notany = NULL; -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - dns_acl_t *geoip = NULL; - dns_acl_t *notgeoip = NULL; - dns_aclelement_t *de; -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - dns_acl_t *pos4pos6 = NULL; - dns_acl_t *notpos4pos6 = NULL; - dns_acl_t *neg4pos6 = NULL; - dns_acl_t *notneg4pos6 = NULL; - dns_acl_t *pos4neg6 = NULL; - dns_acl_t *notpos4neg6 = NULL; - dns_acl_t *neg4neg6 = NULL; - dns_acl_t *notneg4neg6 = NULL; - - dns_acl_t *loop4 = NULL; - dns_acl_t *notloop4 = NULL; - - dns_acl_t *loop6 = NULL; - dns_acl_t *notloop6 = NULL; - - dns_acl_t *loop4pos6 = NULL; - dns_acl_t *notloop4pos6 = NULL; - dns_acl_t *loop4neg6 = NULL; - dns_acl_t *notloop4neg6 = NULL; - - struct in_addr inaddr; - isc_netaddr_t addr; - - UNUSED(state); - - result = dns_acl_any(mctx, &any); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_none(mctx, &none); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬none); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬any); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notnone, none, false); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notany, any, false); - assert_int_equal(result, ISC_R_SUCCESS); - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - result = dns_acl_create(mctx, 1, &geoip); - assert_int_equal(result, ISC_R_SUCCESS); - - de = geoip->elements; - assert_non_null(de); - strlcpy(de->geoip_elem.as_string, "AU", - sizeof(de->geoip_elem.as_string)); - de->geoip_elem.subtype = dns_geoip_country_code; - de->type = dns_aclelementtype_geoip; - de->negative = false; - assert_true(geoip->length < geoip->alloc); - dns_acl_node_count(geoip)++; - de->node_num = dns_acl_node_count(geoip); - geoip->length++; - - result = dns_acl_create(mctx, 1, ¬geoip); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notgeoip, geoip, false); - assert_int_equal(result, ISC_R_SUCCESS); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - assert_true(dns_acl_isinsecure(any)); /* any; */ - assert_false(dns_acl_isinsecure(none)); /* none; */ - assert_false(dns_acl_isinsecure(notany)); /* !any; */ - assert_false(dns_acl_isinsecure(notnone)); /* !none; */ - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - assert_true(dns_acl_isinsecure(geoip)); /* geoip; */ - assert_false(dns_acl_isinsecure(notgeoip)); /* !geoip; */ -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - dns_acl_detach(&any); - dns_acl_detach(&none); - dns_acl_detach(¬any); - dns_acl_detach(¬none); -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - dns_acl_detach(&geoip); - dns_acl_detach(¬geoip); -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - - for (pass = 0; pass < sizeof(ecs)/sizeof(ecs[0]); pass++) { - result = dns_acl_create(mctx, 1, &pos4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬pos4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, &neg4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬neg4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, &pos4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬pos4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, &neg4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬neg4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x0a000000); /* 10.0.0.0 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(pos4pos6->iptable, &addr, 8, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* 0a00:: */ - result = dns_iptable_addprefix2(pos4pos6->iptable, &addr, 8, - true, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notpos4pos6, pos4pos6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x0a000000); /* !10.0.0.0/8 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(neg4pos6->iptable, &addr, 8, - false, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* 0a00::/8 */ - result = dns_iptable_addprefix2(neg4pos6->iptable, &addr, 8, - true, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notneg4pos6, neg4pos6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x0a000000); /* 10.0.0.0/8 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(pos4neg6->iptable, &addr, 8, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* !0a00::/8 */ - result = dns_iptable_addprefix2(pos4neg6->iptable, &addr, 8, - false, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notpos4neg6, pos4neg6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x0a000000); /* !10.0.0.0/8 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(neg4neg6->iptable, &addr, 8, - false, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* !0a00::/8 */ - result = dns_iptable_addprefix2(neg4neg6->iptable, &addr, 8, - false, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notneg4neg6, neg4neg6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_true(dns_acl_isinsecure(pos4pos6)); - assert_false(dns_acl_isinsecure(notpos4pos6)); - assert_true(dns_acl_isinsecure(neg4pos6)); - assert_false(dns_acl_isinsecure(notneg4pos6)); - assert_true(dns_acl_isinsecure(pos4neg6)); - assert_false(dns_acl_isinsecure(notpos4neg6)); - assert_false(dns_acl_isinsecure(neg4neg6)); - assert_false(dns_acl_isinsecure(notneg4neg6)); - - dns_acl_detach(&pos4pos6); - dns_acl_detach(¬pos4pos6); - dns_acl_detach(&neg4pos6); - dns_acl_detach(¬neg4pos6); - dns_acl_detach(&pos4neg6); - dns_acl_detach(¬pos4neg6); - dns_acl_detach(&neg4neg6); - dns_acl_detach(¬neg4neg6); - - result = dns_acl_create(mctx, 1, &loop4); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬loop4); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, &loop6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬loop6); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(loop4->iptable, &addr, 32, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notloop4, loop4, false); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_netaddr_fromin6(&addr, &in6addr_loopback); /* ::1 */ - result = dns_iptable_addprefix2(loop6->iptable, &addr, 128, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notloop6, loop6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - if (!ecs[pass].first) { - assert_false(dns_acl_isinsecure(loop4)); - assert_false(dns_acl_isinsecure(notloop4)); - assert_false(dns_acl_isinsecure(loop6)); - assert_false(dns_acl_isinsecure(notloop6)); - } else if (ecs[pass].first) { - assert_true(dns_acl_isinsecure(loop4)); - assert_false(dns_acl_isinsecure(notloop4)); - assert_true(dns_acl_isinsecure(loop6)); - assert_false(dns_acl_isinsecure(notloop6)); - } - - dns_acl_detach(&loop4); - dns_acl_detach(¬loop4); - dns_acl_detach(&loop6); - dns_acl_detach(¬loop6); - - result = dns_acl_create(mctx, 1, &loop4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬loop4pos6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, &loop4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_create(mctx, 1, ¬loop4neg6); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(loop4pos6->iptable, &addr, 32, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* f700:0001::/32 */ - result = dns_iptable_addprefix2(loop4pos6->iptable, &addr, 32, - true, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notloop4pos6, loop4pos6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - inaddr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ - isc_netaddr_fromin(&addr, &inaddr); - result = dns_iptable_addprefix2(loop4neg6->iptable, &addr, 32, - true, ecs[pass].first); - assert_int_equal(result, ISC_R_SUCCESS); - - addr.family = AF_INET6; /* !f700:0001::/32 */ - result = dns_iptable_addprefix2(loop4neg6->iptable, &addr, 32, - false, ecs[pass].second); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_acl_merge(notloop4neg6, loop4neg6, false); - assert_int_equal(result, ISC_R_SUCCESS); - - if (!ecs[pass].first && !ecs[pass].second) { - assert_true(dns_acl_isinsecure(loop4pos6)); - assert_false(dns_acl_isinsecure(notloop4pos6)); - assert_false(dns_acl_isinsecure(loop4neg6)); - assert_false(dns_acl_isinsecure(notloop4neg6)); - } else if (ecs[pass].first && !ecs[pass].second) { - assert_true(dns_acl_isinsecure(loop4pos6)); - assert_false(dns_acl_isinsecure(notloop4pos6)); - assert_true(dns_acl_isinsecure(loop4neg6)); - assert_false(dns_acl_isinsecure(notloop4neg6)); - } else if (!ecs[pass].first && ecs[pass].second) { - assert_true(dns_acl_isinsecure(loop4pos6)); - assert_false(dns_acl_isinsecure(notloop4pos6)); - assert_false(dns_acl_isinsecure(loop4neg6)); - assert_false(dns_acl_isinsecure(notloop4neg6)); - } else { - assert_true(dns_acl_isinsecure(loop4pos6)); - assert_false(dns_acl_isinsecure(notloop4pos6)); - assert_true(dns_acl_isinsecure(loop4neg6)); - assert_false(dns_acl_isinsecure(notloop4neg6)); - } - - dns_acl_detach(&loop4pos6); - dns_acl_detach(¬loop4pos6); - dns_acl_detach(&loop4neg6); - dns_acl_detach(¬loop4neg6); - } -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(dns_acl_isinsecure_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/db_test.c b/lib/dns-pkcs11/tests/db_test.c deleted file mode 100644 index 60fdb81..0000000 --- a/lib/dns-pkcs11/tests/db_test.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include - -#define UNIT_TESTING -#include - -#include - -#include -#include -#include -#include -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -#define BUFLEN 255 -#define BIGBUFLEN (64 * 1024) -#define TEST_ORIGIN "test" - -/* - * Individual unit tests - */ - -/* test multiple calls to dns_db_getoriginnode */ -static void -getoriginnode_test(void **state) { - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - isc_mem_t *mymctx = NULL; - isc_result_t result; - - UNUSED(state); - - result = isc_mem_create(0, 0, &mymctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_getoriginnode(db, &node); - assert_int_equal(result, ISC_R_SUCCESS); - dns_db_detachnode(db, &node); - - result = dns_db_getoriginnode(db, &node); - assert_int_equal(result, ISC_R_SUCCESS); - dns_db_detachnode(db, &node); - - dns_db_detach(&db); - isc_mem_detach(&mymctx); -} - -/* test getservestalettl and setservestalettl */ -static void -getsetservestalettl_test(void **state) { - dns_db_t *db = NULL; - isc_mem_t *mymctx = NULL; - isc_result_t result; - dns_ttl_t ttl; - - UNUSED(state); - - result = isc_mem_create(0, 0, &mymctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_cache, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - - ttl = 5000; - result = dns_db_getservestalettl(db, &ttl); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(ttl, 0); - - ttl = 6 * 3600; - result = dns_db_setservestalettl(db, ttl); - assert_int_equal(result, ISC_R_SUCCESS); - - ttl = 5000; - result = dns_db_getservestalettl(db, &ttl); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(ttl, 6 * 3600); - - dns_db_detach(&db); - isc_mem_detach(&mymctx); -} - -/* check DNS_DBFIND_STALEOK works */ -static void -dns_dbfind_staleok_test(void **state) { - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; - dns_fixedname_t example_fixed; - dns_fixedname_t found_fixed; - dns_name_t *example; - dns_name_t *found; - dns_rdatalist_t rdatalist; - dns_rdataset_t rdataset; - int count; - int pass; - isc_mem_t *mymctx = NULL; - isc_result_t result; - unsigned char data[] = { 0x0a, 0x00, 0x00, 0x01 }; - - UNUSED(state); - - result = isc_mem_create(0, 0, &mymctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_cache, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - - example = dns_fixedname_initname(&example_fixed); - found = dns_fixedname_initname(&found_fixed); - - result = dns_name_fromstring(example, "example", 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Pass 0: default; no stale processing permitted. - * Pass 1: stale processing for 1 second. - * Pass 2: stale turned off after being on. - */ - for (pass = 0; pass < 3; pass++) { - dns_rdata_t rdata = DNS_RDATA_INIT; - - /* 10.0.0.1 */ - rdata.data = data; - rdata.length = 4; - rdata.rdclass = dns_rdataclass_in; - rdata.type = dns_rdatatype_a; - - dns_rdatalist_init(&rdatalist); - rdatalist.ttl = 2; - rdatalist.type = dns_rdatatype_a; - rdatalist.rdclass = dns_rdataclass_in; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - switch (pass) { - case 0: - /* default: stale processing off */ - break; - case 1: - /* turn on stale processing */ - result = dns_db_setservestalettl(db, 1); - assert_int_equal(result, ISC_R_SUCCESS); - break; - case 2: - /* turn off stale processing */ - result = dns_db_setservestalettl(db, 0); - assert_int_equal(result, ISC_R_SUCCESS); - break; - } - - dns_rdataset_init(&rdataset); - result = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_findnode(db, example, true, &node); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_addrdataset(db, node, NULL, 0, &rdataset, 0, - NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_db_detachnode(db, &node); - dns_rdataset_disassociate(&rdataset); - - result = dns_db_find(db, example, NULL, dns_rdatatype_a, - 0, 0, &node, found, &rdataset, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * May loop for up to 2 seconds performing non stale lookups. - */ - count = 0; - do { - count++; - assert_in_range(count, 0, 20); /* loop sanity */ - assert_int_equal(rdataset.attributes & - DNS_RDATASETATTR_STALE, 0); - assert_true(rdataset.ttl > 0); - dns_db_detachnode(db, &node); - dns_rdataset_disassociate(&rdataset); - - usleep(100000); /* 100 ms */ - - result = dns_db_find(db, example, NULL, - dns_rdatatype_a, 0, 0, - &node, found, &rdataset, NULL); - } while (result == ISC_R_SUCCESS); - - assert_int_equal(result, ISC_R_NOTFOUND); - - /* - * Check whether we can get stale data. - */ - result = dns_db_find(db, example, NULL, dns_rdatatype_a, - DNS_DBFIND_STALEOK, 0, - &node, found, &rdataset, NULL); - switch (pass) { - case 0: - assert_int_equal(result, ISC_R_NOTFOUND); - break; - case 1: - /* - * Should loop for 1 second with stale lookups then - * stop. - */ - count = 0; - do { - count++; - assert_in_range(count, 0, 49); /* loop sanity */ - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdataset.ttl, 0); - assert_int_equal(rdataset.attributes & - DNS_RDATASETATTR_STALE, - DNS_RDATASETATTR_STALE); - dns_db_detachnode(db, &node); - dns_rdataset_disassociate(&rdataset); - - usleep(100000); /* 100 ms */ - - result = dns_db_find(db, example, NULL, - dns_rdatatype_a, - DNS_DBFIND_STALEOK, - 0, &node, found, - &rdataset, NULL); - } while (result == ISC_R_SUCCESS); - assert_in_range(count, 1, 10); - assert_int_equal(result, ISC_R_NOTFOUND); - break; - case 2: - assert_int_equal(result, ISC_R_NOTFOUND); - break; - } - } - - dns_db_detach(&db); - isc_mem_detach(&mymctx); -} - -/* database class */ -static void -class_test(void **state) { - isc_result_t result; - dns_db_t *db = NULL; - - UNUSED(state); - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_load(db, "testdata/db/data.db"); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_int_equal(dns_db_class(db), dns_rdataclass_in); - - dns_db_detach(&db); -} - -/* database type */ -static void -dbtype_test(void **state) { - isc_result_t result; - dns_db_t *db = NULL; - - UNUSED(state); - - /* DB has zone semantics */ - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_db_load(db, "testdata/db/data.db"); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(dns_db_iszone(db)); - assert_false(dns_db_iscache(db)); - dns_db_detach(&db); - - /* DB has cache semantics */ - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_db_load(db, "testdata/db/data.db"); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(dns_db_iscache(db)); - assert_false(dns_db_iszone(db)); - dns_db_detach(&db); - -} - -/* database versions */ -static void -version_test(void **state) { - isc_result_t result; - dns_fixedname_t fname, ffound; - dns_name_t *name, *foundname; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL, *new = NULL; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - - UNUSED(state); - - result = dns_test_loaddb(&db, dns_dbtype_zone, "test.test", - "testdata/db/data.db"); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Open current version for reading */ - dns_db_currentversion(db, &ver); - dns_test_namefromstring("b.test.test", &fname); - name = dns_fixedname_name(&fname); - foundname = dns_fixedname_initname(&ffound); - dns_rdataset_init(&rdataset); - result = dns_db_find(db, name , ver, dns_rdatatype_a, 0, 0, &node, - foundname, &rdataset, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - dns_db_closeversion(db, &ver, false); - - /* Open new version for writing */ - dns_db_currentversion(db, &ver); - dns_test_namefromstring("b.test.test", &fname); - name = dns_fixedname_name(&fname); - foundname = dns_fixedname_initname(&ffound); - dns_rdataset_init(&rdataset); - result = dns_db_find(db, name , ver, dns_rdatatype_a, 0, 0, &node, - foundname, &rdataset, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_newversion(db, &new); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Delete the rdataset from the new version */ - result = dns_db_deleterdataset(db, node, new, dns_rdatatype_a, 0); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - - /* This should fail now */ - result = dns_db_find(db, name, new, dns_rdatatype_a, 0, 0, &node, - foundname, &rdataset, NULL); - assert_int_equal(result, DNS_R_NXDOMAIN); - - dns_db_closeversion(db, &new, true); - - /* But this should still succeed */ - result = dns_db_find(db, name, ver, dns_rdatatype_a, 0, 0, &node, - foundname, &rdataset, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - dns_db_closeversion(db, &ver, false); - - dns_db_detach(&db); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(getoriginnode_test), - cmocka_unit_test(getsetservestalettl_test), - cmocka_unit_test(dns_dbfind_staleok_test), - cmocka_unit_test_setup_teardown(class_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dbtype_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(version_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dbdiff_test.c b/lib/dns-pkcs11/tests/dbdiff_test.c deleted file mode 100644 index 90456d5..0000000 --- a/lib/dns-pkcs11/tests/dbdiff_test.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include - -#include -#include -#include -#include - -#include "dnstest.h" - -#define BUFLEN 255 -#define BIGBUFLEN (64 * 1024) -#define TEST_ORIGIN "test" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static void -test_create(const char *oldfile, dns_db_t **old, - const char *newfile, dns_db_t **newdb) -{ - isc_result_t result; - - result = dns_test_loaddb(old, dns_dbtype_zone, TEST_ORIGIN, oldfile); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_test_loaddb(newdb, dns_dbtype_zone, TEST_ORIGIN, newfile); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* dns_db_diffx of identical content */ -static void -diffx_same(void **state) { - dns_db_t *newdb = NULL, *olddb = NULL; - isc_result_t result; - dns_diff_t diff; - - UNUSED(state); - - test_create("testdata/diff/zone1.data", &olddb, - "testdata/diff/zone1.data", &newdb); - - dns_diff_init(mctx, &diff); - - result = dns_db_diffx(&diff, newdb, NULL, olddb, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_true(ISC_LIST_EMPTY(diff.tuples)); - - dns_diff_clear(&diff); - dns_db_detach(&newdb); - dns_db_detach(&olddb); -} - -/* dns_db_diffx of zone with record added */ -static void -diffx_add(void **state) { - dns_db_t *newdb = NULL, *olddb = NULL; - dns_difftuple_t *tuple; - isc_result_t result; - dns_diff_t diff; - int count = 0; - - UNUSED(state); - - test_create("testdata/diff/zone1.data", &olddb, - "testdata/diff/zone2.data", &newdb); - - dns_diff_init(mctx, &diff); - - result = dns_db_diffx(&diff, newdb, NULL, olddb, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_false(ISC_LIST_EMPTY(diff.tuples)); - for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - assert_int_equal(tuple->op, DNS_DIFFOP_ADD); - count++; - } - assert_int_equal(count, 1); - - dns_diff_clear(&diff); - dns_db_detach(&newdb); - dns_db_detach(&olddb); -} - -/* dns_db_diffx of zone with record removed */ -static void -diffx_remove(void **state) { - dns_db_t *newdb = NULL, *olddb = NULL; - dns_difftuple_t *tuple; - isc_result_t result; - dns_diff_t diff; - int count = 0; - - UNUSED(state); - - test_create("testdata/diff/zone1.data", &olddb, - "testdata/diff/zone3.data", &newdb); - - dns_diff_init(mctx, &diff); - - result = dns_db_diffx(&diff, newdb, NULL, olddb, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_false(ISC_LIST_EMPTY(diff.tuples)); - for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - assert_int_equal(tuple->op, DNS_DIFFOP_DEL); - count++; - } - assert_int_equal(count, 1); - - dns_diff_clear(&diff); - dns_db_detach(&newdb); - dns_db_detach(&olddb); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(diffx_same, _setup, _teardown), - cmocka_unit_test_setup_teardown(diffx_add, _setup, _teardown), - cmocka_unit_test_setup_teardown(diffx_remove, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dbiterator_test.c b/lib/dns-pkcs11/tests/dbiterator_test.c deleted file mode 100644 index a7dbbc4..0000000 --- a/lib/dns-pkcs11/tests/dbiterator_test.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include - -#include -#include -#include - -#include "dnstest.h" - -#define BUFLEN 255 -#define BIGBUFLEN (64 * 1024) -#define TEST_ORIGIN "test" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static isc_result_t -make_name(const char *src, dns_name_t *name) { - isc_buffer_t b; - isc_buffer_constinit(&b, src, strlen(src)); - isc_buffer_add(&b, strlen(src)); - return (dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); -} - -/* create: make sure we can create a dbiterator */ -static void -test_create(const char *filename) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -create(void **state) { - UNUSED(state); - - test_create("testdata/dbiterator/zone1.data"); -} - -static void -create_nsec3(void **state) { - UNUSED(state); - - test_create("testdata/dbiterator/zone2.data"); -} - -/* walk: walk a database */ -static void -test_walk(const char *filename, int nodes) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - dns_dbnode_t *node = NULL; - dns_name_t *name; - dns_fixedname_t f; - int i = 0; - - name = dns_fixedname_initname(&f); - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - for (result = dns_dbiterator_first(iter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(iter)) { - result = dns_dbiterator_current(iter, &node, name); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - assert_int_equal(result, ISC_R_SUCCESS); - dns_db_detachnode(db, &node); - i++; - } - - assert_int_equal(i, nodes); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -walk(void **state) { - UNUSED(state); - - test_walk("testdata/dbiterator/zone1.data", 12); -} - -static void -walk_nsec3(void **state) { - UNUSED(state); - - test_walk("testdata/dbiterator/zone2.data", 33); -} - -/* reverse: walk database backwards */ -static void -test_reverse(const char *filename) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - dns_dbnode_t *node = NULL; - dns_name_t *name; - dns_fixedname_t f; - int i = 0; - - name = dns_fixedname_initname(&f); - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - for (result = dns_dbiterator_last(iter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_prev(iter)) { - result = dns_dbiterator_current(iter, &node, name); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - assert_int_equal(result, ISC_R_SUCCESS); - dns_db_detachnode(db, &node); - i++; - } - - assert_int_equal(i, 12); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -reverse(void **state) { - UNUSED(state); - - test_reverse("testdata/dbiterator/zone1.data"); -} - -static void -reverse_nsec3(void **state) { - UNUSED(state); - - test_reverse("testdata/dbiterator/zone2.data"); -} - -/* seek: walk database starting at a particular node */ -static void -test_seek_node(const char *filename, int nodes) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - dns_dbnode_t *node = NULL; - dns_name_t *name, *seekname; - dns_fixedname_t f1, f2; - int i = 0; - - name = dns_fixedname_initname(&f1); - seekname = dns_fixedname_initname(&f2); - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - result = make_name("c." TEST_ORIGIN, seekname); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dbiterator_seek(iter, seekname); - assert_int_equal(result, ISC_R_SUCCESS); - - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(iter, &node, name); - if (result == DNS_R_NEWORIGIN) - result = ISC_R_SUCCESS; - assert_int_equal(result, ISC_R_SUCCESS); - dns_db_detachnode(db, &node); - result = dns_dbiterator_next(iter); - i++; - } - - assert_int_equal(i, nodes); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -seek_node(void **state) { - UNUSED(state); - - test_seek_node("testdata/dbiterator/zone1.data", 9); -} - -static void -seek_node_nsec3(void **state) { - UNUSED(state); - - test_seek_node("testdata/dbiterator/zone2.data", 30); -} - -/* - * seek_emty: walk database starting at an empty nonterminal node - * (should fail) - */ -static void -test_seek_empty(const char *filename) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - dns_name_t *seekname; - dns_fixedname_t f1; - - seekname = dns_fixedname_initname(&f1); - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - result = make_name("d." TEST_ORIGIN, seekname); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dbiterator_seek(iter, seekname); - assert_int_equal(result, DNS_R_PARTIALMATCH); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -seek_empty(void **state) { - UNUSED(state); - - test_seek_empty("testdata/dbiterator/zone1.data"); -} - -static void -seek_empty_nsec3(void **state) { - UNUSED(state); - - test_seek_empty("testdata/dbiterator/zone2.data"); -} - -/* - * seek_nx: walk database starting at a nonexistent node - */ -static void -test_seek_nx(const char *filename) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbiterator_t *iter = NULL; - dns_name_t *seekname; - dns_fixedname_t f1; - - seekname = dns_fixedname_initname(&f1); - - result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, filename); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_createiterator(db, 0, &iter); - assert_int_equal(result, ISC_R_SUCCESS); - - result = make_name("nonexistent." TEST_ORIGIN, seekname); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dbiterator_seek(iter, seekname); - assert_int_equal(result, DNS_R_PARTIALMATCH); - - result = make_name("nonexistent.", seekname); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dbiterator_seek(iter, seekname); - assert_int_equal(result, ISC_R_NOTFOUND); - - dns_dbiterator_destroy(&iter); - dns_db_detach(&db); -} - -static void -seek_nx(void **state) { - UNUSED(state); - - test_seek_nx("testdata/dbiterator/zone1.data"); -} - -static void -seek_nx_nsec3(void **state) { - UNUSED(state); - - test_seek_nx("testdata/dbiterator/zone2.data"); -} - -/* - * XXX: - * dns_dbiterator API calls that are not yet part of this unit test: - * - * dns_dbiterator_pause - * dns_dbiterator_origin - * dns_dbiterator_setcleanmode - */ -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create, _setup, _teardown), - cmocka_unit_test_setup_teardown(create_nsec3, - _setup, _teardown), - cmocka_unit_test_setup_teardown(walk, _setup, _teardown), - cmocka_unit_test_setup_teardown(walk_nsec3, _setup, _teardown), - cmocka_unit_test_setup_teardown(reverse, _setup, _teardown), - cmocka_unit_test_setup_teardown(reverse_nsec3, - _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_node, _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_node_nsec3, - _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_empty, _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_empty_nsec3, - _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_nx, _setup, _teardown), - cmocka_unit_test_setup_teardown(seek_nx_nsec3, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dbversion_test.c b/lib/dns-pkcs11/tests/dbversion_test.c deleted file mode 100644 index e3b07b3..0000000 --- a/lib/dns-pkcs11/tests/dbversion_test.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "dnstest.h" - -static char tempname[11] = "dtXXXXXXXX"; -static dns_db_t *db1 = NULL, *db2 = NULL; -static dns_dbversion_t *v1 = NULL, *v2 = NULL; - -#ifndef ISC_CHECK_NONE -/* - * The code below enables us to trap assertion failures for testing - * purposes. local_callback() is set as the callback function for - * isc_assertion_failed(). It calls mock_assert() so that CMOCKA - * will be able to see it, then returns to the calling function via - * longjmp() so that the abort() call in isc_assertion_failed() will - * never be reached. Use check_assertion() to check for assertions - * instead of expect_assert_failure(). - */ -jmp_buf assertion; - -#define check_assertion(function_call) \ - do { \ - const int r = setjmp(assertion); \ - if (r == 0) { \ - expect_assert_failure(function_call); \ - } \ - } while(false); - -static void -local_callback(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ - UNUSED(type); - - mock_assert(1, cond, file, line); - longjmp(assertion, 1); -} -#else -#define check_assertion(function_call) -#endif /* ISC_CHECK_NONE */ - -static int -_setup(void **state) { - isc_result_t res; - - UNUSED(state); - -#ifndef ISC_CHECK_NONE - isc_assertion_setcallback(local_callback); -#endif - - res = dns_test_begin(NULL, false); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db1); - assert_int_equal(res, ISC_R_SUCCESS); - dns_db_newversion(db1, &v1); - assert_non_null(v1); - - res = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db2); - assert_int_equal(res, ISC_R_SUCCESS); - dns_db_newversion(db2, &v2); - assert_non_null(v1); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - if (strcmp(tempname, "dtXXXXXXXX") != 0) { - unlink(tempname); - } - - if (v1 != NULL) { - dns_db_closeversion(db1, &v1, false); - assert_null(v1); - } - if (db1 != NULL) { - dns_db_detach(&db1); - assert_null(db1); - } - - if (v2 != NULL) { - dns_db_closeversion(db2, &v2, false); - assert_null(v2); - } - if (db2 != NULL) { - dns_db_detach(&db2); - assert_null(db2); - } - - dns_test_end(); - - return (0); -} - -/* - * Check dns_db_attachversion() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -attachversion(void **state) { - dns_dbversion_t *v = NULL; - - UNUSED(state); - - dns_db_attachversion(db1, v1, &v); - assert_ptr_equal(v, v1); - dns_db_closeversion(db1, &v, false); - assert_null(v); - - check_assertion(dns_db_attachversion(db1, v2, &v)); -} - -/* - * Check dns_db_closeversion() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -closeversion(void **state) { - UNUSED(state); - - assert_non_null(v1); - dns_db_closeversion(db1, &v1, false); - assert_null(v1); - - check_assertion(dns_db_closeversion(db1, &v2, false)); -} - -/* - * Check dns_db_find() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -find(void **state) { - isc_result_t res; - dns_rdataset_t rdataset; - dns_fixedname_t fixed; - dns_name_t *name = NULL; - - UNUSED(state); - - name = dns_fixedname_initname(&fixed); - - dns_rdataset_init(&rdataset); - res = dns_db_find(db1, dns_rootname, v1, dns_rdatatype_soa, - 0, 0, NULL, name, &rdataset, NULL); - assert_int_equal(res, DNS_R_NXDOMAIN); - - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_disassociate(&rdataset); - } - - dns_rdataset_init(&rdataset); - check_assertion((void)dns_db_find(db1, dns_rootname, v2, - dns_rdatatype_soa, 0, 0, NULL, - name, &rdataset, NULL)); -} - -/* - * Check dns_db_allrdatasets() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -allrdatasets(void **state) { - isc_result_t res; - dns_dbnode_t *node = NULL; - dns_rdatasetiter_t *iterator = NULL; - - UNUSED(state); - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_allrdatasets(db1, node, v1, 0, &iterator); - assert_int_equal(res, ISC_R_SUCCESS); - - check_assertion(dns_db_allrdatasets(db1, node, v2, 0, &iterator)); - - dns_rdatasetiter_destroy(&iterator); - assert_null(iterator); - - dns_db_detachnode(db1, &node); - assert_null(node); - - -} - -/* - * Check dns_db_findrdataset() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -findrdataset(void **state) { - isc_result_t res; - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - - UNUSED(state); - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - dns_rdataset_init(&rdataset); - res = dns_db_findrdataset(db1, node, v1, dns_rdatatype_soa, - 0, 0, &rdataset, NULL); - assert_int_equal(res, ISC_R_NOTFOUND); - - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_disassociate(&rdataset); - } - - dns_rdataset_init(&rdataset); - check_assertion(dns_db_findrdataset(db1, node, v2, - dns_rdatatype_soa, 0, 0, - &rdataset, NULL)); - - dns_db_detachnode(db1, &node); - assert_null(node); -} - -/* - * Check dns_db_deleterdataset() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -deleterdataset(void **state) { - isc_result_t res; - dns_dbnode_t *node = NULL; - - UNUSED(state); - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_deleterdataset(db1, node, v1, dns_rdatatype_soa, 0); - assert_int_equal(res, DNS_R_UNCHANGED); - - check_assertion(dns_db_deleterdataset(db1, node, v2, - dns_rdatatype_soa, 0)); - dns_db_detachnode(db1, &node); - assert_null(node); -} - -/* - * Check dns_db_subtractrdataset() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -subtract(void **state) { - isc_result_t res; - dns_rdataset_t rdataset; - dns_rdatalist_t rdatalist; - dns_dbnode_t *node = NULL; - - UNUSED(state); - - dns_rdataset_init(&rdataset); - dns_rdatalist_init(&rdatalist); - - rdatalist.rdclass = dns_rdataclass_in; - - res = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_subtractrdataset(db1, node, v1, &rdataset, 0, NULL); - assert_int_equal(res, DNS_R_UNCHANGED); - - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_disassociate(&rdataset); - } - - dns_rdataset_init(&rdataset); - res = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(res, ISC_R_SUCCESS); - - check_assertion(dns_db_subtractrdataset(db1, node, v2, - &rdataset, 0, NULL)); - - dns_db_detachnode(db1, &node); - assert_null(node); -} - -/* - * Check dns_db_dump() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -dump(void **state) { - isc_result_t res; - FILE *f = NULL; - - UNUSED(state); - - res = isc_file_openunique(tempname, &f); - fclose(f); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_dump(db1, v1, tempname); - assert_int_equal(res, ISC_R_SUCCESS); - - check_assertion(dns_db_dump(db1, v2, tempname)); -} - -/* - * Check dns_db_addrdataset() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -addrdataset(void **state) { - isc_result_t res; - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - dns_rdatalist_t rdatalist; - - UNUSED(state); - - dns_rdataset_init(&rdataset); - dns_rdatalist_init(&rdatalist); - - rdatalist.rdclass = dns_rdataclass_in; - - res = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, NULL); - assert_int_equal(res, ISC_R_SUCCESS); - - check_assertion(dns_db_addrdataset(db1, node, v2, - 0, &rdataset, 0, NULL)); - - dns_db_detachnode(db1, &node); - assert_null(node); -} - -/* - * Check dns_db_getnsec3parameters() passes with matching db and version, - * and asserts with mis-matching db and version. - */ -static void -getnsec3parameters(void **state) { - isc_result_t res; - dns_hash_t hash; - uint8_t flags; - uint16_t iterations; - unsigned char salt[DNS_NSEC3_SALTSIZE]; - size_t salt_length = sizeof(salt); - - UNUSED(state); - - res = dns_db_getnsec3parameters(db1, v1, &hash, - &flags, &iterations, salt, - &salt_length); - assert_int_equal(res, ISC_R_NOTFOUND); - - check_assertion(dns_db_getnsec3parameters(db1, v2, &hash, - &flags, &iterations, - salt, &salt_length)); -} - -/* - * Check dns_db_resigned() passes with matching db and version, and - * asserts with mis-matching db and version. - */ -static void -resigned(void **state) { - isc_result_t res; - dns_rdataset_t rdataset, added; - dns_dbnode_t *node = NULL; - dns_rdatalist_t rdatalist; - dns_rdata_rrsig_t rrsig; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t b; - unsigned char buf[1024]; - - UNUSED(state); - - /* - * Create a dummy RRSIG record and set a resigning time. - */ - dns_rdataset_init(&added); - dns_rdataset_init(&rdataset); - dns_rdatalist_init(&rdatalist); - isc_buffer_init(&b, buf, sizeof(buf)); - - DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in); - rrsig.covered = dns_rdatatype_a; - rrsig.algorithm = 100; - rrsig.labels = 0; - rrsig.originalttl = 0; - rrsig.timeexpire = 3600; - rrsig.timesigned = 0; - rrsig.keyid = 0; - dns_name_init(&rrsig.signer, NULL); - dns_name_clone(dns_rootname, &rrsig.signer); - rrsig.siglen = 0; - rrsig.signature = NULL; - - res = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, - dns_rdatatype_rrsig, &rrsig, &b); - assert_int_equal(res, ISC_R_SUCCESS); - - rdatalist.rdclass = dns_rdataclass_in; - rdatalist.type = dns_rdatatype_rrsig; - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - - res = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(res, ISC_R_SUCCESS); - - rdataset.attributes |= DNS_RDATASETATTR_RESIGN; - rdataset.resign = 7200; - - res = dns_db_findnode(db1, dns_rootname, false, &node); - assert_int_equal(res, ISC_R_SUCCESS); - - res = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added); - assert_int_equal(res, ISC_R_SUCCESS); - - dns_db_detachnode(db1, &node); - assert_null(node); - - check_assertion(dns_db_resigned(db1, &added, v2)); - - dns_db_resigned(db1, &added, v1); - - dns_rdataset_disassociate(&added); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(dump, _setup, _teardown), - cmocka_unit_test_setup_teardown(find, _setup, _teardown), - cmocka_unit_test_setup_teardown(allrdatasets, - _setup, _teardown), - cmocka_unit_test_setup_teardown(findrdataset, - _setup, _teardown), - cmocka_unit_test_setup_teardown(deleterdataset, - _setup, _teardown), - cmocka_unit_test_setup_teardown(subtract, - _setup, _teardown), - cmocka_unit_test_setup_teardown(addrdataset, - _setup, _teardown), - cmocka_unit_test_setup_teardown(getnsec3parameters, - _setup, _teardown), - cmocka_unit_test_setup_teardown(resigned, - _setup, _teardown), - cmocka_unit_test_setup_teardown(attachversion, - _setup, _teardown), - cmocka_unit_test_setup_teardown(closeversion, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dh_test.c b/lib/dns-pkcs11/tests/dh_test.c deleted file mode 100644 index c972fa2..0000000 --- a/lib/dns-pkcs11/tests/dh_test.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include - -#include - -#include - -#include "../dst_internal.h" - -#include "dnstest.h" - -#if defined(OPENSSL) && !defined(PK11_DH_DISABLE) -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* OpenSSL DH_compute_key() failure */ -static void -dh_computesecret(void **state) { - dst_key_t *key = NULL; - isc_buffer_t buf; - unsigned char array[1024]; - isc_result_t result; - dns_fixedname_t fname; - dns_name_t *name; - - UNUSED(state); - - name = dns_fixedname_initname(&fname); - isc_buffer_constinit(&buf, "dh.", 3); - isc_buffer_add(&buf, 3); - result = dns_name_fromtext(name, &buf, NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dst_key_fromfile(name, 18602, DST_ALG_DH, - DST_TYPE_PUBLIC | DST_TYPE_KEY, - "./", mctx, &key); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_buffer_init(&buf, array, sizeof(array)); - result = dst_key_computesecret(key, key, &buf); - assert_int_equal(result, DST_R_NOTPRIVATEKEY); - result = key->func->computesecret(key, key, &buf); - /* PKCS11 variant gives different result, accept both */ - assert_true(result == DST_R_COMPUTESECRETFAILURE || result == DST_R_INVALIDPRIVATEKEY); - - dst_key_free(&key); -} -#endif - -int -main(void) { -#if defined(OPENSSL) && !defined(PK11_DH_DISABLE) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(dh_computesecret, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skipped: dh test broken with PKCS11"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dispatch_test.c b/lib/dns-pkcs11/tests/dispatch_test.c deleted file mode 100644 index 5bca3fd..0000000 --- a/lib/dns-pkcs11/tests/dispatch_test.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dnstest.h" - -dns_dispatchmgr_t *dispatchmgr = NULL; -dns_dispatchset_t *dset = NULL; - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, true); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static isc_result_t -make_dispatchset(unsigned int ndisps) { - isc_result_t result; - isc_sockaddr_t any; - unsigned int attrs; - dns_dispatch_t *disp = NULL; - - result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); - if (result != ISC_R_SUCCESS) - return (result); - - isc_sockaddr_any(&any); - attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &any, 512, 6, 1024, 17, 19, attrs, - attrs, &disp); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_dispatchset_create(mctx, socketmgr, taskmgr, disp, - &dset, ndisps); - dns_dispatch_detach(&disp); - - return (result); -} - -static void -reset(void) { - if (dset != NULL) { - dns_dispatchset_destroy(&dset); - } - if (dispatchmgr != NULL) { - dns_dispatchmgr_destroy(&dispatchmgr); - } -} - -/* create dispatch set */ -static void -dispatchset_create(void **state) { - isc_result_t result; - - UNUSED(state); - - result = make_dispatchset(1); - assert_int_equal(result, ISC_R_SUCCESS); - reset(); - - result = make_dispatchset(10); - assert_int_equal(result, ISC_R_SUCCESS); - reset(); -} - -/* test dispatch set round-robin */ -static void -dispatchset_get(void **state) { - isc_result_t result; - dns_dispatch_t *d1, *d2, *d3, *d4, *d5; - - UNUSED(state); - - result = make_dispatchset(1); - assert_int_equal(result, ISC_R_SUCCESS); - - d1 = dns_dispatchset_get(dset); - d2 = dns_dispatchset_get(dset); - d3 = dns_dispatchset_get(dset); - d4 = dns_dispatchset_get(dset); - d5 = dns_dispatchset_get(dset); - - assert_ptr_equal(d1, d2); - assert_ptr_equal(d2, d3); - assert_ptr_equal(d3, d4); - assert_ptr_equal(d4, d5); - - reset(); - - result = make_dispatchset(4); - assert_int_equal(result, ISC_R_SUCCESS); - - d1 = dns_dispatchset_get(dset); - d2 = dns_dispatchset_get(dset); - d3 = dns_dispatchset_get(dset); - d4 = dns_dispatchset_get(dset); - d5 = dns_dispatchset_get(dset); - - assert_ptr_equal(d1, d5); - assert_ptr_not_equal(d1, d2); - assert_ptr_not_equal(d2, d3); - assert_ptr_not_equal(d3, d4); - assert_ptr_not_equal(d4, d5); - - reset(); -} - -static void -senddone(isc_task_t *task, isc_event_t *event) { - isc_socket_t *sock = event->ev_arg; - - UNUSED(task); - - isc_socket_detach(&sock); - isc_event_free(&event); -} - -static void -nameserver(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - isc_region_t region; - isc_socket_t *dummy; - isc_socket_t *sock = event->ev_arg; - isc_socketevent_t *ev = (isc_socketevent_t *)event; - static unsigned char buf1[16]; - static unsigned char buf2[16]; - - memmove(buf1, ev->region.base, 12); - memset(buf1 + 12, 0, 4); - buf1[2] |= 0x80; /* qr=1 */ - - memmove(buf2, ev->region.base, 12); - memset(buf2 + 12, 1, 4); - buf2[2] |= 0x80; /* qr=1 */ - - /* - * send message to be discarded. - */ - region.base = buf1; - region.length = sizeof(buf1); - dummy = NULL; - isc_socket_attach(sock, &dummy); - result = isc_socket_sendto(sock, ®ion, task, senddone, sock, - &ev->address, NULL); - if (result != ISC_R_SUCCESS) - isc_socket_detach(&dummy); - - /* - * send nextitem message. - */ - region.base = buf2; - region.length = sizeof(buf2); - dummy = NULL; - isc_socket_attach(sock, &dummy); - result = isc_socket_sendto(sock, ®ion, task, senddone, sock, - &ev->address, NULL); - if (result != ISC_R_SUCCESS) - isc_socket_detach(&dummy); - isc_event_free(&event); -} - -static dns_dispatch_t *dispatch = NULL; -static dns_dispentry_t *dispentry = NULL; -static bool first = true; -static isc_mutex_t lock; -static isc_sockaddr_t local; -static unsigned int responses = 0; - -static void -response(isc_task_t *task, isc_event_t *event) { - dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; - isc_result_t result; - bool wasfirst; - - UNUSED(task); - - LOCK(&lock); - wasfirst = first; - first = false; - responses++; - UNLOCK(&lock); - - if (wasfirst) { - result = dns_dispatch_getnext(dispentry, &devent); - assert_int_equal(result, ISC_R_SUCCESS); - } else { - dns_dispatch_removeresponse(&dispentry, &devent); - isc_app_shutdown(); - } -} - -static void -startit(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - isc_socket_t *sock = NULL; - - isc_socket_attach(dns_dispatch_getsocket(dispatch), &sock); - result = isc_socket_sendto(sock, event->ev_arg, task, senddone, sock, - &local, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - isc_event_free(&event); -} - -/* test dispatch getnext */ -static void -dispatch_getnext(void **state) { - isc_region_t region; - isc_result_t result; - isc_socket_t *sock = NULL; - isc_task_t *task = NULL; - uint16_t id; - struct in_addr ina; - unsigned char message[12]; - unsigned int attrs; - unsigned char rbuf[12]; - - UNUSED(state); - - result = isc_mutex_init(&lock); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_task_create(taskmgr, 0, &task); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); - assert_int_equal(result, ISC_R_SUCCESS); - - ina.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&local, &ina, 0); - attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &local, 512, 6, 1024, 17, 19, attrs, - attrs, &dispatch); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Create a local udp nameserver on the loopback. - */ - result = isc_socket_create(socketmgr, AF_INET, isc_sockettype_udp, - &sock); - assert_int_equal(result, ISC_R_SUCCESS); - - ina.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&local, &ina, 0); - result = isc_socket_bind(sock, &local, 0); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_socket_getsockname(sock, &local); - assert_int_equal(result, ISC_R_SUCCESS); - - first = true; - region.base = rbuf; - region.length = sizeof(rbuf); - result = isc_socket_recv(sock, ®ion, 1, task, nameserver, sock); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dispatch_addresponse(dispatch, &local, task, response, - NULL, &id, &dispentry); - assert_int_equal(result, ISC_R_SUCCESS); - - memset(message, 0, sizeof(message)); - message[0] = (id >> 8) & 0xff; - message[1] = id & 0xff; - - region.base = message; - region.length = sizeof(message); - result = isc_app_onrun(mctx, task, startit, ®ion); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_app_run(); - assert_int_equal(result, ISC_R_SUCCESS); - - LOCK(&lock); - assert_int_equal(responses, 2); - UNLOCK(&lock); - - /* - * Shutdown nameserver. - */ - isc_socket_cancel(sock, task, ISC_SOCKCANCEL_RECV); - isc_socket_detach(&sock); - isc_task_detach(&task); - - /* - * Shutdown the dispatch. - */ - dns_dispatch_detach(&dispatch); - dns_dispatchmgr_destroy(&dispatchmgr); - - /* - * Destroy the mutex. - */ - result = isc_mutex_destroy(&lock); - assert_int_equal(result, ISC_R_SUCCESS); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(dispatchset_create, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dispatchset_get, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dispatch_getnext, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dnstap_test.c b/lib/dns-pkcs11/tests/dnstap_test.c deleted file mode 100644 index 3604ff4..0000000 --- a/lib/dns-pkcs11/tests/dnstap_test.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dnstest.h" - -#ifdef HAVE_DNSTAP - -#include - -#define TAPFILE "testdata/dnstap/dnstap.file" -#define TAPSOCK "testdata/dnstap/dnstap.sock" - -#define TAPSAVED "testdata/dnstap/dnstap.saved" -#define TAPTEXT "testdata/dnstap/dnstap.text" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static void -cleanup() { - (void) isc_file_remove(TAPFILE); - (void) isc_file_remove(TAPSOCK); -} - -/* set up dnstap environment */ -static void -create_test(void **state) { - isc_result_t result; - dns_dtenv_t *dtenv = NULL; - struct fstrm_iothr_options *fopt; - - UNUSED(state); - - cleanup(); - - fopt = fstrm_iothr_options_init(); - assert_non_null(fopt); - fstrm_iothr_options_set_num_input_queues(fopt, 1); - - result = dns_dt_create(mctx, dns_dtmode_file, TAPFILE, &fopt, &dtenv); - assert_int_equal(result, ISC_R_SUCCESS); - if (dtenv != NULL) { - dns_dt_detach(&dtenv); - } - if (fopt != NULL) { - fstrm_iothr_options_destroy(&fopt); - } - - assert_true(isc_file_exists(TAPFILE)); - - fopt = fstrm_iothr_options_init(); - assert_non_null(fopt); - fstrm_iothr_options_set_num_input_queues(fopt, 1); - - result = dns_dt_create(mctx, dns_dtmode_unix, TAPSOCK, &fopt, &dtenv); - assert_int_equal(result, ISC_R_SUCCESS); - if (dtenv != NULL) { - dns_dt_detach(&dtenv); - } - if (fopt != NULL) { - fstrm_iothr_options_destroy(&fopt); - } - - /* 'create' should succeed, but the file shouldn't exist yet */ - assert_false(isc_file_exists(TAPSOCK)); - - fopt = fstrm_iothr_options_init(); - assert_non_null(fopt); - fstrm_iothr_options_set_num_input_queues(fopt, 1); - - result = dns_dt_create(mctx, 33, TAPSOCK, &fopt, &dtenv); - assert_int_equal(result, ISC_R_FAILURE); - assert_null(dtenv); - if (dtenv != NULL) { - dns_dt_detach(&dtenv); - } - if (fopt != NULL) { - fstrm_iothr_options_destroy(&fopt); - } - - cleanup(); - - dns_dt_shutdown(); -} - -/* send dnstap messages */ -static void -send_test(void **state) { - isc_result_t result; - dns_dtenv_t *dtenv = NULL; - dns_dthandle_t *handle = NULL; - uint8_t *data; - size_t dsize; - unsigned char zone[DNS_NAME_MAXWIRE]; - unsigned char qambuffer[4096], rambuffer[4096]; - unsigned char qrmbuffer[4096], rrmbuffer[4096]; - isc_buffer_t zb, qamsg, ramsg, qrmsg, rrmsg; - size_t qasize, qrsize, rasize, rrsize; - dns_fixedname_t zfname; - dns_name_t *zname; - dns_dtmsgtype_t dt; - dns_view_t *view = NULL; - dns_compress_t cctx; - isc_region_t zr; - isc_sockaddr_t qaddr; - isc_sockaddr_t raddr; - struct in_addr in; - isc_stdtime_t now; - isc_time_t p, f; - struct fstrm_iothr_options *fopt; - - UNUSED(state); - - cleanup(); - - result = dns_test_makeview("test", &view); - assert_int_equal(result, ISC_R_SUCCESS); - - fopt = fstrm_iothr_options_init(); - assert_non_null(fopt); - fstrm_iothr_options_set_num_input_queues(fopt, 1); - - result = dns_dt_create(mctx, dns_dtmode_file, TAPFILE, &fopt, &dtenv); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_dt_attach(dtenv, &view->dtenv); - view->dttypes = DNS_DTTYPE_ALL; - - /* - * Set up some test data - */ - zname = dns_fixedname_initname(&zfname); - isc_buffer_constinit(&zb, "example.com.", 12); - isc_buffer_add(&zb, 12); - result = dns_name_fromtext(zname, &zb, NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - memset(&zr, 0, sizeof(zr)); - isc_buffer_init(&zb, zone, sizeof(zone)); - result = dns_compress_init(&cctx, -1, mctx); - assert_int_equal(result, ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE); - result = dns_name_towire(zname, &cctx, &zb); - assert_int_equal(result, ISC_R_SUCCESS); - dns_compress_invalidate(&cctx); - isc_buffer_usedregion(&zb, &zr); - - in.s_addr = inet_addr("10.53.0.1"); - isc_sockaddr_fromin(&qaddr, &in, 2112); - in.s_addr = inet_addr("10.53.0.2"); - isc_sockaddr_fromin(&raddr, &in, 2112); - - isc_stdtime_get(&now); - isc_time_set(&p, now - 3600, 0); /* past */ - isc_time_set(&f, now + 3600, 0); /* future */ - - result = dns_test_getdata("testdata/dnstap/query.auth", - qambuffer, sizeof(qambuffer), &qasize); - assert_int_equal(result, ISC_R_SUCCESS); - isc_buffer_init(&qamsg, qambuffer, qasize); - isc_buffer_add(&qamsg, qasize); - - result = dns_test_getdata("testdata/dnstap/response.auth", - rambuffer, sizeof(rambuffer), &rasize); - assert_int_equal(result, ISC_R_SUCCESS); - isc_buffer_init(&ramsg, rambuffer, rasize); - isc_buffer_add(&ramsg, rasize); - - result = dns_test_getdata("testdata/dnstap/query.recursive", qrmbuffer, - sizeof(qrmbuffer), &qrsize); - assert_int_equal(result, ISC_R_SUCCESS); - isc_buffer_init(&qrmsg, qrmbuffer, qrsize); - isc_buffer_add(&qrmsg, qrsize); - - result = dns_test_getdata("testdata/dnstap/response.recursive", - rrmbuffer, sizeof(rrmbuffer), &rrsize); - assert_int_equal(result, ISC_R_SUCCESS); - isc_buffer_init(&rrmsg, rrmbuffer, rrsize); - isc_buffer_add(&rrmsg, rrsize); - - for (dt = DNS_DTTYPE_SQ; dt <= DNS_DTTYPE_TR; dt <<= 1) { - isc_buffer_t *m; - isc_sockaddr_t *q = &qaddr, *r = &raddr; - - switch (dt) { - case DNS_DTTYPE_AQ: - m = &qamsg; - break; - case DNS_DTTYPE_AR: - m = &ramsg; - break; - default: - m = &qrmsg; - if ((dt & DNS_DTTYPE_RESPONSE) != 0) { - m = &ramsg; - } - break; - } - - dns_dt_send(view, dt, q, r, false, &zr, &p, &f, m); - dns_dt_send(view, dt, q, r, false, &zr, NULL, &f, m); - dns_dt_send(view, dt, q, r, false, &zr, &p, NULL, m); - dns_dt_send(view, dt, q, r, false, &zr, NULL, NULL, m); - dns_dt_send(view, dt, q, r, true, &zr, &p, &f, m); - dns_dt_send(view, dt, q, r, true, &zr, NULL, &f, m); - dns_dt_send(view, dt, q, r, true, &zr, &p, NULL, m); - dns_dt_send(view, dt, q, r, true, &zr, NULL, NULL, m); - } - - dns_dt_detach(&view->dtenv); - dns_dt_detach(&dtenv); - dns_dt_shutdown(); - dns_view_detach(&view); - - result = dns_dt_open(TAPFILE, dns_dtmode_file, mctx, &handle); - assert_int_equal(result, ISC_R_SUCCESS); - - while (dns_dt_getframe(handle, &data, &dsize) == ISC_R_SUCCESS) { - dns_dtdata_t *dtdata = NULL; - isc_region_t r; - static dns_dtmsgtype_t expected = DNS_DTTYPE_SQ; - static int n = 0; - - r.base = data; - r.length = dsize; - - result = dns_dt_parse(mctx, &r, &dtdata); - assert_int_equal(result, ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) { - n++; - continue; - } - - assert_int_equal(dtdata->type, expected); - if (++n % 8 == 0) { - expected <<= 1; - } - - dns_dtdata_free(&dtdata); - } - - if (fopt != NULL) { - fstrm_iothr_options_destroy(&fopt); - } - if (handle != NULL) { - dns_dt_close(&handle); - } - cleanup(); -} - -/* dnstap message to text */ -static void -totext_test(void **state) { - isc_result_t result; - dns_dthandle_t *handle = NULL; - uint8_t *data; - size_t dsize; - FILE *fp = NULL; - - UNUSED(state); - - result = dns_dt_open(TAPSAVED, dns_dtmode_file, mctx, &handle); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_stdio_open(TAPTEXT, "r", &fp); - assert_int_equal(result, ISC_R_SUCCESS); - - while (dns_dt_getframe(handle, &data, &dsize) == ISC_R_SUCCESS) { - dns_dtdata_t *dtdata = NULL; - isc_buffer_t *b = NULL; - isc_region_t r; - char s[BUFSIZ], *p; - - r.base = data; - r.length = dsize; - - /* read the corresponding line of text */ - p = fgets(s, sizeof(s), fp); - assert_ptr_equal(p, s); - if (p == NULL) { - break; - } - - p = strchr(p, '\n'); - if (p != NULL) { - *p = '\0'; - } - - /* parse dnstap frame */ - result = dns_dt_parse(mctx, &r, &dtdata); - assert_int_equal(result, ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) { - continue; - } - - isc_buffer_allocate(mctx, &b, 2048); - assert_non_null(b); - if (b == NULL) { - break; - } - - /* convert to text and compare */ - result = dns_dt_datatotext(dtdata, &b); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_string_equal((char *) isc_buffer_base(b), s); - - dns_dtdata_free(&dtdata); - isc_buffer_free(&b); - } - - if (handle != NULL) { - dns_dt_close(&handle); - } - cleanup(); -} -#endif /* HAVE_DNSTAP */ - -int -main(void) { -#if HAVE_DNSTAP - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create_test, _setup, _teardown), - cmocka_unit_test_setup_teardown(send_test, _setup, _teardown), - cmocka_unit_test_setup_teardown(totext_test, _setup, _teardown), - }; - - /* make sure text conversion gets the right local time */ - setenv("TZ", "PST8", 1); - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skip dnstap not enabled\n"); -#endif /* HAVE_DNSTAP */ -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif /* HAVE_CMOCKA */ diff --git a/lib/dns-pkcs11/tests/dnstest.c b/lib/dns-pkcs11/tests/dnstest.c deleted file mode 100644 index e239b0a..0000000 --- a/lib/dns-pkcs11/tests/dnstest.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include -#include - -#if HAVE_CMOCKA -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dnstest.h" - -isc_mem_t *mctx = NULL; -isc_entropy_t *ectx = NULL; -isc_log_t *lctx = NULL; -isc_taskmgr_t *taskmgr = NULL; -isc_task_t *maintask = NULL; -isc_timermgr_t *timermgr = NULL; -isc_socketmgr_t *socketmgr = NULL; -dns_zonemgr_t *zonemgr = NULL; -bool app_running = false; -int ncpus; -bool debug_mem_record = true; - -static bool tests_active = false, test_running = false; - -/* - * Logging categories: this needs to match the list in bin/named/log.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { "query-errors", 0 }, - { NULL, 0 } -}; - -static void -cleanup_managers(void) { - if (maintask != NULL) { - isc_task_shutdown(maintask); - isc_task_destroy(&maintask); - } - if (socketmgr != NULL) { - isc_socketmgr_destroy(&socketmgr); - } - if (taskmgr != NULL) { - isc_taskmgr_destroy(&taskmgr); - } - if (timermgr != NULL) { - isc_timermgr_destroy(&timermgr); - } - if (app_running) { - isc_app_finish(); - } -} - -static isc_result_t -create_managers(void) { - isc_result_t result; -#ifdef ISC_PLATFORM_USETHREADS - ncpus = isc_os_ncpus(); -#else - ncpus = 1; -#endif - - CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr)); - CHECK(isc_timermgr_create(mctx, &timermgr)); - CHECK(isc_socketmgr_create(mctx, &socketmgr)); - CHECK(isc_task_create(taskmgr, 0, &maintask)); - return (ISC_R_SUCCESS); - - cleanup: - cleanup_managers(); - return (result); -} - -int -dns_test_init(void **state) { - isc_result_t result; - - UNUSED(state); - - if (debug_mem_record) { - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - } - - INSIST(mctx == NULL); - result = isc_mem_create(0, 0, &mctx); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = isc_entropy_create(mctx, &ectx); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - tests_active = true; - return (0); -} - -isc_result_t -dns_test_begin(FILE *logfile, bool start_managers) { - isc_result_t result; - - INSIST(!test_running); - test_running = true; - - if (start_managers) { - CHECK(isc_app_start()); - } - if (logfile != NULL) { - isc_logdestination_t destination; - isc_logconfig_t *logconfig = NULL; - - INSIST(lctx == NULL); - CHECK(isc_log_create(mctx, &lctx, &logconfig)); - - isc_log_registercategories(lctx, categories); - isc_log_setcontext(lctx); - dns_log_init(lctx); - dns_log_setcontext(lctx); - - destination.file.stream = logfile; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - CHECK(isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - ISC_LOG_DYNAMIC, - &destination, 0)); - CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL)); - } - - dns_result_register(); - - if (start_managers) { - CHECK(create_managers()); - } - - /* - * The caller might run from another directory, so tests - * that access test data files must first chdir to the proper - * location. - */ - if (chdir(TESTS) == -1) { - CHECK(ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); - - cleanup: - dns_test_end(); - return (result); -} - -void -dns_test_end(void) { - cleanup_managers(); - - if (lctx != NULL) { - isc_log_destroy(&lctx); - } - - test_running = false; -} - -int -dns_test_final(void **state) { - UNUSED(state); - - if (!tests_active) { - return (0); - } - - isc_hash_destroy(); - isc_entropy_detach(&ectx); - dst_lib_destroy(); - isc_mem_destroy(&mctx); - - return (0); -} - -/* - * Create a view. - */ -isc_result_t -dns_test_makeview(const char *name, dns_view_t **viewp) { - isc_result_t result; - dns_view_t *view = NULL; - - CHECK(dns_view_create(mctx, dns_rdataclass_in, name, &view)); - *viewp = view; - - return (ISC_R_SUCCESS); - - cleanup: - if (view != NULL) - dns_view_detach(&view); - return (result); -} - -isc_result_t -dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view, - bool createview) -{ - dns_fixedname_t fixed_origin; - dns_zone_t *zone = NULL; - isc_result_t result; - dns_name_t *origin; - - REQUIRE(view == NULL || !createview); - - /* - * Create the zone structure. - */ - result = dns_zone_create(&zone, mctx); - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * Set zone type and origin. - */ - dns_zone_settype(zone, dns_zone_master); - origin = dns_fixedname_initname(&fixed_origin); - result = dns_name_fromstring(origin, name, 0, NULL); - if (result != ISC_R_SUCCESS) { - goto detach_zone; - } - result = dns_zone_setorigin(zone, origin); - if (result != ISC_R_SUCCESS) { - goto detach_zone; - } - - /* - * If requested, create a view. - */ - if (createview) { - result = dns_test_makeview("view", &view); - if (result != ISC_R_SUCCESS) { - goto detach_zone; - } - } - - /* - * If a view was passed as an argument or created above, attach the - * created zone to it. Otherwise, set the zone's class to IN. - */ - if (view != NULL) { - dns_zone_setview(zone, view); - dns_zone_setclass(zone, view->rdclass); - dns_view_addzone(view, zone); - } else { - dns_zone_setclass(zone, dns_rdataclass_in); - } - - *zonep = zone; - - return (ISC_R_SUCCESS); - - detach_zone: - dns_zone_detach(&zone); - - return (result); -} - -isc_result_t -dns_test_setupzonemgr(void) { - isc_result_t result; - REQUIRE(zonemgr == NULL); - - result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, - &zonemgr); - return (result); -} - -isc_result_t -dns_test_managezone(dns_zone_t *zone) { - isc_result_t result; - REQUIRE(zonemgr != NULL); - - result = dns_zonemgr_setsize(zonemgr, 1); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_zonemgr_managezone(zonemgr, zone); - return (result); -} - -void -dns_test_releasezone(dns_zone_t *zone) { - REQUIRE(zonemgr != NULL); - dns_zonemgr_releasezone(zonemgr, zone); -} - -void -dns_test_closezonemgr(void) { - REQUIRE(zonemgr != NULL); - - dns_zonemgr_shutdown(zonemgr); - dns_zonemgr_detach(&zonemgr); -} - -/* - * Sleep for 'usec' microseconds. - */ -void -dns_test_nap(uint32_t usec) { -#ifdef HAVE_NANOSLEEP - struct timespec ts; - - ts.tv_sec = usec / 1000000; - ts.tv_nsec = (usec % 1000000) * 1000; - nanosleep(&ts, NULL); -#elif HAVE_USLEEP - usleep(usec); -#else - /* - * No fractional-second sleep function is available, so we - * round up to the nearest second and sleep instead - */ - sleep((usec / 1000000) + 1); -#endif -} - -isc_result_t -dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin, - const char *testfile) -{ - isc_result_t result; - dns_fixedname_t fixed; - dns_name_t *name; - - name = dns_fixedname_initname(&fixed); - - result = dns_name_fromstring(name, origin, 0, NULL); - if (result != ISC_R_SUCCESS) - return(result); - - result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in, - 0, NULL, db); - if (result != ISC_R_SUCCESS) - return (result); - - result = dns_db_load(*db, testfile); - return (result); -} - -static int -fromhex(char c) { - if (c >= '0' && c <= '9') - return (c - '0'); - else if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - else if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - - printf("bad input format: %02x\n", c); - exit(3); - /* NOTREACHED */ -} - -/* - * Format contents of given memory region as a hex string, using the buffer - * of length 'buflen' pointed to by 'buf'. 'buflen' must be at least three - * times 'len'. Always returns 'buf'. - */ -char * -dns_test_tohex(const unsigned char *data, size_t len, char *buf, size_t buflen) -{ - isc_constregion_t source = { - .base = data, - .length = len - }; - isc_buffer_t target; - isc_result_t result; - - memset(buf, 0, buflen); - isc_buffer_init(&target, buf, buflen); - result = isc_hex_totext((isc_region_t *)&source, 1, " ", &target); - assert_int_equal(result, ISC_R_SUCCESS); - - return (buf); -} - -isc_result_t -dns_test_getdata(const char *file, unsigned char *buf, - size_t bufsiz, size_t *sizep) -{ - isc_result_t result; - unsigned char *bp; - char *rp, *wp; - char s[BUFSIZ]; - size_t len, i; - FILE *f = NULL; - int n; - - result = isc_stdio_open(file, "r", &f); - if (result != ISC_R_SUCCESS) - return (result); - - bp = buf; - while (fgets(s, sizeof(s), f) != NULL) { - rp = s; - wp = s; - len = 0; - while (*rp != '\0') { - if (*rp == '#') - break; - if (*rp != ' ' && *rp != '\t' && - *rp != '\r' && *rp != '\n') { - *wp++ = *rp; - len++; - } - rp++; - } - if (len == 0U) - continue; - if (len % 2 != 0U) - CHECK(ISC_R_UNEXPECTEDEND); - if (len > bufsiz * 2) - CHECK(ISC_R_NOSPACE); - rp = s; - for (i = 0; i < len; i += 2) { - n = fromhex(*rp++); - n *= 16; - n += fromhex(*rp++); - *bp++ = n; - } - } - - - *sizep = bp - buf; - - result = ISC_R_SUCCESS; - - cleanup: - isc_stdio_close(f); - return (result); -} - -static void -nullmsg(dns_rdatacallbacks_t *cb, const char *fmt, ...) { - UNUSED(cb); - UNUSED(fmt); -} - -isc_result_t -dns_test_rdatafromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t rdtype, unsigned char *dst, - size_t dstlen, const char *src, bool warnings) -{ - dns_rdatacallbacks_t callbacks; - isc_buffer_t source, target; - isc_lex_t *lex = NULL; - isc_lexspecials_t specials = { 0 }; - isc_result_t result; - size_t length; - - REQUIRE(rdata != NULL); - REQUIRE(DNS_RDATA_INITIALIZED(rdata)); - REQUIRE(dst != NULL); - REQUIRE(src != NULL); - - /* - * Set up source to hold the input string. - */ - length = strlen(src); - isc_buffer_constinit(&source, src, length); - isc_buffer_add(&source, length); - - /* - * Create a lexer as one is required by dns_rdata_fromtext(). - */ - result = isc_lex_create(mctx, 64, &lex); - if (result != ISC_R_SUCCESS) { - return (result); - } - - /* - * Set characters which will be treated as valid multi-line RDATA - * delimiters while reading the source string. These should match - * specials from lib/dns/master.c. - */ - specials[0] = 1; - specials['('] = 1; - specials[')'] = 1; - specials['"'] = 1; - isc_lex_setspecials(lex, specials); - - /* - * Expect DNS masterfile comments. - */ - isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); - - /* - * Point lexer at source. - */ - result = isc_lex_openbuffer(lex, &source); - if (result != ISC_R_SUCCESS) { - goto destroy_lexer; - } - - /* - * Set up target for storing uncompressed wire form of provided RDATA. - */ - isc_buffer_init(&target, dst, dstlen); - - /* - * Set up callbacks so warnings and errors are not printed. - */ - if (!warnings) { - dns_rdatacallbacks_init(&callbacks); - callbacks.warn = callbacks.error = nullmsg; - } - - /* - * Parse input string, determining result. - */ - result = dns_rdata_fromtext(rdata, rdclass, rdtype, lex, dns_rootname, - 0, mctx, &target, &callbacks); - - destroy_lexer: - isc_lex_destroy(&lex); - - return (result); -} - -void -dns_test_namefromstring(const char *namestr, dns_fixedname_t *fname) { - size_t length; - isc_buffer_t *b = NULL; - isc_result_t result; - dns_name_t *name; - - length = strlen(namestr); - - name = dns_fixedname_initname(fname); - - result = isc_buffer_allocate(mctx, &b, length); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_buffer_putmem(b, (const unsigned char *) namestr, length); - result = dns_name_fromtext(name, b, dns_rootname, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_buffer_free(&b); -} - -isc_result_t -dns_test_difffromchanges(dns_diff_t *diff, const zonechange_t *changes, - bool warnings) -{ - isc_result_t result = ISC_R_SUCCESS; - unsigned char rdata_buf[1024]; - dns_difftuple_t *tuple = NULL; - isc_consttextregion_t region; - dns_rdatatype_t rdatatype; - dns_fixedname_t fixedname; - dns_rdata_t rdata; - dns_name_t *name; - size_t i; - - REQUIRE(diff != NULL); - REQUIRE(changes != NULL); - - dns_diff_init(mctx, diff); - - for (i = 0; changes[i].owner != NULL; i++) { - /* - * Parse owner name. - */ - name = dns_fixedname_initname(&fixedname); - result = dns_name_fromstring(name, changes[i].owner, 0, mctx); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Parse RDATA type. - */ - region.base = changes[i].type; - region.length = strlen(changes[i].type); - result = dns_rdatatype_fromtext(&rdatatype, - (isc_textregion_t *)®ion); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Parse RDATA. - */ - dns_rdata_init(&rdata); - result = dns_test_rdatafromstring(&rdata, dns_rdataclass_in, - rdatatype, rdata_buf, - sizeof(rdata_buf), - changes[i].rdata, - warnings); - if (result != ISC_R_SUCCESS) { - break; - } - - /* - * Create a diff tuple for the parsed change and append it to - * the diff. - */ - result = dns_difftuple_create(mctx, changes[i].op, name, - changes[i].ttl, &rdata, &tuple); - if (result != ISC_R_SUCCESS) { - break; - } - dns_diff_append(diff, &tuple); - } - - if (result != ISC_R_SUCCESS) { - dns_diff_clear(diff); - } - - return (result); -} -#endif /* HAVE_CMOCKA */ diff --git a/lib/dns-pkcs11/tests/dnstest.h b/lib/dns-pkcs11/tests/dnstest.h deleted file mode 100644 index a5dbd9c..0000000 --- a/lib/dns-pkcs11/tests/dnstest.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define CHECK(r) \ - do { \ - result = (r); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -typedef struct { - dns_diffop_t op; - const char *owner; - dns_ttl_t ttl; - const char *type; - const char *rdata; -} zonechange_t; - -#define ZONECHANGE_SENTINEL { 0, NULL, 0, NULL, NULL } - -extern isc_mem_t *mctx; -extern isc_entropy_t *ectx; -extern isc_log_t *lctx; -extern isc_taskmgr_t *taskmgr; -extern isc_task_t *maintask; -extern isc_timermgr_t *timermgr; -extern isc_socketmgr_t *socketmgr; -extern dns_zonemgr_t *zonemgr; -extern bool app_running; -extern int ncpus; -extern bool debug_mem_record; - -/* Run once before all tests */ -int -dns_test_init(void **); - -/* Can be run before each test case */ -isc_result_t -dns_test_begin(FILE *logfile, bool create_managers); - -/* Can be after each test case */ -void -dns_test_end(void); - -/* Run once after all tests */ -int -dns_test_final(void **); - -isc_result_t -dns_test_makeview(const char *name, dns_view_t **viewp); - -/*% - * Create a zone with origin 'name', return a pointer to the zone object in - * 'zonep'. - * - * If 'view' is set, the returned zone will be assigned to the passed view. - * 'createview' must be set to false when 'view' is non-NULL. - * - * If 'view' is not set and 'createview' is true, a new view is also created - * and the returned zone is assigned to it. This imposes two requirements on - * the caller: 1) the returned zone has to be subsequently assigned to a zone - * manager, otherwise its cleanup will fail, 2) the created view has to be - * cleaned up by the caller. - * - * If 'view' is not set and 'createview' is false, the returned zone will not - * be assigned to any view. - */ -isc_result_t -dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view, - bool createview); - -isc_result_t -dns_test_setupzonemgr(void); - -isc_result_t -dns_test_managezone(dns_zone_t *zone); - -void -dns_test_releasezone(dns_zone_t *zone); - -void -dns_test_closezonemgr(void); - -void -dns_test_nap(uint32_t usec); - -isc_result_t -dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin, - const char *testfile); - -isc_result_t -dns_test_getdata(const char *file, unsigned char *buf, - size_t bufsiz, size_t *sizep); - -char * -dns_test_tohex(const unsigned char *data, size_t len, char *buf, size_t buflen); - -/*% - * Try parsing text form RDATA in "src" (of class "rdclass" and type "rdtype") - * into a structure representing that RDATA at "rdata", storing the - * uncompressed wire form of that RDATA at "dst", which is "dstlen" bytes long. - * Set 'warnings' to true to print logged warnings from dns_rdata_fromtext(). - */ -isc_result_t -dns_test_rdatafromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass, - dns_rdatatype_t rdtype, unsigned char *dst, - size_t dstlen, const char *src, bool warnings); - -void -dns_test_namefromstring(const char *namestr, dns_fixedname_t *fname); - -/*% - * Given a pointer to an uninitialized dns_diff_t structure in 'diff', make it - * contain diff tuples representing zone database changes listed in 'changes'. - * Set 'warnings' to true to print logged warnings from dns_rdata_fromtext(). - */ -isc_result_t -dns_test_difffromchanges(dns_diff_t *diff, const zonechange_t *changes, - bool warnings); diff --git a/lib/dns-pkcs11/tests/dst_test.c b/lib/dns-pkcs11/tests/dst_test.c deleted file mode 100644 index 5e23664..0000000 --- a/lib/dns-pkcs11/tests/dst_test.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../dst_internal.h" - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* Read sig in file at path to buf. Check signature ineffability */ -static isc_result_t -sig_fromfile(const char *path, isc_buffer_t *buf) { - isc_result_t result; - size_t rval, len; - FILE *fp = NULL; - unsigned char val; - char *p, *data; - off_t size; - - result = isc_stdio_open(path, "rb", &fp); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_file_getsizefd(fileno(fp), &size); - assert_int_equal(result, ISC_R_SUCCESS); - - data = isc_mem_get(mctx, (size + 1)); - assert_non_null(data); - - len = (size_t)size; - p = data; - while (len != 0U) { - result = isc_stdio_read(p, 1, len, fp, &rval); - assert_int_equal(result, ISC_R_SUCCESS); - len -= rval; - p += rval; - } - isc_stdio_close(fp); - - p = data; - len = size; - while (len > 0U) { - if ((*p == '\r') || (*p == '\n')) { - ++p; - --len; - continue; - } else if (len < 2U) { - goto err; - } - if (('0' <= *p) && (*p <= '9')) { - val = *p - '0'; - } else if (('A' <= *p) && (*p <= 'F')) { - val = *p - 'A' + 10; - } else { - result = ISC_R_BADHEX; - goto err; - } - ++p; - val <<= 4; - --len; - if (('0' <= *p) && (*p <= '9')) { - val |= (*p - '0'); - } else if (('A' <= *p) && (*p <= 'F')) { - val |= (*p - 'A' + 10); - } else { - result = ISC_R_BADHEX; - goto err; - } - ++p; - --len; - isc_buffer_putuint8(buf, val); - } - - result = ISC_R_SUCCESS; - - err: - isc_mem_put(mctx, data, size + 1); - return (result); -} - -static void -check_sig(const char *datapath, const char *sigpath, const char *keyname, - dns_keytag_t id, dns_secalg_t alg, int type, bool expect) -{ - isc_result_t result; - size_t rval, len; - FILE *fp; - dst_key_t *key = NULL; - unsigned char sig[512]; - unsigned char *p; - unsigned char *data; - off_t size; - isc_buffer_t b; - isc_buffer_t databuf, sigbuf; - isc_region_t datareg, sigreg; - dns_fixedname_t fname; - dns_name_t *name; - dst_context_t *ctx = NULL; - - /* - * Read data from file in a form usable by dst_verify. - */ - result = isc_stdio_open(datapath, "rb", &fp); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_file_getsizefd(fileno(fp), &size); - assert_int_equal(result, ISC_R_SUCCESS); - - data = isc_mem_get(mctx, (size + 1)); - assert_non_null(data); - - p = data; - len = (size_t)size; - do { - result = isc_stdio_read(p, 1, len, fp, &rval); - assert_int_equal(result, ISC_R_SUCCESS); - len -= rval; - p += rval; - } while (len); - isc_stdio_close(fp); - - /* - * Read key from file in a form usable by dst_verify. - */ - name = dns_fixedname_initname(&fname); - isc_buffer_constinit(&b, keyname, strlen(keyname)); - isc_buffer_add(&b, strlen(keyname)); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - result = dst_key_fromfile(name, id, alg, type, "testdata/dst", - mctx, &key); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_buffer_init(&databuf, data, (unsigned int)size); - isc_buffer_add(&databuf, (unsigned int)size); - isc_buffer_usedregion(&databuf, &datareg); - - memset(sig, 0, sizeof(sig)); - isc_buffer_init(&sigbuf, sig, sizeof(sig)); - - /* - * Read precomputed signature from file in a form usable by dst_verify. - */ - result = sig_fromfile(sigpath, &sigbuf); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Verify that the key signed the data. - */ - isc_buffer_remainingregion(&sigbuf, &sigreg); - - result = dst_context_create3(key, mctx, DNS_LOGCATEGORY_GENERAL, - false, &ctx); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dst_context_adddata(ctx, &datareg); - assert_int_equal(result, ISC_R_SUCCESS); - result = dst_context_verify(ctx, &sigreg); - - /* - * Compute the expected signature and emit it - * so the precomputed signature can be updated. - * This should only be done if the covered data - * is updated. - */ - if (expect && result != ISC_R_SUCCESS) { - isc_result_t result2; - - dst_context_destroy(&ctx); - result2 = dst_context_create3(key, mctx, - DNS_LOGCATEGORY_GENERAL, false, - &ctx); - assert_int_equal(result2, ISC_R_SUCCESS); - - result2 = dst_context_adddata(ctx, &datareg); - assert_int_equal(result2, ISC_R_SUCCESS); - - char sigbuf2[4096]; - isc_buffer_t sigb; - isc_buffer_init(&sigb, sigbuf2, sizeof(sigbuf2)); - - result2 = dst_context_sign(ctx, &sigb); - assert_int_equal(result2, ISC_R_SUCCESS); - - isc_region_t r; - isc_buffer_usedregion(&sigb, &r); - - char hexbuf[4096] = { 0 }; - isc_buffer_t hb; - isc_buffer_init(&hb, hexbuf, sizeof(hexbuf)); - - isc_hex_totext(&r, 0, "", &hb); - - fprintf(stderr, "# %s:\n# %s\n", sigpath, hexbuf); - } - - isc_mem_put(mctx, data, size + 1); - dst_context_destroy(&ctx); - dst_key_free(&key); - - assert_true((expect && (result == ISC_R_SUCCESS)) || - (!expect && (result != ISC_R_SUCCESS))); - - return; -} - -static void -sig_test(void **state) { - UNUSED(state); - - struct { - const char *datapath; - const char *sigpath; - const char *keyname; - dns_keytag_t keyid; - dns_secalg_t alg; - bool expect; - } testcases[] = { - { - "testdata/dst/test1.data", - "testdata/dst/test1.dsasig", - "test.", 23616, DST_ALG_DSA, true - }, - { - "testdata/dst/test1.data", - "testdata/dst/test1.rsasig", - "test.", 54622, DST_ALG_RSAMD5, true - }, - { - /* wrong sig */ - "testdata/dst/test1.data", - "testdata/dst/test1.dsasig", - "test.", 54622, DST_ALG_RSAMD5, false - }, - { - /* wrong data */ - "testdata/dst/test2.data", - "testdata/dst/test1.dsasig", - "test.", 23616, DST_ALG_DSA, false - }, - }; - unsigned int i; - - for (i = 0; i < (sizeof(testcases)/sizeof(testcases[0])); i++) { - if (!dst_algorithm_supported(testcases[i].alg)) { - continue; - } - - check_sig(testcases[i].datapath, - testcases[i].sigpath, - testcases[i].keyname, - testcases[i].keyid, - testcases[i].alg, - DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, - testcases[i].expect); - } -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(sig_test, _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/dstrandom_test.c b/lib/dns-pkcs11/tests/dstrandom_test.c deleted file mode 100644 index bd3d164..0000000 --- a/lib/dns-pkcs11/tests/dstrandom_test.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include - -#include - -isc_mem_t *mctx = NULL; -isc_entropy_t *ectx = NULL; -unsigned char buffer[128]; - -/* isc_entropy_getdata() examples */ -static void -isc_entropy_getdata_test(void **state) { - isc_result_t result; - unsigned int returned, status; - const char *randomfile = "testdata/dstrandom/random.data"; - int ret; - - UNUSED(state); - - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - result = isc_mem_create(0, 0, &mctx); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_entropy_create(mctx, &ectx); - assert_int_equal(result, ISC_R_SUCCESS); - result = dst_lib_init(mctx, ectx, 0); - assert_int_equal(result, ISC_R_SUCCESS); - -#ifdef ISC_PLATFORM_CRYPTORANDOM - isc_entropy_usehook(ectx, true); - - returned = 0; - result = isc_entropy_getdata(ectx, buffer, sizeof(buffer), - &returned, 0); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(returned, sizeof(buffer)); - - status = isc_entropy_status(ectx); - assert_int_equal(status, 0); - - isc_entropy_usehook(ectx, false); -#endif - - ret = chdir(TESTS); - assert_int_equal(ret, 0); - - result = isc_entropy_createfilesource(ectx, randomfile); - assert_int_equal(result, ISC_R_SUCCESS); - - returned = 0; - result = isc_entropy_getdata(ectx, buffer, sizeof(buffer), - &returned, 0); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(returned, sizeof(buffer)); - - status = isc_entropy_status(ectx); - assert_true(status > 0); - - dst_lib_destroy(); - isc_entropy_detach(&ectx); - assert_null(ectx); - - isc_mem_destroy(&mctx); - assert_null(mctx); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(isc_entropy_getdata_test), - }; - - return (cmocka_run_group_tests(tests, NULL, NULL)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/geoip_test.c b/lib/dns-pkcs11/tests/geoip_test.c deleted file mode 100644 index dcf0ec5..0000000 --- a/lib/dns-pkcs11/tests/geoip_test.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include - -#include - -#include "dnstest.h" - -#if defined(HAVE_GEOIP2) -#include - -#include "../geoip2.c" - -/* Use GeoIP2 databases from the 'geoip2' system test */ -#define TEST_GEOIP_DATA "../../../bin/tests/system/geoip2/data" -#elif defined(HAVE_GEOIP) -#include - -/* Use GeoIP databases from the 'geoip' system test */ -#define TEST_GEOIP_DATA "../../../bin/tests/system/geoip/data" -#endif - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -static void load_geoip(const char *dir); -static void close_geoip(void); - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Use databases from the geoip system test */ - load_geoip(TEST_GEOIP_DATA); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - close_geoip(); - - dns_test_end(); - - return (0); -} - -static dns_geoip_databases_t geoip; -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - -#if defined(HAVE_GEOIP2) -static MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain; - -static MMDB_s * -open_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) { - char pathbuf[PATH_MAX]; - int ret; - - snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile); - ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb); - if (ret == MMDB_SUCCESS) { - return (mmdb); - } - - return (NULL); -} - -static void -load_geoip(const char *dir) { - geoip.country = open_geoip2(dir, "GeoIP2-Country.mmdb", - &geoip_country); - geoip.city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city); - geoip.as = open_geoip2(dir, "GeoLite2-ASN.mmdb", &geoip_as); - geoip.isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp); - geoip.domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", &geoip_domain); -} - -static void -close_geoip(void) { - MMDB_close(&geoip_country); - MMDB_close(&geoip_city); - MMDB_close(&geoip_as); - MMDB_close(&geoip_isp); - MMDB_close(&geoip_domain); -} - -#elif defined(HAVE_GEOIP) -/* - * Helper functions (mostly copied from bin/named/geoip.c) - */ - -static void -init_geoip_db(void **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, - GeoIPOptions method, const char *name) -{ - GeoIP *db; - - REQUIRE(dbp != NULL); - - db = (GeoIP *)*dbp; - - if (db != NULL) { - GeoIP_delete(db); - db = *dbp = NULL; - } - - if (! GeoIP_db_avail(edition)) { - goto fail; - } - - db = GeoIP_open_type(edition, method); - if (db == NULL) { - goto fail; - } - - *dbp = db; - return; - - fail: - if (fallback != 0) { - init_geoip_db(dbp, fallback, 0, method, name); - } -} - -static void -load_geoip(const char *dir) { - GeoIPOptions method; - -#ifdef _WIN32 - method = GEOIP_STANDARD; -#else - method = GEOIP_MMAP_CACHE; -#endif - - if (dir != NULL) { - char *p; - DE_CONST(dir, p); - GeoIP_setup_custom_directory(p); - } - - init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION, 0, - method, "Country (IPv4)"); -#ifdef HAVE_GEOIP_V6 - init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6, 0, - method, "Country (IPv6)"); -#endif - - init_geoip_db(&geoip.city_v4, GEOIP_CITY_EDITION_REV1, - GEOIP_CITY_EDITION_REV0, method, "City (IPv4)"); -#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6) - init_geoip_db(&geoip.city_v6, GEOIP_CITY_EDITION_REV1_V6, - GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)"); -#endif - - init_geoip_db(&geoip.region, GEOIP_REGION_EDITION_REV1, - GEOIP_REGION_EDITION_REV0, method, "Region"); - init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION, 0, - method, "ISP"); - init_geoip_db(&geoip.org, GEOIP_ORG_EDITION, 0, - method, "Org"); - init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION, 0, - method, "AS"); - init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION, 0, - method, "Domain"); - init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION, 0, - method, "NetSpeed"); -} - -static void -close_geoip(void) { - GeoIP_cleanup(); -} - -static bool -do_lookup_int(const char *addr, uint8_t *scope, - dns_geoip_subtype_t subtype, int id) -{ - dns_geoip_elem_t elt; - struct in_addr in4; - isc_netaddr_t na; - - inet_pton(AF_INET, addr, &in4); - isc_netaddr_fromin(&na, &in4); - - elt.subtype = subtype; - elt.as_int = id; - - return (dns_geoip_match(&na, scope, &geoip, &elt)); -} - -#endif /* HAVE_GEOIP */ - -#ifdef HAVE_GEOIP2 -static bool -/* Check if an MMDB entry of a given subtype exists for the given IP */ -entry_exists(dns_geoip_subtype_t subtype, const char *addr) { - struct in6_addr in6; - struct in_addr in4; - isc_netaddr_t na; - MMDB_s *db; - - if (inet_pton(AF_INET6, addr, &in6) == 1) { - isc_netaddr_fromin6(&na, &in6); - } else if (inet_pton(AF_INET, addr, &in4) == 1) { - isc_netaddr_fromin(&na, &in4); - } else { - INSIST(0); - ISC_UNREACHABLE(); - } - - db = geoip2_database(&geoip, fix_subtype(&geoip, subtype)); - - return (db != NULL && get_entry_for(db, &na) != NULL); -} - -/* - * Baseline test - check if get_entry_for() works as expected, i.e. that its - * return values are consistent with the contents of the test MMDBs found in - * bin/tests/system/geoip2/data/ (10.53.0.1 and fd92:7065:b8e:ffff::1 should be - * present in all databases, 192.0.2.128 should only be present in the country - * database, ::1 should be absent from all databases). - */ -static void -baseline(void **state) { - dns_geoip_subtype_t subtype; - - UNUSED(state); - - subtype = dns_geoip_city_name; - - assert_true(entry_exists(subtype, "10.53.0.1")); - assert_false(entry_exists(subtype, "192.0.2.128")); - assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1")); - assert_false(entry_exists(subtype, "::1")); - - subtype = dns_geoip_country_name; - - assert_true(entry_exists(subtype, "10.53.0.1")); - assert_true(entry_exists(subtype, "192.0.2.128")); - assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1")); - assert_false(entry_exists(subtype, "::1")); - - subtype = dns_geoip_domain_name; - - assert_true(entry_exists(subtype, "10.53.0.1")); - assert_false(entry_exists(subtype, "192.0.2.128")); - assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1")); - assert_false(entry_exists(subtype, "::1")); - - subtype = dns_geoip_isp_name; - - assert_true(entry_exists(subtype, "10.53.0.1")); - assert_false(entry_exists(subtype, "192.0.2.128")); - assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1")); - assert_false(entry_exists(subtype, "::1")); - - subtype = dns_geoip_as_asnum; - - assert_true(entry_exists(subtype, "10.53.0.1")); - assert_false(entry_exists(subtype, "192.0.2.128")); - assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1")); - assert_false(entry_exists(subtype, "::1")); -} -#endif /* HAVE_GEOIP2 */ - -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) -static bool -do_lookup_string(const char *addr, uint8_t *scope, - dns_geoip_subtype_t subtype, const char *string) -{ - dns_geoip_elem_t elt; - struct in_addr in4; - isc_netaddr_t na; - int n; - - n = inet_pton(AF_INET, addr, &in4); - assert_int_equal(n, 1); - isc_netaddr_fromin(&na, &in4); - - elt.subtype = subtype; - strlcpy(elt.as_string, string, sizeof(elt.as_string)); - - return (dns_geoip_match(&na, scope, &geoip, &elt)); -} - -static bool -do_lookup_string_v6(const char *addr, uint8_t *scope, - dns_geoip_subtype_t subtype, const char *string) -{ - dns_geoip_elem_t elt; - struct in6_addr in6; - isc_netaddr_t na; - int n; - - n = inet_pton(AF_INET6, addr, &in6); - assert_int_equal(n, 1); - isc_netaddr_fromin6(&na, &in6); - - elt.subtype = subtype; - strlcpy(elt.as_string, string, sizeof(elt.as_string)); - - return (dns_geoip_match(&na, scope, &geoip, &elt)); -} - -/* GeoIP country matching */ -static void -country(void **state) { - bool match; - uint8_t scope; - - UNUSED(state); - -#ifdef HAVE_GEOIP2 - if (geoip.country == NULL) { - skip(); - } -#else /* HAVE_GEOIP */ - if (geoip.country_v4 == NULL) { - skip(); - } -#endif /* HAVE_GEOIP */ - - match = do_lookup_string("10.53.0.1", &scope, - dns_geoip_country_code, "AU"); - assert_true(match); - assert_int_equal(scope, 32); - - match = do_lookup_string("10.53.0.1", &scope, - dns_geoip_country_name, "Australia"); - assert_true(match); - assert_int_equal(scope, 32); - - match = do_lookup_string("192.0.2.128", &scope, - dns_geoip_country_code, "O1"); - assert_true(match); - assert_int_equal(scope, 24); - - match = do_lookup_string("192.0.2.128", &scope, - dns_geoip_country_name, "Other"); - assert_true(match); - assert_int_equal(scope, 24); -} - -/* GeoIP country (ipv6) matching */ -static void -country_v6(void **state) { - bool match; - uint8_t scope; - - UNUSED(state); - -#ifdef HAVE_GEOIP2 - if (geoip.country == NULL) { - skip(); - } -#else /* HAVE_GEOIP */ - if (geoip.country_v6 == NULL) { - skip(); - } -#endif /* HAVE_GEOIP */ - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope, - dns_geoip_country_code, "AU"); - assert_true(match); - assert_int_equal(scope, 128); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope, - dns_geoip_country_name, "Australia"); - assert_true(match); - assert_int_equal(scope, 128); -} - -/* GeoIP city (ipv4) matching */ -static void -city(void **state) { - bool match; - - UNUSED(state); - -#ifdef HAVE_GEOIP2 - if (geoip.city == NULL) { - skip(); - } -#else /* HAVE_GEOIP */ - if (geoip.city_v4 == NULL) { - skip(); - } -#endif /* HAVE_GEOIP */ - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_continentcode, "NA"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_countrycode, "US"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_countryname, "United States"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_region, "CA"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_regionname, "California"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_name, "Redwood City"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_city_postalcode, "94063"); - assert_true(match); - -#ifdef HAVE_GEOIP - match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_areacode, 650); - assert_true(match); - - match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_metrocode, 807); - assert_true(match); -#endif -} - -/* GeoIP city (ipv6) matching */ -static void -city_v6(void **state) { - bool match; - - UNUSED(state); - -#ifdef HAVE_GEOIP2 - if (geoip.city == NULL) { - skip(); - } -#else /* HAVE_GEOIP */ - if (geoip.city_v6 == NULL) { - skip(); - } -#endif /* HAVE_GEOIP */ - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_continentcode, "NA"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_countrycode, "US"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_countryname, - "United States"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_region, "CA"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_regionname, "California"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_name, "Redwood City"); - assert_true(match); - - match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL, - dns_geoip_city_postalcode, "94063"); - assert_true(match); -} - -/* GeoIP asnum matching */ -static void -asnum(void **state) { - bool match; - - UNUSED(state); - - if (geoip.as == NULL) { - skip(); - } - - match = do_lookup_string("10.53.0.3", NULL, - dns_geoip_as_asnum, "AS100003"); - assert_true(match); -} - -/* GeoIP isp matching */ -static void -isp(void **state) { - bool match; - - UNUSED(state); - - if (geoip.isp == NULL) { - skip(); - } - - match = do_lookup_string("10.53.0.1", NULL, dns_geoip_isp_name, - "One Systems, Inc."); - assert_true(match); -} - -/* GeoIP org matching */ -static void -org(void **state) { - bool match; - - UNUSED(state); - -#ifdef HAVE_GEOIP2 - if (geoip.as == NULL) { - skip(); - } -#else /* HAVE_GEOIP */ - if (geoip.org == NULL) { - skip(); - } -#endif /* HAVE_GEOIP */ - - match = do_lookup_string("10.53.0.2", NULL, dns_geoip_org_name, - "Two Technology Ltd."); - assert_true(match); -} - -/* GeoIP domain matching */ -static void -domain(void **state) { - bool match; - - UNUSED(state); - - if (geoip.domain == NULL) { - skip(); - } - - match = do_lookup_string("10.53.0.5", NULL, - dns_geoip_domain_name, "five.es"); - assert_true(match); -} -#endif /* HAVE_GEOIP || HAVE_GEOIP2 */ - -#ifdef HAVE_GEOIP -/* GeoIP region matching */ -static void -region(void **state) { - bool match; - - UNUSED(state); - - /* Use databases from the geoip system test */ - load_geoip(TEST_GEOIP_DATA); - - if (geoip.region == NULL) { - skip(); - } - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_region_code, "CA"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_region_name, "California"); - assert_true(match); - - match = do_lookup_string("10.53.0.1", NULL, - dns_geoip_region_countrycode, "US"); - assert_true(match); -} - -/* GeoIP netspeed matching */ -static void -netspeed(void **state) { - bool match; - - UNUSED(state); - - /* Use databases from the geoip system test */ - load_geoip(TEST_GEOIP_DATA); - - if (geoip.netspeed == NULL) { - skip(); - } - - match = do_lookup_int("10.53.0.1", NULL, dns_geoip_netspeed_id, 0); - assert_true(match); - - match = do_lookup_int("10.53.0.2", NULL, dns_geoip_netspeed_id, 1); - assert_true(match); - - match = do_lookup_int("10.53.0.3", NULL, dns_geoip_netspeed_id, 2); - assert_true(match); - - match = do_lookup_int("10.53.0.4", NULL, dns_geoip_netspeed_id, 3); - assert_true(match); -} - -/* - * GeoIP best-database matching - * (With no specified database and a city database available, answers - * should come from city database. With city database unavailable, region - * database. Region database unavailable, country database.) - */ -static void -best(void **state) { - bool match; - - UNUSED(state); - - /* Use databases from the geoip system test */ - load_geoip(TEST_GEOIP_DATA); - - if (geoip.region == NULL) { - skip(); - } - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode, "US"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode3, "USA"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countryname, "United States"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_regionname, "Virginia"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_region, "VA"); - assert_true(match); - - GeoIP_delete(geoip.city_v4); - geoip.city_v4 = NULL; - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode, "AU"); - assert_true(match); - - /* - * Note, region doesn't support code3 or countryname, so - * the next two would be answered from the country database instead - */ - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode3, "CAN"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countryname, "Canada"); - assert_true(match); - - GeoIP_delete(geoip.region); - geoip.region = NULL; - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode, "CA"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countrycode3, "CAN"); - assert_true(match); - - match = do_lookup_string("10.53.0.4", NULL, - dns_geoip_countryname, "Canada"); - assert_true(match); -} -#endif /* HAVE_GEOIP */ - -int -main(void) { -#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2) - const struct CMUnitTest tests[] = { -#ifdef HAVE_GEOIP2 - cmocka_unit_test_setup_teardown(baseline, _setup, _teardown), -#endif /* HAVE_GEOIP2 */ - cmocka_unit_test_setup_teardown(country, _setup, _teardown), - cmocka_unit_test_setup_teardown(country_v6, _setup, _teardown), - cmocka_unit_test_setup_teardown(city, _setup, _teardown), - cmocka_unit_test_setup_teardown(city_v6, _setup, _teardown), - cmocka_unit_test_setup_teardown(asnum, _setup, _teardown), - cmocka_unit_test_setup_teardown(isp, _setup, _teardown), - cmocka_unit_test_setup_teardown(org, _setup, _teardown), - cmocka_unit_test_setup_teardown(domain, _setup, _teardown), -#ifdef HAVE_GEOIP - cmocka_unit_test_setup_teardown(region, _setup, _teardown), - cmocka_unit_test_setup_teardown(netspeed, _setup, _teardown), - cmocka_unit_test_setup_teardown(best, _setup, _teardown), -#endif /* HAVE_GEOIP */ - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skip GeoIP not enabled\n"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif /* HAVE_CMOCKA */ diff --git a/lib/dns-pkcs11/tests/gost_test.c b/lib/dns-pkcs11/tests/gost_test.c deleted file mode 100644 index 93824f1..0000000 --- a/lib/dns-pkcs11/tests/gost_test.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include "dnstest.h" - -#ifdef HAVE_OPENSSL_GOST -#include "../dst_gost.h" -#include -#include -#include -#include -#include -#endif - -#ifdef HAVE_PKCS11_GOST -#include "../dst_gost.h" -#include -#define WANT_GOST_PARAMS -#include -#include -#endif - -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* - * Test data from Wikipedia GOST (hash function) - */ - -unsigned char digest[ISC_GOST_DIGESTLENGTH]; -unsigned char buffer[1024]; -const char *s; -char str[2 * ISC_GOST_DIGESTLENGTH + 3]; -int i = 0; - -/* - * Precondition: a hexadecimal number in *d, the length of that number in len, - * and a pointer to a character array to put the output (*out). - * Postcondition: A String representation of the given hexadecimal number is - * placed into the array *out - * - * 'out' MUST point to an array of at least len * 2 + 1 - * - * Return values: ISC_R_SUCCESS if the operation is successful - */ -static isc_result_t -tohexstr(unsigned char *d, unsigned int len, char *out, size_t out_size) { - char c_ret[] = "AA"; - unsigned int j; - - out[0] = '\0'; - strlcat(out, "0x", out_size); - for (j = 0; j < len; j++) { - snprintf(c_ret, sizeof(c_ret), "%02X", d[j]); - strlcat(out, c_ret, out_size); - } - return (ISC_R_SUCCESS); -} - - -#define TEST_INPUT(x) (x), sizeof(x)-1 - -typedef struct hash_testcase { - const char *input; - size_t input_len; - const char *result; - int repeats; -} hash_testcase_t; - -/* GOST R 34.11-94 examples from Wikipedia */ -static void -isc_gost_md(void **state) { - isc_gost_t gost; - isc_result_t result; - - UNUSED(state); - - /* - * These are the various test vectors. All of these are passed - * through the hash function and the results are compared to the - * result specified here. - */ - hash_testcase_t testcases[] = { - /* Test 1 */ - { - TEST_INPUT(""), - "0x981E5F3CA30C841487830F84FB433E1" - "3AC1101569B9C13584AC483234CD656C0", - 1 - }, - /* Test 2 */ - { - TEST_INPUT("a"), - "0xE74C52DD282183BF37AF0079C9F7805" - "5715A103F17E3133CEFF1AACF2F403011", - 1 - }, - /* Test 3 */ - { - TEST_INPUT("abc"), - "0xB285056DBF18D7392D7677369524DD1" - "4747459ED8143997E163B2986F92FD42C", - 1 - }, - /* Test 4 */ - { - TEST_INPUT("message digest"), - "0xBC6041DD2AA401EBFA6E9886734174F" - "EBDB4729AA972D60F549AC39B29721BA0", - 1 - }, - /* Test 5 */ - { - TEST_INPUT("The quick brown fox jumps " - "over the lazy dog"), - "0x9004294A361A508C586FE53D1F1B027" - "46765E71B765472786E4770D565830A76", - 1 - }, - - /* Test 6 */ - { - TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" - "fghijklmnopqrstuvwxyz0123456789"), - "0x73B70A39497DE53A6E08C67B6D4DB85" - "3540F03E9389299D9B0156EF7E85D0F61", - 1 - }, - /* Test 7 */ - { - TEST_INPUT("1234567890123456789012345678901" - "2345678901234567890123456789012" - "345678901234567890"), - "0x6BC7B38989B28CF93AE8842BF9D7529" - "05910A7528A61E5BCE0782DE43E610C90", - 1 - }, - /* Test 8 */ - { - TEST_INPUT("This is message, length=32 bytes"), - "0x2CEFC2F7B7BDC514E18EA57FA74FF35" - "7E7FA17D652C75F69CB1BE7893EDE48EB", - 1 - }, - /* Test 9 */ - { - TEST_INPUT("Suppose the original message " - "has length = 50 bytes"), - "0xC3730C5CBCCACF915AC292676F21E8B" - "D4EF75331D9405E5F1A61DC3130A65011", - 1 - }, - /* Test 10 */ - { - TEST_INPUT("U") /* times 128 */, - "0x1C4AC7614691BBF427FA2316216BE8F" - "10D92EDFD37CD1027514C1008F649C4E8", - 128 - }, - /* Test 11 */ - { - TEST_INPUT("a") /* times 1000000 */, - "0x8693287AA62F9478F7CB312EC0866B6" - "C4E4A0F11160441E8F4FFCD2715DD554F", - 1000000 - }, - { NULL, 0, NULL, 1 } - }; - - hash_testcase_t *testcase = testcases; - - while (testcase->input != NULL && testcase->result != NULL) { - result = isc_gost_init(&gost); - assert_int_equal(result, ISC_R_SUCCESS); - for(i = 0; i < testcase->repeats; i++) { - result = isc_gost_update(&gost, - (const uint8_t *) testcase->input, - testcase->input_len); - assert_int_equal(result, ISC_R_SUCCESS); - } - result = isc_gost_final(&gost, digest); - assert_int_equal(result, ISC_R_SUCCESS); - tohexstr(digest, ISC_GOST_DIGESTLENGTH, str, sizeof(str)); - assert_string_equal(str, testcase->result); - - testcase++; - } -} - -/* GOST R 34.10-2001 private key */ -static void -isc_gost_private(void **state) { - unsigned char privraw[31] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e - }; -#ifdef HAVE_OPENSSL_GOST - unsigned char rbuf[32]; - unsigned char privasn1[70] = { - 0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, - 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, - 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, - 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, - 0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e - }; - unsigned char abuf[71]; - unsigned char gost_dummy_key[71] = { - 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, - 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, - 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, - 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, - 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b, - 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, - 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, - 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, - 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 - }; - EVP_PKEY *pkey; - EC_KEY *eckey; - BIGNUM *privkey; - const BIGNUM *privkey1; - const unsigned char *p; - int len; - unsigned char *q; - - UNUSED(state); - - /* raw parse */ - privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL); - assert_non_null(privkey); - p = gost_dummy_key; - pkey = NULL; - assert_non_null(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) sizeof(gost_dummy_key))); - assert_non_null(pkey); - assert_int_equal(EVP_PKEY_bits(pkey), 256); - eckey = EVP_PKEY_get0(pkey); - assert_non_null(eckey); - assert_int_equal(EC_KEY_set_private_key(eckey, privkey), 1); - BN_clear_free(privkey); - - /* asn1 tofile */ - len = i2d_PrivateKey(pkey, NULL); - assert_int_equal(len, 70); - q = abuf; - assert_int_equal(i2d_PrivateKey(pkey, &q), len); - assert_int_equal(memcmp(abuf, privasn1, len), 0); - EVP_PKEY_free(pkey); - - /* asn1 parse */ - p = privasn1; - pkey = NULL; - assert_non_null(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, - (long) len)); - assert_non_null(pkey); - eckey = EVP_PKEY_get0(pkey); - assert_non_null(eckey); - privkey1 = EC_KEY_get0_private_key(eckey); - len = BN_num_bytes(privkey1); - assert_int_equal(len, 31); - assert_int_equal(BN_bn2bin(privkey1, rbuf), len); - assert_memory_equal(rbuf, privraw, len); -#else - CK_BBOOL truevalue = TRUE; - CK_BBOOL falsevalue = FALSE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_GOSTR3410; - CK_ATTRIBUTE keyTemplate[] = - { - { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, - { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, - { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, - { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, - { CKA_VALUE, privraw, sizeof(privraw) }, - { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, - (CK_ULONG) sizeof(pk11_gost_a_paramset) }, - { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, - (CK_ULONG) sizeof(pk11_gost_paramset) } - }; - CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; - CK_BYTE sig[64]; - CK_ULONG siglen; - pk11_context_t pk11_ctx; - - /* create the private key */ - memset(&pk11_ctx, 0, sizeof(pk11_ctx)); - assert_int_equal(pk11_get_session(&pk11_ctx, OP_GOST, true, - false, false, NULL, - pk11_get_best_token(OP_GOST)), - ISC_R_SUCCESS); - pk11_ctx.object = CK_INVALID_HANDLE; - pk11_ctx.ontoken = false; - assert_int_equal(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate, - (CK_ULONG) 9, - &pk11_ctx.object), - CKR_OK); - assert_int_not_equal(pk11_ctx.object, CK_INVALID_HANDLE); - - /* sign something */ - assert_int_equal(pkcs_C_SignInit(pk11_ctx.session, &mech, - pk11_ctx.object), - CKR_OK); - siglen = 0; - assert_int_equal(pkcs_C_Sign(pk11_ctx.session, sig, 64, - NULL, &siglen), - CKR_OK); - assert_int_equal(siglen, 64); - assert_int_equal(pkcs_C_Sign(pk11_ctx.session, sig, 64, - sig, &siglen), - CKR_OK); - assert_int_equal(siglen, 64); -#endif -}; -#endif - -int -main(void) { -#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_gost_md, - _setup, _teardown), - cmocka_unit_test_setup_teardown(isc_gost_private, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skip GOST is unavailable"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/keytable_test.c b/lib/dns-pkcs11/tests/keytable_test.c deleted file mode 100644 index 56f8749..0000000 --- a/lib/dns-pkcs11/tests/keytable_test.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dnstest.h" - -#if defined(OPENSSL) || defined(PKCS11CRYPTO) - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, true); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -dns_keytable_t *keytable = NULL; -dns_ntatable_t *ntatable = NULL; - -static const char *keystr1 = "BQEAAAABok+vaUC9neRv8yeT/FEGgN7svR8s7VBUVSBd8NsAiV8AlaAg O5FHar3JQd95i/puZos6Vi6at9/JBbN8qVmO2AuiXxVqfxMKxIcy+LEB 0Vw4NaSJ3N3uaVREso6aTSs98H/25MjcwLOr7SFfXA7bGhZatLtYY/xu kp6Km5hMfkE="; -static const dns_keytag_t keytag1 = 30591; - -static const char *keystr2 = "BQEAAAABwuHz9Cem0BJ0JQTO7C/a3McR6hMaufljs1dfG/inaJpYv7vH XTrAOm/MeKp+/x6eT4QLru0KoZkvZJnqTI8JyaFTw2OM/ItBfh/hL2lm Cft2O7n3MfeqYtvjPnY7dWghYW4sVfH7VVEGm958o9nfi79532Qeklxh x8pXWdeAaRU="; - -static dns_view_t *view = NULL; - -/* - * Test utilities. In general, these assume input parameters are valid - * (checking with assert_int_equal, thus aborting if not) and unlikely run time - * errors (such as memory allocation failure) won't happen. This helps keep - * the test code concise. - */ - -/* - * Utility to convert C-string to dns_name_t. Return a pointer to - * static data, and so is not thread safe. - */ -static dns_name_t * -str2name(const char *namestr) { - static dns_fixedname_t fname; - static dns_name_t *name; - static isc_buffer_t namebuf; - void *deconst_namestr; - - name = dns_fixedname_initname(&fname); - DE_CONST(namestr, deconst_namestr); /* OK, since we don't modify it */ - isc_buffer_init(&namebuf, deconst_namestr, strlen(deconst_namestr)); - isc_buffer_add(&namebuf, strlen(namestr)); - assert_int_equal(dns_name_fromtext(name, &namebuf, dns_rootname, - 0, NULL), - ISC_R_SUCCESS); - - return (name); -} - -static void -create_key(uint16_t flags, uint8_t proto, uint8_t alg, - const char *keynamestr, const char *keystr, dst_key_t **target) -{ - dns_rdata_dnskey_t keystruct; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; - unsigned char rrdata[4096]; - isc_buffer_t rrdatabuf; - isc_region_t r; - const dns_rdataclass_t rdclass = dns_rdataclass_in; /* for brevity */ - - keystruct.common.rdclass = rdclass; - keystruct.common.rdtype = dns_rdatatype_dnskey; - keystruct.mctx = NULL; - ISC_LINK_INIT(&keystruct.common, link); - keystruct.flags = flags; - keystruct.protocol = proto; - keystruct.algorithm = alg; - - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - assert_int_equal(isc_base64_decodestring(keystr, &keydatabuf), - ISC_R_SUCCESS); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; - assert_int_equal(dns_rdata_fromstruct(NULL, keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf), - ISC_R_SUCCESS); - - assert_int_equal(dst_key_fromdns(str2name(keynamestr), rdclass, - &rrdatabuf, mctx, target), - ISC_R_SUCCESS); -} - -/* Common setup: create a keytable and ntatable to test with a few keys */ -static void -create_tables() { - isc_result_t result; - dst_key_t *key = NULL; - isc_stdtime_t now; - - result = dns_test_makeview("view", &view); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_int_equal(dns_keytable_create(mctx, &keytable), ISC_R_SUCCESS); - assert_int_equal(dns_ntatable_create(view, taskmgr, timermgr, - &ntatable), ISC_R_SUCCESS); - - /* Add a normal key */ - create_key(257, 3, 5, "example.com", keystr1, &key); - assert_int_equal(dns_keytable_add(keytable, false, &key), - ISC_R_SUCCESS); - - /* Add a null key */ - assert_int_equal(dns_keytable_marksecure(keytable, - str2name("null.example")), - ISC_R_SUCCESS); - - /* Add a negative trust anchor, duration 1 hour */ - isc_stdtime_get(&now); - assert_int_equal(dns_ntatable_add(ntatable, - str2name("insecure.example"), - false, now, 3600), - ISC_R_SUCCESS); -} - -static void -destroy_tables() { - if (ntatable != NULL) { - dns_ntatable_detach(&ntatable); - } - if (keytable != NULL) { - dns_keytable_detach(&keytable); - } - - dns_view_detach(&view); -} - -/* add keys to the keytable */ -static void -add_test(void **state) { - dst_key_t *key = NULL; - dns_keynode_t *keynode = NULL; - dns_keynode_t *next_keynode = NULL; - dns_keynode_t *null_keynode = NULL; - - UNUSED(state); - - create_tables(); - - /* - * Get the keynode for the example.com key. There's no other key for - * the name, so nextkeynode() should return NOTFOUND. - */ - assert_int_equal(dns_keytable_find(keytable, str2name("example.com"), - &keynode), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_nextkeynode(keytable, keynode, - &next_keynode), - ISC_R_NOTFOUND); - - /* - * Try to add the same key. This should have no effect, so - * nextkeynode() should still return NOTFOUND. - */ - create_key(257, 3, 5, "example.com", keystr1, &key); - assert_int_equal(dns_keytable_add(keytable, false, &key), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_nextkeynode(keytable, keynode, - &next_keynode), - ISC_R_NOTFOUND); - - /* Add another key (different keydata) */ - dns_keytable_detachkeynode(keytable, &keynode); - create_key(257, 3, 5, "example.com", keystr2, &key); - assert_int_equal(dns_keytable_add(keytable, false, &key), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_find(keytable, str2name("example.com"), - &keynode), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_nextkeynode(keytable, keynode, - &next_keynode), - ISC_R_SUCCESS); - dns_keytable_detachkeynode(keytable, &next_keynode); - - /* - * Add a normal key to a name that has a null key. The null key node - * will be updated with the normal key. - */ - dns_keytable_detachkeynode(keytable, &keynode); - assert_int_equal(dns_keytable_find(keytable, str2name("null.example"), - &null_keynode), ISC_R_SUCCESS); - create_key(257, 3, 5, "null.example", keystr2, &key); - assert_int_equal(dns_keytable_add(keytable, false, &key), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_find(keytable, str2name("null.example"), - &keynode), - ISC_R_SUCCESS); - assert_ptr_equal(keynode, null_keynode); /* should be the same node */ - assert_non_null(dns_keynode_key(keynode)); /* now have a key */ - dns_keytable_detachkeynode(keytable, &null_keynode); - - /* - * Try to add a null key to a name that already has a key. It's - * effectively no-op, so the same key node is still there, with no - * no next node. - * (Note: this and above checks confirm that if a name has a null key - * that's the only key for the name). - */ - assert_int_equal(dns_keytable_marksecure(keytable, - str2name("null.example")), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_find(keytable, str2name("null.example"), - &null_keynode), - ISC_R_SUCCESS); - assert_ptr_equal(keynode, null_keynode); - assert_non_null(dns_keynode_key(keynode)); - assert_int_equal(dns_keytable_nextkeynode(keytable, keynode, - &next_keynode), - ISC_R_NOTFOUND); - dns_keytable_detachkeynode(keytable, &null_keynode); - - dns_keytable_detachkeynode(keytable, &keynode); - destroy_tables(); -} - -/* delete keys from the keytable */ -static void -delete_test(void **state) { - UNUSED(state); - - create_tables(); - - /* dns_keytable_delete requires exact match */ - assert_int_equal(dns_keytable_delete(keytable, - str2name("example.org")), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_delete(keytable, - str2name("s.example.com")), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_delete(keytable, - str2name("example.com")), - ISC_R_SUCCESS); - - /* works also for nodes with a null key */ - assert_int_equal(dns_keytable_delete(keytable, - str2name("null.example")), - ISC_R_SUCCESS); - - /* or a negative trust anchor */ - assert_int_equal(dns_ntatable_delete(ntatable, - str2name("insecure.example")), - ISC_R_SUCCESS); - - destroy_tables(); -} - -/* delete key nodes from the keytable */ -static void -deletekeynode_test(void **state) { - dst_key_t *key = NULL; - - UNUSED(state); - - create_tables(); - - /* key name doesn't match */ - create_key(257, 3, 5, "example.org", keystr1, &key); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - ISC_R_NOTFOUND); - dst_key_free(&key); - - /* subdomain match is the same as no match */ - create_key(257, 3, 5, "sub.example.com", keystr1, &key); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - ISC_R_NOTFOUND); - dst_key_free(&key); - - /* name matches but key doesn't match (resulting in PARTIALMATCH) */ - create_key(257, 3, 5, "example.com", keystr2, &key); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - DNS_R_PARTIALMATCH); - dst_key_free(&key); - - /* - * exact match. after deleting the node the internal rbt node will be - * empty, and any delete or deletekeynode attempt should result in - * NOTFOUND. - */ - create_key(257, 3, 5, "example.com", keystr1, &key); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - ISC_R_SUCCESS); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_delete(keytable, - str2name("example.com")), - ISC_R_NOTFOUND); - dst_key_free(&key); - - /* - * A null key node for a name is not deleted when searched by key; - * it must be deleted by dns_keytable_delete() - */ - create_key(257, 3, 5, "null.example", keystr1, &key); - assert_int_equal(dns_keytable_deletekeynode(keytable, key), - DNS_R_PARTIALMATCH); - assert_int_equal(dns_keytable_delete(keytable, dst_key_name(key)), - ISC_R_SUCCESS); - dst_key_free(&key); - - destroy_tables(); -} - -/* check find-variant operations */ -static void -find_test(void **state) { - dns_keynode_t *keynode = NULL; - dns_fixedname_t fname; - dns_name_t *name; - - UNUSED(state); - - create_tables(); - - /* - * dns_keytable_find() requires exact name match. It matches node - * that has a null key, too. - */ - assert_int_equal(dns_keytable_find(keytable, str2name("example.org"), - &keynode), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_find(keytable, - str2name("sub.example.com"), - &keynode), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_find(keytable, - str2name("example.com"), - &keynode), - ISC_R_SUCCESS); - dns_keytable_detachkeynode(keytable, &keynode); - assert_int_equal(dns_keytable_find(keytable, - str2name("null.example"), - &keynode), - ISC_R_SUCCESS); - assert_null(dns_keynode_key(keynode)); - dns_keytable_detachkeynode(keytable, &keynode); - - /* - * dns_keytable_finddeepestmatch() allows partial match. Also match - * nodes with a null key. - */ - name = dns_fixedname_initname(&fname); - assert_int_equal(dns_keytable_finddeepestmatch(keytable, - str2name("example.com"), - name), - ISC_R_SUCCESS); - assert_true(dns_name_equal(name, str2name("example.com"))); - assert_int_equal(dns_keytable_finddeepestmatch(keytable, - str2name("s.example.com"), - name), - ISC_R_SUCCESS); - assert_true(dns_name_equal(name, str2name("example.com"))); - assert_int_equal(dns_keytable_finddeepestmatch(keytable, - str2name("example.org"), - name), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_finddeepestmatch(keytable, - str2name("null.example"), - name), - ISC_R_SUCCESS); - assert_true(dns_name_equal(name, str2name("null.example"))); - - /* - * dns_keytable_findkeynode() requires exact name, algorithm, keytag - * match. If algorithm or keytag doesn't match, should result in - * PARTIALMATCH. Same for a node with a null key. - */ - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("example.org"), - 5, keytag1, &keynode), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("sub.example.com"), - 5, keytag1, &keynode), - ISC_R_NOTFOUND); - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("example.com"), - 4, keytag1, &keynode), - DNS_R_PARTIALMATCH); /* different algorithm */ - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("example.com"), - 5, keytag1 + 1, &keynode), - DNS_R_PARTIALMATCH); /* different keytag */ - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("null.example"), - 5, 0, &keynode), - DNS_R_PARTIALMATCH); /* null key */ - assert_int_equal(dns_keytable_findkeynode(keytable, - str2name("example.com"), - 5, keytag1, &keynode), - ISC_R_SUCCESS); /* complete match */ - dns_keytable_detachkeynode(keytable, &keynode); - - destroy_tables(); -} - -/* check issecuredomain() */ -static void -issecuredomain_test(void **state) { - bool issecure; - const char **n; - const char *names[] = {"example.com", "sub.example.com", - "null.example", "sub.null.example", NULL}; - - UNUSED(state); - create_tables(); - - /* - * Domains that are an exact or partial match of a key name are - * considered secure. It's the case even if the key is null - * (validation will then fail, but that's actually the intended effect - * of installing a null key). - */ - for (n = names; *n != NULL; n++) { - assert_int_equal(dns_keytable_issecuredomain(keytable, - str2name(*n), - NULL, - &issecure), - ISC_R_SUCCESS); - assert_true(issecure); - } - - /* - * If the key table has no entry (not even a null one) for a domain or - * any of its ancestors, that domain is considered insecure. - */ - assert_int_equal(dns_keytable_issecuredomain(keytable, - str2name("example.org"), - NULL, - &issecure), - ISC_R_SUCCESS); - assert_false(issecure); - - destroy_tables(); -} - -/* check dns_keytable_dump() */ -static void -dump_test(void **state) { - FILE *f = fopen("/dev/null", "w"); - - UNUSED(state); - - create_tables(); - - /* - * Right now, we only confirm the dump attempt doesn't cause disruption - * (so we don't check the dump content). - */ - assert_int_equal(dns_keytable_dump(keytable, f), ISC_R_SUCCESS); - fclose(f); - - destroy_tables(); -} - -/* check negative trust anchors */ -static void -nta_test(void **state) { - isc_result_t result; - dst_key_t *key = NULL; - bool issecure, covered; - dns_view_t *myview = NULL; - isc_stdtime_t now; - - UNUSED(state); - - result = dns_test_makeview("view", &myview); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_task_create(taskmgr, 0, &myview->task); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_view_initsecroots(myview, mctx); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_view_getsecroots(myview, &keytable); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_view_initntatable(myview, taskmgr, timermgr); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_view_getntatable(myview, &ntatable); - assert_int_equal(result, ISC_R_SUCCESS); - - create_key(257, 3, 5, "example", keystr1, &key); - result = dns_keytable_add(keytable, false, &key); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_stdtime_get(&now); - result = dns_ntatable_add(ntatable, - str2name("insecure.example"), - false, now, 1); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Should be secure */ - result = dns_view_issecuredomain(myview, - str2name("test.secure.example"), - now, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_false(covered); - assert_true(issecure); - - /* Should not be secure */ - result = dns_view_issecuredomain(myview, - str2name("test.insecure.example"), - now, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(covered); - assert_false(issecure); - - /* NTA covered */ - covered = dns_view_ntacovers(myview, now, str2name("insecure.example"), - dns_rootname); - assert_true(covered); - - /* Not NTA covered */ - covered = dns_view_ntacovers(myview, now, str2name("secure.example"), - dns_rootname); - assert_false(covered); - - /* As of now + 2, the NTA should be clear */ - result = dns_view_issecuredomain(myview, - str2name("test.insecure.example"), - now + 2, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_false(covered); - assert_true(issecure); - - /* Now check deletion */ - result = dns_view_issecuredomain(myview, str2name("test.new.example"), - now, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_false(covered); - assert_true(issecure); - - result = dns_ntatable_add(ntatable, str2name("new.example"), - false, now, 3600); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_view_issecuredomain(myview, str2name("test.new.example"), - now, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(covered); - assert_false(issecure); - - result = dns_ntatable_delete(ntatable, str2name("new.example")); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_view_issecuredomain(myview, str2name("test.new.example"), - now, true, &covered, &issecure); - assert_int_equal(result, ISC_R_SUCCESS); - assert_false(covered); - assert_true(issecure); - - /* Clean up */ - dns_ntatable_detach(&ntatable); - dns_keytable_detach(&keytable); - dns_view_detach(&myview); -} -#endif - -int -main(void) { -#if defined(OPENSSL) || defined(PKCS11CRYPTO) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(add_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(delete_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(deletekeynode_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(find_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(issecuredomain_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dump_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(nta_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skipped: keytable requires crypto\n"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/master_test.c b/lib/dns-pkcs11/tests/master_test.c deleted file mode 100644 index 4f91e46..0000000 --- a/lib/dns-pkcs11/tests/master_test.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static void -nullmsg(dns_rdatacallbacks_t *cb, const char *fmt, ...) { - UNUSED(cb); - UNUSED(fmt); -} - -#define BUFLEN 255 -#define BIGBUFLEN (70 * 1024) -#define TEST_ORIGIN "test" - -static dns_masterrawheader_t header; -static bool headerset; - -dns_name_t dns_origin; -char origin[sizeof(TEST_ORIGIN)]; -unsigned char name_buf[BUFLEN]; -dns_rdatacallbacks_t callbacks; -char *include_file = NULL; - -static isc_result_t -add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset); - -static void -rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *header); - -static isc_result_t -add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) { - char buf[BIGBUFLEN]; - isc_buffer_t target; - isc_result_t result; - - UNUSED(arg); - - isc_buffer_init(&target, buf, BIGBUFLEN); - result = dns_rdataset_totext(dataset, owner, false, false, - &target); - return(result); -} - -static void -rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *h) { - UNUSED(zone); - header = *h; - headerset = true; -} - -static isc_result_t -setup_master(void (*warn)(struct dns_rdatacallbacks *, const char *, ...), - void (*error)(struct dns_rdatacallbacks *, const char *, ...)) -{ - isc_result_t result; - int len; - isc_buffer_t source; - isc_buffer_t target; - - strlcpy(origin, TEST_ORIGIN, sizeof(origin)); - len = strlen(origin); - isc_buffer_init(&source, origin, len); - isc_buffer_add(&source, len); - isc_buffer_setactive(&source, len); - isc_buffer_init(&target, name_buf, BUFLEN); - dns_name_init(&dns_origin, NULL); - dns_master_initrawheader(&header); - - result = dns_name_fromtext(&dns_origin, &source, dns_rootname, - 0, &target); - if (result != ISC_R_SUCCESS) { - return(result); - } - - dns_rdatacallbacks_init_stdio(&callbacks); - callbacks.add = add_callback; - callbacks.rawdata = rawdata_callback; - callbacks.zone = NULL; - if (warn != NULL) { - callbacks.warn = warn; - } - if (error != NULL) { - callbacks.error = error; - } - headerset = false; - return (result); -} - -static isc_result_t -test_master(const char *testfile, dns_masterformat_t format, - void (*warn)(struct dns_rdatacallbacks *, const char *, ...), - void (*error)(struct dns_rdatacallbacks *, const char *, ...)) -{ - isc_result_t result; - - result = setup_master(warn, error); - if (result != ISC_R_SUCCESS) { - return(result); - } - - dns_rdatacallbacks_init_stdio(&callbacks); - callbacks.add = add_callback; - callbacks.rawdata = rawdata_callback; - callbacks.zone = NULL; - if (warn != NULL) { - callbacks.warn = warn; - } - if (error != NULL) { - callbacks.error = error; - } - - result = dns_master_loadfile2(testfile, &dns_origin, &dns_origin, - dns_rdataclass_in, true, - &callbacks, mctx, format); - return (result); -} - -static void -include_callback(const char *filename, void *arg) { - char **argp = (char **) arg; - *argp = isc_mem_strdup(mctx, filename); -} - -/* - * Successful load test: - * dns_master_loadfile() loads a valid master file and returns success - */ -static void -load_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master1.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - - -/* - * Unexpected end of file test: - * dns_master_loadfile() returns DNS_R_UNEXPECTED when file ends too soon - */ -static void -unexpected_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master2.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_UNEXPECTEDEND); -} - -/* - * No owner test: - * dns_master_loadfile() accepts broken zones with no TTL for first record - * if it is an SOA - */ -static void -noowner_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master3.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, DNS_R_NOOWNER); -} - -/* - * No TTL test: - * dns_master_loadfile() returns DNS_R_NOOWNER when no owner name is - * specified - */ -static void -nottl_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master4.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* - * Bad class test: - * dns_master_loadfile() returns DNS_R_BADCLASS when record class doesn't - * match zone class - */ -static void -badclass_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master5.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, DNS_R_BADCLASS); -} - -/* - * Too big rdata test: - * dns_master_loadfile() returns ISC_R_NOSPACE when record is too big - */ -static void -toobig_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master15.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_NOSPACE); -} - -/* - * Maximum rdata test: - * dns_master_loadfile() returns ISC_R_SUCCESS when record is maximum size - */ -static void -maxrdata_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master16.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* - * DNSKEY test: - * dns_master_loadfile() understands DNSKEY with key material - */ -static void -dnskey_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master6.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* - * DNSKEY with no key material test: - * dns_master_loadfile() understands DNSKEY with no key material - * - * RFC 4034 removed the ability to signal NOKEY, so empty key material should - * be rejected. - */ -static void -dnsnokey_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master7.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_UNEXPECTEDEND); -} - -/* - * Include test: - * dns_master_loadfile() understands $INCLUDE - */ -static void -include_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master8.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, DNS_R_SEENINCLUDE); -} - -/* - * Include file list test: - * dns_master_loadfile4() returns names of included file - */ -static void -master_includelist_test(void **state) { - isc_result_t result; - char *filename = NULL; - - UNUSED(state); - - result = setup_master(nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_master_loadfile4("testdata/master/master8.data", - &dns_origin, &dns_origin, - dns_rdataclass_in, 0, true, - &callbacks, include_callback, - &filename, mctx, dns_masterformat_text); - assert_int_equal(result, DNS_R_SEENINCLUDE); - assert_non_null(filename); - if (filename != NULL) { - assert_string_equal(filename, "testdata/master/master6.data"); - isc_mem_free(mctx, filename); - } -} - -/* - * Include failure test: - * dns_master_loadfile() understands $INCLUDE failures - */ -static void -includefail_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master9.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, DNS_R_BADCLASS); -} - -/* - * Non-empty blank lines test: - * dns_master_loadfile() handles non-empty blank lines - */ -static void -blanklines_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master10.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* - * SOA leading zeroes test: - * dns_master_loadfile() allows leading zeroes in SOA - */ - -static void -leadingzero_test(void **state) { - isc_result_t result; - - UNUSED(state); - - result = test_master("testdata/master/master11.data", - dns_masterformat_text, nullmsg, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* masterfile totext tests */ -static void -totext_test(void **state) { - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatalist_t rdatalist; - isc_buffer_t target; - unsigned char buf[BIGBUFLEN]; - - UNUSED(state); - - /* First, test with an empty rdataset */ - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = dns_rdataclass_in; - rdatalist.type = dns_rdatatype_none; - rdatalist.covers = dns_rdatatype_none; - - dns_rdataset_init(&rdataset); - result = dns_rdatalist_tordataset(&rdatalist, &rdataset); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_buffer_init(&target, buf, BIGBUFLEN); - result = dns_master_rdatasettotext(dns_rootname, - &rdataset, &dns_master_style_debug, - &target); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(isc_buffer_usedlength(&target), 0); - - /* - * XXX: We will also need to add tests for dumping various - * rdata types, classes, etc, and comparing the results against - * known-good output. - */ -} - -/* - * Raw load test: - * dns_master_loadfile() loads a valid raw file and returns success - */ -static void -loadraw_test(void **state) { - isc_result_t result; - - UNUSED(state); - - /* Raw format version 0 */ - result = test_master("testdata/master/master12.data", - dns_masterformat_raw, nullmsg, nullmsg); - assert_string_equal(isc_result_totext(result), "success"); - assert_true(headerset); - assert_int_equal(header.flags, 0); - - /* Raw format version 1, no source serial */ - result = test_master("testdata/master/master13.data", - dns_masterformat_raw, nullmsg, nullmsg); - assert_string_equal(isc_result_totext(result), "success"); - assert_true(headerset); - assert_int_equal(header.flags, 0); - - /* Raw format version 1, source serial == 2011120101 */ - result = test_master("testdata/master/master14.data", - dns_masterformat_raw, nullmsg, nullmsg); - assert_string_equal(isc_result_totext(result), "success"); - assert_true(headerset); - assert_true((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0); - assert_int_equal(header.sourceserial, 2011120101); -} - -/* - * Raw dump test: - * dns_master_dump*() functions dump valid raw files - */ -static void -dumpraw_test(void **state) { - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *version = NULL; - char myorigin[sizeof(TEST_ORIGIN)]; - dns_name_t dnsorigin; - isc_buffer_t source, target; - unsigned char namebuf[BUFLEN]; - int len; - - UNUSED(state); - - strlcpy(myorigin, TEST_ORIGIN, sizeof(myorigin)); - len = strlen(myorigin); - isc_buffer_init(&source, myorigin, len); - isc_buffer_add(&source, len); - isc_buffer_setactive(&source, len); - isc_buffer_init(&target, namebuf, BUFLEN); - dns_name_init(&dnsorigin, NULL); - result = dns_name_fromtext(&dnsorigin, &source, dns_rootname, - 0, &target); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_create(mctx, "rbt", &dnsorigin, dns_dbtype_zone, - dns_rdataclass_in, 0, NULL, &db); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_db_load(db, "testdata/master/master1.data"); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_db_currentversion(db, &version); - - result = dns_master_dump2(mctx, db, version, - &dns_master_style_default, "test.dump", - dns_masterformat_raw); - assert_int_equal(result, ISC_R_SUCCESS); - - result = test_master("test.dump", dns_masterformat_raw, - nullmsg, nullmsg); - assert_string_equal(isc_result_totext(result), "success"); - assert_true(headerset); - assert_int_equal(header.flags, 0); - - dns_master_initrawheader(&header); - header.sourceserial = 12345; - header.flags |= DNS_MASTERRAW_SOURCESERIALSET; - - unlink("test.dump"); - result = dns_master_dump3(mctx, db, version, - &dns_master_style_default, "test.dump", - dns_masterformat_raw, &header); - assert_int_equal(result, ISC_R_SUCCESS); - - result = test_master("test.dump", dns_masterformat_raw, - nullmsg, nullmsg); - assert_string_equal(isc_result_totext(result), "success"); - assert_true(headerset); - assert_true((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0); - assert_int_equal(header.sourceserial, 12345); - - unlink("test.dump"); - dns_db_closeversion(db, &version, false); - dns_db_detach(&db); -} - -static const char *warn_expect_value; -static bool warn_expect_result; - -static void -warn_expect(struct dns_rdatacallbacks *mycallbacks, const char *fmt, ...) { - char buf[4096]; - va_list ap; - - UNUSED(mycallbacks); - - warn_expect_result = false; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if (warn_expect_value != NULL && - strstr(buf, warn_expect_value) != NULL) - { - warn_expect_result = true; - } -} - -/* - * Origin change test: - * dns_master_loadfile() rejects zones with inherited name following $ORIGIN - */ -static void -neworigin_test(void **state) { - isc_result_t result; - - UNUSED(state); - - warn_expect_value = "record with inherited owner"; - result = test_master("testdata/master/master17.data", - dns_masterformat_text, warn_expect, nullmsg); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(warn_expect_result); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(load_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(unexpected_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(noowner_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(nottl_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(badclass_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dnskey_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dnsnokey_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(include_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(master_includelist_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(includefail_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(blanklines_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(leadingzero_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(totext_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(loadraw_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(dumpraw_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(toobig_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(maxrdata_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(neworigin_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/mkraw.pl b/lib/dns-pkcs11/tests/mkraw.pl deleted file mode 100644 index b05d798..0000000 --- a/lib/dns-pkcs11/tests/mkraw.pl +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -# Convert a hexdump to binary format. -# -# To convert binary data to the input format for this command, -# use the following: -# -# perl -e 'while (read(STDIN, my $byte, 1)) { -# print unpack("H2", $byte); -# } -# print "\n";' < file > file.in - -use strict; -chomp(my $line = ); -print pack("H*", $line); diff --git a/lib/dns-pkcs11/tests/name_test.c b/lib/dns-pkcs11/tests/name_test.c deleted file mode 100644 index 04e7be0..0000000 --- a/lib/dns-pkcs11/tests/name_test.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dnstest.h" - -/* Set to true (or use -v option) for verbose output */ -static bool verbose = false; - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* dns_name_fullcompare test */ -static void -fullcompare_test(void **state) { - dns_fixedname_t fixed1; - dns_fixedname_t fixed2; - dns_name_t *name1; - dns_name_t *name2; - dns_namereln_t relation; - int i; - isc_result_t result; - struct { - const char *name1; - const char *name2; - dns_namereln_t relation; - int order; - unsigned int nlabels; - } data[] = { - /* relative */ - { "", "", dns_namereln_equal, 0, 0 }, - { "foo", "", dns_namereln_subdomain, 1, 0 }, - { "", "foo", dns_namereln_contains, -1, 0 }, - { "foo", "bar", dns_namereln_none, 4, 0 }, - { "bar", "foo", dns_namereln_none, -4, 0 }, - { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 }, - { "foo", "bar.foo", dns_namereln_contains, -1, 1 }, - { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 }, - { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 }, - { "foo.example", "bar.example", dns_namereln_commonancestor, - 4, 1 }, - - /* absolute */ - { ".", ".", dns_namereln_equal, 0, 1 }, - { "foo.", "bar.", dns_namereln_commonancestor, 4, 1 }, - { "bar.", "foo.", dns_namereln_commonancestor, -4, 1 }, - { "foo.example.", "bar.example.", dns_namereln_commonancestor, - 4, 2 }, - { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 }, - { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 }, - { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 }, - { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 }, - { NULL, NULL, dns_namereln_none, 0, 0 } - }; - - UNUSED(state); - - name1 = dns_fixedname_initname(&fixed1); - name2 = dns_fixedname_initname(&fixed2); - for (i = 0; data[i].name1 != NULL; i++) { - int order = 3000; - unsigned int nlabels = 3000; - - if (data[i].name1[0] == 0) { - dns_fixedname_init(&fixed1); - } else { - result = dns_name_fromstring2(name1, data[i].name1, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - } - if (data[i].name2[0] == 0) { - dns_fixedname_init(&fixed2); - } else { - result = dns_name_fromstring2(name2, data[i].name2, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - } - relation = dns_name_fullcompare(name1, name1, &order, &nlabels); - assert_int_equal(relation, dns_namereln_equal); - assert_int_equal(order, 0); - assert_int_equal(nlabels, name1->labels); - - /* Some random initializer */ - order = 3001; - nlabels = 3001; - - relation = dns_name_fullcompare(name1, name2, &order, &nlabels); - assert_int_equal(relation, data[i].relation); - assert_int_equal(order, data[i].order); - assert_int_equal(nlabels, data[i].nlabels); - } -} - -static void -compress_test(dns_name_t *name1, dns_name_t *name2, dns_name_t *name3, - unsigned char *expected, unsigned int length, - dns_compress_t *cctx, dns_decompress_t *dctx) -{ - isc_buffer_t source; - isc_buffer_t target; - dns_name_t name; - unsigned char buf1[1024]; - unsigned char buf2[1024]; - - isc_buffer_init(&source, buf1, sizeof(buf1)); - isc_buffer_init(&target, buf2, sizeof(buf2)); - - assert_int_equal(dns_name_towire(name1, cctx, &source), ISC_R_SUCCESS); - - assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS); - assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS); - assert_int_equal(dns_name_towire(name3, cctx, &source), ISC_R_SUCCESS); - - isc_buffer_setactive(&source, source.used); - - dns_name_init(&name, NULL); - RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, - &target) == ISC_R_SUCCESS); - RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, - &target) == ISC_R_SUCCESS); - RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, - &target) == ISC_R_SUCCESS); - RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, - &target) == ISC_R_SUCCESS); - dns_decompress_invalidate(dctx); - - assert_int_equal(target.used, length); - assert_true(memcmp(target.base, expected, target.used) == 0); -} - -/* name compression test */ -static void -compression_test(void **state) { - unsigned int allowed; - dns_compress_t cctx; - dns_decompress_t dctx; - dns_name_t name1; - dns_name_t name2; - dns_name_t name3; - isc_region_t r; - unsigned char plain1[] = "\003yyy\003foo"; - unsigned char plain2[] = "\003bar\003yyy\003foo"; - unsigned char plain3[] = "\003xxx\003bar\003foo"; - unsigned char plain[] = "\003yyy\003foo\0\003bar\003yyy\003foo\0\003" - "bar\003yyy\003foo\0\003xxx\003bar\003foo"; - - UNUSED(state); - - dns_name_init(&name1, NULL); - r.base = plain1; - r.length = sizeof(plain1); - dns_name_fromregion(&name1, &r); - - dns_name_init(&name2, NULL); - r.base = plain2; - r.length = sizeof(plain2); - dns_name_fromregion(&name2, &r); - - dns_name_init(&name3, NULL); - r.base = plain3; - r.length = sizeof(plain3); - dns_name_fromregion(&name3, &r); - - /* Test 1: NONE */ - allowed = DNS_COMPRESS_NONE; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); - - /* Test2: GLOBAL14 */ - allowed = DNS_COMPRESS_GLOBAL14; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); - - /* Test3: ALL */ - allowed = DNS_COMPRESS_ALL; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); - - /* Test4: NONE disabled */ - allowed = DNS_COMPRESS_NONE; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_compress_disable(&cctx); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); - - /* Test5: GLOBAL14 disabled */ - allowed = DNS_COMPRESS_GLOBAL14; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_compress_disable(&cctx); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); - - /* Test6: ALL disabled */ - allowed = DNS_COMPRESS_ALL; - assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS); - dns_compress_setmethods(&cctx, allowed); - dns_compress_disable(&cctx); - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, allowed); - - compress_test(&name1, &name2, &name3, plain, sizeof(plain), - &cctx, &dctx); - - dns_compress_rollback(&cctx, 0); - dns_compress_invalidate(&cctx); -} - -/* is trust-anchor-telemetry test */ -static void -istat_test(void **state) { - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - size_t i; - struct { - const char *name; - bool istat; - } data[] = { - { ".", false }, - { "_ta-", false }, - { "_ta-1234", true }, - { "_TA-1234", true }, - { "+TA-1234", false }, - { "_fa-1234", false }, - { "_td-1234", false }, - { "_ta_1234", false }, - { "_ta-g234", false }, - { "_ta-1h34", false }, - { "_ta-12i4", false }, - { "_ta-123j", false }, - { "_ta-1234-abcf", true }, - { "_ta-1234-abcf-ED89", true }, - { "_ta-12345-abcf-ED89", false }, - { "_ta-.example", false }, - { "_ta-1234.example", true }, - { "_ta-1234-abcf.example", true }, - { "_ta-1234-abcf-ED89.example", true }, - { "_ta-12345-abcf-ED89.example", false }, - { "_ta-1234-abcfe-ED89.example", false }, - { "_ta-1234-abcf-EcD89.example", false } - }; - - UNUSED(state); - - name = dns_fixedname_initname(&fixed); - - for (i = 0; i < (sizeof(data) / sizeof(data[0])); i++) { - result = dns_name_fromstring(name, data[i].name, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dns_name_istat(name), data[i].istat); - } -} - -/* dns_nane_init */ -static void -init_test(void **state) { - dns_name_t name; - unsigned char offsets[1]; - - UNUSED(state); - - dns_name_init(&name, offsets); - - assert_null(name.ndata); - assert_int_equal(name.length, 0); - assert_int_equal(name.labels, 0); - assert_int_equal(name.attributes, 0); - assert_ptr_equal(name.offsets, offsets); - assert_null(name.buffer); -} - -/* dns_nane_invalidate */ -static void -invalidate_test(void **state) { - dns_name_t name; - unsigned char offsets[1]; - - UNUSED(state); - - dns_name_init(&name, offsets); - dns_name_invalidate(&name); - - assert_null(name.ndata); - assert_int_equal(name.length, 0); - assert_int_equal(name.labels, 0); - assert_int_equal(name.attributes, 0); - assert_null(name.offsets); - assert_null(name.buffer); -} - -/* dns_nane_setbuffer/hasbuffer */ -static void -buffer_test(void **state) { - dns_name_t name; - unsigned char buf[BUFSIZ]; - isc_buffer_t b; - - UNUSED(state); - - isc_buffer_init(&b, buf, BUFSIZ); - dns_name_init(&name, NULL); - dns_name_setbuffer(&name, &b); - assert_ptr_equal(name.buffer, &b); - assert_true(dns_name_hasbuffer(&name)); -} - -/* dns_nane_isabsolute */ -static void -isabsolute_test(void **state) { - struct { - const char *namestr; - bool expect; - } testcases[] = { - { "x", false }, - { "a.b.c.d.", true }, - { "x.z", false} - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_name_t name; - unsigned char data[BUFSIZ]; - isc_buffer_t b, nb; - size_t len; - - len = strlen(testcases[i].namestr); - isc_buffer_constinit(&b, testcases[i].namestr, len); - isc_buffer_add(&b, len); - - dns_name_init(&name, NULL); - isc_buffer_init(&nb, data, BUFSIZ); - dns_name_setbuffer(&name, &nb); - result = dns_name_fromtext(&name, &b, NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_int_equal(dns_name_isabsolute(&name), - testcases[i].expect); - } -} - -/* dns_nane_hash */ -static void -hash_test(void **state) { - struct { - const char *name1; - const char *name2; - bool expect; - bool expecti; - } testcases[] = { - { "a.b.c.d", "A.B.C.D", true, false }, - { "a.b.c.d.", "A.B.C.D.", true, false }, - { "a.b.c.d", "a.b.c.d", true, true }, - { "A.B.C.D.", "A.B.C.D.", true, false }, - { "x.y.z.w", "a.b.c.d", false, false }, - { "x.y.z.w.", "a.b.c.d.", false, false }, - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_fixedname_t f1, f2; - dns_name_t *n1, *n2; - unsigned int h1, h2; - - n1 = dns_fixedname_initname(&f1); - n2 = dns_fixedname_initname(&f2); - - result = dns_name_fromstring2(n1, testcases[i].name1, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_name_fromstring2(n2, testcases[i].name2, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Check case-insensitive hashing first */ - h1 = dns_name_hash(n1, false); - h2 = dns_name_hash(n2, false); - - if (verbose) { - print_message("# %s hashes to %u, " - "%s to %u, case insensitive\n", - testcases[i].name1, h1, - testcases[i].name2, h2); - } - - assert_int_equal((h1 == h2), testcases[i].expect); - - /* Now case-sensitive */ - h1 = dns_name_hash(n1, false); - h2 = dns_name_hash(n2, false); - - if (verbose) { - print_message("# %s hashes to %u, " - "%s to %u, case sensitive\n", - testcases[i].name1, h1, - testcases[i].name2, h2); - } - - assert_int_equal((h1 == h2), testcases[i].expect); - } -} - -/* dns_nane_issubdomain */ -static void -issubdomain_test(void **state) { - struct { - const char *name1; - const char *name2; - bool expect; - } testcases[] = { - { "c.d", "a.b.c.d", false }, - { "c.d.", "a.b.c.d.", false }, - { "b.c.d", "c.d", true }, - { "a.b.c.d.", "c.d.", true }, - { "a.b.c", "a.b.c", true }, - { "a.b.c.", "a.b.c.", true }, - { "x.y.z", "a.b.c", false} - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_fixedname_t f1, f2; - dns_name_t *n1, *n2; - - n1 = dns_fixedname_initname(&f1); - n2 = dns_fixedname_initname(&f2); - - result = dns_name_fromstring2(n1, testcases[i].name1, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_name_fromstring2(n2, testcases[i].name2, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - if (verbose) { - print_message("# check: %s %s a subdomain of %s\n", - testcases[i].name1, - testcases[i].expect ? "is" : "is not", - testcases[i].name2); - } - - assert_int_equal(dns_name_issubdomain(n1, n2), - testcases[i].expect); - } -} - -/* dns_nane_countlabels */ -static void -countlabels_test(void **state) { - struct { - const char *namestr; - unsigned int expect; - } testcases[] = { - { "c.d", 2 }, - { "c.d.", 3 }, - { "a.b.c.d.", 5 }, - { "a.b.c.d", 4 }, - { "a.b.c", 3 }, - { ".", 1 }, - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_fixedname_t fname; - dns_name_t *name; - - name = dns_fixedname_initname(&fname); - - result = dns_name_fromstring2(name, testcases[i].namestr, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - if (verbose) { - print_message("# %s: expect %u labels\n", - testcases[i].namestr, - testcases[i].expect); - } - - assert_int_equal(dns_name_countlabels(name), - testcases[i].expect); - } -} - -/* dns_nane_getlabel */ -static void -getlabel_test(void **state) { - struct { - const char *name1; - unsigned int pos1; - const char *name2; - unsigned int pos2; - } testcases[] = { - { "c.d", 1, "a.b.c.d", 3 }, - { "a.b.c.d", 3, "c.d", 1 }, - { "a.b.c.", 3, "A.B.C.", 3 }, - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_fixedname_t f1, f2; - dns_name_t *n1, *n2; - dns_label_t l1, l2; - unsigned int j; - - n1 = dns_fixedname_initname(&f1); - n2 = dns_fixedname_initname(&f2); - - result = dns_name_fromstring2(n1, testcases[i].name1, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_name_fromstring2(n2, testcases[i].name2, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_name_getlabel(n1, testcases[i].pos1, &l1); - dns_name_getlabel(n2, testcases[i].pos2, &l2); - assert_int_equal(l1.length, l2.length); - - for (j = 0; j < l1.length; j++) { - assert_int_equal(l1.base[j], l2.base[j]); - } - } -} - -/* dns_nane_getlabelsequence */ -static void -getlabelsequence_test(void **state) { - struct { - const char *name1; - unsigned int pos1; - const char *name2; - unsigned int pos2; - unsigned int range; - } testcases[] = { - { "c.d", 1, "a.b.c.d", 3, 1 }, - { "a.b.c.d.e", 2, "c.d", 0, 2 }, - { "a.b.c", 0, "a.b.c", 0, 3 }, - - }; - unsigned int i; - - UNUSED(state); - - for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) { - isc_result_t result; - dns_name_t t1, t2; - dns_fixedname_t f1, f2; - dns_name_t *n1, *n2; - - /* target names */ - dns_name_init(&t1, NULL); - dns_name_init(&t2, NULL); - - /* source names */ - n1 = dns_fixedname_initname(&f1); - n2 = dns_fixedname_initname(&f2); - - result = dns_name_fromstring2(n1, testcases[i].name1, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_name_fromstring2(n2, testcases[i].name2, - NULL, 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_name_getlabelsequence(n1, testcases[i].pos1, - testcases[i].range, &t1); - dns_name_getlabelsequence(n2, testcases[i].pos2, - testcases[i].range, &t2); - - assert_true(dns_name_equal(&t1, &t2)); - } -} - -#ifdef ISC_PLATFORM_USETHREADS -#ifdef DNS_BENCHMARK_TESTS - -/* - * XXXMUKS: Don't delete this code. It is useful in benchmarking the - * name parser, but we don't require it as part of the unit test runs. - */ - -/* Benchmark dns_name_fromwire() implementation */ - -static void * -fromwire_thread(void *arg) { - unsigned int maxval = 32000000; - uint8_t data[] = { - 3, 'w', 'w', 'w', - 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', - 7, 'i', 'n', 'v', 'a', 'l', 'i', 'd', - 0 - }; - unsigned char output_data[DNS_NAME_MAXWIRE]; - isc_buffer_t source, target; - unsigned int i; - dns_decompress_t dctx; - - UNUSED(arg); - - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); - dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE); - - isc_buffer_init(&source, data, sizeof(data)); - isc_buffer_add(&source, sizeof(data)); - isc_buffer_init(&target, output_data, sizeof(output_data)); - - /* Parse 32 million names in each thread */ - for (i = 0; i < maxval; i++) { - dns_name_t name; - - isc_buffer_clear(&source); - isc_buffer_clear(&target); - isc_buffer_add(&source, sizeof(data)); - isc_buffer_setactive(&source, sizeof(data)); - - dns_name_init(&name, NULL); - (void) dns_name_fromwire(&name, &source, &dctx, 0, &target); - } - - return (NULL); -} - -static void -benchmark_test(void **state) { - isc_result_t result; - unsigned int i; - isc_time_t ts1, ts2; - double t; - unsigned int nthreads; - isc_thread_t threads[32]; - - UNUSED(state); - - debug_mem_record = false; - - result = isc_time_now(&ts1); - assert_int_equal(result, ISC_R_SUCCESS); - - nthreads = ISC_MIN(isc_os_ncpus(), 32); - nthreads = ISC_MAX(nthreads, 1); - for (i = 0; i < nthreads; i++) { - result = isc_thread_create(fromwire_thread, NULL, &threads[i]); - assert_int_equal(result, ISC_R_SUCCESS); - } - - for (i = 0; i < nthreads; i++) { - result = isc_thread_join(threads[i], NULL); - assert_int_equal(result, ISC_R_SUCCESS); - } - - result = isc_time_now(&ts2); - assert_int_equal(result, ISC_R_SUCCESS); - - t = isc_time_microdiff(&ts2, &ts1); - - printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n", - nthreads * 32000000, t / 1000000.0, - (nthreads * 32000000) / (t / 1000000.0)); -} - -#endif /* DNS_BENCHMARK_TESTS */ -#endif /* ISC_PLATFORM_USETHREADS */ - -int -main(int argc, char **argv) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(fullcompare_test), - cmocka_unit_test_setup_teardown(compression_test, - _setup, _teardown), - cmocka_unit_test(istat_test), - cmocka_unit_test(init_test), - cmocka_unit_test(invalidate_test), - cmocka_unit_test(buffer_test), - cmocka_unit_test(isabsolute_test), - cmocka_unit_test(hash_test), - cmocka_unit_test(issubdomain_test), - cmocka_unit_test(countlabels_test), - cmocka_unit_test(getlabel_test), - cmocka_unit_test(getlabelsequence_test), -#ifdef ISC_PLATFORM_USETHREADS -#ifdef DNS_BENCHMARK_TESTS - cmocka_unit_test_setup_teardown(benchmark_test, - _setup, _teardown), -#endif /* DNS_BENCHMARK_TESTS */ -#endif /* ISC_PLATFORM_USETHREADS */ - }; - int c; - - while ((c = isc_commandline_parse(argc, argv, "v")) != -1) { - switch (c) { - case 'v': - verbose = true; - break; - default: - break; - } - } - - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/nsec3_test.c b/lib/dns-pkcs11/tests/nsec3_test.c deleted file mode 100644 index 512da66..0000000 --- a/lib/dns-pkcs11/tests/nsec3_test.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include -#include - -#include "dnstest.h" - -#if defined(OPENSSL) || defined(PKCS11CRYPTO) -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static void -iteration_test(const char *file, unsigned int expected) { - isc_result_t result; - dns_db_t *db = NULL; - unsigned int iterations; - - result = dns_test_loaddb(&db, dns_dbtype_zone, "test", file); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_nsec3_maxiterations(db, NULL, mctx, &iterations); - assert_int_equal(result, ISC_R_SUCCESS); - - assert_int_equal(iterations, expected); - - dns_db_detach(&db); -} - -/*% - * Structure containing parameters for nsec3param_salttotext_test(). - */ -typedef struct { - const char *nsec3param_text; /* NSEC3PARAM RDATA in text form */ - const char *expected_salt; /* string expected in target buffer */ -} nsec3param_salttotext_test_params_t; - -/*% - * Check whether dns_nsec3param_salttotext() handles supplied text form - * NSEC3PARAM RDATA correctly: test whether the result of calling the former is - * as expected and whether it properly checks available buffer space. - * - * Assumes supplied text form NSEC3PARAM RDATA is valid as testing handling of - * invalid NSEC3PARAM RDATA is out of scope of this unit test. - */ -static void -nsec3param_salttotext_test(const nsec3param_salttotext_test_params_t *params) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec3param_t nsec3param; - unsigned char buf[1024]; - isc_result_t result; - char salt[64]; - size_t length; - - /* - * Prepare a dns_rdata_nsec3param_t structure for testing. - */ - result = dns_test_rdatafromstring(&rdata, dns_rdataclass_in, - dns_rdatatype_nsec3param, buf, - sizeof(buf), - params->nsec3param_text, false); - assert_int_equal(result, ISC_R_SUCCESS); - result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Check typical use. - */ - result = dns_nsec3param_salttotext(&nsec3param, salt, sizeof(salt)); - assert_int_equal(result, ISC_R_SUCCESS); - assert_string_equal(salt, params->expected_salt); - - /* - * Ensure available space in the buffer is checked before the salt is - * printed to it and that the amount of space checked for includes the - * terminating NULL byte. - */ - length = strlen(params->expected_salt); - assert_true(length < sizeof(salt) - 1); /* prevent buffer overwrite */ - assert_true(length > 0U); /* prevent length underflow */ - - result = dns_nsec3param_salttotext(&nsec3param, salt, length - 1); - assert_int_equal(result, ISC_R_NOSPACE); - - result = dns_nsec3param_salttotext(&nsec3param, salt, length); - assert_int_equal(result, ISC_R_NOSPACE); - - result = dns_nsec3param_salttotext(&nsec3param, salt, length + 1); - assert_int_equal(result, ISC_R_SUCCESS); -} - -/* - * check that appropriate max iterations is returned for different - * key size mixes - */ -static void -max_iterations(void **state) { - UNUSED(state); - - iteration_test("testdata/nsec3/1024.db", 150); - iteration_test("testdata/nsec3/2048.db", 500); - iteration_test("testdata/nsec3/4096.db", 2500); - iteration_test("testdata/nsec3/min-1024.db", 150); - iteration_test("testdata/nsec3/min-2048.db", 500); -} - -/* check dns_nsec3param_salttotext() */ -static void -nsec3param_salttotext(void **state) { - size_t i; - - const nsec3param_salttotext_test_params_t tests[] = { - /* - * Tests with non-empty salts. - */ - { "0 0 10 0123456789abcdef", "0123456789ABCDEF" }, - { "0 1 11 0123456789abcdef", "0123456789ABCDEF" }, - { "1 0 12 42", "42" }, - { "1 1 13 42", "42" }, - /* - * Test with empty salt. - */ - { "0 0 0 -", "-" }, - }; - - UNUSED(state); - - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - nsec3param_salttotext_test(&tests[i]); - } -} -#endif - -int -main(void) { -#if defined(OPENSSL) || defined(PKCS11CRYPTO) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(max_iterations, - _setup, _teardown), - cmocka_unit_test_setup_teardown(nsec3param_salttotext, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skipped: nsec3 test requires crypto\n"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/peer_test.c b/lib/dns-pkcs11/tests/peer_test.c deleted file mode 100644 index 36a0edf..0000000 --- a/lib/dns-pkcs11/tests/peer_test.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include - -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* Test DSCP set/get functions */ -static void -dscp_test(void **state) { - isc_result_t result; - isc_netaddr_t netaddr; - struct in_addr ina; - dns_peer_t *peer = NULL; - isc_dscp_t dscp; - - UNUSED(state); - - /* - * Create peer structure for the loopback address. - */ - ina.s_addr = INADDR_LOOPBACK; - isc_netaddr_fromin(&netaddr, &ina); - result = dns_peer_new(mctx, &netaddr, &peer); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * All should be not set on creation. - * 'dscp' should remain unchanged. - */ - dscp = 100; - result = dns_peer_getquerydscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - result = dns_peer_getnotifydscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - result = dns_peer_gettransferdscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - /* - * Test that setting query dscp does not affect the other - * dscp values. 'dscp' should remain unchanged until - * dns_peer_getquerydscp is called. - */ - dscp = 100; - result = dns_peer_setquerydscp(peer, 1); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_peer_getnotifydscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - result = dns_peer_gettransferdscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - result = dns_peer_getquerydscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 1); - - /* - * Test that setting notify dscp does not affect the other - * dscp values. 'dscp' should remain unchanged until - * dns_peer_getquerydscp is called then should change again - * on dns_peer_getnotifydscp. - */ - dscp = 100; - result = dns_peer_setnotifydscp(peer, 2); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_peer_gettransferdscp(peer, &dscp); - assert_int_equal(result, ISC_R_NOTFOUND); - assert_int_equal(dscp, 100); - - result = dns_peer_getquerydscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 1); - - result = dns_peer_getnotifydscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 2); - - /* - * Test that setting notify dscp does not affect the other - * dscp values. Check that appropriate values are returned. - */ - dscp = 100; - result = dns_peer_settransferdscp(peer, 3); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_peer_getquerydscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 1); - - result = dns_peer_getnotifydscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 2); - - result = dns_peer_gettransferdscp(peer, &dscp); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dscp, 3); - - dns_peer_detach(&peer); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(dscp_test, _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/private_test.c b/lib/dns-pkcs11/tests/private_test.c deleted file mode 100644 index fde132c..0000000 --- a/lib/dns-pkcs11/tests/private_test.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "dnstest.h" - -static dns_rdatatype_t privatetype = 65534; - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -typedef struct { - unsigned char alg; - dns_keytag_t keyid; - bool remove; - bool complete; -} signing_testcase_t; - -typedef struct { - unsigned char hash; - unsigned char flags; - unsigned int iterations; - unsigned long salt; - bool remove; - bool pending; - bool nonsec; -} nsec3_testcase_t; - -static void -make_signing(signing_testcase_t *testcase, dns_rdata_t *private, - unsigned char *buf, size_t len) -{ - dns_rdata_init(private); - - buf[0] = testcase->alg; - buf[1] = (testcase->keyid & 0xff00) >> 8; - buf[2] = (testcase->keyid & 0xff); - buf[3] = testcase->remove; - buf[4] = testcase->complete; - private->data = buf; - private->length = len; - private->type = privatetype; - private->rdclass = dns_rdataclass_in; -} - -static void -make_nsec3(nsec3_testcase_t *testcase, dns_rdata_t *private, - unsigned char *pbuf) -{ - dns_rdata_nsec3param_t params; - dns_rdata_t nsec3param = DNS_RDATA_INIT; - unsigned char bufdata[BUFSIZ]; - isc_buffer_t buf; - uint32_t salt; - unsigned char *sp; - int slen = 4; - - /* for simplicity, we're using a maximum salt length of 4 */ - salt = htonl(testcase->salt); - sp = (unsigned char *) &salt; - while (slen > 0 && *sp == '\0') { - slen--; - sp++; - } - - params.common.rdclass = dns_rdataclass_in; - params.common.rdtype = dns_rdatatype_nsec3param; - params.hash = testcase->hash; - params.iterations = testcase->iterations; - params.salt = sp; - params.salt_length = slen; - - params.flags = testcase->flags; - if (testcase->remove) { - params.flags |= DNS_NSEC3FLAG_REMOVE; - if (testcase->nonsec) { - params.flags |= DNS_NSEC3FLAG_NONSEC; - } - } else { - params.flags |= DNS_NSEC3FLAG_CREATE; - if (testcase->pending) { - params.flags |= DNS_NSEC3FLAG_INITIAL; - } - } - - isc_buffer_init(&buf, bufdata, sizeof(bufdata)); - dns_rdata_fromstruct(&nsec3param, dns_rdataclass_in, - dns_rdatatype_nsec3param, ¶ms, &buf); - - dns_rdata_init(private); - - dns_nsec3param_toprivate(&nsec3param, private, privatetype, - pbuf, DNS_NSEC3PARAM_BUFFERSIZE + 1); -} - -/* convert private signing records to text */ -static void -private_signing_totext_test(void **state) { - dns_rdata_t private; - int i; - - signing_testcase_t testcases[] = { - { DST_ALG_RSASHA512, 12345, 0, 0 }, - { DST_ALG_RSASHA256, 54321, 1, 0 }, - { DST_ALG_NSEC3RSASHA1, 22222, 0, 1 }, - { DST_ALG_RSASHA1, 33333, 1, 1 } - }; - const char *results[] = { - "Signing with key 12345/RSASHA512", - "Removing signatures for key 54321/RSASHA256", - "Done signing with key 22222/NSEC3RSASHA1", - "Done removing signatures for key 33333/RSASHA1" - }; - int ncases = 4; - - UNUSED(state); - - for (i = 0; i < ncases; i++) { - unsigned char data[5]; - char output[BUFSIZ]; - isc_buffer_t buf; - - isc_buffer_init(&buf, output, sizeof(output)); - - make_signing(&testcases[i], &private, data, sizeof(data)); - dns_private_totext(&private, &buf); - assert_string_equal(output, results[i]); - } - -} - -/* convert private chain records to text */ -static void -private_nsec3_totext_test(void **state) { - dns_rdata_t private; - int i; - - nsec3_testcase_t testcases[] = { - { 1, 0, 1, 0xbeef, 0, 0, 0 }, - { 1, 1, 10, 0xdadd, 0, 0, 0 }, - { 1, 0, 20, 0xbead, 0, 1, 0 }, - { 1, 0, 30, 0xdeaf, 1, 0, 0 }, - { 1, 0, 100, 0xfeedabee, 1, 0, 1 }, - }; - const char *results[] = { - "Creating NSEC3 chain 1 0 1 BEEF", - "Creating NSEC3 chain 1 1 10 DADD", - "Pending NSEC3 chain 1 0 20 BEAD", - "Removing NSEC3 chain 1 0 30 DEAF / creating NSEC chain", - "Removing NSEC3 chain 1 0 100 FEEDABEE" - }; - int ncases = 5; - - UNUSED(state); - - for (i = 0; i < ncases; i++) { - unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; - char output[BUFSIZ]; - isc_buffer_t buf; - - isc_buffer_init(&buf, output, sizeof(output)); - - make_nsec3(&testcases[i], &private, data); - dns_private_totext(&private, &buf); - assert_string_equal(output, results[i]); - } -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(private_signing_totext_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(private_nsec3_totext_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rbt_serialize_test.c b/lib/dns-pkcs11/tests/rbt_serialize_test.c deleted file mode 100644 index 089a244..0000000 --- a/lib/dns-pkcs11/tests/rbt_serialize_test.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dnstest.h" - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -/* Set to true (or use -v option) for verbose output */ -static bool verbose = false; - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -typedef struct data_holder { - int len; - const char *data; -} data_holder_t; - -typedef struct rbt_testdata { - const char *name; - size_t name_len; - data_holder_t data; -} rbt_testdata_t; - -#define DATA_ITEM(name) { (name), sizeof(name) - 1, { sizeof(name), (name) } } - -rbt_testdata_t testdata[] = { - DATA_ITEM("first.com."), - DATA_ITEM("one.net."), - DATA_ITEM("two.com."), - DATA_ITEM("three.org."), - DATA_ITEM("asdf.com."), - DATA_ITEM("ghjkl.com."), - DATA_ITEM("1.edu."), - DATA_ITEM("2.edu."), - DATA_ITEM("3.edu."), - DATA_ITEM("123.edu."), - DATA_ITEM("1236.com."), - DATA_ITEM("and_so_forth.com."), - DATA_ITEM("thisisalongname.com."), - DATA_ITEM("a.b."), - DATA_ITEM("test.net."), - DATA_ITEM("whoknows.org."), - DATA_ITEM("blargh.com."), - DATA_ITEM("www.joe.com."), - DATA_ITEM("test.com."), - DATA_ITEM("isc.org."), - DATA_ITEM("uiop.mil."), - DATA_ITEM("last.fm."), - { NULL, 0, { 0, NULL } } -}; - -static void -delete_data(void *data, void *arg) { - UNUSED(arg); - UNUSED(data); -} - -static isc_result_t -write_data(FILE *file, unsigned char *datap, void *arg, uint64_t *crc) { - isc_result_t result; - size_t ret = 0; - data_holder_t *data; - data_holder_t temp; - off_t where; - - UNUSED(arg); - - REQUIRE(file != NULL); - REQUIRE(crc != NULL); - REQUIRE(datap != NULL); - data = (data_holder_t *)datap; - REQUIRE((data->len == 0 && data->data == NULL) || - (data->len != 0 && data->data != NULL)); - - result = isc_stdio_tell(file, &where); - if (result != ISC_R_SUCCESS) { - return (result); - } - - temp = *data; - temp.data = (data->len == 0 - ? NULL - : (char *)((uintptr_t)where + sizeof(data_holder_t))); - - isc_crc64_update(crc, (void *)&temp, sizeof(temp)); - ret = fwrite(&temp, sizeof(data_holder_t), 1, file); - if (ret != 1) { - return (ISC_R_FAILURE); - } - if (data->len > 0) { - isc_crc64_update(crc, (const void *)data->data, data->len); - ret = fwrite(data->data, data->len, 1, file); - if (ret != 1) { - return (ISC_R_FAILURE); - } - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -fix_data(dns_rbtnode_t *p, void *base, size_t max, void *arg, uint64_t *crc) { - data_holder_t *data; - size_t size; - - UNUSED(base); - UNUSED(max); - UNUSED(arg); - - REQUIRE(crc != NULL); - REQUIRE(p != NULL); - - data = p->data; - - if (data == NULL || - (data->len == 0 && data->data != NULL) || - (data->len != 0 && data->data == NULL)) - { - return (ISC_R_INVALIDFILE); - } - - size = max - ((char *)p - (char *)base); - - if (data->len > (int) size || data->data > (const char *) max) { - return (ISC_R_INVALIDFILE); - } - - isc_crc64_update(crc, (void *)data, sizeof(*data)); - - data->data = NULL; - if (data->len != 0) { - data->data = (char *)data + sizeof(data_holder_t); - } - - if (data->len > 0) { - isc_crc64_update(crc, (const void *)data->data, data->len); - } - - return (ISC_R_SUCCESS); -} - -/* - * Load test data into the RBT. - */ -static void -add_test_data(isc_mem_t *mymctx, dns_rbt_t *rbt) { - char buffer[1024]; - isc_buffer_t b; - isc_result_t result; - dns_fixedname_t fname; - dns_name_t *name; - dns_compress_t cctx; - rbt_testdata_t *testdatap = testdata; - - dns_compress_init(&cctx, -1, mymctx); - - while (testdatap->name != NULL && testdatap->data.data != NULL) { - memmove(buffer, testdatap->name, testdatap->name_len); - - isc_buffer_init(&b, buffer, testdatap->name_len); - isc_buffer_add(&b, testdatap->name_len); - name = dns_fixedname_initname(&fname); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - testdatap++; - continue; - } - - if (name != NULL) { - result = dns_rbt_addname(rbt, name, &testdatap->data); - assert_int_equal(result, ISC_R_SUCCESS); - } - testdatap++; - } - - dns_compress_invalidate(&cctx); -} - -/* - * Walk the tree and ensure that all the test nodes are present. - */ -static void -check_test_data(dns_rbt_t *rbt) { - char buffer[1024]; - char *arg; - dns_fixedname_t fname; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - data_holder_t *data; - isc_result_t result; - dns_name_t *foundname; - rbt_testdata_t *testdatap = testdata; - - foundname = dns_fixedname_initname(&fixed); - - while (testdatap->name != NULL && testdatap->data.data != NULL) { - memmove(buffer, testdatap->name, testdatap->name_len + 1); - arg = buffer; - - isc_buffer_init(&b, arg, testdatap->name_len); - isc_buffer_add(&b, testdatap->name_len); - name = dns_fixedname_initname(&fname); - result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); - if (result != ISC_R_SUCCESS) { - testdatap++; - continue; - } - - data = NULL; - result = dns_rbt_findname(rbt, name, 0, foundname, - (void *) &data); - assert_int_equal(result, ISC_R_SUCCESS); - - testdatap++; - } -} - -static void -data_printer(FILE *out, void *datap) { - data_holder_t *data = (data_holder_t *)datap; - - fprintf(out, "%d bytes, %s", data->len, data->data); -} - -/* Test writing an rbt to file */ -static void -serialize_test(void **state) { - dns_rbt_t *rbt = NULL; - isc_result_t result; - FILE *rbtfile = NULL; - dns_rbt_t *rbt_deserialized = NULL; - off_t offset; - int fd; - off_t filesize = 0; - char *base; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - result = dns_rbt_create(mctx, delete_data, NULL, &rbt); - assert_int_equal(result, ISC_R_SUCCESS); - - add_test_data(mctx, rbt); - - if (verbose) { - dns_rbt_printtext(rbt, data_printer, stdout); - } - - /* - * Serialize the tree. - */ - rbtfile = fopen("./zone.bin", "w+b"); - assert_non_null(rbtfile); - result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL, - &offset); - assert_true(result == ISC_R_SUCCESS); - dns_rbt_destroy(&rbt); - - /* - * Deserialize the tree. - * Map in the whole file in one go - */ - fd = open("zone.bin", O_RDWR); - assert_int_not_equal(fd, -1); - isc_file_getsizefd(fd, &filesize); - base = mmap(NULL, filesize, PROT_READ|PROT_WRITE, - MAP_FILE|MAP_PRIVATE, fd, 0); - assert_true(base != NULL && base != MAP_FAILED); - close(fd); - - result = dns_rbt_deserialize_tree(base, filesize, 0, mctx, - delete_data, NULL, fix_data, NULL, - NULL, &rbt_deserialized); - - /* Test to make sure we have a valid tree */ - assert_true(result == ISC_R_SUCCESS); - if (rbt_deserialized == NULL) { - fail_msg("deserialized rbt is null!"); /* Abort execution. */ - } - - check_test_data(rbt_deserialized); - - if (verbose) { - dns_rbt_printtext(rbt_deserialized, data_printer, stdout); - } - - dns_rbt_destroy(&rbt_deserialized); - munmap(base, filesize); - unlink("zone.bin"); -} - -/* Test reading a corrupt map file */ -static void -deserialize_corrupt_test(void **state) { - dns_rbt_t *rbt = NULL; - isc_result_t result; - FILE *rbtfile = NULL; - off_t offset; - int fd; - off_t filesize = 0; - char *base, *p, *q; - uint32_t r; - int i; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - /* Set up map file */ - result = dns_rbt_create(mctx, delete_data, NULL, &rbt); - assert_int_equal(result, ISC_R_SUCCESS); - - add_test_data(mctx, rbt); - rbtfile = fopen("./zone.bin", "w+b"); - assert_non_null(rbtfile); - result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL, - &offset); - assert_true(result == ISC_R_SUCCESS); - dns_rbt_destroy(&rbt); - - /* Read back with random fuzzing */ - for (i = 0; i < 256; i++) { - dns_rbt_t *rbt_deserialized = NULL; - - fd = open("zone.bin", O_RDWR); - assert_int_not_equal(fd, -1); - isc_file_getsizefd(fd, &filesize); - base = mmap(NULL, filesize, PROT_READ|PROT_WRITE, - MAP_FILE|MAP_PRIVATE, fd, 0); - assert_true(base != NULL && base != MAP_FAILED); - close(fd); - - /* Randomly fuzz a portion of the memory */ - isc_random_get(&r); - /* cppcheck-suppress nullPointerArithmeticRedundantCheck */ - p = base + (r % filesize); - /* cppcheck-suppress nullPointerArithmeticRedundantCheck */ - q = base + filesize; - isc_random_get(&r); - q -= (r % (q - p)); - while (p++ < q) { - isc_random_get(&r); - *p = r & 0xff; - } - - result = dns_rbt_deserialize_tree(base, filesize, 0, mctx, - delete_data, NULL, - fix_data, NULL, - NULL, &rbt_deserialized); - - /* Test to make sure we have a valid tree */ - assert_true(result == ISC_R_SUCCESS || - result == ISC_R_INVALIDFILE); - if (result != ISC_R_SUCCESS) { - assert_null(rbt_deserialized); - } - - if (rbt_deserialized != NULL) { - dns_rbt_destroy(&rbt_deserialized); - } - - munmap(base, filesize); - } - - unlink("zone.bin"); -} - -/* Test the dns_rbt_serialize_align() function */ -static void -serialize_align_test(void **state) { - UNUSED(state); - - assert_true(dns_rbt_serialize_align(0) == 0); - assert_true(dns_rbt_serialize_align(1) == 8); - assert_true(dns_rbt_serialize_align(2) == 8); - assert_true(dns_rbt_serialize_align(3) == 8); - assert_true(dns_rbt_serialize_align(4) == 8); - assert_true(dns_rbt_serialize_align(5) == 8); - assert_true(dns_rbt_serialize_align(6) == 8); - assert_true(dns_rbt_serialize_align(7) == 8); - assert_true(dns_rbt_serialize_align(8) == 8); - assert_true(dns_rbt_serialize_align(9) == 16); - assert_true(dns_rbt_serialize_align(0xff) == 0x100); - assert_true(dns_rbt_serialize_align(0x301) == 0x308); -} - -int -main(int argc, char **argv) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(serialize_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(deserialize_corrupt_test, - _setup, _teardown), - cmocka_unit_test(serialize_align_test), - }; - int c; - - while ((c = isc_commandline_parse(argc, argv, "v")) != -1) { - switch (c) { - case 'v': - verbose = true; - break; - default: - break; - } - } - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rbt_test.c b/lib/dns-pkcs11/tests/rbt_test.c deleted file mode 100644 index f318aae..0000000 --- a/lib/dns-pkcs11/tests/rbt_test.c +++ /dev/null @@ -1,1385 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dnstest.h" - -typedef struct { - dns_rbt_t *rbt; - dns_rbt_t *rbt_distances; -} test_context_t; - -/* The initial structure of domain tree will be as follows: - * - * . - * | - * b - * / \ - * a d.e.f - * / | \ - * c | g.h - * | | - * w.y i - * / | \ \ - * x | z k - * | | - * p j - * / \ - * o q - */ - -/* The full absolute names of the nodes in the tree (the tree also - * contains "." which is not included in this list). - */ -static const char * const domain_names[] = { - "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f", - "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h" -}; - -static const size_t domain_names_count = (sizeof(domain_names) / - sizeof(domain_names[0])); - -/* These are set as the node data for the tree used in distances check - * (for the names in domain_names[] above). - */ -static const int node_distances[] = { - 3, 1, 2, 2, 2, 3, 1, 2, 1, 1, 2, 2 -}; - -/* - * The domain order should be: - * ., a, b, c, d.e.f, x.d.e.f, w.y.d.e.f, o.w.y.d.e.f, p.w.y.d.e.f, - * q.w.y.d.e.f, z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h - * . (no data, can't be found) - * | - * b - * / \ - * a d.e.f - * / | \ - * c | g.h - * | | - * w.y i - * / | \ \ - * x | z k - * | | - * p j - * / \ - * o q - */ - -static const char * const ordered_names[] = { - "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f", - "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f", - "g.h", "i.g.h", "k.g.h"}; - -static const size_t ordered_names_count = (sizeof(ordered_names) / - sizeof(*ordered_names)); - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} -static void -delete_data(void *data, void *arg) { - UNUSED(arg); - - isc_mem_put(mctx, data, sizeof(size_t)); -} - -static test_context_t * -test_context_setup(void) { - test_context_t *ctx; - isc_result_t result; - size_t i; - - ctx = isc_mem_get(mctx, sizeof(*ctx)); - assert_non_null(ctx); - - ctx->rbt = NULL; - result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt); - assert_int_equal(result, ISC_R_SUCCESS); - - ctx->rbt_distances = NULL; - result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt_distances); - assert_int_equal(result, ISC_R_SUCCESS); - - for (i = 0; i < domain_names_count; i++) { - size_t *n; - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(domain_names[i], &fname); - - name = dns_fixedname_name(&fname); - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = i + 1; - result = dns_rbt_addname(ctx->rbt, name, n); - assert_int_equal(result, ISC_R_SUCCESS); - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = node_distances[i]; - result = dns_rbt_addname(ctx->rbt_distances, name, n); - assert_int_equal(result, ISC_R_SUCCESS); - } - - return (ctx); -} - -static void -test_context_teardown(test_context_t *ctx) { - dns_rbt_destroy(&ctx->rbt); - dns_rbt_destroy(&ctx->rbt_distances); - - isc_mem_put(mctx, ctx, sizeof(*ctx)); -} - -/* - * Walk the tree and ensure that all the test nodes are present. - */ -static void -check_test_data(dns_rbt_t *rbt) { - dns_fixedname_t fixed; - isc_result_t result; - dns_name_t *foundname; - size_t i; - - foundname = dns_fixedname_initname(&fixed); - - for (i = 0; i < domain_names_count; i++) { - dns_fixedname_t fname; - dns_name_t *name; - size_t *n; - - dns_test_namefromstring(domain_names[i], &fname); - - name = dns_fixedname_name(&fname); - n = NULL; - result = dns_rbt_findname(rbt, name, 0, foundname, - (void *) &n); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(*n, i + 1); - } -} - -/* Test the creation of an rbt */ -static void -rbt_create(void **state) { - test_context_t *ctx; - bool tree_ok; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - check_test_data(ctx->rbt); - - tree_ok = dns__rbt_checkproperties(ctx->rbt); - assert_true(tree_ok); - - test_context_teardown(ctx); -} - -/* Test dns_rbt_nodecount() on a tree */ -static void -rbt_nodecount(void **state) { - test_context_t *ctx; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - assert_int_equal(15, dns_rbt_nodecount(ctx->rbt)); - - test_context_teardown(ctx); -} - -/* Test dns_rbtnode_get_distance() on a tree */ -static void -rbtnode_get_distance(void **state) { - isc_result_t result; - test_context_t *ctx; - const char *name_str = "a"; - dns_fixedname_t fname; - dns_name_t *name; - dns_rbtnode_t *node = NULL; - dns_rbtnodechain_t chain; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - dns_test_namefromstring(name_str, &fname); - name = dns_fixedname_name(&fname); - - dns_rbtnodechain_init(&chain, mctx); - - result = dns_rbt_findnode(ctx->rbt_distances, name, NULL, - &node, &chain, 0, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - while (node != NULL) { - const size_t *distance = (const size_t *) node->data; - if (distance != NULL) - assert_int_equal(*distance, - dns__rbtnode_getdistance(node)); - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result == ISC_R_NOMORE) - break; - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - } - - assert_int_equal(result, ISC_R_NOMORE); - - dns_rbtnodechain_invalidate(&chain); - - test_context_teardown(ctx); -} - -/* - * Test tree balance, inserting names in random order. - * - * This test checks an important performance-related property of - * the red-black tree, which is important for us: the longest - * path from a sub-tree's root to a node is no more than - * 2log(n). This check verifies that the tree is balanced. - */ -static void -rbt_check_distance_random(void **state) { - dns_rbt_t *mytree = NULL; - const unsigned int log_num_nodes = 16; - isc_result_t result; - bool tree_ok; - int i; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - result = dns_rbt_create(mctx, delete_data, NULL, &mytree); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Names are inserted in random order. */ - - /* Make a large 65536 node top-level domain tree, i.e., the - * following code inserts names such as: - * - * savoucnsrkrqzpkqypbygwoiliawpbmz. - * wkadamcbbpjtundbxcmuayuycposvngx. - * wzbpznemtooxdpjecdxynsfztvnuyfao. - * yueojmhyffslpvfmgyfwioxegfhepnqq. - */ - for (i = 0; i < (1 << log_num_nodes); i++) { - size_t *n; - char namebuf[34]; - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = i + 1; - - while (1) { - int j; - dns_fixedname_t fname; - dns_name_t *name; - - for (j = 0; j < 32; j++) { - uint32_t v; - isc_random_get(&v); - namebuf[j] = 'a' + (v % 26); - } - namebuf[32] = '.'; - namebuf[33] = 0; - - dns_test_namefromstring(namebuf, &fname); - name = dns_fixedname_name(&fname); - - result = dns_rbt_addname(mytree, name, n); - if (result == ISC_R_SUCCESS) - break; - } - } - - /* 1 (root . node) + (1 << log_num_nodes) */ - assert_int_equal(1U + (1U << log_num_nodes), - dns_rbt_nodecount(mytree)); - - /* The distance from each node to its sub-tree root must be less - * than 2 * log(n). - */ - assert_true((2U * log_num_nodes) >= dns__rbt_getheight(mytree)); - - /* Also check RB tree properties */ - tree_ok = dns__rbt_checkproperties(mytree); - assert_true(tree_ok); - - dns_rbt_destroy(&mytree); -} - -/* - * Test tree balance, inserting names in sorted order. - * - * This test checks an important performance-related property of - * the red-black tree, which is important for us: the longest - * path from a sub-tree's root to a node is no more than - * 2log(n). This check verifies that the tree is balanced. - */ -static void -rbt_check_distance_ordered(void **state) { - dns_rbt_t *mytree = NULL; - const unsigned int log_num_nodes = 16; - isc_result_t result; - bool tree_ok; - int i; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - result = dns_rbt_create(mctx, delete_data, NULL, &mytree); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Names are inserted in sorted order. */ - - /* Make a large 65536 node top-level domain tree, i.e., the - * following code inserts names such as: - * - * name00000000. - * name00000001. - * name00000002. - * name00000003. - */ - for (i = 0; i < (1 << log_num_nodes); i++) { - size_t *n; - char namebuf[14]; - dns_fixedname_t fname; - dns_name_t *name; - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = i + 1; - - snprintf(namebuf, sizeof(namebuf), "name%08x.", i); - dns_test_namefromstring(namebuf, &fname); - name = dns_fixedname_name(&fname); - - result = dns_rbt_addname(mytree, name, n); - assert_int_equal(result, ISC_R_SUCCESS); - } - - /* 1 (root . node) + (1 << log_num_nodes) */ - assert_int_equal(1U + (1U << log_num_nodes), - dns_rbt_nodecount(mytree)); - - /* The distance from each node to its sub-tree root must be less - * than 2 * log(n). - */ - assert_true((2U * log_num_nodes) >= dns__rbt_getheight(mytree)); - - /* Also check RB tree properties */ - tree_ok = dns__rbt_checkproperties(mytree); - assert_true(tree_ok); - - dns_rbt_destroy(&mytree); -} - -static isc_result_t -insert_helper(dns_rbt_t *rbt, const char *namestr, dns_rbtnode_t **node) { - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(namestr, &fname); - name = dns_fixedname_name(&fname); - - return (dns_rbt_addnode(rbt, name, node)); -} - -static bool -compare_labelsequences(dns_rbtnode_t *node, const char *labelstr) { - dns_name_t name; - isc_result_t result; - char *nodestr = NULL; - bool is_equal; - - dns_name_init(&name, NULL); - dns_rbt_namefromnode(node, &name); - - result = dns_name_tostring(&name, &nodestr, mctx); - assert_int_equal(result, ISC_R_SUCCESS); - - is_equal = strcmp(labelstr, nodestr) == 0 ? true : false; - - isc_mem_free(mctx, nodestr); - - return (is_equal); -} - -/* Test insertion into a tree */ -static void -rbt_insert(void **state) { - isc_result_t result; - test_context_t *ctx; - dns_rbtnode_t *node; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - /* Check node count before beginning. */ - assert_int_equal(15, dns_rbt_nodecount(ctx->rbt)); - - /* Try to insert a node that already exists. */ - node = NULL; - result = insert_helper(ctx->rbt, "d.e.f", &node); - assert_int_equal(result, ISC_R_EXISTS); - - /* Node count must not have changed. */ - assert_int_equal(15, dns_rbt_nodecount(ctx->rbt)); - - /* Try to insert a node that doesn't exist. */ - node = NULL; - result = insert_helper(ctx->rbt, "0", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "0")); - - /* Node count must have increased. */ - assert_int_equal(16, dns_rbt_nodecount(ctx->rbt)); - - /* Another. */ - node = NULL; - result = insert_helper(ctx->rbt, "example.com", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_non_null(node); - assert_null(node->data); - - /* Node count must have increased. */ - assert_int_equal(17, dns_rbt_nodecount(ctx->rbt)); - - /* Re-adding it should return EXISTS */ - node = NULL; - result = insert_helper(ctx->rbt, "example.com", &node); - assert_int_equal(result, ISC_R_EXISTS); - - /* Node count must not have changed. */ - assert_int_equal(17, dns_rbt_nodecount(ctx->rbt)); - - /* Fission the node d.e.f */ - node = NULL; - result = insert_helper(ctx->rbt, "k.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "k")); - - /* Node count must have incremented twice ("d.e.f" fissioned to - * "d" and "e.f", and the newly added "k"). - */ - assert_int_equal(19, dns_rbt_nodecount(ctx->rbt)); - - /* Fission the node "g.h" */ - node = NULL; - result = insert_helper(ctx->rbt, "h", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "h")); - - /* Node count must have incremented ("g.h" fissioned to "g" and - * "h"). - */ - assert_int_equal(20, dns_rbt_nodecount(ctx->rbt)); - - /* Add child domains */ - - node = NULL; - result = insert_helper(ctx->rbt, "m.p.w.y.d.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "m")); - assert_int_equal(21, dns_rbt_nodecount(ctx->rbt)); - - node = NULL; - result = insert_helper(ctx->rbt, "n.p.w.y.d.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "n")); - assert_int_equal(22, dns_rbt_nodecount(ctx->rbt)); - - node = NULL; - result = insert_helper(ctx->rbt, "l.a", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(compare_labelsequences(node, "l")); - assert_int_equal(23, dns_rbt_nodecount(ctx->rbt)); - - node = NULL; - result = insert_helper(ctx->rbt, "r.d.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - node = NULL; - result = insert_helper(ctx->rbt, "s.d.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(25, dns_rbt_nodecount(ctx->rbt)); - - node = NULL; - result = insert_helper(ctx->rbt, "h.w.y.d.e.f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Add more nodes one by one to cover left and right rotation - * functions. - */ - node = NULL; - result = insert_helper(ctx->rbt, "f", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "m", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "nm", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "om", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "k", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "l", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "fe", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "ge", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "i", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "ae", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - node = NULL; - result = insert_helper(ctx->rbt, "n", &node); - assert_int_equal(result, ISC_R_SUCCESS); - - test_context_teardown(ctx); -} - -/* - * Test removal from a tree - * - * This testcase checks that after node removal, the binary-search tree is - * valid and all nodes that are supposed to exist are present in the - * correct order. It mainly tests DomainTree as a BST, and not particularly - * as a red-black tree. This test checks node deletion when upper nodes - * have data. - */ -static void -rbt_remove(void **state) { - isc_result_t result; size_t j; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - /* - * Delete single nodes and check if the rest of the nodes exist. - */ - for (j = 0; j < ordered_names_count; j++) { - dns_rbt_t *mytree = NULL; - dns_rbtnode_t *node; - size_t i; - size_t *n; - bool tree_ok; - dns_rbtnodechain_t chain; - size_t start_node; - - /* Create a tree. */ - result = dns_rbt_create(mctx, delete_data, NULL, &mytree); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Insert test data into the tree. */ - for (i = 0; i < domain_names_count; i++) { - node = NULL; - result = insert_helper(mytree, domain_names[i], &node); - assert_int_equal(result, ISC_R_SUCCESS); - } - - /* Check that all names exist in order. */ - for (i = 0; i < ordered_names_count; i++) { - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(ordered_names[i], &fname); - - name = dns_fixedname_name(&fname); - node = NULL; - result = dns_rbt_findnode(mytree, name, NULL, - &node, NULL, - DNS_RBTFIND_EMPTYDATA, - NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Add node data */ - assert_non_null(node); - assert_null(node->data); - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = i; - - node->data = n; - } - - /* Now, delete the j'th node from the tree. */ - { - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(ordered_names[j], &fname); - - name = dns_fixedname_name(&fname); - - result = dns_rbt_deletename(mytree, name, false); - assert_int_equal(result, ISC_R_SUCCESS); - } - - /* Check RB tree properties. */ - tree_ok = dns__rbt_checkproperties(mytree); - assert_true(tree_ok); - - dns_rbtnodechain_init(&chain, mctx); - - /* Now, walk through nodes in order. */ - if (j == 0) { - /* - * Node for ordered_names[0] was already deleted - * above. We start from node 1. - */ - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(ordered_names[0], &fname); - name = dns_fixedname_name(&fname); - node = NULL; - result = dns_rbt_findnode(mytree, name, NULL, - &node, NULL, - 0, - NULL, NULL); - assert_int_equal(result, ISC_R_NOTFOUND); - - dns_test_namefromstring(ordered_names[1], &fname); - name = dns_fixedname_name(&fname); - node = NULL; - result = dns_rbt_findnode(mytree, name, NULL, - &node, &chain, - 0, - NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - start_node = 1; - } else { - /* Start from node 0. */ - dns_fixedname_t fname; - dns_name_t *name; - - dns_test_namefromstring(ordered_names[0], &fname); - name = dns_fixedname_name(&fname); - node = NULL; - result = dns_rbt_findnode(mytree, name, NULL, - &node, &chain, - 0, - NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - start_node = 0; - } - - /* - * node and chain have been set by the code above at - * this point. - */ - for (i = start_node; i < ordered_names_count; i++) { - dns_fixedname_t fname_j, fname_i; - dns_name_t *name_j, *name_i; - - dns_test_namefromstring(ordered_names[j], &fname_j); - name_j = dns_fixedname_name(&fname_j); - dns_test_namefromstring(ordered_names[i], &fname_i); - name_i = dns_fixedname_name(&fname_i); - - if (dns_name_equal(name_i, name_j)) { - /* - * This may be true for the last node if - * we seek ahead in the loop using - * dns_rbtnodechain_next() below. - */ - if (node == NULL) { - break; - } - - /* All ordered nodes have data - * initially. If any node is empty, it - * means it was removed, but an empty - * node exists because it is a - * super-domain. Just skip it. - */ - if (node->data == NULL) { - result = dns_rbtnodechain_next(&chain, - NULL, - NULL); - if (result == ISC_R_NOMORE) { - node = NULL; - } else { - dns_rbtnodechain_current(&chain, - NULL, - NULL, - &node); - } - } - continue; - } - - assert_non_null(node); - - n = (size_t *) node->data; - if (n != NULL) { - /* printf("n=%zu, i=%zu\n", *n, i); */ - assert_int_equal(*n, i); - } - - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result == ISC_R_NOMORE) { - node = NULL; - } else { - dns_rbtnodechain_current(&chain, NULL, NULL, - &node); - } - } - - /* We should have reached the end of the tree. */ - assert_null(node); - - dns_rbt_destroy(&mytree); - } -} - -static void -insert_nodes(dns_rbt_t *mytree, char **names, - size_t *names_count, uint32_t num_names) -{ - uint32_t i; - dns_rbtnode_t *node; - - for (i = 0; i < num_names; i++) { - size_t *n; - char namebuf[34]; - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - - *n = i; /* Unused value */ - - while (1) { - int j; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - for (j = 0; j < 32; j++) { - uint32_t v; - isc_random_get(&v); - namebuf[j] = 'a' + (v % 26); - } - namebuf[32] = '.'; - namebuf[33] = 0; - - dns_test_namefromstring(namebuf, &fname); - name = dns_fixedname_name(&fname); - - node = NULL; - result = dns_rbt_addnode(mytree, name, &node); - if (result == ISC_R_SUCCESS) { - node->data = n; - names[*names_count] = isc_mem_strdup(mctx, - namebuf); - assert_non_null(names[*names_count]); - *names_count += 1; - break; - } - } - } -} - -static void -remove_nodes(dns_rbt_t *mytree, char **names, - size_t *names_count, uint32_t num_names) -{ - uint32_t i; - - UNUSED(mytree); - - for (i = 0; i < num_names && *names_count > 0; i++) { - uint32_t node; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - isc_random_get(&node); - - node %= *names_count; - - dns_test_namefromstring(names[node], &fname); - name = dns_fixedname_name(&fname); - - result = dns_rbt_deletename(mytree, name, false); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_mem_free(mctx, names[node]); - - if (*names_count > 0) { - names[node] = names[*names_count - 1]; - names[*names_count - 1] = NULL; - *names_count -= 1; - } - } -} - -static void -check_tree(dns_rbt_t *mytree, char **names, size_t names_count) { - bool tree_ok; - - UNUSED(names); - - assert_int_equal(names_count + 1, dns_rbt_nodecount(mytree)); - - /* - * The distance from each node to its sub-tree root must be less - * than 2 * log_2(1024). - */ - assert_true((2 * 10) >= dns__rbt_getheight(mytree)); - - /* Also check RB tree properties */ - tree_ok = dns__rbt_checkproperties(mytree); - assert_true(tree_ok); -} - -/* - * Test insert and remove in a loop. - * - * What is the best way to test our red-black tree code? It is - * not a good method to test every case handled in the actual - * code itself. This is because our approach itself may be - * incorrect. - * - * We test our code at the interface level here by exercising the - * tree randomly multiple times, checking that red-black tree - * properties are valid, and all the nodes that are supposed to be - * in the tree exist and are in order. - * - * NOTE: These tests are run within a single tree level in the - * forest. The number of nodes in the tree level doesn't grow - * over 1024. - */ -static void -rbt_insert_and_remove(void **state) { - isc_result_t result; - dns_rbt_t *mytree = NULL; - size_t *n; - char *names[1024]; - size_t names_count; - int i; - isc_time_t start, now; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - result = dns_rbt_create(mctx, delete_data, NULL, &mytree); - assert_int_equal(result, ISC_R_SUCCESS); - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - result = dns_rbt_addname(mytree, dns_rootname, n); - assert_int_equal(result, ISC_R_SUCCESS); - - memset(names, 0, sizeof(names)); - names_count = 0; - - /* Repeat the insert/remove test for some 4096 times or 180 seconds. */ - result = isc_time_now(&start); - assert_int_equal(result, ISC_R_SUCCESS); - now = start; - for (i = 0; i < 4096 && isc_time_microdiff(&now, &start) < 180000000; i++) { - uint32_t num_names; - isc_random_get(&num_names); - - if (names_count < 1024) { - num_names %= 1024 - names_count; - num_names++; - } else { - num_names = 0; - } - - insert_nodes(mytree, names, &names_count, num_names); - check_tree(mytree, names, names_count); - - isc_random_get(&num_names); - if (names_count > 0) { - num_names %= names_count; - num_names++; - } else { - num_names = 0; - } - - remove_nodes(mytree, names, &names_count, num_names); - check_tree(mytree, names, names_count); - result = isc_time_now(&now); - assert_int_equal(result, ISC_R_SUCCESS); - } - - /* Remove the rest of the nodes */ - remove_nodes(mytree, names, &names_count, names_count); - check_tree(mytree, names, names_count); - - for (i = 0; i < 1024; i++) { - if (names[i] != NULL) { - isc_mem_free(mctx, names[i]); - } - } - - result = dns_rbt_deletename(mytree, dns_rootname, false); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(dns_rbt_nodecount(mytree), 0); - - dns_rbt_destroy(&mytree); -} - -/* Test findname return values */ -static void -rbt_findname(void **state) { - isc_result_t result; - test_context_t *ctx = NULL; - dns_fixedname_t fname, found; - dns_name_t *name = NULL, *foundname = NULL; - size_t *n = NULL; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - /* Try to find a name that exists. */ - dns_test_namefromstring("d.e.f", &fname); - name = dns_fixedname_name(&fname); - - foundname = dns_fixedname_initname(&found); - - result = dns_rbt_findname(ctx->rbt, name, - DNS_RBTFIND_EMPTYDATA, - foundname, (void *) &n); - assert_true(dns_name_equal(foundname, name)); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Now without EMPTYDATA */ - result = dns_rbt_findname(ctx->rbt, name, 0, - foundname, (void *) &n); - assert_int_equal(result, ISC_R_NOTFOUND); - - /* Now one that partially matches */ - dns_test_namefromstring("d.e.f.g.h.i.j", &fname); - name = dns_fixedname_name(&fname); - result = dns_rbt_findname(ctx->rbt, name, - DNS_RBTFIND_EMPTYDATA, - foundname, (void *) &n); - assert_int_equal(result, DNS_R_PARTIALMATCH); - - /* Now one that doesn't match */ - dns_test_namefromstring("1.2", &fname); - name = dns_fixedname_name(&fname); - result = dns_rbt_findname(ctx->rbt, name, - DNS_RBTFIND_EMPTYDATA, - foundname, (void *) &n); - assert_int_equal(result, DNS_R_PARTIALMATCH); - assert_true(dns_name_equal(foundname, dns_rootname)); - - test_context_teardown(ctx); -} - -/* Test addname return values */ -static void -rbt_addname(void **state) { - isc_result_t result; - test_context_t *ctx = NULL; - dns_fixedname_t fname; - dns_name_t *name = NULL; - size_t *n; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = 1; - - dns_test_namefromstring("d.e.f.g.h.i.j.k", &fname); - name = dns_fixedname_name(&fname); - - /* Add a name that doesn't exist */ - result = dns_rbt_addname(ctx->rbt, name, n); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Now add again, should get ISC_R_EXISTS */ - n = isc_mem_get(mctx, sizeof(size_t)); - assert_non_null(n); - *n = 2; - result = dns_rbt_addname(ctx->rbt, name, n); - assert_int_equal(result, ISC_R_EXISTS); - isc_mem_put(mctx, n, sizeof(size_t)); - - test_context_teardown(ctx); -} - -/* Test deletename return values */ -static void -rbt_deletename(void **state) { - isc_result_t result; - test_context_t *ctx = NULL; - dns_fixedname_t fname; - dns_name_t *name = NULL; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - /* Delete a name that doesn't exist */ - dns_test_namefromstring("z.x.y.w", &fname); - name = dns_fixedname_name(&fname); - result = dns_rbt_deletename(ctx->rbt, name, false); - assert_int_equal(result, ISC_R_NOTFOUND); - - /* Now one that does */ - dns_test_namefromstring("d.e.f", &fname); - name = dns_fixedname_name(&fname); - result = dns_rbt_deletename(ctx->rbt, name, false); - assert_int_equal(result, ISC_R_NOTFOUND); - - test_context_teardown(ctx); -} - -/* Test nodechain */ -static void -rbt_nodechain(void **state) { - isc_result_t result; - test_context_t *ctx; - dns_fixedname_t fname, found, expect; - dns_name_t *name, *foundname, *expected; - dns_rbtnode_t *node = NULL; - dns_rbtnodechain_t chain; - - UNUSED(state); - - isc_mem_debugging = ISC_MEM_DEBUGRECORD; - - ctx = test_context_setup(); - - dns_rbtnodechain_init(&chain, mctx); - - dns_test_namefromstring("a", &fname); - name = dns_fixedname_name(&fname); - - result = dns_rbt_findnode(ctx->rbt, name, NULL, - &node, &chain, 0, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - foundname = dns_fixedname_initname(&found); - - dns_test_namefromstring("a", &expect); - expected = dns_fixedname_name(&expect); - UNUSED(expected); - - result = dns_rbtnodechain_first(&chain, ctx->rbt, foundname, NULL); - assert_int_equal(result, DNS_R_NEWORIGIN); - assert_int_equal(dns_name_countlabels(foundname), 0); - - result = dns_rbtnodechain_prev(&chain, NULL, NULL); - assert_int_equal(result, ISC_R_NOMORE); - - result = dns_rbtnodechain_next(&chain, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_rbtnodechain_next(&chain, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_rbtnodechain_last(&chain, ctx->rbt, NULL, NULL); - assert_int_equal(result, DNS_R_NEWORIGIN); - - result = dns_rbtnodechain_next(&chain, NULL, NULL); - assert_int_equal(result, ISC_R_NOMORE); - - result = dns_rbtnodechain_last(&chain, ctx->rbt, NULL, NULL); - assert_int_equal(result, DNS_R_NEWORIGIN); - - result = dns_rbtnodechain_prev(&chain, NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - dns_rbtnodechain_invalidate(&chain); - - test_context_teardown(ctx); -} - -#ifdef ISC_PLATFORM_USETHREADS -#ifdef DNS_BENCHMARK_TESTS - -/* - * XXXMUKS: Don't delete this code. It is useful in benchmarking the - * RBT, but we don't require it as part of the unit test runs. - */ - -static dns_fixedname_t *fnames; -static dns_name_t **names; -static int *values; - -static void * -find_thread(void *arg) { - dns_rbt_t *mytree; - isc_result_t result; - dns_rbtnode_t *node; - unsigned int j, i; - unsigned int start = 0; - - mytree = (dns_rbt_t *) arg; - while (start == 0) - start = random() % 4000000; - - /* Query 32 million random names from it in each thread */ - for (j = 0; j < 8; j++) { - for (i = start; i != start - 1; i = (i + 1) % 4000000) { - node = NULL; - result = dns_rbt_findnode(mytree, names[i], NULL, - &node, NULL, - DNS_RBTFIND_EMPTYDATA, - NULL, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - assert_non_null(node); - assert_int_equal(values[i], (intptr_t) node->data); - } - } - - return (NULL); -} - -/* Benchmark RBT implementation */ -static void -benchmark(void **state) { - isc_result_t result; - char namestr[sizeof("name18446744073709551616.example.org.")]; - unsigned int r; - dns_rbt_t *mytree; - dns_rbtnode_t *node; - unsigned int i; - unsigned int maxvalue = 1000000; - isc_time_t ts1, ts2; - double t; - unsigned int nthreads; - isc_thread_t threads[32]; - - UNUSED(state); - - srandom(time(NULL)); - - debug_mem_record = false; - - fnames = (dns_fixedname_t *) malloc(4000000 * sizeof(dns_fixedname_t)); - names = (dns_name_t **) malloc(4000000 * sizeof(dns_name_t *)); - values = (int *) malloc(4000000 * sizeof(int)); - - for (i = 0; i < 4000000; i++) { - r = ((unsigned long) random()) % maxvalue; - snprintf(namestr, sizeof(namestr), "name%u.example.org.", r); - dns_test_namefromstring(namestr, &fnames[i]); - names[i] = dns_fixedname_name(&fnames[i]); - values[i] = r; - } - - /* Create a tree. */ - mytree = NULL; - result = dns_rbt_create(mctx, NULL, NULL, &mytree); - assert_int_equal(result, ISC_R_SUCCESS); - - /* Insert test data into the tree. */ - for (i = 0; i < maxvalue; i++) { - snprintf(namestr, sizeof(namestr), "name%u.example.org.", i); - node = NULL; - result = insert_helper(mytree, namestr, &node); - assert_int_equal(result, ISC_R_SUCCESS); - node->data = (void *) (intptr_t) i; - } - - result = isc_time_now(&ts1); - assert_int_equal(result, ISC_R_SUCCESS); - - nthreads = ISC_MIN(isc_os_ncpus(), 32); - nthreads = ISC_MAX(nthreads, 1); - for (i = 0; i < nthreads; i++) { - result = isc_thread_create(find_thread, mytree, &threads[i]); - assert_int_equal(result, ISC_R_SUCCESS); - } - - for (i = 0; i < nthreads; i++) { - result = isc_thread_join(threads[i], NULL); - assert_int_equal(result, ISC_R_SUCCESS); - } - - result = isc_time_now(&ts2); - assert_int_equal(result, ISC_R_SUCCESS); - - t = isc_time_microdiff(&ts2, &ts1); - - printf("%u findnode calls, %f seconds, %f calls/second\n", - nthreads * 8 * 4000000, t / 1000000.0, - (nthreads * 8 * 4000000) / (t / 1000000.0)); - - free(values); - free(names); - free(fnames); - - dns_rbt_destroy(&mytree); -} -#endif /* DNS_BENCHMARK_TESTS */ -#endif /* ISC_PLATFORM_USETHREADS */ - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(rbt_create, _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_nodecount, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbtnode_get_distance, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_check_distance_random, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_check_distance_ordered, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_insert, _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_remove, _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_insert_and_remove, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_findname, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_addname, _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_deletename, - _setup, _teardown), - cmocka_unit_test_setup_teardown(rbt_nodechain, - _setup, _teardown), -#ifdef ISC_PLATFORM_USETHREADS -#ifdef DNS_BENCHMARK_TESTS - cmocka_unit_test_setup_teardown(benchmark, _setup, _teardown), -#endif /* DNS_BENCHMARK_TESTS */ -#endif /* ISC_PLATFORM_USETHREADS */ - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rdata_test.c b/lib/dns-pkcs11/tests/rdata_test.c deleted file mode 100644 index 3cddb64..0000000 --- a/lib/dns-pkcs11/tests/rdata_test.c +++ /dev/null @@ -1,2813 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../dst_gost.h" - -#include "dnstest.h" - -static bool debug = false; - -/* - * An array of these structures is passed to compare_ok(). - */ -struct compare_ok { - const char *text1; /* text passed to fromtext_*() */ - const char *text2; /* text passed to fromtext_*() */ - int answer; /* -1, 0, 1 */ - int lineno; /* source line defining this RDATA */ -}; -typedef struct compare_ok compare_ok_t; - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* - * An array of these structures is passed to check_text_ok(). - */ -typedef struct text_ok { - const char *text_in; /* text passed to fromtext_*() */ - const char *text_out; /* text expected from totext_*(); - * NULL indicates text_in is invalid */ - unsigned int loop; -} text_ok_t; - -/* - * An array of these structures is passed to check_wire_ok(). - */ -typedef struct wire_ok { - unsigned char data[512]; /* RDATA in wire format */ - size_t len; /* octets of data to parse */ - bool ok; /* is this RDATA valid? */ - unsigned int loop; -} wire_ok_t; - -#define COMPARE(r1, r2, answer) \ - { r1, r2, answer, __LINE__ } -#define COMPARE_SENTINEL() \ - { NULL, NULL, 0, __LINE__ } - -#define TEXT_VALID_CHANGED(data_in, data_out) \ - { \ - data_in, data_out, 0 \ - } -#define TEXT_VALID(data) \ - { \ - data, data, 0 \ - } -#define TEXT_VALID_LOOP(loop, data) \ - { \ - data, data, loop \ - } -#define TEXT_VALID_LOOPCHG(loop, data_in, data_out) \ - { \ - data_in, data_out, loop \ - } -#define TEXT_INVALID(data) \ - { \ - data, NULL, 0 \ - } -#define TEXT_SENTINEL() TEXT_INVALID(NULL) - -#define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ })) -#define WIRE_TEST(ok, loop, ...) \ - { \ - { __VA_ARGS__ }, VARGC(__VA_ARGS__), ok, loop \ - } -#define WIRE_VALID(...) WIRE_TEST(true, 0, __VA_ARGS__) -#define WIRE_VALID_LOOP(loop, ...) WIRE_TEST(true, loop, __VA_ARGS__) -/* - * WIRE_INVALID() test cases must always have at least one octet specified to - * distinguish them from WIRE_SENTINEL(). Use the 'empty_ok' parameter passed - * to check_wire_ok() for indicating whether empty RDATA is allowed for a given - * RR type or not. - */ -#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, 0, FIRST, __VA_ARGS__) -#define WIRE_SENTINEL() WIRE_TEST(false, 0) - -/* - * Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in - * size and represents RDATA of given 'type' and 'class'. Store the resulting - * uncompressed wire form in 'dst', which is 'dstlen' octets in size, and make - * 'rdata' refer to that uncompressed wire form. - */ -static isc_result_t -wire_to_rdata(const unsigned char *src, size_t srclen, - dns_rdataclass_t rdclass, dns_rdatatype_t type, - unsigned char *dst, size_t dstlen, dns_rdata_t *rdata) -{ - isc_buffer_t source, target; - dns_decompress_t dctx; - isc_result_t result; - - /* - * Set up len-octet buffer pointing at data. - */ - isc_buffer_constinit(&source, src, srclen); - isc_buffer_add(&source, srclen); - isc_buffer_setactive(&source, srclen); - - /* - * Initialize target buffer. - */ - isc_buffer_init(&target, dst, dstlen); - - /* - * Try converting input data into uncompressed wire form. - */ - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); - result = dns_rdata_fromwire(rdata, rdclass, type, &source, &dctx, 0, - &target); - dns_decompress_invalidate(&dctx); - - return (result); -} - -/* - * Call dns_rdata_towire() for rdata and write to result to dst. - */ -static isc_result_t -rdata_towire(dns_rdata_t *rdata, unsigned char *dst, size_t dstlen, - size_t *length) -{ - isc_buffer_t target; - dns_compress_t cctx; - isc_result_t result; - - /* - * Initialize target buffer. - */ - isc_buffer_init(&target, dst, dstlen); - - /* - * Try converting input data into uncompressed wire form. - */ - dns_compress_init(&cctx, -1, mctx); - result = dns_rdata_towire(rdata, &cctx, &target); - dns_compress_invalidate(&cctx); - - *length = isc_buffer_usedlength(&target); - - return (result); -} - -static isc_result_t -additionaldata_cb(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - UNUSED(arg); - UNUSED(name); - UNUSED(qtype); - return (ISC_R_SUCCESS); -} - -/* - * call dns_rdata_additionaldata() for rdata. - */ -static isc_result_t -rdata_additionadata(dns_rdata_t *rdata) { - return (dns_rdata_additionaldata(rdata, additionaldata_cb, NULL)); -} - -/* - * Call dns_rdata_checknames() with various owner names chosen to - * match well known forms. - * - * We are currently only checking that the calls do not trigger - * assertion failures. - * - * XXXMPA A future extension could be to record the expected - * result and the expected value of 'bad'. - */ -static void -rdata_checknames(dns_rdata_t *rdata) { - dns_fixedname_t fixed, bfixed; - dns_name_t *name, *bad; - isc_result_t result; - - name = dns_fixedname_initname(&fixed); - bad = dns_fixedname_initname(&bfixed); - - (void) dns_rdata_checknames(rdata, dns_rootname, NULL); - (void) dns_rdata_checknames(rdata, dns_rootname, bad); - - result = dns_name_fromstring(name, "example.net", 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - (void) dns_rdata_checknames(rdata, name, NULL); - (void) dns_rdata_checknames(rdata, name, bad); - - result = dns_name_fromstring(name, "in-addr.arpa", 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - (void) dns_rdata_checknames(rdata, name, NULL); - (void) dns_rdata_checknames(rdata, name, bad); - - result = dns_name_fromstring(name, "ip6.arpa", 0, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - (void) dns_rdata_checknames(rdata, name, NULL); - (void) dns_rdata_checknames(rdata, name, bad); -} - -/* - * Test whether converting rdata to a type-specific struct and then back to - * rdata results in the same uncompressed wire form. This checks whether - * tostruct_*() and fromstruct_*() routines for given RR class and type behave - * consistently. - * - * This function is called for every correctly processed input RDATA, from both - * check_text_ok_single() and check_wire_ok_single(). - */ -static void -check_struct_conversions(dns_rdata_t *rdata, size_t structsize, - unsigned int loop) { - dns_rdataclass_t rdclass = rdata->rdclass; - dns_rdatatype_t type = rdata->type; - isc_result_t result; - isc_buffer_t target; - void *rdata_struct; - char buf[1024]; - unsigned int count = 0; - - rdata_struct = isc_mem_allocate(mctx, structsize); - assert_non_null(rdata_struct); - - /* - * Convert from uncompressed wire form into type-specific struct. - */ - result = dns_rdata_tostruct(rdata, rdata_struct, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Convert from type-specific struct into uncompressed wire form. - */ - isc_buffer_init(&target, buf, sizeof(buf)); - result = dns_rdata_fromstruct(NULL, rdclass, type, rdata_struct, - &target); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Ensure results are consistent. - */ - assert_int_equal(isc_buffer_usedlength(&target), rdata->length); - - assert_memory_equal(buf, rdata->data, rdata->length); - - /* - * Check that one can walk hip rendezvous servers. - */ - switch (type) { - case dns_rdatatype_hip: { - dns_rdata_hip_t *hip = rdata_struct; - - for (result = dns_rdata_hip_first(hip); result == ISC_R_SUCCESS; - result = dns_rdata_hip_next(hip)) - { - dns_name_t name; - dns_name_init(&name, NULL); - dns_rdata_hip_current(hip, &name); - assert_int_not_equal(dns_name_countlabels(&name), 0); - assert_true(dns_name_isabsolute(&name)); - count++; - } - assert_int_equal(result, ISC_R_NOMORE); - assert_int_equal(count, loop); - break; - } - } - - isc_mem_free(mctx, rdata_struct); -} - -/* - * Check whether converting supplied text form RDATA into uncompressed wire - * form succeeds (tests fromtext_*()). If so, try converting it back into text - * form and see if it results in the original text (tests totext_*()). - */ -static void -check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass, - dns_rdatatype_t type, size_t structsize) -{ - unsigned char buf_fromtext[1024], buf_fromwire[1024], buf_towire[1024]; - dns_rdata_t rdata = DNS_RDATA_INIT, rdata2 = DNS_RDATA_INIT; - char buf_totext[1024] = { 0 }; - isc_buffer_t target; - isc_result_t result; - size_t length = 0; - - /* - * Try converting text form RDATA into uncompressed wire form. - */ - result = dns_test_rdatafromstring(&rdata, rdclass, type, buf_fromtext, - sizeof(buf_fromtext), - text_ok->text_in, false); - /* - * Check whether result is as expected. - */ - if (text_ok->text_out != NULL) { - if (debug && result != ISC_R_SUCCESS) { - fprintf(stdout, "#'%s'\n", text_ok->text_in); - } - assert_int_equal(result, ISC_R_SUCCESS); - } else { - if (debug && result == ISC_R_SUCCESS) { - fprintf(stdout, "#'%s'\n", text_ok->text_in); - } - assert_int_not_equal(result, ISC_R_SUCCESS); - } - - /* - * If text form RDATA was not parsed correctly, performing any - * additional checks is pointless. - */ - if (result != ISC_R_SUCCESS) { - return; - } - - /* - * Try converting uncompressed wire form RDATA back into text form and - * check whether the resulting text is the same as the original one. - */ - isc_buffer_init(&target, buf_totext, sizeof(buf_totext)); - result = dns_rdata_totext(&rdata, NULL, &target); - assert_int_equal(result, ISC_R_SUCCESS); - /* - * Ensure buf_totext is properly NUL terminated as dns_rdata_totext() - * may attempt different output formats writing into the apparently - * unused part of the buffer. - */ - isc_buffer_putuint8(&target, 0); - if (debug && strcmp(buf_totext, text_ok->text_out) != 0) { - fprintf(stdout, "# '%s' != '%s'\n", - buf_totext, text_ok->text_out); - } - assert_string_equal(buf_totext, text_ok->text_out); - - /* - * Ensure that fromtext_*() output is valid input for fromwire_*(). - */ - result = wire_to_rdata(rdata.data, rdata.length, rdclass, type, - buf_fromwire, sizeof(buf_fromwire), &rdata2); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdata.length, rdata2.length); - assert_memory_equal(rdata.data, buf_fromwire, rdata.length); - - /* - * Ensure that fromtext_*() output is valid input for towire_*(). - */ - result = rdata_towire(&rdata, buf_towire, sizeof(buf_towire), &length); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdata.length, length); - assert_memory_equal(rdata.data, buf_towire, length); - - /* - * Test that additionaldata_*() succeeded. - */ - result = rdata_additionadata(&rdata); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Exercise checknames_*(). - */ - rdata_checknames(&rdata); - - /* - * Perform two-way conversion checks between uncompressed wire form and - * type-specific struct. - */ - check_struct_conversions(&rdata, structsize, text_ok->loop); -} - -/* - * Test whether converting rdata to text form and then parsing the result of - * that conversion again results in the same uncompressed wire form. This - * checks whether totext_*() output is parsable by fromtext_*() for given RR - * class and type. - * - * This function is called for every input RDATA which is successfully parsed - * by check_wire_ok_single() and whose type is not a meta-type. - */ -static void -check_text_conversions(dns_rdata_t *rdata) { - char buf_totext[1024] = { 0 }; - unsigned char buf_fromtext[1024]; - isc_result_t result; - isc_buffer_t target; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - - /* - * Convert uncompressed wire form RDATA into text form. This - * conversion must succeed since input RDATA was successfully - * parsed by check_wire_ok_single(). - */ - isc_buffer_init(&target, buf_totext, sizeof(buf_totext)); - result = dns_rdata_totext(rdata, NULL, &target); - assert_int_equal(result, ISC_R_SUCCESS); - /* - * Ensure buf_totext is properly NUL terminated as dns_rdata_totext() - * may attempt different output formats writing into the apparently - * unused part of the buffer. - */ - isc_buffer_putuint8(&target, 0); - if (debug) { - fprintf(stdout, "#'%s'\n", buf_totext); - } - - /* - * Try parsing text form RDATA output by dns_rdata_totext() again. - */ - result = dns_test_rdatafromstring(&rdata2, rdata->rdclass, rdata->type, - buf_fromtext, sizeof(buf_fromtext), - buf_totext, false); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdata2.length, rdata->length); - assert_memory_equal(buf_fromtext, rdata->data, rdata->length); -} - -/* - * Test whether converting rdata to multi-line text form and then parsing the - * result of that conversion again results in the same uncompressed wire form. - * This checks whether multi-line totext_*() output is parsable by fromtext_*() - * for given RR class and type. - * - * This function is called for every input RDATA which is successfully parsed - * by check_wire_ok_single() and whose type is not a meta-type. - */ -static void -check_multiline_text_conversions(dns_rdata_t *rdata) { - char buf_totext[1024] = { 0 }; - unsigned char buf_fromtext[1024]; - isc_result_t result; - isc_buffer_t target; - dns_rdata_t rdata2 = DNS_RDATA_INIT; - unsigned int flags; - - /* - * Convert uncompressed wire form RDATA into multi-line text form. - * This conversion must succeed since input RDATA was successfully - * parsed by check_wire_ok_single(). - */ - isc_buffer_init(&target, buf_totext, sizeof(buf_totext)); - flags = dns_master_styleflags(&dns_master_style_default); - result = dns_rdata_tofmttext(rdata, dns_rootname, flags, 80 - 32, 4, - "\n", &target); - assert_int_equal(result, ISC_R_SUCCESS); - /* - * Ensure buf_totext is properly NUL terminated as - * dns_rdata_tofmttext() may attempt different output formats - * writing into the apparently unused part of the buffer. - */ - isc_buffer_putuint8(&target, 0); - if (debug) { - fprintf(stdout, "#'%s'\n", buf_totext); - } - - /* - * Try parsing multi-line text form RDATA output by - * dns_rdata_tofmttext() again. - */ - result = dns_test_rdatafromstring(&rdata2, rdata->rdclass, rdata->type, - buf_fromtext, sizeof(buf_fromtext), - buf_totext, false); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdata2.length, rdata->length); - assert_memory_equal(buf_fromtext, rdata->data, rdata->length); -} - -/* - * Test whether supplied wire form RDATA is properly handled as being either - * valid or invalid for an RR of given rdclass and type. - */ -static void -check_wire_ok_single(const wire_ok_t *wire_ok, dns_rdataclass_t rdclass, - dns_rdatatype_t type, size_t structsize) -{ - unsigned char buf[1024], buf_towire[1024]; - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - size_t length = 0; - - /* - * Try converting wire data into uncompressed wire form. - */ - result = wire_to_rdata(wire_ok->data, wire_ok->len, rdclass, type, - buf, sizeof(buf), &rdata); - /* - * Check whether result is as expected. - */ - if (wire_ok->ok) { - assert_int_equal(result, ISC_R_SUCCESS); - } else { - assert_int_not_equal(result, ISC_R_SUCCESS); - } - - if (result != ISC_R_SUCCESS) { - return; - } - - /* - * If data was parsed correctly, perform two-way conversion checks - * between uncompressed wire form and type-specific struct. - * - * If the RR type is not a meta-type, additionally perform two-way - * conversion checks between: - * - * - uncompressed wire form and text form, - * - uncompressed wire form and multi-line text form. - */ - check_struct_conversions(&rdata, structsize, wire_ok->loop); - if (!dns_rdatatype_ismeta(rdata.type)) { - check_text_conversions(&rdata); - check_multiline_text_conversions(&rdata); - } - - /* - * Ensure that fromwire_*() output is valid input for towire_*(). - */ - result = rdata_towire(&rdata, buf_towire, sizeof(buf_towire), &length); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(rdata.length, length); - assert_memory_equal(rdata.data, buf_towire, length); - - /* - * Test that additionaldata_*() succeeded. - */ - result = rdata_additionadata(&rdata); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Exercise checknames_*(). - */ - rdata_checknames(&rdata); -} - -/* - * Test fromtext_*() and totext_*() routines for given RR class and type for - * each text form RDATA in the supplied array. See the comment for - * check_text_ok_single() for an explanation of how exactly these routines are - * tested. - */ -static void -check_text_ok(const text_ok_t *text_ok, dns_rdataclass_t rdclass, - dns_rdatatype_t type, size_t structsize) -{ - size_t i; - - /* - * Check all entries in the supplied array. - */ - for (i = 0; text_ok[i].text_in != NULL; i++) { - check_text_ok_single(&text_ok[i], rdclass, type, structsize); - } -} - -/* - * For each wire form RDATA in the supplied array, check whether it is properly - * handled as being either valid or invalid for an RR of given rdclass and - * type, then check whether trying to process a zero-length wire data buffer - * yields the expected result. This checks whether the fromwire_*() routine - * for given RR class and type behaves as expected. - */ -static void -check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok, dns_rdataclass_t rdclass, - dns_rdatatype_t type, size_t structsize) { - wire_ok_t empty_wire = WIRE_TEST(empty_ok, 0); - size_t i; - - /* - * Check all entries in the supplied array. - */ - for (i = 0; wire_ok[i].len != 0; i++) { - check_wire_ok_single(&wire_ok[i], rdclass, type, structsize); - } - - /* - * Check empty wire data. - */ - check_wire_ok_single(&empty_wire, rdclass, type, structsize); -} - -/* - * Check that two records compare as expected with dns_rdata_compare(). - */ -static void -check_compare_ok_single(const compare_ok_t *compare_ok, - dns_rdataclass_t rdclass, dns_rdatatype_t type) -{ - dns_rdata_t rdata1 = DNS_RDATA_INIT, rdata2 = DNS_RDATA_INIT; - unsigned char buf1[1024], buf2[1024]; - isc_result_t result; - int answer; - - result = dns_test_rdatafromstring(&rdata1, rdclass, type, - buf1, sizeof(buf1), - compare_ok->text1, false); - if (result != ISC_R_SUCCESS) { - fail_msg("# line %d: '%s': expected success, got failure", - compare_ok->lineno, compare_ok->text1); - } - - result = dns_test_rdatafromstring(&rdata2, rdclass, type, - buf2, sizeof(buf2), - compare_ok->text2, false); - - if (result != ISC_R_SUCCESS) { - fail_msg("# line %d: '%s': expected success, got failure", - compare_ok->lineno, compare_ok->text2); - } - - answer = dns_rdata_compare(&rdata1, &rdata2); - if (compare_ok->answer == 0 && answer != 0) { - fail_msg("# line %d: dns_rdata_compare('%s', '%s'): " - "expected equal, got %s", - compare_ok->lineno, - compare_ok->text1, compare_ok->text2, - (answer > 0) ? "greater than" : "less than"); - } - if (compare_ok->answer < 0 && answer >= 0) { - fail_msg("# line %d: dns_rdata_compare('%s', '%s'): " - "expected less than, got %s", - compare_ok->lineno, - compare_ok->text1, compare_ok->text2, - (answer == 0) ? "equal" : "greater than"); - } - if (compare_ok->answer > 0 && answer <= 0) { - fail_msg("line %d: dns_rdata_compare('%s', '%s'): " - "expected greater than, got %s", - compare_ok->lineno, - compare_ok->text1, compare_ok->text2, - (answer == 0) ? "equal" : "less than"); - } -} - -/* - * Check that all the records sets in compare_ok compare as expected - * with dns_rdata_compare(). - */ -static void -check_compare_ok(const compare_ok_t *compare_ok, - dns_rdataclass_t rdclass, dns_rdatatype_t type) -{ - size_t i; - /* - * Check all entries in the supplied array. - */ - for (i = 0; compare_ok[i].text1 != NULL; i++) { - check_compare_ok_single(&compare_ok[i], rdclass, type); - } -} - -/* - * Test whether supplied sets of text form and/or wire form RDATA are handled - * as expected. - * - * The empty_ok argument denotes whether an attempt to parse a zero-length wire - * data buffer should succeed or not (it is valid for some RR types). There is - * no point in performing a similar check for empty text form RDATA, because - * dns_rdata_fromtext() returns ISC_R_UNEXPECTEDEND before calling fromtext_*() - * for the given RR class and type. - */ -static void -check_rdata(const text_ok_t *text_ok, const wire_ok_t *wire_ok, - const compare_ok_t *compare_ok, - bool empty_ok, dns_rdataclass_t rdclass, - dns_rdatatype_t type, size_t structsize) -{ - if (text_ok != NULL) { - check_text_ok(text_ok, rdclass, type, structsize); - } - if (wire_ok != NULL) { - check_wire_ok(wire_ok, empty_ok, rdclass, type, structsize); - } - if (compare_ok != NULL) { - check_compare_ok(compare_ok, rdclass, type); - } -} - -/* - * Common tests for RR types based on KEY that require key data: - * - * - CDNSKEY (RFC 7344) - * - DNSKEY (RFC 4034) - * - RKEY (draft-reid-dnsext-rkey-00) - */ -static void -key_required(void **state, dns_rdatatype_t type, size_t size) { - wire_ok_t wire_ok[] = { - /* - * RDATA must be at least 5 octets in size: - * - * - 2 octets for Flags, - * - 1 octet for Protocol, - * - 1 octet for Algorithm, - * - Public Key must not be empty. - * - * RFC 2535 section 3.1.2 allows the Public Key to be empty if - * bits 0-1 of Flags are both set, but that only applies to KEY - * records: for the RR types tested here, the Public Key must - * not be empty. - */ - WIRE_INVALID(0x00), - WIRE_INVALID(0x00, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00), - WIRE_INVALID(0xc0, 0x00, 0x00, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x00), - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00), - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in, type, size); -} - -/* APL RDATA manipulations */ -static void -apl(void **state) { - text_ok_t text_ok[] = { - /* empty list */ - TEXT_VALID(""), - /* min,max prefix IPv4 */ - TEXT_VALID("1:0.0.0.0/0"), - TEXT_VALID("1:127.0.0.1/32"), - /* min,max prefix IPv6 */ - TEXT_VALID("2:::/0"), - TEXT_VALID("2:::1/128"), - /* negated */ - TEXT_VALID("!1:0.0.0.0/0"), - TEXT_VALID("!1:127.0.0.1/32"), - TEXT_VALID("!2:::/0"), - TEXT_VALID("!2:::1/128"), - /* bits set after prefix length - not disallowed */ - TEXT_VALID("1:127.0.0.0/0"), - TEXT_VALID("2:8000::/0"), - /* multiple */ - TEXT_VALID("1:0.0.0.0/0 1:127.0.0.1/32"), - TEXT_VALID("1:0.0.0.0/0 !1:127.0.0.1/32"), - /* family 0, prefix 0, positive */ - TEXT_VALID("\\# 4 00000000"), - /* family 0, prefix 0, negative */ - TEXT_VALID("\\# 4 00000080"), - /* prefix too long */ - TEXT_INVALID("1:0.0.0.0/33"), - TEXT_INVALID("2:::/129"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* zero length */ - WIRE_VALID(), - /* prefix too big IPv4 */ - WIRE_INVALID(0x00, 0x01, 33U, 0x00), - /* prefix too big IPv6 */ - WIRE_INVALID(0x00, 0x02, 129U, 0x00), - /* trailing zero octet in afdpart */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x01, 0x00), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, true, dns_rdataclass_in, - dns_rdatatype_apl, sizeof(dns_rdata_in_apl_t)); -} - -/* - * http://broadband-forum.org/ftp/pub/approved-specs/af-saa-0069.000.pdf - * - * ATMA RR’s have the following RDATA format: - * - * 1 1 1 1 1 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | FORMAT | | - * +--+--+--+--+--+--+--+--+ | - * / ADDRESS / - * | | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * - * The fields have the following meaning: - * - * * FORMAT: One octet that indicates the format of ADDRESS. The two - * possible values for FORMAT are value 0 indicating ATM End System Address - * (AESA) format and value 1 indicating E.164 format. - * - * * ADDRESS: Variable length string of octets containing the ATM address of - * the node to which this RR pertains. - * - * When the format value is 0, indicating that the address is in AESA format, - * the address is coded as described in ISO 8348/AD 2 using the preferred - * binary encoding of the ISO NSAP format. When the format value is 1, - * indicating that the address is in E.164 format, the Address/Number Digits - * appear in the order in which they would be entered on a numeric keypad. - * Digits are coded in IA5 characters with the leftmost bit of each digit set - * to 0. This ATM address appears in ATM End System Address Octets field (AESA - * format) or the Address/Number Digits field (E.164 format) of the Called - * party number information element [ATMUNI3.1]. Subaddress information is - * intentionally not included because E.164 subaddress information is used for - * routing. - * - * ATMA RRs cause no additional section processing. - */ -static void -atma(void **state) { - text_ok_t text_ok[] = { - TEXT_VALID("00"), - TEXT_VALID_CHANGED("0.0", "00"), - /* - * multiple consecutive periods - */ - TEXT_INVALID("0..0"), - /* - * trailing period - */ - TEXT_INVALID("00."), - /* - * leading period - */ - TEXT_INVALID(".00"), - /* - * Not full octets. - */ - TEXT_INVALID("000"), - /* - * E.164 - */ - TEXT_VALID("+61200000000"), - /* - * E.164 with periods - */ - TEXT_VALID_CHANGED("+61.2.0000.0000", "+61200000000"), - /* - * E.164 with period at end - */ - TEXT_INVALID("+61200000000."), - /* - * E.164 with multiple consecutive periods - */ - TEXT_INVALID("+612..00000000"), - /* - * E.164 with period before the leading digit. - */ - TEXT_INVALID("+.61200000000"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Too short. - */ - WIRE_INVALID(0x00), - WIRE_INVALID(0x01), - /* - * all digits - */ - WIRE_VALID(0x01, '6', '1', '2', '0', '0', '0'), - /* - * non digit - */ - WIRE_INVALID(0x01, '+', '6', '1', '2', '0', '0', '0'), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_atma, sizeof(dns_rdata_in_atma_t)); -} - -/* AMTRELAY RDATA manipulations */ -static void -amtrelay(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), - TEXT_INVALID("0"), - TEXT_INVALID("0 0"), - /* gateway type 0 */ - TEXT_VALID("0 0 0"), - TEXT_VALID("0 1 0"), - TEXT_INVALID("0 2 0"), /* discovery out of range */ - TEXT_VALID("255 1 0"), /* max precedence */ - TEXT_INVALID("256 1 0"), /* precedence out of range */ - - /* IPv4 gateway */ - TEXT_INVALID("0 0 1"), /* no address */ - TEXT_VALID("0 0 1 0.0.0.0"), - TEXT_INVALID("0 0 1 0.0.0.0 x"), /* extra */ - TEXT_INVALID("0 0 1 0.0.0.0.0"), /* bad address */ - TEXT_INVALID("0 0 1 ::"), /* bad address */ - TEXT_INVALID("0 0 1 ."), /* bad address */ - - /* IPv6 gateway */ - TEXT_INVALID("0 0 2"), /* no address */ - TEXT_VALID("0 0 2 ::"), - TEXT_INVALID("0 0 2 :: xx"), /* extra */ - TEXT_INVALID("0 0 2 0.0.0.0"), /* bad address */ - TEXT_INVALID("0 0 2 ."), /* bad address */ - - /* hostname gateway */ - TEXT_INVALID("0 0 3"), /* no name */ - /* IPv4 is a valid name */ - TEXT_VALID_CHANGED("0 0 3 0.0.0.0", "0 0 3 0.0.0.0."), - /* IPv6 is a valid name */ - TEXT_VALID_CHANGED("0 0 3 ::", "0 0 3 ::."), - TEXT_VALID_CHANGED("0 0 3 example", "0 0 3 example."), - TEXT_VALID("0 0 3 example."), - TEXT_INVALID("0 0 3 example. x"), /* extra */ - - /* unknown gateway */ - TEXT_VALID("\\# 2 0004"), - TEXT_VALID("\\# 2 0084"), - TEXT_VALID("\\# 2 007F"), - TEXT_VALID("\\# 3 000400"), - TEXT_VALID("\\# 3 008400"), - TEXT_VALID("\\# 3 00FF00"), - - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - WIRE_INVALID(0x00), - WIRE_VALID(0x00, 0x00), - WIRE_VALID(0x00, 0x80), - WIRE_INVALID(0x00, 0x00, 0x00), - WIRE_INVALID(0x00, 0x80, 0x00), - - WIRE_INVALID(0x00, 0x01), - WIRE_INVALID(0x00, 0x01, 0x00), - WIRE_INVALID(0x00, 0x01, 0x00, 0x00), - WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x00), - WIRE_VALID(0x00, 0x01, 0x00, 0x00, 0x00, 0x00), - WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00), - - WIRE_INVALID(0x00, 0x02), - WIRE_INVALID(0x00, 0x02, 0x00), - WIRE_VALID(0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15), - WIRE_INVALID(0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16), - - WIRE_INVALID(0x00, 0x03), - WIRE_VALID(0x00, 0x03, 0x00), - WIRE_INVALID(0x00, 0x03, 0x00, 0x00), /* extra */ - - WIRE_VALID(0x00, 0x04), - WIRE_VALID(0x00, 0x04, 0x00), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_amtrelay, sizeof(dns_rdata_amtrelay_t)); -} - -static void -cdnskey(void **state) { - key_required(state, dns_rdatatype_cdnskey, sizeof(dns_rdata_cdnskey_t)); -} - -/* - * CSYNC tests. - * - * RFC 7477: - * - * 2.1. The CSYNC Resource Record Format - * - * 2.1.1. The CSYNC Resource Record Wire Format - * - * The CSYNC RDATA consists of the following fields: - * - * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | SOA Serial | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Flags | Type Bit Map / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * / Type Bit Map (continued) / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 2.1.1.1. The SOA Serial Field - * - * The SOA Serial field contains a copy of the 32-bit SOA serial number - * from the child zone. If the soaminimum flag is set, parental agents - * querying children's authoritative servers MUST NOT act on data from - * zones advertising an SOA serial number less than this value. See - * [RFC1982] for properly implementing "less than" logic. If the - * soaminimum flag is not set, parental agents MUST ignore the value in - * the SOA Serial field. Clients can set the field to any value if the - * soaminimum flag is unset, such as the number zero. - * - * (...) - * - * 2.1.1.2. The Flags Field - * - * The Flags field contains 16 bits of boolean flags that define - * operations that affect the processing of the CSYNC record. The flags - * defined in this document are as follows: - * - * 0x00 0x01: "immediate" - * - * 0x00 0x02: "soaminimum" - * - * The definitions for how the flags are to be used can be found in - * Section 3. - * - * The remaining flags are reserved for use by future specifications. - * Undefined flags MUST be set to 0 by CSYNC publishers. Parental - * agents MUST NOT process a CSYNC record if it contains a 1 value for a - * flag that is unknown to or unsupported by the parental agent. - * - * 2.1.1.2.1. The Type Bit Map Field - * - * The Type Bit Map field indicates the record types to be processed by - * the parental agent, according to the procedures in Section 3. The - * Type Bit Map field is encoded in the same way as the Type Bit Map - * field of the NSEC record, described in [RFC4034], Section 4.1.2. If - * a bit has been set that a parental agent implementation does not - * understand, the parental agent MUST NOT act upon the record. - * Specifically, a parental agent must not simply copy the data, and it - * must understand the semantics associated with a bit in the Type Bit - * Map field that has been set to 1. - */ -static void -csync(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), - TEXT_INVALID("0"), - TEXT_VALID("0 0"), - TEXT_VALID("0 0 A"), - TEXT_VALID("0 0 NS"), - TEXT_VALID("0 0 AAAA"), - TEXT_VALID("0 0 A AAAA"), - TEXT_VALID("0 0 A NS AAAA"), - TEXT_INVALID("0 0 A NS AAAA BOGUS"), - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Short. - */ - WIRE_INVALID(0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Serial + flags only. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Bad type map. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Bad type map. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Good type map. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_csync, sizeof(dns_rdata_csync_t)); -} - -static void -dnskey(void **state) { - key_required(state, dns_rdatatype_dnskey, sizeof(dns_rdata_dnskey_t)); -} - -/* - * DOA tests. - * - * draft-durand-doa-over-dns-03: - * - * 3.2. DOA RDATA Wire Format - * - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 0: | | - * | DOA-ENTERPRISE | - * | | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 4: | | - * | DOA-TYPE | - * | | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 8: | DOA-LOCATION | DOA-MEDIA-TYPE / - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 10: / / - * / DOA-MEDIA-TYPE (continued) / - * / / - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * / / - * / DOA-DATA / - * / / - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * - * DOA-ENTERPRISE: a 32-bit unsigned integer in network order. - * - * DOA-TYPE: a 32-bit unsigned integer in network order. - * - * DOA-LOCATION: an 8-bit unsigned integer. - * - * DOA-MEDIA-TYPE: A (see [RFC1035]). The first - * octet of the contains the number of characters to - * follow. - * - * DOA-DATA: A variable length blob of binary data. The length of the - * DOA-DATA is not contained within the wire format of the RR and has to - * be computed from the RDLENGTH of the entire RR once other fields have - * been taken into account. - * - * 3.3. DOA RDATA Presentation Format - * - * The DOA-ENTERPRISE field is presented as an unsigned 32-bit decimal - * integer with range 0 - 4,294,967,295. - * - * The DOA-TYPE field is presented as an unsigned 32-bit decimal integer - * with range 0 - 4,294,967,295. - * - * The DOA-LOCATION field is presented as an unsigned 8-bit decimal - * integer with range 0 - 255. - * - * The DOA-MEDIA-TYPE field is presented as a single . - * - * The DOA-DATA is presented as Base64 encoded data [RFC4648] unless the - * DOA-DATA is empty in which case it is presented as a single dash - * character ("-", ASCII 45). White space is permitted within Base64 - * data. - */ -static void -doa(void **state) { - text_ok_t text_ok[] = { - /* - * Valid, non-empty DOA-DATA. - */ - TEXT_VALID("0 0 1 \"text/plain\" Zm9v"), - /* - * Valid, non-empty DOA-DATA with whitespace in between. - */ - TEXT_VALID_CHANGED("0 0 1 \"text/plain\" Zm 9v", - "0 0 1 \"text/plain\" Zm9v"), - /* - * Valid, unquoted DOA-MEDIA-TYPE, non-empty DOA-DATA. - */ - TEXT_VALID_CHANGED("0 0 1 text/plain Zm9v", - "0 0 1 \"text/plain\" Zm9v"), - /* - * Invalid, quoted non-empty DOA-DATA. - */ - TEXT_INVALID("0 0 1 \"text/plain\" \"Zm9v\""), - /* - * Valid, empty DOA-DATA. - */ - TEXT_VALID("0 0 1 \"text/plain\" -"), - /* - * Invalid, quoted empty DOA-DATA. - */ - TEXT_INVALID("0 0 1 \"text/plain\" \"-\""), - /* - * Invalid, missing "-" in empty DOA-DATA. - */ - TEXT_INVALID("0 0 1 \"text/plain\""), - /* - * Valid, undefined DOA-LOCATION. - */ - TEXT_VALID("0 0 100 \"text/plain\" Zm9v"), - /* - * Invalid, DOA-LOCATION too big. - */ - TEXT_INVALID("0 0 256 \"text/plain\" ZM9v"), - /* - * Valid, empty DOA-MEDIA-TYPE, non-empty DOA-DATA. - */ - TEXT_VALID("0 0 2 \"\" aHR0cHM6Ly93d3cuaXNjLm9yZy8="), - /* - * Valid, empty DOA-MEDIA-TYPE, empty DOA-DATA. - */ - TEXT_VALID("0 0 1 \"\" -"), - /* - * Valid, DOA-MEDIA-TYPE with a space. - */ - TEXT_VALID("0 0 1 \"plain text\" Zm9v"), - /* - * Invalid, missing DOA-MEDIA-TYPE. - */ - TEXT_INVALID("1234567890 1234567890 1"), - /* - * Valid, DOA-DATA over 255 octets. - */ - TEXT_VALID("1234567890 1234567890 1 \"image/gif\" " - "R0lGODlhKAAZAOMCAGZmZgBmmf///zOZzMz//5nM/zNmmWbM" - "/5nMzMzMzACZ/////////////////////yH5BAEKAA8ALAAA" - "AAAoABkAAATH8IFJK5U2a4337F5ogRkpnoCJrly7PrCKyh8c" - "3HgAhzT35MDbbtO7/IJIHbGiOiaTxVTpSVWWLqNq1UVyapNS" - "1wd3OAxug0LhnCubcVhsxysQnOt4ATpvvzHlFzl1AwODhWeF" - "AgRpen5/UhheAYMFdUB4SFcpGEGGdQeCAqBBLTuSk30EeXd9" - "pEsAbKGxjHqDSE0Sp6ixN4N1BJmbc7lIhmsBich1awPAjkY1" - "SZR8bJWrz382SGqIBQQFQd4IsUTaX+ceuudPEQA7"), - /* - * Invalid, bad Base64 in DOA-DATA. - */ - TEXT_INVALID("1234567890 1234567890 1 \"image/gif\" R0lGODl"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Valid, empty DOA-MEDIA-TYPE, empty DOA-DATA. - */ - WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01, 0x00), - /* - * Invalid, missing DOA-MEDIA-TYPE. - */ - WIRE_INVALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01), - /* - * Invalid, malformed DOA-MEDIA-TYPE length. - */ - WIRE_INVALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01, 0xff), - /* - * Valid, empty DOA-DATA. - */ - WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01, 0x03, 0x66, 0x6f, 0x6f), - /* - * Valid, non-empty DOA-DATA. - */ - WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01, 0x03, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72), - /* - * Valid, DOA-DATA over 255 octets. - */ - WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, - 0x01, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, - 0x00, 0x66, 0x99, 0xff, 0xff, 0xff, 0x33, 0x99, - 0xcc, 0xcc, 0xff, 0xff, 0x99, 0xcc, 0xff, 0x33, - 0x66, 0x99, 0x66, 0xcc, 0xff, 0x99, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x00, 0x99, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x21, 0xf9, 0x04, - 0x01, 0x0a, 0x00, 0x0f, 0x00, 0x2c, 0x00, 0x00, - 0x00, 0x00, 0x28, 0x00, 0x19, 0x00, 0x00, 0x04, - 0xc7, 0xf0, 0x81, 0x49, 0x2b, 0x95, 0x36, 0x6b, - 0x8d, 0xf7, 0xec, 0x5e, 0x68, 0x81, 0x19, 0x29, - 0x9e, 0x80, 0x89, 0xae, 0x5c, 0xbb, 0x3e, 0xb0, - 0x8a, 0xca, 0x1f, 0x1c, 0xdc, 0x78, 0x00, 0x87, - 0x34, 0xf7, 0xe4, 0xc0, 0xdb, 0x6e, 0xd3, 0xbb, - 0xfc, 0x82, 0x48, 0x1d, 0xb1, 0xa2, 0x3a, 0x26, - 0x93, 0xc5, 0x54, 0xe9, 0x49, 0x55, 0x96, 0x2e, - 0xa3, 0x6a, 0xd5, 0x45, 0x72, 0x6a, 0x93, 0x52, - 0xd7, 0x07, 0x77, 0x38, 0x0c, 0x6e, 0x83, 0x42, - 0xe1, 0x9c, 0x2b, 0x9b, 0x71, 0x58, 0x6c, 0xc7, - 0x2b, 0x10, 0x9c, 0xeb, 0x78, 0x01, 0x3a, 0x6f, - 0xbf, 0x31, 0xe5, 0x17, 0x39, 0x75, 0x03, 0x03, - 0x83, 0x85, 0x67, 0x85, 0x02, 0x04, 0x69, 0x7a, - 0x7e, 0x7f, 0x52, 0x18, 0x5e, 0x01, 0x83, 0x05, - 0x75, 0x40, 0x78, 0x48, 0x57, 0x29, 0x18, 0x41, - 0x86, 0x75, 0x07, 0x82, 0x02, 0xa0, 0x41, 0x2d, - 0x3b, 0x92, 0x93, 0x7d, 0x04, 0x79, 0x77, 0x7d, - 0xa4, 0x4b, 0x00, 0x6c, 0xa1, 0xb1, 0x8c, 0x7a, - 0x83, 0x48, 0x4d, 0x12, 0xa7, 0xa8, 0xb1, 0x37, - 0x83, 0x75, 0x04, 0x99, 0x9b, 0x73, 0xb9, 0x48, - 0x86, 0x6b, 0x01, 0x89, 0xc8, 0x75, 0x6b, 0x03, - 0xc0, 0x8e, 0x46, 0x35, 0x49, 0x94, 0x7c, 0x6c, - 0x95, 0xab, 0xcf, 0x7f, 0x36, 0x48, 0x6a, 0x88, - 0x05, 0x04, 0x05, 0x41, 0xde, 0x08, 0xb1, 0x44, - 0xda, 0x5f, 0xe7, 0x1e, 0xba, 0xe7, 0x4f, 0x11, - 0x00, 0x3b), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_doa, sizeof(dns_rdata_doa_t)); -} - -/* - * DS tests. - * - * RFC 4034: - * - * 5.1. DS RDATA Wire Format - * - * The RDATA for a DS RR consists of a 2 octet Key Tag field, a 1 octet - * Algorithm field, a 1 octet Digest Type field, and a Digest field. - * - * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Key Tag | Algorithm | Digest Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * / / - * / Digest / - * / / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 5.1.1. The Key Tag Field - * - * The Key Tag field lists the key tag of the DNSKEY RR referred to by - * the DS record, in network byte order. - * - * The Key Tag used by the DS RR is identical to the Key Tag used by - * RRSIG RRs. Appendix B describes how to compute a Key Tag. - * - * 5.1.2. The Algorithm Field - * - * The Algorithm field lists the algorithm number of the DNSKEY RR - * referred to by the DS record. - * - * The algorithm number used by the DS RR is identical to the algorithm - * number used by RRSIG and DNSKEY RRs. Appendix A.1 lists the - * algorithm number types. - * - * 5.1.3. The Digest Type Field - * - * The DS RR refers to a DNSKEY RR by including a digest of that DNSKEY - * RR. The Digest Type field identifies the algorithm used to construct - * the digest. Appendix A.2 lists the possible digest algorithm types. - * - * 5.1.4. The Digest Field - * - * The DS record refers to a DNSKEY RR by including a digest of that - * DNSKEY RR. - * - * The digest is calculated by concatenating the canonical form of the - * fully qualified owner name of the DNSKEY RR with the DNSKEY RDATA, - * and then applying the digest algorithm. - * - * digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); - * - * "|" denotes concatenation - * - * DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. - * - * The size of the digest may vary depending on the digest algorithm and - * DNSKEY RR size. As of the time of this writing, the only defined - * digest algorithm is SHA-1, which produces a 20 octet digest. - */ -static void -ds(void **state) { - text_ok_t text_ok[] = { - /* - * Invalid, empty record. - */ - TEXT_INVALID(""), - /* - * Invalid, no algorithm. - */ - TEXT_INVALID("0"), - /* - * Invalid, no digest type. - */ - TEXT_INVALID("0 0"), - /* - * Invalid, no digest. - */ - TEXT_INVALID("0 0 0"), - /* - * Valid, 1-octet digest for a reserved digest type. - */ - TEXT_VALID("0 0 0 00"), - /* - * Invalid, short SHA-1 digest. - */ - TEXT_INVALID("0 0 1 00"), - TEXT_INVALID("0 0 1 4FDCE83016EDD29077621FE568F8DADDB5809B"), - /* - * Valid, 20-octet SHA-1 digest. - */ - TEXT_VALID("0 0 1 4FDCE83016EDD29077621FE568F8DADDB5809B6A"), - /* - * Invalid, excessively long SHA-1 digest. - */ - TEXT_INVALID("0 0 1 4FDCE83016EDD29077621FE568F8DADDB5809B" - "6A00"), - /* - * Invalid, short SHA-256 digest. - */ - TEXT_INVALID("0 0 2 00"), - TEXT_INVALID("0 0 2 D001BD422FFDA9B745425B71DC17D007E69186" - "9BD59C5F237D9BF85434C313"), - /* - * Valid, 32-octet SHA-256 digest. - */ - TEXT_VALID_CHANGED( - "0 0 2 D001BD422FFDA9B745425B71DC17D007E691869B" - "D59C5F237D9BF85434C3133F", - "0 0 2 D001BD422FFDA9B745425B71DC17D007E691869B" - "D59C5F237D9BF854 34C3133F"), - /* - * Invalid, excessively long SHA-256 digest. - */ - TEXT_INVALID("0 0 2 D001BD422FFDA9B745425B71DC17D007E69186" - "9BD59C5F237D9BF85434C3133F00"), -#ifdef ISC_GOST_DIGESTLENGTH - /* - * Invalid, short GOST digest. - */ - TEXT_INVALID("0 0 3 00"), - TEXT_INVALID("0 0 3 D001BD422FFDA9B745425B71DC17D007E69186" - "9BD59C5F237D9BF85434C313"), - /* - * Valid, 32-octet GOST digest. - */ - TEXT_VALID_CHANGED( - "0 0 3 D001BD422FFDA9B745425B71DC17D007E691869B" - "D59C5F237D9BF85434C3133F", - "0 0 3 D001BD422FFDA9B745425B71DC17D007E691869B" - "D59C5F237D9BF854 34C3133F"), - /* - * Invalid, excessively long GOST digest. - */ - TEXT_INVALID("0 0 3 D001BD422FFDA9B745425B71DC17D007E69186" - "9BD59C5F237D9BF85434C3133F00"), -#else - TEXT_VALID("0 0 3 00"), -#endif - /* - * Invalid, short SHA-384 digest. - */ - TEXT_INVALID("0 0 4 00"), - TEXT_INVALID("0 0 4 AC748D6C5AA652904A8763D64B7DFFFFA98152" - "BE12128D238BEBB4814B648F5A841E15CAA2DE348891" - "A37A699F65E5"), - /* - * Valid, 48-octet SHA-384 digest. - */ - TEXT_VALID_CHANGED( - "0 0 4 AC748D6C5AA652904A8763D64B7DFFFFA98152BE" - "12128D238BEBB4814B648F5A841E15CAA2DE348891A37A" - "699F65E54D", - "0 0 4 AC748D6C5AA652904A8763D64B7DFFFFA98152BE" - "12128D238BEBB481 4B648F5A841E15CAA2DE348891A37A" - "699F65E54D"), - /* - * Invalid, excessively long SHA-384 digest. - */ - TEXT_INVALID("0 0 4 AC748D6C5AA652904A8763D64B7DFFFFA98152" - "BE12128D238BEBB4814B648F5A841E15CAA2DE348891" - "A37A699F65E54D00"), - /* - * Valid, 1-octet digest for an unassigned digest type. - */ - TEXT_VALID("0 0 5 00"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Invalid, truncated key tag. - */ - WIRE_INVALID(0x00), - /* - * Invalid, no algorithm. - */ - WIRE_INVALID(0x00, 0x00), - /* - * Invalid, no digest type. - */ - WIRE_INVALID(0x00, 0x00, 0x00), - /* - * Invalid, no digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00), - /* - * Valid, 1-octet digest for a reserved digest type. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Invalid, short SHA-1 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x01, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x01, 0x4F, 0xDC, 0xE8, 0x30, - 0x16, 0xED, 0xD2, 0x90, 0x77, 0x62, 0x1F, 0xE5, - 0x68, 0xF8, 0xDA, 0xDD, 0xB5, 0x80, 0x9B), - /* - * Valid, 20-octet SHA-1 digest. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x01, 0x4F, 0xDC, 0xE8, 0x30, - 0x16, 0xED, 0xD2, 0x90, 0x77, 0x62, 0x1F, 0xE5, - 0x68, 0xF8, 0xDA, 0xDD, 0xB5, 0x80, 0x9B, 0x6A), - /* - * Invalid, excessively long SHA-1 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x01, 0x4F, 0xDC, 0xE8, 0x30, - 0x16, 0xED, 0xD2, 0x90, 0x77, 0x62, 0x1F, 0xE5, - 0x68, 0xF8, 0xDA, 0xDD, 0xB5, 0x80, 0x9B, 0x6A, - 0x00), - /* - * Invalid, short SHA-256 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x02, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x02, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13), - /* - * Valid, 32-octet SHA-256 digest. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x02, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13, 0x3F), - /* - * Invalid, excessively long SHA-256 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x02, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13, 0x3F, 0x00), -#ifdef ISC_GOST_DIGESTLENGTH - /* - * Invalid, short GOST digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x03, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x03, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13), - /* - * Valid, 32-octet GOST digest. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x03, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13, 0x3F), - /* - * Invalid, excessively long GOST digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x03, 0xD0, 0x01, 0xBD, 0x42, - 0x2F, 0xFD, 0xA9, 0xB7, 0x45, 0x42, 0x5B, 0x71, - 0xDC, 0x17, 0xD0, 0x07, 0xE6, 0x91, 0x86, 0x9B, - 0xD5, 0x9C, 0x5F, 0x23, 0x7D, 0x9B, 0xF8, 0x54, - 0x34, 0xC3, 0x13, 0x3F, 0x00), -#else - WIRE_VALID(0x00, 0x00, 0x00, 0x03, 0x00), -#endif - /* - * Invalid, short SHA-384 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x04, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x04, 0xAC, 0x74, 0x8D, 0x6C, - 0x5A, 0xA6, 0x52, 0x90, 0x4A, 0x87, 0x63, 0xD6, - 0x4B, 0x7D, 0xFF, 0xFF, 0xA9, 0x81, 0x52, 0xBE, - 0x12, 0x12, 0x8D, 0x23, 0x8B, 0xEB, 0xB4, 0x81, - 0x4B, 0x64, 0x8F, 0x5A, 0x84, 0x1E, 0x15, 0xCA, - 0xA2, 0xDE, 0x34, 0x88, 0x91, 0xA3, 0x7A, 0x69, - 0x9F, 0x65, 0xE5), - /* - * Valid, 48-octet SHA-384 digest. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x04, 0xAC, 0x74, 0x8D, 0x6C, - 0x5A, 0xA6, 0x52, 0x90, 0x4A, 0x87, 0x63, 0xD6, - 0x4B, 0x7D, 0xFF, 0xFF, 0xA9, 0x81, 0x52, 0xBE, - 0x12, 0x12, 0x8D, 0x23, 0x8B, 0xEB, 0xB4, 0x81, - 0x4B, 0x64, 0x8F, 0x5A, 0x84, 0x1E, 0x15, 0xCA, - 0xA2, 0xDE, 0x34, 0x88, 0x91, 0xA3, 0x7A, 0x69, - 0x9F, 0x65, 0xE5, 0x4D), - /* - * Invalid, excessively long SHA-384 digest. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x04, 0xAC, 0x74, 0x8D, 0x6C, - 0x5A, 0xA6, 0x52, 0x90, 0x4A, 0x87, 0x63, 0xD6, - 0x4B, 0x7D, 0xFF, 0xFF, 0xA9, 0x81, 0x52, 0xBE, - 0x12, 0x12, 0x8D, 0x23, 0x8B, 0xEB, 0xB4, 0x81, - 0x4B, 0x64, 0x8F, 0x5A, 0x84, 0x1E, 0x15, 0xCA, - 0xA2, 0xDE, 0x34, 0x88, 0x91, 0xA3, 0x7A, 0x69, - 0x9F, 0x65, 0xE5, 0x4D, 0x00), - WIRE_VALID(0x00, 0x00, 0x04, 0x00, 0x00), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_ds, sizeof(dns_rdata_ds_t)); -} - -/* - * EDNS Client Subnet tests. - * - * RFC 7871: - * - * 6. Option Format - * - * This protocol uses an EDNS0 [RFC6891] option to include client - * address information in DNS messages. The option is structured as - * follows: - * - * +0 (MSB) +1 (LSB) - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 0: | OPTION-CODE | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 2: | OPTION-LENGTH | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 4: | FAMILY | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 6: | SOURCE PREFIX-LENGTH | SCOPE PREFIX-LENGTH | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * 8: | ADDRESS... / - * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * - * o (Defined in [RFC6891]) OPTION-CODE, 2 octets, for ECS is 8 (0x00 - * 0x08). - * - * o (Defined in [RFC6891]) OPTION-LENGTH, 2 octets, contains the - * length of the payload (everything after OPTION-LENGTH) in octets. - * - * o FAMILY, 2 octets, indicates the family of the address contained in - * the option, using address family codes as assigned by IANA in - * Address Family Numbers [Address_Family_Numbers]. - * - * The format of the address part depends on the value of FAMILY. This - * document only defines the format for FAMILY 1 (IPv4) and FAMILY 2 - * (IPv6), which are as follows: - * - * o SOURCE PREFIX-LENGTH, an unsigned octet representing the leftmost - * number of significant bits of ADDRESS to be used for the lookup. - * In responses, it mirrors the same value as in the queries. - * - * o SCOPE PREFIX-LENGTH, an unsigned octet representing the leftmost - * number of significant bits of ADDRESS that the response covers. - * In queries, it MUST be set to 0. - * - * o ADDRESS, variable number of octets, contains either an IPv4 or - * IPv6 address, depending on FAMILY, which MUST be truncated to the - * number of bits indicated by the SOURCE PREFIX-LENGTH field, - * padding with 0 bits to pad to the end of the last octet needed. - * - * o A server receiving an ECS option that uses either too few or too - * many ADDRESS octets, or that has non-zero ADDRESS bits set beyond - * SOURCE PREFIX-LENGTH, SHOULD return FORMERR to reject the packet, - * as a signal to the software developer making the request to fix - * their implementation. - * - * All fields are in network byte order ("big-endian", per [RFC1700], - * Data Notation). - */ -static void -edns_client_subnet(void **state) { - wire_ok_t wire_ok[] = { - /* - * Option code with no content. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 0x00), - /* - * Option code family 0, source 0, scope 0. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00), - /* - * Option code family 1 (IPv4), source 0, scope 0. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x00), - /* - * Option code family 2 (IPv6) , source 0, scope 0. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x04, - 0x00, 0x02, 0x00, 0x00), - /* - * Extra octet. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x00, - 0x00), - /* - * Source too long for IPv4. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 8, - 0x00, 0x01, 33, 0x00, - 0x00, 0x00, 0x00, 0x00), - /* - * Source too long for IPv6. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 20, - 0x00, 0x02, 129, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00), - /* - * Scope too long for IPv4. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 8, - 0x00, 0x01, 0x00, 33, - 0x00, 0x00, 0x00, 0x00), - /* - * Scope too long for IPv6. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 20, - 0x00, 0x02, 0x00, 129, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00), - /* - * When family=0, source and scope should be 0. - */ - WIRE_VALID(0x00, 0x08, 0x00, 4, - 0x00, 0x00, 0x00, 0x00), - /* - * When family=0, source and scope should be 0. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 5, - 0x00, 0x00, 0x01, 0x00, - 0x00), - /* - * When family=0, source and scope should be 0. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 5, - 0x00, 0x00, 0x00, 0x01, - 0x00), - /* - * Length too short for source IPv4. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 7, - 0x00, 0x01, 32, 0x00, - 0x00, 0x00, 0x00), - /* - * Length too short for source IPv6. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 19, - 0x00, 0x02, 128, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, wire_ok, NULL, true, dns_rdataclass_in, - dns_rdatatype_opt, sizeof(dns_rdata_opt_t)); -} - -/* - * http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt - * - * The RDATA portion of both the NIMLOC and EID records contains - * uninterpreted binary data. The representation in the text master file - * is an even number of hex characters (0 to 9, a to f), case is not - * significant. For readability, whitespace may be included in the value - * field and should be ignored when reading a master file. - */ -static void -eid(void **state) { - text_ok_t text_ok[] = { - TEXT_VALID("AABBCC"), - TEXT_VALID_CHANGED("AA bb cc", "AABBCC"), - TEXT_INVALID("aab"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - WIRE_VALID(0x00), - WIRE_VALID(0xAA, 0xBB, 0xCC), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_eid, sizeof(dns_rdata_in_eid_t)); -} - -/* - * test that an oversized HIP record will be rejected - */ -static void -hip(void **state) { - text_ok_t text_ok[] = { - /* RFC 8005 examples. */ - TEXT_VALID_LOOP(0, "2 200100107B1A74DF365639CC39F1D578 " - "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI" - "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW" - "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b" - "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx" - "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D"), - TEXT_VALID_LOOP(1, "2 200100107B1A74DF365639CC39F1D578 " - "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI" - "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW" - "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b" - "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx" - "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D " - "rvs1.example.com."), - TEXT_VALID_LOOP(2, "2 200100107B1A74DF365639CC39F1D578 " - "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI" - "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW" - "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b" - "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx" - "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D " - "rvs1.example.com. rvs2.example.com."), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - unsigned char hipwire[DNS_RDATA_MAXLENGTH] = { 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x04, 0x41, - 0x42, 0x43, 0x44, 0x00 }; - unsigned char buf[1024 * 1024]; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - size_t i; - - UNUSED(state); - - /* - * Fill the rest of input buffer with compression pointers. - */ - for (i = 12; i < sizeof(hipwire) - 2; i += 2) { - hipwire[i] = 0xc0; - hipwire[i+1] = 0x06; - } - - result = wire_to_rdata(hipwire, sizeof(hipwire), dns_rdataclass_in, - dns_rdatatype_hip, buf, sizeof(buf), &rdata); - assert_int_equal(result, DNS_R_FORMERR); - check_text_ok(text_ok, dns_rdataclass_in, dns_rdatatype_hip, - sizeof(dns_rdata_hip_t)); -} - -/* - * ISDN tests. - * - * RFC 1183: - * - * 3.2. The ISDN RR - * - * The ISDN RR is defined with mnemonic ISDN and type code 20 (decimal). - * - * An ISDN (Integrated Service Digital Network) number is simply a - * telephone number. The intent of the members of the CCITT is to - * upgrade all telephone and data network service to a common service. - * - * The numbering plan (E.163/E.164) is the same as the familiar - * international plan for POTS (an un-official acronym, meaning Plain - * Old Telephone Service). In E.166, CCITT says "An E.163/E.164 - * telephony subscriber may become an ISDN subscriber without a number - * change." - * - * ISDN has the following format: - * - * ISDN - * - * The field is required; is optional. - * - * identifies the ISDN number of and DDI (Direct - * Dial In) if any, as defined by E.164 [8] and E.163 [7], the ISDN and - * PSTN (Public Switched Telephone Network) numbering plan. E.163 - * defines the country codes, and E.164 the form of the addresses. Its - * format in master files is a syntactically - * identical to that used in TXT and HINFO. - * - * specifies the subaddress (SA). The format of in master - * files is a syntactically identical to that used in - * TXT and HINFO. - * - * The format of ISDN is class insensitive. ISDN RRs cause no - * additional section processing. - * - * The is a string of characters, normally decimal - * digits, beginning with the E.163 country code and ending with the DDI - * if any. Note that ISDN, in Q.931, permits any IA5 character in the - * general case. - * - * The is a string of hexadecimal digits. For digits 0-9, the - * concrete encoding in the Q.931 call setup information element is - * identical to BCD. - * - * For example: - * - * Relay.Prime.COM. IN ISDN 150862028003217 - * sh.Prime.COM. IN ISDN 150862028003217 004 - * - * (Note: "1" is the country code for the North American Integrated - * Numbering Area, i.e., the system of "area codes" familiar to people - * in those countries.) - * - * The RR data is the ASCII representation of the digits. It is encoded - * as one or two s, i.e., count followed by - * characters. - */ -static void -isdn(void **state) { - wire_ok_t wire_ok[] = { - /* - * "". - */ - WIRE_VALID(0x00), - /* - * "\001". - */ - WIRE_VALID(0x01, 0x01), - /* - * "\001" "". - */ - WIRE_VALID(0x01, 0x01, 0x00), - /* - * "\001" "\001". - */ - WIRE_VALID(0x01, 0x01, 0x01, 0x01), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_isdn, sizeof(dns_rdata_isdn_t)); -} - -/* - * KEY tests. - */ -static void -key(void **state) { - wire_ok_t wire_ok[] = { - /* - * RDATA is comprised of: - * - * - 2 octets for Flags, - * - 1 octet for Protocol, - * - 1 octet for Algorithm, - * - variable number of octets for Public Key. - * - * RFC 2535 section 3.1.2 states that if bits 0-1 of Flags are - * both set, the RR stops after the algorithm octet and thus - * its length must be 4 octets. In any other case, though, the - * Public Key part must not be empty. - */ - WIRE_INVALID(0x00), - WIRE_INVALID(0x00, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00), - WIRE_VALID(0xc0, 0x00, 0x00, 0x00), - WIRE_INVALID(0xc0, 0x00, 0x00, 0x00, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00, 0x00), - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00), - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_key, sizeof(dns_rdata_key_t)); -} - -/* - * LOC tests. - */ -static void -loc(void **state) { - text_ok_t text_ok[] = { - TEXT_VALID_CHANGED("0 N 0 E 0", "0 0 0.000 N 0 0 0.000 E 0.00m " - "1m 10000m 10m"), - TEXT_VALID_CHANGED("0 S 0 W 0", "0 0 0.000 N 0 0 0.000 E 0.00m " - "1m 10000m 10m"), - TEXT_VALID_CHANGED("0 0 N 0 0 E 0", "0 0 0.000 N 0 0 0.000 E " - "0.00m 1m 10000m 10m"), - TEXT_VALID_CHANGED("0 0 0 N 0 0 0 E 0", - "0 0 0.000 N 0 0 0.000 E 0.00m 1m 10000m " - "10m"), - TEXT_VALID_CHANGED("0 0 0 N 0 0 0 E 0", - "0 0 0.000 N 0 0 0.000 E 0.00m 1m 10000m " - "10m"), - TEXT_VALID_CHANGED("0 0 0. N 0 0 0. E 0", - "0 0 0.000 N 0 0 0.000 E 0.00m 1m 10000m " - "10m"), - TEXT_VALID_CHANGED("0 0 .0 N 0 0 .0 E 0", - "0 0 0.000 N 0 0 0.000 E 0.00m 1m 10000m " - "10m"), - TEXT_INVALID("0 North 0 East 0"), - TEXT_INVALID("0 South 0 West 0"), - TEXT_INVALID("0 0 . N 0 0 0. E 0"), - TEXT_INVALID("0 0 0. N 0 0 . E 0"), - TEXT_INVALID("0 0 0. N 0 0 0. E m"), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 ."), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 m"), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 0 ."), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 0 m"), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 0 0 ."), - TEXT_INVALID("0 0 0. N 0 0 0. E 0 0 0 m"), - TEXT_VALID_CHANGED("90 N 180 E 0", "90 0 0.000 N 180 0 0.000 E " - "0.00m 1m 10000m 10m"), - TEXT_INVALID("90 1 N 180 E 0"), - TEXT_INVALID("90 0 1 N 180 E 0"), - TEXT_INVALID("90 N 180 1 E 0"), - TEXT_INVALID("90 N 180 0 1 E 0"), - TEXT_VALID_CHANGED("90 S 180 W 0", "90 0 0.000 S 180 0 0.000 W " - "0.00m 1m 10000m 10m"), - TEXT_INVALID("90 1 S 180 W 0"), - TEXT_INVALID("90 0 1 S 180 W 0"), - TEXT_INVALID("90 S 180 1 W 0"), - TEXT_INVALID("90 S 180 0 1 W 0"), - TEXT_VALID("0 0 0.000 N 0 0 0.000 E -0.95m 1m 10000m 10m"), - TEXT_VALID("0 0 0.000 N 0 0 0.000 E -0.05m 1m 10000m 10m"), - TEXT_VALID("0 0 0.000 N 0 0 0.000 E -100000.00m 1m 10000m 10m"), - TEXT_VALID("0 0 0.000 N 0 0 0.000 E 42849672.95m 1m 10000m " - "10m"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, 0, NULL, false, dns_rdataclass_in, - dns_rdatatype_loc, sizeof(dns_rdata_loc_t)); -} - -/* - * http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt - * - * The RDATA portion of both the NIMLOC and EID records contains - * uninterpreted binary data. The representation in the text master file - * is an even number of hex characters (0 to 9, a to f), case is not - * significant. For readability, whitespace may be included in the value - * field and should be ignored when reading a master file. - */ -static void -nimloc(void **state) { - text_ok_t text_ok[] = { - TEXT_VALID("AABBCC"), - TEXT_VALID_CHANGED("AA bb cc", "AABBCC"), - TEXT_INVALID("aab"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - WIRE_VALID(0x00), - WIRE_VALID(0xAA, 0xBB, 0xCC), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_nimloc, sizeof(dns_rdata_in_nimloc_t)); -} - -/* - * NSEC tests. - * - * RFC 4034: - * - * 4.1. NSEC RDATA Wire Format - * - * The RDATA of the NSEC RR is as shown below: - * - * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * / Next Domain Name / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * / Type Bit Maps / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 4.1.1. The Next Domain Name Field - * - * The Next Domain field contains the next owner name (in the canonical - * ordering of the zone) that has authoritative data or contains a - * delegation point NS RRset; see Section 6.1 for an explanation of - * canonical ordering. The value of the Next Domain Name field in the - * last NSEC record in the zone is the name of the zone apex (the owner - * name of the zone's SOA RR). This indicates that the owner name of - * the NSEC RR is the last name in the canonical ordering of the zone. - * - * A sender MUST NOT use DNS name compression on the Next Domain Name - * field when transmitting an NSEC RR. - * - * Owner names of RRsets for which the given zone is not authoritative - * (such as glue records) MUST NOT be listed in the Next Domain Name - * unless at least one authoritative RRset exists at the same owner - * name. - * - * 4.1.2. The Type Bit Maps Field - * - * The Type Bit Maps field identifies the RRset types that exist at the - * NSEC RR's owner name. - * - * The RR type space is split into 256 window blocks, each representing - * the low-order 8 bits of the 16-bit RR type space. Each block that - * has at least one active RR type is encoded using a single octet - * window number (from 0 to 255), a single octet bitmap length (from 1 - * to 32) indicating the number of octets used for the window block's - * bitmap, and up to 32 octets (256 bits) of bitmap. - * - * Blocks are present in the NSEC RR RDATA in increasing numerical - * order. - * - * Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+ - * - * where "|" denotes concatenation. - * - * Each bitmap encodes the low-order 8 bits of RR types within the - * window block, in network bit order. The first bit is bit 0. For - * window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds - * to RR type 2 (NS), and so forth. For window block 1, bit 1 - * corresponds to RR type 257, and bit 2 to RR type 258. If a bit is - * set, it indicates that an RRset of that type is present for the NSEC - * RR's owner name. If a bit is clear, it indicates that no RRset of - * that type is present for the NSEC RR's owner name. - * - * Bits representing pseudo-types MUST be clear, as they do not appear - * in zone data. If encountered, they MUST be ignored upon being read. - */ -static void -nsec(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), - TEXT_INVALID("."), - TEXT_VALID(". RRSIG"), - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - WIRE_INVALID(0x00), - WIRE_INVALID(0x00, 0x00), - WIRE_INVALID(0x00, 0x00, 0x00), - WIRE_VALID(0x00, 0x00, 0x01, 0x02), - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_nsec, sizeof(dns_rdata_nsec_t)); -} - -/* - * NSEC3 tests. - * - * RFC 5155. - */ -static void -nsec3(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), - TEXT_INVALID("."), - TEXT_INVALID(". RRSIG"), - TEXT_INVALID("1 0 10 76931F"), - TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG&UED541AS"), - TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONGAUED541AS A RRSIG BADTYPE"), - TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM A RRSIG"), - TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM"), - TEXT_VALID("1 0 10 - AJHVGTICN6K0VDA53GCHFMT219SRRQLM"), - TEXT_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, NULL, NULL, false, dns_rdataclass_in, - dns_rdatatype_nsec3, sizeof(dns_rdata_nsec3_t)); -} - -/* NXT RDATA manipulations */ -static void -nxt(void **state) { - compare_ok_t compare_ok[] = { - COMPARE("a. A SIG", "a. A SIG", 0), - /* - * Records that differ only in the case of the next - * name should be equal. - */ - COMPARE("A. A SIG", "a. A SIG", 0), - /* - * Sorting on name field. - */ - COMPARE("A. A SIG", "b. A SIG", -1), - COMPARE("b. A SIG", "A. A SIG", 1), - /* bit map differs */ - COMPARE("b. A SIG", "b. A AAAA SIG", -1), - /* order of bit map does not matter */ - COMPARE("b. A SIG AAAA", "b. A AAAA SIG", 0), - COMPARE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, NULL, compare_ok, false, dns_rdataclass_in, - dns_rdatatype_nxt, sizeof(dns_rdata_nxt_t)); -} - -static void -rkey(void **state) { - text_ok_t text_ok[] = { - /* - * Valid, flags set to 0 and a key is present. - */ - TEXT_VALID("0 0 0 aaaa"), - /* - * Invalid, non-zero flags. - */ - TEXT_INVALID("1 0 0 aaaa"), - TEXT_INVALID("65535 0 0 aaaa"), - /* - * Sentinel. - */ - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Valid, flags set to 0 and a key is present. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Invalid, non-zero flags. - */ - WIRE_INVALID(0x00, 0x01, 0x00, 0x00, 0x00), - WIRE_INVALID(0xff, 0xff, 0x00, 0x00, 0x00), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - key_required(state, dns_rdatatype_rkey, sizeof(dns_rdata_rkey_t)); - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_rkey, sizeof(dns_rdata_rkey_t)); -} - -/* SSHFP RDATA manipulations */ -static void -sshfp(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), /* too short */ - TEXT_INVALID("0"), /* reserved, too short */ - TEXT_VALID("0 0"), /* no finger print */ - TEXT_VALID("0 0 AA"), /* reserved */ - TEXT_INVALID("0 1 AA"), /* too short SHA 1 digest */ - TEXT_INVALID("0 2 AA"), /* too short SHA 256 digest */ - TEXT_VALID("0 3 AA"), /* unknown finger print type */ - /* good length SHA 1 digest */ - TEXT_VALID("1 1 00112233445566778899AABBCCDDEEFF17181920"), - /* good length SHA 256 digest */ - TEXT_VALID("4 2 A87F1B687AC0E57D2A081A2F282672334D90ED316D2B818CA9580EA3 84D92401"), - /* - * totext splits the fingerprint into chunks and - * emits uppercase hex. - */ - TEXT_VALID_CHANGED("1 2 00112233445566778899aabbccddeeff " - "00112233445566778899AABBCCDDEEFF", - "1 2 00112233445566778899AABBCCDDEEFF" - "00112233445566778899AABB CCDDEEFF"), - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - WIRE_INVALID(0x00), /* reserved too short */ - WIRE_VALID(0x00, 0x00), /* reserved no finger print */ - WIRE_VALID(0x00, 0x00, 0x00), /* reserved */ - - /* too short SHA 1 digests */ - WIRE_INVALID(0x00, 0x01), - WIRE_INVALID(0x00, 0x01, 0x00), - WIRE_INVALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19), - /* good length SHA 1 digest */ - WIRE_VALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20), - /* too long SHA 1 digest */ - WIRE_INVALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21), - /* too short SHA 256 digests */ - WIRE_INVALID(0x00, 0x02), - WIRE_INVALID(0x00, 0x02, 0x00), - WIRE_INVALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, - 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, - 0x31), - /* good length SHA 256 digest */ - WIRE_VALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, - 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, - 0x31, 0x32), - /* too long SHA 256 digest */ - WIRE_INVALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, - 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, - 0x31, 0x32, 0x33), - /* unknown digest, * no fingerprint */ - WIRE_VALID(0x00, 0x03), - WIRE_VALID(0x00, 0x03, 0x00), /* unknown digest */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_sshfp, sizeof(dns_rdata_sshfp_t)); -} - -/* - * WKS tests. - * - * RFC 1035: - * - * 3.4.2. WKS RDATA format - * - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | ADDRESS | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | PROTOCOL | | - * +--+--+--+--+--+--+--+--+ | - * | | - * / / - * / / - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * - * where: - * - * ADDRESS An 32 bit Internet address - * - * PROTOCOL An 8 bit IP protocol number - * - * A variable length bit map. The bit map must be a - * multiple of 8 bits long. - * - * The WKS record is used to describe the well known services supported by - * a particular protocol on a particular internet address. The PROTOCOL - * field specifies an IP protocol number, and the bit map has one bit per - * port of the specified protocol. The first bit corresponds to port 0, - * the second to port 1, etc. If the bit map does not include a bit for a - * protocol of interest, that bit is assumed zero. The appropriate values - * and mnemonics for ports and protocols are specified in [RFC-1010]. - * - * For example, if PROTOCOL=TCP (6), the 26th bit corresponds to TCP port - * 25 (SMTP). If this bit is set, a SMTP server should be listening on TCP - * port 25; if zero, SMTP service is not supported on the specified - * address. - */ -static void -wks(void **state) { - wire_ok_t wire_ok[] = { - /* - * Too short. - */ - WIRE_INVALID(0x00, 0x08, 0x00, 0x00), - /* - * Minimal TCP. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x00, 6), - /* - * Minimal UDP. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x00, 17), - /* - * Minimal other. - */ - WIRE_VALID(0x00, 0x08, 0x00, 0x00, 1), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_wks, sizeof(dns_rdata_in_wks_t)); -} - -/* - * ZONEMD tests. - * - * Excerpted from draft-wessels-dns-zone-digest: - * - * The ZONEMD RDATA wire format is encoded as follows: - * - * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Serial | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Digest Type | Reserved | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | - * | Digest | - * / / - * / / - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 2.1.1. The Serial Field - * - * The Serial field is a 32-bit unsigned integer in network order. It - * is equal to the serial number from the zone's SOA record - * - * 2.1.2. The Digest Type Field - * - * The Digest Type field is an 8-bit unsigned integer that identifies - * the algorithm used to construct the digest. - * - * At the time of this writing, SHA384, with value 1, is the only Digest - * Type defined for ZONEMD records. - * - * 2.1.3. The Reserved Field - * - * The Reserved field is an 8-bit unsigned integer, which is always set - * to zero. - * - * 2.1.4. The Digest Field - * - * The Digest field is a variable-length sequence of octets containing - * the message digest. - */ - -static void -zonemd(void **state) { - text_ok_t text_ok[] = { - TEXT_INVALID(""), - TEXT_INVALID("0"), - TEXT_INVALID("0 0"), - TEXT_INVALID("0 0 0"), - TEXT_INVALID("99999999 0 0"), - TEXT_INVALID("2019020700 0 0"), - TEXT_INVALID("2019020700 1 0 DEADBEEF"), - TEXT_VALID("2019020700 2 0 DEADBEEF"), - TEXT_VALID("2019020700 255 0 DEADBEEF"), - TEXT_INVALID("2019020700 256 0 DEADBEEF"), - TEXT_VALID("2019020700 2 255 DEADBEEF"), - TEXT_INVALID("2019020700 2 256 DEADBEEF"), - TEXT_VALID("2019020700 1 0 7162D2BB75C047A53DE98767C9192BEB" - "14DB01E7E2267135DAF0230A 19BA4A31" - "6AF6BF64AA5C7BAE24B2992850300509"), - TEXT_SENTINEL() - }; - wire_ok_t wire_ok[] = { - /* - * Short. - */ - WIRE_INVALID(0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Short. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - /* - * Minimal, one-octet hash for an undefined digest type. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - /* - * SHA-384 is defined, so we insist there be a digest of - * the expected length. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00), - /* - * 48-octet digest, valid for SHA-384. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), - /* - * 56-octet digest, too long for SHA-384. - */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), - /* - * 56-octet digest, valid for an undefined digest type. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, - 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), - /* - * Sentinel. - */ - WIRE_SENTINEL() - }; - - UNUSED(state); - - check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in, - dns_rdatatype_zonemd, sizeof(dns_rdata_zonemd_t)); -} - -static void -atcname(void **state) { - unsigned int i; - UNUSED(state); -#define UNR "# Unexpected result from dns_rdatatype_atcname for type %u\n" - for (i = 0; i < 0xffffU; i++) { - bool tf = dns_rdatatype_atcname((dns_rdatatype_t)i); - switch (i) { - case dns_rdatatype_nsec: - case dns_rdatatype_key: - case dns_rdatatype_rrsig: - if (!tf) { - print_message(UNR, i); - } - assert_true(tf); - break; - default: - if (tf) { - print_message(UNR, i); - } - assert_false(tf); - break; - } - - } -#undef UNR -} - -static void -atparent(void **state) { - unsigned int i; - UNUSED(state); -#define UNR "# Unexpected result from dns_rdatatype_atparent for type %u\n" - for (i = 0; i < 0xffffU; i++) { - bool tf = dns_rdatatype_atparent((dns_rdatatype_t)i); - switch (i) { - case dns_rdatatype_ds: - if (!tf) { - print_message(UNR, i); - } - assert_true(tf); - break; - default: - if (tf) { - print_message(UNR, i); - } - assert_false(tf); - break; - } - - } -#undef UNR -} - -static void -iszonecutauth(void **state) { - unsigned int i; - UNUSED(state); -#define UNR "# Unexpected result from dns_rdatatype_iszonecutauth for type %u\n" - for (i = 0; i < 0xffffU; i++) { - bool tf = dns_rdatatype_iszonecutauth((dns_rdatatype_t)i); - switch (i) { - case dns_rdatatype_ns: - case dns_rdatatype_ds: - case dns_rdatatype_nsec: - case dns_rdatatype_key: - case dns_rdatatype_rrsig: - if (!tf) { - print_message(UNR, i); - } - assert_true(tf); - break; - default: - if (tf) { - print_message(UNR, i); - } - assert_false(tf); - break; - } - - } -#undef UNR -} - -int -main(int argc, char **argv) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(amtrelay, _setup, _teardown), - cmocka_unit_test_setup_teardown(apl, _setup, _teardown), - cmocka_unit_test_setup_teardown(atma, _setup, _teardown), - cmocka_unit_test_setup_teardown(cdnskey, _setup, _teardown), - cmocka_unit_test_setup_teardown(csync, _setup, _teardown), - cmocka_unit_test_setup_teardown(doa, _setup, _teardown), - cmocka_unit_test_setup_teardown(dnskey, _setup, _teardown), - cmocka_unit_test_setup_teardown(ds, _setup, _teardown), - cmocka_unit_test_setup_teardown(eid, _setup, _teardown), - cmocka_unit_test_setup_teardown(edns_client_subnet, - _setup, _teardown), - cmocka_unit_test_setup_teardown(hip, _setup, _teardown), - cmocka_unit_test_setup_teardown(isdn, _setup, _teardown), - cmocka_unit_test_setup_teardown(key, _setup, _teardown), - cmocka_unit_test_setup_teardown(loc, _setup, _teardown), - cmocka_unit_test_setup_teardown(nimloc, _setup, _teardown), - cmocka_unit_test_setup_teardown(nsec, _setup, _teardown), - cmocka_unit_test_setup_teardown(nsec3, _setup, _teardown), - cmocka_unit_test_setup_teardown(nxt, _setup, _teardown), - cmocka_unit_test_setup_teardown(sshfp, _setup, _teardown), - cmocka_unit_test_setup_teardown(wks, _setup, _teardown), - cmocka_unit_test_setup_teardown(rkey, _setup, _teardown), - cmocka_unit_test_setup_teardown(zonemd, _setup, _teardown), - cmocka_unit_test_setup_teardown(atcname, NULL, NULL), - cmocka_unit_test_setup_teardown(atparent, NULL, NULL), - cmocka_unit_test_setup_teardown(iszonecutauth, NULL, NULL), - }; - struct CMUnitTest selected[sizeof(tests) / sizeof(tests[0])]; - size_t i; - int c; - - memset(selected, 0, sizeof(selected)); - - while ((c = isc_commandline_parse(argc, argv, "dlt:")) != -1) { - switch (c) { - case 'd': - debug = true; - break; - case 'l': - for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) - { - if (tests[i].name != NULL) { - fprintf(stdout, "%s\n", tests[i].name); - } - } - return (0); - case 't': - if (!cmocka_add_test_byname( - tests, isc_commandline_argument, selected)) - { - fprintf(stderr, "unknown test '%s'\n", - isc_commandline_argument); - exit(1); - } - break; - default: - break; - } - } - - if (selected[0].name != NULL) { - return (cmocka_run_group_tests(tests, dns_test_init, - dns_test_final)); - } else { - return (cmocka_run_group_tests(tests, dns_test_init, - dns_test_final)); - } -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rdataset_test.c b/lib/dns-pkcs11/tests/rdataset_test.c deleted file mode 100644 index 1134ffc..0000000 --- a/lib/dns-pkcs11/tests/rdataset_test.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include - -#include -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/* test trimming of rdataset TTLs */ -static void -trimttl(void **state) { - dns_rdataset_t rdataset, sigrdataset; - dns_rdata_rrsig_t rrsig; - isc_stdtime_t ttltimenow, ttltimeexpire; - - ttltimenow = 10000000; - ttltimeexpire = ttltimenow + 800; - - UNUSED(state); - - dns_rdataset_init(&rdataset); - dns_rdataset_init(&sigrdataset); - - rdataset.ttl = 900; - sigrdataset.ttl = 1000; - rrsig.timeexpire = ttltimeexpire; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - true); - assert_int_equal(rdataset.ttl, 800); - assert_int_equal(sigrdataset.ttl, 800); - - rdataset.ttl = 900; - sigrdataset.ttl = 1000; - rrsig.timeexpire = ttltimenow - 200; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - true); - assert_int_equal(rdataset.ttl, 120); - assert_int_equal(sigrdataset.ttl, 120); - - rdataset.ttl = 900; - sigrdataset.ttl = 1000; - rrsig.timeexpire = ttltimenow - 200; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - false); - assert_int_equal(rdataset.ttl, 0); - assert_int_equal(sigrdataset.ttl, 0); - - sigrdataset.ttl = 900; - rdataset.ttl = 1000; - rrsig.timeexpire = ttltimeexpire; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - true); - assert_int_equal(rdataset.ttl, 800); - assert_int_equal(sigrdataset.ttl, 800); - - sigrdataset.ttl = 900; - rdataset.ttl = 1000; - rrsig.timeexpire = ttltimenow - 200; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - true); - assert_int_equal(rdataset.ttl, 120); - assert_int_equal(sigrdataset.ttl, 120); - - sigrdataset.ttl = 900; - rdataset.ttl = 1000; - rrsig.timeexpire = ttltimenow - 200; - rrsig.originalttl = 1000; - - dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, - false); - assert_int_equal(rdataset.ttl, 0); - assert_int_equal(sigrdataset.ttl, 0); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(trimttl, _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rdatasetstats_test.c b/lib/dns-pkcs11/tests/rdatasetstats_test.c deleted file mode 100644 index 08c9356..0000000 --- a/lib/dns-pkcs11/tests/rdatasetstats_test.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include - -#include - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static void -set_typestats(dns_stats_t *stats, dns_rdatatype_t type, bool stale) { - dns_rdatastatstype_t which; - unsigned int attributes; - - attributes = 0; - if (stale) { - attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; - } - which = DNS_RDATASTATSTYPE_VALUE(type, attributes); - dns_rdatasetstats_increment(stats, which); - - attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; - if (stale) { - attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; - } - which = DNS_RDATASTATSTYPE_VALUE(type, attributes); - dns_rdatasetstats_increment(stats, which); -} - -static void -set_nxdomainstats(dns_stats_t *stats, bool stale) { - dns_rdatastatstype_t which; - unsigned int attributes; - - attributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN; - if (stale) { - attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; - } - which = DNS_RDATASTATSTYPE_VALUE(0, attributes); - dns_rdatasetstats_increment(stats, which); -} - -#define ATTRIBUTE_SET(y) ((attributes & (y)) != 0) -static void -checkit1(dns_rdatastatstype_t which, uint64_t value, void *arg) { - unsigned int attributes; -#if debug - unsigned int type; -#endif - - UNUSED(which); - UNUSED(arg); - - attributes = DNS_RDATASTATSTYPE_ATTR(which); -#if debug - type = DNS_RDATASTATSTYPE_BASE(which); - - fprintf(stderr, "%s%s%s%s/%u, %u\n", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) ? "O" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_NXRRSET) ? "!" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_STALE) ? "#" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) ? "X" : " ", - type, (unsigned)value); -#endif - if ((attributes & DNS_RDATASTATSTYPE_ATTR_STALE) == 0) { - assert_int_equal(value, 1); - } else { - assert_int_equal(value, 0); - } -} - -static void -checkit2(dns_rdatastatstype_t which, uint64_t value, void *arg) { - unsigned int attributes; -#if debug - unsigned int type; -#endif - - UNUSED(which); - UNUSED(arg); - - attributes = DNS_RDATASTATSTYPE_ATTR(which); -#if debug - type = DNS_RDATASTATSTYPE_BASE(which); - - fprintf(stderr, "%s%s%s%s/%u, %u\n", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) ? "O" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_NXRRSET) ? "!" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_STALE) ? "#" : " ", - ATTRIBUTE_SET(DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) ? "X" : " ", - type, (unsigned)value); -#endif - if ((attributes & DNS_RDATASTATSTYPE_ATTR_STALE) == 0) { - assert_int_equal(value, 0); - } else { - assert_int_equal(value, 1); - } -} -/* - * Individual unit tests - */ - -/* test that rdatasetstats counters are properly set */ -static void -rdatasetstats(void **state) { - unsigned int i; - dns_stats_t *stats = NULL; - isc_result_t result; - - UNUSED(state); - - result = dns_rdatasetstats_create(mctx, &stats); - assert_int_equal(result, ISC_R_SUCCESS); - - /* First 256 types. */ - for (i = 0; i <= 255; i++) - set_typestats(stats, (dns_rdatatype_t)i, false); - /* Specials */ - set_typestats(stats, dns_rdatatype_dlv, false); - set_typestats(stats, (dns_rdatatype_t)1000, false); - set_nxdomainstats(stats, false); - - /* - * Check that all counters are set to appropriately. - */ - dns_rdatasetstats_dump(stats, checkit1, NULL, 1); - - /* First 256 types. */ - for (i = 0; i <= 255; i++) - set_typestats(stats, (dns_rdatatype_t)i, true); - /* Specials */ - set_typestats(stats, dns_rdatatype_dlv, true); - set_typestats(stats, (dns_rdatatype_t)1000, true); - set_nxdomainstats(stats, true); - - /* - * Check that all counters are set to appropriately. - */ - dns_rdatasetstats_dump(stats, checkit2, NULL, 1); - - dns_stats_detach(&stats); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(rdatasetstats, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/resolver_test.c b/lib/dns-pkcs11/tests/resolver_test.c deleted file mode 100644 index 44d1b16..0000000 --- a/lib/dns-pkcs11/tests/resolver_test.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "dnstest.h" - -static dns_dispatchmgr_t *dispatchmgr = NULL; -static dns_dispatch_t *dispatch = NULL; -static dns_view_t *view = NULL; - -static int -_setup(void **state) { - isc_result_t result; - isc_sockaddr_t local; - - UNUSED(state); - - result = dns_test_begin(NULL, true); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_test_makeview("view", &view); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_sockaddr_any(&local); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local, - 4096, 100, 100, 100, 500, 0, 0, - &dispatch); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_dispatch_detach(&dispatch); - dns_view_detach(&view); - dns_dispatchmgr_destroy(&dispatchmgr); - dns_test_end(); - - return (0); -} - - -static void -mkres(dns_resolver_t **resolverp) { - isc_result_t result; - - result = dns_resolver_create(view, taskmgr, 1, 1, - socketmgr, timermgr, 0, - dispatchmgr, dispatch, NULL, resolverp); - assert_int_equal(result, ISC_R_SUCCESS); -} - -static void -destroy_resolver(dns_resolver_t **resolverp) { - dns_resolver_shutdown(*resolverp); - dns_resolver_detach(resolverp); -} - -/* dns_resolver_create */ -static void -create_test(void **state) { - dns_resolver_t *resolver = NULL; - - UNUSED(state); - - mkres(&resolver); - destroy_resolver(&resolver); -} - -/* dns_resolver_gettimeout */ -static void -gettimeout_test(void **state) { - dns_resolver_t *resolver = NULL; - unsigned int timeout; - - UNUSED(state); - - mkres(&resolver); - - timeout = dns_resolver_gettimeout(resolver); - assert_true(timeout > 0); - - destroy_resolver(&resolver); -} - -/* dns_resolver_settimeout */ -static void -settimeout_test(void **state) { - dns_resolver_t *resolver = NULL; - unsigned int default_timeout, timeout; - - UNUSED(state); - - - mkres(&resolver); - - default_timeout = dns_resolver_gettimeout(resolver); - dns_resolver_settimeout(resolver, default_timeout + 1); - timeout = dns_resolver_gettimeout(resolver); - assert_true(timeout == default_timeout + 1); - - destroy_resolver(&resolver); -} - -/* dns_resolver_settimeout */ -static void -settimeout_default_test(void **state) { - dns_resolver_t *resolver = NULL; - unsigned int default_timeout, timeout; - - UNUSED(state); - - - mkres(&resolver); - - default_timeout = dns_resolver_gettimeout(resolver); - dns_resolver_settimeout(resolver, default_timeout + 10); - - timeout = dns_resolver_gettimeout(resolver); - assert_int_equal(timeout, default_timeout + 10); - - dns_resolver_settimeout(resolver, 0); - timeout = dns_resolver_gettimeout(resolver); - assert_int_equal(timeout, default_timeout); - - destroy_resolver(&resolver); -} - -/* dns_resolver_settimeout below minimum */ -static void -settimeout_belowmin_test(void **state) { - dns_resolver_t *resolver = NULL; - unsigned int default_timeout, timeout; - - UNUSED(state); - - - mkres(&resolver); - - default_timeout = dns_resolver_gettimeout(resolver); - dns_resolver_settimeout(resolver, 9); - - timeout = dns_resolver_gettimeout(resolver); - assert_int_equal(timeout, default_timeout); - - destroy_resolver(&resolver); -} - -/* dns_resolver_settimeout over maximum */ -static void -settimeout_overmax_test(void **state) { - dns_resolver_t *resolver = NULL; - unsigned int timeout; - - UNUSED(state); - - - mkres(&resolver); - - dns_resolver_settimeout(resolver, 4000000); - timeout = dns_resolver_gettimeout(resolver); - assert_in_range(timeout, 0, 3999999); - destroy_resolver(&resolver); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(create_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(gettimeout_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(settimeout_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(settimeout_default_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(settimeout_belowmin_test, - _setup, _teardown), - cmocka_unit_test_setup_teardown(settimeout_overmax_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/result_test.c b/lib/dns-pkcs11/tests/result_test.c deleted file mode 100644 index 61fdcb6..0000000 --- a/lib/dns-pkcs11/tests/result_test.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include -#include -#include - -/* - * Check ids array is populated. - */ -static void -ids(void **state) { - const char *str; - isc_result_t result; - - UNUSED(state); - - dns_result_register(); - dst_result_register(); - - for (result = ISC_RESULTCLASS_DNS; - result < (ISC_RESULTCLASS_DNS + DNS_R_NRESULTS); - result++) - { - str = isc_result_toid(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - } - - str = isc_result_toid(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); - - for (result = ISC_RESULTCLASS_DST; - result < (ISC_RESULTCLASS_DST + DST_R_NRESULTS); - result++) - { - str = isc_result_toid(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - } - - str = isc_result_toid(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); - - for (result = ISC_RESULTCLASS_DNSRCODE; - result < (ISC_RESULTCLASS_DNSRCODE + DNS_R_NRCODERESULTS); - result++) - { - str = isc_result_toid(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_not_equal(str, - "(result code text not available)"); - } - - str = isc_result_toid(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); - - str = isc_result_totext(result); - assert_non_null(str); - assert_string_equal(str, "(result code text not available)"); -} - -int -main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(ids), - }; - - return (cmocka_run_group_tests(tests, NULL, NULL)); -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/rsa_test.c b/lib/dns-pkcs11/tests/rsa_test.c deleted file mode 100644 index 6a9635b..0000000 --- a/lib/dns-pkcs11/tests/rsa_test.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - - -#include - -#if HAVE_CMOCKA - -#include -#include -#include - -#include /* IWYU pragma: keep */ -#include -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include - -#include - -#include "dnstest.h" - -#include "../dst_internal.h" - -#if defined(OPENSSL) || defined(PKCS11CRYPTO) -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -static unsigned char d[10] = { - 0xa, 0x10, 0xbb, 0, 0xfe, 0x15, 0x1, 0x88, 0xcc, 0x7d -}; - -static unsigned char sigsha1[256] = { - 0x45, 0x55, 0xd6, 0xf8, 0x05, 0xd2, 0x2e, 0x79, - 0x14, 0x2b, 0x1b, 0xd1, 0x4b, 0xb7, 0xcd, 0xc0, - 0xa2, 0xf3, 0x85, 0x32, 0x1f, 0xa3, 0xfd, 0x1f, - 0x30, 0xe0, 0xde, 0xb2, 0x6f, 0x3c, 0x8e, 0x2b, - 0x82, 0x92, 0xcd, 0x1c, 0x1b, 0xdf, 0xe6, 0xd5, - 0x4d, 0x93, 0xe6, 0xaa, 0x40, 0x28, 0x1b, 0x7b, - 0x2e, 0x40, 0x4d, 0xb5, 0x4d, 0x43, 0xe8, 0xfc, - 0x93, 0x86, 0x68, 0xe3, 0xbf, 0x73, 0x9a, 0x1e, - 0x6b, 0x5d, 0x52, 0xb8, 0x98, 0x1c, 0x94, 0xe1, - 0x85, 0x8b, 0xee, 0xb1, 0x4f, 0x22, 0x71, 0xcb, - 0xfd, 0xb2, 0xa8, 0x88, 0x64, 0xb4, 0xb1, 0x4a, - 0xa1, 0x7a, 0xce, 0x52, 0x83, 0xd8, 0xf2, 0x9e, - 0x67, 0x4c, 0xc3, 0x37, 0x74, 0xfe, 0xe0, 0x25, - 0x2a, 0xfd, 0xa3, 0x09, 0xff, 0x8a, 0x92, 0x0d, - 0xa9, 0xb3, 0x90, 0x23, 0xbe, 0x6a, 0x2c, 0x9e, - 0x5c, 0x6d, 0xb4, 0xa7, 0xd7, 0x97, 0xdd, 0xc6, - 0xb8, 0xae, 0xd4, 0x88, 0x64, 0x63, 0x1e, 0x85, - 0x20, 0x09, 0xea, 0xc4, 0x0b, 0xca, 0xbf, 0x83, - 0x5c, 0x89, 0xae, 0x64, 0x15, 0x76, 0x06, 0x51, - 0xb6, 0xa1, 0x99, 0xb2, 0x3c, 0x50, 0x99, 0x86, - 0x7d, 0xc7, 0xca, 0x4e, 0x1d, 0x2c, 0x17, 0xbb, - 0x6c, 0x7a, 0xc9, 0x3f, 0x5e, 0x28, 0x57, 0x2c, - 0xda, 0x01, 0x1d, 0xe8, 0x01, 0xf8, 0xf6, 0x37, - 0xe1, 0x34, 0x56, 0xae, 0x6e, 0xb1, 0xd4, 0xa2, - 0xc4, 0x02, 0xc1, 0xca, 0x96, 0xb0, 0x06, 0x72, - 0x2a, 0x27, 0xaa, 0xc8, 0xd5, 0x50, 0x81, 0x49, - 0x46, 0x33, 0xf8, 0xf7, 0x6b, 0xf4, 0x9c, 0x30, - 0x90, 0x50, 0xf6, 0x16, 0x76, 0x9d, 0xc6, 0x73, - 0xb5, 0xbc, 0x8a, 0xb6, 0x1d, 0x98, 0xcb, 0xce, - 0x36, 0x6f, 0x60, 0xec, 0x96, 0x49, 0x08, 0x85, - 0x5b, 0xc1, 0x8e, 0xb0, 0xea, 0x9e, 0x1f, 0xd6, - 0x27, 0x7f, 0xb6, 0xe0, 0x04, 0x12, 0xd2, 0x81 -}; - -#ifndef PK11_MD5_DISABLE -static unsigned char sigmd5[256] = { - 0xc0, 0x99, 0x90, 0xd6, 0xea, 0xc1, 0x5f, 0xc7, - 0x23, 0x60, 0xfc, 0x13, 0x3d, 0xcc, 0xda, 0x93, - 0x19, 0xf7, 0x22, 0xa9, 0x55, 0xbe, 0x70, 0x3c, - 0x87, 0x24, 0x8a, 0x7e, 0xa7, 0x59, 0x58, 0xd3, - 0x0e, 0x7c, 0x50, 0x3c, 0x81, 0x0f, 0x7a, 0x2b, - 0xb1, 0x94, 0x21, 0x87, 0xe4, 0x87, 0xcd, 0x2b, - 0xb9, 0xf1, 0xb8, 0x26, 0xc1, 0x02, 0xf4, 0x30, - 0x83, 0x41, 0x89, 0x61, 0xcc, 0x3d, 0xe3, 0x0f, - 0xec, 0x4a, 0x74, 0x95, 0x10, 0x65, 0xac, 0xd1, - 0xf5, 0x95, 0xe9, 0x99, 0xa8, 0x45, 0x98, 0x99, - 0xb5, 0xfd, 0x7a, 0x78, 0x80, 0xe5, 0x00, 0x33, - 0xa5, 0x54, 0xe5, 0xa3, 0xc0, 0x1b, 0x6c, 0xb9, - 0x77, 0x52, 0x6f, 0xe5, 0x85, 0xa8, 0xfa, 0x45, - 0x78, 0x49, 0x14, 0xa0, 0x10, 0x58, 0x40, 0x80, - 0x90, 0xc6, 0x55, 0x52, 0x6d, 0x46, 0x58, 0x50, - 0x3d, 0x5e, 0x40, 0x25, 0x51, 0x7c, 0xc4, 0x12, - 0x87, 0x2d, 0x7b, 0x10, 0xcd, 0x80, 0xec, 0x5d, - 0x27, 0x15, 0x09, 0x37, 0x1f, 0xa7, 0x86, 0x15, - 0xd1, 0xdd, 0xf1, 0x86, 0x1e, 0x42, 0x3a, 0xf9, - 0x5a, 0xed, 0x33, 0x07, 0xa9, 0x98, 0x08, 0x79, - 0xc5, 0xa4, 0x09, 0x95, 0x6e, 0x12, 0xfe, 0xee, - 0x49, 0x61, 0xe0, 0x99, 0xaa, 0x34, 0xa5, 0xca, - 0x82, 0xd3, 0x9b, 0x1c, 0x5b, 0x79, 0xf5, 0x0e, - 0x2c, 0x6c, 0x3b, 0x48, 0xd1, 0xbc, 0xd0, 0xda, - 0x73, 0xba, 0xe1, 0x81, 0x48, 0x27, 0x39, 0x2f, - 0x98, 0x77, 0x08, 0xb3, 0xf7, 0x38, 0x28, 0x6d, - 0x02, 0x56, 0xfa, 0x31, 0xbb, 0x14, 0x81, 0x6b, - 0x3c, 0x24, 0xa2, 0x68, 0x7a, 0x0a, 0x53, 0xbd, - 0x9d, 0x57, 0xd0, 0x99, 0x10, 0x28, 0x78, 0x69, - 0x31, 0x93, 0xa4, 0x73, 0x8d, 0x1a, 0xe4, 0xdc, - 0x0c, 0x15, 0xb8, 0x51, 0xd8, 0x66, 0x6a, 0x95, - 0x56, 0x17, 0x0a, 0x45, 0x72, 0xb5, 0xb8, 0xc4 -}; -#endif - -static unsigned char sigsha256[256] = { - 0x83, 0x53, 0x15, 0xfc, 0xca, 0xdb, 0xf6, 0x0d, - 0x53, 0x24, 0x5b, 0x5a, 0x8e, 0xd0, 0xbe, 0x5e, - 0xbc, 0xe8, 0x9e, 0x92, 0x3c, 0xfa, 0x93, 0x03, - 0xce, 0x2f, 0xc7, 0x6d, 0xd0, 0xbb, 0x9d, 0x06, - 0x83, 0xc6, 0xd3, 0xc0, 0xc1, 0x57, 0x9c, 0x82, - 0x17, 0x7f, 0xb5, 0xf8, 0x31, 0x18, 0xda, 0x46, - 0x05, 0x2c, 0xf8, 0xea, 0xaa, 0xcd, 0x99, 0x18, - 0xff, 0x23, 0x5e, 0xef, 0xf0, 0x87, 0x47, 0x6e, - 0x91, 0xfd, 0x19, 0x0b, 0x39, 0x19, 0x6a, 0xc8, - 0xdf, 0x71, 0x66, 0x8e, 0xa9, 0xa0, 0x79, 0x5c, - 0x2c, 0x52, 0x00, 0x61, 0x17, 0x86, 0x66, 0x03, - 0x52, 0xad, 0xec, 0x06, 0x53, 0xd9, 0x6d, 0xe3, - 0xe3, 0xea, 0x28, 0x15, 0xb3, 0x75, 0xf4, 0x61, - 0x7d, 0xed, 0x69, 0x2c, 0x24, 0xf3, 0x21, 0xb1, - 0x8a, 0xea, 0x60, 0xa2, 0x9e, 0x6a, 0xa6, 0x53, - 0x12, 0xf6, 0x5c, 0xef, 0xd7, 0x49, 0x4a, 0x02, - 0xe7, 0xf8, 0x64, 0x89, 0x13, 0xac, 0xd5, 0x1e, - 0x58, 0xff, 0xa1, 0x63, 0xdd, 0xa0, 0x1f, 0x44, - 0x99, 0x6a, 0x59, 0x7f, 0x35, 0xbd, 0xf1, 0xf3, - 0x7a, 0x28, 0x44, 0xe3, 0x4c, 0x68, 0xb1, 0xb3, - 0x97, 0x3c, 0x46, 0xe3, 0xc2, 0x12, 0x9e, 0x68, - 0x0b, 0xa6, 0x6c, 0x8f, 0x58, 0x48, 0x44, 0xa4, - 0xf7, 0xa7, 0xc2, 0x91, 0x8f, 0xbf, 0x00, 0xd0, - 0x01, 0x35, 0xd4, 0x86, 0x6e, 0x1f, 0xea, 0x42, - 0x60, 0xb1, 0x84, 0x27, 0xf4, 0x99, 0x36, 0x06, - 0x98, 0x12, 0x83, 0x32, 0x9f, 0xcd, 0x50, 0x5a, - 0x5e, 0xb8, 0x8e, 0xfe, 0x8d, 0x8d, 0x33, 0x2d, - 0x45, 0xe1, 0xc9, 0xdf, 0x2a, 0xd8, 0x38, 0x1d, - 0x95, 0xd4, 0x42, 0xee, 0x93, 0x5b, 0x0f, 0x1e, - 0x07, 0x06, 0x3a, 0x92, 0xf1, 0x59, 0x1d, 0x6e, - 0x1c, 0x31, 0xf3, 0xce, 0xa9, 0x1f, 0xad, 0x4d, - 0x76, 0x4d, 0x24, 0x98, 0xe2, 0x0e, 0x8c, 0x35 -}; - -static unsigned char sigsha512[512] = { - 0x4e, 0x2f, 0x63, 0x42, 0xc5, 0xf3, 0x05, 0x4a, - 0xa6, 0x3a, 0x93, 0xa0, 0xd9, 0x33, 0xa0, 0xd1, - 0x46, 0x33, 0x42, 0xe8, 0x74, 0xeb, 0x3b, 0x10, - 0x82, 0xd7, 0xcf, 0x39, 0x23, 0xb3, 0xe9, 0x23, - 0x53, 0x87, 0x8c, 0xee, 0x78, 0xcb, 0xb3, 0xd9, - 0xd2, 0x6d, 0x1a, 0x7c, 0x01, 0x4f, 0xed, 0x8d, - 0xf2, 0x72, 0xe4, 0x6a, 0x00, 0x8a, 0x60, 0xa6, - 0xd5, 0x9c, 0x43, 0x6c, 0xef, 0x38, 0x0c, 0x74, - 0x82, 0x5d, 0x22, 0xaa, 0x87, 0x81, 0x90, 0x9c, - 0x64, 0x07, 0x9b, 0x13, 0x51, 0xe0, 0xa5, 0xc2, - 0x83, 0x78, 0x2b, 0x9b, 0xb3, 0x8a, 0x9d, 0x36, - 0x33, 0xbd, 0x0d, 0x53, 0x84, 0xae, 0xe8, 0x13, - 0x36, 0xf6, 0xdf, 0x96, 0xe9, 0xda, 0xc3, 0xd7, - 0xa9, 0x2f, 0xf3, 0x5e, 0x5f, 0x1f, 0x7f, 0x38, - 0x7e, 0x8d, 0xbe, 0x90, 0x5e, 0x13, 0xb2, 0x20, - 0xbb, 0x9d, 0xfe, 0xe1, 0x52, 0xce, 0xe6, 0x80, - 0xa7, 0x95, 0x24, 0x59, 0xe3, 0xac, 0x24, 0xc4, - 0xfa, 0x1c, 0x44, 0x34, 0x29, 0x8d, 0xb1, 0xd0, - 0xd9, 0x4c, 0xff, 0xc4, 0xdb, 0xca, 0xc4, 0x3f, - 0x38, 0xf9, 0xe4, 0xaf, 0x75, 0x0a, 0x67, 0x4d, - 0xa0, 0x2b, 0xb0, 0x83, 0xce, 0x53, 0xc4, 0xb9, - 0x2e, 0x61, 0xb6, 0x64, 0xe5, 0xb5, 0xe5, 0xac, - 0x9d, 0x51, 0xec, 0x58, 0x42, 0x90, 0x78, 0xf6, - 0x46, 0x96, 0xef, 0xb6, 0x97, 0xb7, 0x54, 0x28, - 0x1a, 0x4c, 0x29, 0xf4, 0x7a, 0x33, 0xc6, 0x07, - 0xfd, 0xec, 0x97, 0x36, 0x1d, 0x42, 0x88, 0x94, - 0x27, 0xc2, 0xa3, 0xe1, 0xd4, 0x87, 0xa1, 0x8a, - 0x2b, 0xff, 0x47, 0x60, 0xfe, 0x1f, 0xaf, 0xc2, - 0xeb, 0x17, 0xdd, 0x56, 0xc5, 0x94, 0x5c, 0xcb, - 0x23, 0xe5, 0x49, 0x4d, 0x99, 0x06, 0x02, 0x5a, - 0xfc, 0xfc, 0xdc, 0xee, 0x49, 0xbc, 0x47, 0x60, - 0xff, 0x6a, 0x63, 0x8b, 0xe1, 0x2e, 0xa3, 0xa7 -}; - -/* RSA verify */ -static void -isc_rsa_verify_test(void **state) { - isc_result_t ret; - dns_fixedname_t fname; - isc_buffer_t buf; - dns_name_t *name; - dst_key_t *key = NULL; - dst_context_t *ctx = NULL; - isc_region_t r; - - UNUSED(state); - - name = dns_fixedname_initname(&fname); - isc_buffer_constinit(&buf, "rsa.", 4); - isc_buffer_add(&buf, 4); - ret = dns_name_fromtext(name, &buf, NULL, 0, NULL); - assert_int_equal(ret, ISC_R_SUCCESS); - - ret = dst_key_fromfile(name, 29235, DST_ALG_RSASHA1, - DST_TYPE_PUBLIC, "./", mctx, &key); - assert_int_equal(ret, ISC_R_SUCCESS); - - /* RSASHA1 */ - - ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, - false, &ctx); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = d; - r.length = 10; - ret = dst_context_adddata(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = sigsha1; - r.length = 256; - ret = dst_context_verify(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - dst_context_destroy(&ctx); - - /* RSAMD5 */ - -#ifndef PK11_MD5_DISABLE - if (isc_md5_available()) { - /* wrong indentation is kept for diff minimization */ - key->key_alg = DST_ALG_RSAMD5; - - ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, - false, &ctx); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = d; - r.length = 10; - ret = dst_context_adddata(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = sigmd5; - r.length = 256; - ret = dst_context_verify(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - dst_context_destroy(&ctx); - } -#endif - - /* RSASHA256 */ - - key->key_alg = DST_ALG_RSASHA256; - - ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, - false, &ctx); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = d; - r.length = 10; - ret = dst_context_adddata(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = sigsha256; - r.length = 256; - ret = dst_context_verify(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - dst_context_destroy(&ctx); - - /* RSASHA512 */ - - key->key_alg = DST_ALG_RSASHA512; - - ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, - false, &ctx); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = d; - r.length = 10; - ret = dst_context_adddata(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - r.base = sigsha512; - r.length = 256; - ret = dst_context_verify(ctx, &r); - assert_int_equal(ret, ISC_R_SUCCESS); - - dst_context_destroy(&ctx); - - - dst_key_free(&key); -} -#endif - -int -main(void) { -#if defined(OPENSSL) || defined(PKCS11CRYPTO) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(isc_rsa_verify_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - print_message("1..0 # Skipped: RSA not available\n"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/sigs_test.c b/lib/dns-pkcs11/tests/sigs_test.c deleted file mode 100644 index e093bbd..0000000 --- a/lib/dns-pkcs11/tests/sigs_test.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -#include - -#if HAVE_CMOCKA - -#include -#include -#include -#include - -#if defined(OPENSSL) || defined(PKCS11CRYPTO) -#include /* IWYU pragma: keep */ -#include -#include -#include - -#define UNIT_TESTING -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../zone_p.h" - -#include "dnstest.h" - -static int -_setup(void **state) { - isc_result_t result; - - UNUSED(state); - - result = dns_test_begin(NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - return (0); -} - -static int -_teardown(void **state) { - UNUSED(state); - - dns_test_end(); - - return (0); -} - -/*% - * Structure characterizing a single diff tuple in the dns_diff_t structure - * prepared by dns__zone_updatesigs(). - */ -typedef struct { - dns_diffop_t op; - const char *owner; - dns_ttl_t ttl; - const char *type; -} zonediff_t; - -#define ZONEDIFF_SENTINEL { 0, NULL, 0, NULL } - -/*% - * Structure defining a dns__zone_updatesigs() test. - */ -typedef struct { - const char *description; /* test description */ - const zonechange_t *changes; /* array of "raw" zone changes */ - const zonediff_t *zonediff; /* array of "processed" zone changes */ -} updatesigs_test_params_t; - -/*% - * Check whether the 'found' tuple matches the 'expected' tuple. 'found' is - * the 'idx'th tuple output by dns__zone_updatesigs() in test 'test'. - */ -static void -compare_tuples(const zonediff_t *expected, dns_difftuple_t *found, - size_t idx) -{ - char found_covers[DNS_RDATATYPE_FORMATSIZE] = { }; - char found_type[DNS_RDATATYPE_FORMATSIZE] = { }; - char found_name[DNS_NAME_FORMATSIZE]; - isc_consttextregion_t typeregion; - dns_fixedname_t expected_fname; - dns_rdatatype_t expected_type; - dns_name_t *expected_name; - dns_rdata_rrsig_t rrsig; - isc_buffer_t typebuf; - isc_result_t result; - - REQUIRE(expected != NULL); - REQUIRE(found != NULL); - REQUIRE(idx > 0); - - /* - * Check operation. - */ - assert_int_equal(expected->op, found->op); - - /* - * Check owner name. - */ - expected_name = dns_fixedname_initname(&expected_fname); - result = dns_name_fromstring(expected_name, expected->owner, 0, mctx); - assert_int_equal(result, ISC_R_SUCCESS); - dns_name_format(&found->name, found_name, sizeof(found_name)); - assert_true(dns_name_equal(expected_name, &found->name)); - - /* - * Check TTL. - */ - assert_int_equal(expected->ttl, found->ttl); - - /* - * Parse expected RR type. - */ - typeregion.base = expected->type; - typeregion.length = strlen(expected->type); - result = dns_rdatatype_fromtext(&expected_type, - (isc_textregion_t*)&typeregion); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Format found RR type for reporting purposes. - */ - isc_buffer_init(&typebuf, found_type, sizeof(found_type)); - result = dns_rdatatype_totext(found->rdata.type, &typebuf); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Check RR type. - */ - switch (expected->op) { - case DNS_DIFFOP_ADDRESIGN: - case DNS_DIFFOP_DELRESIGN: - /* - * Found tuple must be of type RRSIG. - */ - assert_int_equal(found->rdata.type, dns_rdatatype_rrsig); - if (found->rdata.type != dns_rdatatype_rrsig) { - break; - } - /* - * The signature must cover an RRset of type 'expected->type'. - */ - result = dns_rdata_tostruct(&found->rdata, &rrsig, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - isc_buffer_init(&typebuf, found_covers, sizeof(found_covers)); - result = dns_rdatatype_totext(rrsig.covered, &typebuf); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(expected_type, rrsig.covered); - break; - default: - /* - * Found tuple must be of type 'expected->type'. - */ - assert_int_equal(expected_type, found->rdata.type); - break; - } -} - -/*% - * Perform a single dns__zone_updatesigs() test defined in 'test'. All other - * arguments are expected to remain constant between subsequent invocations of - * this function. - */ -static void -updatesigs_test(const updatesigs_test_params_t *test, dns_zone_t *zone, - dns_db_t *db, dst_key_t *zone_keys[], unsigned int nkeys, - isc_stdtime_t now) -{ - size_t tuples_expected, tuples_found, idx; - dns_dbversion_t *version = NULL; - dns_diff_t raw_diff, zone_diff; - const zonediff_t *expected; - dns_difftuple_t *found; - isc_result_t result; - - dns__zonediff_t zonediff = { - .diff = &zone_diff, - .offline = false, - }; - - REQUIRE(test != NULL); - REQUIRE(test->description != NULL); - REQUIRE(test->changes != NULL); - REQUIRE(zone != NULL); - REQUIRE(db != NULL); - REQUIRE(zone_keys != NULL); - - /* - * Create a new version of the zone's database. - */ - result = dns_db_newversion(db, &version); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Create a diff representing the supplied changes. - */ - result = dns_test_difffromchanges(&raw_diff, test->changes, false); - assert_int_equal(result, ISC_R_SUCCESS); - - /* - * Apply the "raw" diff to the new version of the zone's database as - * this is what dns__zone_updatesigs() expects to happen before it is - * called. - */ - dns_diff_apply(&raw_diff, db, version); - - /* - * Initialize the structure dns__zone_updatesigs() will modify. - */ - dns_diff_init(mctx, &zone_diff); - - /* - * Check whether dns__zone_updatesigs() behaves as expected. - */ - result = dns__zone_updatesigs(&raw_diff, db, version, zone_keys, nkeys, - zone, now - 3600, now + 3600, now, - true, false, &zonediff); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(ISC_LIST_EMPTY(raw_diff.tuples)); - assert_false(ISC_LIST_EMPTY(zone_diff.tuples)); - - /* - * Ensure that the number of tuples in the zone diff is as expected. - */ - - tuples_expected = 0; - for (expected = test->zonediff; expected->owner != NULL; expected++) { - tuples_expected++; - } - - tuples_found = 0; - for (found = ISC_LIST_HEAD(zone_diff.tuples); - found != NULL; - found = ISC_LIST_NEXT(found, link)) - { - tuples_found++; - } - - assert_int_equal(tuples_expected, tuples_found); - - /* - * Ensure that every tuple in the zone diff matches expectations. - */ - expected = test->zonediff; - idx = 1; - for (found = ISC_LIST_HEAD(zone_diff.tuples); - found != NULL; - found = ISC_LIST_NEXT(found, link)) - { - compare_tuples(expected, found, idx); - expected++; - idx++; - } - - /* - * Apply changes to zone database contents and clean up. - */ - dns_db_closeversion(db, &version, true); - dns_diff_clear(&zone_diff); - dns_diff_clear(&raw_diff); -} - -/* dns__zone_updatesigs() tests */ -static void -updatesigs_next_test(void **state) { - dst_key_t *zone_keys[DNS_MAXZONEKEYS]; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - isc_result_t result; - unsigned int nkeys; - isc_stdtime_t now; - size_t i; - - UNUSED(state); - - /* - * Prepare a zone along with its signing keys. - */ - - result = dns_test_makezone("example", &zone, NULL, false); - assert_int_equal(result, ISC_R_SUCCESS); - - result = dns_test_loaddb(&db, dns_dbtype_zone, "example", - "testdata/master/master18.data"); - assert_int_equal(result, DNS_R_SEENINCLUDE); - - result = dns_zone_setkeydirectory(zone, "testkeys"); - assert_int_equal(result, ISC_R_SUCCESS); - - isc_stdtime_get(&now); - result = dns__zone_findkeys(zone, db, NULL, now, mctx, DNS_MAXZONEKEYS, - zone_keys, &nkeys); - assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(nkeys, 2); - - /* - * Define the tests to be run. Note that changes to zone database - * contents introduced by each test are preserved between tests. - */ - - const zonechange_t changes_add[] = { - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT", "foo" }, - { DNS_DIFFOP_ADD, "bar.example", 600, "TXT", "bar" }, - ZONECHANGE_SENTINEL, - }; - const zonediff_t zonediff_add[] = { - { DNS_DIFFOP_ADDRESIGN, "foo.example", 300, "TXT" }, - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT" }, - { DNS_DIFFOP_ADDRESIGN, "bar.example", 600, "TXT" }, - { DNS_DIFFOP_ADD, "bar.example", 600, "TXT" }, - ZONEDIFF_SENTINEL, - }; - const updatesigs_test_params_t test_add = { - .description = "add new RRsets", - .changes = changes_add, - .zonediff = zonediff_add, - }; - - const zonechange_t changes_append[] = { - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT", "foo1" }, - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT", "foo2" }, - ZONECHANGE_SENTINEL, - }; - const zonediff_t zonediff_append[] = { - { DNS_DIFFOP_DELRESIGN, "foo.example", 300, "TXT" }, - { DNS_DIFFOP_ADDRESIGN, "foo.example", 300, "TXT" }, - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT" }, - { DNS_DIFFOP_ADD, "foo.example", 300, "TXT" }, - ZONEDIFF_SENTINEL, - }; - const updatesigs_test_params_t test_append = { - .description = "append multiple RRs to an existing RRset", - .changes = changes_append, - .zonediff = zonediff_append, - }; - - const zonechange_t changes_replace[] = { - { DNS_DIFFOP_DEL, "bar.example", 600, "TXT", "bar" }, - { DNS_DIFFOP_ADD, "bar.example", 600, "TXT", "rab" }, - ZONECHANGE_SENTINEL, - }; - const zonediff_t zonediff_replace[] = { - { DNS_DIFFOP_DELRESIGN, "bar.example", 600, "TXT" }, - { DNS_DIFFOP_ADDRESIGN, "bar.example", 600, "TXT" }, - { DNS_DIFFOP_DEL, "bar.example", 600, "TXT" }, - { DNS_DIFFOP_ADD, "bar.example", 600, "TXT" }, - ZONEDIFF_SENTINEL, - }; - const updatesigs_test_params_t test_replace = { - .description = "replace an existing RRset", - .changes = changes_replace, - .zonediff = zonediff_replace, - }; - - const zonechange_t changes_delete[] = { - { DNS_DIFFOP_DEL, "bar.example", 600, "TXT", "rab" }, - ZONECHANGE_SENTINEL, - }; - const zonediff_t zonediff_delete[] = { - { DNS_DIFFOP_DELRESIGN, "bar.example", 600, "TXT" }, - { DNS_DIFFOP_DEL, "bar.example", 600, "TXT" }, - ZONEDIFF_SENTINEL, - }; - const updatesigs_test_params_t test_delete = { - .description = "delete an existing RRset", - .changes = changes_delete, - .zonediff = zonediff_delete, - }; - - const zonechange_t changes_mixed[] = { - { DNS_DIFFOP_ADD, "baz.example", 900, "TXT", "baz1" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "A", "127.0.0.1" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "TXT", "baz2" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "AAAA", "::1" }, - ZONECHANGE_SENTINEL, - }; - const zonediff_t zonediff_mixed[] = { - { DNS_DIFFOP_ADDRESIGN, "baz.example", 900, "TXT" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "TXT" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "TXT" }, - { DNS_DIFFOP_ADDRESIGN, "baz.example", 900, "A" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "A" }, - { DNS_DIFFOP_ADDRESIGN, "baz.example", 900, "AAAA" }, - { DNS_DIFFOP_ADD, "baz.example", 900, "AAAA" }, - ZONEDIFF_SENTINEL, - }; - const updatesigs_test_params_t test_mixed = { - .description = "add different RRsets with common owner name", - .changes = changes_mixed, - .zonediff = zonediff_mixed, - }; - - const updatesigs_test_params_t *tests[] = { - &test_add, - &test_append, - &test_replace, - &test_delete, - &test_mixed, - }; - - /* - * Run tests. - */ - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - updatesigs_test(tests[i], zone, db, zone_keys, nkeys, now); - } - - /* - * Clean up. - */ - for (i = 0; i < nkeys; i++) { - dst_key_free(&zone_keys[i]); - } - dns_db_detach(&db); - dns_zone_detach(&zone); -} -#endif - -int -main(void) { -#if defined(OPENSSL) || defined(PKCS11CRYPTO) - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(updatesigs_next_test, - _setup, _teardown), - }; - - return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final)); -#else - printf("1..0 # Skipped: sigs test requires crypto\n"); -#endif -} - -#else /* HAVE_CMOCKA */ - -#include - -int -main(void) { - printf("1..0 # Skipped: cmocka not available\n"); - return (0); -} - -#endif diff --git a/lib/dns-pkcs11/tests/testdata/db/data.db b/lib/dns-pkcs11/tests/testdata/db/data.db deleted file mode 100644 index dddc3d4..0000000 --- a/lib/dns-pkcs11/tests/testdata/db/data.db +++ /dev/null @@ -1,20 +0,0 @@ -; Copyright (C) Internet Systems Consortium, Inc. ("ISC") -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, you can obtain one at https://mozilla.org/MPL/2.0/. -; -; See the COPYRIGHT file distributed with this work for additional -; information regarding copyright ownership. - -$TTL 1000 -@ in soa localhost. postmaster.localhost. ( - 1993050801 ;serial - 3600 ;refresh - 1800 ;retry - 604800 ;expiration - 3600 ) ;minimum -a in ns ns.vix.com. -a in ns ns2.vix.com. -a in ns ns3.vix.com. -b in a 1.2.3.4 diff --git a/lib/dns-pkcs11/tests/testdata/dbiterator/zone1.data b/lib/dns-pkcs11/tests/testdata/dbiterator/zone1.data deleted file mode 100644 index c380d39..0000000 --- a/lib/dns-pkcs11/tests/testdata/dbiterator/zone1.data +++ /dev/null @@ -1,30 +0,0 @@ -; Copyright (C) Internet Systems Consortium, Inc. ("ISC") -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, you can obtain one at https://mozilla.org/MPL/2.0/. -; -; See the COPYRIGHT file distributed with this work for additional -; information regarding copyright ownership. - -$TTL 600 -@ in soa localhost. postmaster.localhost. ( - 2011080901 ;serial - 3600 ;refresh - 1800 ;retry - 604800 ;expiration - 600 ) ;minimum - in ns ns - in ns ns2 -ns in a 10.0.0.1 -ns2 in a 10.0.0.2 - -a in txt "test" -b in txt "test" -c in txt "test" -d.e.f in txt "test" -e in txt "test" -f.g.h in txt "test" -f.g.i in txt "test" -f.g.j in txt "test" -k in txt "test" diff --git a/lib/dns-pkcs11/tests/testdata/dbiterator/zone2.data b/lib/dns-pkcs11/tests/testdata/dbiterator/zone2.data deleted file mode 100644 index 7265c27..0000000 --- a/lib/dns-pkcs11/tests/testdata/dbiterator/zone2.data +++ /dev/null @@ -1,319 +0,0 @@ -; File written on Mon Aug 15 16:51:56 2011 -; dnssec_signzone version 9.7.3rc1 -test. 600 IN SOA localhost. postmaster.localhost. ( - 2011080901 ; serial - 3600 ; refresh (1 hour) - 1800 ; retry (30 minutes) - 604800 ; expire (1 week) - 600 ; minimum (10 minutes) - ) - 600 RRSIG SOA 7 1 600 20110914225156 ( - 20110815225156 39833 test. - IoQPcpx+Y2btVBBdM2H/9ppRMjphB1thwrdh - midhKH+MXDAauUIENucugi3zLsc1o2ke8LnQ - v3lCLd/bb5MD1otuS8vOw1GWEFhXOUBZU6wS - QwEIcG4BiSlz7/GvOlRa2znkOmZ3c8bD/J3Y - XUWDI3BEDPgrZqfxEvoMyPEWjO8= ) - 600 NS ns.test. - 600 NS ns2.test. - 600 RRSIG NS 7 1 600 20110914225156 ( - 20110815225156 39833 test. - OgEimhmFIAqlH0hyQy3pTsveBHKyqs9WfO1S - uDPRj3DFgFEAjoY473T8GxG2C+jTVL/UMVcb - BTZ8wIAiUHhqKLcmr0q/1X+kNUs7tNi+6oMn - /jxaOuRL6c8Kf2gl2t4g6JTwQqLQhUHTfQP+ - bEfKUr75VsVfxCQZIHlZ3/AlxZM= ) - 600 DNSKEY 256 3 7 ( - AwEAAc0FzrE7jUiaKIGZpIaFE8E989topAJN - dWIQUQ7BSKabmpBP2M+SXHwIiQ/yC25iqudO - IxjRcK7nHB1VoP84xU2oMj6eeSqQHf/bYaji - Y8IfR7lgrzoDWzq+0rtnKMJc/JM8SMkcoBAS - llvxarDJTZheZjlrCvhpRJC+FAkBsx81 - ) ; key id = 39833 - 600 DNSKEY 257 3 7 ( - AwEAAc55LPDhBLqfDUpjYYbBt+N63CiZtKrD - UDGeFAerbw0MWIUi3PgMr7yGVrj8e5Qjp9UN - zBUax6NdhlYVtFA8CwMTXGBjxgyqUoWpce08 - lswxfE70BpgUA6w5efs0/mYtX9/A76etCaSI - oNH2vfa47BCdCPDfC1uTgyeuNuDvhszHaSiD - 8OY7tLa/voecUlq38sdqi2raf2DvgOm7rdFa - reXOS/WIj7zd4XYrV1JGthxOMVlQ7zdv9rVd - UNUIF2d4hwCZJQr0ejhmvB3m/DuNmNOPYmnv - KTmLSE+IJ6baqYvKOVxwV+SaCnuJEjv+3Yrx - 8WQYD/iS9WBhC9FUit0dy+0= - ) ; key id = 57183 - 600 RRSIG DNSKEY 7 1 600 20110914225156 ( - 20110815225156 39833 test. - xPV+bSGUlbxA5MKBeeRbwUDh3Qc+dm77+OHQ - BHIr1L8/kRP5o5J7MqPA37kea6nhyltYf9xM - RsxyiaBGUUeLyWg/q6hTtkNgAHifOPAhiDz8 - AJDSTdSsq9RVtjdobAD0jyzz9sWnB+TPSOmj - Nlyd7VtPVEuSYljgawwfBBO3Kho= ) - 600 RRSIG DNSKEY 7 1 600 20110914225156 ( - 20110815225156 57183 test. - S3jkC7AvyFc4ShfHt6AWgS4zpx9DzWHBK9gV - 2H23OJzy8H1At/CjKxWVHLJ/io+ygryVnt/I - 47Jyhh9i43TnXj8il475YsweGnXGZSorrcXA - 3IsD2lOuRYnp3yetxe2ZrMGNDqqImE6X4x1a - UJI0cbE2UMZfUt8Rm5USiGzwAEgFD1OXxvMD - UT3flyp+Ote9FConK8gewV4wlJuBFemWT7BZ - lUYnoqfuAeEn2+1pIBS0iA0LNFjNBaEgtcjo - QeweN32yKoApau47Dl/Klw7KFT8+PLZ0QPbt - XAkJU7q94Q5aucDuHCSCTCc+2vZxdEnXKvRY - rfLuG8r/V5Kn+1iYrQ== ) - 0 NSEC3PARAM 1 0 10 - - 0 RRSIG NSEC3PARAM 7 1 0 20110914225156 ( - 20110815225156 39833 test. - kghSSeP8AZiQ/zmxgxAyG0itoUMo5adG5pxD - p8T3ZmbxEUSyG5acxBFkmeY39wVU0Cda8tWc - HHrMbB5e2GN8z6xJ0A4rVyXfKSYJSz+iKWfk - 7sOFRjd8OLYE3di6PwIpk6ORUiRPMFLDQCH0 - Q27hLsSoKyd50orKKI+ncjz7WzU= ) -a.test. 600 IN TXT "test" - 600 RRSIG TXT 7 2 600 20110914225156 ( - 20110815225156 39833 test. - UEVOlnL6CDRNCfk/Xge2oaGYCV1+ewwi5zJ0 - CX4DdwiNEkItL4HgBe8xXfxgFC3qySdsSYPE - 1krdFyIkAclMCwHECd1UwZbGlMTEUGrE1KOB - 8vQY+OhIV9TAhqNwnjbu7s2ZdNUv3wiUPcfk - hCJ4rzP6yeV2inLwZulXnhxb6Pk= ) -b.test. 600 IN TXT "test" - 600 RRSIG TXT 7 2 600 20110914225156 ( - 20110815225156 39833 test. - HcyQlO9io6Rc5e4vVqlRmK5PacOaFQJmdERG - 5Aobpgm1FuCLC7F+IMZ0d1XvBWnsw9iDzV43 - UKzTGqUSmDiSBzs4QzHlacGickIW8EOV4xyJ - +mcJ0FZh4YNbkt6CiX+8SF6IxfCMhRMjpSsK - rWqJMG3LXkI6W9stShzsYAFBOzQ= ) -e.test. 600 IN TXT "test" - 600 RRSIG TXT 7 2 600 20110914225156 ( - 20110815225156 39833 test. - jUn5FGRTL9OcFU7tvfkUnSwY8jA+8JynE0hi - ZJbYXDU5CiWGmR2B3yPHxUCewRqouyVCV8bc - xZsSuBxvcdYKryYDbjsmB83GlSEuxE9J7XZs - 8SxUP8PobLVqzXgEZS/XRU2G+R915ZDP9/iL - z9oYwc9TkeyXbp8J/ZsH88tG980= ) -c.test. 600 IN TXT "test" - 600 RRSIG TXT 7 2 600 20110914225156 ( - 20110815225156 39833 test. - cRxAj45oFDDCd8xQXxD1F0Qq8XeBWAj8EYS3 - 7nFXAgAy8sTczFvYCNGj79o7BALJwM4vc/wx - 6rjsiO/sHgfTMEBDq6lH9Wql72uhwavI2SrL - /h/wBP5q4BXlQ4xp6cLhhdifOWhNTvLP+Fe5 - U6yjvqneiKspze9SiFbcmRDiJds= ) -d.e.f.test. 600 IN TXT "test" - 600 RRSIG TXT 7 4 600 20110914225156 ( - 20110815225156 39833 test. - ENjCzr/P9rJmj5OJLzYwWtHtBg2Uz+qJDucz - I97Pq9F819/c5sxNfT4hgICCw6ZfT4ffbzye - fFJ0JVrh2cYOzu68ozlgek/Uml1UW0pDQVdI - s4zEgp4XK9wXUxtWChSqp5YXMdeHegZFu32i - IMNTbJDudwYSwhr2FyG92ZRi8Y8= ) -f.g.h.test. 600 IN TXT "test" - 600 RRSIG TXT 7 4 600 20110914225156 ( - 20110815225156 39833 test. - HT7iocFsfDjeX6j9RJdE3xfVGkIxhajFHgM/ - T/mJj/al4HKV6Ajia8DhpdfDrgM2m7r+Pgcn - FSIstfebQsuFCnHX/gIalDND/grHKsetQnMP - Y7O4QLsRnTV53fdlqQ4eT+jBW6fzJdGySVN+ - bg6kNJZS8DebjmlKtZz7tXjkP+4= ) -f.g.i.test. 600 IN TXT "test" - 600 RRSIG TXT 7 4 600 20110914225156 ( - 20110815225156 39833 test. - kHJJeNSL1rz4QRYqOzhGMQl1yIdio7l8Lg8H - f0TsvFLa6BudVtwKUm+Kz2QiDn7/Lew8w0KX - vVHxX/Vwl3Ixk54YgMKLNogz2TEvnh/VGiS7 - 8r0oSUrg0CFd+xDfxnLeRqX5NNfMuSJap5WH - Aw7IVeRjXDwJFYnytMEnTrhHHHg= ) -f.g.j.test. 600 IN TXT "test" - 600 RRSIG TXT 7 4 600 20110914225156 ( - 20110815225156 39833 test. - lIEHEhDFhOWK8W/F2xWELU2p/X77S2KTivm9 - sY4k3RPsLNHE7p+lF8p72Lcb79rtltnoVYtE - pTIiaUcmgGwfaI4cwfXbeuEgnuTiLg7Xrefx - 3GT86Q+8gfgbMXUmRA/eouWZhCOaYJN99gYz - urzDMiRLYmILHmLlnvo82SgXeuk= ) -k.test. 600 IN TXT "test" - 600 RRSIG TXT 7 2 600 20110914225156 ( - 20110815225156 39833 test. - wC3zgYWsuLga8Vu3QFu/Ci8SzRbA5bvjSmDj - NzcpjU5cvJBxtgzatCr02AaUC94bI0JzNrEB - nFyWCYw55lyy+bAHU1u05UcQmz0n5yxkvmHX - i8ZjMyQkAvNKodJHaFQqUKKIDuSHD2EziKqg - eNn55YRS11ihkODehUVNl7TnYeA= ) -ns.test. 600 IN A 10.0.0.1 - 600 RRSIG A 7 2 600 20110914225156 ( - 20110815225156 39833 test. - VyK/WlQ6ikXdjF/arGzyAyYhOc8IYNBp4QLW - gtYjvbjIcV5+9JINWmUs61VjJ14nES1sI0xb - 9vQJuiPXTM1awUAnvOKLhaX6fbJaEiR1w6Cf - RT5QKBMxNBKVStqdabHcigY4DUuc1PQk1vCw - yMUJt3nHNVMZk+XAycNHzBeYjik= ) -ns2.test. 600 IN A 10.0.0.2 - 600 RRSIG A 7 2 600 20110914225156 ( - 20110815225156 39833 test. - CX6UlZL+5NQJViKfbe/E3uIJk/wjUzoiHBhY - B6gS8nxZzlRPdTTXyMZoRa4etTZEbrRjnyXk - 1rP47faCUwbh//XqukN9f7FZ4Y39NpPS2XpX - 0Lx6M93Jz46lbzmseMFs2YmNMzzhN4uhRvl/ - 8gPtYsn9KMXnAlFfa4XrE5LNVyY= ) -1F3JQ6EANHNHOCMUPQTVNM339VDTR51C.test. 600 IN NSEC3 1 0 10 - 7QKPELF33JOK9BVJ7CKE99AHG40B0SH7 A RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - w7aS12lxLNh+G1B/2kEq1BO6IzYvyC8n/MGV - 0jvFnapNXGZMPrPxGeO2wkw1JXepuXCv98be - M4SjQywaH+VP6ZMTIfjxRxtcCM+aLAFhiz0l - /MILEkjemmxjAfvV7emRVMwCGcoGI7qC3Xxq - q5g8EzJiYyTCOnI5LKRggn97wGg= ) -7QKPELF33JOK9BVJ7CKE99AHG40B0SH7.test. 600 IN NSEC3 1 0 10 - 94Q15K1V1VE5F87EI37T2B9A39EEC368 TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - J4ObL3p4eN0jWh06M+rX2SSPANQoKfnosElB - KcKE7fLqEjKK7N6Yh6KUlbEP25tfeZ7W6GBJ - b7q6Nh0Ax8fYdc/6JVvmxcwWcx5Lw1TfITGB - ttFntJlbp1A8lwP3pn8Ksql1X2ogh78AsgTb - X5kmXVukC1oEzt98EAa/V/an8QA= ) -CS8M3UVG0UJDR6USBES4U9SNUGQI2RJE.test. 600 IN NSEC3 1 0 10 - ETEQB5V431INUIIE547FKSOF7O4DJ62J A RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - Vyd/2b0S15fACJ8TiPXKtScV9A/ZztVumZAm - o2S6jaVJKWik+8orDW+WiJ4/PEl26PK2m1uv - HD2beuUCHj9EnYkN/dzL3Bsc302qr9xqsh0q - VFS2moznoNG415ZV3vgYR7L9DAp43ZeFuw6I - 7sr21hLYLUeo31xBsJg7RlOL+4s= ) -ETEQB5V431INUIIE547FKSOF7O4DJ62J.test. 600 IN NSEC3 1 0 10 - F8G1MB0JUEU3FBI11CAVFIPGEA3POOIM - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - oOHs1eb3JYeOMOnzE2PS6NIXBNzSoTYPIxo/ - P0d/ihsLKra3yNJNPTlu4kf+FZoNYAGtMK/D - 6dZWFvtdswDdi2C5WSgsanuHqXq5Lr3A1nCe - cQI5PO4RrLymB+MtYg15CNKcnc0WmJO8deSR - WzNOarC+Iz1Xj3FkKDS4FFr+02Q= ) -94Q15K1V1VE5F87EI37T2B9A39EEC368.test. 600 IN NSEC3 1 0 10 - CS8M3UVG0UJDR6USBES4U9SNUGQI2RJE - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - K0PvN7YtHQ63x/x2yXXa2S9GBGuTNJywDZ8M - wyMSwytCb9mn4hnKD5mJHaXGTw3YX7usbnEO - ce6hiJdN/VhMfbRMOvUpgyblOj4kXiYVZY1a - SyycfugK/Hu1j4az7lIhhnnx58GChA6mg8Vx - 3Uz6cNDDCSTBTl09NyeUUrKWsHQ= ) -FBH6B0LHT9PPQB1P98D228HA1H52L8PO.test. 600 IN NSEC3 1 0 10 - JGU2L7C3LKLHAKC5RHUOORTI2DCKK3KL - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - giXRE+4ZeIzDrhx1XkFSpIKGFd3UGzlrLZnO - Ur9nMUfwvU5A3fitEkdayo3ZDH7MQGpSotaH - ReiFXx3Z6Hm2NIN/RHYZQr9e0vbMYSjkANdu - HWBA1SrSq5SHyuy970mPd4jfTHiABCo6fJGB - ykGClZGou0WSaB+Ak19fMbeQ2Wo= ) -JGU2L7C3LKLHAKC5RHUOORTI2DCKK3KL.test. 600 IN NSEC3 1 0 10 - KFMJ88CKMKUQQJE59IKFBOLLLD4DF55H TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - BHTDUgZdWNLgz3xHYMqvlWK/IJ0xrXESoREc - 6D3sO9bcLTMYPO9t80itOlipwp4AmaVOBXPt - cKSdgsUXDEtHqNSxtGbNr5xQ+Aqsep0GX71V - HkcIuiNdTUw83dkajCHMkmQCbEjp9mbdiTmS - haNW2EsscldfaS1aq5tYUhCT3l4= ) -L993U6VC0DUV5QJ8TRPD2IQLM8FJ7AT9.test. 600 IN NSEC3 1 0 10 - LSMRLLNBQGGK8J6V40KLM2LG5TE4FS0P - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - vE7K0Nrju4qLFDYkIyMY5bIMT0wu8MJdxL6u - 7WVA4HepccKQcUnvVoBAcrA9+MUeteyrad8Y - SJvQIt7sz5t7FViWSq5IMPVPujWtW5J30LhJ - mOLd1KmnFWoVthJ1oFNzBM80A60seKNnEw1M - lV6Y+v0gNYIQensUb9w6SVMTpxE= ) -F8G1MB0JUEU3FBI11CAVFIPGEA3POOIM.test. 600 IN NSEC3 1 0 10 - FA1T7MKUUV9SD4VDBJQ3GRFK1IDTCKL7 - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - DkL9ONc0vpsKdG20ol8XPAaVfLb7kf1wnKbR - rQUB1trGSHm/Igo06of43zm9J+56htFJg1xD - I2de0sCUBQYyHVBBDiBAd1g+ZvcpUlLP0w8M - NxMviMiG/WQAdGXHwYfUimwMWD7gNGl1m05H - HwYmzGs+d1bClDNBrFhdfdL2+iA= ) -LSMRLLNBQGGK8J6V40KLM2LG5TE4FS0P.test. 600 IN NSEC3 1 0 10 - LUAN2Q3I2OCVSD41MP08HNA9JP22D38K - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - ZgiWuMqodQuhwuAF6CIiJTsdRahi+poOiZAM - WXNP0wXfdptcG2uhbdDwy+0crhe3tuybhwcb - CuiaQUh0XNPhgF+qmXpGobaqBhCEvCF4K9qY - OCIoMfsI1pIBVbMw0+YXVarFZ8+mfNU/+6n6 - yy2+1nCg3k4XR2Dpv4CeDBfcAuM= ) -NAL1UIEBM38NKMN6RQOKE8T781IA7UKI.test. 600 IN NSEC3 1 0 10 - OUSGP0LO9FGAROHDULQVSTI3OLQIBB39 TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - x8JiXPI+EXHz8ZO/VW0/+9wWsBNqeSMxXZIV - ibOnogSg7Wi7Yq1xftKC2+xEevNxSZnBibEy - Sgro5xKTf0n7pD9hHVBLoYmOOnbXY3QNQ2EQ - y3LdPT355WmwVddVOOxNpNRp2zQyqg7BhVA3 - wxY7tyVQd4x1+95ATUQBnFditdE= ) -KFMJ88CKMKUQQJE59IKFBOLLLD4DF55H.test. 600 IN NSEC3 1 0 10 - L993U6VC0DUV5QJ8TRPD2IQLM8FJ7AT9 TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - KQPaN2Ecebifbl4Bz5Yo0x2DgGmZiVhpSydm - oy/5NtMjt7G472JrKlqByap+VxW0bpzo3IER - 3P8Dsv7pfBD4/Cl5sFqwZL7wYy7RB4dQLVCi - Pepc/Mr3gR2XmL91fpGttMj5jGscnVQJCyFa - obzhsVaVImUQZFDPb0UQUHwIhOA= ) -LUAN2Q3I2OCVSD41MP08HNA9JP22D38K.test. 600 IN NSEC3 1 0 10 - NAL1UIEBM38NKMN6RQOKE8T781IA7UKI TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - NJ+X3d0qh2+fbSnG0iQPxAeDIOzX5NTmY9fS - x7IO/DDcgUhPvl1YYdz5J999cec1zzOKp10J - YbsIAzg0w/Y4D4CBUw3IkcOrUFOODb6eJQGb - rVFRqmp3BUP4qOAWUZvx4oQ0KG4K/h/KJMbU - Vcdl7PF7G5O5hMyR9UWg4zal7Sk= ) -OUSGP0LO9FGAROHDULQVSTI3OLQIBB39.test. 600 IN NSEC3 1 0 10 - PQQ28M3U2MM08GGFV3JKR76G2H9IUJPC TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - A/qxYrSE/smBGbST8j8eGPCrRnwvVa25kDha - IuA3nv0vzXhFvlruc9f0HRGwsq6A2pw3I5W+ - xo2/JxsNyFOotdwaDDEBzqPkJmrzupxQS4Hm - rHSLnRnNw4QzvzNjAGWMYAoe3OeHC47wmAtI - qE91EHZTlPP28CUXOMo+7sCaOa8= ) -U0UVS2SUP89P2TM3PJO4TC1GPJ2O6519.test. 600 IN NSEC3 1 0 10 - VA2VG5BEMCKQP6MS5NHHGL18031BIA7M NS SOA RRSIG DNSKEY NSEC3PARAM - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - rahhkfiF+Rk6oqbWTdu9qcwhmj5hbDuIFdiJ - GmaG+cFSv5Mjp+txNVCvBK9Hq/VpW0ypen/3 - JC0sVAugSX+HAKAgyaMKmgWCvoQZ6ZSJUh7o - LRPcT+oxVXQAqjovxpaV8k6sYo44tpljPdOD - UluWAP5SrmJKjzCxs27KGRx8MK4= ) -VA2VG5BEMCKQP6MS5NHHGL18031BIA7M.test. 600 IN NSEC3 1 0 10 - VAKOQ2TPD7S25NFBJT73J3C4OGU10RJ5 TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - XcBeZ8lo9Qo8z56+1FdGDjh6ZHCfO+MQ/wnY - TEUo/aWLkPTyq39nLhe0qVBJxmDpM+KQFuG9 - cjQT5fvrlrY+lv6dedB64EBMYy4kKbIv7N5+ - r6+sfWlvtKsfXxysLSk2+jLEm5NuLFrOdNas - WLVsq741D3YcWt4kM1HCyk3DNF8= ) -FA1T7MKUUV9SD4VDBJQ3GRFK1IDTCKL7.test. 600 IN NSEC3 1 0 10 - FBH6B0LHT9PPQB1P98D228HA1H52L8PO TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - jB/vLrvx4sQQD7J3ZacAAyhcFmIPh7LH3ljw - IAIaeLb10oX5q1/nQKYdfq976TMy5sWpBcmd - i91WLxd+T/gOSumyP8bC3g+SUoyZ9wxY6A6a - MMx1rn0QA9IKrxMqojs9M3urJ8QAeIS+KyAn - rbyyJuG+EVm0prqlPZtzUi28WCI= ) -PQQ28M3U2MM08GGFV3JKR76G2H9IUJPC.test. 600 IN NSEC3 1 0 10 - U0UVS2SUP89P2TM3PJO4TC1GPJ2O6519 - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - asCOU9OkVWMvUU2IUpwMgdYf0faA04zPbaFf - qywYsv3NH01Lky6G3a0WUPAbBm7TAYx/ln8a - 559vlpp/gpXEl9CcLrjO6wy5i0ryp8gVHtKJ - rQlEc/uw4SY+S5t7FuZc2rNRdAbxVMYuwrvm - HBsKDPblre3e06ZZFEmnGFzCgmg= ) -VAKOQ2TPD7S25NFBJT73J3C4OGU10RJ5.test. 600 IN NSEC3 1 0 10 - VNCCJH8JPOLGLAGVMV3FKS09M7RRDU47 TXT RRSIG - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - Pt4tKB1p/jsyLYab9LSt5MF1KTRT18nRTOox - q0IACkXkKx7W5xv6nSYXIB+nQzNp1Y1hhoXn - 9IFi0liPnIAOp73w4vybhfIdTFiEmHPHT6O9 - VIx5cSriqBI6Qda8GtfeIb96P8SojbUk5BDI - g18iYjviGhQYRgpU3tg1qd7pbcc= ) -VNCCJH8JPOLGLAGVMV3FKS09M7RRDU47.test. 600 IN NSEC3 1 0 10 - 1F3JQ6EANHNHOCMUPQTVNM339VDTR51C - 600 RRSIG NSEC3 7 2 600 20110914225156 ( - 20110815225156 39833 test. - ZMZPHawhkuzSV7C7zkgghH/jpw9CQVR1JUXq - pAeY2iIIWwNhfuskJaLgtu/5SuKnJtrv6D4N - g+lfEkBReia5xO/SCcHv8/hXEPH8vZ4xe1C9 - 6GVB6ip2hKw2g5HpyF7X18WgwZ0cqPWVg+Q+ - xRLpXH+53391Wt5rG7qJswn5RLE= ) diff --git a/lib/dns-pkcs11/tests/testdata/diff/zone1.data b/lib/dns-pkcs11/tests/testdata/diff/zone1.data deleted file mode 100644 index 8ddf669..0000000 --- a/lib/dns-pkcs11/tests/testdata/diff/zone1.data +++ /dev/null @@ -1,13 +0,0 @@ -; Copyright (C) Internet Systems Consortium, Inc. ("ISC") -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, you can obtain one at https://mozilla.org/MPL/2.0/. -; -; See the COPYRIGHT file distributed with this work for additional -; information regarding copyright ownership. - -@ 0 SOA . . 0 0 0 0 0 -@ 0 NS @ -@ 0 A 1.2.3.4 -remove 0 A 5.6.7.8 diff --git a/lib/dns-pkcs11/tests/testdata/diff/zone2.data b/lib/dns-pkcs11/tests/testdata/diff/zone2.data deleted file mode 100644 index 363af42..0000000 --- a/lib/dns-pkcs11/tests/testdata/diff/zone2.data +++ /dev/null @@ -1,14 +0,0 @@ -; Copyright (C) Internet Systems Consortium, Inc. ("ISC") -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, you can obtain one at https://mozilla.org/MPL/2.0/. -; -; See the COPYRIGHT file distributed with this work for additional -; information regarding copyright ownership. - -@ 0 SOA . . 0 0 0 0 0 -@ 0 NS @ -@ 0 A 1.2.3.4 -remove 0 A 5.6.7.8 -added 0 A 5.6.7.8 diff --git a/lib/dns-pkcs11/tests/testdata/diff/zone3.data b/lib/dns-pkcs11/tests/testdata/diff/zone3.data deleted file mode 100644 index ae3a60e..0000000 --- a/lib/dns-pkcs11/tests/testdata/diff/zone3.data +++ /dev/null @@ -1,12 +0,0 @@ -; Copyright (C) Internet Systems Consortium, Inc. ("ISC") -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, you can obtain one at https://mozilla.org/MPL/2.0/. -; -; See the COPYRIGHT file distributed with this work for additional -; information regarding copyright ownership. - -@ 0 SOA . . 0 0 0 0 0 -@ 0 NS @ -@ 0 A 1.2.3.4 diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.saved b/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.saved deleted file mode 100644 index c657f41..0000000 Binary files a/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.saved and /dev/null differ diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.text b/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.text deleted file mode 100644 index 71977e4..0000000 --- a/lib/dns-pkcs11/tests/testdata/dnstap/dnstap.text +++ /dev/null @@ -1,96 +0,0 @@ -03-Feb-2017 15:47:16.000 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 SR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 SR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 SR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 SR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 SR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 CR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 CR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 CR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 CR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 CR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 AR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 AR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 AR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 AR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 AR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 RR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 RR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 RR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 RR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 RR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 FR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 FR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 FR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 FR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 FR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 UDP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 15:47:16.000 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TQ 10.53.0.1:2112 -> 10.53.0.2:2112 TCP 40b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 TR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 TR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TR 10.53.0.1:2112 <- 10.53.0.2:2112 UDP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 TR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 17:47:16.000 TR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A -03-Feb-2017 16:47:16.830 TR 10.53.0.1:2112 <- 10.53.0.2:2112 TCP 287b www.isc.org/IN/A diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/query.auth b/lib/dns-pkcs11/tests/testdata/dnstap/query.auth deleted file mode 100644 index a14f850..0000000 --- a/lib/dns-pkcs11/tests/testdata/dnstap/query.auth +++ /dev/null @@ -1,4 +0,0 @@ -# authoritative query, www.isc.org/A -8d 24 00 20 00 01 00 00 00 00 00 01 03 77 77 77 -03 69 73 63 03 6f 72 67 00 00 01 00 01 00 00 29 -10 00 00 00 00 00 00 00 diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/query.recursive b/lib/dns-pkcs11/tests/testdata/dnstap/query.recursive deleted file mode 100644 index 8ee705f..0000000 --- a/lib/dns-pkcs11/tests/testdata/dnstap/query.recursive +++ /dev/null @@ -1,4 +0,0 @@ -# recursive query for www.isc.org/A -bf 08 01 20 00 01 00 00 00 00 00 01 03 77 77 77 -03 69 73 63 03 6f 72 67 00 00 01 00 01 00 00 29 -10 00 00 00 00 00 00 00 diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/response.auth b/lib/dns-pkcs11/tests/testdata/dnstap/response.auth deleted file mode 100644 index 4d0ea81..0000000 --- a/lib/dns-pkcs11/tests/testdata/dnstap/response.auth +++ /dev/null @@ -1,19 +0,0 @@ -# authoritative response, www.isc.org/A -8d 24 84 00 00 01 00 01 00 04 00 07 03 77 77 77 -03 69 73 63 03 6f 72 67 00 00 01 00 01 c0 0c 00 -01 00 01 00 00 00 3c 00 04 95 14 40 45 c0 10 00 -02 00 01 00 00 1c 20 00 0d 03 61 6d 73 06 73 6e -73 2d 70 62 c0 10 c0 10 00 02 00 01 00 00 1c 20 -00 07 04 73 66 62 61 c0 3d c0 10 00 02 00 01 00 -00 1c 20 00 19 02 6e 73 03 69 73 63 0b 61 66 69 -6c 69 61 73 2d 6e 73 74 04 69 6e 66 6f 00 c0 10 -00 02 00 01 00 00 1c 20 00 06 03 6f 72 64 c0 3d -c0 39 00 01 00 01 00 00 1c 20 00 04 c7 06 01 1e -c0 39 00 1c 00 01 00 00 1c 20 00 10 20 01 05 00 -00 60 00 00 00 00 00 00 00 00 00 30 c0 8a 00 01 -00 01 00 00 1c 20 00 04 c7 06 00 1e c0 8a 00 1c -00 01 00 00 1c 20 00 10 20 01 05 00 00 71 00 00 -00 00 00 00 00 00 00 30 c0 52 00 01 00 01 00 00 -1c 20 00 04 95 14 40 03 c0 52 00 1c 00 01 00 00 -1c 20 00 10 20 01 04 f8 00 00 00 02 00 00 00 00 -00 00 00 19 00 00 29 10 00 00 00 00 00 00 00 diff --git a/lib/dns-pkcs11/tests/testdata/dnstap/response.recursive b/lib/dns-pkcs11/tests/testdata/dnstap/response.recursive deleted file mode 100644 index 6e3a3cf..0000000 --- a/lib/dns-pkcs11/tests/testdata/dnstap/response.recursive +++ /dev/null @@ -1,19 +0,0 @@ -# recursive response, www.isc.org/A -bf 08 81 a0 00 01 00 01 00 04 00 07 03 77 77 77 -03 69 73 63 03 6f 72 67 00 00 01 00 01 c0 0c 00 -01 00 01 00 00 00 15 00 04 95 14 40 45 c0 10 00 -02 00 01 00 00 1b a6 00 0e 04 73 66 62 61 06 73 -6e 73 2d 70 62 c0 10 c0 10 00 02 00 01 00 00 1b -a6 00 06 03 6f 72 64 c0 3e c0 10 00 02 00 01 00 -00 1b a6 00 19 02 6e 73 03 69 73 63 0b 61 66 69 -6c 69 61 73 2d 6e 73 74 04 69 6e 66 6f 00 c0 10 -00 02 00 01 00 00 1b a6 00 06 03 61 6d 73 c0 3e -c0 8a 00 01 00 01 00 00 b1 d5 00 04 c7 06 01 1e -c0 8a 00 1c 00 01 00 00 b1 d5 00 10 20 01 05 00 -00 60 00 00 00 00 00 00 00 00 00 30 c0 53 00 01 -00 01 00 00 b1 d5 00 04 c7 06 00 1e c0 53 00 1c -00 01 00 00 b1 d5 00 10 20 01 05 00 00 71 00 00 -00 00 00 00 00 00 00 30 c0 39 00 01 00 01 00 00 -b1 d5 00 04 95 14 40 03 c0 39 00 1c 00 01 00 00 -b1 d5 00 10 20 01 04 f8 00 00 00 02 00 00 00 00 -00 00 00 19 00 00 29 10 00 00 00 00 00 00 00 diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+00002.key b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+00002.key deleted file mode 100644 index a8b4b4d..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+00002.key +++ /dev/null @@ -1 +0,0 @@ -test. IN DNSKEY 49152 2 1 diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.key b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.key deleted file mode 100644 index b0277e3..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.key +++ /dev/null @@ -1 +0,0 @@ -test. IN DNSKEY 257 3 1 AQPQjwSpaVzxIgRCpiUoozUQKGh2oX8NIFKDOvtxK+tn536OZg2cROKTlgGEHXJK9YHfW/6nzQULTVpb63P+SQMmjCCidb8IYyhItixRztVeJQ== diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.private b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.private deleted file mode 100644 index c97ac30..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+001+54622.private +++ /dev/null @@ -1,10 +0,0 @@ -Private-key-format: v1.2 -Algorithm: 1 (RSA) -Modulus: 0I8EqWlc8SIEQqYlKKM1EChodqF/DSBSgzr7cSvrZ+d+jmYNnETik5YBhB1ySvWB31v+p80FC01aW+tz/kkDJowgonW/CGMoSLYsUc7VXiU= -PublicExponent: Aw== -PrivateExponent: iwoDG5uTS2wC1xluGxd4tXBFpGuqCMA3AidSS3Kc7++ptEQJEtiXC9kfCJMvZhGfQLaujft2OgrmkcuDVtPIbQWEENhyJhb4Lk82kFXbfus= -Prime1: /rSKuzcZY7R5cY2YWD4CiBNyj9WJMq1wWmBnb9+5M08nTl5E9NW5qQ== -Prime2: 0Z5shXQYd16E2Gs6e5WxtO0Oqlly2KkSqXohwTQWDWTb8Pw0WTZmHQ== -Exponent1: qc2x0iS7l82mS7O65X6sWrehtTkGIcj1kZWaSpUmIjTE3umDTePRGw== -Exponent2: i77zA6K6+j8DOvIm/Q52eJ4JxuZMkHC3G6bBK3gOs5iSoKgi5iREEw== -Coefficient: 3+wYZB0SJad7z2EsjzgbSlg6CawoaOvrROGSbwSiW5DCsMFROudOTw== diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.key b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.key deleted file mode 100644 index 958d585..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.key +++ /dev/null @@ -1 +0,0 @@ -test. IN DNSKEY 16641 3 3 ANp1//lqDlEfTavcFI+cyudNfgEz73V/K7fSDvkA0eDYcGg/kSvEjAEO/oLWCERltkuC55ZcM/mSv17WF1d/wR6kww/pLI9eXwkjftAYqs5sNxk+mbEGl6zwve9wq5z7IoTY5/J4l7XLCKftg/wGvrzXQhggIkRvEh3myhxd+ouILcpfvTIthWlTKiH59tSJpmgmiSMTE7nDYaf10iVRWN6DMSprgejiH05/fpmyZAt44tyAh4m1wXS5u4tam1PXDJYJozn7EfQ8e2weIv1yC+t6PHSx diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.private b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.private deleted file mode 100644 index 5781c9d..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+23616.private +++ /dev/null @@ -1,7 +0,0 @@ -Private-key-format: v1.2 -Algorithm: 3 (DSA) -Prime(p): 73V/K7fSDvkA0eDYcGg/kSvEjAEO/oLWCERltkuC55ZcM/mSv17WF1d/wR6kww/pLI9eXwkjftAYqs5sNxk+mQ== -Subprime(q): 2nX/+WoOUR9Nq9wUj5zK501+ATM= -Base(g): sQaXrPC973CrnPsihNjn8niXtcsIp+2D/Aa+vNdCGCAiRG8SHebKHF36i4gtyl+9Mi2FaVMqIfn21ImmaCaJIw== -Private_value(x): Nky4tvIwg6xlcyeHXr4k2DEZg0E= -Public_value(y): ExO5w2Gn9dIlUVjegzEqa4Ho4h9Of36ZsmQLeOLcgIeJtcF0ubuLWptT1wyWCaM5+xH0PHtsHiL9cgvrejx0sQ== diff --git a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+49667.key b/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+49667.key deleted file mode 100644 index fb73f57..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/Ktest.+003+49667.key +++ /dev/null @@ -1 +0,0 @@ -test. IN DNSKEY 49152 2 3 diff --git a/lib/dns-pkcs11/tests/testdata/dst/test1.data b/lib/dns-pkcs11/tests/testdata/dst/test1.data deleted file mode 100644 index cf84e9f..0000000 --- a/lib/dns-pkcs11/tests/testdata/dst/test1.data +++ /dev/null @@ -1,3077 +0,0 @@ -Network Working Group P. Mockapetris -Request for Comments: 1035 ISI - November 1987 -Obsoletes: RFCs 882, 883, 973 - - DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION - - -1. STATUS OF THIS MEMO - -This RFC describes the details of the domain system and protocol, and -assumes that the reader is familiar with the concepts discussed in a -companion RFC, "Domain Names - Concepts and Facilities" [RFC-1034]. - -The domain system is a mixture of functions and data types which are an -official protocol and functions and data types which are still -experimental. Since the domain system is intentionally extensible, new -data types and experimental behavior should always be expected in parts -of the system beyond the official protocol. The official protocol parts -include standard queries, responses and the Internet class RR data -formats (e.g., host addresses). Since the previous RFC set, several -definitions have changed, so some previous definitions are obsolete. - -Experimental or obsolete features are clearly marked in these RFCs, and -such information should be used with caution. - -The reader is especially cautioned not to depend on the values which -appear in examples to be current or complete, since their purpose is -primarily pedagogical. Distribution of this memo is unlimited. - - Table of Contents - - 1. STATUS OF THIS MEMO 1 - 2. INTRODUCTION 3 - 2.1. Overview 3 - 2.2. Common configurations 4 - 2.3. Conventions 7 - 2.3.1. Preferred name syntax 7 - 2.3.2. Data Transmission Order 8 - 2.3.3. Character Case 9 - 2.3.4. Size limits 10 - 3. DOMAIN NAME SPACE AND RR DEFINITIONS 10 - 3.1. Name space definitions 10 - 3.2. RR definitions 11 - 3.2.1. Format 11 - 3.2.2. TYPE values 12 - 3.2.3. QTYPE values 12 - 3.2.4. CLASS values 13 - - - -Mockapetris [Page 1] - -RFC 1035 Domain Implementation and Specification November 1987 - - - 3.2.5. QCLASS values 13 - 3.3. Standard RRs 13 - 3.3.1. CNAME RDATA format 14 - 3.3.2. HINFO RDATA format 14 - 3.3.3. MB RDATA format (EXPERIMENTAL) 14 - 3.3.4. MD RDATA format (Obsolete) 15 - 3.3.5. MF RDATA format (Obsolete) 15 - 3.3.6. MG RDATA format (EXPERIMENTAL) 16 - 3.3.7. MINFO RDATA format (EXPERIMENTAL) 16 - 3.3.8. MR RDATA format (EXPERIMENTAL) 17 - 3.3.9. MX RDATA format 17 - 3.3.10. NULL RDATA format (EXPERIMENTAL) 17 - 3.3.11. NS RDATA format 18 - 3.3.12. PTR RDATA format 18 - 3.3.13. SOA RDATA format 19 - 3.3.14. TXT RDATA format 20 - 3.4. ARPA Internet specific RRs 20 - 3.4.1. A RDATA format 20 - 3.4.2. WKS RDATA format 21 - 3.5. IN-ADDR.ARPA domain 22 - 3.6. Defining new types, classes, and special namespaces 24 - 4. MESSAGES 25 - 4.1. Format 25 - 4.1.1. Header section format 26 - 4.1.2. Question section format 28 - 4.1.3. Resource record format 29 - 4.1.4. Message compression 30 - 4.2. Transport 32 - 4.2.1. UDP usage 32 - 4.2.2. TCP usage 32 - 5. MASTER FILES 33 - 5.1. Format 33 - 5.2. Use of master files to define zones 35 - 5.3. Master file example 36 - 6. NAME SERVER IMPLEMENTATION 37 - 6.1. Architecture 37 - 6.1.1. Control 37 - 6.1.2. Database 37 - 6.1.3. Time 39 - 6.2. Standard query processing 39 - 6.3. Zone refresh and reload processing 39 - 6.4. Inverse queries (Optional) 40 - 6.4.1. The contents of inverse queries and responses 40 - 6.4.2. Inverse query and response example 41 - 6.4.3. Inverse query processing 42 - - - - - - -Mockapetris [Page 2] - -RFC 1035 Domain Implementation and Specification November 1987 - - - 6.5. Completion queries and responses 42 - 7. RESOLVER IMPLEMENTATION 43 - 7.1. Transforming a user request into a query 43 - 7.2. Sending the queries 44 - 7.3. Processing responses 46 - 7.4. Using the cache 47 - 8. MAIL SUPPORT 47 - 8.1. Mail exchange binding 48 - 8.2. Mailbox binding (Experimental) 48 - 9. REFERENCES and BIBLIOGRAPHY 50 - Index 54 - -2. INTRODUCTION - -2.1. Overview - -The goal of domain names is to provide a mechanism for naming resources -in such a way that the names are usable in different hosts, networks, -protocol families, internets, and administrative organizations. - -From the user's point of view, domain names are useful as arguments to a -local agent, called a resolver, which retrieves information associated -with the domain name. Thus a user might ask for the host address or -mail information associated with a particular domain name. To enable -the user to request a particular type of information, an appropriate -query type is passed to the resolver with the domain name. To the user, -the domain tree is a single information space; the resolver is -responsible for hiding the distribution of data among name servers from -the user. - -From the resolver's point of view, the database that makes up the domain -space is distributed among various name servers. Different parts of the -domain space are stored in different name servers, although a particular -data item will be stored redundantly in two or more name servers. The -resolver starts with knowledge of at least one name server. When the -resolver processes a user query it asks a known name server for the -information; in return, the resolver either receives the desired -information or a referral to another name server. Using these -referrals, resolvers learn the identities and contents of other name -servers. Resolvers are responsible for dealing with the distribution of -the domain space and dealing with the effects of name server failure by -consulting redundant databases in other servers. - -Name servers manage two kinds of data. The first kind of data held in -sets called zones; each zone is the complete database for a particular -"pruned" subtree of the domain space. This data is called -authoritative. A name server periodically checks to make sure that its -zones are up to date, and if not, obtains a new copy of updated zones - - - -Mockapetris [Page 3] - -RFC 1035 Domain Implementation and Specification November 1987 - - -from master files stored locally or in another name server. The second -kind of data is cached data which was acquired by a local resolver. -This data may be incomplete, but improves the performance of the -retrieval process when non-local data is repeatedly accessed. Cached -data is eventually discarded by a timeout mechanism. - -This functional structure isolates the problems of user interface, -failure recovery, and distribution in the resolvers and isolates the -database update and refresh problems in the name servers. - -2.2. Common configurations - -A host can participate in the domain name system in a number of ways, -depending on whether the host runs programs that retrieve information -from the domain system, name servers that answer queries from other -hosts, or various combinations of both functions. The simplest, and -perhaps most typical, configuration is shown below: - - Local Host | Foreign - | - +---------+ +----------+ | +--------+ - | | user queries | |queries | | | - | User |-------------->| |---------|->|Foreign | - | Program | | Resolver | | | Name | - | |<--------------| |<--------|--| Server | - | | user responses| |responses| | | - +---------+ +----------+ | +--------+ - | A | - cache additions | | references | - V | | - +----------+ | - | cache | | - +----------+ | - -User programs interact with the domain name space through resolvers; the -format of user queries and user responses is specific to the host and -its operating system. User queries will typically be operating system -calls, and the resolver and its cache will be part of the host operating -system. Less capable hosts may choose to implement the resolver as a -subroutine to be linked in with every program that needs its services. -Resolvers answer user queries with information they acquire via queries -to foreign name servers and the local cache. - -Note that the resolver may have to make several queries to several -different foreign name servers to answer a particular user query, and -hence the resolution of a user query may involve several network -accesses and an arbitrary amount of time. The queries to foreign name -servers and the corresponding responses have a standard format described - - - -Mockapetris [Page 4] - -RFC 1035 Domain Implementation and Specification November 1987 - - -in this memo, and may be datagrams. - -Depending on its capabilities, a name server could be a stand alone -program on a dedicated machine or a process or processes on a large -timeshared host. A simple configuration might be: - - Local Host | Foreign - | - +---------+ | - / /| | - +---------+ | +----------+ | +--------+ - | | | | |responses| | | - | | | | Name |---------|->|Foreign | - | Master |-------------->| Server | | |Resolver| - | files | | | |<--------|--| | - | |/ | | queries | +--------+ - +---------+ +----------+ | - -Here a primary name server acquires information about one or more zones -by reading master files from its local file system, and answers queries -about those zones that arrive from foreign resolvers. - -The DNS requires that all zones be redundantly supported by more than -one name server. Designated secondary servers can acquire zones and -check for updates from the primary server using the zone transfer -protocol of the DNS. This configuration is shown below: - - Local Host | Foreign - | - +---------+ | - / /| | - +---------+ | +----------+ | +--------+ - | | | | |responses| | | - | | | | Name |---------|->|Foreign | - | Master |-------------->| Server | | |Resolver| - | files | | | |<--------|--| | - | |/ | | queries | +--------+ - +---------+ +----------+ | - A |maintenance | +--------+ - | +------------|->| | - | queries | |Foreign | - | | | Name | - +------------------|--| Server | - maintenance responses | +--------+ - -In this configuration, the name server periodically establishes a -virtual circuit to a foreign name server to acquire a copy of a zone or -to check that an existing copy has not changed. The messages sent for - - - -Mockapetris [Page 5] - -RFC 1035 Domain Implementation and Specification November 1987 - - -these maintenance activities follow the same form as queries and -responses, but the message sequences are somewhat different. - -The information flow in a host that supports all aspects of the domain -name system is shown below: - - Local Host | Foreign - | - +---------+ +----------+ | +--------+ - | | user queries | |queries | | | - | User |-------------->| |---------|->|Foreign | - | Program | | Resolver | | | Name | - | |<--------------| |<--------|--| Server | - | | user responses| |responses| | | - +---------+ +----------+ | +--------+ - | A | - cache additions | | references | - V | | - +----------+ | - | Shared | | - | database | | - +----------+ | - A | | - +---------+ refreshes | | references | - / /| | V | - +---------+ | +----------+ | +--------+ - | | | | |responses| | | - | | | | Name |---------|->|Foreign | - | Master |-------------->| Server | | |Resolver| - | files | | | |<--------|--| | - | |/ | | queries | +--------+ - +---------+ +----------+ | - A |maintenance | +--------+ - | +------------|->| | - | queries | |Foreign | - | | | Name | - +------------------|--| Server | - maintenance responses | +--------+ - -The shared database holds domain space data for the local name server -and resolver. The contents of the shared database will typically be a -mixture of authoritative data maintained by the periodic refresh -operations of the name server and cached data from previous resolver -requests. The structure of the domain data and the necessity for -synchronization between name servers and resolvers imply the general -characteristics of this database, but the actual format is up to the -local implementor. - - - - -Mockapetris [Page 6] - -RFC 1035 Domain Implementation and Specification November 1987 - - -Information flow can also be tailored so that a group of hosts act -together to optimize activities. Sometimes this is done to offload less -capable hosts so that they do not have to implement a full resolver. -This can be appropriate for PCs or hosts which want to minimize the -amount of new network code which is required. This scheme can also -allow a group of hosts can share a small number of caches rather than -maintaining a large number of separate caches, on the premise that the -centralized caches will have a higher hit ratio. In either case, -resolvers are replaced with stub resolvers which act as front ends to -resolvers located in a recursive server in one or more name servers -known to perform that service: - - Local Hosts | Foreign - | - +---------+ | - | | responses | - | Stub |<--------------------+ | - | Resolver| | | - | |----------------+ | | - +---------+ recursive | | | - queries | | | - V | | - +---------+ recursive +----------+ | +--------+ - | | queries | |queries | | | - | Stub |-------------->| Recursive|---------|->|Foreign | - | Resolver| | Server | | | Name | - | |<--------------| |<--------|--| Server | - +---------+ responses | |responses| | | - +----------+ | +--------+ - | Central | | - | cache | | - +----------+ | - -In any case, note that domain components are always replicated for -reliability whenever possible. - -2.3. Conventions - -The domain system has several conventions dealing with low-level, but -fundamental, issues. While the implementor is free to violate these -conventions WITHIN HIS OWN SYSTEM, he must observe these conventions in -ALL behavior observed from other hosts. - -2.3.1. Preferred name syntax - -The DNS specifications attempt to be as general as possible in the rules -for constructing domain names. The idea is that the name of any -existing object can be expressed as a domain name with minimal changes. - - - -Mockapetris [Page 7] - -RFC 1035 Domain Implementation and Specification November 1987 - - -However, when assigning a domain name for an object, the prudent user -will select a name which satisfies both the rules of the domain system -and any existing rules for the object, whether these rules are published -or implied by existing programs. - -For example, when naming a mail domain, the user should satisfy both the -rules of this memo and those in RFC-822. When creating a new host name, -the old rules for HOSTS.TXT should be followed. This avoids problems -when old software is converted to use domain names. - -The following syntax will result in fewer problems with many - -applications that use domain names (e.g., mail, TELNET). - - ::= | " " - - ::=